OSDN Git Service

add jni skinning support
authorKazuhiko Kobayashi <chototsu_moushinp@yahoo.co.jp>
Sat, 25 Feb 2012 00:38:58 +0000 (09:38 +0900)
committerKazuhiko Kobayashi <chototsu_moushinp@yahoo.co.jp>
Sat, 25 Feb 2012 00:38:58 +0000 (09:38 +0900)
src/projectkyoto/jme3/mmd/GeometryOptimizer.java
src/projectkyoto/jme3/mmd/PMDGeometry.java
src/projectkyoto/jme3/mmd/PMDLoaderGLSLSkinning2.java
src/projectkyoto/jme3/mmd/PMDNode.java
src/projectkyoto/jme3/mmd/PMDSkinMesh.java
src/projectkyoto/jme3/mmd/SkeletonControl.java
src/projectkyoto/jme3/mmd/Skin.java

index 4c1fd2a..30f6dae 100644 (file)
@@ -20,6 +20,8 @@ import java.nio.FloatBuffer;
 import java.nio.IntBuffer;
 import java.nio.ShortBuffer;
 import java.nio.channels.FileChannel.MapMode;
+import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Set;
 import projectkyoto.mmd.file.util2.BufferUtil;
@@ -69,6 +71,47 @@ public class GeometryOptimizer {
             System.out.println("done");
         }
     }
+    String createVBKey(VertexBuffer vb) {
+        StringBuilder sb = new StringBuilder();
+           sb.append(vb.getNumComponents())
+                   .append(",")
+                   .append(vb.getFormat())
+                   .append(",")
+                   .append(vb.isNormalized())
+                   .append(",")
+                   .append(vb.getStride())
+                   .append(",")
+                   .append(vb.getOffset())
+                   .append(",")
+                   .append(vb.getBufferType());
+           return sb.toString();
+    }
+    public void optimize3() {
+        HashMap<String, VertexBuffer>vbMap = new HashMap<String, VertexBuffer>();
+        ArrayList<VertexBuffer> vbList = new ArrayList<VertexBuffer>();
+        for(Mesh mesh : meshSet) {
+            vbList.clear();
+            for(VertexBuffer vb : mesh.getBufferList()) {
+                if (vb.getBufferType().equals(VertexBuffer.Type.Index)
+                        || vb.getBufferType().equals(VertexBuffer.Type.InterleavedData)){
+                    continue;
+                }
+                if (vb.getStride() > 0) {
+                    String key = createVBKey(vb);
+                    System.out.append("key = "+key);
+                    VertexBuffer vb2 = vbMap.get(key);
+                    if (vb2 != null) {
+                        vbList.add(vb2);
+                    } else {
+                        vbMap.put(key, vb);
+                    }
+                }
+            }
+            for(VertexBuffer vb : vbList) {
+//                mesh.setBuffer(vb);
+            }
+        }
+    }
     public void optimize() {
         calcInterleavedSize();
         interleavedBuffer = BufferUtil.createByteBuffer(interleavedSize);
index 27a2796..0e2cbb0 100755 (executable)
@@ -96,8 +96,15 @@ public class PMDGeometry extends Geometry {
         if (mesh instanceof PMDSkinMesh) {
             PMDSkinMesh oldMesh = (PMDSkinMesh)mesh;
             PMDSkinMesh newMesh = new PMDSkinMesh();
+            newMesh.setBuffer(oldMesh.getBuffer(Type.Position));
+            newMesh.setBuffer(oldMesh.getBuffer(Type.Normal));
+            newMesh.setBuffer(oldMesh.getBuffer(Type.BoneIndex));
+            newMesh.setBuffer(oldMesh.getBuffer(Type.BoneWeight));
             newMesh.boneIndexArray = oldMesh.boneIndexArray;
-//            newMesh.boneMatrixArray = new Matrix4f[mesh.boneMatrixArray.length];
+            newMesh.boneMatrixArray = new Matrix4f[oldMesh.boneMatrixArray.length];
+            if (oldMesh.getBuffer(Type.TexCoord) != null) {
+                newMesh.setBuffer(oldMesh.getBuffer(Type.TexCoord));
+            }
 //            for(int i=0;i<mesh.boneMatrixArray.length;i++) {
 //                newMesh.boneMatrixArray[i] = new Matrix4f();
 //                newMesh.boneMatrixArray[i].loadIdentity();
index b1048c5..11536e9 100755 (executable)
@@ -56,6 +56,7 @@ 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.IOException;
 import java.nio.ByteBuffer;
 import java.nio.FloatBuffer;
@@ -88,6 +89,9 @@ public class PMDLoaderGLSLSkinning2 implements AssetLoader{
     VertexBuffer skinnb;
     VertexBuffer skinnb2;
     VertexBuffer skintb;
+    VertexBuffer skinbib;
+    VertexBuffer skinwb;
+    int[] skinIndexArray;
     Skin skinArray[];
     SkeletonControl skeletonControl;
     HashMap<String, Texture> textureMap = new HashMap<String, Texture>();
@@ -171,6 +175,9 @@ public class PMDLoaderGLSLSkinning2 implements AssetLoader{
         meshConverter = null;
         model.setVertexBuffer(null);
 //        go.optimize();
+        FloatBuffer fb = (FloatBuffer)skinvb.getData();
+        node.skinPosBuffer = BufferUtils.createFloatBuffer(fb.limit());
+        projectkyoto.jme3.mmd.nativelib.SkinUtil.copy(fb, node.skinPosBuffer, fb.limit() * 4);
         node.init();
         node.calcOffsetMatrices();
         node.update();
@@ -188,24 +195,56 @@ public class PMDLoaderGLSLSkinning2 implements AssetLoader{
         
         skinnb = new VertexBuffer(VertexBuffer.Type.Normal);
         FloatBuffer skinnfb = BufferUtils.createFloatBuffer(meshConverter.getSkinMeshData().getVertexList().size() * 3);
-        skinnb.setupData(VertexBuffer.Usage.Dynamic, 3, VertexBuffer.Format.Float, 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.Dynamic, 3, VertexBuffer.Format.Float, skinnfb2);
+        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);
         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);
+        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);
+        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);
             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()));
+            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;
+            }
         }
-        skintb.setUpdateNeeded();
     }
 
     PMDSkinMesh createSkinMesh(PMDMaterial pmdMaterial) {
+        boolean textureFlag = true;
+        if (pmdMaterial.getTextureFileName().length() == 0) {
+            textureFlag = false;
+        }
         PMDSkinMesh mesh = new PMDSkinMesh();
         List<Integer> indexList = meshConverter.getSkinMeshData().getIndexMap().get(pmdMaterial);
         mesh.setMode(Mesh.Mode.Triangles);
@@ -213,7 +252,11 @@ public class PMDLoaderGLSLSkinning2 implements AssetLoader{
         mesh.setSkinvb2(skinvb2);
         mesh.setBuffer(skinnb);
         mesh.setSkinnb2(skinnb2);
-        mesh.setBuffer(skintb);
+        if (textureFlag) {
+            mesh.setBuffer(skintb);
+        }
+        mesh.setBuffer(skinbib);
+        mesh.setBuffer(skinwb);
         VertexBuffer ib = new VertexBuffer(VertexBuffer.Type.Index);
         ShortBuffer isb = BufferUtils.createShortBuffer(indexList.size());
         for (Integer index : indexList) {
@@ -221,6 +264,12 @@ public class PMDLoaderGLSLSkinning2 implements AssetLoader{
         }
         ib.setupData(VertexBuffer.Usage.Static, 1, VertexBuffer.Format.UnsignedShort, isb);
         mesh.setBuffer(ib);
+        mesh.setBoneIndexArray(skinIndexArray);
+        mesh.setBoneMatrixArray(new Matrix4f[skinIndexArray.length]);
+        for (int i = 0; i < mesh.getBoneMatrixArray().length; i++) {
+            mesh.getBoneMatrixArray()[i] = new Matrix4f();
+            mesh.getBoneMatrixArray()[i].loadIdentity();
+        }
         return mesh;
     }
 
@@ -363,14 +412,14 @@ public class PMDLoaderGLSLSkinning2 implements AssetLoader{
 
     void setupMaterial(PMDMaterial m, PMDGeometry geom) {
         Material mat;
-        if (geom.getMesh() instanceof PMDSkinMesh) {
+        if (false /*geom.getMesh() instanceof PMDSkinMesh*/) {
 //            mat = new Material(assetManager, "Common/MatDefs/Light/Lighting.j3md");
             mat = createMaterial(m, false);
             geom.setMaterial(mat);
             geom.setGlslSkinningMaterial(mat);
             geom.setNoSkinningMaterial(mat);
         } else {
-            PMDMesh mesh = (PMDMesh)geom.getMesh();
+//            PMDMesh mesh = (PMDMesh)geom.getMesh();
             mat = createMaterial(m, true);
             geom.setMaterial(mat);
             geom.setGlslSkinningMaterial(mat);
@@ -572,7 +621,8 @@ public class PMDLoaderGLSLSkinning2 implements AssetLoader{
             PMDSkinData pmdSkinData = model.getSkinData()[i];
             if (pmdSkinData.getSkinType() != 0) {
                 Skin skin = new Skin(node, pmdSkinData.getSkinName());
-                skin.setSkinData(pmdSkinData);
+                skin.setIndexBuf(pmdSkinData.getIndexBuf());
+                skin.setSkinBuf(pmdSkinData.getSkinBuf());
                 skinList.add(skin);
             }
         }
index 2434b51..c78775d 100755 (executable)
@@ -86,12 +86,13 @@ 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 skinPosArray[];
+//    javax.vecmath.Vector3f skinNormalArray[];
     javax.vecmath.Vector3f skinPosArrayOrig[];
-    javax.vecmath.Vector3f skinNormalArrayOrig[];
-    float skinBoneWeightArray[];
-    int skinBoneArray[];
+//    javax.vecmath.Vector3f skinNormalArrayOrig[];
+    FloatBuffer skinPosBuffer;
+//    float skinBoneWeightArray[];
+//    int skinBoneArray[];
     AssetManager assetManager;
     Matrix4f[] offsetMatrices;
     boolean updateNeeded = true;
@@ -114,8 +115,8 @@ public class PMDNode extends Node {
         pmdModel = (PMDModel)SavableUtil.read(c, "pmdModel", null);
         skeleton = (Skeleton)c.readSavable("skeleton", null);
         skinMap = (Map<String, Skin>)c.readStringSavableMap("skinMap", new HashMap<String, Savable>());
-        skinBoneWeightArray = c.readFloatArray("skinBoneWeightArray", new float[0]);
-        skinBoneArray = c.readIntArray("skinBoneArray", new int[0]);
+//        skinBoneWeightArray = c.readFloatArray("skinBoneWeightArray", new float[0]);
+//        skinBoneArray = c.readIntArray("skinBoneArray", new int[0]);
         edgeSize = c.readFloat("edgeSize", 1.0f);
         int pmdGeometryArrayLength = c.readInt("pmdGeometryArrayLength", 0);
         pmdGeometryArray = new PMDGeometry[pmdGeometryArrayLength];
@@ -170,7 +171,7 @@ public class PMDNode extends Node {
                 l2:
                 for(int i2=0;i2<pmdModel.getSkinCount();i2++){
                     if (pmdModel.getSkinData()[i2].getSkinName().equals(skin.getSkinName())) {
-                        skin.skinData = pmdModel.getSkinData()[i2];
+//                        skin.skinData = pmdModel.getSkinData()[i2];
                         break l2;
                     }
                 }
@@ -178,18 +179,18 @@ public class PMDNode extends Node {
                 skin.setUpdateNeeded(true);
                 skinMap.put(skin.skinName, skin);
             }
-            skinPosArray = (javax.vecmath.Vector3f[])SavableUtil.read(c, "skinPosArray", null);
-            skinPosArrayOrig = new javax.vecmath.Vector3f[skinPosArray.length];
-            for(int i=0;i<skinPosArray.length;i++) {
-                skinPosArrayOrig[i] = new javax.vecmath.Vector3f(skinPosArray[i]);
-            }
-            skinNormalArray = (javax.vecmath.Vector3f[])SavableUtil.read(c, "skinNormalArray", null);
-            skinNormalArrayOrig = new javax.vecmath.Vector3f[skinNormalArray.length];
-            for(int i=0;i<skinNormalArray.length;i++) {
-                skinNormalArrayOrig[i] = new javax.vecmath.Vector3f(skinNormalArray[i]);
-            }
-            skinBoneArray = c.readIntArray("skinBoneArray", skinBoneArray);
-            skinBoneWeightArray = c.readFloatArray("skinBoneWeightArray", skinBoneWeightArray);
+//            skinPosArray = (javax.vecmath.Vector3f[])SavableUtil.read(c, "skinPosArray", null);
+//            skinPosArrayOrig = new javax.vecmath.Vector3f[skinPosArray.length];
+//            for(int i=0;i<skinPosArray.length;i++) {
+//                skinPosArrayOrig[i] = new javax.vecmath.Vector3f(skinPosArray[i]);
+//            }
+//            skinNormalArray = (javax.vecmath.Vector3f[])SavableUtil.read(c, "skinNormalArray", null);
+//            skinNormalArrayOrig = new javax.vecmath.Vector3f[skinNormalArray.length];
+//            for(int i=0;i<skinNormalArray.length;i++) {
+//                skinNormalArrayOrig[i] = new javax.vecmath.Vector3f(skinNormalArray[i]);
+//            }
+//            skinBoneArray = c.readIntArray("skinBoneArray", skinBoneArray);
+//            skinBoneWeightArray = c.readFloatArray("skinBoneWeightArray", skinBoneWeightArray);
     }
 
     @Override
@@ -200,8 +201,8 @@ public class PMDNode extends Node {
         SavableUtil.write(c, pmdModel, "pmdModel");
         c.write(skeleton, "skeleton", new Skeleton());
         c.writeStringSavableMap(skinMap, "skinMap", new HashMap<String, Skin>());
-        c.write(skinBoneWeightArray, "skinBoneWeightArray", null);
-        c.write(skinBoneArray, "skinBoneArray", null);
+//        c.write(skinBoneWeightArray, "skinBoneWeightArray", null);
+//        c.write(skinBoneArray, "skinBoneArray", null);
         c.write(edgeSize, "edgeSize", 1.0f);
         c.write(pmdGeometryArray.length, "pmdGeometryArrayLength",0);
         c.write(skinTargets.length, "skinTargetsLength",0);
@@ -212,10 +213,10 @@ public class PMDNode extends Node {
             c.write(mesh.getBuffer(Type.TexCoord),"skintb",null);
         }
         c.write(skinArray, "skinArray", null);
-        SavableUtil.write(c, skinPosArrayOrig,"skinPosArray");
-        SavableUtil.write(c, skinNormalArrayOrig, "skinNormalArray");
-        c.write(skinBoneArray, "skinBoneArray", null);
-        c.write(skinBoneWeightArray, "skinBoneWeightArray", null);
+//        SavableUtil.write(c, skinPosArrayOrig,"skinPosArray");
+//        SavableUtil.write(c, skinNormalArrayOrig, "skinNormalArray");
+//        c.write(skinBoneArray, "skinBoneArray", null);
+//        c.write(skinBoneWeightArray, "skinBoneWeightArray", null);
         
     }
 
@@ -241,21 +242,21 @@ public class PMDNode extends Node {
             skinMap.put(skin.getSkinName(), skin);
         }
         int skinVertSize = skinVertexList.size();
-        skinPosArray = new javax.vecmath.Vector3f[skinVertSize];
-        skinNormalArray = new javax.vecmath.Vector3f[skinVertSize];
+//        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];
+//        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();
+//            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();
         }
     }
 
@@ -300,7 +301,30 @@ boolean setBoneMatricesFlag = true;
                     }
                 }
             }
-            
+            for(int i=getChildren().size()-1;i>=0;i--) {
+                Spatial sp = getChild(i);
+                if (sp instanceof PMDGeometry) {
+                    PMDGeometry g = (PMDGeometry) sp;
+                    Mesh mesh = g.getMesh();
+                    if (mesh instanceof PMDSkinMesh) {
+                        PMDSkinMesh skinMesh = (PMDSkinMesh)mesh;
+                        Material m = g.getMaterial();
+                        int boneIndexArray[] = skinMesh.getBoneIndexArray();
+                        Matrix4f[] boneMatrixArray = skinMesh.getBoneMatrixArray();
+                        for (int i2 = skinMesh.getBoneIndexArray().length-1; i2 >=0; i2--) {
+                            boneMatrixArray[i2] = (offsetMatrices[boneIndexArray[i2]]);
+                        }
+                        if (glslSkinning) {
+                            if (skinMesh.boneMatricesParamIndex < 0) {
+                                m.setParam("BoneMatrices", VarType.Matrix4Array, skinMesh.getBoneMatrixArray());
+                                skinMesh.boneMatricesParamIndex = g.getMaterial().getParamIndex("BoneMatrices");
+                            } else {
+                                m.setParam(skinMesh.boneMatricesParamIndex, VarType.Matrix4Array, skinMesh.getBoneMatrixArray());
+                            }
+                        }
+                    }
+                }
+            }
             if (!glslSkinning) {
                 for (PMDMesh mesh : targets) {
                     softwareSkinUpdate(mesh);
@@ -343,21 +367,21 @@ boolean setBoneMatricesFlag = true;
             return;
         }
         VertexBuffer vb = skinTargets[0].getBuffer(VertexBuffer.Type.Position);
-        VertexBuffer nb = skinTargets[0].getBuffer(VertexBuffer.Type.Normal);
+//        VertexBuffer nb = skinTargets[0].getBuffer(VertexBuffer.Type.Normal);
         skinTargets[0].skinvb2.setUpdateNeeded();
-        skinTargets[0].skinnb2.setUpdateNeeded();
+//        skinTargets[0].skinnb2.setUpdateNeeded();
         for(PMDSkinMesh skinMesh : skinTargets) {
 //            skinMesh.clearBuffer(Type.Position);
 //            skinMesh.clearBuffer(Type.Normal);
             skinMesh.setBuffer(skinTargets[0].getSkinvb2());
-            skinMesh.setBuffer(skinTargets[0].getSkinnb2());
+//            skinMesh.setBuffer(skinTargets[0].getSkinnb2());
         }
         skinTargets[0].skinvb2 = vb;
-        skinTargets[0].skinnb2 = nb;
+//        skinTargets[0].skinnb2 = nb;
         vb = skinTargets[0].getBuffer(VertexBuffer.Type.Position);
-        nb = skinTargets[0].getBuffer(VertexBuffer.Type.Normal);
+//        nb = skinTargets[0].getBuffer(VertexBuffer.Type.Normal);
         vb.setUpdateNeeded();
-        nb.setUpdateNeeded();
+//        nb.setUpdateNeeded();
     }
     private void softwareSkinUpdate(PMDMesh mesh){
         int maxWeightsPerVert = 2;//mesh.getMaxNumWeights();
@@ -459,142 +483,35 @@ boolean setBoneMatricesFlag = true;
         PMDSkinMesh skinMesh = skinTargets[0];
         VertexBuffer vb = skinMesh.getSkinvb2(); //.getBuffer(Type.Position);
         FloatBuffer fvb = (FloatBuffer) vb.getData();
-        VertexBuffer nb = skinMesh.getSkinnb2(); //skinMesh.getBuffer(Type.Normal);
-        FloatBuffer fnb = (FloatBuffer) nb.getData();
-
-        for(int i=skinPosArray.length-1;i>=0;i--) {
-            skinPosArray[i].set(skinPosArrayOrig[i]);
-        }
+        fvb.position(0);
+//        float[] floatBuf = skinPosBuffer.array();
+        int length = fvb.capacity();
+//        for(int i=0;i<length;i++) {
+//            fvb.put(floatBuf[i]);
+//        }
+        projectkyoto.jme3.mmd.nativelib.SkinUtil.copy(skinPosBuffer, fvb, fvb.limit() * 4);
         for (Skin skin : skinArray) {
             if (true || skin.isUpdateNeeded()) {
-                if (skin.getWeight() != 0f) {
-                    for (PMDSkinVertData svd : skin.getSkinData().getSkinVertData()) {
-                        javax.vecmath.Vector3f dist = skinPosArray[svd.getSkinVertIndex()];
-                        dist.set(svd.getSkinVertPos());
-                        dist.scale(skin.getWeight());
-                        dist.add(skinPosArrayOrig[svd.getSkinVertIndex()]);
-                    }
+                float weight = skin.getWeight();
+                if (weight != 0f) {
+//                    for (PMDSkinVertData svd : skin.getSkinData().getSkinVertData()) {
+//                        javax.vecmath.Vector3f svp = svd.getSkinVertPos();
+//                        javax.vecmath.Vector3f svop = skinPosArrayOrig[svd.getSkinVertIndex()];
+//                        fvb.position(svd.getSkinVertIndex() * 3);
+//                        fvb.put(svp.x*weight+svop.x).put(svp.y*weight+svop.y).put(svp.z*weight+svop.z);
+//                    }
+                    projectkyoto.jme3.mmd.nativelib.SkinUtil.setSkin(fvb, skin.getIndexBuf(), skin.getSkinBuf(), weight);
+                    
                 }
                 skin.setUpdateNeeded(false);
             }
         }
 
-        fvb.position(0);
-        fnb.position(0);
-        TempVars vars = TempVars.get();
-        for (int i = 0; i < skinPosArray.length; i++) {
-            int idxWeights = 0;
-
-            float[] posBuf = vars.skinPositions;
-            float[] normBuf = vars.skinNormals;
-
-            // read next set of positions and normals from native buffer
-            int idxPositions = 0;
-
-            // iterate vertices and apply skinning transform for each effecting bone
-            float nmx = skinNormalArray[i].x;//normBuf[idxPositions];
-            float vtx = skinPosArray[i].x;//posBuf[idxPositions++];
-            float nmy = skinNormalArray[i].y;//normBuf[idxPositions];
-            float vty = skinPosArray[i].y;//posBuf[idxPositions++];
-            float nmz = skinNormalArray[i].z;//normBuf[idxPositions];
-            float vtz = skinPosArray[i].z;//posBuf[idxPositions++];
-
-            float rx = 0, ry = 0, rz = 0, rnx = 0, rny = 0, rnz = 0;
-
-            for (int w = 2 - 1; w >= 0; w--) {
-                float weight = skinBoneWeightArray[i];//(float) v.getBoneWeight();//weights[idxWeights];
-                if (w == 1) {
-                    weight = 1f - weight;
-                }
-                //weight = weight / 100f;
-
-                Matrix4f mat = offsetMatrices[skinBoneArray[i * 2 + w]];
-
-                rx += (mat.m00 * vtx + mat.m01 * vty + mat.m02 * vtz + mat.m03) * weight;
-                ry += (mat.m10 * vtx + mat.m11 * vty + mat.m12 * vtz + mat.m13) * weight;
-                rz += (mat.m20 * vtx + mat.m21 * vty + mat.m22 * vtz + mat.m23) * weight;
-
-                rnx += (nmx * mat.m00 + nmy * mat.m01 + nmz * mat.m02) * weight;
-                rny += (nmx * mat.m10 + nmy * mat.m11 + nmz * mat.m12) * weight;
-                rnz += (nmx * mat.m20 + nmy * mat.m21 + nmz * mat.m22) * weight;
-            }
-
-            fnb.put(rnx).put(rny).put(rnz);
-            fvb.put(rx).put(ry).put(rz);
-        }
-        vars.release();
         vb.setUpdateNeeded();
-        nb.setUpdateNeeded();
+//        nb.setUpdateNeeded();
         skinUpdateNeeded = false;
     }
 
-    void updateSkinMesh(PMDSkinMesh skinMesh) {
-        VertexBuffer vb = skinMesh.getBuffer(Type.Position);
-        FloatBuffer fvb = (FloatBuffer) vb.getData();
-        VertexBuffer nb = skinMesh.getBuffer(Type.Normal);
-        FloatBuffer fnb = (FloatBuffer) nb.getData();
-
-        for (Skin skin : skinArray) {
-            if (skin.isUpdateNeeded()) {
-                if (skin.getWeight() != 1f) {
-                    for (PMDSkinVertData svd : skin.getSkinData().getSkinVertData()) {
-                        javax.vecmath.Vector3f dist = skinPosArray[svd.getSkinVertIndex()];
-                        dist.set(svd.getSkinVertPos());
-                        dist.scale(skin.getWeight());
-                        dist.add(skinPosArrayOrig[svd.getSkinVertIndex()]);
-                    }
-                }
-                skin.setUpdateNeeded(false);
-            }
-        }
-
-        fvb.position(0);
-        fnb.position(0);
-        TempVars vars = TempVars.get();
-        for (int i = 0; i < skinPosArray.length; i++) {
-            int idxWeights = 0;
-
-            float[] posBuf = vars.skinPositions;
-            float[] normBuf = vars.skinNormals;
-
-            // read next set of positions and normals from native buffer
-            int idxPositions = 0;
-
-            // iterate vertices and apply skinning transform for each effecting bone
-            float nmx = skinNormalArray[i].x;//normBuf[idxPositions];
-            float vtx = skinPosArray[i].x;//posBuf[idxPositions++];
-            float nmy = skinNormalArray[i].y;//normBuf[idxPositions];
-            float vty = skinPosArray[i].y;//posBuf[idxPositions++];
-            float nmz = skinNormalArray[i].z;//normBuf[idxPositions];
-            float vtz = skinPosArray[i].z;//posBuf[idxPositions++];
-
-            float rx = 0, ry = 0, rz = 0, rnx = 0, rny = 0, rnz = 0;
-
-            for (int w = 2 - 1; w >= 0; w--) {
-                float weight = skinBoneWeightArray[i];//(float) v.getBoneWeight();//weights[idxWeights];
-                if (w == 1) {
-                    weight = 1f - weight;
-                }
-                //weight = weight / 100f;
-
-                Matrix4f mat = offsetMatrices[skinBoneArray[i * 2 + w]];
-
-                rx += (mat.m00 * vtx + mat.m01 * vty + mat.m02 * vtz + mat.m03) * weight;
-                ry += (mat.m10 * vtx + mat.m11 * vty + mat.m12 * vtz + mat.m13) * weight;
-                rz += (mat.m20 * vtx + mat.m21 * vty + mat.m22 * vtz + mat.m23) * weight;
-
-                rnx += (nmx * mat.m00 + nmy * mat.m01 + nmz * mat.m02) * weight;
-                rny += (nmx * mat.m10 + nmy * mat.m11 + nmz * mat.m12) * weight;
-                rnz += (nmx * mat.m20 + nmy * mat.m21 + nmz * mat.m22) * weight;
-            }
-
-            fnb.put(rnx).put(rny).put(rnz);
-            fvb.put(rx).put(ry).put(rz);
-        }
-        vars.release();
-        vb.setUpdateNeeded();
-        nb.setUpdateNeeded();
-    }
 
     public void resetToBind() {
         for (int i = 0; i < skeleton.getBoneCount(); i++) {
@@ -949,15 +866,17 @@ boolean setBoneMatricesFlag = true;
                             skinMesh.setSkinvb2(skinMesh0.getSkinvb2());
                             skinMesh.setBuffer(skinMesh0.getBuffer(Type.Normal));
                             skinMesh.setSkinnb2(skinMesh0.getSkinnb2());
-                            skinMesh.setBuffer(skinMesh0.getBuffer(Type.TexCoord));
+                            if (skinMesh0.getBuffer(Type.TexCoord) != null)
+                                skinMesh.setBuffer(skinMesh0.getBuffer(Type.TexCoord));
                         } else {
                             PMDSkinMesh skinMesh = (PMDSkinMesh)mesh;
                             PMDSkinMesh skinMesh0 = skinTargets[0];
                             skinMesh.setBuffer(skinMesh0.getBuffer(Type.Position).clone());
                             skinMesh.setSkinvb2(skinMesh0.getSkinvb2().clone());
-                            skinMesh.setBuffer(skinMesh0.getBuffer(Type.Normal).clone());
-                            skinMesh.setSkinnb2(skinMesh0.getSkinnb2().clone());
-                            skinMesh.setBuffer(skinMesh0.getBuffer(Type.TexCoord));
+                            skinMesh.setBuffer(skinMesh0.getBuffer(Type.Normal));
+                            skinMesh.setSkinnb2(skinMesh0.getSkinnb2());
+                            if (skinMesh0.getBuffer(Type.TexCoord) != null)
+                                skinMesh.setBuffer(skinMesh0.getBuffer(Type.TexCoord));
                         }
                         newPMDNode.skinTargets[skinMeshCount++] = (PMDSkinMesh)mesh;
                     }
@@ -971,14 +890,14 @@ boolean setBoneMatricesFlag = true;
                 newPMDNode.skinMap.put(skinName, skin);
             }
             newPMDNode.skinArray = newPMDNode.skinMap.values().toArray(new Skin[newPMDNode.skinMap.size()]);
-            newPMDNode.skinPosArray = new javax.vecmath.Vector3f[skinPosArray.length];
-            for(int i=0;i<skinPosArray.length;i++) {
-                newPMDNode.skinPosArray[i] = new javax.vecmath.Vector3f(skinPosArray[i]);
-            }
-            newPMDNode.skinNormalArray = new javax.vecmath.Vector3f[skinNormalArray.length];
-            for(int i=0;i<skinNormalArray.length;i++) {
-                newPMDNode.skinNormalArray[i] = new javax.vecmath.Vector3f(skinNormalArray[i]);
-            }
+//            newPMDNode.skinPosArray = new javax.vecmath.Vector3f[skinPosArray.length];
+//            for(int i=0;i<skinPosArray.length;i++) {
+//                newPMDNode.skinPosArray[i] = new javax.vecmath.Vector3f(skinPosArray[i]);
+//            }
+//            newPMDNode.skinNormalArray = new javax.vecmath.Vector3f[skinNormalArray.length];
+//            for(int i=0;i<skinNormalArray.length;i++) {
+//                newPMDNode.skinNormalArray[i] = new javax.vecmath.Vector3f(skinNormalArray[i]);
+//            }
 //            newPMDNode.offsetMatrices = new Matrix4f[offsetMatrices.length];
 //            newPMDNode.setGlslSkinning(newPMDNode.glslSkinning);
             newPMDNode.skeleton.updateWorldVectors();
index 5b26385..dafd716 100755 (executable)
@@ -52,7 +52,7 @@ public class PMDSkinMesh extends Mesh {
     Matrix4f boneMatrixArray[];
     VertexBuffer skinvb2;
     VertexBuffer skinnb2;
-
+    int boneMatricesParamIndex = -1;
     public PMDSkinMesh() {
         super();
     }
index 1dafffa..7354ffa 100755 (executable)
@@ -386,18 +386,18 @@ public class SkeletonControl extends AbstractControl implements Savable, Cloneab
         return skinMap.get(skinName).getWeight();
     }
 
-    public void setSkinWeight(String skinName, float weight) {
-        Skin skin = skinMap.get(skinName);
-        skin.setWeight(weight);
-        for (PMDSkinVertData svd : skin.getSkinData().getSkinVertData()) {
-            javax.vecmath.Vector3f dist = skinPosArray[svd.getSkinVertIndex()];
-//            dist.set(skinPosArrayOrig[svd.getSkinVertIndex()]);
-//            dist.interpolate(svd.getSkinVertPos(), weight);
-            dist.set(svd.getSkinVertPos());
-            dist.scale(weight);
-            dist.add(skinPosArrayOrig[svd.getSkinVertIndex()]);
-        }
-    }
+//    public void setSkinWeight(String skinName, float weight) {
+//        Skin skin = skinMap.get(skinName);
+//        skin.setWeight(weight);
+//        for (PMDSkinVertData svd : skin.getSkinData().getSkinVertData()) {
+//            javax.vecmath.Vector3f dist = skinPosArray[svd.getSkinVertIndex()];
+////            dist.set(skinPosArrayOrig[svd.getSkinVertIndex()]);
+////            dist.interpolate(svd.getSkinVertPos(), weight);
+//            dist.set(svd.getSkinVertPos());
+//            dist.scale(weight);
+//            dist.add(skinPosArrayOrig[svd.getSkinVertIndex()]);
+//        }
+//    }
 
     public Matrix4f[] getOffsetMatrices() {
         return offsetMatrices;
index fd1fb0f..ede1431 100755 (executable)
@@ -34,8 +34,12 @@ import com.jme3.export.JmeExporter;
 import com.jme3.export.JmeImporter;
 import com.jme3.export.OutputCapsule;
 import com.jme3.export.Savable;
+import com.jme3.util.BufferUtils;
 import java.io.IOException;
+import java.nio.FloatBuffer;
+import java.nio.ShortBuffer;
 import projectkyoto.mmd.file.PMDSkinData;
+import projectkyoto.mmd.file.PMDSkinVertData;
 
 /**
  *
@@ -45,9 +49,10 @@ public class Skin implements Cloneable, Savable{
 
     String skinName;
     float weight = 0f;
-    PMDSkinData skinData;
     PMDNode pmdNode;
     boolean updateNeeded = false;
+    ShortBuffer indexBuf;
+    FloatBuffer skinBuf;
 
     public Skin(PMDNode pmdNode, String skinName) {
         this.pmdNode = pmdNode;
@@ -77,14 +82,6 @@ public class Skin implements Cloneable, Savable{
         }
     }
 
-    public PMDSkinData getSkinData() {
-        return skinData;
-    }
-
-    public void setSkinData(PMDSkinData skinData) {
-        this.skinData = skinData;
-    }
-
     public boolean isUpdateNeeded() {
         return updateNeeded;
     }
@@ -106,6 +103,30 @@ public class Skin implements Cloneable, Savable{
         
     }
 
+    public ShortBuffer getIndexBuf() {
+        return indexBuf;
+    }
+
+    public void setIndexBuf(ShortBuffer indexBuf) {
+        this.indexBuf = indexBuf;
+    }
+
+    public PMDNode getPmdNode() {
+        return pmdNode;
+    }
+
+    public void setPmdNode(PMDNode pmdNode) {
+        this.pmdNode = pmdNode;
+    }
+
+    public FloatBuffer getSkinBuf() {
+        return skinBuf;
+    }
+
+    public void setSkinBuf(FloatBuffer skinBuf) {
+        this.skinBuf = skinBuf;
+    }
+
     @Override
     public void read(JmeImporter im) throws IOException {
         InputCapsule c = im.getCapsule(this);