OSDN Git Service

add VMDLoader
authorKazuhiko Kobayashi <chototsu_moushinp@yahoo.co.jp>
Mon, 8 Aug 2011 06:18:23 +0000 (15:18 +0900)
committerKazuhiko Kobayashi <chototsu_moushinp@yahoo.co.jp>
Mon, 8 Aug 2011 06:18:23 +0000 (15:18 +0900)
add native library loading support for Solaris

src/projectkyoto/jme3/mmd/PMDLoaderGLSLSkinning2.java
src/projectkyoto/jme3/mmd/PMDModelKey.java [new file with mode: 0644]
src/projectkyoto/jme3/mmd/PMDNode.java
src/projectkyoto/jme3/mmd/VMDLoader.java [new file with mode: 0644]
src/projectkyoto/mmd/file/DataInputStreamLittleEndian.java
src/projectkyoto/mmd/file/PMDMaterial.java
src/projectkyoto/mmd/file/PMDModel.java
src/projectkyoto/mmd/file/VMDFile.java
src/projectkyoto/mmd/file/util2/MeshConverter.java

index 74fde61..15dc47a 100755 (executable)
@@ -31,6 +31,8 @@ package projectkyoto.jme3.mmd;
 
 import com.jme3.animation.Bone;
 import com.jme3.animation.Skeleton;
+import com.jme3.asset.AssetInfo;
+import com.jme3.asset.AssetLoader;
 import com.jme3.asset.AssetManager;
 import com.jme3.asset.AssetNotFoundException;
 import com.jme3.material.Material;
@@ -52,6 +54,7 @@ import com.jme3.shader.VarType;
 import com.jme3.texture.Texture;
 import com.jme3.util.BufferUtils;
 import com.jme3.util.TempVars;
+import java.io.IOException;
 import java.nio.FloatBuffer;
 import java.nio.ShortBuffer;
 import java.util.ArrayList;
@@ -65,13 +68,14 @@ import projectkyoto.mmd.file.util2.MeshData;
  *
  * @author kobayasi
  */
-public class PMDLoaderGLSLSkinning2 {
+public class PMDLoaderGLSLSkinning2 implements AssetLoader{
 
     PMDModel model;
     PMDNode node;
     MeshConverter meshConverter;
     int meshCount = 1;
     AssetManager assetManager;
+    String folderName;
     List<PMDMesh> meshList = new ArrayList<PMDMesh>();
     List<PMDSkinMesh> skinMeshList = new ArrayList<PMDSkinMesh>();
     VertexBuffer skinvb;
@@ -82,9 +86,13 @@ public class PMDLoaderGLSLSkinning2 {
     Skin skinArray[];
     SkeletonControl skeletonControl;
 
+    public PMDLoaderGLSLSkinning2() {
+    }
+
     public PMDLoaderGLSLSkinning2(AssetManager assetManager, PMDModel model) {
         this.assetManager = assetManager;
         this.model = model;
+        folderName = "/Model/";
 //        System.out.println("vertexCount = " + model.getVertCount());
 //        System.out.println("faceVertCount = " + model.getFaceVertCount());
         meshConverter = new MeshConverter(model);
@@ -208,8 +216,8 @@ public class PMDLoaderGLSLSkinning2 {
         }
 //        System.out.println("isb.capacity() = " + isb.capacity());
 //        System.out.println("isb.capacity() = " + md.getIndexList().size());
-        vb.setupData(VertexBuffer.Usage.Static, 3, VertexBuffer.Format.Float, vfb);
-        nb.setupData(VertexBuffer.Usage.Static, 3, VertexBuffer.Format.Float, nfb);
+        vb.setupData(VertexBuffer.Usage.Dynamic, 3, VertexBuffer.Format.Float, vfb);
+        nb.setupData(VertexBuffer.Usage.Dynamic, 3, VertexBuffer.Format.Float, nfb);
 
         bvb.setupData(VertexBuffer.Usage.CpuOnly, 3, VertexBuffer.Format.Float, bvfb);
         bnb.setupData(VertexBuffer.Usage.CpuOnly, 3, VertexBuffer.Format.Float, bnfb);
@@ -307,7 +315,7 @@ public class PMDLoaderGLSLSkinning2 {
                 String fileName = st.nextToken();
                 System.out.println("fileName = " + fileName);
                 String s = fileName.substring(fileName.indexOf('.') + 1);
-                Texture texture = assetManager.loadTexture("Model/" + fileName /*
+                Texture texture = assetManager.loadTexture(folderName + fileName /*
                          * m.getTextureFileName()
                          */);
                 s = s.toLowerCase();
@@ -328,7 +336,7 @@ public class PMDLoaderGLSLSkinning2 {
         if (toonIndex >= 0) {
             String extToonName = model.getToonTextureList().getToonFileName()[toonIndex];
             try {
-                toonTexture = assetManager.loadTexture("/Model/" + extToonName);
+                toonTexture = assetManager.loadTexture(folderName + extToonName);
             } catch (AssetNotFoundException ex) {
                 String toonname = null;
                 switch (toonIndex) {
@@ -498,4 +506,13 @@ public class PMDLoaderGLSLSkinning2 {
 
         return boneNode;
     }
+
+    @Override
+    public Object load(AssetInfo ai) throws IOException {
+        this.assetManager = ai.getManager();
+        model = new PMDModel(ai.openStream());
+        folderName = ai.getKey().getFolder();
+        meshConverter = new MeshConverter(model);
+        return createNode(ai.getKey().getName());
+    }
 }
diff --git a/src/projectkyoto/jme3/mmd/PMDModelKey.java b/src/projectkyoto/jme3/mmd/PMDModelKey.java
new file mode 100644 (file)
index 0000000..6a8c5ec
--- /dev/null
@@ -0,0 +1,49 @@
+// Copyright (c) 2011 Kazuhiko Kobayashi
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+//   notice, this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright
+//   notice, this list of conditions and the following disclaimer in the
+//   documentation and/or other materials provided with the distribution.
+//
+// * Neither the name of 'MMDLoaderJME' nor the names of its contributors
+//   may be used to endorse or promote products derived from this software
+//   without specific prior written permission.
+//
+//  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package projectkyoto.jme3.mmd;
+
+import com.jme3.asset.ModelKey;
+
+/**
+ *
+ * @author kobayasi
+ */
+public class PMDModelKey extends ModelKey{
+
+    public PMDModelKey() {
+        super();
+    }
+
+    public PMDModelKey(String name) {
+        super(name);
+    }
+    
+}
index 6b6ffa3..426d752 100755 (executable)
@@ -212,13 +212,9 @@ public class PMDNode extends Node {
     }
     private void swapSkinMesh() {
         VertexBuffer vb = skinTargets[0].getBuffer(VertexBuffer.Type.Position);
-        vb.setUsage(Usage.CpuOnly);
         VertexBuffer nb = skinTargets[0].getBuffer(VertexBuffer.Type.Normal);
-        nb.setUsage(Usage.CpuOnly);
         skinTargets[0].skinvb2.setUpdateNeeded();
-        skinTargets[0].skinvb2.setUsage(Usage.Static);
         skinTargets[0].skinnb2.setUpdateNeeded();
-        skinTargets[0].skinnb2.setUsage(Usage.Static);
         for(PMDSkinMesh skinMesh : skinTargets) {
             skinMesh.clearBuffer(Type.Position);
             skinMesh.clearBuffer(Type.Normal);
@@ -232,7 +228,7 @@ public class PMDNode extends Node {
         vb.setUpdateNeeded();
         nb.setUpdateNeeded();
     }
-    private void softwareSkinUpdate(PMDMesh mesh) {
+    private void softwareSkinUpdate(PMDMesh mesh){
         int maxWeightsPerVert = 2;//mesh.getMaxNumWeights();
         int fourMinusMaxWeights = 4 - maxWeightsPerVert;
 //        Matrix4f[] offsetMatrices = mesh.getBoneMatrixArray();
@@ -263,9 +259,9 @@ public class PMDNode extends Node {
         float[] posBuf = vars.skinPositions;
         float[] normBuf = vars.skinNormals;
 
-        int iterations = (int) FastMath.ceil(fvb.capacity() / ((float) posBuf.length));
+        int iterations = (int) FastMath.ceil(fvb.capacity() / ((float)posBuf.length));
         int bufLength = posBuf.length * 3;
-        for (int i = iterations - 1; i >= 0; i--) {
+        for (int i = iterations-1; i >= 0; i--){
             // read next set of positions and normals from native buffer
             bufLength = Math.min(posBuf.length, fvb.remaining());
             fvb.get(posBuf, 0, bufLength);
@@ -274,7 +270,7 @@ public class PMDNode extends Node {
             int idxPositions = 0;
 
             // iterate vertices and apply skinning transform for each effecting bone
-            for (int vert = verts - 1; vert >= 0; vert--) {
+            for (int vert = verts - 1; vert >= 0; vert--){
                 float nmx = normBuf[idxPositions];
                 float vtx = posBuf[idxPositions++];
                 float nmy = normBuf[idxPositions];
@@ -282,9 +278,9 @@ public class PMDNode extends Node {
                 float nmz = normBuf[idxPositions];
                 float vtz = posBuf[idxPositions++];
 
-                float rx = 0, ry = 0, rz = 0, rnx = 0, rny = 0, rnz = 0;
+                float rx=0, ry=0, rz=0, rnx=0, rny=0, rnz=0;
 
-                for (int w = maxWeightsPerVert - 1; w >= 0; w--) {
+                for (int w = maxWeightsPerVert - 1; w >= 0; w--){
                     float weight = wb.get(idxWeights); //weights[idxWeights];
                     Matrix4f mat = mesh.getBoneMatrixArray()[ib.get(idxWeights++)];//offsetMatrices[indices[idxWeights++]];
 
@@ -309,15 +305,15 @@ public class PMDNode extends Node {
             }
 
 
-            fvb.position(fvb.position() - bufLength);
+            fvb.position(fvb.position()-bufLength);
             fvb.put(posBuf, 0, bufLength);
-            fnb.position(fnb.position() - bufLength);
+            fnb.position(fnb.position()-bufLength);
             fnb.put(normBuf, 0, bufLength);
         }
-
-        vb.updateData(fvb);
-        nb.updateData(fnb);
+        vb.setUpdateNeeded();
+        nb.setUpdateNeeded();
         vars.release();
+        
 //        mesh.updateBound();
     }
     public void updateSkinBackData() {
@@ -740,6 +736,13 @@ public class PMDNode extends Node {
                 Mesh mesh = ((PMDGeometry) sp).getMesh();
                 if (mesh instanceof PMDMesh) {
                     resetToBind((PMDMesh) mesh);
+                    if (glslSkinning) {
+                        mesh.getBuffer(Type.Position).setUsage(Usage.Static);
+                        mesh.getBuffer(Type.Normal).setUsage(Usage.Static);
+                    } else {
+                        mesh.getBuffer(Type.Position).setUsage(Usage.Dynamic);
+                        mesh.getBuffer(Type.Normal).setUsage(Usage.Dynamic);
+                    }
                 }
             }
         }
@@ -758,4 +761,10 @@ public class PMDNode extends Node {
     public int hashCode() {
         return pmdModel.getModelName().hashCode();
     }
+
+    @Override
+    public Spatial clone() {
+        return super.clone();
+    }
+    
 }
diff --git a/src/projectkyoto/jme3/mmd/VMDLoader.java b/src/projectkyoto/jme3/mmd/VMDLoader.java
new file mode 100644 (file)
index 0000000..f0bd69d
--- /dev/null
@@ -0,0 +1,50 @@
+// Copyright (c) 2011 Kazuhiko Kobayashi
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+//   notice, this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright
+//   notice, this list of conditions and the following disclaimer in the
+//   documentation and/or other materials provided with the distribution.
+//
+// * Neither the name of 'MMDLoaderJME' nor the names of its contributors
+//   may be used to endorse or promote products derived from this software
+//   without specific prior written permission.
+//
+//  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+package projectkyoto.jme3.mmd;
+
+import com.jme3.asset.AssetInfo;
+import com.jme3.asset.AssetLoader;
+import java.io.IOException;
+import projectkyoto.mmd.file.VMDFile;
+
+/**
+ *
+ * @author kobayasi
+ */
+public class VMDLoader implements AssetLoader {
+
+    public VMDLoader() {
+    }
+
+    @Override
+    public Object load(AssetInfo ai) throws IOException {
+        return new VMDFile(ai.openStream());
+    }
+}
index 8f80489..d10043d 100755 (executable)
@@ -46,7 +46,7 @@ import java.net.URL;
  * @author Kazuhiko Kobayashi
  */
 public class DataInputStreamLittleEndian extends FilterInputStream {
-    public URL url;
+//    public URL url;
     private DataInputStream dis;
     byte[] buf;
 
@@ -56,7 +56,7 @@ public class DataInputStreamLittleEndian extends FilterInputStream {
     }
     public DataInputStreamLittleEndian(URL url) throws IOException {
         super(new BufferedInputStream(url.openStream()));
-        this.url = url;
+//        this.url = url;
         dis = new DataInputStream(this);
     }
     final byte[] getBuf(int size) {
index 6ad2af7..193b881 100755 (executable)
@@ -46,7 +46,7 @@ public class PMDMaterial {
     private byte edgeFlag;
     private int faceVertCount;
     private String textureFileName; // 20文字
-    private byte[] textureData;
+//    private byte[] textureData;
 
     public PMDMaterial() {
     }
@@ -59,30 +59,30 @@ public class PMDMaterial {
 //        if (textureFileName.length() != 0) {
 //            texture = TextureIO.newTexture(new URL(is.url ,textureFileName), true,"bmp");
 //        }
-        if ( false && !textureFileName.isEmpty()) {
-            InputStream textureIs = null;
-            try {
-                textureIs = new URL(is.url ,textureFileName).openStream();
-                ByteArrayOutputStream os = new ByteArrayOutputStream();
-                byte[] buf = new byte[4096];
-                for(;;) {
-                    int size = textureIs.read(buf);
-                    if (size <= 0) {
-                        break;
-                    }
-                    os.write(buf,0,size);
-                }
-                os.close();
-                textureData = os.toByteArray();
-            } catch(IOException ex) {
-                ex.printStackTrace();
-            } finally {
-                if (textureIs != null) {
-                    textureIs.close();
-                    textureIs = null;
-                }
-            }
-        }
+//        if ( false && !textureFileName.isEmpty()) {
+//            InputStream textureIs = null;
+//            try {
+//                textureIs = new URL(is.url ,textureFileName).openStream();
+//                ByteArrayOutputStream os = new ByteArrayOutputStream();
+//                byte[] buf = new byte[4096];
+//                for(;;) {
+//                    int size = textureIs.read(buf);
+//                    if (size <= 0) {
+//                        break;
+//                    }
+//                    os.write(buf,0,size);
+//                }
+//                os.close();
+//                textureData = os.toByteArray();
+//            } catch(IOException ex) {
+//                ex.printStackTrace();
+//            } finally {
+//                if (textureIs != null) {
+//                    textureIs.close();
+//                    textureIs = null;
+//                }
+//            }
+//        }
     }
 
     public byte getEdgeFlag() {
@@ -125,13 +125,13 @@ public class PMDMaterial {
         this.toonIndex = toonIndex;
     }
 
-    public byte[] getTextureData() {
-        return textureData;
-    }
-
-    public void setTextureData(byte[] textureData) {
-        this.textureData = textureData;
-    }
+//    public byte[] getTextureData() {
+//        return textureData;
+//    }
+//
+//    public void setTextureData(byte[] textureData) {
+//        this.textureData = textureData;
+//    }
 
     @Override
     public String toString() {
index 764e466..0782a1b 100755 (executable)
@@ -29,7 +29,9 @@
  */
 package projectkyoto.mmd.file;
 
+import java.io.BufferedInputStream;
 import java.io.IOException;
+import java.io.InputStream;
 import java.net.URL;
 
 /**
@@ -61,29 +63,30 @@ public class PMDModel {
     private PMDToonTextureList toonTextureList;
     private PMDRigidBodyList rigidBodyList;
     private PMDJointList jointList;
-    private URL url;
 
     public PMDModel() {
     }
 
     public PMDModel(URL url) throws IOException {
-        readFromFile(url);
+        readFromFile(url.openStream());
     }
-
-    public void readFromFile(URL url) throws IOException {
-        DataInputStreamLittleEndian is = null;
+    public PMDModel(InputStream is) throws IOException {
+        readFromFile(is);
+    }
+    public void readFromFile(InputStream is) throws IOException {
+        DataInputStreamLittleEndian dis = null;
         try {
 //            is = new DataInputStreamLittleEndian(new BufferedInputStream(
 //                    new FileInputStream(
 //                    file)));
-            is = new DataInputStreamLittleEndian(url);
-            readFromStream(is);
-            is.close();
-            this.url = url;
+            dis = new DataInputStreamLittleEndian(new BufferedInputStream(is));
+            readFromStream(dis);
+            dis.close();
+//            this.url = url;
         } finally {
-            if (is != null) {
-                is.close();
-                is = null;
+            if (dis != null) {
+                dis.close();
+                dis = null;
             }
         }
 //        System.out.println(toString());
index f631607..d5da368 100755 (executable)
@@ -32,7 +32,9 @@
 
 package projectkyoto.mmd.file;
 
+import java.io.BufferedInputStream;
 import java.io.IOException;
+import java.io.InputStream;
 import java.net.URL;
 
 /**
@@ -46,13 +48,23 @@ public class VMDFile {
     private VMDMotion motionArray[];
     private int skinCount;
     private VMDSkin skinArray[];
+
+    public VMDFile() {
+    }
+    
     public VMDFile(URL url) throws IOException {
+        read(url.openStream());
+    }
+    public VMDFile(InputStream is2) throws IOException {
+        read(is2);
+    }
+    public void read(InputStream is2) throws IOException{
         DataInputStreamLittleEndian is = null;
         try {
-            is = new DataInputStreamLittleEndian(url);
+            is = new DataInputStreamLittleEndian(new BufferedInputStream(is2));
             vmdHeader = is.readString(30);
             if (!"Vocaloid Motion Data 0002".equals(vmdHeader)) {
-                throw new InvalidVMDFileException(url.toString());
+                throw new InvalidVMDFileException();
             }
             vmdModelName = is.readString(20);
             motionCount = is.readInt();
index bf36b2b..8c8e71e 100755 (executable)
@@ -93,6 +93,9 @@ public class MeshConverter {
         int faceVertNo = 0;
         for (int materialNo = 0; materialNo < model.getMaterialCount(); materialNo++) {
             PMDMaterial material = model.getMaterial()[materialNo];
+            if (material.getFaceVertCount() == 0) {
+                continue;
+            }
             MeshData meshData = new MeshData(model, maxBoneSize, material);
             meshDataList.add(meshData);
             for (int materialFaceVertNo = 0; materialFaceVertNo < material.getFaceVertCount(); materialFaceVertNo += 3) {
@@ -110,6 +113,9 @@ public class MeshConverter {
                     }
                 }
             }
+            if (meshData.getVertexList().size() == 0) {
+                meshDataList.remove(meshDataList.size()-1);
+            }
         }
         int vertSizeSum = 0;
         int boneSizeSum = 0;
@@ -120,6 +126,7 @@ public class MeshConverter {
             boneSizeSum += meshData.getBoneList().size();
             indexSizeSum += meshData.getIndexList().size();
 //            printMeshData(meshData);
+//            System.out.println("mesh size = "+meshData.vertexList.size());
         }
 //        System.out.println("-----------------------skin");
 //        System.out.println("index " + model.getFaceVertCount() + " " + indexSizeSum