Hello everyone,
I’m working on a little game to practice my Three.js skills. My goal is to load a bunch of objects from a GLTF file and draw bounding-boxes around the individual objects. After trying to apply the Axis-Aligned Bound Boxes (AABB) I concluded that rotating was not possible, so I jumped to the Oriented Bounding Boxes (OBB) for this purpose.
I currently have two solutions with the OBB. The first solution works half, when I manually rotate the mesh the bounding-box ‘grows’. But even when rotating the bounding-box should keep the same shape/dimension as the mesh. It’s giving the following results:
With the matching code
gltfLoader.load("/blender/3D-logo.glb", (gltf) => {
gltf.scene.traverse((child) => {
child.material = meshMaterial;
});
// Add mesh to the scene || use as 'main' object in calculations
const meshIcon = gltf.scene.children[1];
// Center mesh to its own pivot-point
const meshIconCenter = new THREE.Vector3();
meshIcon.geometry.computeBoundingBox();
meshIcon.geometry.boundingBox.getCenter(meshIconCenter);
meshIcon.geometry.center();
// Transform mesh to its gltf-origin
meshIcon.position.copy(meshIconCenter);
meshIcon.rotation.set(Math.PI / 4, 0, 0);
// Stores bounding-box dimension based on mesh
const boxSize = new THREE.Box3().setFromObject(meshIcon);
// Set-up oriented bounding box (OBB) in userData object
meshIcon.userData.obb = new OBB().fromBox3(boxSize);
// Visual representation of the bounding-box
const bbox = new THREE.Mesh(
new THREE.BoxGeometry(
meshIcon.userData.obb.halfSize.x * 2,
meshIcon.userData.obb.halfSize.y * 2,
meshIcon.userData.obb.halfSize.z * 2
),
bboxMaterial
);
bbox.applyMatrix4(meshIcon.matrix);
camera.lookAt(gltf.scene.position);
scene.add(meshIcon, bbox);
});
The second solution works and is an iteration on the first solution. The bounding-box fits each 3d-object from the GLTF file and respects the rotations. Except, I’m not sure if this is the ‘right way’ because the matrix rotation is not set on bb.boxapplyMatrix4() but with bbox.rotation.copy(meshIcon.rotation). It feels odd to do it like this…
See the matching code below:
gltfLoader.load("/blender/3D-logo.glb", (gltf) => {
gltf.scene.traverse((child) => {
child.material = meshMaterial;
});
// Add mesh to the scene || use as 'main' object in calculations
const meshIcon = gltf.scene.children[1];
// Center mesh to its own pivot-point
const meshIconCenter = new THREE.Vector3();
meshIcon.geometry.computeBoundingBox();
meshIcon.geometry.boundingBox.getCenter(meshIconCenter);
meshIcon.geometry.center();
// Transform mesh to its gltf-origin
meshIcon.position.copy(meshIconCenter);
// Stores bounding-box dimension based on mesh
const boxSize = new THREE.Box3().setFromObject(meshIcon);
// Set-up oriented bounding box (OBB) in userData object
meshIcon.userData.obb = new OBB().fromBox3(boxSize);
// Visual representation of the bounding-box
const bbox = new THREE.Mesh(
new THREE.BoxGeometry(
meshIcon.userData.obb.halfSize.x * 2,
meshIcon.userData.obb.halfSize.y * 2,
meshIcon.userData.obb.halfSize.z * 2
),
bboxMaterial
);
meshIcon.rotation.set(Math.PI / 3, 0, 0); // #issue-01 : Rotation alternative
bbox.applyMatrix4(meshIcon.matrix);
bbox.rotation.copy(meshIcon.rotation); // #issue-01 : Rotation alternative - Should not be necessary when 'normal' rotation is solved
camera.lookAt(gltf.scene.position);
scene.add(meshIcon, bbox);
});
If anyone could help me out, it’s very appreciated!
Thanks in advance,