You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 13:09:03