[SOLVED] Mesh VertexBuffer Usage Questions

Hello!

I’ve just been having a look at what the Usages (as in VertexBuffer.Usage) of my various Meshes are, with a view to optimizing my code, and I have a few questions.

  1. I understand that you mark a Mesh as Static (Mesh.setStatic()) if it’s never going to be altered. However, if that Mesh’s Geometry is translated or rotated, should the Mesh still be Static? My guess is that it should be. And out of interest, what about if the Geometry changes scale?

I loaded the Jaime model, and printed out its Usages, like so:

public void simpleInitApp() {
    Spatial spatial = assetManager.loadModel("Models/Jaime/Jaime.j3o");
    
    spatial.depthFirstTraversal(new SceneGraphVisitorAdapter() {
        
        @Override
        public void visit(Geometry geom) {
            for (VertexBuffer vb : geom.getMesh().getBufferList()) {
                System.out.printf("%s: %s\n", vb.getBufferType(), vb.getUsage());
            }
        }
    });
}

The output was as follows:

TexCoord: Static
BindPoseTangent: CpuOnly
Index: Static
BindPosePosition: CpuOnly
BindPoseNormal: CpuOnly
BoneWeight: CpuOnly
BoneIndex: CpuOnly
HWBoneIndex: CpuOnly
HWBoneWeight: CpuOnly
Position: Stream
Normal: Stream
Tangent: Stream

If my understanding is correct, what these Usages are assuming is that the texture coordinate and index vertex buffers will never change (which makes sense), but that the position and normal vertex buffers will continually change. This also makes sense, as the vertex positions (and, presumably, their normals) will be being deformed every frame by the bones (in turn moved by the animations).

  1. However, should all those other vertex buffers really be CpuOnly, even if we’re using hardware skinning? And what about HWBoneIndex and HWBoneWeight? Assuming HW stands for “hardware”, should they really be CpuOnly?

I then ran the same code with my own model (created in Blender), and got the following output:

Color: Dynamic
Index: Dynamic
BindPosePosition: CpuOnly
BindPoseNormal: CpuOnly
BoneWeight: CpuOnly
BoneIndex: CpuOnly
HWBoneIndex: CpuOnly
HWBoneWeight: CpuOnly
Position: Static
Normal: Static

A lot of these values strike me as wrong. Index is Dynamic, but why would an Index buffer ever change? It’s conceivable, but highly unlikely, so it seems a strange value that something’s decided to default that to. The model is not using textures, which is why there’s a Color instead of a TexCoord, but Color is Dynamic, which is also a bit strange.

And then Position and Normal are Static. Again, those seem like odd values that something’s decided to give to those vertex buffers, when they belong to a model with a skeleton that has animations on it.

  1. So, should I change the Usage of these vertex buffers? I’d change Color and Index to Static, and Position and Normal to Stream. And if I should change those CpuOnly ones as well, what should I set them to?

Thanks!

Translating or rotating a geometry does not touch the mesh data at all. Man, that would be really slow.

To the rest, I will let someone else answer. I almost 100% ignore this enum and have never had any issues.

I’ve carried on looking into this today, and the key to understanding it all is that on a subsequent frame jMonkeyEngine changes those Usages to values that make much more sense.

It doesn’t change Color or Index though, but I doubt changing those to Static would really make that much difference anyway, if at all, so it’s probably not worth fiddling with.

All in all, it seems to me that jMonkeyEngine takes care of Usage itself perfectly well, so your approach of ignoring it completely is probably the right one.