获取three.js网格顶点的最佳方法

8

我是一个Three.js的新手,也许我不是最优化的方法,

我创建几何体的方式如下,

const geo = new THREE.PlaneBufferGeometry(10,0);

然后我对它应用旋转

geo.applyMatrix( new THREE.Matrix4().makeRotationX( Math.PI * 0.5 ) );

然后我从中创建一个网格。
const open = new THREE.Mesh( geo, materialNormal);

然后,我对网格应用了一系列操作,以正确定位它,具体如下:

open.position.copy(v2(10,20);
open.position.z = 0.5*10

open.position.x -= 20
open.position.y -= 10
open.rotation.z = angle;

现在,获取网格在位置改变前后的顶点最好的方法是什么?我惊讶地发现网格的顶点不是内置在three.js中的。

任何提示和代码示例都将不胜感激。

2个回答

14

我认为你在关于three.js对象的某些语义上被绊倒了。

1) 一个Mesh没有顶点。一个Mesh包含对Geometry/BufferGeometryMaterial的引用。顶点包含在Meshgeometry属性/对象中。

2) 您正在使用PlaneBufferGeometry,这意味着BufferGeometry对象的一种实现。BufferGeometry将其顶点保存在position属性(mesh.geometry.attributes.position)中。请记住,顶点顺序可能会受到index属性(mesh.geometry.index)的影响。

现在回答你的问题,几何原点也是其父Mesh的原点,因此“网格转换之前”的顶点位置与创建网格时完全相同。只需按原样读取它们即可。

要获得“网格转换后”的顶点位置,您需要将每个顶点从Mesh的本地空间转换为世界空间。幸运的是,three.js有一个方便的函数来完成这项工作:

var tempVertex = new THREE.Vector3();
// set tempVertex based on information from mesh.geometry.attributes.position

mesh.localToWorld(tempVertex);
// tempVertex is converted from local coordinates into world coordinates,
// which is its "after mesh transformation" position

-2
这是一个使用 TypeScript 编写的示例。
它获取网格在世界坐标系中的位置。
    GetObjectVertices(obj: THREE.Object3D): { pts: Array<THREE.Vector3>, faces: Array<THREE.Face3> }
{
    let pts: Array<THREE.Vector3> = [];

    let rs = { pts: pts, faces: null };

    if (obj.hasOwnProperty("geometry"))
    {
        let geo = obj["geometry"];
        if (geo instanceof THREE.Geometry)
        {
            for (let pt of geo.vertices)
            {
                pts.push(pt.clone().applyMatrix4(obj.matrix));
            }
            rs.faces = geo.faces;
        }
        else if (geo instanceof THREE.BufferGeometry)
        {
            let tempGeo = new THREE.Geometry().fromBufferGeometry(geo);
            for (let pt of tempGeo.vertices)
            {
                pts.push(pt.applyMatrix4(obj.matrix));
            }
            rs.faces = tempGeo.faces;
            tempGeo.dispose();
        }
    }
    return rs;
}

或者

if (geo instanceof THREE.BufferGeometry)
{
    let positions: Float32Array = geo.attributes["position"].array;
    let ptCout = positions.length / 3;
    for (let i = 0; i < ptCout; i++)
    {
        let p = new THREE.Vector3(positions[i * 3], positions[i * 3 + 1], positions[i * 3 + 2]);
    }
}

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