Milkshape loader for JOGL

[quote]I have done a Linux test of it and texture doesn’t show.
I need more feedback for my port on Linux…
[/quote]
I’m in front of my Solaris box right now and I think I’ve figured out why the textures don’t show up under Linux (or any Unix for that matter). You see, the texture name is hardcoded in the data file as “data/Wood.TGA”. The only problem is that when you unzip the file it comes out “data/Wood.tga”. Note the caps in TGA. Under Windows, it doesn’t care about the case of a file, but under Unix, case makes a big difference.

I changed “data/Wood.tga” to “data/Wood.TGA” and it worked fine on my Solaris box. You’ll have to try on your Linux box and let me know if it works.

Duh, I fill stupid :-[

A new version is upload it checks for uppercase and lowercase, and see if the file exist.

Thx

Mik

mik,

While I am using LWJGL and Chman’s port of Brett Porter’s code, it seems there are a lot of simularities between the two. I’m currently trying to get the animation working but am having trouble reading in the joint information. Have you had any luck?

Thanks

Not finished yet… Not enough time, this WeekEnd I will work on it.

Mik

Great, I’m going to continue working on it as well. So we can compare notes if you’d like. I basically, have a bunch of code working, that is, unfortunately, returning bad results. For instance, my number of keyframes is in the tens of thousands as are my joints. Seem to reading the wrong bytes somewhere.

Have you read the spec file contained in the SDK? That should help you solve any issues you’re having.

Yeah, I’m looking at both the spec and rsn.gamedev.net. I think I’m reading in the correct order, but apparently not.

have you a link where I could see and test your code?

Well, I don’t have it posted anywhere at the moment. I can post the part of the method where the loading is occurring here though. If you need any more than this, I’ll have to e-mail it to you or something. This code chunk occurs with in the data loader at the end.

'
    
   float animFPS = Conversion.byte2float(byteBuffer, dataPointer);
   dataPointer += 8;
   
   int totalFrames = Conversion.byte2int(byteBuffer, dataPointer);
   dataPointer +=4;
   
   totalTime = totalFrames * 1000.0f/animFPS;
   
   numJoints = Conversion.byte2short(byteBuffer, dataPointer);
   dataPointer += 2;
   
   joints = new Joint[numJoints];
   
   int tempPointer = dataPointer;
   
   JointNameListRec[] nameList = new JointNameListRec[numJoints];
   for(int i = 0; i < numJoints; i++) {
  MS3DJoint joint = new MS3DJoint(byteBuffer, tempPointer);
  tempPointer += joint.sizeof();
  tempPointer += 16 * (joint.numRotationKeyframes +  
     joint.numTranslationKeyframes);
  nameList[i] = new JointNameListRec();
  nameList[i].jointIndex = i;
  nameList[i].name = Conversion.byte2String(joint.name);
   }
   
   for(int i = 0; i < numJoints; i++) {
  MS3DJoint joint = new MS3DJoint(byteBuffer, dataPointer);
  dataPointer += joint.sizeof();
   
  int j, parentIndex = -1;
  if(joint.parentName.length > 0) {
      for(j = 0; j < numJoints; j++) {
     if(nameList[j].name.equalsIgnoreCase(new String(joint.parentName))) {
    parentIndex = nameList[j].jointIndex;
    break;
     }
      }
       
      if(parentIndex == -1) {
     //no parent joint.
      }
  }
   
  joints[i] = new Joint();
  joints[i].localRotation = joint.rotation;
  joints[i].localTranslation = joint.translation;
  joints[i].parent = parentIndex;
  joints[i].numRotationKeyframes = joint.numRotationKeyframes;
  joints[i].numTranslationKeyframes = joint.numTranslationKeyframes;
  joints[i].translationKeyframes = new Keyframe[joint.numTranslationKeyframes];
   
  for(j = 0; j < joint.numRotationKeyframes; j++) {
      MS3DKeyframe keyframe = new MS3DKeyframe(byteBuffer, dataPointer);
      dataPointer += keyframe.sizeof();
      setJointKeyframe(i,j,keyframe.time*1000.0f,keyframe.parameter,true);
  }
   
  for(j = 0; j < joint.numRotationKeyframes; j++) {
      MS3DKeyframe keyframe = new MS3DKeyframe(byteBuffer, dataPointer);
      dataPointer += keyframe.sizeof();
      setJointKeyframe(i,j,keyframe.time*1000.0f,keyframe.parameter,false);
  }
   }
   
   setupJoints();
   
 } 

All values, totalFrames, numJoints etc are very high, ie 30,000.

Let me know if there is any thing else you’d like to see.

A float is only 4 bytes long :wink: :
dataPointer += 4; // second line

right, but I’m skipping two floats. Hence, the eight.

for the high value did you try without the multiply by 1000.

No, I haven’t tried removing the 1000. But it won’t matter at the moment, as that part of the code is not used before the app dumps. The first problem is totalFrames and numJoints are incorrect values, so, as I am reading in joints in the for loops I run out of bounds in the byte array.

ok, I think I have localize the bug, there is a bug in sully implementation of MS3DMaterial, it assume that the texture name is always 128 bytes long and use a System.arraycopy for copying from the buffer to m_texture.
And because Material Texture loading was the last operation it doesn’t bug. But if you continue the process as you do, the pointer is wrong.
To bypass that you need to find the filename length, and change two arraycopy and also the MS3DMaterial sizeof according.
Not enough time to test, but I think it would do the job…

Ahhh! I think you are right. Checking now.

Well, after further investigation, it looks like 128 bytes are allocated for the texture and alpha map. Whether or not the texture name fills this does not matter.

So, I don’t think that is the problem. I’m wondering why in the original loader the byte array was not just wrapped in a ByteBuffer and then use .getFloat(), .getShort(), etc on it.

Ya, you need to rewrite all.I think i will do that,.

I found another bug in loadModelData changed to:

code changed to
` boolean loadModelData(InputStream is, long filesize)
{
// wrap a buffer to make reading more efficient (faster)
DataInputStream dis = new DataInputStream(new BufferedInputStream(is));

        int fileSize = (int) filesize;  // Warning! File size trunctuated to 32bits!

        byte[] pBuffer = new byte[fileSize];
        try
        {
              dis.readFully(pBuffer);
              dis.close();
        }
        catch (IOException ioe)
        {
              System.out.println("MilkshapeModel Error: Failed to read file contents.");
              ioe.printStackTrace();
              return false;
        }


`

Ok, I am going to try starting again using ByteBuffer and see if I have luck with that. I’ll keep you posted. If you want to continue working with the current version, that’d be good too.

ok, for the model that you are trying to load, could you give it to me? The best for such a problem, is to use in the same time a hex editor, and find the faulty bytes (and know how little and big endian works)

I’m using the “Ernie” model from the RealSoonNow tutorial.
http://rsn.gamedev.net/tutorials/ms3danim.asp

the download link at the bottom contains the model.