OSDN Git Service

Add pmdcache support.
authorKazuhiko Kobayashi <chototsu_moushinp@yahoo.co.jp>
Wed, 17 Oct 2012 08:21:47 +0000 (17:21 +0900)
committerKazuhiko Kobayashi <chototsu_moushinp@yahoo.co.jp>
Wed, 17 Oct 2012 08:21:47 +0000 (17:21 +0900)
33 files changed:
src/projectkyoto/jme3/mmd/PMDLoaderGLSLSkinning2.java
src/projectkyoto/jme3/mmd/PMDNode.java
src/projectkyoto/mmd/file/Coords2d.java
src/projectkyoto/mmd/file/DataInputStreamLittleEndian.java
src/projectkyoto/mmd/file/DataOutputStreamLittleEndian.java [new file with mode: 0644]
src/projectkyoto/mmd/file/PMDBone.java
src/projectkyoto/mmd/file/PMDBoneDisp.java
src/projectkyoto/mmd/file/PMDBoneDispList.java
src/projectkyoto/mmd/file/PMDBoneDispNameList.java
src/projectkyoto/mmd/file/PMDBoneList.java
src/projectkyoto/mmd/file/PMDHeaderEnglish.java
src/projectkyoto/mmd/file/PMDIKData.java
src/projectkyoto/mmd/file/PMDIKList.java
src/projectkyoto/mmd/file/PMDJoint.java
src/projectkyoto/mmd/file/PMDJointList.java
src/projectkyoto/mmd/file/PMDMaterial.java
src/projectkyoto/mmd/file/PMDModel.java
src/projectkyoto/mmd/file/PMDRigidBody.java
src/projectkyoto/mmd/file/PMDRigidBodyList.java
src/projectkyoto/mmd/file/PMDSkinData.java
src/projectkyoto/mmd/file/PMDSkinDispList.java
src/projectkyoto/mmd/file/PMDSkinVertData.java
src/projectkyoto/mmd/file/PMDToonTextureList.java
src/projectkyoto/mmd/file/PMDUtil.java
src/projectkyoto/mmd/file/PMDVertex.java
src/projectkyoto/mmd/file/XColorRGB.java
src/projectkyoto/mmd/file/XColorRGBA.java
src/projectkyoto/mmd/file/XMaterial.java
src/projectkyoto/mmd/file/util2/BufferUtil.java
src/projectkyoto/mmd/file/util2/MeshConverter.java
src/projectkyoto/mmd/file/util2/MeshData.java
src/projectkyoto/mmd/file/util2/PMDFileUtil.java [new file with mode: 0644]
src/projectkyoto/mmd/file/util2/SkinMeshData.java

index c0b92ea..5fdcfaf 100755 (executable)
@@ -34,13 +34,10 @@ 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.asset.DesktopAssetManager;
 import com.jme3.material.Material;
 import com.jme3.material.RenderState.BlendMode;
-import com.jme3.material.RenderState.FaceCullMode;
 import com.jme3.math.ColorRGBA;
-import com.jme3.math.FastMath;
 import com.jme3.math.Matrix4f;
 import com.jme3.math.Quaternion;
 import com.jme3.math.Vector3f;
@@ -53,13 +50,12 @@ import com.jme3.scene.debug.SkeletonPoints;
 import com.jme3.scene.debug.SkeletonWire;
 import com.jme3.scene.shape.Box;
 import com.jme3.shader.VarType;
-import com.jme3.system.JmeSystem;
 import com.jme3.texture.Texture;
 import com.jme3.util.BufferUtils;
 import com.jme3.util.TempVars;
-import com.sun.jmx.remote.util.OrderClassLoaders;
+import java.io.BufferedInputStream;
 import java.io.IOException;
-import java.nio.ByteBuffer;
+import java.io.InputStream;
 import java.nio.FloatBuffer;
 import java.nio.ShortBuffer;
 import java.util.ArrayList;
@@ -69,11 +65,11 @@ import java.util.Map;
 import java.util.StringTokenizer;
 import java.util.logging.Level;
 import java.util.logging.Logger;
-import org.lwjgl.opengl.GL11;
 import projectkyoto.mmd.file.*;
-import projectkyoto.mmd.file.pmn.PMNData;
 import projectkyoto.mmd.file.util2.MeshConverter;
 import projectkyoto.mmd.file.util2.MeshData;
+import projectkyoto.mmd.file.util2.PMDFileUtil;
+import projectkyoto.mmd.file.util2.SkinMeshData;
 
 /**
  *
@@ -173,13 +169,13 @@ public class PMDLoaderGLSLSkinning2 implements AssetLoader{
 //        go.optimize3();
         createSkinCommonVertData();
         int numBones = meshConverter.getMaxBoneSize();
-        if (meshConverter.getSkinMeshData().getBoneList().size() > numBones) {
-            if (meshConverter.getSkinMeshData().getBoneList().size() > 56) {
-                throw new TooManyBonesException(Integer.toString(meshConverter.getSkinMeshData().getBoneList().size()));
+        if (meshConverter.getSkinMeshData().skinIndexArray.length > numBones) {
+            if (meshConverter.getSkinMeshData().skinIndexArray.length > 56) {
+                throw new TooManyBonesException(Integer.toString(meshConverter.getSkinMeshData().skinIndexArray.length));
             }
-            numBones = meshConverter.getSkinMeshData().getBoneList().size();
+            numBones = meshConverter.getSkinMeshData().skinIndexArray.length;
         }
-        for (PMDMaterial pmdMaterial : meshConverter.getSkinMeshData().getIndexMap().keySet()) {
+        for (PMDMaterial pmdMaterial : meshConverter.getSkinMeshData().indexShortBufferMap.keySet()) {
             PMDSkinMesh mesh = createSkinMesh(pmdMaterial);
             PMDGeometry geom = new PMDGeometry("geom" + meshCount++);
             geom.setMesh(mesh);
@@ -221,71 +217,38 @@ public class PMDLoaderGLSLSkinning2 implements AssetLoader{
     }
 
     void createSkinCommonVertData() {
+        SkinMeshData smd = meshConverter.getSkinMeshData();
         skinvb = new VertexBuffer(VertexBuffer.Type.Position);
-        FloatBuffer skinvfb = BufferUtils.createFloatBuffer(meshConverter.getSkinMeshData().getVertexList().size() * 3);
+        FloatBuffer skinvfb = smd.skinvfb;
         skinvb.setupData(VertexBuffer.Usage.Dynamic, 3, VertexBuffer.Format.Float, skinvfb);
 
         skinvb2 = new VertexBuffer(VertexBuffer.Type.Position);
-        FloatBuffer skinvfb2 = BufferUtils.createFloatBuffer(meshConverter.getSkinMeshData().getVertexList().size() * 3);
+        FloatBuffer skinvfb2 = smd.skinvfb2;
         skinvb2.setupData(VertexBuffer.Usage.Dynamic, 3, VertexBuffer.Format.Float, skinvfb2);
         
         skinnb = new VertexBuffer(VertexBuffer.Type.Normal);
-        FloatBuffer skinnfb = BufferUtils.createFloatBuffer(meshConverter.getSkinMeshData().getVertexList().size() * 3);
+        FloatBuffer skinnfb = smd.skinnfb;
         skinnb.setupData(VertexBuffer.Usage.Static, 3, VertexBuffer.Format.Float, skinnfb);
 
-//        skinnb2 = new VertexBuffer(VertexBuffer.Type.Normal);
-//        FloatBuffer skinnfb2 = BufferUtils.createFloatBuffer(meshConverter.getSkinMeshData().getVertexList().size() * 3);
-//        skinnb2.setupData(VertexBuffer.Usage.Static, 3, VertexBuffer.Format.Float, skinnfb2);
-        
         skintb = new VertexBuffer(VertexBuffer.Type.TexCoord);
-        FloatBuffer skintfb = BufferUtils.createFloatBuffer(meshConverter.getSkinMeshData().getVertexList().size() * 2);
+        FloatBuffer skintfb = smd.skintfb;
         skintb.setupData(VertexBuffer.Usage.Static, 2, VertexBuffer.Format.Float, skintfb);
 
         skinbib = new VertexBuffer(VertexBuffer.Type.BoneIndex);
-        ShortBuffer skinbisb = BufferUtils.createShortBuffer(meshConverter.getSkinMeshData().getVertexList().size() * 2);
+        ShortBuffer skinbisb = smd.skinbisb;
         skinbib.setupData(VertexBuffer.Usage.Static, 2, VertexBuffer.Format.UnsignedShort, skinbisb);
 
         skinwb = new VertexBuffer(VertexBuffer.Type.BoneWeight);
-        FloatBuffer wfb = BufferUtils.createFloatBuffer(meshConverter.getSkinMeshData().getVertexList().size() * 2);
+        FloatBuffer wfb = smd.wfb;
         skinwb.setupData(VertexBuffer.Usage.Static, 2, VertexBuffer.Format.Float, wfb);
 
-        for (PMDVertex v : meshConverter.getSkinMeshData().getVertexList()) {
-            skinvfb.put(v.getPos().x).put(v.getPos().y).put(v.getPos().z);
-            skinnfb.put(v.getNormal().x).put(v.getNormal().y).put(v.getNormal().z);
-                float f1 = v.getUv().getU();
-                float f2 = v.getUv().getV();
-//                tfb.put(v.getUv().getU()).put(1f - v.getUv().getV());
-                f1 = f1 - FastMath.floor(f1);
-                f2 = f2 - FastMath.floor(f2);
-                f2 = 1 - f2;
-                skintfb.put(f1).put(f2);
-//            skintfb.put(v.getUv().getU()).put(1f - v.getUv().getV());
-//            skinbisb.put((short) meshConverter.getSkinMeshData()
-//                    .getBoneList().indexOf(v.getBoneNum1()))
-//                    .put((short) meshConverter.getSkinMeshData()
-//                    .getBoneList().indexOf(v.getBoneNum2()));
-            short b1 = (short)meshConverter.getSkinMeshData().getBoneList().indexOf(v.getBoneNum1());
-            short b2 = (short)meshConverter.getSkinMeshData().getBoneList().indexOf(v.getBoneNum2());
-            if (b1 < 0) b1 = 0;
-            if (b2 < 0) b2 = 0;
-            skinbisb.put(b1).put(b2);
-            float weight = (float) v.getBoneWeight() / 100.0f;
-            wfb.put(weight).put(1f - weight);
-        }
         skinvfb.position(0);
         skinvfb2.position(0);
         skinvfb2.put(skinvfb);
         skinnfb.position(0);
 //        skinnfb2.position(0);
 //        skinnfb2.put(skinnfb);
-        skinIndexArray = new int[meshConverter.getSkinMeshData().getBoneList().size()];
-        for (int i = 0; i < skinIndexArray.length; i++) {
-            if (i < meshConverter.getSkinMeshData().getBoneList().size()) {
-                skinIndexArray[i] = meshConverter.getSkinMeshData().getBoneList().get(i).shortValue();
-            } else {
-                skinIndexArray[i] = 0;
-            }
-        }
+        skinIndexArray = smd.skinIndexArray;
     }
 
     PMDSkinMesh createSkinMesh(PMDMaterial pmdMaterial) {
@@ -294,7 +257,6 @@ public class PMDLoaderGLSLSkinning2 implements AssetLoader{
             textureFlag = false;
         }
         PMDSkinMesh mesh = new PMDSkinMesh();
-        List<Integer> indexList = meshConverter.getSkinMeshData().getIndexMap().get(pmdMaterial);
         mesh.setMode(Mesh.Mode.Triangles);
         mesh.setBuffer(skinvb);
         mesh.setSkinvb2(skinvb2);
@@ -306,10 +268,7 @@ public class PMDLoaderGLSLSkinning2 implements AssetLoader{
         mesh.setBuffer(skinbib);
         mesh.setBuffer(skinwb);
         VertexBuffer ib = new VertexBuffer(VertexBuffer.Type.Index);
-        ShortBuffer isb = BufferUtils.createShortBuffer(indexList.size());
-        for (Integer index : indexList) {
-            isb.put(index.shortValue());
-        }
+        ShortBuffer isb = meshConverter.getSkinMeshData().indexShortBufferMap.get(pmdMaterial);
         ib.setupData(VertexBuffer.Usage.Static, 1, VertexBuffer.Format.UnsignedShort, isb);
         mesh.setBuffer(ib);
         mesh.setBoneIndexArray(skinIndexArray);
@@ -336,76 +295,27 @@ public class PMDLoaderGLSLSkinning2 implements AssetLoader{
         PMDMesh mesh = new PMDMesh();
         mesh.setMode(Mesh.Mode.Triangles);
         VertexBuffer vb = new VertexBuffer(VertexBuffer.Type.Position);
-        FloatBuffer vfb = BufferUtils.createFloatBuffer(md.getVertIndexList().size() * 3);
         VertexBuffer nb = new VertexBuffer(VertexBuffer.Type.Normal);
-        FloatBuffer nfb = BufferUtils.createFloatBuffer(md.getVertIndexList().size() * 3);
-
-//        VertexBuffer bvb = new VertexBuffer(VertexBuffer.Type.BindPosePosition);
-//        FloatBuffer bvfb = BufferUtils.createFloatBuffer(md.getVertexList().size() * 3);
-//        VertexBuffer bnb = new VertexBuffer(VertexBuffer.Type.BindPoseNormal);
-//        FloatBuffer bnfb = BufferUtils.createFloatBuffer(md.getVertexList().size() * 3);
 
         VertexBuffer tb = new VertexBuffer(VertexBuffer.Type.TexCoord);
 
-        FloatBuffer tfb = null;
-        if (textureFlag ) {
-            tfb = BufferUtils.createFloatBuffer(md.getVertIndexList().size() * 2);
-        }
         VertexBuffer wb = new VertexBuffer(VertexBuffer.Type.BoneWeight);
-        FloatBuffer wfb = BufferUtils.createFloatBuffer(md.getVertIndexList().size() * 2);
         VertexBuffer ib = new VertexBuffer(VertexBuffer.Type.Index);
-        ShortBuffer isb = BufferUtils.createShortBuffer(md.getIndexList().size()/*md.getMaterial().getFaceVertCount()*/);
         VertexBuffer bib = new VertexBuffer(VertexBuffer.Type.BoneIndex);
-        ShortBuffer bisb = BufferUtils.createShortBuffer(md.getVertIndexList().size() * 2);
         PMDVertex v = new PMDVertex();
-        for (Integer vertIndex : md.getVertIndexList()) {
-            model.getVertex(vertIndex, v);
-            vfb.put(v.getPos().x).put(v.getPos().y).put(v.getPos().z);
-            nfb.put(v.getNormal().x).put(v.getNormal().y).put(v.getNormal().z);
-
-//            bvfb.put(v.getPos().x).put(v.getPos().y).put(v.getPos().z);
-//            bnfb.put(v.getNormal().x).put(v.getNormal().y).put(v.getNormal().z);
-            if (textureFlag) {
-                float f1 = v.getUv().getU();
-                float f2 = v.getUv().getV();
-//                tfb.put(v.getUv().getU()).put(1f - v.getUv().getV());
-                f1 = f1 - FastMath.floor(f1);
-                f2 = f2 - FastMath.floor(f2);
-                f2 = 1 - f2;
-                tfb.put(f1).put(f2);
-            }
-            float weight = (float) v.getBoneWeight() / 100.0f;
-            wfb.put(weight).put(1f - weight);
-            short b1 = (short)md.getBoneList().indexOf(v.getBoneNum1());
-            short b2 = (short)md.getBoneList().indexOf(v.getBoneNum2());
-            if (b1 < 0) b1 = 0;
-            if (b2 < 0) b2 = 0;
-            bisb.put(b1).put(b2);
-//            bisb.put((short) md.getBoneList().indexOf(v.getBoneNum1())).put((short) md.getBoneList().indexOf(v.getBoneNum2()));
-//            if (( weight != 0 && md.getBoneList().indexOf(v.getBoneNum1()) < 0)
-//                    || (weight != 1 && md.getBoneList().indexOf(v.getBoneNum2())<0)){
-//                System.out.println("ERROR!! "+v.getBoneNum1()+" "+v.getBoneNum2());
-//                System.out.println(""+md.getBoneList().indexOf(v.getBoneNum1())+" "+md.getBoneList().indexOf(v.getBoneNum2()));
-//                System.out.println("weight = "+weight);
-//            }
-        }
-        for (Integer index : md.getIndexList()) {
-            isb.put(index.shortValue());
-//            System.out.println("index = "+index);
-        }
 //        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.Static, 3, VertexBuffer.Format.Float, md.vfb);
+        nb.setupData(VertexBuffer.Usage.Static, 3, VertexBuffer.Format.Float, md.nfb);
 
 //        bvb.setupData(VertexBuffer.Usage.CpuOnly, 3, VertexBuffer.Format.Float, bvfb);
 //        bnb.setupData(VertexBuffer.Usage.CpuOnly, 3, VertexBuffer.Format.Float, bnfb);
         if (textureFlag) {
-            tb.setupData(VertexBuffer.Usage.Static, 2, VertexBuffer.Format.Float, tfb);
+            tb.setupData(VertexBuffer.Usage.Static, 2, VertexBuffer.Format.Float, md.tfb);
         }
-        wb.setupData(VertexBuffer.Usage.Static, 2, VertexBuffer.Format.Float, wfb);
-        ib.setupData(VertexBuffer.Usage.Static, 1, VertexBuffer.Format.UnsignedShort, isb);
-        bib.setupData(VertexBuffer.Usage.Static, 2, VertexBuffer.Format.UnsignedShort, bisb);
+        wb.setupData(VertexBuffer.Usage.Static, 2, VertexBuffer.Format.Float, md.wfb);
+        ib.setupData(VertexBuffer.Usage.Static, 1, VertexBuffer.Format.UnsignedShort, md.isb);
+        bib.setupData(VertexBuffer.Usage.Static, 2, VertexBuffer.Format.UnsignedShort, md.bisb);
         mesh.setBuffer(vb);
         mesh.setBuffer(nb);
         
@@ -420,18 +330,9 @@ public class PMDLoaderGLSLSkinning2 implements AssetLoader{
         mesh.setBuffer(wb);
         mesh.setBuffer(ib);
         mesh.setBuffer(bib);
-        int[] indexArray = new int[md.getBoneList().size()];
-        ShortBuffer indexBuffer = BufferUtils.createShortBuffer(md.getBoneList().size());
-        for (int i = 0; i < indexArray.length; i++) {
-            if (i < md.getBoneList().size()) {
-                indexArray[i] = md.getBoneList().get(i).shortValue();
-            } else {
-                indexArray[i] = 0;
-            }
-            indexBuffer.put((short)indexArray[i]);
-        }
+        int[] indexArray = md.indexArray;
         mesh.setBoneIndexArray(indexArray);
-        mesh.setBoneIndexBuffer(indexBuffer);
+        mesh.setBoneIndexBuffer(md.indexBuffer);
         FloatBuffer boneMatrixBuffer = BufferUtils.createFloatBuffer(16 * indexArray.length);
         mesh.setBoneMatrixArray(new Matrix4f[indexArray.length]);
         mesh.setBoneMatrixBuffer(boneMatrixBuffer);
@@ -511,7 +412,7 @@ public class PMDLoaderGLSLSkinning2 implements AssetLoader{
         mat.setFloat("Shininess", m.getMaterial().getPower());
         if (m.getTextureFileName().length() > 0) {
             StringTokenizer st = new StringTokenizer(m.getTextureFileName().replace("\\", "/"), "*");
-            System.out.println("m.getTextureFileName() = " + m.getTextureFileName());
+//            System.out.println("m.getTextureFileName() = " + m.getTextureFileName());
             while (st.hasMoreElements()) {
                 String fileName = st.nextToken();
 //                System.out.println("fileName = " + fileName);
@@ -725,7 +626,13 @@ public class PMDLoaderGLSLSkinning2 implements AssetLoader{
         for(;;) {
             try {
                 PMDLoaderGLSLSkinning2 loader = new PMDLoaderGLSLSkinning2();
-                return loader.load2(ai);
+                Object result;
+                if (ai.getKey().getName().toLowerCase().endsWith(".pmd")) {
+                    result =  loader.load2(ai);
+                } else {
+                    result = loader.load3(ai);
+                }
+                return result;
             }catch(OutOfMemoryError ex) {
                 if (errFlag) {
                     throw ex;
@@ -749,18 +656,40 @@ public class PMDLoaderGLSLSkinning2 implements AssetLoader{
 //        model.setVertexList(null);
         model.setFaceVertIndex(null);
         PMDNode pmdNode = createNode(ai.getKey().getName());
-        if (JmeSystem.getFullName().indexOf("Android") == -1) {
-            try {
-                String vendor = GL11.glGetString(GL11.GL_VENDOR);
-                if (vendor != null && vendor.toLowerCase().contains("intel")) {
-                    pmdNode.setGlslSkinning(false);
-                } else {
-                    pmdNode.setGlslSkinning(true);
-                }
-            } catch(Exception ex) {
-                pmdNode.setGlslSkinning(false);
-            }
-        }
+//        if (JmeSystem.getFullName().indexOf("Android") == -1) {
+//            try {
+//                String vendor = GL11.glGetString(GL11.GL_VENDOR);
+//                if (vendor != null && vendor.toLowerCase().contains("intel")) {
+//                    pmdNode.setGlslSkinning(false);
+//                } else {
+//                    pmdNode.setGlslSkinning(true);
+//                }
+//            } catch(Exception ex) {
+//                pmdNode.setGlslSkinning(false);
+//            }
+//        }
+        return pmdNode;
+    }
+    private Object load3(AssetInfo ai) throws IOException {
+        this.assetManager = ai.getManager();
+        folderName = ai.getKey().getFolder();
+        InputStream is = ai.openStream();
+        meshConverter = PMDFileUtil.readPMDCache1(is);
+        is.close();
+        model = meshConverter.getModel();
+        PMDNode pmdNode = createNode(ai.getKey().getName());
+//        if (JmeSystem.getFullName().indexOf("Android") == -1) {
+//            try {
+//                String vendor = GL11.glGetString(GL11.GL_VENDOR);
+//                if (vendor != null && vendor.toLowerCase().contains("intel")) {
+//                    pmdNode.setGlslSkinning(false);
+//                } else {
+//                    pmdNode.setGlslSkinning(true);
+//                }
+//            } catch(Exception ex) {
+//                pmdNode.setGlslSkinning(false);
+//            }
+//        }
         return pmdNode;
     }
 
@@ -780,7 +709,7 @@ public class PMDLoaderGLSLSkinning2 implements AssetLoader{
         }
         return tex;
         } catch(Exception ex) {
-            logger.log(Level.WARNING,"Txture "+name+" not found.");
+            logger.log(Level.FINE,"Txture "+name+" not found.");
             return null;
         }
     }
index 39e283c..51f4219 100755 (executable)
@@ -88,13 +88,7 @@ public class PMDNode extends Node {
     PMDGeometry[] pmdGeometryArray;
     Map<String, Skin> skinMap = new HashMap<String, Skin>();
     Skin[] skinArray = new Skin[0];
-//    javax.vecmath.Vector3f skinPosArray[];
-//    javax.vecmath.Vector3f skinNormalArray[];
-    javax.vecmath.Vector3f skinPosArrayOrig[];
-//    javax.vecmath.Vector3f skinNormalArrayOrig[];
     FloatBuffer skinPosBuffer;
-//    float skinBoneWeightArray[];
-//    int skinBoneArray[];
     AssetManager assetManager;
     Matrix4f[] offsetMatrices;
     FloatBuffer offsetMatrixbuffer;
@@ -244,23 +238,6 @@ public class PMDNode extends Node {
         for (Skin skin : skinAray) {
             skinMap.put(skin.getSkinName(), skin);
         }
-        int skinVertSize = skinVertexList.size();
-//        skinPosArray = new javax.vecmath.Vector3f[skinVertSize];
-//        skinNormalArray = new javax.vecmath.Vector3f[skinVertSize];
-        skinPosArrayOrig = new javax.vecmath.Vector3f[skinVertSize];
-//        skinNormalArrayOrig = new javax.vecmath.Vector3f[skinVertSize];
-//        skinBoneWeightArray = new float[skinVertSize];
-//        skinBoneArray = new int[skinVertSize * 2];
-        for (int i = 0; i < skinVertSize; i++) {
-            PMDVertex v = skinVertexList.get(i);
-            skinPosArrayOrig[i] = v.getPos();
-//            skinPosArray[i] = new javax.vecmath.Vector3f(v.getPos());
-//            skinNormalArrayOrig[i] = v.getNormal();
-//            skinNormalArray[i] = new javax.vecmath.Vector3f(v.getNormal());
-//            skinBoneWeightArray[i] = (float) v.getBoneWeight() / 100f;
-//            skinBoneArray[i * 2] = v.getBoneNum1();
-//            skinBoneArray[i * 2 + 1] = v.getBoneNum2();
-        }
     }
 
     public PMDModel getPmdModel() {
index a7fea13..7500143 100755 (executable)
@@ -31,6 +31,8 @@
  */
 package projectkyoto.mmd.file;
 
+import java.io.DataInput;
+import java.io.DataOutput;
 import java.io.IOException;
 import java.io.Serializable;
 import java.nio.ByteBuffer;
@@ -54,15 +56,19 @@ public class Coords2d implements Serializable{
         this.u = u;
         this.v = v;
     }
-    public Coords2d(DataInputStreamLittleEndian is) throws IOException {
+    public Coords2d(DataInput is) throws IOException {
         u = is.readFloat();
         v = is.readFloat();
     }
-    public Coords2d readFromStream(DataInputStreamLittleEndian is) throws IOException {
+    public Coords2d readFromStream(DataInput is) throws IOException {
         u = is.readFloat();
         v = is.readFloat();
         return this;
     }
+    public void writeToStream(DataOutput os) throws IOException {
+        os.writeFloat(u);
+        os.writeFloat(v);
+    }
     public Coords2d readFromBuffer(ByteBuffer bb) {
         u = bb.getFloat();
         v = bb.getFloat();
index f441027..89c1a96 100755 (executable)
@@ -32,6 +32,7 @@
 package projectkyoto.mmd.file;
 
 import java.io.BufferedInputStream;
+import java.io.DataInput;
 import java.io.DataInputStream;
 import java.io.File;
 import java.io.FileInputStream;
@@ -45,39 +46,49 @@ import java.net.URL;
  *
  * @author Kazuhiko Kobayashi
  */
-public class DataInputStreamLittleEndian extends FilterInputStream {
+public class DataInputStreamLittleEndian extends FilterInputStream implements DataInput {
 //    public URL url;
+
     private DataInputStream dis;
     byte[] buf;
 
     public DataInputStreamLittleEndian(InputStream in) {
         super(in);
-        dis = new DataInputStream(this);
+        dis = new DataInputStream(in);
     }
+
     public DataInputStreamLittleEndian(URL url) throws IOException {
         super(new BufferedInputStream(url.openStream()));
 //        this.url = url;
         dis = new DataInputStream(this);
     }
+
     final byte[] getBuf(int size) {
         if (buf == null || buf.length < size) {
             buf = new byte[size];
         }
         return buf;
     }
+
+    @Override
     public final int readInt() throws IOException {
         return Integer.reverseBytes(dis.readInt());
     }
 
+    @Override
     public final short readShort() throws IOException {
         return Short.reverseBytes(dis.readShort());
     }
+
+    @Override
     public final int readUnsignedShort() throws IOException {
         short shortValue = readShort();
         int intValue = shortValue;
         intValue = intValue & 0xffff;
         return intValue;
     }
+
+    @Override
     public final int readUnsignedByte() throws IOException {
         byte byteValue = readByte();
         int intValue = byteValue;
@@ -85,30 +96,84 @@ public class DataInputStreamLittleEndian extends FilterInputStream {
         return intValue;
     }
 
+    @Override
     public final long readLong() throws IOException {
         return Long.reverseBytes(dis.readLong());
     }
 
+    @Override
     public final float readFloat() throws IOException {
         return Float.intBitsToFloat(readInt());
     }
 
+    @Override
     public final double readDouble() throws IOException {
         return Double.longBitsToDouble(readLong());
     }
+
     public final String readString(int size) throws IOException {
         byte[] buf = getBuf(size);
-        read(buf,0,size);
-        for(int i=0;i<size;i++) {
+        read(buf, 0, size);
+        for (int i = 0; i < size; i++) {
             if (buf[i] == 0) {
-                return new String(buf,0,i,"Shift_JIS").intern();
+                return new String(buf, 0, i, "Shift_JIS").intern();
             }
         }
-        return new String(buf,"Shift_JIS").intern();
+        return new String(buf, 0, size, "Shift_JIS").intern();
     }
-    public final byte readByte() throws IOException{
+
+    @Override
+    public final byte readByte() throws IOException {
         byte[] buf = getBuf(1);
-        read(buf,0,1);
+        read(buf, 0, 1);
         return buf[0];
     }
+
+    @Override
+    public long skip(long l) throws IOException {
+        long l2 = l;
+        while (l2 > 0) {
+            long l3 = dis.skip(l2);
+            l2 = l2 - l3;
+            if (l3 == 0) {
+                break;
+            }
+        }
+        return l;
+    }
+
+    @Override
+    public void readFully(byte[] bytes) throws IOException {
+        dis.readFully(bytes);
+    }
+
+    @Override
+    public void readFully(byte[] bytes, int i, int i1) throws IOException {
+        dis.readFully(bytes, i, i1);
+    }
+
+    @Override
+    public int skipBytes(int i) throws IOException {
+        return dis.skipBytes(i);
+    }
+
+    @Override
+    public boolean readBoolean() throws IOException {
+        return dis.readBoolean();
+    }
+
+    @Override
+    public char readChar() throws IOException {
+        return dis.readChar();
+    }
+
+    @Override
+    public String readLine() throws IOException {
+        return dis.readLine();
+    }
+
+    @Override
+    public String readUTF() throws IOException {
+        return dis.readUTF();
+    }
 }
diff --git a/src/projectkyoto/mmd/file/DataOutputStreamLittleEndian.java b/src/projectkyoto/mmd/file/DataOutputStreamLittleEndian.java
new file mode 100644 (file)
index 0000000..50a4ce4
--- /dev/null
@@ -0,0 +1,88 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package projectkyoto.mmd.file;
+
+import java.io.DataOutput;
+import java.io.DataOutputStream;
+import java.io.FilterOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+
+/**
+ *
+ * @author kobayasi
+ */
+public class DataOutputStreamLittleEndian extends FilterOutputStream implements DataOutput{
+    DataOutputStream dos;
+    public DataOutputStreamLittleEndian(OutputStream out) {
+        super(out);
+        dos = new DataOutputStream(out);
+    }
+
+    @Override
+    public void writeBoolean(boolean bln) throws IOException {
+        dos.writeBoolean(bln);
+    }
+
+    @Override
+    public void writeByte(int i) throws IOException {
+        dos.writeByte(i);
+    }
+
+    @Override
+    public void writeShort(int i) throws IOException {
+        dos.writeShort(Short.reverseBytes((short)i));
+    }
+
+    @Override
+    public void writeChar(int i) throws IOException {
+        dos.writeChar(i);
+    }
+
+    @Override
+    public void writeInt(int i) throws IOException {
+        dos.writeInt(Integer.reverseBytes(i));
+    }
+
+    @Override
+    public void writeLong(long l) throws IOException {
+        dos.writeLong(Long.reverseBytes(l));
+    }
+
+    @Override
+    public void writeFloat(float f) throws IOException {
+        writeInt(Float.floatToIntBits(f));
+    }
+
+    @Override
+    public void writeDouble(double d) throws IOException {
+        writeLong(Double.doubleToLongBits(d));
+    }
+
+    @Override
+    public void writeBytes(String string) throws IOException {
+        dos.writeBytes(string);
+    }
+
+    @Override
+    public void writeChars(String string) throws IOException {
+        dos.writeChars(string);
+    }
+
+    @Override
+    public void writeUTF(String string) throws IOException {
+        dos.writeUTF(string);
+    }
+
+    @Override
+    public void flush() throws IOException {
+        dos.flush();
+    }
+
+    @Override
+    public void close() throws IOException {
+        dos.close();
+    }
+}
index b983b8a..6f74ce7 100755 (executable)
@@ -31,6 +31,7 @@
  */
 package projectkyoto.mmd.file;
 
+import java.io.DataOutput;
 import java.io.IOException;
 import java.io.Serializable;
 import java.nio.ByteBuffer;
@@ -67,6 +68,9 @@ public class PMDBone implements Serializable {
     public PMDBone() {
     }
     public PMDBone(DataInputStreamLittleEndian is) throws IOException {
+        readFromStream(is);
+    }
+    public PMDBone readFromStream(DataInputStreamLittleEndian is) throws IOException {
         boneName = is.readString(20);
         parentBoneIndex = is.readUnsignedShort();
         tailPosBoneIndex = is.readUnsignedShort();
@@ -79,6 +83,17 @@ public class PMDBone implements Serializable {
         } else {
             hiza = false;
         }
+        return this;
+    }
+    public void writeToStream(DataOutput os) throws IOException {
+        PMDUtil.writeString(os, boneName, 20);
+        os.writeShort(parentBoneIndex);
+        os.writeShort(tailPosBoneIndex);
+        os.writeByte(boneType);
+        os.writeShort(targetBone);
+        os.writeFloat(boneHeadPos.x);
+        os.writeFloat(boneHeadPos.y);
+        os.writeFloat(-boneHeadPos.z);
     }
 
     public void readFromBuffer(ByteBuffer bb) {
index 8ad6e95..319251f 100755 (executable)
@@ -32,6 +32,7 @@
 
 package projectkyoto.mmd.file;
 
+import java.io.DataOutput;
 import java.io.IOException;
 import java.io.Serializable;
 import java.nio.ByteBuffer;
@@ -49,6 +50,10 @@ public class PMDBoneDisp implements Serializable{
         boneIndex = is.readUnsignedShort();
         boneDispFrameIndex = is.readUnsignedByte();
     }
+    public void writeToStream(DataOutput os) throws IOException {
+        os.writeShort(boneIndex);
+        os.writeByte(boneDispFrameIndex);
+    }
     public void readFromBuffer(ByteBuffer bb) {
         boneIndex = bb.getShort();
         boneDispFrameIndex = bb.get();
index 246d25e..1b6e58c 100755 (executable)
@@ -32,6 +32,7 @@
 
 package projectkyoto.mmd.file;
 
+import java.io.DataOutput;
 import java.io.IOException;
 import java.io.Serializable;
 import java.nio.ByteBuffer;
@@ -53,6 +54,12 @@ public class PMDBoneDispList implements Serializable{
             boneDispArray[i] = new PMDBoneDisp(is);
         }
     }
+    public void writeToStream(DataOutput os) throws IOException {
+        os.writeInt(boneDispCount);
+        for(int i=0;i<boneDispCount;i++) {
+            boneDispArray[i].writeToStream(os);
+        }
+    }
     public void readFromBuffer(ByteBuffer bb) {
         boneDispCount = bb.getInt();
         boneDispArray = new PMDBoneDisp[boneDispCount];
index 5d94b29..9325d10 100755 (executable)
@@ -32,6 +32,7 @@
 
 package projectkyoto.mmd.file;
 
+import java.io.DataOutput;
 import java.io.IOException;
 import java.io.Serializable;
 import java.nio.ByteBuffer;
@@ -54,6 +55,12 @@ public class PMDBoneDispNameList implements Serializable{
             dispNameArray[i] = is.readString(50);
         }
     }
+    public void writeToStream(DataOutput os) throws IOException {
+        os.writeByte(boneDispNameCount);
+        for(String dispName : dispNameArray) {
+            PMDUtil.writeString(os, dispName, 50);
+        }
+    }
     public void readFromBuffer(ByteBuffer bb) {
         boneDispNameCount = bb.get();
         dispNameArray = new String[boneDispNameCount];
index 2cb9544..e12f78f 100755 (executable)
@@ -32,6 +32,7 @@
 
 package projectkyoto.mmd.file;
 
+import java.io.DataOutput;
 import java.io.IOException;
 import java.io.Serializable;
 
@@ -49,6 +50,12 @@ public class PMDBoneList implements Serializable{
             bones[i] = new PMDBone(is);
         }
     }
+    public void writeToStream(DataOutput os) throws IOException {
+        os.writeShort(boneCount);
+        for(PMDBone bone : bones) {
+            bone.writeToStream(os);
+        }
+    }
     @Override
     public String toString() {
         StringBuffer sb = new StringBuffer();
index 64c0277..fda9844 100755 (executable)
@@ -29,9 +29,9 @@
  * 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.mmd.file;
 
+import java.io.DataOutput;
 import java.io.IOException;
 import java.io.Serializable;
 
@@ -39,7 +39,7 @@ import java.io.Serializable;
  *
  * @author kobayasi
  */
-public class PMDHeaderEnglish implements Serializable{
+public class PMDHeaderEnglish implements Serializable {
 
     private int englishNameCompatibility;
     private String modelName;
@@ -51,8 +51,8 @@ public class PMDHeaderEnglish implements Serializable{
     public PMDHeaderEnglish(PMDModel model, DataInputStreamLittleEndian is) throws IOException {
         englishNameCompatibility = is.readUnsignedByte();
         if (englishNameCompatibility == 1) {
-        modelName = is.readString(20);
-        comment = is.readString(256);
+            modelName = is.readString(20);
+            comment = is.readString(256);
             boneNameEnglish = new String[model.getBoneList().getBoneCount()];
             for (int i = 0; i < boneNameEnglish.length; i++) {
                 boneNameEnglish[i] = is.readString(20);
@@ -63,12 +63,29 @@ public class PMDHeaderEnglish implements Serializable{
             }
 
             dispNameEnglish = new String[model.getBoneDispNameList().getBoneDispNameCount()];
-            for(int i=0;i<dispNameEnglish.length;i++) {
+            for (int i = 0; i < dispNameEnglish.length; i++) {
                 dispNameEnglish[i] = is.readString(50);
             }
         }
     }
 
+    public void writeToStream(DataOutput os) throws IOException {
+        os.writeByte(englishNameCompatibility);
+        if (englishNameCompatibility == 1) {
+            PMDUtil.writeString(os, modelName, 20);
+            PMDUtil.writeString(os, comment, 256);
+            for(String boneName : boneNameEnglish) {
+                PMDUtil.writeString(os, boneName, 20);
+            }
+            for(String skinName : skinNameEnglish) {
+                PMDUtil.writeString(os, skinName, 20);
+            }
+            for(String dispName : dispNameEnglish) {
+                PMDUtil.writeString(os, dispName, 50);
+            }
+        }
+    }
+
     @Override
     public String toString() {
         StringBuilder sb = new StringBuilder();
@@ -79,19 +96,19 @@ public class PMDHeaderEnglish implements Serializable{
             sb.append("modelName = ").append(modelName).append('\n');
             sb.append("comment = ").append(comment).append('\n');
             sb.append("boneNameEnglish = ").append("{\n");
-            for(int i=0;i<boneNameEnglish.length;i++) {
+            for (int i = 0; i < boneNameEnglish.length; i++) {
                 sb.append(i);
                 sb.append(" ").append(boneNameEnglish[i]).append('\n');
             }
             sb.append("}\n");
             sb.append("skinNameEnglish = ").append("{\n");
-            for(int i=0;i<skinNameEnglish.length;i++) {
+            for (int i = 0; i < skinNameEnglish.length; i++) {
                 sb.append(i);
                 sb.append(" ").append(skinNameEnglish[i]).append('\n');
             }
             sb.append("}\n");
             sb.append("dispNameEnglish = ").append("{\n");
-            for(int i=0;i<dispNameEnglish.length;i++) {
+            for (int i = 0; i < dispNameEnglish.length; i++) {
                 sb.append(i);
                 sb.append(" ").append(dispNameEnglish[i]).append('\n');
             }
index 39ad808..a908102 100755 (executable)
@@ -29,9 +29,9 @@
  * 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.mmd.file;
 
+import java.io.DataOutput;
 import java.io.IOException;
 import java.io.Serializable;
 
@@ -39,14 +39,15 @@ import java.io.Serializable;
  *
  * @author kobayasi
  */
-public class PMDIKData implements Serializable{
+public class PMDIKData implements Serializable {
+
     private int ikBoneIndex;
     private int ikTargetBoneIndex;
     private int ikChainLength;
     private int iterations;
     private float controlWeight;
     private int[] ikChildBoneIndex;
-    
+
     public PMDIKData(DataInputStreamLittleEndian is) throws IOException {
         ikBoneIndex = is.readUnsignedShort();
         ikTargetBoneIndex = is.readUnsignedShort();
@@ -54,22 +55,33 @@ public class PMDIKData implements Serializable{
         iterations = is.readShort();
         controlWeight = is.readFloat();
         ikChildBoneIndex = new int[ikChainLength];
-        for(int i=0;i<ikChainLength;i++) {
+        for (int i = 0; i < ikChainLength; i++) {
             ikChildBoneIndex[i] = is.readUnsignedShort();
         }
     }
 
+    public void writeToStream(DataOutput os) throws IOException {
+        os.writeShort(ikBoneIndex);
+        os.writeShort(ikTargetBoneIndex);
+        os.writeByte(ikChainLength);
+        os.writeShort(iterations);
+        os.writeFloat(controlWeight);
+        for (int s : ikChildBoneIndex) {
+            os.writeShort(s);
+        }
+    }
+
     @Override
     public String toString() {
         StringBuffer sb = new StringBuffer();
-        sb.append("{ikBoneIndex = "+ikBoneIndex);
-        sb.append("\n").append("ikTargetBoneIndex = "+ikTargetBoneIndex);
-        sb.append(" ikChainLength = "+ikChainLength);
-        sb.append(" \niterations = "+iterations);
-        sb.append("\ncontrolWeight = "+controlWeight);
+        sb.append("{ikBoneIndex = " + ikBoneIndex);
+        sb.append("\n").append("ikTargetBoneIndex = " + ikTargetBoneIndex);
+        sb.append(" ikChainLength = " + ikChainLength);
+        sb.append(" \niterations = " + iterations);
+        sb.append("\ncontrolWeight = " + controlWeight);
         sb.append("\n{");
-        for(int i=0;i<ikChainLength;i++) {
-            sb.append("ikChildBoneIndex = "+ikChildBoneIndex[i]);
+        for (int i = 0; i < ikChainLength; i++) {
+            sb.append("ikChildBoneIndex = " + ikChildBoneIndex[i]);
         }
         sb.append("}");
         return sb.toString();
@@ -122,5 +134,4 @@ public class PMDIKData implements Serializable{
     public void setIterations(int iterations) {
         this.iterations = iterations;
     }
-
 }
index a6c8a84..312446e 100755 (executable)
@@ -32,6 +32,7 @@
 
 package projectkyoto.mmd.file;
 
+import java.io.DataOutput;
 import java.io.IOException;
 import java.io.Serializable;
 
@@ -50,6 +51,12 @@ public class PMDIKList implements Serializable{
             pmdIKData[i] = new PMDIKData(is);
         }
     }
+    public void writeToStream(DataOutput os) throws IOException {
+        os.writeShort(ikDataCount);
+        for(PMDIKData ikData : pmdIKData) {
+            ikData.writeToStream(os);
+        }
+    }
 
     @Override
     public String toString() {
index da276f1..b0333ac 100755 (executable)
@@ -31,6 +31,7 @@
  */
 package projectkyoto.mmd.file;
 
+import java.io.DataOutput;
 import java.io.IOException;
 import java.io.Serializable;
 import javax.vecmath.Vector3f;
@@ -102,55 +103,42 @@ public class PMDJoint implements Serializable{
         constRot2 = new Vector3f(-is.readFloat(), -is.readFloat(), is.readFloat());
         
         float tmp;
-//        if (constPos1.x > constPos2.x) {
-//            tmp = constPos1.x;
-//            constPos1.x = constPos2.x;
-//            constPos2.x = tmp;
-//        }
-//        if (constPos1.y > constPos2.y) {
-//            tmp = constPos1.y;
-//            constPos1.y = constPos2.y;
-//            constPos2.y = tmp;
-//        }
-//        if (constPos1.z > constPos2.z) {
-//            tmp = constPos1.z;
-//            constPos1.z = constPos2.z;
-//            constPos2.z = tmp;
-//        }
-
-//        float tmp;
         tmp = constPos1.z;
         constPos1.z = constPos2.z;
         constPos2.z = tmp;
-//
-//        tmp = constRot1.x;
-//        constRot1.x = -constRot2.x;
-//        constRot2.x = -tmp;
-//        tmp = constRot1.y;
-//        constRot1.y = -constRot2.y;
-//        constRot2.y = -tmp;
-//
-//        Vector3f tmpV = constRot1;
-//        constRot1 = constRot2;
-//        constRot1 = constRot2;
-//        constRot2 = tmpV;
-//        constRot1.x *= -1f;
-//        constRot2.x *= -1f;
-//        constRot1.y *= -1f;
-//        constRot2.y *= -1f;
         swapConst(constRot1, constRot2);
-
-        //        tmp = constRot1.z;
-        //        constRot1.z = -constRot2.z;
-        //        constRot2.z = -tmp;
-        //        springPos = new Vector3f(is.readFloat(), is.readFloat(), -is.readFloat());
-        //        springRot = new Vector3f(-is.readFloat(), -is.readFloat(), is.readFloat());
         for (int i = 0; i < 6; i++) {
             stiffness[i] = is.readFloat();
         }
-//        stiffness[2] = -stiffness[2];
-//        stiffness[3] = -stiffness[3];
-//        stiffness[4] = -stiffness[4];
+    }
+    public void writeToStream(DataOutput os) throws IOException {
+        PMDUtil.writeString(os, jointName, 20);
+        os.writeInt(rigidBodyA);
+        os.writeInt(rigidBodyB);
+        PMDUtil.writeVector3f(os, jointPos);
+        
+        os.writeFloat(-jointRot.x);
+        os.writeFloat(-jointRot.y);
+        os.writeFloat(jointRot.z);
+        
+        os.writeFloat(constPos1.x);
+        os.writeFloat(constPos1.y);
+        os.writeFloat(-constPos2.z);
+
+        os.writeFloat(constPos2.x);
+        os.writeFloat(constPos2.y);
+        os.writeFloat(-constPos1.z);
+        
+        os.writeFloat(-constRot2.x);
+        os.writeFloat(-constRot2.y);
+        os.writeFloat(constRot1.z);
+        
+        os.writeFloat(-constRot1.x);
+        os.writeFloat(-constRot1.y);
+        os.writeFloat(constRot2.z);
+        for(float f : stiffness) {
+            os.writeFloat(f);
+        }
     }
 
     @Override
index c906c04..e4dc002 100755 (executable)
@@ -32,6 +32,7 @@
 
 package projectkyoto.mmd.file;
 
+import java.io.DataOutput;
 import java.io.IOException;
 import java.io.Serializable;
 
@@ -55,7 +56,12 @@ public class PMDJointList implements Serializable{
             jointArray[i] = new PMDJoint(is);
         }
     }
-
+    public void writeToStream(DataOutput os) throws IOException {
+        os.writeInt(jointCount);
+        for(PMDJoint joint : jointArray) {
+            joint.writeToStream(os);
+        }
+    }
     @Override
     public String toString() {
         StringBuilder sb = new StringBuilder();
index 42ba691..b4d1b8b 100755 (executable)
@@ -32,6 +32,7 @@
 package projectkyoto.mmd.file;
 
 import java.io.ByteArrayOutputStream;
+import java.io.DataOutput;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.Serializable;
@@ -47,6 +48,7 @@ public class PMDMaterial implements Serializable{
     private byte edgeFlag;
     private int faceVertCount;
     private String textureFileName; // 20文字
+    private int materialNo;
 //    private byte[] textureData;
 
     public PMDMaterial() {
@@ -57,33 +59,13 @@ public class PMDMaterial implements Serializable{
         edgeFlag = is.readByte();
         faceVertCount = is.readInt();
         textureFileName = is.readString(20);
-//        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;
-//                }
-//            }
-//        }
+    }
+    public void writeToStream(DataOutput os) throws IOException {
+        material.writeToStream(os);
+        os.writeByte(toonIndex);
+        os.writeByte(edgeFlag);
+        os.writeInt(faceVertCount);
+        PMDUtil.writeString(os, textureFileName, 20);
     }
 
     public byte getEdgeFlag() {
@@ -126,6 +108,14 @@ public class PMDMaterial implements Serializable{
         this.toonIndex = toonIndex;
     }
 
+    public int getMaterialNo() {
+        return materialNo;
+    }
+
+    public void setMaterialNo(int materialNo) {
+        this.materialNo = materialNo;
+    }
+
 //    public byte[] getTextureData() {
 //        return textureData;
 //    }
index a7d2d72..28b9e1d 100755 (executable)
@@ -30,6 +30,7 @@
 package projectkyoto.mmd.file;
 
 import java.io.BufferedInputStream;
+import java.io.DataOutput;
 import java.io.EOFException;
 import java.io.File;
 import java.io.FileOutputStream;
@@ -104,6 +105,10 @@ public class PMDModel implements Serializable{
 
     public void readFromStream(DataInputStreamLittleEndian is) throws
             IOException {
+        readFromStream(is, false);
+    }
+    public void readFromStream(DataInputStreamLittleEndian is, boolean skipVertFlag) throws
+            IOException {
         id = is.readString(3);
         if (!"Pmd".equals(id)) {
             throw new InvalidPMDFileException("Invalid ID:" + id);
@@ -114,29 +119,51 @@ public class PMDModel implements Serializable{
         vertCount = is.readInt();
 //        vertexList = new PMDVertex[vertCount];
 //        vertexBuffer = ByteBuffer.allocateDirect(PMDVertex.size() * vertCount);
-        vertexBuffer = BufferUtil.createByteBuffer(PMDVertex.size() * vertCount);
-        vertexBuffer.order(ByteOrder.nativeOrder());
-        PMDVertex tmpVertex = new PMDVertex();
-        for (int i = 0; i < vertCount; i++) {
-            tmpVertex.readFromStream(is);
-            tmpVertex.writeToBuffer(vertexBuffer);
-            
+        if (skipVertFlag) {
+//            vertexBuffer = BufferUtil.createByteBuffer(PMDVertex.size() * vertCount);
+//            vertexBuffer.order(ByteOrder.nativeOrder());
+//            PMDVertex tmpVertex = new PMDVertex();
+//            for (int i = 0; i < vertCount; i++) {
+//                tmpVertex.readFromStream(is);
+////                tmpVertex.writeToBuffer(vertexBuffer);
+//
+//            }
+            is.skip(38 * vertCount);
+        } else {
+            vertexBuffer = BufferUtil.createByteBuffer(PMDVertex.size() * vertCount);
+            vertexBuffer.order(ByteOrder.nativeOrder());
+            PMDVertex tmpVertex = new PMDVertex();
+            for (int i = 0; i < vertCount; i++) {
+                tmpVertex.readFromStream(is);
+                tmpVertex.writeToBuffer(vertexBuffer);
+            }
         }
         faceVertCount = is.readInt();
-        faceVertIndex = new int[faceVertCount];
-        for (int i = 0; i < faceVertCount; i++) {
-            faceVertIndex[i] = is.readUnsignedShort();
-        }
-        // 逆にする。
-        for (int i = 0; i < faceVertCount; i += 3) {
-            int tmp = faceVertIndex[i];
-            faceVertIndex[i] = faceVertIndex[i + 1];
-            faceVertIndex[i + 1] = tmp;
+        if (skipVertFlag) {
+//            for (int i = 0; i < faceVertCount; i++) {
+//                is.readUnsignedShort();
+//            }
+            long skip = is.skip(faceVertCount * 2);
+            if (skip != faceVertCount * 2) {
+                throw new IllegalArgumentException("skip = "+skip+" "+faceVertCount * 2);
+            }
+        } else {
+            faceVertIndex = new int[faceVertCount];
+            for (int i = 0; i < faceVertCount; i++) {
+                faceVertIndex[i] = is.readUnsignedShort();
+            }
+            // 逆にする。
+            for (int i = 0; i < faceVertCount; i += 3) {
+                int tmp = faceVertIndex[i];
+                faceVertIndex[i] = faceVertIndex[i + 1];
+                faceVertIndex[i + 1] = tmp;
+            }
         }
         materialCount = is.readInt();
         material = new PMDMaterial[materialCount];
         for (int i = 0; i < materialCount; i++) {
             material[i] = new PMDMaterial(is);
+            material[i].setMaterialNo(i);
         }
         boneList = new PMDBoneList(is);
         ikList = new PMDIKList(is);
@@ -161,6 +188,43 @@ public class PMDModel implements Serializable{
 //        rigidBodyList = new PMDRigidBodyList();
 //        jointList = new PMDJointList();
     }
+    public void writeToStream(DataOutput os) throws IOException {
+        PMDUtil.writeString(os, "Pmd", 3);
+        os.writeFloat(version);
+        PMDUtil.writeString(os, modelName, 20);
+        PMDUtil.writeString(os, comment, 256);
+        os.writeInt(vertCount);
+        System.out.print("vertCount out = "+vertCount);
+        for (int i = 0; i < vertCount; i++) {
+            PMDVertex tmpVertex = new PMDVertex();
+            getVertex(i, tmpVertex);
+            tmpVertex.writeToStream(os);
+        }
+        os.writeInt(faceVertCount);
+        for (int i = 0; i < faceVertCount; i += 3) {
+            os.writeShort(faceVertIndex[i+1]);
+            os.writeShort(faceVertIndex[i]);
+            os.writeShort(faceVertIndex[i+2]);
+        }
+        os.writeInt(materialCount);
+        for(PMDMaterial mat : material) {
+            mat.writeToStream(os);
+        }
+        boneList.writeToStream(os);
+        ikList.writeToStream(os);
+        os.writeShort(skinCount);
+        for(PMDSkinData skin : skinData) {
+            skin.writeToStream(os);
+        }
+        skinDispList.writeToStream(os);
+        boneDispNameList.writeToStream(os);
+        boneDispList.writeToStream(os);
+        headerEnglish.writeToStream(os);
+        toonTextureList.writeToStream(os);
+        rigidBodyList.writeToStream(os);
+        jointList.writeToStream(os);
+        
+    }    
     public PMDVertex getVertex(int i) {
         return getVertex(i, new PMDVertex());
     }
index d9f1fdb..022d8ab 100755 (executable)
@@ -32,6 +32,7 @@
 
 package projectkyoto.mmd.file;
 
+import java.io.DataOutput;
 import java.io.IOException;
 import java.io.Serializable;
 import javax.vecmath.Vector3f;
@@ -75,6 +76,26 @@ public class PMDRigidBody implements Serializable{
         friction = is.readFloat();
         rigidBodyType = is.readUnsignedByte();
     }
+    public void writeToStream(DataOutput os) throws IOException {
+        PMDUtil.writeString(os, rigidBodyName, 20);
+        os.writeShort(relBoneIndex);
+        os.writeByte(rigidBodyGroupIndex);
+        os.writeShort(rigidBodyGroupTarget);
+        os.writeByte(shapeType);
+        os.writeFloat(shapeW);
+        os.writeFloat(shapeH);
+        os.writeFloat(shapeD);
+        PMDUtil.writeVector3f(os, pos);
+        os.writeFloat(-rot.x);
+        os.writeFloat(-rot.y);
+        os.writeFloat(rot.z);
+        os.writeFloat(weight);
+        os.writeFloat(posDim);
+        os.writeFloat(rotDim);
+        os.writeFloat(recoil);
+        os.writeFloat(friction);
+        os.writeByte(rigidBodyType);
+    }
 
     @Override
     public String toString() {
index cc9dbb7..8b7604a 100755 (executable)
@@ -24,6 +24,7 @@
  */
 package projectkyoto.mmd.file;
 
+import java.io.DataOutput;
 import java.io.IOException;
 import java.io.Serializable;
 
@@ -48,6 +49,12 @@ public class PMDRigidBodyList implements Serializable{
             rigidBodyArray[i] = new PMDRigidBody(is);
         }
     }
+    public void writeToStream(DataOutput os) throws IOException {
+        os.writeInt(rigidBodyCount);
+        for(PMDRigidBody rigidBody : rigidBodyArray) {
+            rigidBody.writeToStream(os);
+        }
+    }
 
     @Override
     public String toString() {
index bb4f1f4..f39068a 100755 (executable)
@@ -33,6 +33,7 @@
 package projectkyoto.mmd.file;
 
 import com.jme3.util.BufferUtils;
+import java.io.DataOutput;
 import java.io.IOException;
 import java.io.Serializable;
 import java.nio.FloatBuffer;
@@ -68,6 +69,19 @@ public class PMDSkinData implements Serializable{
             skinBuf.put(-is.readFloat());
         }
     }
+    public void writeToStream(DataOutput os) throws IOException {
+        PMDUtil.writeString(os, skinName, 20);
+        os.writeInt(skinVertCount);
+        os.writeByte(skinType);
+        indexBuf.position(0);
+        skinBuf.position(0);
+        for(int i=0;i<skinVertCount;i++) {
+            os.writeInt(indexBuf.get() & 0xffff);
+            os.writeFloat(skinBuf.get());
+            os.writeFloat(skinBuf.get());
+            os.writeFloat(-skinBuf.get());
+        }
+    }
 
     @Override
     public String toString() {
index ae5ce36..bc60da2 100755 (executable)
@@ -32,6 +32,7 @@
 
 package projectkyoto.mmd.file;
 
+import java.io.DataOutput;
 import java.io.IOException;
 import java.io.Serializable;
 
@@ -49,6 +50,12 @@ public class PMDSkinDispList implements Serializable{
             skinIndexArray[i] = is.readShort();
         }
     }
+    public void writeToStream(DataOutput os) throws IOException {
+        os.writeByte(skinDispCount);
+        for(short s : skinIndexArray) {
+            os.writeShort(s);
+        }
+    }
 
     @Override
     public String toString() {
index 8e5f2f6..3d4bc8b 100755 (executable)
@@ -32,6 +32,7 @@
 
 package projectkyoto.mmd.file;
 
+import java.io.DataOutput;
 import java.io.IOException;
 import java.io.Serializable;
 import javax.vecmath.Vector3f;
@@ -55,7 +56,12 @@ public class PMDSkinVertData implements Serializable{
         skinVertPos.y = is.readFloat();
         skinVertPos.z = -is.readFloat();
     }
-
+    public void writeToStream(DataOutput os) throws IOException {
+        os.writeInt(skinVertIndex);
+        os.writeFloat(skinVertPos.x);
+        os.writeFloat(skinVertPos.y);
+        os.writeFloat(-skinVertPos.z);
+    }
     public int getSkinVertIndex() {
         return skinVertIndex;
     }
index 6a1d4af..b8f74f9 100755 (executable)
@@ -32,6 +32,7 @@
 
 package projectkyoto.mmd.file;
 
+import java.io.DataOutput;
 import java.io.IOException;
 import java.io.Serializable;
 
@@ -47,12 +48,16 @@ public class PMDToonTextureList implements Serializable{
             toonFileName[i] = "";
         }
     }
-    
     public PMDToonTextureList(DataInputStreamLittleEndian is) throws IOException {
         for(int i=0;i<10;i++) {
             toonFileName[i] = is.readString(100);
         }
     }
+    public void writeToStream(DataOutput os) throws IOException {
+        for(int i=0;i<10;i++) {
+            PMDUtil.writeString(os, toonFileName[i], 100);
+        }
+    }    
 
     @Override
     public String toString() {
index 11919e5..166b284 100755 (executable)
@@ -31,6 +31,7 @@
  */
 package projectkyoto.mmd.file;
 
+import java.io.DataOutput;
 import java.io.IOException;
 import java.nio.ByteBuffer;
 import javax.vecmath.Vector3f;
@@ -61,4 +62,21 @@ public class PMDUtil {
         bb.putFloat(v.z);
         return v;
     }
+    public static void writeString(DataOutput os, String s, int len) throws IOException {
+        byte[] buf = s.getBytes("Shift_JIS");
+        int l = buf.length;
+        if (l > len) {
+            os.write(buf, 0, len);
+        } else {
+            os.write(buf);
+            for(;l < len;l++) {
+                os.writeByte(0);
+            }
+        }
+    }
+    public static void writeVector3f(DataOutput os, Vector3f v) throws IOException{
+        os.writeFloat(v.x);
+        os.writeFloat(v.y);
+        os.writeFloat(-v.z);
+    }
 }
index d8921b8..ba7b74e 100755 (executable)
@@ -32,6 +32,7 @@
 
 package projectkyoto.mmd.file;
 
+import java.io.DataOutput;
 import java.io.IOException;
 import java.io.Serializable;
 import java.nio.ByteBuffer;
@@ -79,6 +80,15 @@ public class PMDVertex implements Serializable{
         edgeFlag = is.readByte();
         return this;
     }
+    public void writeToStream(DataOutput os) throws IOException {
+        PMDUtil.writeVector3f(os, pos);
+        PMDUtil.writeVector3f(os, normal);
+        uv.writeToStream(os);
+        os.writeShort(boneNum1);
+        os.writeShort(boneNum2);
+        os.writeByte(boneWeight);
+        os.writeByte(edgeFlag);
+    }    
     public PMDVertex readFromBuffer(ByteBuffer bb) {
         PMDUtil.readVector3f(bb, pos);
         PMDUtil.readVector3f(bb, normal);
index ea02003..5665ed8 100755 (executable)
@@ -32,6 +32,7 @@
 
 package projectkyoto.mmd.file;
 
+import java.io.DataOutput;
 import java.io.IOException;
 import java.io.Serializable;
 
@@ -85,6 +86,11 @@ public class XColorRGB implements Serializable{
         green = is.readFloat();
         blue = is.readFloat();
     }
+    public void writeToStream(DataOutput os) throws IOException {
+        os.writeFloat(red);
+        os.writeFloat(green);
+        os.writeFloat(blue);
+    }
     @Override
     public String toString() {
         return "{red = "+red
index 40774f1..ac38508 100755 (executable)
@@ -32,6 +32,7 @@
 
 package projectkyoto.mmd.file;
 
+import java.io.DataOutput;
 import java.io.IOException;
 import java.io.Serializable;
 
@@ -55,6 +56,10 @@ public class XColorRGBA extends XColorRGB implements Serializable{
         super(is);
         alpha = is.readFloat();
     }
+    public void writeToStream(DataOutput os) throws IOException {
+        super.writeToStream(os);
+        os.writeFloat(alpha);
+    }
 
     public float getAlpha() {
         return alpha;
index 97b257d..28a038d 100755 (executable)
@@ -32,6 +32,7 @@
 
 package projectkyoto.mmd.file;
 
+import java.io.DataOutput;
 import java.io.IOException;
 import java.io.Serializable;
 
@@ -53,6 +54,12 @@ public class XMaterial implements Serializable{
         specularColor = new XColorRGB(is);
         ambientColor = new XColorRGB(is);
     }
+    public void writeToStream(DataOutput os) throws IOException {
+        faceColor.writeToStream(os);
+        os.writeFloat(power);
+        specularColor.writeToStream(os);
+        ambientColor.writeToStream(os);
+    }
 
     @Override
     public String toString() {
index a253b7a..6f5020e 100644 (file)
@@ -4,8 +4,12 @@
  */
 package projectkyoto.mmd.file.util2;
 
+import com.jme3.util.BufferUtils;
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
 import java.io.File;
 import java.io.IOException;
+import java.io.OutputStream;
 import java.io.RandomAccessFile;
 import java.io.UnsupportedEncodingException;
 import java.nio.ByteBuffer;
@@ -24,7 +28,7 @@ import javax.vecmath.Quat4f;
  */
 public class BufferUtil {
     public static File tmpDir = null;
-    public static final Logger logger = Logger.getLogger(BufferUtil.class.getName());
+    private static final Logger logger = Logger.getLogger(BufferUtil.class.getName());
     public static ByteBuffer createByteBuffer2(int size) {
         ByteBuffer bb = ByteBuffer.allocateDirect(size);
         bb.order(ByteOrder.nativeOrder());
@@ -120,4 +124,32 @@ public class BufferUtil {
         bb.putFloat(q.z);
         bb.putFloat(q.w);
     }
+    public static void write(ByteBuffer bb, DataOutputStream os, byte[] buf) throws IOException {
+        bb.position(0);
+        final int capacity = bb.capacity();
+        os.writeInt(capacity);
+        while(bb.position() < capacity) {
+            int size = capacity - bb.position();
+            if (size > buf.length) {
+                size = buf.length;
+            }
+            bb.get(buf, 0, size);
+            os.write(buf, 0, size);
+        }
+    }
+    public static ByteBuffer read(DataInputStream is, byte[]buf) throws IOException {
+        final int capacity = is.readInt();
+        ByteBuffer bb = BufferUtils.createByteBuffer(capacity);
+        while(bb.position() < capacity) {
+            int size = capacity - bb.position();
+            if (size > buf.length) {
+                size = buf.length;
+            }
+            is.read(buf, 0, size);
+            bb.put(buf, 0, size);
+        }
+        bb.position(0);
+        return bb;
+    }
+
 }
index ae957f2..7b721da 100755 (executable)
 
 package projectkyoto.mmd.file.util2;
 
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
 import java.io.Serializable;
 import java.net.URL;
 import java.nio.ByteBuffer;
@@ -67,10 +72,11 @@ public class MeshConverter implements Serializable{
     HashMap<Integer, Integer> meshTmpVertMap = new HashMap<Integer, Integer>();
     HashMap<Integer, Integer> skinTmpVertMap = new HashMap<Integer, Integer>();
     public ByteBuffer interleavedBuffer;
-    public ArrayList<ByteBuffer> skinBufferList;
-    public ByteBuffer skinIndexBuffer;
     int currentVertIndex = 0;
     PMNData pmnData;
+    public MeshConverter() {
+        
+    }
     public MeshConverter(PMDModel model) {
         this.model = model;
         skinMeshData = new SkinMeshData(this, model);
@@ -111,7 +117,7 @@ public class MeshConverter implements Serializable{
             meshTmpVertMap.clear();
             PMDMaterial material = model.getMaterial()[materialNo];
             // find same material
-            MeshData meshData = new MeshData(model, maxBoneSize, material, currentVertIndex);
+            MeshData meshData = new MeshData(model, maxBoneSize, material);
             for(int meshIndex = meshDataList.size()-1;meshIndex >=0;meshIndex--) {
                 PMDMaterial material2 = meshDataList.get(meshIndex).getMaterial();
                 if (material.equals(material2)) {
@@ -137,7 +143,7 @@ public class MeshConverter implements Serializable{
                     addSkinTriangle(material, i1, i2, i3);
                 } else {
                     if (!meshData.addTriangle(this, i1, i2, i3)) {
-                        meshData = new MeshData(model, maxBoneSize, material, currentVertIndex);
+                        meshData = new MeshData(model, maxBoneSize, material);
                         meshTmpVertMap.clear();
                         meshDataList.add(meshData);
                         meshData.addTriangle(this, i1, i2, i3);
@@ -156,8 +162,13 @@ public class MeshConverter implements Serializable{
             MeshData md = it.next();
             if (md.getIndexList().size() == 0) {
                 it.remove();
+            } else {
+                md.createMesh();
             }
         }
+        skinMeshData.createSkinCommonVertData();
+        meshTmpVertMap = null;
+        skinTmpVertMap = null;
     }
     void removeUnusedSkinVertex() {
         HashSet<Integer> tmpSet = new HashSet<Integer>();
@@ -374,6 +385,31 @@ public class MeshConverter implements Serializable{
         }
         return size;
     }
+    public void write(OutputStream os) throws IOException {
+        DataOutputStream dos = new DataOutputStream(os);
+        byte[] buf = new byte[1024 * 16];
+        dos.writeInt(meshDataList.size());
+        for(int i=0;i<meshDataList.size();i++) {
+            MeshData md = meshDataList.get(i);
+            md.write(dos, buf);
+        }
+        skinMeshData.write(dos, buf);
+        dos.flush();
+    }
+    public void read(InputStream is) throws IOException {
+        DataInputStream dis = new DataInputStream(is);
+        byte[] buf = new byte[1024 * 16];
+        meshDataList = new ArrayList<MeshData>();
+        int meshDataSize = dis.readInt();
+        for(int i=0;i<meshDataSize;i++) {
+            MeshData md = new MeshData(model, maxBoneSize, null);
+            md.read(dis, buf);
+            meshDataList.add(md);
+        }
+        skinMeshData = new SkinMeshData();
+        skinMeshData.model = model;
+        skinMeshData.read(dis, buf);
+    }
     public int getMaxBoneSize() {
         return maxBoneSize;
     }
index 77da52d..e1fdfbb 100755 (executable)
 
 package projectkyoto.mmd.file.util2;
 
+import com.jme3.math.FastMath;
+import com.jme3.util.BufferUtils;
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
 import java.nio.ByteBuffer;
 import java.nio.ByteOrder;
+import java.nio.FloatBuffer;
+import java.nio.ShortBuffer;
 import java.util.ArrayList;
 import java.util.HashSet;
 import java.util.List;
@@ -56,16 +64,13 @@ public class MeshData {
     List<Integer> indexList = new ArrayList<Integer>();
 //    public ByteBuffer indexBuffer;
     List<Integer> vertIndexList = new ArrayList<Integer>();
-    public int offset;
     private PMDVertex tmpVert = new PMDVertex();
-    public MeshData(PMDModel model, int maxBoneSize, PMDMaterial material
-            , int offset) {
+    public MeshData(PMDModel model, int maxBoneSize, PMDMaterial material) {
         this.model = model;
         this.maxBoneSize = maxBoneSize;
         this.material = material;
 //        indexBuffer = ByteBuffer.allocateDirect(material.getFaceVertCount() * 2);
 //        indexBuffer.order(ByteOrder.nativeOrder());
-        this.offset = offset;
     }
     public boolean addTriangle(MeshConverter mc, int i1,int i2,int i3) {
         int boneListSizeBefore = boneList.size();
@@ -118,7 +123,150 @@ public class MeshData {
 //        indexBuffer.putShort((short)newVertIndex);
         indexList.add(newVertIndex);
     }
-    public List<Integer> getBoneList() {
+    ByteBuffer vfbb;
+    ByteBuffer nfbb;
+    ByteBuffer tfbb;
+    ByteBuffer wfbb;
+    ByteBuffer isbb;
+    ByteBuffer bisbb;
+    ByteBuffer indexBufferb;
+
+    public FloatBuffer vfb;
+    public FloatBuffer nfb;
+    public FloatBuffer tfb;
+    public FloatBuffer wfb;
+    public ShortBuffer isb;
+    public ShortBuffer bisb;
+    public ShortBuffer indexBuffer;
+    public int[] indexArray;
+    public void write(DataOutputStream os, byte[] buf) throws IOException {
+        os.writeInt(material.getMaterialNo());
+        BufferUtil.write(vfbb, os, buf);
+        BufferUtil.write(nfbb, os, buf);
+        if (tfbb != null) {
+            os.writeBoolean(true);
+            BufferUtil.write(tfbb, os, buf);
+        } else {
+            os.writeBoolean(false);
+        }
+        BufferUtil.write(wfbb, os, buf);
+        BufferUtil.write(isbb, os, buf);
+        BufferUtil.write(bisbb, os, buf);
+        BufferUtil.write(indexBufferb, os, buf);
+        os.writeInt(indexArray.length);
+        for(int i : indexArray) {
+            os.writeInt(i);
+        }
+    }
+    public void read(DataInputStream is, byte[] buf) throws IOException {
+        material = model.getMaterial()[is.readInt()];
+        vfbb = BufferUtil.read(is, buf);
+        vfb = vfbb.asFloatBuffer();
+        nfbb = BufferUtil.read(is, buf);
+        nfb = nfbb.asFloatBuffer();
+        if (is.readBoolean()) {
+            tfbb = BufferUtil.read(is, buf);
+            tfb = tfbb.asFloatBuffer();
+        }
+        wfbb = BufferUtil.read(is, buf);
+        wfb = wfbb.asFloatBuffer();
+        isbb = BufferUtil.read(is, buf);
+        isb = isbb.asShortBuffer();
+        bisbb = BufferUtil.read(is, buf);
+        bisb = bisbb.asShortBuffer();
+        indexBufferb = BufferUtil.read(is, buf);
+        indexBuffer = indexBufferb.asShortBuffer();
+        int length = is.readInt();
+        indexArray = new int[length];
+        for(int i=0;i<length;i++) {
+            indexArray[i] = is.readInt();
+        }
+    }
+    void createMesh() {
+        boolean textureFlag = true;
+        if (getMaterial().getTextureFileName().length() == 0) {
+            textureFlag = false;
+        }
+        vfbb = BufferUtils.createByteBuffer(4 * getVertIndexList().size() * 3);
+        vfb = vfbb.asFloatBuffer();
+//        vfb = BufferUtils.createFloatBuffer(getVertIndexList().size() * 3);
+        nfbb = BufferUtils.createByteBuffer(4 * getVertIndexList().size() * 3);
+        nfb = nfbb.asFloatBuffer();
+//        nfb = BufferUtils.createFloatBuffer(getVertIndexList().size() * 3);
+
+        tfb = null;
+        if (textureFlag ) {
+            tfbb = BufferUtils.createByteBuffer(4 * getVertIndexList().size() * 2);
+            tfb = tfbb.asFloatBuffer();
+//            tfb = BufferUtils.createFloatBuffer(getVertIndexList().size() * 2);
+        }
+        wfbb = BufferUtils.createByteBuffer(4 * getVertIndexList().size() * 2);
+        wfb = wfbb.asFloatBuffer();
+//        wfb = BufferUtils.createFloatBuffer(getVertIndexList().size() * 2);
+        isbb = BufferUtils.createByteBuffer(2 * getIndexList().size());
+        isb = isbb.asShortBuffer();
+//        isb = BufferUtils.createShortBuffer(getIndexList().size()/*md.getMaterial().getFaceVertCount()*/);
+        bisbb = BufferUtils.createByteBuffer(2 * getVertIndexList().size() * 2);
+        bisb = bisbb.asShortBuffer();
+//        bisb = BufferUtils.createShortBuffer(getVertIndexList().size() * 2);
+        PMDVertex v = new PMDVertex();
+        for (Integer vertIndex : getVertIndexList()) {
+            model.getVertex(vertIndex, v);
+            vfb.put(v.getPos().x).put(v.getPos().y).put(v.getPos().z);
+            nfb.put(v.getNormal().x).put(v.getNormal().y).put(v.getNormal().z);
+
+//            bvfb.put(v.getPos().x).put(v.getPos().y).put(v.getPos().z);
+//            bnfb.put(v.getNormal().x).put(v.getNormal().y).put(v.getNormal().z);
+            if (textureFlag) {
+                float f1 = v.getUv().getU();
+                float f2 = v.getUv().getV();
+//                tfb.put(v.getUv().getU()).put(1f - v.getUv().getV());
+                f1 = f1 - FastMath.floor(f1);
+                f2 = f2 - FastMath.floor(f2);
+                f2 = 1 - f2;
+                tfb.put(f1).put(f2);
+            }
+            float weight = (float) v.getBoneWeight() / 100.0f;
+            wfb.put(weight).put(1f - weight);
+            short b1 = (short)getBoneList().indexOf(v.getBoneNum1());
+            short b2 = (short)getBoneList().indexOf(v.getBoneNum2());
+            if (b1 < 0) b1 = 0;
+            if (b2 < 0) b2 = 0;
+            bisb.put(b1).put(b2);
+//            bisb.put((short) md.getBoneList().indexOf(v.getBoneNum1())).put((short) md.getBoneList().indexOf(v.getBoneNum2()));
+//            if (( weight != 0 && md.getBoneList().indexOf(v.getBoneNum1()) < 0)
+//                    || (weight != 1 && md.getBoneList().indexOf(v.getBoneNum2())<0)){
+//                System.out.println("ERROR!! "+v.getBoneNum1()+" "+v.getBoneNum2());
+//                System.out.println(""+md.getBoneList().indexOf(v.getBoneNum1())+" "+md.getBoneList().indexOf(v.getBoneNum2()));
+//                System.out.println("weight = "+weight);
+//            }
+        }
+        for (Integer index : getIndexList()) {
+            isb.put(index.shortValue());
+//            System.out.println("index = "+index);
+        }
+//        System.out.println("isb.capacity() = " + isb.capacity());
+//        System.out.println("isb.capacity() = " + md.getIndexList().size());
+
+//        bvb.setupData(VertexBuffer.Usage.CpuOnly, 3, VertexBuffer.Format.Float, bvfb);
+//        bnb.setupData(VertexBuffer.Usage.CpuOnly, 3, VertexBuffer.Format.Float, bnfb);
+        indexArray = new int[getBoneList().size()];
+        indexBufferb = BufferUtils.createByteBuffer(2 * getBoneList().size());
+        indexBuffer = indexBufferb.asShortBuffer();
+//        indexBuffer = BufferUtils.createShortBuffer(getBoneList().size());
+        for (int i = 0; i < indexArray.length; i++) {
+            if (i < getBoneList().size()) {
+                indexArray[i] = getBoneList().get(i).shortValue();
+            } else {
+                indexArray[i] = 0;
+            }
+            indexBuffer.put((short)indexArray[i]);
+        }
+        boneList = null;
+        vertIndexList = null;
+        vertIndexList = null;
+    }
+    List<Integer> getBoneList() {
         return boneList;
     }
 
@@ -154,11 +302,11 @@ public class MeshData {
 //        return indexBuffer;
 //    }
 
-    public List<Integer> getVertIndexList() {
+    List<Integer> getVertIndexList() {
         return vertIndexList;
     }
 
-    public List<Integer> getIndexList() {
+    List<Integer> getIndexList() {
         return indexList;
     }
 
diff --git a/src/projectkyoto/mmd/file/util2/PMDFileUtil.java b/src/projectkyoto/mmd/file/util2/PMDFileUtil.java
new file mode 100644 (file)
index 0000000..40494d9
--- /dev/null
@@ -0,0 +1,123 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package projectkyoto.mmd.file.util2;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.StringTokenizer;
+import projectkyoto.mmd.file.DataInputStreamLittleEndian;
+import projectkyoto.mmd.file.DataOutputStreamLittleEndian;
+import projectkyoto.mmd.file.PMDModel;
+import projectkyoto.mmd.file.PMDUtil;
+
+/**
+ *
+ * @author kobayasi
+ */
+public class PMDFileUtil {
+    public static final String PMDCACHE1HEADER = "PMDCACHEVer1";
+    public static void makeMeshCache(PMDModel pmdModel, OutputStream os) throws IOException {
+        MeshConverter mc = new MeshConverter(pmdModel);
+        mc.convertMesh();
+    }
+    public static MeshConverter readPMDCache1(InputStream is) throws IOException {
+        DataInputStreamLittleEndian dis = null;
+        try {
+            dis = new DataInputStreamLittleEndian(new BufferedInputStream(is));
+            String version = dis.readString(20);
+            if (!PMDCACHE1HEADER.equals(version)) {
+                throw new IllegalArgumentException("Invalid header "+version);
+            }
+            int maxBoneSize = dis.readInt();
+            PMDModel model = new PMDModel();
+            model.readFromStream(dis);
+            MeshConverter mc = new MeshConverter();
+            mc.setModel(model);
+            mc.read(dis);
+            mc.setMaxBoneSize(maxBoneSize);
+            return mc;
+        } finally {
+//            if (dis != null) {
+//                dis.close();
+//            }
+        }
+    }
+    public static void writePMDCache1(PMDModel model, File file) throws IOException {
+        MeshConverter mc = new MeshConverter(model);
+        model.setFaceVertCount(0);
+        model.setVertCount(0);
+        DataOutputStreamLittleEndian dos = null;
+        try {
+            dos = new DataOutputStreamLittleEndian(new BufferedOutputStream(new FileOutputStream(file)));
+            // write header
+            PMDUtil.writeString(dos, PMDCACHE1HEADER, 20);
+            dos.writeInt(mc.getMaxBoneSize());
+            model.writeToStream(dos);
+            mc.convertMesh();
+            mc.write(dos);
+        } finally {
+            if (dos != null) {
+                dos.close();
+            }
+        }
+    }
+    public static void createPmdcache1(File file) throws IOException{
+        List<String> list = new ArrayList<String>();
+        StringTokenizer st = new StringTokenizer(file.getName(), ".");
+        while(st.hasMoreElements()) {
+            String s = st.nextToken();
+            list.add(s);
+        }
+        if (list.size() < 3) {
+            throw new FileNotFoundException(file.getAbsolutePath());
+        }
+        if (!list.get(list.size()-1).equals("pmdcache1")) {
+            throw new FileNotFoundException(file.getAbsolutePath());
+        }
+        File pmdFile = null;
+        FileInputStream is = null;
+        try {
+            int boneSize = Integer.parseInt(list.get(list.size()-2));
+            String fileName = file.getAbsolutePath();
+            int delmCount = 0;
+            for(int i=fileName.length()-1;i>0;i--) {
+                if (fileName.charAt(i) == '.') {
+                    delmCount++;
+                    if (delmCount == 2) {
+                        fileName = fileName.substring(0, i);
+                        pmdFile = new File(fileName);
+                        break;
+                    }
+                }
+            }
+            if (pmdFile != null) {
+                System.out.println("pmdFile = "+pmdFile.getAbsolutePath());
+                if (!pmdFile.exists()) {
+                    throw new FileNotFoundException(file.getAbsolutePath());
+                }
+                MeshConverter.DEFAULT_MAX_BONE_SIZE = boneSize;
+                is = new FileInputStream(pmdFile);
+                PMDModel pmdModel = new PMDModel(is);
+                writePMDCache1(pmdModel, file);
+                return;
+            }
+        } catch(NumberFormatException ex) {
+        } finally {
+            if (is != null) {
+                is.close();
+            }
+        }
+        throw new FileNotFoundException(file.getAbsolutePath());
+    }
+}
index 2b0a27b..fed3fe8 100755 (executable)
  * 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.mmd.file.util2;
 
+import com.jme3.math.FastMath;
+import com.jme3.util.BufferUtils;
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
 import java.io.Serializable;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.FloatBuffer;
+import java.nio.ShortBuffer;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
@@ -46,24 +54,27 @@ import projectkyoto.mmd.file.PMDVertex;
  *
  * @author kobayasi
  */
-public class SkinMeshData implements Serializable{
+public class SkinMeshData implements Serializable {
 
     PMDModel model;
     List<Integer> boneList = new ArrayList<Integer>();
     List<PMDVertex> vertexList = new ArrayList<PMDVertex>();
     Map<PMDMaterial, List<Integer>> indexMap = new HashMap<PMDMaterial, List<Integer>>();
-
+    public SkinMeshData() {
+        
+    }
     public SkinMeshData(MeshConverter mc, PMDModel model) {
         this.model = model;
-        for(PMDSkinData sd : model.getSkinData()) {
+        if (model.getVertexBuffer() != null)
+        for (PMDSkinData sd : model.getSkinData()) {
             if (sd.getSkinType() == 0) {
-                for(int i=0;i<sd.getSkinVertCount();i++) {
+                for (int i = 0; i < sd.getSkinVertCount(); i++) {
                     int skinVertIndex = sd.getIndexBuf().get(i) & 0xffff;
                     try {
                         PMDVertex v = model.getVertex(skinVertIndex);
                         vertexList.add(v);
                         mc.skinTmpVertMap.put(skinVertIndex, i);
-                    } catch(Exception ex) {
+                    } catch (Exception ex) {
                         ex.printStackTrace();
                     }
                 }
@@ -81,9 +92,9 @@ public class SkinMeshData implements Serializable{
             indexList = new ArrayList<Integer>();
             indexMap.put(material, indexList);
         }
-        addVertex(mc, indexList,i1);
-        addVertex(mc, indexList,i2);
-        addVertex(mc, indexList,i3);
+        addVertex(mc, indexList, i1);
+        addVertex(mc, indexList, i2);
+        addVertex(mc, indexList, i3);
     }
 
     private void addBoneList(int vertIndex) {
@@ -96,7 +107,7 @@ public class SkinMeshData implements Serializable{
         }
     }
 
-    private void addVertex(MeshConverter mc, List<Integer>indexList, int vertIndex) {
+    private void addVertex(MeshConverter mc, List<Integer> indexList, int vertIndex) {
         PMDVertex v = model.getVertex(vertIndex);
         Integer index = mc.skinTmpVertMap.get(vertIndex);
         int newVertIndex;
@@ -110,8 +121,160 @@ public class SkinMeshData implements Serializable{
         }
         indexList.add(index/*newVertIndex*/);
     }
+    public ByteBuffer skinvfbb;
+    public ByteBuffer skinnfbb;
+    public ByteBuffer skintfbb;
+    public ByteBuffer skinbisbb;
+    public ByteBuffer wfbb;
+    public FloatBuffer skinvfb;
+    public FloatBuffer skinvfb2;
+    public FloatBuffer skinnfb;
+    public FloatBuffer skintfb;
+    public ShortBuffer skinbisb;
+    public FloatBuffer wfb;
+    public int[] skinIndexArray;
+    public Map<PMDMaterial, ShortBuffer> indexShortBufferMap = new HashMap<PMDMaterial, ShortBuffer>();
+
+    public void write(DataOutputStream os, byte[] buf) throws IOException {
+        BufferUtil.write(skinvfbb, os, buf);
+        BufferUtil.write(skinnfbb, os, buf);
+        if (skintfbb != null) {
+            os.writeBoolean(true);
+            BufferUtil.write(skintfbb, os, buf);
+        } else {
+            os.writeBoolean(false);
+        }
+        BufferUtil.write(wfbb, os, buf);
+        BufferUtil.write(skinbisbb, os, buf);
+        os.writeInt(skinIndexArray.length);
+        for (int i : skinIndexArray) {
+            os.writeInt(i);
+        }
+        os.writeInt(indexShortBufferMap.size());
+        for (PMDMaterial mat : indexShortBufferMap.keySet()) {
+            os.writeInt(mat.getMaterialNo());
+            ShortBuffer sb = indexShortBufferMap.get(mat);
+            os.writeInt(sb.capacity() * 2);
+            sb.position(0);
+            if (ByteOrder.nativeOrder().equals(ByteOrder.LITTLE_ENDIAN)) {
+                for (int i = 0; i < sb.capacity(); i++) {
+                    short s = sb.get();
+                    os.writeByte(s);
+                    os.writeByte(s >> 8);
+                }
+            } else {
+                for (int i = 0; i < sb.capacity(); i++) {
+                    short s = sb.get();
+                    os.writeByte(s >> 8);
+                    os.writeByte(s);
+                }
+            }
+        }
+    }
+
+    public void read(DataInputStream is, byte[] buf) throws IOException {
+        skinvfbb = BufferUtil.read(is, buf);
+        skinvfb = skinvfbb.asFloatBuffer();
+        skinnfbb = BufferUtil.read(is, buf);
+        skinnfb = skinnfbb.asFloatBuffer();
+        if (is.readBoolean()) {
+            skintfbb = BufferUtil.read(is, buf);
+            skintfb = skintfbb.asFloatBuffer();
+        }
+        wfbb = BufferUtil.read(is, buf);
+        wfb = wfbb.asFloatBuffer();
+        skinbisbb = BufferUtil.read(is, buf);
+        skinbisb = skinbisbb.asShortBuffer();
+        int length = is.readInt();
+        skinIndexArray = new int[length];
+        for (int i = 0; i < length; i++) {
+            skinIndexArray[i] = is.readInt();
+        }
+        int size = is.readInt();
+        indexShortBufferMap = new HashMap<PMDMaterial, ShortBuffer>();
+        for(int i=0;i<size;i++) {
+            PMDMaterial mat = model.getMaterial()[is.readInt()];
+            ShortBuffer sb = BufferUtil.read(is, buf).asShortBuffer();
+            indexShortBufferMap.put(mat, sb);
+        }
+        skinvfb2 = BufferUtils.createFloatBuffer(skinvfb.capacity());
+        skinvfb.position(0);
+        skinvfb2.put(skinvfb);
+    }
 
-    public List<Integer> getBoneList() {
+    void createSkinCommonVertData() {
+        skinvfbb = BufferUtils.createByteBuffer(getVertexList().size() * 3 * 4);
+        skinvfb = skinvfbb.asFloatBuffer();
+
+        skinvfb2 = BufferUtils.createFloatBuffer(getVertexList().size() * 3);
+
+        skinnfbb = BufferUtils.createByteBuffer(getVertexList().size() * 3 * 4);
+        skinnfb = skinnfbb.asFloatBuffer();
+
+        skintfbb = BufferUtils.createByteBuffer(getVertexList().size() * 2 * 4);
+        skintfb = skintfbb.asFloatBuffer();
+
+        skinbisbb = BufferUtils.createByteBuffer(getVertexList().size() * 2 * 2);
+        skinbisb = skinbisbb.asShortBuffer();
+
+        wfbb = BufferUtils.createByteBuffer(getVertexList().size() * 2 * 4);
+        wfb = wfbb.asFloatBuffer();
+
+        for (PMDVertex v : getVertexList()) {
+            skinvfb.put(v.getPos().x).put(v.getPos().y).put(v.getPos().z);
+            skinnfb.put(v.getNormal().x).put(v.getNormal().y).put(v.getNormal().z);
+            float f1 = v.getUv().getU();
+            float f2 = v.getUv().getV();
+//                tfb.put(v.getUv().getU()).put(1f - v.getUv().getV());
+            f1 = f1 - FastMath.floor(f1);
+            f2 = f2 - FastMath.floor(f2);
+            f2 = 1 - f2;
+            skintfb.put(f1).put(f2);
+//            skintfb.put(v.getUv().getU()).put(1f - v.getUv().getV());
+//            skinbisb.put((short) meshConverter.getSkinMeshData()
+//                    .getBoneList().indexOf(v.getBoneNum1()))
+//                    .put((short) meshConverter.getSkinMeshData()
+//                    .getBoneList().indexOf(v.getBoneNum2()));
+            short b1 = (short) getBoneList().indexOf(v.getBoneNum1());
+            short b2 = (short) getBoneList().indexOf(v.getBoneNum2());
+            if (b1 < 0) {
+                b1 = 0;
+            }
+            if (b2 < 0) {
+                b2 = 0;
+            }
+            skinbisb.put(b1).put(b2);
+            float weight = (float) v.getBoneWeight() / 100.0f;
+            wfb.put(weight).put(1f - weight);
+        }
+        skinvfb.position(0);
+        skinvfb2.position(0);
+        skinvfb2.put(skinvfb);
+        skinnfb.position(0);
+//        skinnfb2.position(0);
+//        skinnfb2.put(skinnfb);
+        skinIndexArray = new int[getBoneList().size()];
+        for (int i = 0; i < skinIndexArray.length; i++) {
+            if (i < getBoneList().size()) {
+                skinIndexArray[i] = getBoneList().get(i).shortValue();
+            } else {
+                skinIndexArray[i] = 0;
+            }
+        }
+        for (PMDMaterial key : indexMap.keySet()) {
+            List<Integer> indexList = indexMap.get(key);
+            ShortBuffer isb = BufferUtils.createShortBuffer(indexList.size());
+            for (Integer index : indexList) {
+                isb.put(index.shortValue());
+            }
+            indexShortBufferMap.put(key, isb);
+        }
+        indexMap = null;
+        boneList = null;
+        vertexList = null;
+    }
+
+    List<Integer> getBoneList() {
         return boneList;
     }
 
@@ -119,7 +282,6 @@ public class SkinMeshData implements Serializable{
         this.boneList = boneList;
     }
 
-
     public PMDModel getModel() {
         return model;
     }
@@ -136,7 +298,7 @@ public class SkinMeshData implements Serializable{
         this.vertexList = vertexList;
     }
 
-    public Map<PMDMaterial, List<Integer>> getIndexMap() {
+    Map<PMDMaterial, List<Integer>> getIndexMap() {
         return indexMap;
     }