[fixed]correct BoundingBox for SkinnedMesh
Posted: Tue Sep 30, 2008 12:58 pm
Hi,
problem was in incorret calculatiing boundingbox. I think I solved this problem, in CSkinnedMesh.cpp:
diffrient is location of this code and transforming local boundingbox. can be it commit on svn?
problem was in incorret calculatiing boundingbox. I think I solved this problem, in CSkinnedMesh.cpp:
Code: Select all
void CSkinnedMesh::finalize()
{
u32 i;
LastAnimatedFrame=-1;
LastSkinnedFrame=-1;
//calculate bounding box
for (i=0; i<LocalBuffers.size(); ++i)
{
LocalBuffers[i]->recalculateBoundingBox();
}
if (AllJoints.size() || RootJoints.size())
{
// populate AllJoints or RootJoints, depending on which is empty
if (!RootJoints.size())
{
for(u32 CheckingIdx=0; CheckingIdx < AllJoints.size(); ++CheckingIdx)
{
bool foundParent=false;
for(i=0; i < AllJoints.size(); ++i)
{
for(u32 n=0; n < AllJoints[i]->Children.size(); ++n)
{
if (AllJoints[i]->Children[n] == AllJoints[CheckingIdx])
foundParent=true;
}
}
if (!foundParent)
RootJoints.push_back(AllJoints[CheckingIdx]);
}
}
else
{
AllJoints=RootJoints;
}
}
for(i=0; i < AllJoints.size(); ++i)
{
AllJoints[i]->UseAnimationFrom=AllJoints[i];
}
//Set array sizes...
for (i=0; i<LocalBuffers.size(); ++i)
{
Vertices_Moved.push_back( core::array<bool>() );
Vertices_Moved[i].set_used(LocalBuffers[i]->getVertexCount());
}
//Todo: optimise keys here...
checkForAnimation();
if (HasAnimation)
{
//--- optimize and check keyframes ---
for(i=0;i<AllJoints.size();++i)
{
core::array<SPositionKey> &PositionKeys =AllJoints[i]->PositionKeys;
core::array<SScaleKey> &ScaleKeys = AllJoints[i]->ScaleKeys;
core::array<SRotationKey> &RotationKeys = AllJoints[i]->RotationKeys;
if (PositionKeys.size()>2)
{
for(u32 j=0;j<PositionKeys.size()-2;++j)
{
if (PositionKeys[j].position == PositionKeys[j+1].position && PositionKeys[j+1].position == PositionKeys[j+2].position)
{
PositionKeys.erase(j+1); //the middle key is unneeded
--j;
}
}
}
if (PositionKeys.size()>1)
{
for(u32 j=0;j<PositionKeys.size()-1;++j)
{
if (PositionKeys[j].frame >= PositionKeys[j+1].frame) //bad frame, unneed and may cause problems
{
PositionKeys.erase(j+1);
--j;
}
}
}
if (ScaleKeys.size()>2)
{
for(u32 j=0;j<ScaleKeys.size()-2;++j)
{
if (ScaleKeys[j].scale == ScaleKeys[j+1].scale && ScaleKeys[j+1].scale == ScaleKeys[j+2].scale)
{
ScaleKeys.erase(j+1); //the middle key is unneeded
--j;
}
}
}
if (ScaleKeys.size()>1)
{
for(u32 j=0;j<ScaleKeys.size()-1;++j)
{
if (ScaleKeys[j].frame >= ScaleKeys[j+1].frame) //bad frame, unneed and may cause problems
{
ScaleKeys.erase(j+1);
--j;
}
}
}
if (RotationKeys.size()>2)
{
for(u32 j=0;j<RotationKeys.size()-2;++j)
{
if (RotationKeys[j].rotation == RotationKeys[j+1].rotation && RotationKeys[j+1].rotation == RotationKeys[j+2].rotation)
{
RotationKeys.erase(j+1); //the middle key is unneeded
--j;
}
}
}
if (RotationKeys.size()>1)
{
for(u32 j=0;j<RotationKeys.size()-1;++j)
{
if (RotationKeys[j].frame >= RotationKeys[j+1].frame) //bad frame, unneed and may cause problems
{
RotationKeys.erase(j+1);
--j;
}
}
}
//Fill empty keyframe areas
if (PositionKeys.size())
{
SPositionKey *Key;
Key=&PositionKeys[0];//getFirst
if (Key->frame!=0)
{
PositionKeys.push_front(*Key);
Key=&PositionKeys[0];//getFirst
Key->frame=0;
}
Key=&PositionKeys.getLast();
if (Key->frame!=AnimationFrames)
{
PositionKeys.push_back(*Key);
Key=&PositionKeys.getLast();
Key->frame=AnimationFrames;
}
}
if (ScaleKeys.size())
{
SScaleKey *Key;
Key=&ScaleKeys[0];//getFirst
if (Key->frame!=0)
{
ScaleKeys.push_front(*Key);
Key=&ScaleKeys[0];//getFirst
Key->frame=0;
}
Key=&ScaleKeys.getLast();
if (Key->frame!=AnimationFrames)
{
ScaleKeys.push_back(*Key);
Key=&ScaleKeys.getLast();
Key->frame=AnimationFrames;
}
}
if (RotationKeys.size())
{
SRotationKey *Key;
Key=&RotationKeys[0];//getFirst
if (Key->frame!=0)
{
RotationKeys.push_front(*Key);
Key=&RotationKeys[0];//getFirst
Key->frame=0;
}
Key=&RotationKeys.getLast();
if (Key->frame!=AnimationFrames)
{
RotationKeys.push_back(*Key);
Key=&RotationKeys.getLast();
Key->frame=AnimationFrames;
}
}
}
}
//Needed for animation and skinning...
CalculateGlobalMatrices(0,0);
//animateMesh(0, 1);
//buildAll_LocalAnimatedMatrices();
//buildAll_GlobalAnimatedMatrices();
//rigid animation for non animated meshes
for (i=0; i<AllJoints.size(); ++i)
{
for (u32 j=0; j<AllJoints[i]->AttachedMeshes.size(); ++j)
{
SSkinMeshBuffer* Buffer=(*SkinningBuffers)[ AllJoints[i]->AttachedMeshes[j] ];
Buffer->Transformation=AllJoints[i]->GlobalAnimatedMatrix;
}
}
// Get BoundingBox...
if (LocalBuffers.empty())
BoundingBox.reset(0,0,0);
else
{
irr::core::aabbox3df bb(LocalBuffers[0]->BoundingBox);
LocalBuffers[0]->Transformation.transformBoxEx(bb);
BoundingBox.reset(bb);
for (u32 j=1; j<LocalBuffers.size(); ++j)
{
bb = LocalBuffers[j]->BoundingBox;
LocalBuffers[j]->Transformation.transformBoxEx(bb);
BoundingBox.addInternalBox(bb);
}
}
//add 5% padding to bounding box
core::vector3df Padding=BoundingBox.getExtent()*0.05f;
BoundingBox.MinEdge-=Padding;
BoundingBox.MaxEdge+=Padding;
}
Code: Select all
// Get BoundingBox...
if (LocalBuffers.empty())
BoundingBox.reset(0,0,0);
else
{
irr::core::aabbox3df bb(LocalBuffers[0]->BoundingBox);
LocalBuffers[0]->Transformation.transformBoxEx(bb);
BoundingBox.reset(bb);
for (u32 j=1; j<LocalBuffers.size(); ++j)
{
bb = LocalBuffers[j]->BoundingBox;
LocalBuffers[j]->Transformation.transformBoxEx(bb);
BoundingBox.addInternalBox(bb);
}
}