Subversion Repositories AndroidProjects

Rev

Rev 1803 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1718 chris 1
package com.gebauz.bauzoid2.graphics.model;
2
 
1738 chris 3
import com.badlogic.gdx.Gdx;
4
import com.badlogic.gdx.graphics.Texture;
1719 chris 5
import com.badlogic.gdx.utils.JsonReader;
6
import com.badlogic.gdx.utils.JsonValue;
1718 chris 7
import com.gebauz.bauzoid2.file.FileUtil;
1764 chris 8
import com.gebauz.bauzoid2.game.Consts;
1718 chris 9
import com.gebauz.bauzoid2.game.Engine;
1773 chris 10
import com.gebauz.bauzoid2.graphics.animation.Animation;
11
import com.gebauz.bauzoid2.graphics.animation.BoneKeyframes;
1720 chris 12
import com.gebauz.bauzoid2.graphics.geometry.IndexStream;
13
import com.gebauz.bauzoid2.graphics.geometry.VertexAttribute;
14
import com.gebauz.bauzoid2.graphics.geometry.VertexStream;
1802 chris 15
import com.gebauz.bauzoid2.graphics.util.Transform;
1723 chris 16
import com.gebauz.bauzoid2.math.Matrix4;
17
import com.gebauz.bauzoid2.math.Quaternion;
1773 chris 18
import com.gebauz.bauzoid2.math.Vector3;
1718 chris 19
 
1747 chris 20
import java.lang.reflect.Field;
1750 chris 21
import java.util.ArrayDeque;
1719 chris 22
import java.util.ArrayList;
1750 chris 23
import java.util.Deque;
1718 chris 24
 
1764 chris 25
import sun.security.provider.certpath.Vertex;
26
 
1718 chris 27
public class GdxModelUtil
28
{
1762 chris 29
    public final static int NUM_POSITION_COORDS = 3;
30
    public final static int NUM_NORMAL_COORDS = 3;
31
    public final static int NUM_TEXCOORD_COORDS = 2;
32
    public final static int NUM_COLOR_COORDS = 4;
33
    public final static int NUM_COLOR_PACKED_COORDS = 1;
34
    public final static int NUM_TANGENT_COORDS = 3;
35
    public final static int NUM_BINORMAL_COORDS = 3;
36
    public final static int NUM_BLENDWEIGHT_COORDS = 2;
1718 chris 37
 
1762 chris 38
    public final static int NUM_COMBINED_BLENDINDICES_COORDS = 4;
39
    public final static int NUM_COMBINED_BLENDWEIGHTS_COORDS = 4;
40
 
1738 chris 41
    public static class MeshData
1719 chris 42
    {
43
        public String[] attributes = null;
44
        public float[] vertices = null;
1720 chris 45
        public int numIndices = 0;
1719 chris 46
 
47
        public ArrayList<PartData> parts = new ArrayList<PartData>();
48
    }
49
 
1738 chris 50
    public static class PartData
1719 chris 51
    {
52
        public String id = null;
53
        public String type = null;
1720 chris 54
        public short[] indices = null;
1719 chris 55
    }
56
 
1738 chris 57
    public static class MaterialData
1719 chris 58
    {
59
        public String id = null;
60
 
61
        public ArrayList<TextureData> textures = new ArrayList<TextureData>();
1736 chris 62
        float[] ambient = null;
63
        float[] diffuse = null;
64
        float[] emissive = null;
65
        float opacity = 1.0f;
66
        float[] specular = null;
67
        float shininess = 1.0f;
1719 chris 68
    }
69
 
1738 chris 70
    public static class TextureData
1719 chris 71
    {
72
        public String id = null;
73
        public String type = null;
74
        public String filename = null;
1738 chris 75
 
76
        public boolean isAsync = false;
1719 chris 77
    }
78
 
1746 chris 79
    public static class NodePartData
1719 chris 80
    {
1720 chris 81
        public String subMeshId = null;
1719 chris 82
        public String materialId = null;
1746 chris 83
 
84
        public ArrayList<BoneData> bones = new ArrayList<BoneData>();
85
 
86
        // TODO: uvmapping
1719 chris 87
    }
88
 
1738 chris 89
    public static class NodeData
1719 chris 90
    {
91
        public String id = null;
92
 
1723 chris 93
        public float[] translation = null;
94
        public float[] rotation = null;
95
        public float[] scale = null;
96
 
1746 chris 97
        public ArrayList<NodePartData> parts = new ArrayList<NodePartData>();
98
 
99
        public ArrayList<NodeData> children = new ArrayList<NodeData>();
1751 chris 100
 
101
        public NodeData parent = null;
1719 chris 102
    }
103
 
1746 chris 104
    public static class BoneData
105
    {
106
        String nodeId = null;
107
 
108
        public float[] translation = null;
109
        public float[] rotation = null;
110
        public float[] scale = null;
111
    }
112
 
1771 chris 113
    public static class KeyframeData
1746 chris 114
    {
1771 chris 115
        float time = 0.0f;
1746 chris 116
 
1771 chris 117
        public float[] translation = null;
118
        public float[] rotation = null;
119
        public float[] scale = null;
1746 chris 120
    }
121
 
1771 chris 122
    public static class BoneKeyframeData
123
    {
124
        public String boneId = null;
125
        public ArrayList<KeyframeData> keyframes = new ArrayList<KeyframeData>();
126
    }
127
 
128
    public static class AnimationData
129
    {
130
        public String id = null;
131
        public ArrayList<BoneKeyframeData> boneKeys = new ArrayList<BoneKeyframeData>();
132
    }
133
 
1737 chris 134
    public static class GdxModelDescriptor
135
    {
1747 chris 136
        public int[] version = null;
137
 
1737 chris 138
        public String id = null;
139
        public ArrayList<MeshData> meshes = new ArrayList<MeshData>();
1746 chris 140
        public ArrayList<MaterialData> materials = new ArrayList<MaterialData>();
141
        public ArrayList<NodeData> nodes = new ArrayList<NodeData>();
142
        public ArrayList<AnimationData> animations = new ArrayList<AnimationData>();
1719 chris 143
 
1737 chris 144
        public GdxModelDescriptor()
145
        {
146
        }
147
    }
148
 
1718 chris 149
    private GdxModelUtil() {}
150
 
1737 chris 151
    public static GdxModelDescriptor readModel(String filename)
1718 chris 152
    {
153
        String modelFile = FileUtil.loadString(filename);
154
 
1719 chris 155
        JsonValue root = new JsonReader().parse(modelFile);
1718 chris 156
 
1737 chris 157
        GdxModelDescriptor descriptor = new GdxModelDescriptor();
1719 chris 158
 
159
        for (JsonValue entry : root)
1718 chris 160
        {
1719 chris 161
            if (entry.name.equalsIgnoreCase("version"))
1718 chris 162
            {
1747 chris 163
                try
164
                {
165
                    Field f = GdxModelDescriptor.class.getField(entry.name);
166
                    if (f.getType().isArray())
167
                    {
168
                        if (f.getType().getComponentType() == int.class)
169
                        {
170
                            f.set(descriptor, entry.asIntArray());
171
                        }
172
                    }
173
                    Engine.log("bla");
174
                }
175
                catch (Exception ex)
176
                {
177
                    Engine.log(ex.getMessage());
178
                }
1718 chris 179
 
1747 chris 180
                //int[] version = entry.asIntArray();
181
 
182
                Engine.log("G3DJ Version: " + descriptor.version[0] + "." + descriptor.version[1]);
1719 chris 183
            }
184
            else if (entry.name.equalsIgnoreCase("id"))
185
            {
1737 chris 186
                descriptor.id = entry.asString();
1719 chris 187
            }
188
            else if (entry.name.equalsIgnoreCase("meshes"))
189
            {
190
                for (JsonValue meshEntry : entry)
191
                {
1737 chris 192
                    descriptor.meshes.add(processMesh(meshEntry));
1719 chris 193
                }
194
            }
195
            else if (entry.name.equalsIgnoreCase("materials"))
196
            {
197
                for (JsonValue materialEntry : entry)
198
                {
1737 chris 199
                    descriptor.materials.add(processMaterial(materialEntry));
1719 chris 200
                }
201
            }
202
            else if (entry.name.equalsIgnoreCase("nodes"))
203
            {
204
                for (JsonValue nodeEntry : entry)
205
                {
1737 chris 206
                    descriptor.nodes.add(processNode(nodeEntry));
1719 chris 207
                }
208
            }
1746 chris 209
            else if (entry.name.equalsIgnoreCase("animations"))
210
            {
211
                for (JsonValue animationEntry : entry)
212
                {
213
                    descriptor.animations.add(processAnimation(animationEntry));
214
                }
215
            }
1719 chris 216
        }
1718 chris 217
 
1737 chris 218
        return descriptor;
219
    }
1718 chris 220
 
1737 chris 221
    public static Model buildModel(GdxModelDescriptor descriptor)
222
    {
1773 chris 223
        return buildModel(descriptor.id, descriptor.meshes, descriptor.materials, descriptor.nodes, descriptor.animations);
1719 chris 224
    }
1718 chris 225
 
1773 chris 226
    public static Model buildModel(String id, ArrayList<MeshData> meshDatas, ArrayList<MaterialData> materialDatas,
227
                                                                   ArrayList<NodeData> nodeDatas, ArrayList<AnimationData> anims)
1719 chris 228
    {
229
        Model model = new Model(id);
1718 chris 230
 
1720 chris 231
        Mesh[] meshes = new Mesh[meshDatas.size()];
1718 chris 232
 
1720 chris 233
        for (int meshIndex = 0; meshIndex < meshDatas.size(); meshIndex++)
1719 chris 234
        {
1720 chris 235
            MeshData meshData = meshDatas.get(meshIndex);
236
            meshes[meshIndex] = new Mesh();
1718 chris 237
 
1757 chris 238
            ArrayList<VertexAttribute> attribs = new ArrayList<VertexAttribute>();
1718 chris 239
 
1720 chris 240
            int byteOffset = 0;
241
            int coords = 0;
242
 
1764 chris 243
            ArrayList<VertexStream> vertexStreams = buildVertexStream(attribs, meshData.attributes, meshData.vertices);
244
            meshes[meshIndex].getGeometry().setVertexStreams(vertexStreams.toArray(new VertexStream[vertexStreams.size()]));
1718 chris 245
 
1720 chris 246
            short[] indices = new short[meshData.numIndices];
247
            int indexOffset = 0;
1718 chris 248
 
1720 chris 249
            MeshGroup[] subMeshes = new MeshGroup[meshData.parts.size()];
250
            for (int partIndex = 0; partIndex < meshData.parts.size(); partIndex++)
251
            {
252
                PartData part = meshData.parts.get(partIndex);
253
 
254
                System.arraycopy(part.indices, 0, indices, indexOffset, part.indices.length);
255
 
256
                subMeshes[partIndex] = new MeshGroup(meshes[meshIndex], part.id, indexOffset, indexOffset + part.indices.length);
257
 
258
                indexOffset += part.indices.length;
1718 chris 259
            }
1720 chris 260
            meshes[meshIndex].setMeshGroups(subMeshes);
261
 
262
            IndexStream is = new IndexStream();
263
            is.setData(indices);
1721 chris 264
            is.upload();
265
            meshes[meshIndex].getGeometry().setIndexStream(is);
1718 chris 266
        }
1719 chris 267
 
1720 chris 268
        Material[] materials = new Material[materialDatas.size()];
269
        for (int materialIndex = 0; materialIndex < materialDatas.size(); materialIndex++)
270
        {
1736 chris 271
            // TODO: for now, only take first texture, always diffuse
1720 chris 272
            MaterialData matData = materialDatas.get(materialIndex);
1736 chris 273
            String textureFile = null;
1738 chris 274
            Texture texture = null;
1736 chris 275
            if (matData.textures.size() > 0)
276
            {
1738 chris 277
                TextureData texData = matData.textures.get(0);
278
                textureFile = texData.filename;
279
                if (texData.isAsync)
280
                {
281
                    texture = Engine.assets.get(textureFile);
282
                }
283
                else
284
                {
285
                    texture = new Texture(Gdx.files.internal(textureFile));
286
                }
1736 chris 287
            }
1738 chris 288
            materials[materialIndex] = new Material(matData.id, texture);
1736 chris 289
            //matData.textures
1720 chris 290
        }
291
 
292
        model.setMeshes(meshes);
293
        model.setMaterials(materials);
294
 
1750 chris 295
        int nodeCount = getTotalNodeCount(nodeDatas);
296
 
1780 chris 297
                ArrayList<ModelPart> partList = new ArrayList<ModelPart>();
298
                ArrayList<NodePartData> partDataList = new ArrayList<NodePartData>();
299
 
1751 chris 300
        ModelNode[] nodes = new ModelNode[nodeCount];
301
        int newNodeIndex = 0;
1720 chris 302
        for (int nodeIndex = 0; nodeIndex < nodeDatas.size(); nodeIndex++)
303
        {
1751 chris 304
            Deque<NodeData> stack = new ArrayDeque<NodeData>();
305
            Deque<Integer> parentStack = new ArrayDeque<Integer>();
306
            stack.push(nodeDatas.get(nodeIndex));
307
            parentStack.push(-1);
308
 
309
            while (!stack.isEmpty())
310
            {
311
                NodeData nodeData = stack.pop();
312
                int parentIndex = parentStack.pop();
313
 
314
                nodes[newNodeIndex] = new ModelNode(nodeData.id, parentIndex);
315
 
316
                if (nodeData.parts.size() > 0)
317
                {
318
                    ModelPart[] parts = new ModelPart[nodeData.parts.size()];
319
                    for (int partIndex = 0; partIndex < nodeData.parts.size(); partIndex++)
320
                    {
321
                        NodePartData pair = nodeData.parts.get(partIndex);
322
 
323
                        MeshGroup group = findSubMesh(meshes, pair.subMeshId);
324
                        Material material = findMaterial(materials, pair.materialId);
325
 
326
                        parts[partIndex] = new ModelPart(pair.subMeshId, group, material);
1780 chris 327
 
328
                                                // for later wiring
329
                                                partList.add(parts[partIndex]);
330
                                                partDataList.add(pair);
1751 chris 331
                    }
332
                    nodes[newNodeIndex].parts = parts;
333
                }
334
 
1774 chris 335
                                if (nodeData.scale != null)
1800 chris 336
                                        nodes[newNodeIndex].bindPose.scale.set(nodeData.scale);
1778 chris 337
                                if (nodeData.rotation != null)
1800 chris 338
                                        nodes[newNodeIndex].bindPose.rotation.set(nodeData.rotation);
1778 chris 339
                                if (nodeData.translation != null)
1800 chris 340
                                        nodes[newNodeIndex].bindPose.translation.set(nodeData.translation);
1778 chris 341
 
1800 chris 342
                nodes[newNodeIndex].transform.setFrom(nodes[newNodeIndex].bindPose);
343
 
1751 chris 344
                for (NodeData child : nodeData.children)
345
                {
346
                    stack.push(child);
347
                    parentStack.push(newNodeIndex);
348
                }
1753 chris 349
 
350
                newNodeIndex++;
1751 chris 351
            }
1720 chris 352
        }
353
 
1721 chris 354
        model.setNodes(nodes);
355
 
1780 chris 356
                // wire together bone influences
357
                for (int i = 0; i < partList.size(); i++)
358
                {
359
                        ModelPart part = partList.get(i);
360
                        NodePartData partData = partDataList.get(i);
361
 
1803 chris 362
                        if (partData.bones.size() == 0)
363
                                continue;
364
 
1780 chris 365
                        ModelNode[] influences = new ModelNode[partData.bones.size()];
1802 chris 366
                        Transform[] transforms = new Transform[partData.bones.size()];
1780 chris 367
                        for (int j = 0; j < partData.bones.size(); j++)
368
                        {
369
                                influences[j] = model.findNode(partData.bones.get(j).nodeId);
1802 chris 370
                                transforms[j] = new Transform();
371
                                transforms[j].translation.set(partData.bones.get(j).translation);
372
                                transforms[j].rotation.set(partData.bones.get(j).rotation);
373
                                transforms[j].scale.set(partData.bones.get(j).scale);
1780 chris 374
                        }
1804 chris 375
                        part.setBones(influences, transforms);
1780 chris 376
                }
377
 
1773 chris 378
                Animation[] animations = new Animation[anims.size()];
379
 
380
                for (int i = 0; i < anims.size(); i++)
381
                {
382
                        AnimationData animData = anims.get(i);
383
                        animations[i] = new Animation(animData.id);
384
 
1774 chris 385
                        float totalTime = 0.0f;
386
 
1773 chris 387
                        BoneKeyframes[] boneKeys = new BoneKeyframes[animData.boneKeys.size()];
388
                        for (int j = 0; j < animData.boneKeys.size(); j++)
389
                        {
390
                                BoneKeyframeData boneKeyData = animData.boneKeys.get(j);
391
 
1774 chris 392
                                ModelNode bone = model.findNode(boneKeyData.boneId);
393
                                boneKeys[j] = new BoneKeyframes(bone);
394
 
1773 chris 395
                                ArrayList<BoneKeyframes.RotationKey> rotations = new ArrayList<BoneKeyframes.RotationKey>();
396
 
397
                                for (KeyframeData keyframe : boneKeyData.keyframes)
398
                                {
399
                                        if (keyframe.translation != null)
400
                                        {
401
 
402
                                        }
403
                                        if (keyframe.rotation != null)
404
                                        {
405
                                                rotations.add(new BoneKeyframes.RotationKey(keyframe.time, new Quaternion(keyframe.rotation)));
406
                                        }
407
                                        if (keyframe.scale != null)
408
                                        {
409
 
410
                                        }
1774 chris 411
 
412
                                        if (keyframe.time > totalTime)
413
                                                totalTime = keyframe.time;
1773 chris 414
                                }
415
                                boneKeys[j].setRotationKeys(rotations.toArray(new BoneKeyframes.RotationKey[rotations.size()]));
416
                        }
417
 
418
                        animations[i].setBoneKeys(boneKeys);
1774 chris 419
                        animations[i].setTotalTime(totalTime);
1773 chris 420
                }
421
 
422
                model.setAnimations(animations);
423
 
1719 chris 424
        return model;
425
    }
426
 
1773 chris 427
        private static float[] toFloatArray(ArrayList<Float> array)
428
        {
429
                float[] rt = new float[array.size()];
430
                for (int k = 0; k < array.size(); k++)
431
                        rt[k] = array.get(k);
432
 
433
                return rt;
434
        }
435
 
1762 chris 436
    private static ArrayList<VertexStream> buildVertexStream(ArrayList<VertexAttribute> attribs, String[] attributes, float[] vertices)
1760 chris 437
    {
1762 chris 438
        int coordsPerVertex = calcVertexSize(attributes);
439
        int numVertices = vertices.length / coordsPerVertex;
440
 
1763 chris 441
        ArrayList<VertexStream> result = new ArrayList<VertexStream>();
442
 
1762 chris 443
        float[] coords = null;
444
        float[] normals = null;
445
        float[] texcoords = null;
446
        float[] blendIndices = null;
447
        float[] blendWeights = null;
448
 
449
        int offset = 0;
1786 chris 450
                int blendOffset = 0;
1762 chris 451
 
452
        for (String attr : attributes)
453
        {
454
            if (attr.equalsIgnoreCase("POSITION"))
455
            {
456
                coords = new float[numVertices*NUM_POSITION_COORDS];
1788 chris 457
                extractInterleaved(coords, 0, NUM_POSITION_COORDS, vertices, offset, coordsPerVertex, NUM_POSITION_COORDS);
1762 chris 458
                offset += NUM_POSITION_COORDS;
1763 chris 459
 
1764 chris 460
                result.add(createIndividualVertexStream(coords, VertexAttribute.POSITION, NUM_POSITION_COORDS, "POSITION"));
1762 chris 461
            }
462
            else if (attr.equalsIgnoreCase("NORMAL"))
463
            {
464
                normals = new float[numVertices*NUM_NORMAL_COORDS];
1788 chris 465
                extractInterleaved(normals, 0, NUM_NORMAL_COORDS, vertices, offset, coordsPerVertex, NUM_NORMAL_COORDS);
1762 chris 466
                offset += NUM_NORMAL_COORDS;
1764 chris 467
 
468
                result.add(createIndividualVertexStream(normals, VertexAttribute.NORMAL, NUM_NORMAL_COORDS, "NORMAL"));
1762 chris 469
            }
470
            else if (attr.equalsIgnoreCase("TEXCOORD0"))
471
            {
472
                texcoords = new float[numVertices*NUM_TEXCOORD_COORDS];
1788 chris 473
                extractInterleaved(texcoords, 0, NUM_TEXCOORD_COORDS, vertices, offset, coordsPerVertex, NUM_TEXCOORD_COORDS);
1762 chris 474
                offset += NUM_TEXCOORD_COORDS;
1764 chris 475
 
476
                result.add(createIndividualVertexStream(texcoords, VertexAttribute.TEXCOORD0, NUM_TEXCOORD_COORDS, "TEXCOORD0"));
1762 chris 477
            }
1788 chris 478
            else if (attr.startsWith("BLENDWEIGHT"))
1762 chris 479
            {
480
                if (blendIndices == null)
481
                    blendIndices = new float[numVertices*NUM_COMBINED_BLENDINDICES_COORDS];
482
                if (blendWeights == null)
483
                    blendWeights = new float[numVertices*NUM_COMBINED_BLENDWEIGHTS_COORDS];
1788 chris 484
                extractInterleaved(blendIndices, blendOffset, NUM_COMBINED_BLENDINDICES_COORDS, vertices, offset, coordsPerVertex, 1);
485
                extractInterleaved(blendWeights, blendOffset, NUM_COMBINED_BLENDWEIGHTS_COORDS, vertices, offset+1, coordsPerVertex, 1);
1786 chris 486
                                blendOffset++;
1762 chris 487
                offset += NUM_BLENDWEIGHT_COORDS;
488
            }
489
        }
490
 
1764 chris 491
        if ((blendIndices != null) && (blendWeights != null))
492
        {
493
            result.add(createIndividualVertexStream(blendIndices, VertexAttribute.BLENDINDICES, NUM_COMBINED_BLENDINDICES_COORDS, "BLENDINDICES"));
494
            result.add(createIndividualVertexStream(blendWeights, VertexAttribute.BLENDWEIGHTS, NUM_COMBINED_BLENDWEIGHTS_COORDS, "BLENDWEIGHTS"));
495
        }
496
 
497
        return result;
1760 chris 498
    }
499
 
1764 chris 500
    private static VertexStream createIndividualVertexStream(float[] data, int attribute, int numCoords, String name)
501
    {
502
        VertexAttribute[] vertexAttribs = new VertexAttribute[]
503
            {
504
                new VertexAttribute(attribute, numCoords, 0)
505
            };
506
        VertexStream vs = new VertexStream(VertexStream.StreamType.INDIVIDUAL, name, vertexAttribs, false);
507
        vs.setData(data, numCoords, numCoords * Consts.SIZEOF_FLOAT);
508
        vs.upload();
509
 
510
        return vs;
511
    }
512
 
1787 chris 513
    private static void extractInterleaved(float[] dest, int destOffset, int destStride, float[] src, int srcOffset, int srcStride, int count)
1762 chris 514
    {
1787 chris 515
        int targetIndex = 0;
516
        int sourceIndex = 0;
517
        while (sourceIndex < src.length)
1762 chris 518
        {
519
            for (int j = 0; j < count; j++)
1787 chris 520
                        {
521
                                dest[targetIndex + destOffset + j] = src[sourceIndex + srcOffset + j];
522
                        }
1762 chris 523
 
1787 chris 524
                        targetIndex += destStride;
525
            sourceIndex += srcStride;
1762 chris 526
        }
527
    }
528
 
1755 chris 529
    public static int calcVertexSize(String[] attribs)
530
    {
531
        int result = 0;
532
 
533
        for (String attr : attribs)
534
        {
535
            if (attr.equalsIgnoreCase("POSITION"))
1762 chris 536
                result += NUM_POSITION_COORDS;
1755 chris 537
            else if (attr.equalsIgnoreCase("NORMAL"))
1762 chris 538
                result += NUM_NORMAL_COORDS;
1755 chris 539
            else if (attr.equalsIgnoreCase("COLOR"))
1762 chris 540
                result += NUM_COLOR_COORDS;
1755 chris 541
            else if (attr.equalsIgnoreCase("COLORPACKED"))
1762 chris 542
                result += NUM_COLOR_PACKED_COORDS;
1755 chris 543
            else if (attr.equalsIgnoreCase("TANGENT"))
1762 chris 544
                result += NUM_TANGENT_COORDS;
1755 chris 545
            else if (attr.equalsIgnoreCase("BINORMAL"))
1762 chris 546
                result += NUM_BINORMAL_COORDS;
1755 chris 547
            else if (attr.startsWith("TEXCOORD"))
1762 chris 548
                result += NUM_TEXCOORD_COORDS;
1755 chris 549
            else if (attr.startsWith("BLENDWEIGHT"))
1762 chris 550
                result += NUM_BLENDWEIGHT_COORDS;
1755 chris 551
        }
552
 
553
        return result;
554
    }
555
 
1750 chris 556
    public static int getTotalNodeCount(ArrayList<NodeData> nodeDatas)
557
    {
558
        int nodeCount = 0;
559
        for (int nodeIndex = 0; nodeIndex < nodeDatas.size(); nodeIndex++)
560
        {
561
            NodeData rootNode = nodeDatas.get(nodeIndex);
562
 
563
            Deque<NodeData> stack = new ArrayDeque<NodeData>();
564
            stack.push(rootNode);
565
            while (!stack.isEmpty())
566
            {
567
                NodeData node = stack.pop();
568
                nodeCount++;
569
 
570
                for (int j = 0; j < node.children.size(); j++)
571
                {
572
                    stack.push(node.children.get(j));
573
                }
574
            }
575
        }
576
        return nodeCount;
577
    }
578
 
1720 chris 579
    public static MeshGroup findSubMesh(Mesh[] meshes, String id)
580
    {
581
        for (Mesh mesh : meshes)
582
        {
583
            for (MeshGroup group : mesh.getMeshGroups())
584
            {
585
                if (id.equalsIgnoreCase(group.getName()))
586
                    return group;
587
            }
588
        }
589
        return null;
590
    }
591
 
592
    public static Material findMaterial(Material[] materials, String id)
593
    {
594
        for (Material mat : materials)
595
        {
596
            if (id.equalsIgnoreCase(mat.getName()))
597
                return mat;
598
        }
599
        return null;
600
    }
601
 
1719 chris 602
    public static MeshData processMesh(JsonValue meshesEntry)
603
    {
604
        MeshData result = new MeshData();
1718 chris 605
 
1719 chris 606
        for (JsonValue entry : meshesEntry)
607
        {
608
            if (entry.name.equalsIgnoreCase("attributes"))
609
            {
610
                result.attributes = entry.asStringArray();
611
            }
612
            else if (entry.name.equalsIgnoreCase("vertices"))
613
            {
614
                result.vertices = entry.asFloatArray();
615
            }
616
            else if (entry.name.equalsIgnoreCase("parts"))
617
            {
1720 chris 618
                result.numIndices = 0;
1719 chris 619
                for (JsonValue partEntry : entry)
620
                {
621
                    result.parts.add(processParts(partEntry));
1720 chris 622
                    result.numIndices += result.parts.get(result.parts.size()-1).indices.length;
1719 chris 623
                }
624
            }
1718 chris 625
        }
1719 chris 626
 
627
        return result;
1718 chris 628
    }
629
 
1719 chris 630
    public static PartData processParts(JsonValue partsEntry)
1718 chris 631
    {
1719 chris 632
        PartData result = new PartData();
1718 chris 633
 
1719 chris 634
        for (JsonValue entry : partsEntry)
1718 chris 635
        {
1719 chris 636
            if (entry.name.equalsIgnoreCase("id"))
637
            {
638
                result.id = entry.asString();
639
            }
640
            else if (entry.name.equalsIgnoreCase("type"))
641
            {
642
                result.type = entry.asString();
643
            }
644
            else if (entry.name.equalsIgnoreCase("indices"))
645
            {
1720 chris 646
                result.indices = entry.asShortArray();
1719 chris 647
            }
1718 chris 648
        }
649
 
650
        return result;
651
    }
652
 
1719 chris 653
    public static MaterialData processMaterial(JsonValue materialsEntry)
1718 chris 654
    {
1719 chris 655
        MaterialData result = new MaterialData();
1718 chris 656
 
1719 chris 657
        for (JsonValue entry : materialsEntry)
1718 chris 658
        {
1719 chris 659
            if (entry.name.equalsIgnoreCase("id"))
660
            {
661
                result.id = entry.asString();
662
            }
663
            else if (entry.name.equalsIgnoreCase("textures"))
664
            {
665
                for (JsonValue textureEntry : entry)
666
                {
667
                    result.textures.add(processTexture(textureEntry));
668
                }
669
            }
1736 chris 670
            else if (entry.name.equalsIgnoreCase("ambient"))
671
            {
672
                result.ambient = entry.asFloatArray();
673
            }
674
            else if (entry.name.equalsIgnoreCase("diffuse"))
675
            {
676
                result.diffuse = entry.asFloatArray();
677
            }
678
            else if (entry.name.equalsIgnoreCase("emissive"))
679
            {
680
                result.emissive = entry.asFloatArray();
681
            }
682
            else if (entry.name.equalsIgnoreCase("opacity"))
683
            {
684
                result.opacity = entry.asFloat();
685
            }
686
            else if (entry.name.equalsIgnoreCase("specular"))
687
            {
688
                result.specular = entry.asFloatArray();
689
            }
690
            else if (entry.name.equalsIgnoreCase("shininess"))
691
            {
692
                result.shininess = entry.asFloat();
693
            }
1718 chris 694
        }
695
 
696
        return result;
697
    }
698
 
1719 chris 699
    public static TextureData processTexture(JsonValue textureEntry)
1718 chris 700
    {
1719 chris 701
        TextureData result = new TextureData();
702
 
703
        for (JsonValue entry : textureEntry)
704
        {
705
            if (entry.name.equalsIgnoreCase("id"))
706
            {
707
                result.id = entry.asString();
708
            }
709
            else if (entry.name.equalsIgnoreCase("filename"))
710
            {
711
                result.filename = entry.asString();
712
            }
713
            else if (entry.name.equalsIgnoreCase("type"))
714
            {
715
                result.type = entry.asString();
716
            }
717
        }
718
 
719
        return result;
1718 chris 720
    }
721
 
1719 chris 722
    public static NodeData processNode(JsonValue nodeEntry)
1718 chris 723
    {
1719 chris 724
        NodeData result = new NodeData();
725
 
726
        for (JsonValue entry : nodeEntry)
727
        {
728
            if (entry.name.equalsIgnoreCase("id"))
729
            {
730
                result.id = entry.asString();
731
            }
1723 chris 732
            else if (entry.name.equalsIgnoreCase("translation"))
733
            {
734
                result.translation = entry.asFloatArray();
735
            }
736
            else if (entry.name.equalsIgnoreCase("rotation"))
737
            {
738
                result.rotation = entry.asFloatArray();
739
            }
740
            else if (entry.name.equalsIgnoreCase("scale"))
741
            {
742
                result.scale = entry.asFloatArray();
743
            }
1719 chris 744
            else if (entry.name.equalsIgnoreCase("parts"))
745
            {
746
                for (JsonValue partEntry : entry)
747
                {
1746 chris 748
                    result.parts.add(processNodePart(partEntry));
1719 chris 749
                }
750
            }
1746 chris 751
            else if (entry.name.equalsIgnoreCase("children"))
752
            {
753
                for (JsonValue childEntry : entry)
754
                {
1751 chris 755
                    NodeData node = processNode(childEntry);
756
                    node.parent = result;
757
                    result.children.add(node);
1746 chris 758
                }
759
            }
1719 chris 760
        }
761
 
762
        return result;
1718 chris 763
    }
764
 
1746 chris 765
    public static NodePartData processNodePart(JsonValue partEntry)
1719 chris 766
    {
1746 chris 767
        NodePartData result = new NodePartData();
1719 chris 768
 
769
        for (JsonValue entry : partEntry)
770
        {
771
            if (entry.name.equalsIgnoreCase("meshpartid"))
772
            {
1720 chris 773
                result.subMeshId = entry.asString();
1719 chris 774
            }
775
            else if (entry.name.equalsIgnoreCase("materialid"))
776
            {
777
                result.materialId = entry.asString();
778
            }
1746 chris 779
            else if (entry.name.equalsIgnoreCase("bones"))
780
            {
781
                for (JsonValue boneEntry : entry)
782
                {
783
                    result.bones.add(processBone(boneEntry));
784
                }
785
            }
1719 chris 786
        }
787
 
788
        return result;
789
    }
1737 chris 790
 
1746 chris 791
    public static BoneData processBone(JsonValue boneEntry)
792
    {
793
        BoneData result = new BoneData();
794
 
795
        for (JsonValue entry : boneEntry)
796
        {
797
            if (entry.name.equalsIgnoreCase("node"))
798
            {
799
                result.nodeId = entry.asString();
800
            }
801
            else if (entry.name.equalsIgnoreCase("translation"))
802
            {
803
                result.translation = entry.asFloatArray();
804
            }
805
            else if (entry.name.equalsIgnoreCase("rotation"))
806
            {
807
                result.rotation = entry.asFloatArray();
808
            }
809
            else if (entry.name.equalsIgnoreCase("scale"))
810
            {
811
                result.scale = entry.asFloatArray();
812
            }
813
        }
1747 chris 814
 
815
        return result;
1746 chris 816
    }
817
 
818
    public static AnimationData processAnimation(JsonValue animEntry)
819
    {
820
        AnimationData result = new AnimationData();
821
 
822
        for (JsonValue entry : animEntry)
823
        {
824
            if (entry.name.equalsIgnoreCase("id"))
825
            {
1771 chris 826
                result.id = entry.asString();
827
            }
828
            else if (entry.name.equalsIgnoreCase("bones"))
829
            {
830
                for (JsonValue boneKeyEntry : entry)
831
                {
832
                    result.boneKeys.add(processBoneKeyframe(boneKeyEntry));
833
                }
834
            }
835
        }
1746 chris 836
 
1771 chris 837
        return result;
838
    }
839
 
840
    public static BoneKeyframeData processBoneKeyframe(JsonValue boneKeyEntry)
841
    {
842
        BoneKeyframeData result = new BoneKeyframeData();
843
 
844
        for (JsonValue entry : boneKeyEntry)
845
        {
846
            if (entry.name.equalsIgnoreCase("boneId"))
1746 chris 847
            {
1771 chris 848
                result.boneId = entry.asString();
849
            }
850
            else if (entry.name.equalsIgnoreCase("keyframes"))
851
            {
852
                for (JsonValue keyframeEntry : entry)
853
                {
854
                    result.keyframes.add(processKeyframe(keyframeEntry));
855
                }
856
            }
857
        }
1746 chris 858
 
1771 chris 859
        return result;
860
    }
861
 
862
    public static KeyframeData processKeyframe(JsonValue keyframeEntry)
863
    {
864
        KeyframeData result = new KeyframeData();
865
 
866
        for (JsonValue entry : keyframeEntry)
867
        {
1774 chris 868
            if (entry.name.equalsIgnoreCase("keytime"))
1771 chris 869
            {
870
                result.time = entry.asFloat();
1746 chris 871
            }
1771 chris 872
            else if (entry.name.equalsIgnoreCase("translation"))
873
            {
874
                result.translation = entry.asFloatArray();
875
            }
876
            else if (entry.name.equalsIgnoreCase("rotation"))
877
            {
878
                result.rotation = entry.asFloatArray();
879
            }
880
            else if (entry.name.equalsIgnoreCase("scale"))
881
            {
882
                result.scale = entry.asFloatArray();
883
            }
1746 chris 884
        }
885
 
886
        return result;
887
    }
888
 
1718 chris 889
}