调用applyQuaternion提示不是函数,如何用quaternion更新geometry顶点?
问题解决方法
问题根本原因
你遇到的问题是Three.js r125版本之后完全移除了旧版Geometry类,当前版本所有几何体默认采用BufferGeometry实现,两者顶点存储逻辑完全不同:
- 旧版
Geometry.vertices存储的是THREE.Vector3实例数组,每个元素自带applyQuaternion方法,可以直接调用 - 新版
BufferGeometry.attributes.position.array是扁平化Float32Array类型,存储的是[x1,y1,z1,x2,y2,z2...]格式的连续数值,单个元素是纯数字,本身没有向量相关方法,直接调用applyQuaternion自然不会生效。
解决方法
场景1:需要变换单个/部分指定顶点
先声明一个可复用的临时THREE.Vector3实例,完成「读取顶点→应用四元数→写回缓冲区」的流程:
// 初始化全局复用的临时向量,避免重复创建造成性能损耗 const _tempVec = new THREE.Vector3() // 获取几何体的position属性 const positionAttr = geometry.attributes.position // 示例:变换索引为n的顶点(顶点索引从0开始计数) const targetVertexIndex = 0 // 从缓冲区读取顶点坐标到临时向量 _tempVec.fromBufferAttribute(positionAttr, targetVertexIndex) // 应用四元数变换 _tempVec.applyQuaternion(quaternion) // 将变换后的坐标写回缓冲区 positionAttr.setXYZ(targetVertexIndex, _tempVec.x, _tempVec.y, _tempVec.z) // 标记position属性需要更新,否则渲染器不会读取新的顶点数据 positionAttr.needsUpdate = true
场景2:需要给整个几何体所有顶点应用同一个四元数
直接调用BufferGeometry内置的applyQuaternion方法即可,内部已经封装了高效的遍历变换逻辑,无需手动处理顶点:
geometry.applyQuaternion(quaternion)
注意事项
- 不要直接修改
positionAttr.array的单个元素后不做后续处理,修改完成后必须设置positionAttr.needsUpdate = true,否则更新不会生效 - 临时向量建议全局复用,不要在循环逻辑中重复创建
THREE.Vector3实例,避免频繁GC导致页面卡顿 - 如果多个Mesh共享同一个几何体,修改几何体顶点会影响所有关联的Mesh;如果只需要单个模型做旋转变换,直接操作Mesh实例的
quaternion属性即可,不需要修改几何体本身。
内容的提问来源于stack exchange,提问作者Jqui
相关产品推荐
相关产品推荐

