three.js:使用createMultiMaterialObject创建的多材质对象无法使用光线跟踪Raycaster选中

时间:2024-04-19 22:04:08

创建多材质对象:

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;
}
},