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)
相关推荐
古柳_Deserts_X1 天前
坏消息又断更8个多月,好消息准备重新开始更新 Shader 教程啦
前端·javascript·three.js
漫步云端的码农2 天前
Three.js场景渲染优化
前端·性能优化·three.js
伶俜monster3 天前
探秘 Threejs GUI:开启丝滑调试之旅
前端·webgl·three.js
Lovely Ruby5 天前
【ThreeJS Basics 06】Camera
three.js
青云交11 天前
Java 大视界 -- 基于 Java 的大数据可视化交互设计与实现技巧(105)
java·信息可视化·echarts·three.js·实时渲染·可视化交互·ar 可视化
优雅永不过时·1 个月前
原生Three.js 和 Cesium.js 案例 。 智慧城市 数字孪生常用功能列表
前端·javascript·低代码·编辑器·智慧城市·webgl·three.js
一粒马豆1 个月前
three.js用粒子使用canvas生成的中文字符位图材质
3d·three.js·canvas·中文字符·粒子动画
一粒马豆2 个月前
three.js实现裸眼双目平行立体视觉
3d·vr·three.js·裸眼双目平行立体视觉
咔咔库奇2 个月前
【three.js】纹理贴图
开发语言·javascript·three.js·贴图·three
程序员小淞2 个月前
1、如何本地部署Threejs官网文档
前端·three.js