threejs - 包围盒和包围球

在Three.js中,包围盒(Bounding Box)和包围球(Bounding Sphere)是两种常见的用于简化碰撞检测和空间查询的几何体

包围盒

  1. 碰撞检测:包围盒是一个简单的几何空间,里面包含着复杂形状的物体。通过为物体添加包围盒,可以在进行精确的碰撞检测之前进行过滤,即当包围盒碰撞时,才进行精确的碰撞检测和处理。这样可以显著提高碰撞检测的效率。
  2. 场景边界判定:包围盒可以作为场景边界的判定值,用于确定物体是否在某个特定区域内。
  3. 体积和中心点计算:对于不规则物体,可以通过包围盒来近似计算其体积和中心点。

计算几何体的矩形包围

js 复制代码
gltfLoader.load(
  "./model/Duck.glb",
  (gltf)=>{
    console.log(gltf);
    // 把模型加入到场景中
    scene.add(gltf.scene)
    // 获取到几何体
    let duckMesh = gltf.scene.getObjectByName("LOD3spShape")
    let duckGeometry = duckMesh.geometry
    // 计算包围盒
    duckGeometry.computeBoundingBox()
    // 获取包围盒
    let duckBox = duckGeometry.boundingBox
    // 创建包围盒辅助器
    let boxHelper = new THREE.Box3Helper(duckBox, 0xffff00)
    // 更新世界矩阵
    duckMesh.updateWorldMatrix(true, true)
    // 更新包围盒
    duckBox.applyMatrix4(duckMesh.matrixWorld)
    // 添加到场景中
    scene.add(boxHelper)
  }
)

几何体居中

几何体.center()

js 复制代码
const gltfLoader = new GLTFLoader()
gltfLoader.load(
  "./model/Duck.glb",
  (gltf)=>{
    console.log(gltf);
    // 把模型加入到场景中
    scene.add(gltf.scene)
    // 获取到几何体
    let duckMesh = gltf.scene.getObjectByName("LOD3spShape")
    let duckGeometry = duckMesh.geometry
    // 设置居中
    duckGeometry.center()
    // 计算包围盒
    duckGeometry.computeBoundingBox()
    // 获取包围盒
    let duckBox = duckGeometry.boundingBox
    // 创建包围盒辅助器
    let boxHelper = new THREE.Box3Helper(duckBox, 0xffff00)
    // 更新世界矩阵
    duckMesh.updateWorldMatrix(true, true)
    // 更新包围盒
    duckBox.applyMatrix4(duckMesh.matrixWorld)
    // 添加到场景中
    scene.add(boxHelper)
  }
)
获取包围盒中心点
js 复制代码
// 获取包围盒中心点
    let center = duckBox.getCenter(new THREE.Vector3())

包围球

  1. 碰撞检测:与包围盒类似,包围球也可以用于碰撞检测。通过将物体封装到一个包围球中,可以简化碰撞检测的计算过程。
  2. 相机飞行参考值:在Three.js中,包围球还可以作为相机飞行的参考值,帮助确定相机的移动范围和视角。
js 复制代码
 // 获取包围球
let duckSphere = duckGeometry.boundingSphere
duckSphere.applyMatrix4(duckMesh.matrixWorld)
// 创建包围球辅助器
let sphereGeometry = new THREE.SphereGeometry(duckSphere.radius, 16, 16)
let sphereMaterial = new THREE.MeshBasicMaterial({
  color: 0xff0000,
  wireframe: true
})
let sphereMesh = new THREE.Mesh(sphereGeometry, sphereMaterial)
sphereMesh.position.copy(duckSphere.center)
scene.add(sphereMesh)

多个物体的包围盒

第一种方式

循环需要包围的盒子,用一个空盒子合并需要包围的盒子,然后创建父盒子的包围盒

js 复制代码
let box = new THREE.Box3()
let arrSphere = [sphere1, sphere2, sphere3]
for (let i = 0; i < arrSphere.length; i++) {
  // 计算当前物体的包围盒
  arrSphere[i].geometry.computeBoundingBox()
  // 获取包围盒
  let box3 = arrSphere[i].geometry.boundingBox
  // 更新世界矩阵
  arrSphere[i].updateWorldMatrix(true, true)
  // 将包围盒转换到世界坐标系
  box3.applyMatrix4(arrSphere[i].matrixWorld)
  // 合并包围盒
  box.union(box3)
}
// 创建包围盒辅助器
let boxHelper = new THREE.Box3Helper(box, 0xffff00)
scene.add(boxHelper)

第二种方式

使用setFromObject,计算包围盒的3D对象

js 复制代码
let box = new THREE.Box3()
let arrSphere = [sphere1, sphere2, sphere3]
for (let i = 0; i < arrSphere.length; i++) {
  let box3 = new THREE.Box3().setFromObject(arrSphere[i])
  // 合并包围盒
  box.union(box3)
}
// 创建包围盒辅助器
let boxHelper = new THREE.Box3Helper(box, 0xffff00)
scene.add(boxHelper)
相关推荐
Nan_Shu_61417 小时前
学习: Threejs (15)& Threejs (16)
学习·three.js
Charlie_lll18 小时前
学习Three.js–材质(Material)
前端·three.js
答案—answer5 天前
开源项目:Three.js3D模型可视化编辑系统
javascript·3d·开源·开源项目·three.js·three.js编辑器
贝格前端工场5 天前
困在像素里:我的可视化大屏项目与前端价值觉醒
前端·three.js
全栈王校长5 天前
Three.js 材质进阶
webgl·three.js
全栈王校长5 天前
Three.js Geometry进阶
webgl·three.js
烛阴6 天前
3D字体TextGeometry
前端·webgl·three.js
全栈王校长6 天前
Three.js 开发快速入门
three.js
全栈王校长6 天前
Three.js 环境搭建与开发初识
three.js
DaMu7 天前
Dreamcore3D ARPG IDE “手搓”游戏引擎,轻量级实时3D创作工具,丝滑操作,即使小白也能轻松愉快的创作出属于你自己的游戏世界!
前端·架构·three.js