Skip to content

Commit

Permalink
skeleton bounding boxes: only compute the bone bounding radius if it …
Browse files Browse the repository at this point in the history
…is needed by an entity (lazy evaluation)
  • Loading branch information
lunkhound committed Nov 18, 2013
1 parent 2babdad commit 3502890
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 12 deletions.
4 changes: 1 addition & 3 deletions OgreMain/include/OgreEntity.h
Expand Up @@ -872,9 +872,7 @@ namespace Ogre {
Also the resulting bounding box will be expanded by the amount of GetMesh()->getBoneBoundingRadius().
The expansion amount can be changed on the mesh to achieve a better fitting bounding box.
*/
void setUpdateBoundingBoxFromSkeleton(bool update) {
mUpdateBoundingBoxFromSkeleton = update;
}
void setUpdateBoundingBoxFromSkeleton(bool update);

/** If true, the skeleton of the entity will be used to update the bounding box for culling.
Useful if you have skeletal animations that move the bones away from the root. Otherwise, the
Expand Down
11 changes: 8 additions & 3 deletions OgreMain/include/OgreMesh.h
Expand Up @@ -216,7 +216,6 @@ namespace Ogre {

void mergeAdjacentTexcoords( unsigned short finalTexCoordSet,
unsigned short texCoordSetToDestroy, VertexData *vertexData );
void computeBoneBoundingRadius();


public:
Expand Down Expand Up @@ -367,11 +366,17 @@ namespace Ogre {

/** Manually set the bone bounding radius.
@remarks
This value is computed automatically when the mesh is loaded, however it can
be overriden with this method.
This value is normally computed automatically, however it can be overriden with this method.
*/
void _setBoneBoundingRadius(Real radius);

/** Compute the bone bounding radius by looking at the vertices, vertex-bone-assignments, and skeleton bind pose.
@remarks
This is automatically called by Entity if necessary. Only does something if the boneBoundingRadius is zero to
begin with. Only works if vertex data is readable (i.e. not WRITE_ONLY).
*/
void _computeBoneBoundingRadius();

/** Automatically update the bounding radius and bounding box for this Mesh.
@remarks
Calling this method is required when building manual meshes. However it is recommended to
Expand Down
14 changes: 14 additions & 0 deletions OgreMain/src/OgreEntity.cpp
Expand Up @@ -171,6 +171,11 @@ namespace Ogre {
{
mSkeletonInstance = OGRE_NEW SkeletonInstance(mMesh->getSkeleton());
mSkeletonInstance->load();
// if mUpdateBoundingBoxFromSkeleton was turned on before the mesh was loaded, and mesh hasn't computed the boneBoundingRadius yet,
if ( mUpdateBoundingBoxFromSkeleton && mMesh->getBoneBoundingRadius() == Real(0))
{
mMesh->_computeBoneBoundingRadius();
}
}

// Build main subentity list
Expand Down Expand Up @@ -505,6 +510,15 @@ namespace Ogre {
}
}
//-----------------------------------------------------------------------
void Entity::setUpdateBoundingBoxFromSkeleton(bool update)
{
mUpdateBoundingBoxFromSkeleton = update;
if (mMesh->isLoaded() && mMesh->getBoneBoundingRadius() == Real(0))
{
mMesh->_computeBoneBoundingRadius();
}
}
//-----------------------------------------------------------------------
const AxisAlignedBox& Entity::getBoundingBox(void) const
{
if (mMesh->isLoaded())
Expand Down
11 changes: 5 additions & 6 deletions OgreMain/src/OgreMesh.cpp
Expand Up @@ -561,7 +561,6 @@ namespace Ogre {
// Take the opportunity to update the compiled bone assignments
_updateCompiledBoneAssignments();

computeBoneBoundingRadius();
}

// Animation states for vertex animation
Expand Down Expand Up @@ -905,7 +904,7 @@ namespace Ogre {
return pt.distance( onLine );
}
//---------------------------------------------------------------------
Real _computeBoneBoundingRadius( VertexData* vertexData,
Real _computeBoneBoundingRadiusHelper( VertexData* vertexData,
const Mesh::VertexBoneAssignmentList& boneAssignments,
const vector<Vector3>::type& bonePositions,
const vector< vector<ushort>::type >::type& boneChildren
Expand Down Expand Up @@ -966,9 +965,9 @@ namespace Ogre {
return maxRadius;
}
//---------------------------------------------------------------------
void Mesh::computeBoneBoundingRadius()
void Mesh::_computeBoneBoundingRadius()
{
if (mBoneBoundingRadius == Real(0))
if (mBoneBoundingRadius == Real(0) && ! mSkeleton.isNull())
{
Real radius = Real(0);
vector<Vector3>::type bonePositions;
Expand Down Expand Up @@ -996,7 +995,7 @@ namespace Ogre {
if (sharedVertexData)
{
// check shared vertices
radius = _computeBoneBoundingRadius(sharedVertexData, mBoneAssignments, bonePositions, boneChildren);
radius = _computeBoneBoundingRadiusHelper(sharedVertexData, mBoneAssignments, bonePositions, boneChildren);
}

// check submesh vertices
Expand All @@ -1008,7 +1007,7 @@ namespace Ogre {
SubMesh* submesh = *itor;
if (!submesh->useSharedVertices && submesh->vertexData)
{
Real r = _computeBoneBoundingRadius(submesh->vertexData, submesh->mBoneAssignments, bonePositions, boneChildren);
Real r = _computeBoneBoundingRadiusHelper(submesh->vertexData, submesh->mBoneAssignments, bonePositions, boneChildren);
radius = std::max( radius, r );
}
++itor;
Expand Down

0 comments on commit 3502890

Please sign in to comment.