I am using linux x64 GCC and I would like to point out a bug that I encountered when trying to convert an ogre mesh to softbody using the create
function. Apparently my compiler didn't like it when you made the direct conversion between the dynamic arrays from (unsigned long*) to (unsigned int*), it always came out with wrong indices and it looked like half of the mesh was missing.
So in your example (main.cpp) I had to change
btSoftBody* psb = Globals::softBody->create(ogreMeshEntity,
to instead iterate through each index and convert from (unsigned long) to (unsigned int) and then it worked properly
unsigned int indexCount = MyMeshData.triangleCount * 3;
unsigned int* newindices = new unsigned int[indexCount];
for (int i = 0; i < indexCount; i++)
newindices[i] = (unsigned int) indices[i];
btSoftBody* psb = Globals::softBody->create(ogreMeshEntity, MyMeshData.vertexCount,
MyMeshData.vertices, indexCount, newindices);
I found another problem too, using the function updateOgreMesh()
it does not update the vertices if the mesh is bound to a skeleton. I have tried taking the skeleton off of the mesh and it works, I cannot find a workaround for this. I wonder about the possibility of using a pose animation but I am currently inexperienced in that area.
Also I think Lord_Tirion is right about mesh pointers. You can try using MeshPtr::clone
to copy the original mesh and build the entity off of the clone using the new mesh name but it note that it will take up more memory. I have not tested this yet since I have not had the need to make more than one entity of the same mesh so I cannot guarantee that this will work but I am pretty sure.
@Lord_Tirion: Regarding your question about finding nodes (if I understood correctly what you wanted), I created a function I use for my softbody controller class that finds all nodes within a boxed margin and anchors them to the rigid body specified in the parameter. Here is the function:
void BulletSoftBody::addAnchors( btRigidBody *pAnchorBody, Ogre::Vector3 pMarginPos, Ogre::Vector3 pMarginSize )
btVector3 lMarginPos = BtOgre::Convert::toBullet(pMarginPos);
btVector3 lMarginSize = BtOgre::Convert::toBullet(pMarginSize);
btVector3 lMinPos = lMarginPos - lMarginSize*0.5;
btVector3 lMaxPos = lMarginPos + lMarginSize*0.5;
for (int i = 0; i < psb->m_nodes.size(); i++)
if (TestPointAgainstAabb2( lMinPos, lMaxPos, mSB->m_nodes[i].m_x ))
psb->appendAnchor( i, pAnchorBody, true );
I hope this helps. NOTE that the boxed margin is in world space, not local softbody space, you will have to make sure you are putting the margin in the right place when adding anchors. Note also that it takes the current position of the nodes so make sure that you call this before the softbody starts moving. Also make sure to #include "bullet/LinearMath/btAabbUtil2.h"
if you use this.
If you have the need you can create a function to grab all of the nodes within a specific radius from a point (or just the closest one) if you know the positions of the vertices rather than using a margin box.