Reputation: 34215
I use Bullet Physics and I need to copy an instance of the btTriangleMesh
type.
// the variable is a class member
btTriangleMesh triangles;
My aim is to change the collision shape of a body to a new triangle mesh shape. This shape should hold the data currently stored in the triangles
variable, even if this variable changes in future. Therefore I need a deep copy.
// in a method change collision shape
btTriangleMesh *copy = new btTriangleMesh(triangles);
btBvhTriangleMeshShape *shape = new btBvhTriangleMeshShape(copy), true, true);
body->setCollisionShape(shape);
// after that, reset variable
triangles = btTriangleMesh();
// change content of variable for next body
// ...
I though instancing a new variable on the heap new btTriangleMesh(triangles)
would deep copy the object. But as you can see in the images below, the collision shape of the first body is affected by the next one.
In the image, the white lines represent the collision shape whereas you can see the actual desired shape rendered underneath. This is how the first body looks like, everything is fine here.
And this is how it looks after inserting another body on the right side. The shape of the first body changed to equal the one of the second body. That shouldn't happen. It might be not clear on the image but in 3D you definitely see that the shape of the first body changed to exactly match the one of the second.
How to deep copy a btTriangleMesh
? Or am I doing anything else wrong?
By the way the reason for the fact that I use the same variable as source for all triangle shapes is that this variable is filled asynchronously by another thread.
Upvotes: 1
Views: 961
Reputation: 3
I spent some time investigating this myself.
You can deep copy a btTriangleMesh by accessing its getIndexedMeshArray[0]
btTriangleMesh doesn't use more than one btIndexedMesh.
Construct all your btTriangleMeshes with args (true, true) to force the index and vertex arrays to be Integer and btVector3 types, respectively.
Here's some code I wrote to extract the triangles from a btTriangleMesh and put them into my own model data class, IndexedModel.
IndexedModel retrieveIndexedModelFromTriMesh(btTriangleMesh* trimesh){
IndexedModel retval;
//We will assume it was created using true, true
btIndexedMesh& mushy = trimesh->getIndexedMeshArray()[0]; //typedef btAlignedObjectArray< btIndexedMesh > IndexedMeshArray
size_t numVerts = mushy.m_numVertices;
size_t numTris = mushy.m_numTriangles;
size_t numIndices = numTris * 3;
PHY_ScalarType indexType = mushy.m_indexType;
PHY_ScalarType vertexType = mushy.m_vertexType;
if(indexType != PHY_INTEGER)
return getErrorShape("Error, tri mesh was apparently made using Short indices");
btVector3* vertArray = (btVector3*)mushy.m_vertexBase;
int* indArray = (int*)mushy.m_triangleIndexBase;
for(size_t i = 0; i < numIndices; i++){
retval.indices.push_back(retval.positions.size());
glm::vec3 pos = b2g_vec3(vertArray[indArray[i]]);
retval.positions.push_back(pos);
}
retval.validate(); //fills in texcoords and normals for exporting to OBJ
return retval;
//Vertex Stride is sizeof(btVector3)
//Index stride is sizeof(int) * 3 (per triangle, of course)
}
I had to dig around in Bullet's source code to figure out how to do this.
Here's how I did it: 1) Looked at btTriangleMesh's cpp file and noticed that it only used m_IndexedMeshArray[0] Here is a link to the CPP file reference on pybullet for convenience https://pybullet.org/Bullet/BulletFull/btTriangleMesh_8cpp_source.html
2) Looked up the IndexedMeshArray typedef https://pybullet.org/Bullet/BulletFull/btTriangleIndexVertexArray_8h.html#ad682f0bb6b27957cb135e379beb73b54
3) I went to the btIndexedMesh page https://pybullet.org/Bullet/BulletFull/structbtIndexedMesh.html
4) I looked at the types
5) I went back to btTriangleMesh's cpp file and reverse-engineered the class.
Bullet physics is disastrously under-documented for how complex it is. Every advanced functionality seems to require an hour or so of digging to figure out.
Hopefully this gives you an idea of how to proceed with bullet in addition to answering your question.
Upvotes: 0