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)
相关推荐
Mintopia19 小时前
Three.js 制作飘摇的草:从基础到进阶的全流程教学
前端·javascript·three.js
三年三月1 天前
three的基本介绍
three.js
小桥风满袖2 天前
Three.js-硬要自学系列15 (圆弧顶点、几何体方法、曲线简介、圆、椭圆、样条曲线、贝塞尔曲线)
前端·css·three.js
伶俜monster2 天前
光影编程师:Threejs Shader 基础全攻略
前端·webgl·three.js
小桥风满袖2 天前
Three.js-硬要自学系列14 (PBR材质、环境贴图、清漆层、物理材质透光率)
前端·css·three.js
Mintopia2 天前
Three.js 物体碰撞试验学习指南
前端·javascript·three.js
小桥风满袖3 天前
Three.js-硬要自学系列13 (加载gltf外部模型、加载大模型)
前端·css·three.js
前端小崔3 天前
从零开始学习three.js(14):一文详解three.js中的场景Scene
webgl·three.js·数据可视化
小桥风满袖3 天前
Three.js-硬要自学系列12 (各种贴图的综合应用)
前端·css·three.js
Mintopia3 天前
Three.js 与物理引擎配合学习指南
前端·javascript·three.js