1

我使用 Bullet Physics,我需要复制该btTriangleMesh类型的一个实例。

// the variable is a class member
btTriangleMesh triangles;

我的目标是将身体的碰撞形状更改为新的三角形网格形状。这个形状应该保存当前存储在triangles变量中的数据,即使这个变量将来发生变化。因此我需要一个深拷贝。

// 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
// ...

我虽然在堆上实例化一个新变量new btTriangleMesh(triangles)会深度复制对象。但正如您在下图中所见,第一个物体的碰撞形状受到下一个物体的影响。

在图像中,白线代表碰撞形状,而您可以在下面看到实际所需的形状。这是第一具尸体的样子,这里一切都很好。

具有正确碰撞形状的单个块

这就是在右侧插入另一个身体后的样子。第一个身体的形状改变为与第二个身体的形状相同。那不应该发生。图像上可能不清楚,但在 3D 中,您肯定会看到第一个身体的形状发生了变化,与第二个身体完全匹配。

插入第二个块不必要地改变了第一个块的形状

如何深拷贝一个btTriangleMesh?还是我做错了什么?

顺便说一句,我对所有三角形都使用相同的变量作为源的原因是这个变量是由另一个线程异步填充的。

4

1 回答 1

0

我花了一些时间自己调查这个。

您可以通过访问其 getIndexedMeshArray[0] 来深度复制 btTriangleMesh

btTriangleMesh 不使用多个 btIndexedMesh。

使用 args (true, true) 构造所有 btTriangleMeshes,以强制索引和顶点数组分别为 Integer 和 btVector3 类型。

这是我编写的一些代码,用于从 btTriangleMesh 中提取三角形并将它们放入我自己的模型数据类 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)
}

我不得不在 Bullet 的源代码中四处挖掘以弄清楚如何做到这一点。

我是这样做的: 1) 查看 btTriangleMesh 的 cpp 文件并注意到它只使用了 m_IndexedMeshArray[0] 为了方便起见,这里是指向 pybullet 上的 CPP 文件参考的链接 https://pybullet.org/Bullet/BulletFull/btTriangleMesh_8cpp_source。 html

2)查找IndexedMeshArray typedef https://pybullet.org/Bullet/BulletFull/btTriangleIndexVertexArray_8h.html#ad682f0bb6b27957cb135e379beb73b54

3)我去了btIndexedMesh页面 https://pybullet.org/Bullet/BulletFull/structbtIndexedMesh.html

4)我查看了类型

5)我回到btTriangleMesh的cpp文件并逆向工程类。

子弹物理学的复杂程度严重不足。每个高级功能似乎都需要一个小时左右的挖掘才能弄清楚。

除了回答您的问题之外,希望这能让您了解如何继续使用项目符号。

于 2020-05-13T23:26:48.180 回答