創建多材質對象:
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; } },