btSoftBodyHelpers::CreateFromTriMesh - Ogre version?

JayAr
Posts: 9
Joined: Tue Nov 02, 2010 1:28 pm

Re: btSoftBodyHelpers::CreateFromTriMesh - Ogre version?

Post by JayAr »

Inside BtOgreSoftBody::create(...) I just changed the "btSoftBodyHelpers::CreateFromTriMesh(...)"-part to a "btSoftBodyHelpers::CreatePatch()" part. I made a 8*3 patch, and a mesh in Maya with 8*3 vertices.
It works, but the vertices of the mesh are in completely wrong places now, so I see the patch, and the geometry is there, but the vertices are completely wrong. I dont know how to solve this, maybe change the texture coordinates in the original mesh. Since the mesh is not too complicated this could work.
JayAr
Posts: 9
Joined: Tue Nov 02, 2010 1:28 pm

Re: btSoftBodyHelpers::CreateFromTriMesh - Ogre version?

Post by JayAr »

Ok, it works now. I had to change the texture coordinates and the pointers to the polygons inside the mesh file with OgreXMLConverter.

Image
JayAr
Posts: 9
Joined: Tue Nov 02, 2010 1:28 pm

Re: btSoftBodyHelpers::CreateFromTriMesh - Ogre version?

Post by JayAr »

Has anybody ever made more than one Softbody?
If I make more than one, I see both Softbodies with the Debug Drawer, but I see only one Geometry from the mesh... It always shows only the Geometry for which I called the function mSoftBody->updateOgreMesh() the last time in the frame Started Method. If change the order, than I see the other Geometry, but not the one which was shown the last time.

I really dont get why this happens, I checked all the functions and I cant find the error. I thought maybe the Softbodies Geometry somehow use the same SceneNode, but this is not the case when I debug. So there are different SceneNodes, different Entities, different OgreSoftbodies, so actually it should work, but it shows only one Mesh.

Also the funtion updateOgreMeshes() didn't help.
Lord_Tirion
Posts: 2
Joined: Wed Oct 26, 2011 4:24 pm

Re: btSoftBodyHelpers::CreateFromTriMesh - Ogre version?

Post by Lord_Tirion »

I'm probably wrong (I don't really have a lot of time using either OGRE or Bullet) but I suppose it has to do that entities manage mesh pointers... so I suppose that there is only one mesh that is being modified and used by all the entities, maybe it would be better to make a copy to be used only by that entity alone.

Now I have a question of my own, right now I have to make a soft body from a Ogre model that comes from a .STL and I need to use anchors to fix to a rigid body (unless I'm doing something stupid like I've doing in the last month of trying to solve issues that were already solved) but I have no idea of how to chose the nodes, I suppose the nodes are the vertices of the soft model but I can't think of how are the nodes defined in the model in Ogre. ¿is there a way to know what node to choose from the model?
StrakeFengala
Posts: 3
Joined: Fri Oct 28, 2011 2:47 am

Re: btSoftBodyHelpers::CreateFromTriMesh - Ogre version?

Post by StrakeFengala »

Greetings,

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

Code: Select all

btSoftBody*	psb = Globals::softBody->create(ogreMeshEntity, 
	MyMeshData.vertexCount, 
	MyMeshData.vertices,
	MyMeshData.triangleCount*3,
	(unsigned int*)indices);
to instead iterate through each index and convert from (unsigned long) to (unsigned int) and then it worked properly

Code: Select all

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:

Code: Select all

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.
Lord_Tirion
Posts: 2
Joined: Wed Oct 26, 2011 4:24 pm

Re: btSoftBodyHelpers::CreateFromTriMesh - Ogre version?

Post by Lord_Tirion »

Thanks a lot, right now I'm focusing on something that came up (more evidence that I don't know how to use this... pretty much most of my work is useless...) but once I can test it I'll tell you if it worked
OSasuke
Posts: 47
Joined: Tue Dec 09, 2008 10:12 am

Re: btSoftBodyHelpers::CreateFromTriMesh - Ogre version?

Post by OSasuke »

This is my code :

Code: Select all

// When Retreive vertex and index data do this :

            ///...........
            for(int j = 0; j < vertex_data->vertexCount; ++j, vertex += vbuf->getVertexSize())
            {
                posElem->baseVertexPointerToElement(vertex, &pReal);
                //std::vector<float*> m_vdata; is a member of the class
                m_vdata.push_back(&pReal[0]);
                m_vdata.push_back(&pReal[1]);
                m_vdata.push_back(&pReal[2]);
                bvertices.push_back(btVector3(pReal[0], pReal[1], pReal[2]));
            }
            //...............

    m_p = new btSoftBody(&world->getWorldInfo(), vertex_count, &bvertices[0], 0);

    for(int i=0; i<index_count; i+=3)
    {
        m_p->appendLink(indices[i], indices[i+1]);
        m_p->appendLink(indices[i+1], indices[i+2]);
        m_p->appendLink(indices[i], indices[i+2]);
        m_p->appendFace(indices[i+0],indices[i+1],indices[i+2]);
    }

	m_p->setTotalMass(mass, true);
And updating the vertex data like this :

Code: Select all

// Claculating SoftBody shape center :
    btVector3 aabbMin, aabbMax, pos;
    m_soft->getAabb(aabbMin, aabbMax);
    pos = aabbMin+aabbMax;
    pos *= 0.5f;
    m_sceneNode->setPosition(pos.x(), pos.y(), pos.z());

    // updating vertex data
    Ogre::Mesh* mesh=m_entity->getMesh().getPointer();
    for(int i = 0;i < mesh->getNumSubMeshes();i++)
    {
        SubMesh* submesh = mesh->getSubMesh(i);
        Ogre::VertexData* vertex_data = submesh->useSharedVertices ? mesh->sharedVertexData : submesh->vertexData;
        if(!submesh->useSharedVertices)
        {
            const Ogre::VertexElement* posElem = vertex_data->vertexDeclaration->findElementBySemantic(Ogre::VES_POSITION);
            Ogre::HardwareVertexBufferSharedPtr vbuf = vertex_data->vertexBufferBinding->getBuffer(posElem->getSource());
            unsigned char* vertex = static_cast<unsigned char*>(vbuf->lock(Ogre::HardwareBuffer::HBL_NORMAL));
        }
    }

    for(int i=0; i<m_p->m_nodes.size(); i++)
    {
        btVector3 np = m_p->m_nodes[i].m_x - pos;
        *m_vdata[i*3+0]=np.x();
        *m_vdata[i*3+1]=np.y();
        *m_vdata[i*3+2]=np.z();
    }

    for(int i = 0;i < mesh->getNumSubMeshes();i++)
    {
        SubMesh* submesh = mesh->getSubMesh(i);
        Ogre::VertexData* vertex_data = submesh->useSharedVertices ? mesh->sharedVertexData : submesh->vertexData;
        if(!submesh->useSharedVertices)
        {
            const Ogre::VertexElement* posElem = vertex_data->vertexDeclaration->findElementBySemantic(Ogre::VES_POSITION);
            Ogre::HardwareVertexBufferSharedPtr vbuf = vertex_data->vertexBufferBinding->getBuffer(posElem->getSource());
            vbuf->unlock();
        }
    }

    // updating the bounding box
    Ogre::AxisAlignedBox bounds(Util::toVector3(aabbMin), Util::toVector3(aabbMax));
    mesh->_setBounds(bounds);
@JayAr : You don't have problems with the ball passing through the softbody at high speed ?
billias13
Posts: 18
Joined: Thu Mar 22, 2012 9:29 am

Re: btSoftBodyHelpers::CreateFromTriMesh - Ogre version?

Post by billias13 »

Hello, thank you for this work, its trully very helpful for a quick start in soft bodies and ogre.
I have a question, did somebody figured out the problem with objects not showing properly (the lighting is not updated) when changing position-shape?
billias13
Posts: 18
Joined: Thu Mar 22, 2012 9:29 am

Re: btSoftBodyHelpers::CreateFromTriMesh - Ogre version?

Post by billias13 »

anyone?