Advertisement

Bounding Box Orientation

Started by January 09, 2022 11:20 PM
1 comment, last by frob 2 years, 11 months ago

Hi, I am trying to work out a reasonably efficient way to get a axis aligned bounding box. I'd like sense check to make sure I am going in the right direction.

What I am doing is this:

What I load a model, calculate the model extremes. Min and max for all the x,y,z positions. Then using the extremes create a box and store that on the game object.

This is what I am doing:

    var min = new Vector3(float.PositiveInfinity);
    var max = new Vector3(float.NegativeInfinity);

    for (var meshIndex = 0; meshIndex < model.meshCount; meshIndex++)
    {
      var currentMesh = model.meshes[meshIndex];

      for (var vertIndex = 0; vertIndex < currentMesh.vertexCount; vertIndex++)
      {
        var vert = new Vector3(currentMesh.vertices[vertIndex * 3], currentMesh.vertices[vertIndex * 3 + 1], currentMesh.vertices[vertIndex * 3 + 2]);

        min.X = MathF.Min(min.X, vert.X);
        min.Y = MathF.Min(min.Y, vert.Y);
        min.Z = MathF.Min(min.Z, vert.Z);

        max.X = MathF.Max(max.X, vert.X);
        max.Y = MathF.Max(max.Y, vert.Y);
        max.Z = MathF.Max(max.Z, vert.Z);
      }
    }

    // store on object

    var corners = new Vector3[] {
        new Vector3(min.X, max.Y, max.Z),
        new Vector3(max.X, max.Y, max.Z),
        new Vector3(max.X, min.Y, max.Z),
        new Vector3(min.X, min.Y, max.Z),
        new Vector3(min.X, max.Y, min.Z),
        new Vector3(max.X, max.Y, min.Z),
        new Vector3(max.X, min.Y, min.Z),
        new Vector3(min.X, min.Y, min.Z)
    };

Then in the game update loop post transformations, I update the gameObjects bounding box by applying all of the objects transformations to the set of corners and retake the extremes to create my bounding box.

    var min = new Vector3(float.PositiveInfinity);
    var max = new Vector3(float.NegativeInfinity);

    for (var i = 0; i < gameObject.corners.Count(); i++)
    {
      var c = corners[i];
      ApplyTransformation(ref c, gameObject.rotation, gameObject.scale, gameObject.position);

      min.X = MathF.Min(min.X, c.X);
      min.Y = MathF.Min(min.Y, c.Y);
      min.Z = MathF.Min(min.Z, c.Z);

      max.X = MathF.Max(max.X, c.X);
      max.Y = MathF.Max(max.Y, c.Y);
      max.Z = MathF.Max(max.Z, c.Z);
    }
    
    var BB = new BoundingBox(min, max);

Is this the right thing to do? Or am I going down the wrong path

There are fancy versions that compile down to non-branching conditional assignments, but what you wrote looks functional.

It can grow because you are taking the bounds of an already bounded box, which can be troublesome in some scenarios. Something long and skinny (e.g. a pencil) can end up diagonally on the first pass making a large box, and rotated diagonally again in the second making a much bigger box even though the final AABB should be quite small in 2 dimensions. If this matters to your situation you may want to look at alternatives. It often does not matter, but sometimes is quite significant.

This topic is closed to new replies.

Advertisement