OSDN Git Service

Add path separator "\" support.
authorKazuhiko Kobayashi <chototsu_moushinp@yahoo.co.jp>
Tue, 27 Mar 2012 10:30:27 +0000 (19:30 +0900)
committerKazuhiko Kobayashi <chototsu_moushinp@yahoo.co.jp>
Tue, 27 Mar 2012 10:30:27 +0000 (19:30 +0900)
15 files changed:
src/projectkyoto/jme3/mmd/PMDLoaderGLSLSkinning2.java
src/projectkyoto/jme3/mmd/nativebullet/PMDPhysicsWorld.java
src/projectkyoto/jme3/mmd/vmd/VMDControl.java
src/projectkyoto/jme3/mmd/vmd/VMDControlMT.java
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/TooManyBonesException.java [new file with mode: 0644]
src/projectkyoto/mmd/file/pmn/PMNData.java [new file with mode: 0644]
src/projectkyoto/mmd/file/pmn/PMNMesh.java [new file with mode: 0644]
src/projectkyoto/mmd/file/pmn/PMNSkinMesh.java [new file with mode: 0644]
src/projectkyoto/mmd/file/util2/MeshConverter.java
src/projectkyoto/mmd/file/util2/MeshData.java
src/projectkyoto/mmd/file/util2/SkinMeshData.java

index 35404c7..5ccd9cb 100755 (executable)
@@ -40,6 +40,7 @@ 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;
@@ -67,6 +68,7 @@ import java.util.List;
 import java.util.StringTokenizer;
 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;
 
@@ -155,15 +157,23 @@ public class PMDLoaderGLSLSkinning2 implements AssetLoader{
             node.pmdGeometryArray[pmdGeometryIndex++] = geom;
             meshConverter.getMeshDataList().set(i, null);
 //            go.add(mesh);
-            mesh.setInterleaved();    
+//            mesh.setInterleaved();    
         }
 //        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()));
+            }
+            numBones = meshConverter.getSkinMeshData().getBoneList().size();
+        }
         for (PMDMaterial pmdMaterial : meshConverter.getSkinMeshData().getIndexMap().keySet()) {
             PMDSkinMesh mesh = createSkinMesh(pmdMaterial);
             PMDGeometry geom = new PMDGeometry("geom" + meshCount++);
             geom.setMesh(mesh);
             setupMaterial(pmdMaterial, geom);
+            geom.getMaterial().setInt("NumBones", numBones);
             node.attachChild(geom);
             skinMeshList.add(mesh);
         }
@@ -216,7 +226,14 @@ public class PMDLoaderGLSLSkinning2 implements AssetLoader{
         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);
-            skintfb.put(v.getUv().getU()).put(1f - v.getUv().getV());
+                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()
@@ -316,7 +333,13 @@ public class PMDLoaderGLSLSkinning2 implements AssetLoader{
 //            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) {
-                tfb.put(v.getUv().getU()).put(1f - v.getUv().getV());
+                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);
@@ -380,51 +403,6 @@ public class PMDLoaderGLSLSkinning2 implements AssetLoader{
         }
         return mesh;
     }
-    PMDMesh createMesh(MeshData md) {
-        PMDMesh mesh = new PMDMesh();
-        mesh.setMode(Mesh.Mode.Triangles);
-        VertexBuffer vb = new VertexBuffer(VertexBuffer.Type.Position);
-        VertexBuffer nb = new VertexBuffer(VertexBuffer.Type.Normal);
-        VertexBuffer tb = new VertexBuffer(VertexBuffer.Type.TexCoord);
-        VertexBuffer wb = new VertexBuffer(VertexBuffer.Type.BoneWeight);
-        VertexBuffer ib = new VertexBuffer(VertexBuffer.Type.Index);
-        VertexBuffer bib = new VertexBuffer(VertexBuffer.Type.BoneIndex);
-
-        vb.setupData(VertexBuffer.Usage.Dynamic, 3, VertexBuffer.Format.Float, md.offset, MeshConverter.stride);
-        nb.setupData(VertexBuffer.Usage.Dynamic, 3, VertexBuffer.Format.Float,  md.offset, MeshConverter.stride);
-        tb.setupData(VertexBuffer.Usage.Static, 2, VertexBuffer.Format.Float,  md.offset, MeshConverter.stride);
-        wb.setupData(VertexBuffer.Usage.Static, 4, VertexBuffer.Format.Float,  md.offset, MeshConverter.stride);
-        ib.setupData(VertexBuffer.Usage.Static, 1, VertexBuffer.Format.UnsignedShort,  md.offset, MeshConverter.stride);
-        bib.setupData(VertexBuffer.Usage.Static, 4, VertexBuffer.Format.Short,  md.offset, MeshConverter.stride);
-
-        PMDVertex v = new PMDVertex();
-        mesh.setBuffer(vb);
-        mesh.setBuffer(nb);
-        mesh.setVertCount(md.getVertIndexList().size());
-        
-        mesh.setVbBackup(vb);
-        mesh.setNbBackup(nb);
-
-        mesh.setBuffer(tb);
-        mesh.setBuffer(wb);
-        mesh.setBuffer(ib);
-        mesh.setBuffer(bib);
-        int[] indexArray = new int[md.getMaxBoneSize()];
-        for (int i = 0; i < indexArray.length; i++) {
-            if (i < md.getBoneList().size()) {
-                indexArray[i] = md.getBoneList().get(i).shortValue();
-            } else {
-                indexArray[i] = 0;
-            }
-        }
-        mesh.setBoneIndexArray(indexArray);
-        mesh.setBoneMatrixArray(new Matrix4f[indexArray.length]);
-        for (int i = 0; i < mesh.getBoneMatrixArray().length; i++) {
-            mesh.getBoneMatrixArray()[i] = new Matrix4f();
-            mesh.getBoneMatrixArray()[i].loadIdentity();
-        }
-        return mesh;
-    }
 
     void setupMaterial(PMDMaterial m, PMDGeometry geom) {
         Material mat;
@@ -488,8 +466,8 @@ public class PMDLoaderGLSLSkinning2 implements AssetLoader{
         mat.setColor("Diffuse", ambientAndDiffuseColor);
         mat.setFloat("Shininess", m.getMaterial().getPower());
         if (m.getTextureFileName().length() > 0) {
-            StringTokenizer st = new StringTokenizer(m.getTextureFileName(), "*");
-//            System.out.println("m.getTextureFileName() = " + m.getTextureFileName());
+            StringTokenizer st = new StringTokenizer(m.getTextureFileName().replace("\\", "/"), "*");
+            System.out.println("m.getTextureFileName() = " + m.getTextureFileName());
             while (st.hasMoreElements()) {
                 String fileName = st.nextToken();
 //                System.out.println("fileName = " + fileName);
@@ -499,9 +477,11 @@ public class PMDLoaderGLSLSkinning2 implements AssetLoader{
                          */);
                 s = s.toLowerCase();
                 if (s.equals("spa")) {
+//                    texture.setWrap(Texture.WrapMode.Repeat);
                     texture.setMinFilter(Texture.MinFilter.BilinearNoMipMaps);
                     mat.setTexture("SphereMap_A", texture);
                 } else if (s.equals("sph")) {
+//                    texture.setWrap(Texture.WrapMode.Repeat);
                     texture.setMinFilter(Texture.MinFilter.BilinearNoMipMaps);
                     mat.setTexture("SphereMap_H", texture);
                 } else {
@@ -580,7 +560,7 @@ public class PMDLoaderGLSLSkinning2 implements AssetLoader{
             mat.getAdditionalRenderState().setAlphaTest(true);
 //                    mat.getAdditionalRenderState().setFaceCullMode(FaceCullMode.Back);
         } else {
-//            mat.getAdditionalRenderState().setBlendMode(BlendMode.Alpha);
+            mat.getAdditionalRenderState().setBlendMode(BlendMode.Alpha);
 //                    mat.getAdditionalRenderState().setFaceCullMode(FaceCullMode.Back);
 //                    mat.getAdditionalRenderState().setBlendMode(BlendMode.Alpha);
 //            mat.getAdditionalRenderState().setAlphaTest(true);
@@ -698,7 +678,7 @@ public class PMDLoaderGLSLSkinning2 implements AssetLoader{
                 return loader.load2(ai);
             }catch(OutOfMemoryError ex) {
                 if (errFlag) {
-                    throw new RuntimeException(ex);
+                    throw ex;
                 }
                 errFlag = true;
                 if (ai.getManager() instanceof DesktopAssetManager) {
@@ -715,6 +695,7 @@ public class PMDLoaderGLSLSkinning2 implements AssetLoader{
         folderName = ai.getKey().getFolder();
         meshConverter = new MeshConverter(model);
         meshConverter.convertMesh();
+        PMNData pmdData = meshConverter.createPMNData();
 //        model.setVertexList(null);
         model.setFaceVertIndex(null);
         PMDNode pmdNode = createNode(ai.getKey().getName());
index 475be86..32253d7 100755 (executable)
@@ -503,7 +503,7 @@ public class PMDPhysicsWorld {
 //            applyResultToBone();
 //        }
 //        synchronized(lockObject) {
-            physicsSpace.update(timeStep, 100);
+            physicsSpace.update(timeStep, 5);
 //        }
 //        applyResultToBone();
     }
@@ -550,11 +550,12 @@ public class PMDPhysicsWorld {
             for (int i = 0; i < rbarray.length; i++) {
                 PMDRigidBody rb = rbarray[i];
                 if (true) {
-                    PMDNode pmdNode = rb.getPmdNode();
-                    Node rigidBodyNode = pmdNode.getRigidBodyNode();
-                    rb.updateFromBoneMatrix();
-                    rb.setLinearVelocity(Vector3f.ZERO);
-                    rb.setAngularVelocity(Vector3f.ZERO);
+//                    PMDNode pmdNode = rb.getPmdNode();
+//                    Node rigidBodyNode = pmdNode.getRigidBodyNode();
+//                    rb.updateFromBoneMatrix();
+//                    rb.setLinearVelocity(Vector3f.ZERO);
+//                    rb.setAngularVelocity(Vector3f.ZERO);
+                    rb.reset();
                 }
             }
         }
index dab0c1d..bb3b0b7 100755 (executable)
@@ -96,7 +96,7 @@ public class VMDControl extends AbstractControl {
         if (addPmdNodeFlag) {
             physicsControl.getWorld().addPMDNode(pmdNode);
         }
-//         physicsControl.getWorld().getPhysicsSpace().addTickListener(tl);
+        physicsControl.getWorld().getPhysicsSpace().addTickListener(tl);
         ikControl = new IKControl(pmdNode);
         boneEnabled = new int[pmdNode.getSkeleton().getBoneCount()];
         for(int i=0;i<boneEnabled.length;i++) {
@@ -215,6 +215,7 @@ public class VMDControl extends AbstractControl {
         }
         boneMotionListArray = motionMap.values().toArray(new BoneMotionList[motionMap.size()]);
         skinListArray = skinMap.values().toArray(new SkinList[skinMap.size()]);
+        setFrameNo(0);
     }
     Quat4f tmpq1 = new Quat4f();
     Quat4f tmpq2 = new Quat4f();
@@ -270,32 +271,19 @@ public class VMDControl extends AbstractControl {
     float accuracy = 1f/120f;
     @Override
     protected void controlUpdate(float tpf) {
-//        for(;time > 0; time -= physicsControl.getWorld().accuracy) {
-//            controlUpdate2(physicsControl.getWorld().accuracy);
-//        }
-//        tpf = stepTime;
-//        tpf = 1f/15f;
-        if (tpf > 1) {
-            setFrameNo((int)((currentTime + tpf) * 30f));
+        if (isPause()) {
             return;
         }
-        boolean needUpdateSkin = false;
-        if (tpf != 0 && !pause) {
-            tpf += prevTpf;
-            for(;tpf > accuracy ; tpf -= accuracy ) {
-                controlUpdate2(accuracy);
-                physicsControl.update(accuracy);
-                physicsControl.getWorld().getPhysicsSpace().distributeEvents();
-                needUpdateSkin = true;
-            }
-//            System.out.println("X = "+pmdNode.getSkeleton().getBone("前髪").getModelSpacePosition().getX());
+        if (tpf > 1) {
+            currentTime += tpf;
+            currentFrameNo = (int)(currentTime * 30f);
+            setFrameNo(currentFrameNo);
+        } else {
+            physicsControl.update(tpf);
             physicsControl.getWorld().applyResultToBone();
-//            pmdNode.getSkeleton().updateWorldVectors();
-            prevTpf = tpf;
-            if (needUpdateSkin) {
-                resetSkins();
-                calcSkins();
-            }
+            resetSkins();
+            calcSkins();
+            physicsControl.getWorld().getPhysicsSpace().distributeEvents();
         }
     }
     protected void resetBonePos() {
@@ -484,7 +472,6 @@ public class VMDControl extends AbstractControl {
             pmdNode.setSkinWeight(skinName, 0f);
         }
     }
-
     public void setFrameNo(int frameNo) {
         resetBonePos();
         for (BoneMotionList bml : boneMotionListArray) {
@@ -517,6 +504,7 @@ public class VMDControl extends AbstractControl {
 //        calcBonePosition(currentFrameNo, pmdNode.getSkeleton());
         pmdNode.getSkeleton().updateWorldVectors();
         physicsControl.getWorld().resetRigidBodyPos();
+        physicsControl.getWorld().resetRigidBodyPos();
 //        pmdNode.update();
     }
 
@@ -537,6 +525,17 @@ public class VMDControl extends AbstractControl {
     }
 
     @Override
+    public void setSpatial(Spatial spatial) {
+        super.setSpatial(spatial);
+        if (spatial == null) {
+            if (tl != null) {
+                physicsControl.getWorld().getPhysicsSpace().removeTickListener(tl);
+            }
+            tl = null;
+        }
+    }
+
+    @Override
     protected void controlRender(RenderManager rm, ViewPort vp) {
     }
 
@@ -558,7 +557,7 @@ public class VMDControl extends AbstractControl {
 
         @Override
         public void physicsTick(PhysicsSpace ps, float f) {
-            physicsControl.getWorld().applyResultToBone();
+//            physicsControl.getWorld().applyResultToBone();
         }
         
     }
@@ -575,7 +574,7 @@ public class VMDControl extends AbstractControl {
 }
 class BoneMotionList extends ArrayList<VMDMotion> {
 
-    static final int IPTABLESIZE = 64;
+    static final int IPTABLESIZE = 16;
     String boneName;
     Bone bone;
     int boneIndex;
index c8360de..c8fd119 100644 (file)
@@ -48,6 +48,7 @@ public class VMDControlMT extends AbstractControl {
     @Override
     protected void controlUpdate(float f) {
         sync();
+        pmdNode.update();
         callable.setTpf(f);
         future = executor.submit(callable);
     }
@@ -55,8 +56,7 @@ public class VMDControlMT extends AbstractControl {
         if (future != null) {
             try {
                 future.get();
-                callable.vmdControl.getPhysicsControl().getWorld().updateRigidBodyPos();
-                pmdNode.update();
+//                callable.vmdControl.getPhysicsControl().getWorld().updateRigidBodyPos();
             } catch (InterruptedException ex) {
                 Logger.getLogger(VMDControlMT.class.getName()).log(Level.SEVERE, null, ex);
             } catch (ExecutionException ex) {
@@ -83,6 +83,7 @@ public class VMDControlMT extends AbstractControl {
         super.setSpatial(spatial);
         if (spatial == null) {
             Logger.getLogger(VMDControlMT.class.getName()).log(Level.INFO,"remove");
+            getCallable().getVmdControl().setSpatial(null);
             if (future != null) {
                 try {
                     future.get();
index bd15c00..b983b8a 100755 (executable)
@@ -33,13 +33,15 @@ package projectkyoto.mmd.file;
 
 import java.io.IOException;
 import java.io.Serializable;
+import java.nio.ByteBuffer;
 import javax.vecmath.Vector3f;
+import projectkyoto.mmd.file.util2.BufferUtil;
 
 /**
  *
  * @author Kazuhiko Kobayashi
  */
-public class PMDBone implements Serializable{
+public class PMDBone implements Serializable {
 
     private String boneName;
     private int parentBoneIndex;
@@ -62,7 +64,8 @@ public class PMDBone implements Serializable{
                 + "}"
                 + "}\n";
     }
-
+    public PMDBone() {
+    }
     public PMDBone(DataInputStreamLittleEndian is) throws IOException {
         boneName = is.readString(20);
         parentBoneIndex = is.readUnsignedShort();
@@ -78,6 +81,29 @@ public class PMDBone implements Serializable{
         }
     }
 
+    public void readFromBuffer(ByteBuffer bb) {
+        boneName = BufferUtil.readString(bb, 20);
+        parentBoneIndex = bb.getShort();
+        tailPosBoneIndex = bb.getShort();
+        boneType = bb.get();
+        targetBone = bb.getShort();
+        boneHeadPos = new Vector3f(bb.getFloat(), bb.getFloat(), bb.getFloat());
+        if (boneName.indexOf("ひざ") >= 0) {
+            hiza = true;
+        } else {
+            hiza = false;
+        }
+    }
+
+    public void writeToBuffer(ByteBuffer bb) {
+        BufferUtil.writeString(bb, boneName, 20);
+        bb.putShort((short) parentBoneIndex);
+        bb.putShort((short) tailPosBoneIndex);
+        bb.put((byte) boneType);
+        bb.putShort((short) targetBone);
+        bb.putFloat(boneHeadPos.x).putFloat(boneHeadPos.y).putFloat(boneHeadPos.z);
+    }
+
     public Vector3f getBoneHeadPos() {
         return boneHeadPos;
     }
index b0b221d..8ad6e95 100755 (executable)
@@ -34,6 +34,7 @@ package projectkyoto.mmd.file;
 
 import java.io.IOException;
 import java.io.Serializable;
+import java.nio.ByteBuffer;
 
 /**
  *
@@ -42,11 +43,20 @@ import java.io.Serializable;
 public class PMDBoneDisp implements Serializable{
     private int boneIndex;
     private int boneDispFrameIndex;
+    public PMDBoneDisp() {
+    }
     public PMDBoneDisp(DataInputStreamLittleEndian is) throws IOException {
         boneIndex = is.readUnsignedShort();
         boneDispFrameIndex = is.readUnsignedByte();
     }
-
+    public void readFromBuffer(ByteBuffer bb) {
+        boneIndex = bb.getShort();
+        boneDispFrameIndex = bb.get();
+    }
+    public void writeToBuffer(ByteBuffer bb) {
+        bb.putShort((short)boneIndex);
+        bb.put((byte)boneDispFrameIndex);
+    }
     @Override
     public String toString() {
         return "PMDBoneDisp{" + "boneIndex=" + boneIndex + ", boneDispFrameIndex=" + boneDispFrameIndex + '}';
index 64c4ab9..246d25e 100755 (executable)
@@ -34,6 +34,7 @@ package projectkyoto.mmd.file;
 
 import java.io.IOException;
 import java.io.Serializable;
+import java.nio.ByteBuffer;
 
 /**
  *
@@ -42,6 +43,9 @@ import java.io.Serializable;
 public class PMDBoneDispList implements Serializable{
     private int boneDispCount;
     private PMDBoneDisp boneDispArray[];
+
+    public PMDBoneDispList() {
+    }
     public PMDBoneDispList(DataInputStreamLittleEndian is) throws IOException {
         boneDispCount = is.readInt();
         boneDispArray = new PMDBoneDisp[boneDispCount];
@@ -49,7 +53,21 @@ public class PMDBoneDispList implements Serializable{
             boneDispArray[i] = new PMDBoneDisp(is);
         }
     }
-
+    public void readFromBuffer(ByteBuffer bb) {
+        boneDispCount = bb.getInt();
+        boneDispArray = new PMDBoneDisp[boneDispCount];
+        for(int i=0;i<boneDispCount;i++) {
+            PMDBoneDisp bd = new PMDBoneDisp();
+            bd.readFromBuffer(bb);
+            boneDispArray[i] = bd;
+        }
+    }
+    public void writeToBuffer(ByteBuffer bb) {
+        bb.putInt(boneDispCount);
+        for(PMDBoneDisp bd : boneDispArray) {
+            bd.writeToBuffer(bb);
+        }
+    }
     @Override
     public String toString() {
         return "PMDBoneDispList{" + "boneDispCount=" + boneDispCount + ", boneDispArray=" + boneDispArray + '}';
index 486a124..5d94b29 100755 (executable)
@@ -34,6 +34,8 @@ package projectkyoto.mmd.file;
 
 import java.io.IOException;
 import java.io.Serializable;
+import java.nio.ByteBuffer;
+import projectkyoto.mmd.file.util2.BufferUtil;
 
 /**
  *
@@ -42,6 +44,9 @@ import java.io.Serializable;
 public class PMDBoneDispNameList implements Serializable{
     private int boneDispNameCount;
     private String[] dispNameArray;
+    
+    public PMDBoneDispNameList() {
+    }
     public PMDBoneDispNameList(DataInputStreamLittleEndian is) throws IOException {
         boneDispNameCount = is.readUnsignedByte();
         dispNameArray = new String[boneDispNameCount];
@@ -49,7 +54,16 @@ public class PMDBoneDispNameList implements Serializable{
             dispNameArray[i] = is.readString(50);
         }
     }
-
+    public void readFromBuffer(ByteBuffer bb) {
+        boneDispNameCount = bb.get();
+        dispNameArray = new String[boneDispNameCount];
+        for(int i=0;i<boneDispNameCount;i++) {
+            dispNameArray[i] = BufferUtil.readString(bb, 50);
+        }
+    }
+    public void writeToBuffer(ByteBuffer bb) {
+//        boneDispNameCou
+    }
     @Override
     public String toString() {
         return "PMDBoneDispNameList{" + "boneDispNameCount=" + boneDispNameCount + ", dispNameArray=" + dispNameArray + '}';
diff --git a/src/projectkyoto/mmd/file/TooManyBonesException.java b/src/projectkyoto/mmd/file/TooManyBonesException.java
new file mode 100644 (file)
index 0000000..3a05bd4
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package projectkyoto.mmd.file;
+
+/**
+ *
+ * @author kobayasi
+ */
+public class TooManyBonesException extends RuntimeException{
+
+    public TooManyBonesException(Throwable thrwbl) {
+        super(thrwbl);
+    }
+
+    public TooManyBonesException(String string, Throwable thrwbl) {
+        super(string, thrwbl);
+    }
+
+    public TooManyBonesException(String string) {
+        super(string);
+    }
+
+    public TooManyBonesException() {
+    }
+}
diff --git a/src/projectkyoto/mmd/file/pmn/PMNData.java b/src/projectkyoto/mmd/file/pmn/PMNData.java
new file mode 100644 (file)
index 0000000..afec5f0
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package projectkyoto.mmd.file.pmn;
+
+import projectkyoto.mmd.file.PMDModel;
+
+/**
+ *
+ * @author kobayasi
+ */
+public class PMNData {
+
+    PMDModel pmdModel;
+    PMNMesh meshArray[];
+    PMNSkinMesh skinMesh;
+
+    public PMNData() {
+    }
+
+    public PMNMesh[] getMeshArray() {
+        return meshArray;
+    }
+
+    public void setMeshArray(PMNMesh[] meshArray) {
+        this.meshArray = meshArray;
+    }
+
+    public PMDModel getPmdModel() {
+        return pmdModel;
+    }
+
+    public void setPmdModel(PMDModel pmdModel) {
+        this.pmdModel = pmdModel;
+    }
+
+    public PMNSkinMesh getSkinMesh() {
+        return skinMesh;
+    }
+
+    public void setSkinMesh(PMNSkinMesh skinMesh) {
+        this.skinMesh = skinMesh;
+    }
+}
diff --git a/src/projectkyoto/mmd/file/pmn/PMNMesh.java b/src/projectkyoto/mmd/file/pmn/PMNMesh.java
new file mode 100644 (file)
index 0000000..c6b8b8c
--- /dev/null
@@ -0,0 +1,79 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package projectkyoto.mmd.file.pmn;
+
+import java.nio.ByteBuffer;
+import java.nio.ShortBuffer;
+
+/**
+ *
+ * @author kobayasi
+ */
+public class PMNMesh {
+    ByteBuffer interleavedBuffer;
+    ShortBuffer indexBuffer;
+    /**
+     * 0 point
+     * 1 normal
+     * 2 texcoord
+     * 3 boneIndex
+     * 4 boneWeight
+     */
+    byte[] offsetArray;
+    int stride;
+    int materialIndex;
+    short[] boneIndexArray;
+    public PMNMesh() {
+    }
+
+    public short[] getBoneIndexArray() {
+        return boneIndexArray;
+    }
+
+    public void setBoneIndexArray(short[] boneIndexArray) {
+        this.boneIndexArray = boneIndexArray;
+    }
+
+    public ShortBuffer getIndexBuffer() {
+        return indexBuffer;
+    }
+
+    public void setIndexBuffer(ShortBuffer indexBuffer) {
+        this.indexBuffer = indexBuffer;
+    }
+
+    public ByteBuffer getInterleavedBuffer() {
+        return interleavedBuffer;
+    }
+
+    public void setInterleavedBuffer(ByteBuffer interleavedBuffer) {
+        this.interleavedBuffer = interleavedBuffer;
+    }
+
+    public int getMaterialIndex() {
+        return materialIndex;
+    }
+
+    public void setMaterialIndex(int materialIndex) {
+        this.materialIndex = materialIndex;
+    }
+
+    public byte[] getOffsetArray() {
+        return offsetArray;
+    }
+
+    public void setOffsetArray(byte[] offsetArray) {
+        this.offsetArray = offsetArray;
+    }
+
+    public int getStride() {
+        return stride;
+    }
+
+    public void setStride(int stride) {
+        this.stride = stride;
+    }
+    
+}
diff --git a/src/projectkyoto/mmd/file/pmn/PMNSkinMesh.java b/src/projectkyoto/mmd/file/pmn/PMNSkinMesh.java
new file mode 100644 (file)
index 0000000..d657d9c
--- /dev/null
@@ -0,0 +1,90 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package projectkyoto.mmd.file.pmn;
+
+import java.nio.ByteBuffer;
+import java.nio.FloatBuffer;
+import java.nio.ShortBuffer;
+
+/**
+ *
+ * @author kobayasi
+ */
+public class PMNSkinMesh {
+    FloatBuffer pointBuffer;
+    FloatBuffer normalBuffer;
+    FloatBuffer texCoordBuffer;
+    ShortBuffer boneIndexBuffer;
+    FloatBuffer boneWeightBuffer;
+    short[] boneIndexArray;
+    int[] materialIndexArray;
+    ShortBuffer[] indexBufferArray;
+    public PMNSkinMesh() {
+    }
+
+    public short[] getBoneIndexArray() {
+        return boneIndexArray;
+    }
+
+    public void setBoneIndexArray(short[] boneIndexArray) {
+        this.boneIndexArray = boneIndexArray;
+    }
+
+    public ShortBuffer getBoneIndexBuffer() {
+        return boneIndexBuffer;
+    }
+
+    public void setBoneIndexBuffer(ShortBuffer boneIndexBuffer) {
+        this.boneIndexBuffer = boneIndexBuffer;
+    }
+
+    public FloatBuffer getBoneWeightBuffer() {
+        return boneWeightBuffer;
+    }
+
+    public void setBoneWeightBuffer(FloatBuffer boneWeightBuffer) {
+        this.boneWeightBuffer = boneWeightBuffer;
+    }
+
+    public ShortBuffer[] getIndexBufferArray() {
+        return indexBufferArray;
+    }
+
+    public void setIndexBufferArray(ShortBuffer[] indexBufferArray) {
+        this.indexBufferArray = indexBufferArray;
+    }
+
+    public int[] getMaterialIndexArray() {
+        return materialIndexArray;
+    }
+
+    public void setMaterialIndexArray(int[] materialIndexArray) {
+        this.materialIndexArray = materialIndexArray;
+    }
+
+    public FloatBuffer getNormalBuffer() {
+        return normalBuffer;
+    }
+
+    public void setNormalBuffer(FloatBuffer normalBuffer) {
+        this.normalBuffer = normalBuffer;
+    }
+
+    public FloatBuffer getPointBuffer() {
+        return pointBuffer;
+    }
+
+    public void setPointBuffer(FloatBuffer pointBuffer) {
+        this.pointBuffer = pointBuffer;
+    }
+
+    public FloatBuffer getTexCoordBuffer() {
+        return texCoordBuffer;
+    }
+
+    public void setTexCoordBuffer(FloatBuffer texCoordBuffer) {
+        this.texCoordBuffer = texCoordBuffer;
+    }
+}
index 48bf13f..ae957f2 100755 (executable)
@@ -36,6 +36,7 @@ import java.io.Serializable;
 import java.net.URL;
 import java.nio.ByteBuffer;
 import java.nio.ByteOrder;
+import java.nio.ShortBuffer;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.HashSet;
@@ -48,6 +49,9 @@ import projectkyoto.mmd.file.PMDModel;
 import projectkyoto.mmd.file.PMDSkinData;
 import projectkyoto.mmd.file.PMDSkinVertData;
 import projectkyoto.mmd.file.PMDVertex;
+import projectkyoto.mmd.file.pmn.PMNData;
+import projectkyoto.mmd.file.pmn.PMNMesh;
+import projectkyoto.mmd.file.pmn.PMNSkinMesh;
 
 /**
  *
@@ -66,7 +70,7 @@ public class MeshConverter implements Serializable{
     public ArrayList<ByteBuffer> skinBufferList;
     public ByteBuffer skinIndexBuffer;
     int currentVertIndex = 0;
-    public static int stride = 56;
+    PMNData pmnData;
     public MeshConverter(PMDModel model) {
         this.model = model;
         skinMeshData = new SkinMeshData(this, model);
@@ -175,32 +179,6 @@ public class MeshConverter implements Serializable{
             }
         }
     }
-    void createInterleavedBuffer() {
-        int size = 0;
-        for(MeshData md : meshDataList) {
-            md.offset = size * stride;
-            size += md.vertIndexList.size();
-        }
-        interleavedBuffer = ByteBuffer.allocateDirect(size * stride);
-        interleavedBuffer.order(ByteOrder.nativeOrder());
-        PMDVertex tmpVert = new PMDVertex();
-        for(MeshData md : meshDataList) {
-            for(Integer vertIndex : md.getVertIndexList()) {
-                PMDVertex v = model.getVertex(vertIndex, tmpVert);
-                interleavedBuffer.putFloat(v.getPos().x);
-                interleavedBuffer.putFloat(v.getPos().y);
-                interleavedBuffer.putFloat(v.getPos().z);
-                interleavedBuffer.putFloat(v.getNormal().x);
-                interleavedBuffer.putFloat(v.getNormal().y);
-                interleavedBuffer.putFloat(v.getNormal().z);
-                interleavedBuffer.putFloat(v.getUv().getU()).putFloat(1f - v.getUv().getV());
-                float weight = (float) v.getBoneWeight() / 100.0f;
-                interleavedBuffer.putFloat(weight).putFloat(1f - weight)
-                        .putFloat(0).putFloat(0);
-                interleavedBuffer.putShort((short)v.getBoneNum1()).putShort((short)v.getBoneNum2());
-            }
-        }
-    } 
     void printMeshData(MeshData meshData) {
 //            System.out.println("vertSize = " + meshData.getVertexList().size()
 //                    + " indexSize = " + meshData.getIndexList().size()
@@ -237,7 +215,165 @@ public class MeshConverter implements Serializable{
     void addSkinTriangle(PMDMaterial material, int i1,int i2,int i3) {
         skinMeshData.addTriangle(this, material, i1, i2, i3);
     }
+    public PMNData createPMNData() {
+        pmnData = new PMNData();
+        PMNMesh meshArrah[] = new PMNMesh[meshDataList.size()];
+        for(int i=0;i<meshDataList.size();i++) {
+            MeshData md = meshDataList.get(i);
+            PMNMesh pmnMesh = new PMNMesh();
+            createInterleavedBuffer(md, pmnMesh);
+            
+        }
+        PMNSkinMesh pmnSkinMesh = new PMNSkinMesh();
+        ByteBuffer pointBuffer = ByteBuffer.allocateDirect(12 * skinMeshData.vertexList.size());
+        pointBuffer.order(ByteOrder.nativeOrder());
+        pmnSkinMesh.setPointBuffer(pointBuffer.asFloatBuffer());
+        
+        ByteBuffer normalBuffer = ByteBuffer.allocateDirect(12 * skinMeshData.vertexList.size());
+        normalBuffer.order(ByteOrder.nativeOrder());
+        pmnSkinMesh.setNormalBuffer(normalBuffer.asFloatBuffer());
+        
+        ByteBuffer texCoordBuffer = ByteBuffer.allocateDirect(8 * skinMeshData.vertexList.size());
+        texCoordBuffer.order(ByteOrder.nativeOrder());
+        pmnSkinMesh.setTexCoordBuffer(texCoordBuffer.asFloatBuffer());
+        
+        ByteBuffer boneIndexBuffer = ByteBuffer.allocateDirect(4 * skinMeshData.vertexList.size());
+        boneIndexBuffer.order(ByteOrder.nativeOrder());
+        pmnSkinMesh.setBoneIndexBuffer(boneIndexBuffer.asShortBuffer());
 
+        ByteBuffer boneWeightBuffer = ByteBuffer.allocateDirect(8 * skinMeshData.vertexList.size());
+        boneWeightBuffer.order(ByteOrder.nativeOrder());
+        pmnSkinMesh.setBoneWeightBuffer(boneWeightBuffer.asFloatBuffer());
+        for(PMDVertex v : skinMeshData.vertexList) {
+            pointBuffer.putFloat(v.getPos().x)
+                    .putFloat(v.getPos().y)
+                    .putFloat(v.getPos().z);
+            normalBuffer.putFloat(v.getNormal().x)
+                    .putFloat(v.getNormal().y)
+                    .putFloat(v.getNormal().z);
+            texCoordBuffer.putFloat(v.getUv().getU())
+                    .putFloat(v.getUv().getV());
+            short boneIndex = (short)skinMeshData.boneList.indexOf(v.getBoneNum1());
+            if (boneIndex < 0) {
+                boneIndex = 0;
+            }
+            boneIndexBuffer.putShort(boneIndex);
+            boneIndex = (short)skinMeshData.boneList.indexOf(v.getBoneNum2());
+            if (boneIndex < 0) {
+                boneIndex = 0;
+            }
+            boneIndexBuffer.putShort(boneIndex);
+            float weight = (float)v.getBoneWeight() / 100f;
+            boneWeightBuffer.putFloat(weight).putFloat(1f - weight);
+        }
+        pmnSkinMesh.setIndexBufferArray(new ShortBuffer[skinMeshData.indexMap.size()]);
+        pmnSkinMesh.setMaterialIndexArray(new int[skinMeshData.indexMap.size()]);
+        int i=0;
+        for(PMDMaterial m : skinMeshData.indexMap.keySet()) {
+            List<Integer>indexList = skinMeshData.indexMap.get(m);
+            ByteBuffer indexBuffer = ByteBuffer.allocateDirect(2 * indexList.size());
+            indexBuffer.order(ByteOrder.nativeOrder());
+            for(Integer index : indexList) {
+                indexBuffer.putShort(index.shortValue());
+            }
+            pmnSkinMesh.getIndexBufferArray()[i] = indexBuffer.asShortBuffer();
+            for(int mi=0;mi<model.getMaterialCount();mi++) {
+                if (model.getMaterial()[mi] == m) {
+                    pmnSkinMesh.getMaterialIndexArray()[i] = mi;
+                    break;
+                }
+            }
+            i++;
+        }
+        
+        return pmnData;
+    }
+    public void createInterleavedBuffer(MeshData md, PMNMesh pmnMesh) {
+        byte offset = 0;
+        byte[] offsetArray = new byte[5];
+        pmnMesh.setOffsetArray(offsetArray);
+        short[] boneIndexArray = new short[md.boneList.size()];
+        pmnMesh.setBoneIndexArray(boneIndexArray);
+        // point
+        offsetArray[0] = offset;
+        offset += 12;
+        // normal
+        offsetArray[1] = offset;
+        offset += 12;
+        if (md.material.getTextureFileName().length() >= 0) {
+            // texcoord
+            offsetArray[2] = offset;
+            offset += 8;
+        } else {
+            offsetArray[2] = -1;
+        }
+        // boneIndex
+        offsetArray[3] = offset;
+        offset += 4;
+        //boneWeight
+        offsetArray[4] = offset;
+        offset += 8;
+        
+        pmnMesh.setStride(offset);
+        ByteBuffer interleavedBuffer = ByteBuffer.allocateDirect(offset * md.vertIndexList.size());
+        interleavedBuffer.order(ByteOrder.nativeOrder());
+        pmnMesh.setInterleavedBuffer(interleavedBuffer);
+        PMDVertex v = new PMDVertex();
+        for(Integer vertIndex : md.getVertIndexList()) {
+            model.getVertex(vertIndex, v);
+            interleavedBuffer.putFloat(v.getPos().x)
+                    .putFloat(v.getPos().y)
+                    .putFloat(v.getPos().z);
+            interleavedBuffer.putFloat(v.getNormal().x)
+                    .putFloat(v.getNormal().y)
+                    .putFloat(v.getNormal().z);
+            if (offsetArray[2] >= 0) {
+                interleavedBuffer.putFloat(v.getUv().getU())
+                        .putFloat(v.getUv().getV());
+            }
+            short boneIndex = (short)md.boneList.indexOf(v.getBoneNum1());
+            if (boneIndex < 0) {
+                boneIndex = 0;
+            }
+            interleavedBuffer.putShort(boneIndex);
+            boneIndex = (short)md.boneList.indexOf(v.getBoneNum2());
+            if (boneIndex < 0) {
+                boneIndex = 0;
+            }
+            interleavedBuffer.putShort(boneIndex);
+            float weight = (float)v.getBoneWeight() / 100f;
+            interleavedBuffer.putFloat(weight).putFloat(1f - weight);
+        }
+        ByteBuffer indexBuffer = ByteBuffer.allocateDirect(2 * md.getIndexList().size());
+        indexBuffer.order(ByteOrder.nativeOrder());
+        for(Integer index : md.getIndexList()) {
+            indexBuffer.putShort(index.shortValue());
+        }
+        pmnMesh.setIndexBuffer(indexBuffer.asShortBuffer());
+        for(int i=0;i<model.getMaterialCount();i++) {
+            if (model.getMaterial()[i] == md.getMaterial()) {
+                pmnMesh.setMaterialIndex(model.getFaceVertCount());
+                break;
+            }
+        }
+        for(int i=0;i<boneIndexArray.length;i++) {
+            boneIndexArray[i] = md.boneList.get(i).shortValue();
+        }
+    }
+    public int calcPMNSize() {
+        int size = 16;
+        for(MeshData md : meshDataList) {
+            int stride;
+            if (md.material.getTextureFileName().length() >= 0) {
+                stride = 44;
+            } else {
+                stride = 36;
+            }
+            size += stride * md.getVertIndexList().size();
+            size += 2 * md.getIndexList().size();
+        }
+        return size;
+    }
     public int getMaxBoneSize() {
         return maxBoneSize;
     }
@@ -269,13 +405,18 @@ public class MeshConverter implements Serializable{
     public void setSkinMeshData(SkinMeshData skinMeshData) {
         this.skinMeshData = skinMeshData;
     }
+
+    public PMNData getPmnData() {
+        return pmnData;
+    }
+    
     
 }
 class VertIndex implements Serializable{
     int index;
 
     public VertIndex(int index) {
-        this.index = index;
+        this.index = index & 0xffff;
     }
 
     @Override
index ddea9de..77da52d 100755 (executable)
@@ -54,7 +54,7 @@ public class MeshData {
     List<Integer>boneList = new ArrayList<Integer>();
 //    List<PMDVertex> vertexList = new ArrayList<PMDVertex>();
     List<Integer> indexList = new ArrayList<Integer>();
-    public ByteBuffer indexBuffer;
+//    public ByteBuffer indexBuffer;
     List<Integer> vertIndexList = new ArrayList<Integer>();
     public int offset;
     private PMDVertex tmpVert = new PMDVertex();
@@ -150,9 +150,9 @@ public class MeshData {
         this.model = model;
     }
 
-    public ByteBuffer getIndexBuffer() {
-        return indexBuffer;
-    }
+//    public ByteBuffer getIndexBuffer() {
+//        return indexBuffer;
+//    }
 
     public List<Integer> getVertIndexList() {
         return vertIndexList;
index 20d0306..2b0a27b 100755 (executable)
@@ -58,10 +58,14 @@ public class SkinMeshData implements Serializable{
         for(PMDSkinData sd : model.getSkinData()) {
             if (sd.getSkinType() == 0) {
                 for(int i=0;i<sd.getSkinVertCount();i++) {
-                    int skinVertIndex = sd.getIndexBuf().get(i);
-                    PMDVertex v = model.getVertex(skinVertIndex);
-                    vertexList.add(v);
-                    mc.skinTmpVertMap.put(skinVertIndex, 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) {
+                        ex.printStackTrace();
+                    }
                 }
                 break;
             }