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)
相关推荐
程序员_三木3 小时前
从 0 到 1 实现鼠标联动粒子动画
javascript·计算机外设·webgl·three.js
MossGrower14 小时前
43. Three.js案例-绘制100个立方体
three.js·webglrenderer·perspectivecam·boxgeometry
程序员_三木3 天前
Three.js入门-Raycaster鼠标拾取详解与应用
开发语言·javascript·计算机外设·webgl·three.js
MossGrower5 天前
36. Three.js案例-创建带光照和阴影的球体与平面
3d图形·webgl·three.js·光照与阴影
MossGrower5 天前
34. Three.js案例-创建球体与模糊阴影
webgl·three.js·3d渲染·阴影效果
广东数字化转型5 天前
Three.js相机Camera控件知识梳理
3d·three.js
关山月6 天前
9个学习着色器的GLSL示例
前端·three.js
程序员_三木6 天前
Three.js资源-贴图材质网站推荐
javascript·webgl·three.js·材质·贴图
MossGrower7 天前
37. Three.js案例-绘制部分球体
3d图形·webgl·three.js·球体几何体
关山月7 天前
如何使用Three.js创建3D音频可视化工具
前端·three.js