我有以下函数来获取所选对象,所以我的函数在这里
function onMouseDown(event) {
console.log(event);
event.preventDefault();
mouse.x = ( event.clientX / window.innerWidth ) * 2 - 1;
mouse.y = - ( event.clientY / window.innerHeight ) * 2 + 1;
// find intersections
var vector = new THREE.Vector3( mouse.x, mouse.y, 0.5 );
projector.unprojectVector( vector, camera );
var pLocal = new THREE.Vector3(0, 0, -1);
var pWorld = pLocal.applyMatrix4(camera.matrixWorld);
var ray = new THREE.Raycaster(pWorld, vector.sub(pWorld).normalize());
ray.set( camera.position, vector.sub( camera.position ).normalize() );
var intersects = ray.intersectObjects( scene.children );
//console.log(intersects);
console.log(scene.children);
if ( intersects.length > 0 ) {
var clickedObject = intersects[0].object;
console.log('objects '+intersects[ 0 ].object);
console.log('objects id'+intersects[ 0 ].object.id);
console.log('objects name'+intersects[ 0 ].object.name);
if ( INTERSECTED != intersects[ 0 ].object ) {
if ( INTERSECTED ) INTERSECTED.material.emissive.setHex( INTERSECTED.currentHex );
INTERSECTED = intersects[ 0 ].object;
console.log('INTERSECTED '+INTERSECTED);
INTERSECTED.currentHex = INTERSECTED.material.emissive.getHex();
INTERSECTED.material.emissive.setHex( 0xff0000 );
}
} else {
if ( INTERSECTED ) INTERSECTED.material.emissive.setHex( INTERSECTED.currentHex );
INTERSECTED = null;
}
}
但我在intersects
上获得了空数组,我尝试了我的最佳水平,但我无法找到任何解决方案,如果我控制scene.children
我可以看到所有附加的对象现场
在此之前将对象添加到场景中就像这里一样
var loader = new THREE.JSONLoader();
loader.load("uploads/accessories/3d/code/3dfile_"+file+".js",
function(geometry, object_material)
{
var object = new THREE.Mesh(geometry, new THREE.MeshFaceMaterial(object_material));
model = new THREE.Object3D();
model.id="Myid"+file;
model.name="Myname"+file;
model.userData ={ URL: "http://myurl.com" };
model.add(object);
model.position.set(x,y,z);
model.scale.set(obj_width,obj_height,obj_rotation);
model.opacity =2;
model.rotation.y = 600;
model.duration = 12000;
model.mirroredLoop = true;
model.castShadow = true;
model.receiveShadow = true;
console.log(model);
var smodel=model;
scene.add(smodel);
}
);
现在我希望在new THREE.Object3D();
中通过onMouseDown
获取添加的模型,但我不能,任何人都有相同的问题?
答案 0 :(得分:4)
您需要将recursive
标记传递给Raycaster.intersectObjects()
。
intersects = ray.intersectObjects( scene.children, true );
另外,请勿覆盖Object3D.id
。改为设置Object3D.userData.id
。
three.js r.68
答案 1 :(得分:0)
您正在使用没有十六进制抓取的MeshFaceMaterial。您必须从'材料'中获取'材料数组',如下所示:
for(var p =0; p < INTERSECTED.material.materials.length; p++){
INTERSECTED.currentHex = INTERSECTED.material.materials[p].emissive.getHex();
}
这样您就不会选择MeshFaceMaterial,而是选择每个面使用的MeshLambertMaterial或MeshBasicMaterial。如果您使用图像作为纹理,我建议您查看Three.js material texture and color以快速回答该问题。
希望这有用!
答案 2 :(得分:0)
Raycaster有点棘手,我已经添加了解释
为使raycaster正常工作,需要完成以下典型设置:
首先初始化一个变量,以保存需要从中发出光线的鼠标位置
var mouse = {
x: 0,
y: 0
};
//object intersected
var INTERSECTED;
// pool of objects which can be selected
var objects = [];
// ray caster initialization
var raycaster = new THREE.Raycaster();
我们需要创建一个Object3D
父对象来容纳所有子网格物体
let mainGroup = new THREE.Object3D();
// add into object pool
objects.push(mainGroup);
scene.add(mainGroup);
// add mesh to be select by ray caster in Object3D parent
mainGroup.add(meshToSelect);
添加事件侦听器以获取鼠标X,Y位置
document.addEventListener("mousemove", this.onDocumentMouseMove, false);
onDocumentMouseMove = event => {
event.preventDefault();
if (event && typeof event !== undefined) {
mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;
}
};
现在像这样使用raycaster:
renderScene = () => {
// Emit ray
raycaster.setFromCamera(mouse, this.camera);
// all intersects
var intersects = raycaster.intersectObjects(objects, true);
if (intersects.length > 0) {
if (INTERSECTED != intersects[0].object) {
//if new item selected swap color of new item
//& revert color of previous item
if (INTERSECTED)
INTERSECTED.material.color.setHex(INTERSECTED.currentHex);
INTERSECTED = intersects[0].object;
INTERSECTED.currentHex = INTERSECTED.material.color.getHex();
INTERSECTED.material.color.setHex(0xff0000);
}
} else {
// None selected then revert color of previous item
if (INTERSECTED)
INTERSECTED.material.color.setHex(INTERSECTED.currentHex);
INTERSECTED = null;
}
if (this.renderer) this.renderer.render(scene, this.camera);
};
答案 3 :(得分:-2)
尝试完成此example。查看控制台中的消息。
<script src="js/controls/EventsControls.js"></script>
EventsControls = new EventsControls( camera, renderer.domElement );
EventsControls.draggable = false;
EventsControls.onclick = function() {
console.log( this.focused.name );
}
var jsonLoader = new THREE.JSONLoader();
jsonLoader.load( "models/Tux.js", addModelToScene );
function addModelToScene( geometry, materials ) {
var material = new THREE.MeshFaceMaterial( materials );
model = new THREE.Mesh( geometry, material );
model.scale.set( 10, 10, 10 ); model.name = 'Tux';
model.rotation.x = -Math.PI/2;
model.position.set( 175, 45, 125 );
scene.add( model );
EventsControls.attach( model );
}