Prechádzať zdrojové kódy

Bugfix: (hopefully) final fixes to armature applying to models without applied transformations (+ removing unused pieces of code)

git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@10529 75d07b2b-3a1a-0410-a2c5-0572b91ccdca
Kae..pl 12 rokov pred
rodič
commit
4f104e4200

+ 3 - 5
engine/src/blender/com/jme3/scene/plugins/blender/animations/ArmatureHelper.java

@@ -85,17 +85,15 @@ public class ArmatureHelper extends AbstractBlenderHelper {
      *            the parent bone
      * @param result
      *            the list where the newly created bone will be added
-     * @param bonesPoseChannels
-     *            a map of bones poses channels
      * @param blenderContext
      *            the blender context
      * @throws BlenderFileException
      *             an exception is thrown when there is problem with the blender
      *             file
      */
-    public void buildBones(Long armatureObjectOMA, Structure boneStructure, Bone parent, List<Bone> result, Matrix4f arbt, final Map<Long, Structure> bonesPoseChannels, BlenderContext blenderContext) throws BlenderFileException {
-        BoneContext bc = new BoneContext(armatureObjectOMA, boneStructure, arbt, bonesPoseChannels, blenderContext);
-        bc.buildBone(result, bonesOMAs, blenderContext);
+    public void buildBones(Long armatureObjectOMA, Structure boneStructure, Bone parent, List<Bone> result, Matrix4f objectToArmatureTransformation, BlenderContext blenderContext) throws BlenderFileException {
+        BoneContext bc = new BoneContext(armatureObjectOMA, boneStructure, blenderContext);
+        bc.buildBone(result, bonesOMAs, objectToArmatureTransformation, blenderContext);
     }
 
     /**

+ 26 - 40
engine/src/blender/com/jme3/scene/plugins/blender/animations/BoneContext.java

@@ -37,8 +37,6 @@ public class BoneContext {
     private Matrix4f          restMatrix;
     /** Bone's total inverse transformation. */
     private Matrix4f          inverseTotalTransformation;
-    /** Bone's parent inverse matrix. */
-    private Matrix4f          inverseParentMatrix;
     /** The length of the bone. */
     private float             length;
 
@@ -49,18 +47,14 @@ public class BoneContext {
      *            the OMA of the bone's armature object
      * @param boneStructure
      *            the bone's structure
-     * @param objectToArmatureMatrix
-     *            object-to-armature transformation matrix
-     * @param bonesPoseChannels
-     *            a map of pose channels for each bone OMA
      * @param blenderContext
      *            the blender context
      * @throws BlenderFileException
      *             an exception is thrown when problem with blender data reading
      *             occurs
      */
-    public BoneContext(Long armatureObjectOMA, Structure boneStructure, Matrix4f objectToArmatureMatrix, final Map<Long, Structure> bonesPoseChannels, BlenderContext blenderContext) throws BlenderFileException {
-        this(boneStructure, armatureObjectOMA, null, objectToArmatureMatrix, bonesPoseChannels, blenderContext);
+    public BoneContext(Long armatureObjectOMA, Structure boneStructure, BlenderContext blenderContext) throws BlenderFileException {
+        this(boneStructure, armatureObjectOMA, null, blenderContext);
     }
 
     /**
@@ -72,17 +66,13 @@ public class BoneContext {
      *            the OMA of the bone's armature object
      * @param parent
      *            bone's parent (null if the bone is the root bone)
-     * @param objectToArmatureMatrix
-     *            object-to-armature transformation matrix
-     * @param bonesPoseChannels
-     *            a map of pose channels for each bone OMA
      * @param blenderContext
      *            the blender context
      * @throws BlenderFileException
      *             an exception is thrown when problem with blender data reading
      *             occurs
      */
-    private BoneContext(Structure boneStructure, Long armatureObjectOMA, BoneContext parent, Matrix4f objectToArmatureMatrix, final Map<Long, Structure> bonesPoseChannels, BlenderContext blenderContext) throws BlenderFileException {
+    private BoneContext(Structure boneStructure, Long armatureObjectOMA, BoneContext parent, BlenderContext blenderContext) throws BlenderFileException {
         this.parent = parent;
         this.boneStructure = boneStructure;
         this.armatureObjectOMA = armatureObjectOMA;
@@ -90,34 +80,23 @@ public class BoneContext {
         length = ((Number) boneStructure.getFieldValue("length")).floatValue();
         ObjectHelper objectHelper = blenderContext.getHelper(ObjectHelper.class);
         armatureMatrix = objectHelper.getMatrix(boneStructure, "arm_mat", blenderContext.getBlenderKey().isFixUpAxis());
-
-        this.computeRestMatrix(objectToArmatureMatrix);
+        
+        //compute the bone's rest matrix
+        restMatrix = armatureMatrix.clone();
+        inverseTotalTransformation = restMatrix.invert();
+        if(parent != null) {
+            restMatrix = parent.inverseTotalTransformation.mult(restMatrix);
+        }
+        
+        //create the children
         List<Structure> childbase = ((Structure) boneStructure.getFieldValue("childbase")).evaluateListBase(blenderContext);
         for (Structure child : childbase) {
-            this.children.add(new BoneContext(child, armatureObjectOMA, this, objectToArmatureMatrix, bonesPoseChannels, blenderContext));
+            this.children.add(new BoneContext(child, armatureObjectOMA, this, blenderContext));
         }
 
         blenderContext.setBoneContext(boneStructure.getOldMemoryAddress(), this);
     }
 
-    /**
-     * This method computes the rest matrix for the bone.
-     * 
-     * @param objectToArmatureMatrix
-     *            object-to-armature transformation matrix
-     */
-    private void computeRestMatrix(Matrix4f objectToArmatureMatrix) {
-        if (parent != null) {
-            inverseParentMatrix = parent.inverseTotalTransformation.clone();
-        } else {
-            inverseParentMatrix = objectToArmatureMatrix.clone();
-        }
-
-        restMatrix = armatureMatrix.clone();
-        inverseTotalTransformation = restMatrix.invert();
-
-        restMatrix = inverseParentMatrix.mult(restMatrix);
-    }
 
     /**
      * This method builds the bone. It recursively builds the bone's children.
@@ -126,27 +105,34 @@ public class BoneContext {
      *            a list of bones where the newly created bone will be added
      * @param boneOMAs
      *            the map between bone and its old memory address
+     * @param objectToArmatureMatrix
+     *            object to armature transformation matrix
      * @param blenderContext
      *            the blender context
      * @return newly created bone
      */
-    public Bone buildBone(List<Bone> bones, Map<Bone, Long> boneOMAs, BlenderContext blenderContext) {
+    public Bone buildBone(List<Bone> bones, Map<Bone, Long> boneOMAs, Matrix4f objectToArmatureMatrix, BlenderContext blenderContext) {
         Long boneOMA = boneStructure.getOldMemoryAddress();
         bone = new Bone(boneName);
         bones.add(bone);
         boneOMAs.put(bone, boneOMA);
         blenderContext.addLoadedFeatures(boneOMA, boneName, boneStructure, bone);
 
-        Matrix4f pose = this.restMatrix.clone();
         ObjectHelper objectHelper = blenderContext.getHelper(ObjectHelper.class);
 
-        Vector3f poseLocation = pose.toTranslationVector();
-        Quaternion rotation = pose.toRotationQuat();
-        Vector3f scale = objectHelper.getScale(pose);
+        Vector3f poseLocation = restMatrix.toTranslationVector();
+        Quaternion rotation = restMatrix.toRotationQuat().normalizeLocal();
+        Vector3f scale = objectHelper.getScale(restMatrix);
+        if(parent == null) {
+            Quaternion rotationQuaternion = objectToArmatureMatrix.toRotationQuat().normalizeLocal(); 
+            scale.multLocal(objectHelper.getScale(objectToArmatureMatrix));            
+            rotationQuaternion.multLocal(poseLocation.addLocal(objectToArmatureMatrix.toTranslationVector()));
+            rotation.multLocal(rotationQuaternion);
+        }
 
         bone.setBindTransforms(poseLocation, rotation, scale);
         for (BoneContext child : children) {
-            bone.addChild(child.buildBone(bones, boneOMAs, blenderContext));
+            bone.addChild(child.buildBone(bones, boneOMAs, objectToArmatureMatrix, blenderContext));
         }
 
         return bone;

+ 6 - 24
engine/src/blender/com/jme3/scene/plugins/blender/modifiers/ArmatureModifier.java

@@ -17,9 +17,7 @@ import com.jme3.animation.Bone;
 import com.jme3.animation.BoneTrack;
 import com.jme3.animation.Skeleton;
 import com.jme3.animation.SkeletonControl;
-import com.jme3.math.Matrix3f;
 import com.jme3.math.Matrix4f;
-import com.jme3.math.Quaternion;
 import com.jme3.scene.Geometry;
 import com.jme3.scene.Mesh;
 import com.jme3.scene.Node;
@@ -87,32 +85,16 @@ import com.jme3.util.BufferUtils;
                 // load skeleton
                 Structure armatureStructure = ((Pointer) armatureObject.getFieldValue("data")).fetchData(blenderContext.getInputStream()).get(0);
 
-                Structure pose = ((Pointer) armatureObject.getFieldValue("pose")).fetchData(blenderContext.getInputStream()).get(0);
-                List<Structure> chanbase = ((Structure) pose.getFieldValue("chanbase")).evaluateListBase(blenderContext);
-
-                Map<Long, Structure> bonesPoseChannels = new HashMap<Long, Structure>(chanbase.size());
-                for (Structure poseChannel : chanbase) {
-                    Pointer pBone = (Pointer) poseChannel.getFieldValue("bone");
-                    bonesPoseChannels.put(pBone.getOldMemoryAddress(), poseChannel);
-                }
-
-                Matrix4f objectToArmatureTransformation = Matrix4f.IDENTITY;
                 ObjectHelper objectHelper = blenderContext.getHelper(ObjectHelper.class);
-                
-                if(objectHelper.isLineage(armatureObject, objectStructure, blenderContext)) {
-                    boolean fixUpAxis = blenderContext.getBlenderKey().isFixUpAxis();
-	                Matrix4f armatureObjectMatrix = objectHelper.getMatrix(armatureObject, "obmat", fixUpAxis);
-	                Matrix4f inverseMeshObjectMatrix = objectHelper.getMatrix(objectStructure, "imat", fixUpAxis);
-	                objectToArmatureTransformation = armatureObjectMatrix.multLocal(inverseMeshObjectMatrix);
-	                Matrix3f rot = objectToArmatureTransformation.toRotationMatrix();
-	                objectToArmatureTransformation = new Matrix4f();
-	                objectToArmatureTransformation.setRotationQuaternion(new Quaternion().fromRotationMatrix(rot));
-                }
+                boolean fixUpAxis = blenderContext.getBlenderKey().isFixUpAxis();
+                Matrix4f armatureObjectMatrix = objectHelper.getMatrix(armatureObject, "obmat", fixUpAxis);
+                Matrix4f inverseMeshObjectMatrix = objectHelper.getMatrix(objectStructure, "imat", fixUpAxis);
+                Matrix4f objectToArmatureTransformation = armatureObjectMatrix.multLocal(inverseMeshObjectMatrix);
 
                 List<Structure> bonebase = ((Structure) armatureStructure.getFieldValue("bonebase")).evaluateListBase(blenderContext);
                 List<Bone> bonesList = new ArrayList<Bone>();
                 for (int i = 0; i < bonebase.size(); ++i) {
-                    armatureHelper.buildBones(armatureObject.getOldMemoryAddress(), bonebase.get(i), null, bonesList, objectToArmatureTransformation, bonesPoseChannels, blenderContext);
+                    armatureHelper.buildBones(armatureObject.getOldMemoryAddress(), bonebase.get(i), null, bonesList, objectToArmatureTransformation, blenderContext);
                 }
                 bonesList.add(0, new Bone(""));
                 Bone[] bones = bonesList.toArray(new Bone[bonesList.size()]);
@@ -244,7 +226,7 @@ import com.jme3.util.BufferUtils;
         }
         node.addControl(control);
         node.addControl(new SkeletonControl(animData.skeleton));
-
+        
         return node;
     }
 

+ 0 - 25
engine/src/blender/com/jme3/scene/plugins/blender/objects/ObjectHelper.java

@@ -250,31 +250,6 @@ public class ObjectHelper extends AbstractBlenderHelper {
         }
         return result;
     }
-
-    /**
-     * Method tells if the structure1 is a lineage of structure2.
-     * 
-     * @param structure1
-     *            the first structure
-     * @param structure2
-     *            the second structure
-     * @return <b>true</b> if the first structure is a lineage of the second
-     *         structure and <b>false</b> otherwise
-     * @throws BlenderFileException
-     *             thrown when problems with reading the blend file occur
-     */
-    public boolean isLineage(Structure structure1, Structure structure2, BlenderContext blenderContext) throws BlenderFileException {
-        Pointer pParent = (Pointer) structure2.getFieldValue("parent");
-        while (pParent.isNotNull()) {
-            long oma = pParent.getOldMemoryAddress();
-            if (structure1.getOldMemoryAddress().longValue() == oma) {
-                return true;
-            }
-            structure2 = blenderContext.getFileBlock(oma).getStructure(blenderContext);
-            pParent = (Pointer) structure2.getFieldValue("parent");
-        }
-        return false;
-    }
     
     /**
      * This method calculates local transformation for the object. Parentage is taken under consideration.