Three.js 进阶(包围盒、世界矩阵转换、包围球及几何体居中)

本篇主要学习内容 :

  1. 包围盒
  2. 世界矩阵转换
  3. 几何体居中(获取几何体中心)

点赞 + 关注 + 收藏 = 学会了

1. 包围盒

描述一个长方体包围盒需要通过xyz坐标来表示,X范围[Xmin,Xmax],Y范围[Ymin,Ymax],Z范围[Zmin,Zmax],.min属性值是Vector3(Xmin, Ymin, Zmin),.max属性值是Vector3(Xmax, Ymax, Zmax).

在这里插入图片描述

// 计算包围盒
duckGeometry.computeBoundingBox()
//获取包围盒  //min左后下角 max 右上前角  xyz三轴一条线
let duckBox = duckGeometry.boundingBox

//包围盒辅助器
let boxHelper = new THREE.Box3Helper(duckBox, 'yellow')
scene.add(boxHelper)

2.世界矩阵转换

查看Three.js文档,模型对象的父类Object3D,可以看到本地矩阵.matrix和世界矩阵.matrixWorld两个属性,本节重点学习 世界矩阵.matrixWorld

通过.getWorldPosition()获取的世界坐标,是模型相对世界坐标系的坐标,也就是该对象及其父对象所有.position属性值的累加。

const worldPosition = new THREE.Vector3();
mesh.getWorldPosition(worldPosition)
console.log('世界坐标',worldPosition);

一个模型对象的世界矩阵属性.matrixWorld是自身及其所有父对象本地矩阵属性.matrix的复合矩阵。

请添加图片描述

 // 更新世界矩阵
duckMesh.updateWorldMatrix(true, true)
// 更新包围盒 应用世界矩阵
duckBox.applyMatrix4(duckMesh.matrixWorld)

如果不更新会是这样的,就相当于基于整个模型,本地和世界的关系类似于css种绝对定位和相对定位基于的父元素不一样,得到的包围盒也就不一样

在这里插入图片描述

3.几何体居中(获取几何体中心)

为什么要获取几何体中心这和包围球有什么关系???

图片1 图片2
在这里插入图片描述 在这里插入图片描述

对比图一图二我们可以发现一个包围球基于了模型的包围盒,另一个基于了模型中心

这就是为什么我们要获取几何体中心,下面看代码如何获取,两种方式适用于不同场景

// 加载模型
gltfloader.load(
    // 模型路径
    './model/Duck.glb',
    // 加载回调
    (gltf) => {
    
    
        scene.add(gltf.scene)
        // 获取元素
        let duckMesh = gltf.scene.getObjectByName('LOD3spShape')
        let duckGeometry = duckMesh.geometry
        // 计算包围盒
        duckGeometry.computeBoundingBox()
        // 设置居中
        duckGeometry.center()
        //获取包围盒
        let duckBox = duckGeometry.boundingBox //min左后下角 max 右上前角  xyz三轴一条线
        // 更新世界矩阵
        duckMesh.updateWorldMatrix(true, true)
        // 更新包围盒 应用世界矩阵
        duckBox.applyMatrix4(duckMesh.matrixWorld)
        // 获取包围盒中心点
        let center = duckBox.getCenter(new THREE.Vector3())
        console.log(center, 'cccc')
        //包围盒辅助器
        let boxHelper = new THREE.Box3Helper(duckBox, 'yellow')
        scene.add(boxHelper)

        // 获取包围球
        let duckSphere = duckGeometry.boundingSphere
        // 应用世界矩阵
        duckSphere.applyMatrix4(duckMesh.matrixWorld)
        // 创建包围球
        let sphereGeometry = new THREE.SphereGeometry(duckSphere.radius, 10, 10)
        let sphereMaterial = new THREE.MeshBasicMaterial({
    
    
            color: 'red',
            wireframe: true,
        })
        let sphereMesh = new THREE.Mesh(sphereGeometry, sphereMaterial)
        sphereMesh.position.copy(duckSphere.center)
        scene.add(sphereMesh)
    }
)

到此进阶(三)学习告一段落,道阻且长,行则将至。与诸君共勉。 ⭐️