Questions concerning Cal3d and MD5 loaders.

I’m in the process of making Cal3d and Md5 loaders xith aware. I would like to ask a couple of questions because i’m not much educated regarding xith architecture.
in cal3d every mesh contains information for vertices, indices, normals and texcoords, in md5 normals must be auto-calculated.
Which is the best geometry container to store those attributes? At the moment i’m using IndexedTriangleArray.
Which options must be set in Appearance for texturing? I’m using setPolygonAttributes(new PolygonAttributes(PolygonAttributes.POLYGON_FILL, PolygonAttributes.CULL_NONE, 0));
And a last question? Does xith supports Controllers like JME ( a controller gets automatically executed at each update cycle and gets added in any scengraph node).
I believe by the end of the week i will have something to show!

[quote]And a last question? Does xith supports Controllers like JME ( a controller gets automatically executed at each update cycle and gets added in any scengraph node).
[/quote]
There is NodeUpdater, but because in Xith3d you’ve got direct access to the render-loop, this could also be done very easily directly by letting the user call the animation frame etc…
you could also look how it’s done in the md2 loader, that one supports animation, so it must have solved that problem in some way.

Actually this also belongs into the section of a general Loader specification of models with animations…

Hmm… long after the end of the week but finally it’s here… first screenies !!

Model loading and displaying work well, but animation is crappy… it mess up all polygons… I’ll have to see that deeper.

Some dump old code of mine for cal3d support in XITH

public class XithModel extends BranchGroup{
    protected static Vector3fBuffer vertexBuffer = new Vector3fBuffer(10000); // FIXME: ARBITRARY SIZED BUFFER - replace soon!
    protected static Vector3fBuffer normalBuffer = new Vector3fBuffer(10000); // FIXME: ARBITRARY SIZED BUFFER - replace soon!
    public CalModel model;
    Appearance app;
    public XithModel(String name,Appearance app,CalModel model) {
	this.model = model;
        this.app=app;
        initialize();
    }
    
    /** Creates a new instance of JmeCalModel */
    public XithModel(String name,CalCoreModel coreModel) {
	this.model = new CalModel(coreModel);
        initialize();
    }
    
    
    
    
    
    
    public void initialize(){
	//BranchGroup  result = new BranchGroup();
        //System.out.println("DRAWING");
	Vector meshes = model.getMeshes();
	int myCounter=0;
	for (Iterator i = meshes.iterator(); i.hasNext(); ) {
	    //System.out.println("INSIDE");
	    CalMesh mesh = (CalMesh) i.next();
	    Vector submeshes = mesh.getSubmeshes();
	    for (Iterator j = submeshes.iterator(); j.hasNext(); ) {
		CalSubmesh submesh = (CalSubmesh) j.next();
		CalCoreMaterial material = submesh.getCoreMaterial();
		
		
		float [ ] colour = { 1.0f, 1.0f, 1.0f, 1.0f }; //new float [4];
		
		if (submesh.hasInternalData()) {
		    
		    myCounter++;
		}
		else {
		    int numVertices = submesh.getCoreSubmesh().getVertexCount();
		    Vector3fBuffer vertexBuffer2 = submesh.getCoreSubmesh().getVertexPositions();
		    Vector3fBuffer normalBuffer2 = submesh.getCoreSubmesh().getVertexNormals();
		    int[] faces = new int[submesh.getCoreSubmesh().getFaceCount()*3];
		    int cc=0;
		    for(int p=0;p<submesh.getCoreSubmesh().getFaceCount();p++){
			Face aface = submesh.getCoreSubmesh().getVectorFace()[p];
			faces[cc]=aface.vertexId[0];
			cc++;
			faces[cc]=aface.vertexId[1];
			cc++;
			faces[cc]=aface.vertexId[2];
			cc++;
		    }
                    
                    IndexedTriangleArray iar = new IndexedTriangleArray(numVertices,GeometryArray.COORDINATES|GeometryArray.NORMALS,faces.length);
                    
                    
                    
                    for(int kk=0;kk<numVertices;kk++){
                        iar.setCoordinate(kk,new float[]{vertexBuffer2.getX(kk),vertexBuffer2.getY(kk),vertexBuffer2.getZ(kk)});
                        iar.setNormal(kk,normalBuffer2.get(kk));
                    }
                    iar.setIndex(faces);
                    Shape3D shape3d = new Shape3D(iar,app);
                     addChild(shape3d);
                     submesh.shape3d=shape3d;
		    myCounter++;
		}
		
	    }
	}
	
    }
    
    public void updateModel(float tpf){
	    model.update(tpf);
	    initialize2();
    }
    
    public void initialize2(){
	Vector meshes = model.getMeshes();
	int myCounter=0;
	for (Iterator i = meshes.iterator(); i.hasNext(); ) {
	    
	    CalMesh mesh = (CalMesh) i.next();
	    Vector submeshes = mesh.getSubmeshes();
	    for (Iterator j = submeshes.iterator(); j.hasNext(); ) {
		//System.out.println("INSIDE2");
		CalSubmesh submesh = (CalSubmesh) j.next();
		CalCoreMaterial material = submesh.getCoreMaterial();
		
		
		float [ ] colour = { 1.0f, 1.0f, 1.0f, 1.0f }; //new float [4];
		
		if (submesh.hasInternalData()) {
		    
		    myCounter++;
		}
		else {
		    int numVertices = model.getPhysique().calculateVertices(submesh, vertexBuffer);
                    int numNormals = model.getPhysique().calculateNormals(submesh, normalBuffer);
                    int aa = submesh.getFaceCount();
                    for(int kk=0;kk<numVertices;kk++){
                        ((IndexedTriangleArray)submesh.shape3d.getGeometry()).setCoordinate(kk,new float[]{vertexBuffer.getX(kk),vertexBuffer.getY(kk),vertexBuffer.getZ(kk)});
                        ((IndexedTriangleArray)submesh.shape3d.getGeometry()).setNormal(kk,normalBuffer.get(kk));
                    }
		    myCounter++;
		}
		
	    }
	}
        //return result;
	
    }
    
}

And where do you differenciate if the CalCoreMesh has internal data or not ? In the jME code you gave me there’s three possibility where the geometry is created :

  • has internal data, vertex positions + vertex normals
  • does not have internal data, vertex positions + vertex normals
  • and does not have internal data, vertex positions + vertex normals + textures coordinates
    And colors are added later in the code…

this is some older code i posted it only for the update function as a reference. Most submeshes dont have internal data. Internal data are used for meshes not directly attached to a bone like cally’s hair for instance and that are manipulated by cal3d’s own physique system

I see. Did it worked with this code ? I originally thought the messed vertices were because of a bug in the Mixer (or in the vecmath)

You must use the latest vecmath version due to bugs in Quaternion interpolate method

OK I thought it was in the mul() method so I grabbed the one from com.jme.math but it still doesn’t work. Downloading vecmath, I’l see if it works.

EDIT: Tried with the new build (CVS + ant build) but It didn’t change anything.

theKman, why don’t read the .cfg files directly ? instead of those .xml house-made files ?

Ok, I coded a cfg file reader, works pretty well BUT I tried animation with the Cally model and it doesn’t work either !! Arrghh this thing is driving me mad.

theKman, DID YOU HAVE SUCESSFUL RESULTS with the code source on kproject.gr ??

Is it possible it’s just me doing the Xith3D vertex update wrong ? The indices stay the same during the animation, right ?

Okay here are my sources, so you can review them : http://mkjeu.free.fr/cal3dj.zip (Note to potential users : it’s buggy). I included some data-files with it.

theKman, any news ? It’s really annoying I explored COLLADA and OBJ keyframes but Cal3D would be definitely better…