Mesh classes

Mesh classes

Pierre T.'s picture

Hi,

I'm getting confused by all the different mesh classes.... I have two basic questions:

a) What is the "best", or recommended mesh class, for a static game level (made of triangles only)? What is the difference between hkpBvCompressedMeshShape and hkpExtendedMeshShape/hkpMoppBvTreeShape? What are the pros & cons?

b) What possibility does Havok offer for dynamic meshes, if any?

Thanks,

- Pierre

5 posts / 0 new
Last post
For more complete information about compiler optimizations, see our Optimization Notice.
HavokTim's picture

Hi Pierre--

Havok supports several mesh classes in large part to maintain legacy support for clients that have adoped a particular API, while still allowing us to improve our interfaces and implementations. In general, a new user will get the best performance and memory characteristics using the newest shape that supports a particular use case. With respect to the mesh types you listed, hkpBvCompressedMeshShape is the best choice for static mesh - it compresses the mesh to optimize size, and automatically includes a high performance bounding volume hierarchy for fast queries. An hkpExtendedMeshShape, on the other hand, is useful if you want to share mesh data for both physics and renderin, but must be wrapped in a hierarchical structure to get good performance.

With respect to dynamic meshes, mesh vs. mesh collision is very expensive, but low-poly dynamic mesh objects can sometimes work. However, in most cases it's better to use convex shapes (or compound convex shapes) for dynamic objects. Our commercial package includes tools to automatically create convex decompositions of arbitrary objects, but you can perform this process manually as well. Can you describe your use case in more detail so I can provide more specific guidance. Thanks!

--Tim

Pierre T.'s picture

Hi Tim,

My bad, my question about dynamic meshes was misleading. I should have said "deformable meshes". I'm not talking about static-meshes-with-a-dynamic-transform, but rather about dynamic-meshes-with-a-static-transform :) So for example meshes whose geometry or topology can change at runtime.

Thanks,

- Pierre

Pierre T.'s picture

So I tried hkpBvCompressedMeshShape and while I see a clear performance gain in raycasts/linearCast, I also seem to get worse performance for rigid body simulation, and especially an increased memory usage in most cases. Is that possible?

Here is the code creating the meshes. Can you spot something wrong? Thanks.

hkpShape* CreateMeshShape(const MESH_CREATE& create, HavokMeshFormat format)
{
    const udword NbVerts = create.mSurface.mNbVerts;
    const Point* V = create.mSurface.mVerts;

    const udword NbTris = create.mSurface.mNbFaces;
    const udword* I = create.mSurface.mDFaces;

    hkpShape* HavokShape=null;
    if(format==HAVOK_BV_COMPRESSED_MESH_SHAPE)
    {
        hkGeometry geom;
        for(udword i=0;i<NbVerts;i++)
        {
            geom.m_vertices.pushBack(hkVector4(V[i].x, V[i].y, V[i].z));
        }

        for(udword i=0;i<NbTris;i++)
        {
            hkGeometry::Triangle T;
            T.set(I[0], I[1], I[2], -1);
            I+=3;
            geom.m_triangles.pushBack(T);
        }
        {
            hkpDefaultBvCompressedMeshShapeCinfo cinfo(&geom);
            HavokShape = new hkpBvCompressedMeshShape(cinfo);
        }
    }
    else if(format==HAVOK_EXTENDED_MESH_SHAPE)
    {
        hkpExtendedMeshShape* m_mesh = new hkpExtendedMeshShape;
    
        {
            hkpExtendedMeshShape::TrianglesSubpart part;

            part.m_vertexBase            = &V->x;
            part.m_vertexStriding        = sizeof(Point);
            part.m_numVertices            = NbVerts;

            part.m_indexBase            = I;
            part.m_indexStriding        = sizeof(udword)*3;
            part.m_numTriangleShapes    = NbTris;
            part.m_stridingType            = hkpExtendedMeshShape::INDICES_INT32;

            m_mesh->addTrianglesSubpart(part);
        }

        hkpMoppCompilerInput mci;
        hkpMoppCode* m_code = hkpMoppUtility::buildCode(m_mesh, mci);

        HavokShape = new hkpMoppBvTreeShape(m_mesh, m_code);

        m_code->removeReference();
        m_mesh->removeReference();
    }
    return HavokShape;
}

HavokTim's picture

Hi Pierre--

The memory characteristics are to be expected because an extended mesh shape just holds a reference to your triangle data (it points to  create.mSurface.mVerts), while the BvCompressedMeshShape duplicates this data internally. With respect to rigid body performance, how are you profiling performance and what is the scenario you're testing?

With regard to deformable mesh, there aren't any cheap solutions. If you deform a mesh, you'll have to reintegrate and recollide to update the world state, and if it's any sort of hierarchical shape, you'd need to update its bounding hierarchy as well. If you're going for deformable terrain, a heightmap shape would be your best solution because you can modify the height of individual cells and it doesn't have an explicit hierarchy to update. You would still need to reintegrate and recollide, as well as make sure that any objects resting on the object move properly in response to this deformation. What kind of deformation are you trying to achieve? A specialized ragdoll may be a viable solution, depending on the use case.

--Tim

Login to leave a comment.