OSDN Git Service

added a model loader for the OpenCTM file format using the lib JOpenCTM
authorDaniel Heinrich <dannynullzwo@gmail.com>
Sun, 16 Sep 2012 05:02:29 +0000 (13:02 +0800)
committerDaniel Heinrich <dannynullzwo@gmail.com>
Sun, 16 Sep 2012 05:02:29 +0000 (13:02 +0800)
extensions/model-loaders/model-loaders/libs/JOpenCTM-1.0.jar [new file with mode: 0644]
extensions/model-loaders/model-loaders/src/com/badlogic/gdx/graphics/g3d/loaders/ModelLoaderRegistry.java
extensions/model-loaders/model-loaders/src/com/badlogic/gdx/graphics/g3d/loaders/openctm/CtmModelLoader.java [new file with mode: 0644]

diff --git a/extensions/model-loaders/model-loaders/libs/JOpenCTM-1.0.jar b/extensions/model-loaders/model-loaders/libs/JOpenCTM-1.0.jar
new file mode 100644 (file)
index 0000000..f8bbebc
Binary files /dev/null and b/extensions/model-loaders/model-loaders/libs/JOpenCTM-1.0.jar differ
index 6302d52..6335025 100644 (file)
@@ -31,6 +31,7 @@ import com.badlogic.gdx.graphics.g3d.loaders.g3d.G3dtLoader.G3dtStillModelLoader
 import com.badlogic.gdx.graphics.g3d.loaders.md2.MD2Loader;\r
 import com.badlogic.gdx.graphics.g3d.loaders.md2.MD2Loader.MD2LoaderHints;\r
 import com.badlogic.gdx.graphics.g3d.loaders.ogre.OgreXmlLoader;\r
+import com.badlogic.gdx.graphics.g3d.loaders.openctm.CtmModelLoader;\r
 import com.badlogic.gdx.graphics.g3d.loaders.wavefront.ObjLoader;\r
 import com.badlogic.gdx.graphics.g3d.model.Model;\r
 import com.badlogic.gdx.graphics.g3d.model.keyframe.KeyframedModel;\r
@@ -60,6 +61,7 @@ public class ModelLoaderRegistry {
                registerLoader("g3d", new G3dStillModelLoader(), new ModelLoaderHints(false));\r
                registerLoader("g3d", new G3dKeyframedModelLoader(), new ModelLoaderHints(false));\r
                registerLoader("g3d", new G3dSkeletonModelLoader(), new ModelLoaderHints(false));\r
+               registerLoader("ctm", new CtmModelLoader(), new ModelLoaderHints(false));\r
        }\r
 \r
        /** Registers a new loader with the registry. The extension will be used to match the loader against a file to be loaded. The\r
diff --git a/extensions/model-loaders/model-loaders/src/com/badlogic/gdx/graphics/g3d/loaders/openctm/CtmModelLoader.java b/extensions/model-loaders/model-loaders/src/com/badlogic/gdx/graphics/g3d/loaders/openctm/CtmModelLoader.java
new file mode 100644 (file)
index 0000000..457121d
--- /dev/null
@@ -0,0 +1,153 @@
+/*******************************************************************************
+ * Copyright 2012 Daniel Heinrich.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+package com.badlogic.gdx.graphics.g3d.loaders.openctm;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import darwin.jopenctm.data.AttributeData;
+import darwin.jopenctm.io.CtmFileReader;
+
+import com.badlogic.gdx.files.FileHandle;
+import com.badlogic.gdx.graphics.*;
+import com.badlogic.gdx.graphics.VertexAttributes.Usage;
+import com.badlogic.gdx.graphics.g3d.ModelLoaderHints;
+import com.badlogic.gdx.graphics.g3d.loaders.ModelLoader;
+import com.badlogic.gdx.graphics.g3d.model.Model;
+import com.badlogic.gdx.graphics.g3d.model.still.StillModel;
+import com.badlogic.gdx.graphics.g3d.model.still.StillSubMesh;
+import com.badlogic.gdx.graphics.glutils.ShaderProgram;
+import com.badlogic.gdx.utils.GdxRuntimeException;
+
+import static darwin.jopenctm.data.Mesh.*;
+
+/**
+ *
+ * @author Daniel Heinrich <dannynullzwo@gmail.com>
+ */
+public class CtmModelLoader implements ModelLoader {
+
+    @Override
+    public Model load(FileHandle file, ModelLoaderHints hints) {
+        CtmFileReader reader = new CtmFileReader(file.read());
+        try {
+            darwin.jopenctm.data.Mesh ctmMesh = reader.decode();
+
+            Mesh mesh = convert(ctmMesh);
+
+            StillSubMesh ssm = new StillSubMesh(reader.getFileComment(),
+                                                mesh, GL10.GL_TRIANGLES);
+            StillModel model = new StillModel(new StillSubMesh[]{ssm});
+            return model;
+        } catch (Throwable ex) {
+            throw new GdxRuntimeException("An error occured while loading model: "
+                                          + file.name(), ex);
+        }
+
+    }
+
+    private Mesh convert(darwin.jopenctm.data.Mesh ctmMesh) {
+
+        if (ctmMesh.getVertexCount() > Short.MAX_VALUE) {
+            throw new GdxRuntimeException("The indices exceed the range of SHORT!");
+        }
+
+        List<VertexAttribute> vas = new ArrayList<VertexAttribute>();
+
+        VertexAttribute position = new VertexAttribute(Usage.Position,
+                                                       CTM_POSITION_ELEMENT_COUNT,
+                                                       ShaderProgram.POSITION_ATTRIBUTE);
+
+        vas.add(position);
+
+        VertexAttribute normal = null;
+        if (ctmMesh.hasNormals()) {
+            normal = new VertexAttribute(Usage.Normal,
+                                         CTM_NORMAL_ELEMENT_COUNT,
+                                         ShaderProgram.NORMAL_ATTRIBUTE);
+            vas.add(normal);
+        }
+
+        VertexAttribute[] uvs = new VertexAttribute[ctmMesh.getUVCount()];
+        if (ctmMesh.getUVCount() > 0) {
+            uvs[0] = new VertexAttribute(Usage.TextureCoordinates,
+                                         CTM_UV_ELEMENT_COUNT,
+                                         ShaderProgram.TEXCOORD_ATTRIBUTE);
+            vas.add(uvs[0]);
+            if (ctmMesh.getUVCount() > 1) {
+                for (int i = 1; i < ctmMesh.getUVCount(); ++i) {
+                    AttributeData ad = ctmMesh.texcoordinates[i];
+                    uvs[i] = new VertexAttribute(Usage.TextureCoordinates,
+                                                 CTM_UV_ELEMENT_COUNT,
+                                                 ad.name);
+                    vas.add(uvs[i]);
+                }
+            }
+        }
+
+        VertexAttribute[] others = new VertexAttribute[ctmMesh.getAttrCount()];
+        for (int i = 0; i < ctmMesh.getAttrCount(); ++i) {
+            others[i] = new VertexAttribute(Usage.Generic,
+                                            CTM_ATTR_ELEMENT_COUNT,
+                                            ctmMesh.attributs[i].name);
+            vas.add(others[i]);
+        }
+
+        Mesh m = new Mesh(true, ctmMesh.getVertexCount(),
+                          ctmMesh.getTriangleCount() * 3,
+                          vas.toArray(new VertexAttribute[0]));
+
+        m.setIndices(convertIndices(ctmMesh.indices));
+
+        int vsize = m.getVertexSize() / 4;
+        float[] data = new float[vsize * ctmMesh.getVertexCount()];
+        for (int i = 0; i < ctmMesh.getVertexCount(); i++) {
+            //position data
+            System.arraycopy(ctmMesh.vertices, i * CTM_POSITION_ELEMENT_COUNT,
+                             data, i * vsize, CTM_POSITION_ELEMENT_COUNT);
+            //normal
+            if (normal != null) {
+                System.arraycopy(ctmMesh.normals, i * CTM_NORMAL_ELEMENT_COUNT,
+                                 data, i * vsize + normal.offset / 4, CTM_NORMAL_ELEMENT_COUNT);
+            }
+            //uvs
+            for(VertexAttribute va: uvs)
+            {                
+                AttributeData ad=ctmMesh.texcoordinates[i];
+                System.arraycopy(ad.values, i * CTM_UV_ELEMENT_COUNT,
+                                 data, i * vsize + va.offset / 4, CTM_UV_ELEMENT_COUNT);
+            }
+            //other
+            for(VertexAttribute va: others)
+            {                
+                AttributeData ad=ctmMesh.attributs[i];
+                System.arraycopy(ad.values, i * CTM_ATTR_ELEMENT_COUNT,
+                                 data, i * vsize + va.offset / 4, CTM_ATTR_ELEMENT_COUNT);
+            }
+        }
+
+        m.setVertices(data);
+        return m;
+    }
+
+    private static short[] convertIndices(int[] ind) {
+        short[] r = new short[ind.length];
+        for (int i = 0; i < r.length; i++) {
+            r[i] = (short) ind[i];
+        }
+        return r;
+    }
+}