Fix #21224, "FBX export has object translation issues".
authorArystanbek Dyussenov <arystan.d@gmail.com>
Fri, 12 Mar 2010 16:50:52 +0000 (16:50 +0000)
committerArystanbek Dyussenov <arystan.d@gmail.com>
Fri, 12 Mar 2010 16:50:52 +0000 (16:50 +0000)
Reversed the order of all matrix multiplications to confirm to API change.

release/scripts/io/export_fbx.py

index 9f91b66c21611a76a5b4bbae2670d81feced37bc..bc1a0b82d852221f3a4d38090cbaedb7c68d9fcc 100644 (file)
@@ -545,10 +545,10 @@ def write(filename, batch_objects = None, \
             #arm_mat = self.fbxArm.parRelMatrix()
             if not self.parent:
                 #return mtx4_z90 * (self.getPoseMatrix(frame) * arm_mat) # dont apply arm matrix anymore
-                return mtx4_z90 * self.getPoseMatrix(frame)
+                return self.getPoseMatrix(frame) * mtx4_z90
             else:
                 #return (mtx4_z90 * ((self.getPoseMatrix(frame) * arm_mat)))  *  (mtx4_z90 * (self.parent.getPoseMatrix(frame) * arm_mat)).invert()
-                return (mtx4_z90 * (self.getPoseMatrix(frame)))  *  (mtx4_z90 * self.parent.getPoseMatrix(frame)).invert()
+                return (self.parent.getPoseMatrix(frame) * mtx4_z90).invert() * ((self.getPoseMatrix(frame)) * mtx4_z90)
 
         # we need thes because cameras and lights modified rotations
         def getAnimParRelMatrixRot(self, frame):
@@ -565,14 +565,14 @@ def write(filename, batch_objects = None, \
             self.blenObject = ob
             self.fbxGroupNames = []
             self.fbxParent = None # set later on IF the parent is in the selection.
-            if matrixWorld:            self.matrixWorld = matrixWorld * GLOBAL_MATRIX
-            else:                              self.matrixWorld = ob.matrix * GLOBAL_MATRIX
+            if matrixWorld:            self.matrixWorld = GLOBAL_MATRIX * matrixWorld
+            else:                              self.matrixWorld = GLOBAL_MATRIX * ob.matrix
 #                      else:                           self.matrixWorld = ob.matrixWorld * GLOBAL_MATRIX
             self.__anim_poselist = {} # we should only access this
 
         def parRelMatrix(self):
             if self.fbxParent:
-                return self.matrixWorld * self.fbxParent.matrixWorld.copy().invert()
+                return self.fbxParent.matrixWorld.copy().invert() * self.matrixWorld
             else:
                 return self.matrixWorld
 
@@ -583,24 +583,24 @@ def write(filename, batch_objects = None, \
         def getAnimParRelMatrix(self, frame):
             if self.fbxParent:
                 #return (self.__anim_poselist[frame] * self.fbxParent.__anim_poselist[frame].copy().invert() ) * GLOBAL_MATRIX
-                return (self.__anim_poselist[frame] * GLOBAL_MATRIX) * (self.fbxParent.__anim_poselist[frame] * GLOBAL_MATRIX).invert()
+                return (GLOBAL_MATRIX * self.fbxParent.__anim_poselist[frame]).invert() * (GLOBAL_MATRIX * self.__anim_poselist[frame])
             else:
-                return self.__anim_poselist[frame] * GLOBAL_MATRIX
+                return GLOBAL_MATRIX * self.__anim_poselist[frame]
 
         def getAnimParRelMatrixRot(self, frame):
             type = self.blenObject.type
             if self.fbxParent:
-                matrix_rot = (((self.__anim_poselist[frame] * GLOBAL_MATRIX) * (self.fbxParent.__anim_poselist[frame] * GLOBAL_MATRIX).invert())).rotation_part()
+                matrix_rot = ((GLOBAL_MATRIX * self.fbxParent.__anim_poselist[frame]).invert() * (GLOBAL_MATRIX * self.__anim_poselist[frame])).rotation_part()
             else:
-                matrix_rot = (self.__anim_poselist[frame] * GLOBAL_MATRIX).rotation_part()
+                matrix_rot = (GLOBAL_MATRIX * self.__anim_poselist[frame]).rotation_part()
 
             # Lamps need to be rotated
             if type =='LAMP':
-                matrix_rot = mtx_x90 * matrix_rot
+                matrix_rot = matrix_rot * mtx_x90
             elif type =='CAMERA':
 #                      elif ob and type =='Camera':
-                y = Mathutils.Vector(0,1,0) * matrix_rot
-                matrix_rot = matrix_rot * Mathutils.RotationMatrix(math.pi/2, 3, y)
+                y = matrix_rot * Mathutils.Vector(0,1,0)
+                matrix_rot = Mathutils.RotationMatrix(math.pi/2, 3, y) * matrix_rot
 
             return matrix_rot
 
@@ -666,15 +666,15 @@ def write(filename, batch_objects = None, \
 
             # we know we have a matrix
             # matrix = mtx4_z90 * (ob.matrix['ARMATURESPACE'] * matrix_mod)
-            matrix = mtx4_z90 * ob.matrix_local # dont apply armature matrix anymore
+            matrix = ob.matrix_local * mtx4_z90 # dont apply armature matrix anymore
 #                      matrix = mtx4_z90 * ob.matrix['ARMATURESPACE'] # dont apply armature matrix anymore
 
             parent = ob.parent
             if parent:
                 #par_matrix = mtx4_z90 * (parent.matrix['ARMATURESPACE'] * matrix_mod)
-                par_matrix = mtx4_z90 * parent.matrix_local # dont apply armature matrix anymore
+                par_matrix = parent.matrix_local * mtx4_z90 # dont apply armature matrix anymore
 #                              par_matrix = mtx4_z90 * parent.matrix['ARMATURESPACE'] # dont apply armature matrix anymore
-                matrix = matrix * par_matrix.copy().invert()
+                matrix = par_matrix.copy().invert() * matrix
 
             matrix_rot =       matrix.rotation_part()
 
@@ -698,11 +698,11 @@ def write(filename, batch_objects = None, \
                 matrix_rot = matrix.rotation_part()
                 # Lamps need to be rotated
                 if ob and ob.type =='Lamp':
-                    matrix_rot = mtx_x90 * matrix_rot
+                    matrix_rot = matrix_rot * mtx_x90
                     rot = tuple(matrix_rot.to_euler())
                 elif ob and ob.type =='Camera':
-                    y = Mathutils.Vector(0,1,0) * matrix_rot
-                    matrix_rot = matrix_rot * Mathutils.RotationMatrix(math.pi/2, 3, y)
+                    y = matrix_rot * Mathutils.Vector(0,1,0)
+                    matrix_rot = Mathutils.RotationMatrix(math.pi/2, 3, y) * matrix_rot
                     rot = tuple(matrix_rot.to_euler())
                 else:
                     rot = tuple(matrix_rot.to_euler())
@@ -1087,8 +1087,8 @@ def write(filename, batch_objects = None, \
         file.write('\n\t\tTypeFlags: "Camera"')
         file.write('\n\t\tGeometryVersion: 124')
         file.write('\n\t\tPosition: %.6f,%.6f,%.6f' % loc)
-        file.write('\n\t\tUp: %.6f,%.6f,%.6f' % tuple(Mathutils.Vector(0,1,0) * matrix_rot) )
-        file.write('\n\t\tLookAt: %.6f,%.6f,%.6f' % tuple(Mathutils.Vector(0,0,-1)*matrix_rot) )
+        file.write('\n\t\tUp: %.6f,%.6f,%.6f' % tuple(matrix_rot * Mathutils.Vector(0,1,0)) )
+        file.write('\n\t\tLookAt: %.6f,%.6f,%.6f' % tuple(matrix_rot * Mathutils.Vector(0,0,-1)) )
 
         #file.write('\n\t\tUp: 0,0,0' )
         #file.write('\n\t\tLookAt: 0,0,0' )
@@ -1485,10 +1485,10 @@ def write(filename, batch_objects = None, \
 
         if my_mesh.fbxParent:
             # TODO FIXME, this case is broken in some cases. skinned meshes just shouldnt have parents where possible!
-            m = mtx4_z90 * (my_bone.restMatrix * my_bone.fbxArm.matrixWorld.copy() * my_mesh.matrixWorld.copy().invert() )
+            m = (my_mesh.matrixWorld.copy().invert() * my_bone.fbxArm.matrixWorld.copy() * my_bone.restMatrix) * mtx4_z90
         else:
             # Yes! this is it...  - but dosnt work when the mesh is a.
-            m = mtx4_z90 * (my_bone.restMatrix * my_bone.fbxArm.matrixWorld.copy() * my_mesh.matrixWorld.copy().invert() )
+            m = (my_mesh.matrixWorld.copy().invert() * my_bone.fbxArm.matrixWorld.copy() * my_bone.restMatrix) * mtx4_z90
 
         #m = mtx4_z90 * my_bone.restMatrix
         matstr = mat4x4str(m)
@@ -2812,7 +2812,7 @@ Takes:  {''')
                 # Set the action active
                 for my_bone in ob_arms:
                     if blenAction in my_bone.blenActionList:
-                        ob.action = blenAction
+                        ob.animation_data.action = blenAction
                         # print '\t\tSetting Action!', blenAction
                 # scene.update(1)
 
@@ -2969,7 +2969,7 @@ Takes:  {''')
             # end action loop. set original actions
             # do this after every loop incase actions effect eachother.
             for my_bone in ob_arms:
-                my_bone.blenObject.action = my_bone.blenAction
+                my_bone.blenObject.animation_data.action = my_bone.blenAction
 
         file.write('\n}')
 
@@ -3150,9 +3150,9 @@ def fbx_ui_write(filename, context):
     # Make the matrix
     GLOBAL_MATRIX = mtx4_identity
     GLOBAL_MATRIX[0][0] = GLOBAL_MATRIX[1][1] = GLOBAL_MATRIX[2][2] = GLOBALS['_SCALE'].val
-    if GLOBALS['_XROT90'].val: GLOBAL_MATRIX = GLOBAL_MATRIX * mtx4_x90n
-    if GLOBALS['_YROT90'].val: GLOBAL_MATRIX = GLOBAL_MATRIX * mtx4_y90n
-    if GLOBALS['_ZROT90'].val: GLOBAL_MATRIX = GLOBAL_MATRIX * mtx4_z90n
+    if GLOBALS['_XROT90'].val: GLOBAL_MATRIX = mtx4_x90n * GLOBAL_MATRIX
+    if GLOBALS['_YROT90'].val: GLOBAL_MATRIX = mtx4_y90n * GLOBAL_MATRIX
+    if GLOBALS['_ZROT90'].val: GLOBAL_MATRIX = mtx4_z90n * GLOBAL_MATRIX
 
     ret = write(\
         filename, None,\
@@ -3403,9 +3403,9 @@ class ExportFBX(bpy.types.Operator):
 
         GLOBAL_MATRIX = mtx4_identity
         GLOBAL_MATRIX[0][0] = GLOBAL_MATRIX[1][1] = GLOBAL_MATRIX[2][2] = self.properties.TX_SCALE
-        if self.properties.TX_XROT90: GLOBAL_MATRIX = GLOBAL_MATRIX * mtx4_x90n
-        if self.properties.TX_YROT90: GLOBAL_MATRIX = GLOBAL_MATRIX * mtx4_y90n
-        if self.properties.TX_ZROT90: GLOBAL_MATRIX = GLOBAL_MATRIX * mtx4_z90n
+        if self.properties.TX_XROT90: GLOBAL_MATRIX = mtx4_x90n * GLOBAL_MATRIX
+        if self.properties.TX_YROT90: GLOBAL_MATRIX = mtx4_y90n * GLOBAL_MATRIX
+        if self.properties.TX_ZROT90: GLOBAL_MATRIX = mtx4_z90n * GLOBAL_MATRIX
 
         write(self.properties.path,
               None, # XXX