Papervision BoundingBox Utility Class

I've been using this helper class alot lately so I thought I'd share it. I don't remember who posted it to the mailing list, but I can't take credit it for it myself.

It is very helpful to finding the size of a 3D object.

package
{
import org.papervision3d.core.geom.renderables.Vertex3D;
import org.papervision3d.objects.DisplayObject3D;

/**
* Utility class that calculates the bounding box dimensions of a Papervision DisplayObject3D
*/

public class BoundingBox
{
public var maxX :Number = 0;
public var minX :Number = 0;
public var maxY :Number = 0;
public var minY :Number = 0;
public var maxZ :Number = 0;
public var minZ :Number = 0;

public var sizeX :Number = 0;
public var sizeY :Number = 0;
public var sizeZ :Number = 0;

/**
* Constructor.
*
* @param object The DisplayObject3D instance for which you want to calculate the bounding box
*/
public function BoundingBox( object:DisplayObject3D )
{
parseMesh( object );

sizeX = maxX - minX;
sizeY = maxY - minY;
sizeZ = maxZ - minZ;
}

/*
Here is where we make the doughnuts...
Recursively, we cycle through all objects and child objects, loop
through each of their vertices and storing the max of each dimension
*/
private function parseMesh(object:DisplayObject3D):void
{
if (object.children)
for each(var child:DisplayObject3D in object.children)
parseMesh(child);

if ( !object.geometry)
return;

for each(var vertex:Vertex3D in object.geometry.vertices)
{
maxX = Math.max(maxX, vertex.x);
minX = Math.min(minX, vertex.x);
maxY = Math.max(maxY, vertex.y);
minY = Math.min(minY, vertex.y);
maxZ = Math.max(maxZ, vertex.z);
minZ = Math.min(minZ, vertex.z);
}
}
}
}

Comments

CodeJockey said…
OK, Andy Zupko suggested to use geometry.boundingBox() instead. I haven't tried it out yet but when I do I'll post an update here.
Unknown said…
I have not had any luck using boundingBox after loading a dae. but your code returns the dimensions very nicely. Thanks for this!
Norel said…
Thank you for this code !
A boundingBox is very useful indeed.

It works fine, although on some loaded objects, the axis seem swapped. (Ex. the resulting boundingbox has the right size, but is sometimes facing the wrong axis.)
I feel the answer is very close ;)
xcx said…
Thanks man! This is great function. However I noticed that it didn't worked properly in my case so I made little fixes to it. Here's new version.
Old version what you made didn't work if inner DisplayObjects were moved.

package
{
import flash.display.DisplayObject;
import org.papervision3d.core.geom.renderables.Vertex3D;
import org.papervision3d.core.math.Number3D;
import org.papervision3d.objects.DisplayObject3D;
import org.papervision3d.core.math.Matrix3D;

/**
* Utility class that calculates the bounding box dimensions of a Papervision DisplayObject3D
*/

public class BoundingBox
{
public var maxX :Number = 0;
public var minX :Number = 0;
public var maxY :Number = 0;
public var minY :Number = 0;
public var maxZ :Number = 0;
public var minZ :Number = 0;

public var sizeX :Number = 0;
public var sizeY :Number = 0;
public var sizeZ :Number = 0;

/**
* Constructor.
*
* @param object The DisplayObject3D instance for which you want to calculate the bounding box
*/
public function BoundingBox( object:DisplayObject3D )
{
parseMesh( object, new Number3D());

sizeX = maxX - minX;
sizeY = maxY - minY;
sizeZ = maxZ - minZ;
}

/*
Here is where we make the doughnuts...
Recursively, we cycle through all objects and child objects, loop
through each of their vertices and storing the max of each dimension
*/
private function parseMesh(obj:DisplayObject3D, pos:Number3D):void
{
if (obj.children)
{
for each( var child:* in obj.children )
{
var n:Number3D = new Number3D(
pos.x + obj.x,
pos.y + obj.y,
pos.z + obj.z);
parseMesh( child, n );
}
}

if (obj.geometry)
{
for each(var vertex:Vertex3D in obj.geometry.vertices)
{
var vx:Number = pos.x + vertex.x;
var vy:Number = pos.y + vertex.y;
var vz:Number = pos.z + vertex.z;

maxX = Math.max(maxX, vx);
minX = Math.min(minX, vx);
maxY = Math.max(maxY, vy);
minY = Math.min(minY, vy);
maxZ = Math.max(maxZ, vz);
minZ = Math.min(minZ, vz);
}
}
}
}
}
xcx said…
Actully my version might be incorrect as well :). It is only intrested about position, but DisplayObjects can be rotated when values would be different.
Wilson Silva said…
It worked for what I needed, thanks.

Popular Posts