Three.js射线拾取平面/网格v69的面段

3

由于three.js不再支持四边形面,因此我在使用Raycast拾取四个顶点组成的正方形的线段时遇到了问题,因为现在它们由三角形面组成。

因此,我的拾取返回的是三角形而不是正方形:

                var faces = 10;
                var myplane = new THREE.Mesh(
                new THREE.PlaneGeometry(1000, 1000, faces, faces),
                new THREE.MeshNormalMaterial({
                color: 0x993333,
                wireframe: false
                }));

                objects.push(myplane);
                scene.add(myplane); 

                //raycast code


                if ( intersects.length > 0 ) {

                    _controls.noRotate = true;
                    var face = intersects[0].face;
                    var temp = intersects[0].object;
                    var geo = temp.geometry;

                    geo.vertices[face.a].z -= 20;
                    geo.vertices[face.b].z -= 20;
                    geo.vertices[face.c].z -= 20;
                    //want other face verts below basically
                    geo.vertices[face.d].z -= 20;
                    geo.vertices[face.e].z -= 20;
                    geo.vertices[face.f].z -= 20;   
                    geo.verticesNeedUpdate = true;

                    if(intersects[ 0 ].faceIndex % 2 == 0){
                        // geo.vertices[intersects[0].faceIndex + 1].z = 40;     
                       // console.log("Even face Index: " + intersects[ 0 ].faceIndex);

                     }else{
                        // console.log("Odd face Index: " + intersects[ 0 ].faceIndex -1);
                       //geo.vertices[intersects[0].faceIndex - 1].z = 40, of course doest work
                     }

                    }   

以下是一个2D示例,用于更好地展示:
目前我得到的结果是红色的,但我希望像绿色的示例一样选择: 平面分段示例

你有一个平面,想要进行射线投射以获取一个三角形,而不是一个正方形/两个三角形的面。我在考虑是否可以创建一个平面并将每个面成对存储,然后在循环中通过引用访问它们...但我希望有一个简单的解决方案,我相信这个答案会帮助许多人在更新他们的three.js版本时节省时间。 - Careen
1
如果你正在使用 THREE.Geometry 类型的几何体进行平面光线投射,那么 intersects[ 0 ].faceIndex 将告诉你所选面的面索引。 如果 faceIndex 是偶数,则加1可得到该四边形第二个面的面索引。 如果 faceIndex 是奇数,则减去1。 - WestLangley
在相交的三角形中找到最长的边,循环遍历所有其他面并找到具有相同边缘的面(指定构成该边缘的顶点)。 - meirm
geo.vertices[intersects[0].faceIndex + 1].z = 40; 我在这里漏掉了什么,顶点与当前面选择不同... - Careen
@meirm 我认为这对于非常大的网格来说不是一个好主意...现在我放弃了,4天过去了,我都快疯了。 - Careen
显示剩余2条评论
2个回答

7

尝试使用此代码获取交集面

if ( intersects.length > 0 )
{
    var faceIndex = intersects[0].faceIndex;
    var obj = intersects[0].object;
    var geom = obj.geometry;
    var faces = obj.geometry.faces;
    var facesIndices = ["a","b","c"];
    facesIndices.forEach(function(indices){
        geom.vertices[faces[faceIndex][indices]].setZ(-10);
    });
    if(faceIndex%2 == 0){
        faceIndex = faceIndex+1;
    }else{
        faceIndex = faceIndex-1;
    }
    facesIndices.forEach(function(indices){
        geom.vertices[faces[faceIndex][indices]].setZ(-10);
    }); 
    geom.verticesNeedUpdate = true;                               
}

1
A++ 很棒,它让我快疯了... 非常感谢 :) - Careen

0
在一般情况下,获取和更改射线投射到网格三角形相交的几何信息只需:
var face = intersects[0].face;
var obj = intersects[0].object;
var geom = obj.geometry; 

var vertA = geom.vertices[face.a];
var vertB = geom.vertices[face.b];
var vertC = geom.vertices[face.c];

vertA.setY(100);
vertB.setY(110);
vertC.setY(105);

geom.verticesNeedUpdate = true;

不需要遍历面数组,或构建一个人为的面顶点数组,仅仅为了在下一步中循环遍历它。

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