I am creating an extension that implements a kind of extrude function into Omniverse. Basically I want to use the new curve feature to define the middle line of a train track and use another curve as a profile shape to extrude along the first curve. I was successful in creating a Mesh prim, but I have not set a couple of attributes yet that I have seen in meshes created within Omniverse or Maya, for example:
I am particularly interested in making the collision api work on that custom mesh. So far, it seems to work without setting these attributes, but I want to be sure:
Does the collision api rely on normals or primvars:st?
If so, could someone give me some directions on how to set these correctly? I have not yet understood how to correctly set primvars and how interpolation works.
For physics the normals are required for triangle mesh approximation, if you want this mesh to be in a dynamic rigid body, then the approximation like convex hull will not use normals.
But for triangle meshes, its necessary to provide normals, since the winding does matter for physics, double sided is not supported.
in this case I need to configure normals, because it will be a triangle mesh collider. Could you give me some more directions? The USD doc is helpful, but does not answer all questions
I have checked some Mesh shapes that you can create in Omniverse and it seems they produce more than one normal per vertex. Or are they face normals? I don’t know. When I create a cube, it has 6 faces, 8 vertices, but 24 normals. What is each normal supposed to represent, and in which order are they arranged in the array? My mesh is made out of triangles.
Regarding normals, here is some more information In USD:
Normals are just primvars and they can be defined with different interpolation modes. They can be constant, per face, per vertex or some intermediate cases.
They can either be stored simply with one normal per vertex/face in a primvar array or additionally with an index array. If you don’t have this index array, the length of the primvar array needs to be the appropriate size and order based on your interpolation setting, i.e.:
Constant - 1
Uniform - # of faces (len(faceVertexCounts)) - “normal per face”
Certex - # of verts (len(points)) - “normal per vertex”
Varying / faceVarying - # of verts per face for all faces (len(faceVertexIndices)) - “normal per vert per UV patch (generally a face of a mesh))”
When you create a mesh from a Kit UI Menu, it creates it by default with faceVarying interpolation and no normal indices. This is the default, but you can certainly have and render meshes with different types of interpolations.
Although not the default in Kit, having an additional index array could help, for instance, reduce the file size.
Apart from using the Kit’s propriety window, a good way of analyzing a mesh / file is to save the file as a “usda” (human-readable USD format) and then open it up to see the way they are defined.
If I don’t care about anything visual, I can leave the normals array empty. The collider will work if the winding order of the indices is correct. The question is, what defines the correct winding order? Is it the way face vertices are arranged in either clockwise or anti-clockwise fashion? If so, my guess would be if I am looking on top of a face and see the vertices of that face numbered counter-clockwise, the normals vector points away from me, correct?
If I create a mesh inside Omniverse, it is created with normals and primvars:st. Default interpolation is faceVarying. I just checked this in a usda file.
If I am interested in textures etc. normals and primvars:st should be provided.
When I create a cylinder, it seems to have 32 faces with 4 vertices and 64 triangles with 3 faces, 96 faces altogether. The normals array contains 320 normals. The primvars:st array contains 320 entries. That is because interpolation is faceVarying and that means 1 normal per vertex per face.
Assuming my mesh has only triangles and I want to use uniform interpolation, I need one normal for each face. Presumably oriented orthogonal on the face.
If I want to use faceVarying interpolation, I need 3 normals for each face, correct? how do I need to orient each of these normals?
This is not exactly true, since RTX rendering is rendering triangles double sided, so you wont see if the winding (order of indices) is correct. (you can also change that through GetOrientationAttr that is on a UsdGeomMesh).
For physics, you can see the end result normals using the physics debug visualization and enabling normals.
Then we are rendering the normals for the meshes together with the mesh triangles:
This is the best way to ensure that your normals are facing the right directly in physics.