如何从OBJLoader加载的Object3D创建BufferGeometry?
解决Object3D转BufferGeometry的问题
你踩了两个典型的Three.js新手坑——混淆了容器对象和几何体对象,以及没搞懂BufferGeometry和旧版Geometry的差异,咱们一个个说清楚:
1. 第一种方法报错的原因
OBJLoader加载完成返回的是Object3D(本质是一个可以包含多个Mesh的组容器),但BufferGeometry.fromGeometry()要求的参数是**THREE.Geometry类型的几何体对象**,你直接把整个Object3D传进去,方法自然找不到它需要的顶点/面数据,才会报Cannot read property '0' of undefined。
正确的操作是先从Object3D里取出真正的Mesh,再拿它的Geometry:
const loader = new THREE.OBJLoader(); loader.load('你的模型.obj', (object3d) => { // 遍历容器里的所有子对象,找到Mesh类型的元素 object3d.traverse((child) => { if (child.isMesh) { // child.geometry才是你要的Geometry对象 const bufferGeo = new THREE.BufferGeometry().fromGeometry(child.geometry); // 现在bufferGeo就是可用的BufferGeometry了 } }); });
2. 为什么第二种方法里bgeometry.faces是undefined?
因为BufferGeometry根本没有faces属性!faces是旧版Geometry的专属属性,BufferGeometry用更高效的「顶点属性数组」和「索引数组」来存储数据:
- 顶点坐标存在
bufferGeo.attributes.position - 面的顶点索引存在
bufferGeo.index(如果是索引化几何体)
如果想查看面的数量,你可以这样算:
const bufferGeo = new THREE.BufferGeometry(); bufferGeo.setFromObject(object3d); // 这个方法会自动合并Object3D下所有可见Mesh的几何体 // 查看总顶点数 console.log(bufferGeo.attributes.position.count); // 查看索引总数(每个面对应3个索引) if (bufferGeo.index) { const faceCount = bufferGeo.index.count / 3; console.log(`总面数:${faceCount}`); } else { // 无索引的话,每3个顶点组成一个面 const faceCount = bufferGeo.attributes.position.count / 3; console.log(`总面数:${faceCount}`); }
另外补充:setFromObject()会自动合并模型里的所有Mesh,如果你需要逐个处理单个面,建议先单独取出每个Mesh的几何体再转BufferGeometry,避免合并后的数据不好拆分。
内容的提问来源于stack exchange,提问作者simone
相关产品推荐
相关产品推荐

