OBB Bounding-box 'growing' after rotation

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,

1 Like