Three.js射线检测器未能检测到场景网格。

5

我在Chrome浏览器版本35.0.1916.153 m中使用的是three.js r67。

我正在尝试相交一些我在场景中创建的自定义网格。射线投射器似乎没有注册这些网格,尽管它们存在于scene.children中。

网格创建代码:

if (modelVertices != null && modelVertices.length >= 3) {
            triangles = THREE.Shape.Utils.triangulateShape ( modelVertices, holes );

            for( var i = 0; i < triangles.length; i++ ){

               modelGeometry.faces.push( new THREE.Face3( triangles[i][0], triangles[i][2], triangles[i][2] ));

                }

            modelGeometry.computeFaceNormals();
            var modelMesh = new THREE.Mesh(modelGeometry, material);
            modelMesh.material.side = THREE.DoubleSide;
            polyhedralzGroup.add(modelMesh)
    }

射线投射代码:

                var projector = new THREE.Projector();
                projector.unprojectVector( vector, camera );

                var raycaster = new THREE.Raycaster( camera.position, vector.sub( camera.position ).normalize() );
                //console.log("Work");
                // See if the ray from the camera into the world hits one of our meshes

                var intersects = raycaster.intersectObjects( scene.children, true );
                helper.position.set( 0, 0, 0 );
                //console.log(intersects.length);
                if ( intersects.length > 0 ) {  
                    if (intersects[ 0 ].face != null) {
                    helper.lookAt( intersects[ 0 ].face.normal );
                    helper.position.copy( intersects[ 0 ].point ); 
}

在代码中,我使用了computeFaceNormals();所以这不是问题(参见这里)。奇怪的是,场景似乎与其他使用简单三角形构建的几何体(即不使用THREE.Shape.Utils.triangulateShape;只是手动推三角形顶点和面)完美地相交,这意味着这不能是一个没有考虑相交的画布偏移的问题。我检查了两个几何图形,它们之间似乎没有任何基本差异。

无法相交对象的示例

有人对问题有什么想法吗?

2个回答

6
问题出在构建顶点的方式上:使用字符串。虽然three.js允许您使用字符串构建顶点(因此构建几何和网格),进而使用字符串显示几何,但它不允许您使用这些顶点进行射线投射检测。简洁地说,问题可以归纳为:
将此代码更改为:
aVertex = new THREE.Vector3( part[0], part[1] , part[2] );

转换为:

aVertex = new THREE.Vector3( parseFloat(part[0]), parseFloat(part[1]) , parseFloat(part[2]) );

我不确定这是一个 bug 还是一个特性,因为使用字符串格式的顶点时似乎不会抛出错误,尽管你无法在具有字符串顶点几何体的对象上进行光线投射(可能是因为无法计算法向量?)。


3

你的问题在于你将场景中的子对象 scene.children 传递给了射线检测器。

 var intersects = raycaster.intersectObjects( scene.children, true );

解决方案 1. 将您的模型加载到一个对象中

var objects = [];

objects.push(mesh);

然后

var intersects = raycaster.intersectObjects( objects, true );

解决方案1:

在第二场景中传递您的对象,并将其传递给您的光线投射器(raycaster)。

var scene_2

scene_2 = new THREE.Scene();
scene.add(scene_2);
scene_2.add(mesh);

var intersects = raycaster.intersectObjects( scene_2, true );

2
这不是一个解决方案。在你的例子中,scene.childrenobjects将指向完全相同的对象。 - Pål Thingbø

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接