Java-Gaming.org    
Featured games (79)
games approved by the League of Dukes
Games in Showcase (475)
Games in Android Showcase (106)
games submitted by our members
Games in WIP (530)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: 1 [2]
  ignore  |  Print  
  Milkshape loader for JOGL  (Read 8872 times)
0 Members and 1 Guest are viewing this topic.
Offline Mojomonkey

Senior Member




ooh ooh eee eeee


« Reply #30 - Posted 2003-07-01 20:25:42 »

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

Don't send a man to do a monkey's work.
Offline mik

Senior Newbie




Java games rock everywhere!


« Reply #31 - Posted 2003-07-01 20:59:41 »

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

Senior Member




ooh ooh eee eeee


« Reply #32 - Posted 2003-07-01 21:06:05 »

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.

Don't send a man to do a monkey's work.
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline mik

Senior Newbie




Java games rock everywhere!


« Reply #33 - Posted 2003-07-01 21:41:44 »

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...

Offline Mojomonkey

Senior Member




ooh ooh eee eeee


« Reply #34 - Posted 2003-07-01 21:42:38 »

Ahhh! I think you are right. Checking now.

Don't send a man to do a monkey's work.
Offline Mojomonkey

Senior Member




ooh ooh eee eeee


« Reply #35 - Posted 2003-07-01 22:28:50 »

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.

Don't send a man to do a monkey's work.
Offline mik

Senior Newbie




Java games rock everywhere!


« Reply #36 - Posted 2003-07-02 11:18:18 »

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;
           }
...
Offline Mojomonkey

Senior Member




ooh ooh eee eeee


« Reply #37 - Posted 2003-07-02 13:12:48 »

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.

Don't send a man to do a monkey's work.
Offline mik

Senior Newbie




Java games rock everywhere!


« Reply #38 - Posted 2003-07-02 13:20:56 »

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)
Offline Mojomonkey

Senior Member




ooh ooh eee eeee


« Reply #39 - Posted 2003-07-02 13:24:42 »

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.

Don't send a man to do a monkey's work.
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline Mojomonkey

Senior Member




ooh ooh eee eeee


« Reply #40 - Posted 2003-07-02 15:14:06 »

Ok, I have completely rewritten the loader. I'm now loading the mode and displaying it fine. I'm going to start loading the joints now. Using the ByteBuffer has been much easier. I'm able to follow the spec directly and read just as it says. Hitting the joints now...

Don't send a man to do a monkey's work.
Offline mik

Senior Newbie




Java games rock everywhere!


« Reply #41 - Posted 2003-07-02 15:19:24 »

great job guy  Wink
Offline Mojomonkey

Senior Member




ooh ooh eee eeee


« Reply #42 - Posted 2003-07-02 16:39:06 »

Alright! Works. Here is the complete loading code. My apologies for the length. You may notice I changed some things, mostly I am trying to move away from using the MS3D* classes in favor of just the generic ones. Which means I changes the generic ones a little bit.

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
50  
51  
52  
53  
54  
55  
56  
57  
58  
59  
60  
61  
62  
63  
64  
65  
66  
67  
68  
69  
70  
71  
72  
73  
74  
75  
76  
77  
78  
79  
80  
81  
82  
83  
84  
85  
86  
87  
88  
89  
90  
91  
92  
93  
94  
95  
96  
97  
98  
99  
100  
101  
102  
103  
104  
105  
106  
107  
108  
109  
110  
111  
112  
113  
114  
115  
116  
117  
118  
119  
120  
121  
122  
123  
124  
125  
126  
127  
128  
129  
130  
131  
132  
133  
134  
135  
136  
137  
138  
139  
140  
141  
142  
143  
144  
145  
146  
147  
148  
149  
150  
151  
152  
153  
154  
155  
156  
157  
158  
159  
160  
161  
162  
163  
164  
165  
166  
167  
168  
169  
170  
171  
172  
173  
174  
175  
176  
177  
178  
179  
180  
181  
182  
183  
184  
185  
186  
187  
188  
189  
190  
191  
192  
193  
194  
195  
196  
197  
198  
199  
200  
201  
202  
203  
204  
205  
206  
207  
208  
209  
210  
211  
212  
213  
214  
215  
216  
217  
218  
219  
220  
221  
222  
223  
224  
225  
226  
227  
228  
229  
230  
231  
232  
233  
234  
235  
public void initialize() {
        //read the byte data
       byte data[] = null;
        File file = new File(modelFile);
        path = file.getAbsolutePath().substring(
            0,
            file.getAbsolutePath().length() - file.getName().length());
        int length = (int)file.length();
        data = new byte[length];
        FileInputStream fis;
        try {
            fis = new FileInputStream(file);
            fis.read(data);
            fis.close();
        } catch (FileNotFoundException e) {
            LoggingSystem.getLoggingSystem().getLogger().log(
                Level.WARNING,
                "Could not find model file " + modelFile);
            return;
        } catch (IOException e) {
            LoggingSystem.getLoggingSystem().getLogger().log(
                Level.WARNING,
                "Could not read model file " + modelFile);
            return;
        }

        buffer = ByteBuffer.wrap(data).order(ByteOrder.nativeOrder());

        //read header information
       //the ID is 10 bytes
       byte idBuffer[] = new byte[10];
        for (int i = 0; i < 10; i++) {
            idBuffer[i] = buffer.get();
        }
        id = Conversion.byte2String(idBuffer);
        version = buffer.getInt();

        if (!id.equals("MS3D000000")) {
            LoggingSystem.getLoggingSystem().getLogger().log(
                Level.WARNING,
                modelFile + " is not a valid Milkshape3D model file.");
            return;
        }

        if (version < 3) {
            LoggingSystem.getLoggingSystem().getLogger().log(
                Level.WARNING,
                "Bad " + modelFile + " version.");
            return;
        }

        //Read the vertices
       numVertices = buffer.getShort();
        vertices = new Vertex[numVertices];
        MS3DVertex vertex = null;
        for (int i = 0; i < numVertices; i++) {
            vertex = new MS3DVertex();
            vertex.flags = buffer.get();
            vertices[i] = new Vertex();
            vertices[i].point[0] = buffer.getFloat();
            vertices[i].point[1] = buffer.getFloat();
            vertices[i].point[2] = buffer.getFloat();
            vertices[i].boneId = buffer.get();
            vertex.refCount = buffer.get();
        }

        //Read the Triangles
       numTriangles = buffer.getShort();
        triangles = new Triangle[numTriangles];
        MS3DTriangle tri = new MS3DTriangle();
        for (int i = 0; i < numTriangles; i++) {
            tri = new MS3DTriangle();
            tri.flags = buffer.getShort();
            triangles[i] = new Triangle();
            for (int j = 0; j < 3; j++) {
                triangles[i].vertexIndices[j] = buffer.getShort();
            }

            for (int j = 0; j < 3; j++) {
                triangles[i].vertexNormals[j][0] = buffer.getFloat();
                triangles[i].vertexNormals[j][1] = buffer.getFloat();
                triangles[i].vertexNormals[j][2] = buffer.getFloat();
            }

            for (int j = 0; j < 3; j++) {
                triangles[i].s[j] = buffer.getFloat();
            }

            for (int j = 0; j < 3; j++) {
                triangles[i].t[j] = 1.0f - buffer.getFloat();
            }

            tri.smoothingGroup = buffer.get();
            tri.groupIndex = buffer.get();

        }

        //Read the meshes
       numMeshes = buffer.getShort();
        meshes = new Mesh[numMeshes];
        for (int i = 0; i < numMeshes; i++) {
            meshes[i] = new Mesh();
            meshes[i].flags = buffer.get();
            //get the name 32 bytes
           byte nameBuffer[] = new byte[32];
            for (int j = 0; j < 32; j++) {
                nameBuffer[j] = buffer.get();
            }
            meshes[i].name = Conversion.byte2String(nameBuffer);
            meshes[i].numTriangles = buffer.getShort();
            meshes[i].triangleIndices = new int[meshes[i].numTriangles];
            for (int j = 0; j < meshes[i].numTriangles; j++) {
                meshes[i].triangleIndices[j] = buffer.getShort();
            }
            meshes[i].materialIndex = buffer.get();

        }

        //read materials
       numMaterials = buffer.getShort();
        materials = new Material[numMaterials];
        for (int i = 0; i < numMaterials; i++) {
            materials[i] = new Material();

            //read the material name 32 bytes
           byte nameBuffer[] = new byte[32];
            for (int j = 0; j < 32; j++) {
                nameBuffer[j] = buffer.get();
            }
            materials[i].name = Conversion.byte2String(nameBuffer);
           
            materials[i].ambient[0] = buffer.getFloat();
            materials[i].ambient[1] = buffer.getFloat();
            materials[i].ambient[2] = buffer.getFloat();
            materials[i].ambient[3] = buffer.getFloat();

            materials[i].diffuse[0] = buffer.getFloat();
            materials[i].diffuse[1] = buffer.getFloat();
            materials[i].diffuse[2] = buffer.getFloat();
            materials[i].diffuse[3] = buffer.getFloat();

            materials[i].specular[0] = buffer.getFloat();
            materials[i].specular[1] = buffer.getFloat();
            materials[i].specular[2] = buffer.getFloat();
            materials[i].specular[3] = buffer.getFloat();

            materials[i].emissive[0] = buffer.getFloat();
            materials[i].emissive[1] = buffer.getFloat();
            materials[i].emissive[2] = buffer.getFloat();
            materials[i].emissive[3] = buffer.getFloat();
           
            materials[i].shininess = buffer.getFloat();
            materials[i].transparency = buffer.getFloat();
            materials[i].mode = buffer.get();
           
            //get texture
           byte texBuffer[] = new byte[128];
            for(int j = 0; j < 128; j++) {
                texBuffer[j] = buffer.get();
            }
            materials[i].textureFilename = Conversion.byte2String(texBuffer);
            byte alphaBuffer[] = new byte[128];
            for(int j = 0; j < 128; j++) {
                alphaBuffer[j] = buffer.get();
            }
            materials[i].alphaFilename = Conversion.byte2String(texBuffer);
        }
        loadTextures();
       
        //Read key frames
       animationFPS = buffer.getFloat();
        currentTime = (buffer.getFloat() * 1000);
        totalFrames = buffer.getInt();
       
        numJoints = buffer.getShort();
        joints = new Joint[numJoints];
       
        for(int i = 0; i < numJoints; i++) {
            joints[i] = new Joint();
            joints[i].flags = buffer.get();
            //get name 32 bytes
           byte[] nameBuffer = new byte[32];
            for(int j = 0; j < 32; j++) {
                nameBuffer[j] = buffer.get();
            }
           
            joints[i].name = Conversion.byte2String(nameBuffer);
            //get parent name 32 bytes
           byte[] parentBuffer = new byte[32];
            for(int j = 0; j < 32; j++) {
                parentBuffer[j] = buffer.get();
            }
            joints[i].parentName = Conversion.byte2String(parentBuffer);
           
            joints[i].rotation[0] = buffer.getFloat();
            joints[i].rotation[1] = buffer.getFloat();
            joints[i].rotation[2] = buffer.getFloat();
           
            joints[i].translation[0] = buffer.getFloat();
            joints[i].translation[1] = buffer.getFloat();
            joints[i].translation[2] = buffer.getFloat();
           
            joints[i].numRotationKeyframes = buffer.getShort();
            joints[i].rotationKeyframes =
                    new Keyframe[joints[i].numRotationKeyframes];
           
            joints[i].numTranslationKeyframes = buffer.getShort();
            joints[i].translationKeyframes =
                    new Keyframe[joints[i].numTranslationKeyframes];
           
            for(int j = 0; j < joints[i].numRotationKeyframes; j++) {
                joints[i].rotationKeyframes[j] = new Keyframe();
                joints[i].rotationKeyframes[j].time =
                        (buffer.getFloat() * 1000);
                joints[i].rotationKeyframes[j].parameter[0] =
                    buffer.getFloat();
                joints[i].rotationKeyframes[j].parameter[1] =
                    buffer.getFloat();
                joints[i].rotationKeyframes[j].parameter[2] =
                    buffer.getFloat();
            }
           
            for(int j = 0; j < joints[i].numTranslationKeyframes; j++) {
                joints[i].translationKeyframes[j] = new Keyframe();
                joints[i].translationKeyframes[j].time =
                        (buffer.getFloat() * 1000);
                joints[i].translationKeyframes[j].parameter[0] =
                    buffer.getFloat();
                joints[i].translationKeyframes[j].parameter[1] =
                    buffer.getFloat();
                joints[i].translationKeyframes[j].parameter[2] =
                    buffer.getFloat();
            }
        }
    }

Don't send a man to do a monkey's work.
Offline Mojomonkey

Senior Member




ooh ooh eee eeee


« Reply #43 - Posted 2003-07-02 18:19:10 »

Ok, while loading the data is now correct, the setupJoints method is totally whacked.

Don't send a man to do a monkey's work.
Offline Mojomonkey

Senior Member




ooh ooh eee eeee


« Reply #44 - Posted 2003-07-04 16:13:34 »

Hey Mik,

Don't know if you are still interested, but I've put aside the Milkshape Animation for a moment and I am moving on to Quake 3 Loading and Animating. I am successfully loading all the Milkshape data (joints and all) but having trouble getting them to animate. My hope is to write a Quake 3 loader and get that animating and that may help me with the Milkshape. My design is such that the loaders build a common model anyways.

I'd still be interested in your progress though. So, let me know if you have any luck.

Don't send a man to do a monkey's work.
Offline dodgy

Junior Newbie




It wasn't me.


« Reply #45 - Posted 2003-08-07 08:42:00 »

Hi mik and mojo.

I've also started on a bones animation project for ms3d.
Did u guys finish your or did you move on to mdl loaders? Anyway my program loads all the data and setups the joints correctly. Just gona battle it out some more with the Quartenions and the timer stuff and hopefully it will work. Right now it displays the image but no animation. Also I want to separate the animation from the model file and insted load in animation files like smd.

/dodgy
Offline Mojomonkey

Senior Member




ooh ooh eee eeee


« Reply #46 - Posted 2003-08-07 14:28:08 »

I got as far as loading the joints, and then moved on to MD3. I was having problems with my joint translations, causing the vertices to be totally put out of whack. If you get a loader done, I'd love to see what you did for animation.

Don't send a man to do a monkey's work.
Offline TarmTarm

Senior Newbie




Write once, never run.


« Reply #47 - Posted 2003-08-07 17:49:42 »

I used the tutorial at http://rsn.gamedev.net/tutorials/ms3danim.asp and got it to work. Since the whole class is to long I'll just post four methods:

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
50  
51  
52  
53  
54  
55  
56  
57  
58  
59  
60  
61  
62  
63  
64  
65  
66  
67  
68  
69  
70  
71  
72  
73  
74  
75  
76  
77  
78  
79  
80  
81  
82  
83  
84  
85  
86  
87  
88  
89  
90  
91  
92  
93  
94  
95  
96  
97  
98  
99  
100  
101  
102  
103  
104  
105  
106  
107  
108  
109  
110  
111  
112  
113  
114  
115  
116  
117  
118  
119  
120  
121  
122  
123  
124  
125  
126  
127  
128  
129  
130  
131  
132  
133  
134  
135  
136  
137  
138  
139  
140  
141  
142  
143  
144  
145  
146  
147  
148  
149  
150  
151  
152  
153  
154  
155  
156  
157  
158  
159  
160  
161  
162  
163  
164  
165  
166  
167  
168  
169  
170  
171  
172  
173  
174  
175  
176  
177  
178  
179  
180  
181  
182  
183  
184  
185  
186  
187  
188  
189  
190  
191  
192  
193  
194  
195  
196  
197  
198  
199  
200  
201  
202  
203  
204  
205  
206  
207  
208  
209  
210  
211  
212  
213  
214  
public void setupJoints() {

        for (int i = 0; i < numJoints; i++) {
            Joint joint = joints[i];

            joint.relative.setRotationRadians(joint.rotation);
            joint.relative.setTranslation(joint.translation);
            joint.parent = -1;
            for (int j = 0; j < numJoints; j++) {
                if (joints[j].name.compareTo(joint.parentName) == 0)
                    joint.parent = j;
            }

            if (joint.parent != -1) {
                joint.absolute.set(joints[joint.parent].absolute.getMatrix());
                joint.absolute.postMultiply(joint.relative);
            } else {
                joint.absolute.set(joint.relative.getMatrix());
            }

        }

        for (int i = 0; i < numVertices; i++) {
            Vertex vertex = vertices[i];

            if (vertex.boneId != -1) {
                Matrix matrix = joints[vertex.boneId].absolute;

                vertex.point = matrix.inverseTranslateVect(vertex.point);
                vertex.point = matrix.inverseRotateVect(vertex.point);
            }
        }

        for (int i = 0; i < numTriangles; i++) {
            Triangle triangle = triangles[i];

            for (int j = 0; j < 3; j++) {
                Vertex vertex = vertices[triangle.vertexIndices[j]];
                if (vertex.boneId != -1) {
                    Matrix matrix = joints[vertex.boneId].absolute;

                    triangle.vertexNormals[j] = matrix.inverseRotateVect(triangle.vertexNormals[j]);
                }
            }
        }
    }

void advanceAnimation() {
        double time = timer.getTime();
        if (time > totalTime) {
            if (looping) {
                restart();
                time = 0;
            } else
                time = totalTime;
        }

        for (int i = 0; i < numJoints; i++) {
            float[] transVec = new float[3];
            Matrix transform = new Matrix();
            int frame;
            Joint joint = joints[i];

            if (joint.numRotationKeyframes == 0 && joint.numTranslationKeyframes == 0) {
                joint.m_final.set(joint.absolute.getMatrix());
                continue;      // OBS!
           }

            frame = joint.currentTranslationkeyframe;
            while (frame < joint.numTranslationKeyframes &&
                    joint.translationKeyframes[frame].time < time) {
                frame++;

            }
            joint.currentTranslationkeyframe = frame;
            if (frame == 0)
                transVec = joint.translationKeyframes[0].parameter;
//                     memcpy( transVec, joint.translationKeyframes[0].parameter, sizeof ( float )*3 );
           else if (frame == joint.numTranslationKeyframes)
                transVec = joint.translationKeyframes[frame - 1].parameter;
//                     memcpy( transVec, joint.translationKeyframes[frame-1].parameter, sizeof ( float )*3 );
           else {
//                     assert( frame > 0 && frame < joint.numTranslationKeyframes );

                Keyframe curFrame = joint.translationKeyframes[frame];
                Keyframe prevFrame = joint.translationKeyframes[frame - 1];

                float timeDelta = curFrame.time - prevFrame.time;
                float interpValue = (float) ((time - prevFrame.time) / timeDelta);

                transVec[0] = prevFrame.parameter[0] + (curFrame.parameter[0] - prevFrame.parameter[0]) * interpValue;
                transVec[1] = prevFrame.parameter[1] + (curFrame.parameter[1] - prevFrame.parameter[1]) * interpValue;
                transVec[2] = prevFrame.parameter[2] + (curFrame.parameter[2] - prevFrame.parameter[2]) * interpValue;
            }

            frame = joint.currentRotationkeyframe;
            while (frame < joint.numRotationKeyframes &&
                    joint.rotationKeyframes[frame].time < time) {
                frame++;
            }
            joint.currentRotationkeyframe = frame;

            if (frame == 0)
                transform.setRotationRadians(joint.rotationKeyframes[0].parameter);
            else if (frame == joint.numRotationKeyframes)
                transform.setRotationRadians(joint.rotationKeyframes[frame - 1].parameter);
            else {
//                   assert( frame > 0 && frame < pJoint->m_numRotationKeyframes );

                Keyframe curFrame = joint.rotationKeyframes[frame];
                Keyframe prevFrame = joint.rotationKeyframes[frame - 1];

                float timeDelta = curFrame.time - prevFrame.time;
                float interpValue = (float) ((time - prevFrame.time) / timeDelta);

                //          assert( interpValue >= 0 && interpValue <= 1 );

                Quaternion qPrev = new Quaternion(prevFrame.parameter);
                Quaternion qCur = new Quaternion(curFrame.parameter);
                Quaternion qFinal = new Quaternion(qPrev, qCur, interpValue);
                transform.setRotationQuaternion(qFinal);
            }
            transform.setTranslation(transVec);

            Matrix relativeFinal = new Matrix(joint.relative);
            relativeFinal.postMultiply(transform);

            if (joint.parent == -1)
                joint.m_final.set(relativeFinal.getMatrix());
            else {
                joint.m_final.set(joints[joint.parent].m_final.getMatrix());
                joint.m_final.postMultiply(relativeFinal);
            }
        }
    }


    public void draw() {
        advanceAnimation();
        boolean texEnabled = gl.glIsEnabled(GL.GL_TEXTURE_2D);
        // Draw by group
       for (int i = 0; i < numMeshes; i++) {
            int materialIndex = meshes[i].materialIndex;
            if (materialIndex >= 0) {
                gl.glMaterialfv(GL.GL_FRONT, GL.GL_AMBIENT, materials[materialIndex].ambient);
                gl.glMaterialfv(GL.GL_FRONT, GL.GL_DIFFUSE, materials[materialIndex].diffuse);
                gl.glMaterialfv(GL.GL_FRONT, GL.GL_SPECULAR, materials[materialIndex].specular);
                gl.glMaterialfv(GL.GL_FRONT, GL.GL_EMISSION, materials[materialIndex].emissive);
                gl.glMaterialf(GL.GL_FRONT, GL.GL_SHININESS, materials[materialIndex].shininess);

                if (materials[i].textureFilename.length() > 0) {
                    textureManager.bindTexture(materials[i].textureFilename);
                    gl.glEnable(GL.GL_TEXTURE_2D);
                } else
                    gl.glDisable(GL.GL_TEXTURE_2D);
            } else {
                // Material properties?
               gl.glDisable(GL.GL_TEXTURE_2D);
            }

            gl.glBegin(GL.GL_TRIANGLES);
            {
                for (int j = 0; j < meshes[i].numTriangles; j++) {
                    int triangleIndex = meshes[i].triangleIndices[j];
                    Triangle pTri = (Triangle) (triangles[triangleIndex]);

                    for (int k = 0; k < 3; k++) {

                        int index = pTri.vertexIndices[k];

                        if (vertices[index].boneId == -1) {
                            // same as before
                           gl.glTexCoord2f(pTri.s[k], pTri.t[k]);
                            gl.glNormal3fv(pTri.vertexNormals[k]);
                            gl.glVertex3fv(vertices[index].point);

                        } else {
                            // rotate according to transformation matrix
                           Matrix finalMatrix = joints[vertices[index].boneId].m_final;

                            gl.glTexCoord2f(pTri.s[k], pTri.t[k]);
                            Vector newNormal = new Vector(pTri.vertexNormals[k]);
                            newNormal.transform3(finalMatrix);
                            newNormal.normalize();

                            gl.glNormal3fv(newNormal.getVector3());
                            Vector newVertex = new Vector(vertices[index].point);
                            newVertex.transform(finalMatrix);

                            gl.glVertex3fv(newVertex.getVector3());

                        }
                    }
                }
            }
            gl.glEnd();
        }

        if (texEnabled)
            gl.glEnable(GL.GL_TEXTURE_2D);
        else
            gl.glDisable(GL.GL_TEXTURE_2D);


    }

   public void restart() {
        for (int i = 0; i < numJoints; i++) {
            joints[i].currentRotationkeyframe = joints[i].currentTranslationkeyframe = 0;
            joints[i].m_final.set(joints[i].absolute.getMatrix());
        }

        timer.reset();
    }
Offline Java Cool Dude

Senior Member




Java forever


« Reply #48 - Posted 2003-08-07 19:57:52 »

I got this error running the loader
F:\JOGL\MS3D Loader>java -jar nehe31.jar
INIT GL IS: net.java.games.jogl.impl.windows.WindowsGLImpl
Force TGA : data/Wood.TGA
java.lang.NoClassDefFoundError: net/java/games/util/TGAImage
       at MilkshapeModel.LoadGLTextures(MilkshapeModel.java:690)
       at MilkshapeModel.reloadTextures(MilkshapeModel.java:660)
       at MilkshapeModel.loadModelData(MilkshapeModel.java:555)
       at MilkshapeModel.loadModelData(MilkshapeModel.java:399)
       at Nehe31$Renderer.init(Nehe31.java:116)
       at net.java.games.jogl.impl.GLDrawableHelper.init(GLDrawableHelper.java:
68)
       at net.java.games.jogl.GLCanvas$InitAction.run(GLCanvas.java:201)
       at net.java.games.jogl.impl.windows.WindowsGLContext.makeCurrent(Windows
GLContext.java:144)
       at net.java.games.jogl.impl.windows.WindowsOnscreenGLContext.makeCurrent
(WindowsOnscreenGLContext.java:110)
       at net.java.games.jogl.impl.GLContext.setRenderingThread(GLContext.java:
253)
       at net.java.games.jogl.GLCanvas.setRenderingThread(GLCanvas.java:162)
       at net.java.games.jogl.Animator$1.run(Animator.java:89)
       at java.lang.Thread.run(Unknown Source)
Offline dodgy

Junior Newbie




It wasn't me.


« Reply #49 - Posted 2003-08-07 21:08:46 »


I used the same tutorial Tarm. Wich Timer did you use?
My app runs but its looks like shit... vertices and stuff everywhere...

I wonder if it is the timer that is wrong. Which model have you tested it on?
Offline Mojomonkey

Senior Member




ooh ooh eee eeee


« Reply #50 - Posted 2003-08-07 21:20:28 »

Quote
vertices and stuff everywhere...


sounds exactly like what I am experiencing. :-/

Don't send a man to do a monkey's work.
Offline Java Cool Dude

Senior Member




Java forever


« Reply #51 - Posted 2003-08-07 21:38:19 »

Any help with that TGAImage class, or shall I code my own Cry
Offline TarmTarm

Senior Newbie




Write once, never run.


« Reply #52 - Posted 2003-08-07 21:41:13 »

I tried it on "bert.ms3d". I think it's included when you download milkshape.

Here is my timer class
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
public class Timer {
    double timerStart;
    int pauseCount = 0;
    double pauseTime = 0;

    public Timer() {
        timerStart = System.currentTimeMillis();
        pauseCount = 0;
        pauseTime = 0;
    }

    public void reset() {
        timerStart = System.currentTimeMillis();
    }

    public double getTime() {
        if (pauseCount > 0)
            return pauseTime;

        return (System.currentTimeMillis() - timerStart);
    }

    void pause() {
        if (pauseCount == 0)
            pauseTime = System.currentTimeMillis();

        pauseCount++;
    }

    void unpause() {
        if (pauseCount > 0) ;
        pauseCount--;

        if (pauseCount == 0) {
            timerStart = (System.currentTimeMillis() - pauseTime);
        }
    }

}


Remember that c++ uses pointers, porting from c++ to java isn't always very easy. If you get vertices at very odd places it might be because you are passing on a reference to a method when you need to copy the value instead.
Offline dodgy

Junior Newbie




It wasn't me.


« Reply #53 - Posted 2003-08-08 06:41:52 »

Im using a model called fantasy. Its basicly just a head with headspikes growing out of it as an animation. Its good for testing as it is quit simple. The animation works but the spikes seem to grow in the wrong direction.. coming out under the head instead of ontop of it.

This could surely be a reference problem that Tarm was talking about. God knows I have been known to get into trouble with pointers.

I could also be an matematichal error, maybee my slerp funtion in Quarteninons is faulty or something.

Anyway, gona look at it tonight when I come home from work.

Be well guys.

/d
Offline Java Cool Dude

Senior Member




Java forever


« Reply #54 - Posted 2003-08-08 21:05:52 »

Can I get some help please?
The loader won't work for me as it's missing some TGAImage class...
Do I really need to reinvent the wheel and code my own loader:'(
Offline tortoise

Junior Member




<3 Shmups


« Reply #55 - Posted 2003-08-08 21:39:08 »

TGAImage is a part of the jogl utils jar which I believe is here

https://jogl.dev.java.net/servlets/ProjectDocumentList?folderID=159

in the jogl-demos.tar.gz
Offline dodgy

Junior Newbie




It wasn't me.


« Reply #56 - Posted 2003-08-09 10:25:46 »


I messed a little with my postMulty method and now my models look good except that nothing gets animated... very strange.

Maybee there are some strange stuff in my Matrix/Quart classes. idont know.

/d
Offline Big_Bear_Scot

Junior Newbie




Java games rock!


« Reply #57 - Posted 2004-05-13 22:54:56 »

Just reviving an old thread here  Grin

I am currently in the process of creating a loader for JOGL using the GL4JAVA port of Nehe lesson31 as a basis for my loader.

I have completed the loader but when I try to animate the Model, the Model seems to explode outwards with vertices every where. When I remove the animate function the model loads thing with no Animation.

Did anybody complete their Milkshape Loader with Skeletal Animation ?

If not can anybody have a wee look at my Animation code and see if i have made any mistakes.

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
50  
51  
52  
53  
54  
55  
56  
57  
58  
59  
60  
61  
62  
63  
64  
65  
66  
67  
68  
69  
70  
71  
72  
73  
74  
75  
76  
77  
78  
79  
80  
81  
82  
83  
84  
85  
86  
87  
88  
89  
90  
91  
92  
93  
94  
      void advancedAnimation(){


            double timer=time.getTime();


            if(timer>m_totalTime){
                  if(m_looping){
                        restart();
                        timer=0;
                  }
                  else{
                        timer=m_totalTime;
                  }
            }

            for (int i=0;i<m_numJoints;i++){
                  float[] transvec= new float[3];
                  Matrix transform=new Matrix();
                  int frame;

                  Joint joint=m_pJoints[i];

                  if (joint.m_numTranslationKeyframes==0 && joint.m_numTranslationKeyframes==0){
                        joint.m_final.set(joint.m_absolute.getMatrix());
                        continue;
                  }
                  frame=joint.m_currentTranslationkeyframe;

                  while (frame < joint.m_numTranslationKeyframes &&
                  joint.m_pTranslationkeyframes[frame].m_time < timer) {
                        frame++;
                  }
                  joint.m_currentTranslationkeyframe = frame;
                  if (frame==0){
                        transvec=joint.m_pTranslationkeyframes[0].m_parameters;
                  }
                  else if (frame==joint.m_numTranslationKeyframes)
                        transvec=joint.m_pTranslationkeyframes[frame-1].m_parameters;
                  else{
                        Keyframe curFrame=joint.m_pTranslationkeyframes[frame];
                        Keyframe prevFrame=joint.m_pTranslationkeyframes[frame-1];

                        float timeDelta=curFrame.m_time-prevFrame.m_time;
                        float interpvalue=(float)((timer-prevFrame.m_time)/timeDelta);

                        transvec[0]=prevFrame.m_parameters[0]+(curFrame.m_parameters[0]
                        -prevFrame.m_parameters[0])*interpvalue;
                        transvec[1]=prevFrame.m_parameters[1]+(curFrame.m_parameters[1]
                        -prevFrame.m_parameters[1])*interpvalue;
                        transvec[2]=prevFrame.m_parameters[2]+(curFrame.m_parameters[2]
                        -prevFrame.m_parameters[2])*interpvalue;
                  }

                  frame=joint.m_currentRotationkeyframe;

                  while (frame < joint.m_numRotationKeyframes &&
                  joint.m_pRotationkeyframes[frame].m_time < timer) {
                        frame++;
                  }
                  joint.m_currentRotationkeyframe=frame;
                  if (frame==0){
                        transform.setRotationRadians(joint.m_pRotationkeyframes[0].m_parameters);
                  }
                  else if (frame==joint.m_numRotationKeyframes)
                        transform.setRotationRadians(joint.m_pRotationkeyframes[frame-1].m_parameters);
                  else{
                        Keyframe curFrame=joint.m_pRotationkeyframes[frame];
                        Keyframe prevFrame=joint.m_pRotationkeyframes[frame-1];

                        float timeDelta=curFrame.m_time-prevFrame.m_time;
                        float interpvalue=(float)((timer-prevFrame.m_time)/timeDelta);

                        Quaternion qPrev= new Quaternion(prevFrame.m_parameters);
                        Quaternion qCur= new Quaternion(curFrame.m_parameters);
                        Quaternion qFinal = new Quaternion(qPrev,qCur,interpvalue);
                        transform.setRotationQuaternion(qFinal);
                  }

                  transform.setTranslation(transvec);

                  Matrix relativeFinal=new Matrix(joint.m_relative.getMatrix());
                  relativeFinal.postMultiply(transform);

                  if (joint.m_parent==-1){
                        joint.m_final.set(relativeFinal.getMatrix());
                  }
                  else{
                        joint.m_final.set(m_pJoints[joint.m_parent].m_final.getMatrix());
                        joint.m_final.postMultiply(relativeFinal);
                  }
            }

      }


Thanks in advance

*****EDIT******

Heres a screen capture of my app running with the Animation function taken out

http://www.honours.pwp.blueyonder.co.uk/noAnim.jpg

With the Animation function put in

http://www.honours.pwp.blueyonder.co.uk/probVertsEverywhere.jpg

*************Another edit**********

Messed about with my animation function, got some sort of animation but it seems like the had is coming out of the models chest and the arms and legs look weird

http://www.honours.pwp.blueyonder.co.uk/probsweirdAnim.jpg

Maybe a problem with my Matrix class or Quaternion class
Pages: 1 [2]
  ignore  |  Print  
 
 
You cannot reply to this message, because it is very, very old.

 

Add your game by posting it in the WIP section,
or publish it in Showcase.

The first screenshot will be displayed as a thumbnail.

ctomni231 (32 views)
2014-07-18 06:55:21

Zero Volt (28 views)
2014-07-17 23:47:54

danieldean (24 views)
2014-07-17 23:41:23

MustardPeter (25 views)
2014-07-16 23:30:00

Cero (40 views)
2014-07-16 00:42:17

Riven (42 views)
2014-07-14 18:02:53

OpenGLShaders (29 views)
2014-07-14 16:23:47

Riven (29 views)
2014-07-14 11:51:35

quew8 (26 views)
2014-07-13 13:57:52

SHC (63 views)
2014-07-12 17:50:04
HotSpot Options
by dleskov
2014-07-08 03:59:08

Java and Game Development Tutorials
by SwordsMiner
2014-06-14 00:58:24

Java and Game Development Tutorials
by SwordsMiner
2014-06-14 00:47:22

How do I start Java Game Development?
by ra4king
2014-05-17 11:13:37

HotSpot Options
by Roquen
2014-05-15 09:59:54

HotSpot Options
by Roquen
2014-05-06 15:03:10

Escape Analysis
by Roquen
2014-04-29 22:16:43

Experimental Toys
by Roquen
2014-04-28 13:24:22
java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!