Md3ToJme reversed vertex order

Md3ToJme seems to produce triangles with reversed vertex order. I noticed this having back face cull on the rootnode and the model show up with only back faces visible.

Well that depends on the type of winding your model has (not the importer), because there's currently no way to set the winding in jME, maybe you can reverse it in the modeling program you use.

It's also the case with the md3 models in jmetest/data/model/lara/. It's inside out.



I had the same problem with the ported Quake3Loader but was able to fix it through these lines:



//reverse indices for correct vertex order for JME

Isn't this the case with both MD2 and MD3? This isn't something we're doing differently, but the way the formats are defined.

mojomonk said:

Isn't this the case with both MD2 and MD3? This isn't something we're doing differently, but the way the formats are defined.


I don't know if you are saying that everything is fine with the loader but if you are: Shouldn't the loader produce models that has a vertex order that is suitable for jME? I think it should be as close to the intended result as possible even if it means changing the vertex order in the import.

I made a tiny change to the code inside constructMesh() and now the model displays correctly.


    private Node constructMesh() {
        Node toReturn=new Node("MD3 File");
        for (int i=0;i<head.numSurface;i++){
            KeyframeController vkc=new KeyframeController();
            MD3Surface thisSurface=surfaces[i];
            TriMesh object=new TriMesh(thisSurface.name);
           //reverse indices for correct vertex order for jME
            int reversedIndex[] = new int[thisSurface.triIndexes.length];
            for (int j = 0;j<thisSurface.triIndexes.length;j++){
                reversedIndex[j] = thisSurface.triIndexes[thisSurface.triIndexes.length-1-j];
            }
        //    object.setIndexBuffer(BufferUtils.createIntBuffer(thisSurface.triIndexes));
            object.setIndexBuffer(BufferUtils.createIntBuffer(reversedIndex));
            object.setVertexBuffer(BufferUtils.createFloatBuffer(thisSurface.verts[0]));
            object.setNormalBuffer(BufferUtils.createFloatBuffer(thisSurface.norms[0]));
            object.setTextureBuffer(BufferUtils.createFloatBuffer(thisSurface.texCoords));
            toReturn.attachChild(object);
            vkc.setMorphingMesh(object);
            for (int j=0;j<head.numFrames;j++){
                TriMesh etm=new TriMesh();
                etm.setVertexBuffer(BufferUtils.createFloatBuffer(thisSurface.verts[j]));
                etm.setNormalBuffer(BufferUtils.createFloatBuffer(thisSurface.norms[j]));
                vkc.setKeyframe(j,etm);
            }
            vkc.setActive(true);
            object.addController(vkc);
        }
        nullAll();
        return toReturn;
    }