Three.js: 缩放对象的边界球体

Three.js: Bounding sphere of a scaled object

我有一组 3D 形状(金字塔、立方体、八面体、棱柱等),我需要围绕每个形状构建描述的球体。使用 geometry.boundingSphere 很容易做到这一点,因为它具有所描述球体的半径。但是,如果我缩放一个对象,则边界球体不会被更新。是否可以相对于比例更新边界球体? 使用 Three.js 0.129.

const { position } = entity.object3D;
const mesh = entity.getObject3D('mesh') as THREE.Mesh;

mesh.geometry.computeBoundingSphere();

const { radius } = mesh.geometry.boundingSphere;

createSphere(radius, position);

geometry.boundingSphere属性表示几何。从技术上讲,您可以让两个具有不同比例的网格共享相同的几何体,因此您需要保留几何体的原始边界球体,然后分别为每个网格体计算一个新的边界球体。

缩放边界球体的一个问题是您可以分别在xyz中缩放网格,甚至在给定负缩放值的情况下反转顶点位置值。不相等的比例值会导致它更像是一个椭球体,而不是一个球体,这对你的数学没有帮助。

可以做的是根据更新的世界变换矩阵重新计算网格的边界球体。我建议使用世界矩阵,因为你的网格的其他祖先也可能以不可预测的方式影响比例。

// Given:
// (THREE.Mesh) yourMesh

// Copy the geometry 
let geoClone = yourMesh.geometry.clone() // really bad for memory, but it's simple/easy

// Apply the world transformation to the copy (updates vertex positions)
geoClone.applyMatrix4( yourMesh.matrixWorld )

// Convert the vertices into Vector3s (also bad for memeory)
let vertices = []
let pos = geoClone.attributes.position.array
for( let i = 0, l = pos.length; i < l; i += 3 ){
  vertices.push( new THREE.Vector3( pos[i], pos[i+1], pos[i+2] ) )
}

// Create and set your mesh's bounding sphere
yourMesh.userData.boundingSphereWorld = new THREE.Sphere()
yourMesh.userData.boundingSphereWorld.setFromPoints( vertices )

这将为您的网格创建一个与世界对齐的边界球体。如果你想要一个基于局部变换的,你可以使用局部 yourMesh.matrix 矩阵来遵循相同的想法。只需知道球体的中心将基于网格的 local transformation/rotation,而不仅仅是其比例。