Tracing all the process, the skinning works properly, but the update of the bone nodes doesn't happen correctly on the EJUOR_CONTROL skinned meshes. Taking a peek to the code of the getMeshForCurrentFrame() method of the CAnimatedMeshSceneNode class, in the file CAnimatedMeshSceneNode.cpp, in the source directory, there is a conditional that is executed when the mode is EJUOR_READ:
Code: Select all
if (JointMode == EJUOR_READ)//read from mesh
{
skinnedMesh->recoverJointsFromMesh(JointChildSceneNodes);
//---slow---
for (u32 n=0;n<JointChildSceneNodes.size();++n)
if (JointChildSceneNodes[n]->getParent()==this)
{
JointChildSceneNodes[n]->updateAbsolutePositionOfAllChildren(); //temp, should be an option
}
}
Code: Select all
if(JointMode == EJUOR_CONTROL)
{
// For meshes other than EJUOR_CONTROL, this is done by calling animateMesh()
skinnedMesh->updateBoundingBox();
}
Adding that same code to the EJUOR_CONTROL conditional solves this, and, although it is marked as slow and temporary, it is also convenient, The function updateAbsolutePositionOfAllChildren() doesn't diference nodes, and thus the childs (bones or not) are updated correctly, and their rendering happens on the expected place, instead of the place that they had been the previous frame.
Code: Select all
if(JointMode == EJUOR_CONTROL)
{
// For meshes other than EJUOR_CONTROL, this is done by calling animateMesh()
//---slow---
for (u32 n=0;n<JointChildSceneNodes.size();++n)
if (JointChildSceneNodes[n]->getParent()==this)
{
JointChildSceneNodes[n]->updateAbsolutePositionOfAllChildren(); //temp, should be an option
}
skinnedMesh->updateBoundingBox();
}
For the Skinned meshes, maybe their children nodes should be rendered BEFORE the skinned node because this would force the nodes to update, and maybe the scene traverse wouldn't suffer much, because this can be done locally in the skinned mesh node scope, and when the regular flow of the scene traverse wouldn't be affected too much.