three.js:使用createMultiMaterialObject創建的多材質對象無法使用光線跟蹤Raycaster選中


創建多材質對象:

var loader = new THREE.DDSLoader();
var map = loader.load('../assets/textures/Mountains_argb_nomip.dds', function ( texture ) {
    texture.magFilter = THREE.LinearFilter;
    texture.minFilter = THREE.LinearFilter;
    texture.mapping = THREE.CubeReflectionMapping;
    material.needsUpdate = true;
});
var material = new THREE.MeshLambertMaterial({envMap: map, transparent: true, opacity: 0.8});
var material1 = new THREE.MeshBasicMaterial({color: 0x2277ff, transparent: true, opacity: 0.3});

//
var leftdown1 = new THREE.SceneUtils.createMultiMaterialObject(new THREE.BoxGeometry(6, 1, 9),[material,material1.clone()]);
leftdown1.position.set(-11, 3, 9);
leftdown1.name = "movealbe-element-leftdown1";
group.add(leftdown1);
this.objects.push(leftdown1);

光線跟蹤:

onDocumentMouseMove: function (e) {
    var event = e || window.event;
    event.preventDefault();

    var mouseX = (event.clientX / map3d.width) * 2 - 1;//標准設備橫坐標
    var mouseY = -(event.clientY / map3d.height) * 2 + 1;//標准設備縱坐標
    var vector = new THREE.Vector3(mouseX, mouseY, 0.5);//標准設備坐標
    //標准設備坐標轉世界坐標
    var worldVector = vector.unproject(map3d.camera);
    //射線投射方向單位向量(worldVector坐標減相機位置坐標)
    var ray = worldVector.sub(map3d.camera.position).normalize();
    //創建射線投射器對象
    var raycaster = new THREE.Raycaster(map3d.camera.position, ray);
    //返回射線選中的對象
    var intersects = raycaster.intersectObjects(map3d.objects,true);
    if (intersects.length > 0) {
        var obj = intersects[0].object;
        var target=null;
        if (obj.name.startsWith("movealbe-element")) {
            target=obj;
        }else{
            if(obj.parent && obj.parent.name.startsWith("movealbe-element")){
                target=obj.parent;
            }
        }
        if(target){
            //如果聚焦的對象存在,並且相同
            if (map3d.focusobj && target.uuid == map3d.focusobj.uuid)
                return;
            //更新最新一次聚焦的對象引用
            map3d.focusobj = target;
            if(map3d.focusobj.children.length>1)
                map3d.focusobj.children[1].material.color = new THREE.Color("#00FF7F");
        }
    } else {

    }
},

材質還原:

map3d.scene.traverse(function (e) {
    if (e.name && e.name.startsWith("movealbe-element") && map3d.focusobj && map3d.focusobj.uuid != e.uuid) {
        if(e.children.length>1)
            e.children[1].material.color = new THREE.Color("#2277ff");
    }
});

說明:多材質對象,是創建了一個group,可以通過獲取子對象來獲取這個group。另外加載的3d模型也是group,可以通過這種方式使用raycaster選中模型。

initCityModel:function(){
    // this.addModel({name:'powerstation',x:-10});
    this.addModel({name:'movealbe-element-powerstation',model:'powerstation',x:0,y:0,z:-10});
},
//  根據模型名稱像場景中添加一個模型對象
addModel:function(obj){
    var self=this;
    if(!obj.model)
        return;
    if(!obj.path)
        obj.path='../assets/models/';
    if(!obj.x&&isNaN(obj.x))
        obj.x=0;
    if(!obj.y&&isNaN(obj.y))
        obj.y=0;
    if(!obj.z&&isNaN(obj.z))
        obj.z=0;

    var onProgress = function (xhr) {
        if (xhr.lengthComputable) {
            var percentComplete = xhr.loaded / xhr.total * 100;
            console.log(obj.model + Math.round(percentComplete,2) + '% downloaded');
        }
    };

    var onError = function () { };

    new THREE.MTLLoader()
        .setPath(obj.path)
        .load(obj.model+'.mtl', function (materials) {
            materials.preload();

            new THREE.OBJLoader()
                .setMaterials(materials)
                .setPath(obj.path)
                .load(obj.model+'.obj', function (object) {
                    object.position.set(obj.x,obj.y,obj.z);
                    if(obj.name){
                        object.name=obj.name;
                        console.log(object);
                        self.objects.push(object);
                    }
                    self.scene.add(object);
                },onProgress,onError);
        });
},
//  鼠標事件
onDocumentMouseDown: function (e) {
    var event = e || window.event;
    event.preventDefault();

    var mouseX = (event.clientX / map3d.width) * 2 - 1;//標准設備橫坐標
    var mouseY = -(event.clientY / map3d.height) * 2 + 1;//標准設備縱坐標
    var vector = new THREE.Vector3(mouseX, mouseY, 0.5);//標准設備坐標
    //標准設備坐標轉世界坐標
    var worldVector = vector.unproject(map3d.camera);
    //射線投射方向單位向量(worldVector坐標減相機位置坐標)
    var ray = worldVector.sub(map3d.camera.position).normalize();
    //創建射線投射器對象
    var raycaster = new THREE.Raycaster(map3d.camera.position, ray);
    //返回射線選中的對象
    var intersects = raycaster.intersectObjects(map3d.objects,true);
    console.log(map3d.camera.position);
    if (intersects.length > 0) {
        // 禁用軌道控制器
        // map3d.controls.enabled = false;

        var obj = intersects[0].object;
        var target=null;
        if (obj.name.startsWith("movealbe-element")) {
            target=obj;
        }else{
            if(obj.parent && obj.parent.name.startsWith("movealbe-element")){
                target=obj.parent;
            }
        }
        // 設置選中的元素
        if(target){
            map3d.selection = target;
        }
    } else {
        map3d.selection = null;
    }
},

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM