Removing MeshBuffers from an ISkinnedMesh

Post those lines of code you feel like sharing or find what you require for your project here; or simply use them as tutorials.
Post Reply
wyrmmage
Posts: 204
Joined: Sun Mar 16, 2008 3:12 am
Contact:

Removing MeshBuffers from an ISkinnedMesh

Post by wyrmmage »

Hello :)

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--;
         }
      }
   }
First, we have to find out what number our MeshBuffer is; currently you just have to guess and check, but I'm working a patch that will let you grab the MeshBuffer by its name, so I'll post back here when that's done :)

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:
ImageImage

Hope this helps someone :)
-wyrmmage
Worlds at War (Current Project) - http://www.awkward-games.com
Ganadu'r, The Eternal Sage (Other Current Project) - http://rpg.naget.com
fmx

Post by fmx »

quite interesting work.
not sure why this issue of mesh-buffer removal hasn't been brought up before, but its cool to know it'll be possible soon

looking forward to the patch :)
wyrmmage
Posts: 204
Joined: Sun Mar 16, 2008 3:12 am
Contact:

Post by wyrmmage »

Thanks :)

Actually, you don't have to patch Irrlicht at all to accomplish this, you just have to load a mesh with bones and then apply the above code; the patch I was talking about was a patch that will allow you to look up MeshBuffers by their names :)
-wyrmmage
Worlds at War (Current Project) - http://www.awkward-games.com
Ganadu'r, The Eternal Sage (Other Current Project) - http://rpg.naget.com
Post Reply