Skip to main content
GameDev.net gamedev.net
🔒 Locked

aabb - obb

Started by Vexator Jan 18, 2007 at 5:27 AM 4 replies 8.1k views
Original Post
Vexator
Vexator
so far i'm using axis aligned bounding boxes to check if geometry is in the view frustum. for geometry that can be rotated i simply recalculate the box each time. that's slow, so i guess i should use obb for such geometry instead. could someone point me to a good article/tutorial that explains how to implement obb's? i suck at maths. thanks! :)
Wunderwerk Engine is an OpenGL-based, shader-driven, cross-platform game engine. It is targeted at aspiring game designers who have been kept from realizing their ideas due to lacking programming skills.

blog.wunderwerk-engine.com
Zakwayda
Zakwayda
Quote:
Original post by Vexator
for geometry that can be rotated i simply recalculate the box each time. that's slow, so i guess i should use obb for such geometry instead.
Or, you could size the AABB such that it fully contains the object in any orientation. The AABB will of course not be as good of a fit, but that may be offset by the low cost of AABB culling.
Quote:
could someone point me to a good article/tutorial that explains how to implement obb's?
What aspect do you need help with?

An OBB is generally represented as a coordinate system (center and three orthonormal basis vectors), and the half-extents in each dimension. To find the half-extents, just compute an AABB in the object's local space; the coordinate system for the OBB can then be extracted from the object transform at any given time.

This assumes that the AABB as computed in local space is more or less optimal. If the object is, say, a pipe that is not axis aligned in local space, then the resulting AABB (and therefore OBB) will be a poor fit. In this case there are other methods of computing a tight-fitting OBB, but these are considerably more complicated to implement. The local-space AABB method should probably be preferred unless the resulting OBB is a particularly poor fit.

OBB culling is similar to AABB culling in that you compare the distance from the box center to the plane to the box's 'radius' as projected onto the plane normal. AABB/plane culling is actually just a special case of OBB culling that can be optimized due to the axis alignment.
Vexator
Vexator
ok wait.
so i have a class BoundingBox with the following members:

Vector3D m_kMinimum; // minimum x, y, z extentsVector3D m_kMaximum; // maximum x, y, z extentsVector3D m_kTranslation; // positionVector3D GetPositiveVertex( Vector3D &normal ); // computes positive vertexVector3D GetNegativeVertex( Vector3D &normal ); // computes negative vertex


this is how i check if a box is in the frustum:

int Frustum::TestIntersection( BoundingBox *box ){	int iResult = TEST_INSIDE;	for( unsigned int i = 0; i < 6; i++ )	{		Vector3D kNormal = Vector3D( m_akPlanes.x, m_akPlanes.y, m_akPlanes.z );		if( m_akPlanes.GetDistance(box->GetPositiveVertex(kNormal)) < 0.0f )			return TEST_OUTSIDE;		if( m_akPlanes.GetDistance(box->GetNegativeVertex(kNormal)) < 0.0f )			iResult =  TEST_INTERSECT;	}		return iResult; }


this is working fine.. so how can i adopt this for obb now? (i told you i suck at maths :)
Wunderwerk Engine is an OpenGL-based, shader-driven, cross-platform game engine. It is targeted at aspiring game designers who have been kept from realizing their ideas due to lacking programming skills.

blog.wunderwerk-engine.com
Zakwayda
Zakwayda
Quote:
Original post by Vexator
this is working fine.. so how can i adopt this for obb now? (i told you i suck at maths :)
The first step is to use a different algorithm for your AABB culling - the one you're using works, but is unnecessarily complex.

Actually, the real first step is to write the OBB version and then specialize it for AABBs.

The key support function you need is a function that computes the projected radius of an oriented box onto an axis:
float OBB::ProjectedRadius(const Vector3& axis){    return        std::fabs(dot(m_axes[0], axis)) * m_extents[0] +        std::fabs(dot(m_axes[1], axis)) * m_extents[1] +        std::fabs(dot(m_axes[2], axis)) * m_extents[2];}
The plane test then proceeds as follows:
int TestOBBPlane(const OBB& box, const Plane& plane){    float distance = dot(box.center, plane.normal) - plane.distance;    float radius = box.ProjectedRadius(plane.normal);    if (distance < -radius) {        return TEST_OUTSIDE;    } else if (distance > radius) {        return TEST_INSIDE;    } else {        return TEST_INTERSECT;    }}
For the AABB test, just substitute the cardinal basis vectors for m_axes, eliminate all the unnecessary operations, and you should be left with:
float AABB::ProjectedRadius(const Vector3& axis){    return        std::fabs(axis[0])) * m_extents[0] +        std::fabs(axis[1])) * m_extents[1] +        std::fabs(axis[2])) * m_extents[2];}
None of the above has been compiled or tested, but it should be close to correct.
Vexator
Vexator
oha..! two remaining stupid questions:

- three three-component axes to define a rotation? how do i get these from a quaternion?
- can i also get this working if i have two different extents, maximum and minimum?

thanks so far! :D
Wunderwerk Engine is an OpenGL-based, shader-driven, cross-platform game engine. It is targeted at aspiring game designers who have been kept from realizing their ideas due to lacking programming skills.

blog.wunderwerk-engine.com
Zakwayda
Zakwayda
Quote:
- three three-component axes to define a rotation? how do i get these from a quaternion?
The three axes form an orthonormal basis (three mutually perpendicular unit-length vectors), which is one way to represent a rotation in 3D.

These vectors form the rows or columns (depending on convention) of the 3x3 matrix that represents the same rotation, so all you need to do is convert your quaternion to a matrix and extract the basis vectors directly.
Quote:
- can i also get this working if i have two different extents, maximum and minimum?
I'm not sure how you're using the terms minimum and maximum here, but in a typical AABB representation these refer to the two corners of the AABB representing the minimum and maximum projections onto each cardinal axis. Here's how to convert back and forth between the min/max and center/extents representations:
// Min/max to center/extents:Vector3 center = (max + min) * 0.5f;Vector3 extents = (max - min) * 0.5f;// Center/extents to min/max:Vector3 min = center - extents;Vector3 max = center + extents;

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.