Although it's fairly easy to add MeshBuffers to an ISkinnedMesh, it is somewhat more difficult to remove them. Over the past couple of weeks I tried numerous approaches to removing a MeshBuffer, and I learned a lot about how ISkinnedMeshes work and such, but it was a bit of a pain to get it working. Anyway, here's some code that removes a mesh buffer
Code: Select all
IAnimatedMesh* referenceMesh = sceneManager->getMesh("oricon.b3d");
assert(referenceMesh);
ISkinnedMesh* skinnedMesh = (ISkinnedMesh*)referenceMesh;
//in this particular example, we can use numbers from 0 to 9
u32 meshBufferNum = 9;
skinnedMesh->getMeshBuffers().erase(meshBufferNum);
/*loop through all of the weights in all of the joints and if the weight's
buffer_id is referencing the meshBufferNum we've chosen, eliminate the weight*/
for(u32 i=0; i<skinnedMesh->getAllJoints().size(); ++i)
{
for(u32 x=0; x<skinnedMesh->getAllJoints()[i]->Weights.size(); ++x)
{
if(skinnedMesh->getAllJoints()[i]->Weights[x].buffer_id==meshBufferNum)
{
skinnedMesh->getAllJoints()[i]->Weights.erase(x);
--x;
}
}
}
/*we need to loop through all of the weights and decrease their buffer_id if they come after the buffer_id we removed*/
for(u32 i=0; i<skinnedMesh->getAllJoints().size(); ++i)
{
for(u32 x=0; x<skinnedMesh->getAllJoints()[i]->Weights.size(); ++x)
{
if(skinnedMesh->getAllJoints()[i]->Weights[x].buffer_id > meshBufferNum)
{
skinnedMesh->getAllJoints()[i]->Weights[x].buffer_id--;
}
}
}
After figuring out what number our MeshBuffer is, we then loop through all of the weights in the mesh and remove the weights that apply to the MeshBuffer we removed.
Next, we cycle through the remaining weights and decrease the buffer_id of of any weight that came after the weights we removed. Why must we do this? Well, if there were five MeshBuffers and we removed the third one, then you'd still have weights pointing to MeshBuffer number five (which is now number four), etc.
And....that's it!
Here's the effect in action:
Hope this helps someone
-wyrmmage