Trouble converting model loader

Problems with Canvas, OpenGL, etc...

Trouble converting model loader

Postby jonbonazza » Sat Aug 14, 2010 3:31 am

I wasn't quite sure where to put this, but anywho...

I have a C++ class that loads the data from a MD2 model into memory. I am trying to convert this into Java, but since I am not as familiar with java as I am with C++, I am having a bit of difficulty at one point. Instead of pasting the entire C++ code (it is rather lengthy), I will just supply the relevant parts:


first off, I have a few structs that look like this:
Syntax: [ Download ] [ Hide ]
Using c Syntax Highlighting
  1. typedef struct
  2. {
  3.           float[] point = new float[3];
  4. } Vector;
  5.  
  6. typedef struct
  7. {
  8.         int ident;                                      //identifies as MD2 file "IDP2"
  9.         int version;                            //should be equal to 8
  10.         int skinWidth;                          //width of the texture
  11.         int skinHeight;                         //height of the texture
  12.         int frameSize;                          //number of bytes per frame
  13.         int numSkins;                           //number of textures
  14.         int numXYZ;                                     //number of vertices
  15.         int numST;                                      //number of texture coordinates
  16.         int numTris;                            //number of triangles
  17.         int numGLcmds;                          //number of OpenGL command types
  18.         int numFrames;                          //total number of frames;
  19.         int offsetSkins;                        //offset of skin names (64 bytes each)
  20.         int offsetST;                           //offset of texture coordinate pairs
  21.         int offsetTris;                         //offset of triangle mesh
  22.         int offsetFrames;                       //offset of frame data (points)
  23.         int offsetGLcmds;                       //offset of type of OpenGL cmds to use
  24.         int offsetEnd;                          //end of file;
  25. } ModelHeader;
  26.  
  27. typedef struct
  28. {
  29.         unsigned char v[3];                   //point info
  30.         unsigned char normalIndex;       // normal index
  31. } FramePoint;
  32.  
  33. typedef struct
  34. {
  35.        float scale[3];                          //scaling for frame vertices
  36.        float translate[3];                    //translation for frame vertices
  37.        char name[16];                        //name of model;
  38.        FramePoint fp[1];                    //beginning of frame vertex list;
  39. } Frame;
  40.  
Parsed in 0.016 seconds, using GeSHi 1.0.8.4


then I have a seperate class called Model that contains a private variable like this:
Syntax: [ Download ] [ Hide ]
Using c Syntax Highlighting
  1. private:
  2. ...
  3. Vector *vertexList;              //Vertex list
  4.  
Parsed in 0.001 seconds, using GeSHi 1.0.8.4


and then the C++ code I am stuck on is in a method called LoadModel():

Syntax: [ Download ] [ Hide ]
Using c Syntax Highlighting
  1. Frame *frame;                                 // Pointer to frame data
  2. Vector *vertexListPtr;                     //Pointer to vertex list
  3. ModelHeader *modelHeader;            //Pointer to model header
  4. ...
  5. vertexList = new Vector[modelHeader->numXYZ * modelHeader->numFrames];
  6. ...
  7. numVertices = modelHeader->numXYZ;
  8. numFrames = modelHeader->numFrames;
  9. frameSize = modelHeader->frameSize;
  10.  
  11. for(int j = 0; j < numFrames; j++)
  12. {  
  13.         ...
  14.         vertexListPtr = (Vector*)&vertexList[numVertices * j];
  15.         for(int i = 0; i < numVertices; i++)
  16.         {
  17.                 vertexListPtr[i].point[0] = frame->scale[0] * frame->fp[i].v[0] + frame->translate[0];
  18.                 vertexListPtr[i].point[1] = frame>scale[1] * frame->fp[i].v[1] + frame->translate[1];
  19.                 vertexListPtr[i].point[2] = frame->scale[2] * frame->fp[i].v[2] + frame->translate[2];
  20.         }
  21. }
  22.  
Parsed in 0.005 seconds, using GeSHi 1.0.8.4


I can't for the life of me get this much converted to Java. Everything else in the method I can get working, but if I convert the structures and variables to how I THINK they should be represented in java, the loop at the end becomes impossible to wrap my head around... Any help on this?

Also, should I just use native code for this instead?
jonbonazza
Master Developer
Master Developer
 
Posts: 665
Joined: Thu Jul 15, 2010 2:58 pm
Location: WV USA

Top

Re: Trouble converting model loader

Postby jonbonazza » Sat Aug 14, 2010 11:27 pm

Ok so I got most of it. The only problem I ma having now is the following line:

vertexListPtr = (Vector*)&vertexList[numVertices * j];

Look up at the code to see what everything is defined as.
jonbonazza
Master Developer
Master Developer
 
Posts: 665
Joined: Thu Jul 15, 2010 2:58 pm
Location: WV USA

Re: Trouble converting model loader

Postby MichaelEGR » Sun Aug 15, 2010 2:14 am

You can convert to the following block of code assuming your vertexList is an array of Vector objects and the Frame object has public member variables scale, fp, and translate.

Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1. int index = numVerticles * j;
  2. for (int cntr = 0; cntr < numVertices; cntr++)
  3. {
  4.    Vector vertex = vertexList[index++];
  5.    vertex.point[0] = frame.scale[0] * frame.fp[cntr].v[0] + frame.translate[0];
  6.    vertex.point[1] = frame.scale[1] * frame.fp[cntr].v[1] + frame.translate[1];
  7.    vertex.point[2] = frame.scale[2] * frame.fp[cntr].v[2] + frame.translate[2];
  8. }
  9.  
Parsed in 0.030 seconds, using GeSHi 1.0.8.4
Founder & Principal Architect; EGR Software LLC
http://www.typhonrt.org
http://www.egrsoftware.com
User avatar
MichaelEGR
Senior Developer
Senior Developer
 
Posts: 147
Joined: Thu Jan 21, 2010 5:30 am
Location: San Francisco, CA

Re: Trouble converting model loader

Postby jonbonazza » Sun Aug 15, 2010 7:08 pm

Hey, thanks for the info! Unfortunately, it still didn't work. Although I did change it a little:

When I tried to initialize fp[j].v[0], fp[j].v[1], and fp[j].v[2] before entering the loop you gave me it kept giving me an exception, so I tried something else. here is my code. I feel like I am so close, but so far away:

Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1. public int loadModel(String filepath, String tex) throws IOException
  2.         {
  3.                 File file = new File(filepath);
  4.                 FileInputStream fis = new FileInputStream(file);
  5.                 Mesh[] bufIndexPtr;
  6.                 Frame frame = new Frame();
  7.                 ModelHeader header = new ModelHeader();
  8.                 StIndex[] stPtr;
  9.                 LittleEndianInputStream is = new LittleEndianInputStream(fis);
  10.                
  11.  
  12.                 header.ident = is.readInt();
  13.                 header.version = is.readInt();
  14.                 header.skinWidth = is.readInt();
  15.                 header.skinHeight = is.readInt();
  16.                 header.frameSize = is.readInt();
  17.                 header.numSkins = is.readInt();
  18.                 header.numXYZ = is.readInt();
  19.                 header.numST = is.readInt();
  20.                 header.numTris = is.readInt();
  21.                 header.numGLcmds = is.readInt();
  22.                 header.numFrames = is.readInt();
  23.                 header.offsetSkins = is.readInt();
  24.                 header.offsetST = is.readInt();
  25.                 header.offsetTris = is.readInt();
  26.                 header.offsetFrames = is.readInt();
  27.                 header.offsetGLcmds = is.readInt();
  28.                 header.offsetEnd = is.readInt();
  29.                 String texture = tex;
  30.                
  31.                 byte[] buffer = new byte[header.offsetEnd - 68];
  32.                 is.read(buffer);
  33.                
  34.                
  35.                 numST = header.numSkins;
  36.                 numVertices = header.numXYZ;
  37.                 numFrames = header.numFrames;
  38.                 frameSize = header.frameSize;
  39.                
  40.                 ByteArrayInputStream bs = new ByteArrayInputStream(buffer, header.offsetFrames - 68, buffer.length - header.offsetFrames);
  41.                 is = new LittleEndianInputStream(bs);
  42.                 vertexList = new Vector[header.numXYZ * header.numFrames];
  43.                 for(int i = 0; i < numFrames; i++)
  44.                 {
  45.                        
  46.                         frame.scale[0] = is.readFloat();
  47.                         frame.scale[1] = is.readFloat();
  48.                         frame.scale[2] = is.readFloat();
  49.                        
  50.                         frame.translate[0] = is.readFloat();
  51.                         frame.translate[1] = is.readFloat();
  52.                         frame.translate[2] = is.readFloat();
  53.                        
  54.                         frame.name = is.readString(16);
  55.                        
  56.                         int index = numVertices * i;
  57.                         for(int j = 0; j < numVertices; j++)
  58.                         {
  59.                                 Vector vertex = vertexList[index++];
  60.                                 vertex.point[0] = frame.scale[0] * is.readUnsignedChar() + frame.translate[0];
  61.                                 vertex.point[1] = frame.scale[1] * is.readUnsignedChar() + frame.translate[1];
  62.                                 vertex.point[2] = frame.scale[2] * is.readUnsignedChar() + frame.translate[2];
  63.                         }
  64.                 }
  65. ....
  66. }
  67.  
Parsed in 0.043 seconds, using GeSHi 1.0.8.4
jonbonazza
Master Developer
Master Developer
 
Posts: 665
Joined: Thu Jul 15, 2010 2:58 pm
Location: WV USA

Re: Trouble converting model loader

Postby jonbonazza » Sun Aug 15, 2010 7:45 pm

Ok, so I tried an alternate method which is closer to your idea, and it sitll didn't work, but here it is:

Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1. ...
  2.  
  3. vertexList = new Vector[header.numXYZ * header.numFrames];
  4.                 frame.fp = new FramePoint[numFrames];
  5.                 for(int i = 0; i < numFrames; i++)
  6.                 {
  7.                        
  8.                         frame.scale[0] = is.readFloat();
  9.                         frame.scale[1] = is.readFloat();
  10.                         frame.scale[2] = is.readFloat();
  11.                        
  12.                         frame.translate[0] = is.readFloat();
  13.                         frame.translate[1] = is.readFloat();
  14.                         frame.translate[2] = is.readFloat();
  15.                        
  16.                         frame.name = is.readString(16);
  17.                        
  18.                         frame.fp[i].v[0] = is.readByte();
  19.                         frame.fp[i].v[1] = is.readByte();
  20.                         frame.fp[i].v[2] = is.readByte();
  21.                        
  22.                         frame.fp[i].normalIndex = is.readByte();
  23.                        
  24.                        
  25.                        
  26.                         int index = numVertices * i;
  27.                         for(int j = 0; j < numVertices; j++)
  28.                         {
  29.                                 Vector vertex = vertexList[index++];
  30.                                 vertex.point[0] = frame.scale[0] * frame.fp[j].v[0] + frame.translate[0];
  31.                                 vertex.point[1] = frame.scale[1] * frame.fp[j].v[1] + frame.translate[1];
  32.                                 vertex.point[2] = frame.scale[2] * frame.fp[j].v[2] + frame.translate[2];
  33.                         }
  34.                 }
  35.  
  36. ...
  37.  
  38. }
  39.  
Parsed in 0.039 seconds, using GeSHi 1.0.8.4


Any ideas? This one little section of code is driving me insane! lol
jonbonazza
Master Developer
Master Developer
 
Posts: 665
Joined: Thu Jul 15, 2010 2:58 pm
Location: WV USA

Re: Trouble converting model loader

Postby MichaelEGR » Sun Aug 15, 2010 8:45 pm

frame.fp = new FramePoint[numFrames];

You are creating an array, but are not initializing fp[0 to 3]

frame.fp[0] = new FramePoint();
frame.fp[1] = new FramePoint();
frame.fp[2] = new FramePoint();

You can likely do this in the for loop.

Note that the FramePoint constructor should also initialize whatever the v[] member variable is as well. Create the v[] array and also create new objects in that array.

I don't know your programming background, but it could help to take a step back and get up to speed on Java a little more and work on some simpler games until Java is familiar. Jumping in and porting model loading and animation code from C is not an easy initial step per se.. :)

Of course once you get this to compile and all that it would be a good idea to try and verify the data loaded before moving onto the next stage. Without seeing how you are handling byte data when loading and also dealing with any further algorithm issues keep in mind that Java only supports signed primitives whereas in C there is unsigned data and often in the Quake level and model data unsigned bytes are used. Just a FYI / keep in mind point if you run into further issues.
Founder & Principal Architect; EGR Software LLC
http://www.typhonrt.org
http://www.egrsoftware.com
User avatar
MichaelEGR
Senior Developer
Senior Developer
 
Posts: 147
Joined: Thu Jan 21, 2010 5:30 am
Location: San Francisco, CA

Top

Re: Trouble converting model loader

Postby jonbonazza » Sun Aug 15, 2010 10:57 pm

Ok cool, thanks... I guess when I failed to remember I was using classes and not structures now, when converting the structs over haha... Silly me... But yea, I am very good at C/C++, but java I just started learning near the beginning of the summer. I actually have an extensive java class this comeing semester at the university, so I am hoping that will help me out a bit... I am not bad at java by any means... It's just entirely different (more so than you would think) comeing over from C/C++. I figured since I was fairly familiar with the OO sde of C/C++ (with libraries such as the wxWidgets library and OpenGL), that it wouldn't be much differnt... I am getting there though... practice makes perfect, right? :P
jonbonazza
Master Developer
Master Developer
 
Posts: 665
Joined: Thu Jul 15, 2010 2:58 pm
Location: WV USA

Re: Trouble converting model loader

Postby jonbonazza » Sun Aug 15, 2010 11:07 pm

Ok, so I tried your recomendation like so:

Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1. for(int i = 0; i < numFrames; i++)
  2.                 {
  3.                        
  4.                         frame.scale[0] = is.readFloat();
  5.                         frame.scale[1] = is.readFloat();
  6.                         frame.scale[2] = is.readFloat();
  7.                        
  8.                         frame.translate[0] = is.readFloat();
  9.                         frame.translate[1] = is.readFloat();
  10.                         frame.translate[2] = is.readFloat();
  11.                        
  12.                         frame.name = is.readString(16);
  13.                        
  14.                         frame.fp[i] = new FramePoint();
  15.                        
  16.                         frame.fp[i].v[0] = is.readByte();
  17.                         frame.fp[i].v[1] = is.readByte();
  18.                         frame.fp[i].v[2] = is.readByte();
  19.                        
  20.                         frame.fp[i].normalIndex = is.readByte();
  21.                        
  22.                        
  23.                        
  24.                         int index = numVertices * i;
  25.                         for(int j = 0; j < numVertices; j++)
  26.                         {
  27.                                
  28.                                 Vector vertex = vertexList[index++];
  29.                                 vertex.point[0] = frame.scale[0] * frame.fp[j].v[0] + frame.translate[0];
  30.                                 vertex.point[1] = frame.scale[1] * frame.fp[j].v[1] + frame.translate[1];
  31.                                 vertex.point[2] = frame.scale[2] * frame.fp[j].v[2] + frame.translate[2];
  32.                         }
  33.                 }
  34.  
Parsed in 0.039 seconds, using GeSHi 1.0.8.4


but it still fails. :/

Also, here is my FramePoint class:

Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1. public class FramePoint
  2. {
  3.         byte[] v;       //the point info
  4.         byte normalIndex;               //Not used, but needs to be included so that the model is loaded correctly
  5.        
  6.         public FramePoint()
  7.         {
  8.                 v = new byte[3];
  9.         }
  10. }
  11.  
Parsed in 0.037 seconds, using GeSHi 1.0.8.4


Notice that v[] is an array of bytes.... How can I initialize a primitive like byte? If I use null it throws an error on compile. Also, I thought that you didn't need to initialize a variable of the byte data type. I was under the impression that it was the only one you didn't need to.
jonbonazza
Master Developer
Master Developer
 
Posts: 665
Joined: Thu Jul 15, 2010 2:58 pm
Location: WV USA

Re: Trouble converting model loader

Postby MichaelEGR » Sun Aug 15, 2010 11:18 pm

Indeed.. It sounds like you have the enthusiasm and passion to get right in there and take the bull by the horns though and that is the most important aspect of diving into a new technology or platform!

The thing that was throwing you off with the "vertexListPtr = (Vector*)&vertexList[numVertices * j]" statement and indexing in the C for loop was that the counter (i) used in the C code was doing pointer arithmetic / indexing so it's possible to use one counter to iterate through the local variables and sub section of the vertex list. With Java you need two counters to keep track of the position in the vertex list and the local iteration (numVectices).

Definitely post some results back here when you get some cool stuff working! :)
Founder & Principal Architect; EGR Software LLC
http://www.typhonrt.org
http://www.egrsoftware.com
User avatar
MichaelEGR
Senior Developer
Senior Developer
 
Posts: 147
Joined: Thu Jan 21, 2010 5:30 am
Location: San Francisco, CA

Re: Trouble converting model loader

Postby jonbonazza » Sun Aug 15, 2010 11:26 pm

Lol I plan on it! Do you mind taking another glance at my previous post? I threw in a few questions on the ninja. :P
jonbonazza
Master Developer
Master Developer
 
Posts: 665
Joined: Thu Jul 15, 2010 2:58 pm
Location: WV USA

Re: Trouble converting model loader

Postby jonbonazza » Sun Aug 15, 2010 11:32 pm

Also, I think I found the problem (or at least one of them), but I have no idea how to go about fixing it... lol I initialized the frame.fp[] array as having numFrams values. Then, further down in the code, when I am within the inner loop of the notorious double loops that have been giving me so much problems, I am looping through the fram.fp[] array numVertices times. The problem is that numVertices is MUCH higher than numFrames, so it is actually reaching the end of the frame.fp[] array before it exits the inner loop... any idea how to go about fixing this? In the c++ Frame struct, I had frame.fp[] initialized differntly (that will not work in java) and I also had frame declared as a pointer (Frame frame;). Without direct access to memory life is a bitch. XD
jonbonazza
Master Developer
Master Developer
 
Posts: 665
Joined: Thu Jul 15, 2010 2:58 pm
Location: WV USA

Re: Trouble converting model loader

Postby MichaelEGR » Mon Aug 16, 2010 12:07 am

>Without direct access to memory life is a bitch.

Nah... It can make life a lot easier and way less error prone, but yeah tricks abound when you can directly access memory.

Of course with just seeing snippets of code and not seeing the entire original and modifications you've had to make on the way it's hard to say, but verify that for frame.fp[] what counter you are supposed to use. Likely it should be the outer loop counter indexing on numFrames and not the numVertices. The inner loop numVertices is to iterate and set values of the vertexList.
Founder & Principal Architect; EGR Software LLC
http://www.typhonrt.org
http://www.egrsoftware.com
User avatar
MichaelEGR
Senior Developer
Senior Developer
 
Posts: 147
Joined: Thu Jan 21, 2010 5:30 am
Location: San Francisco, CA

Re: Trouble converting model loader

Postby jonbonazza » Mon Aug 16, 2010 2:44 pm

Wooo! I finally figured it out! I was confused in my last post because I had already tried switching the index of frame.fp[] in the inner loop to frame.fp[i], but it still wouldn't work... After some more hunting, I finally found the problem... I had:

vertexList = new Vector[header.numXYZ * header.numFrames];

but I never initialized each value.

I added the following code right after it and it fixed everything:

for(int i = 0; i < (header.numXYZ * header.numFrames); i++)
{
vertexList[i] = new Vector();
}
jonbonazza
Master Developer
Master Developer
 
Posts: 665
Joined: Thu Jul 15, 2010 2:58 pm
Location: WV USA

Top

Return to Android 2D/3D Graphics - OpenGL Problems

Who is online

Users browsing this forum: No registered users and 4 guests