THREE.js中BoxGeometry的vertices顶点含义及获取相关问题
BoxGeometry顶点数量相关说明
一个标准立方体在三维空间中仅有8个空间顶点,但Three.js的BoxGeometry(默认继承自BufferGeometry)会存储24个顶点,对应72个浮点型坐标值,原因如下:
- 立方体共6个面,每个面独立存储4个顶点,
6 * 4 = 24个顶点,每个顶点包含x/y/z三个分量,总长度就是24 * 3 = 72 - 即使多个顶点的空间坐标完全一致,也会单独存储,因为每个顶点需要绑定对应面的法线、UV坐标等专属属性,用于材质渲染、纹理映射等逻辑,所以你会看到大量重复的坐标值
- 每个面的4个顶点按逆时针顺序排列,顺序决定了面的正反朝向,用于背面剔除等渲染优化逻辑
为什么sidehand.vertices无法获取顶点
vertices属性是旧版Three.js(r125版本之前)中Geometry类的属性,目前新版Three.js已经废弃了Geometry,所有内置几何体默认使用BufferGeometry实现,没有顶层的vertices属性,所有顶点数据都存储在几何体的attributes属性下。
另外你之前的写法this.sidehand.attributes.position.array也有错误:attributes是几何体的属性,不是Mesh实例的属性,正确的获取路径是:
const positionArray = sidehand.geometry.attributes.position.array
Raycaster碰撞检测实现方案
你不需要自己提取顶点做碰撞检测,Three.js已经封装了成熟的方案,常用两种实现方式:
1. 原生Mesh碰撞检测
直接调用Raycaster的intersectObject方法即可,支持直接检测射线和Mesh的相交:
// 初始化射线实例 const raycaster = new THREE.Raycaster() // 设置射线的起点和方向,示例为从相机发出指向鼠标位置的射线 const mouse = new THREE.Vector2() mouse.x = (event.clientX / window.innerWidth) * 2 - 1 mouse.y = -(event.clientY / window.innerHeight) * 2 + 1 raycaster.setFromCamera(mouse, camera) // 检测和sidehand的碰撞 const intersects = raycaster.intersectObject(sidehand) if (intersects.length > 0) { // 存在碰撞,intersects数组中包含碰撞点、碰撞距离、碰撞面等详细信息 }
2. 包围盒高性能碰撞检测
如果仅需要判断是否碰撞,不需要精确碰撞点信息,可以提前为Mesh绑定轴对齐包围盒Box3,性能更高:
// 初始化时计算一次包围盒,sidehand位置发生变化时需要重新计算 const sidehandBoundingBox = new THREE.Box3().setFromObject(sidehand) // 碰撞检测 if (sidehandBoundingBox.intersectsRay(raycaster.ray)) { // 存在碰撞 }
如果你确实需要获取去重后的8个立方体顶点,可以直接对positionArray中的坐标按x/y/z值做去重处理,或者直接根据BoxGeometry的长宽高参数计算8个顶点坐标,效率更高。
内容的提问来源于stack exchange,提问作者hellooooo
相关产品推荐
相关产品推荐

