[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [22957] trunk/blender/release/scripts/ bpymodules/colladaImEx/translator.py: This is a bugfix patch by Dmitri Sviridov to skinning and animation for Collada 1 .4 import/export

Tom Musgrove LetterRip at gmail.com
Wed Sep 2 23:57:27 CEST 2009


Revision: 22957
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=22957
Author:   letterrip
Date:     2009-09-02 23:57:27 +0200 (Wed, 02 Sep 2009)

Log Message:
-----------
This is a bugfix patch by Dmitri Sviridov to skinning and animation for Collada 1.4 import/export

Modified Paths:
--------------
    trunk/blender/release/scripts/bpymodules/colladaImEx/translator.py

Modified: trunk/blender/release/scripts/bpymodules/colladaImEx/translator.py
===================================================================
--- trunk/blender/release/scripts/bpymodules/colladaImEx/translator.py	2009-09-02 20:57:18 UTC (rev 22956)
+++ trunk/blender/release/scripts/bpymodules/colladaImEx/translator.py	2009-09-02 21:57:27 UTC (rev 22957)
@@ -6,7 +6,7 @@
 # Copyright (C) 2006: Illusoft - colladablender at illusoft.com
 #    - 2008.08: multiple bugfixes by migius (AKA Remigiusz Fiedler)
 #    - 2009.05: bugfixes by jan (AKA Jan Diederich)
-#    - 2009.08: bugfixed by nico (AKA Nicolai Wojke, Labor Bilderkennen Uni-Koblenz)
+#    - 2009.08: bugfixes by dynabyte (AKA Dmitri Sviridov, cast3d.org)
 #
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -26,14 +26,26 @@
 # --------------------------------------------------------------------------
 
 # History
-# 2009.08.22 by nico:
-# - Fixed a bug where visual scene nodes containing instances of nodes in the nodes library, 
-#   which themselves instantiate geometry in the geometry library, where not imported
-#   correctly (only the node instantiation was created, not the geometry)
-# - Fixed a bug where nodes in the nodes library that have children instantiating other
-#   nodes in the nodes library where not resolved properly. Added a post-library-creation
-#   phase where DaeInstance object references are updated after the entire library is created
-# - Changed nodes library syntax from 'library_NODES' to 'library_nodes'
+# 2009.08.11 by dynabyte ( cast3d at gmail.com, www.cast3d.org):
+# - Fixed skeleton/bone and animation. (export only). Brief change log:
+#       - Fuction Controller.SaveToDae :
+#               INV_BIND_MATRIX composition as = (bArmatureObject.matrixWorld * Bone.matrix['ARMATURESPACE']).invert() 
+#       -  Fuction ArmatrureNode.SaveToDae :
+#               - mutliple root bones handling added
+#               - return argument as list
+#       -  Fuction ArmatrureNode.BoneToDae :
+#               - local bone matrix composition as = Bone.matrix['ARMATURESPACE'] * parent_bone.matrix["ARMATURESPACE"].invert()
+#               - bone's action IPOs compiled in to list 
+#               - removed redundant function arguments
+#       -  Fuction Animation.SaveToDae : - new impementation
+#               - removed unused getEulerAnimation() function
+#               - function takes IPOs list as input argument
+#               - new function getLocalPoseMatrix added
+#       -  Fuction SceneNode.SaveSceneToDae : 
+#               - Added creation of Armature node as parent of Skeleton
+#               - Controler transforms cleaned up
+#               - Node animation handling fixedS
+#
 # 2009.05.17 by jan:
 # - More information for the user if an error happened (wrong/missing parenting).
 # - Added a progress bar for export (bar for import already exists). 
@@ -73,9 +85,10 @@
 
 import BPyMesh
 import BPyObject
+import bpy
 
 debprn = 0 #--- print debug "print 'deb: ..."
-dmitri = 0 #switch for testing patch from Dmitri
+dmitri = 1 #switch for testing patch from Dmitri
 
 class Translator(object):
 	isImporter = False
@@ -1033,7 +1046,7 @@
 		daeSkin.source = meshName
 
 		# Set the bindshapematrix
-		daeSkin.bindShapeMatrix = Matrix(bMeshObject.matrix).transpose()##bMeshObject.getMatrix('localspace').transpose()
+		daeSkin.bindShapeMatrix = Matrix(bMeshObject.matrix).transpose()
 
 		bArmatureObject = bModifier[Blender.Modifier.Settings.OBJECT]
 		if (bArmatureObject is None):
@@ -1107,6 +1120,7 @@
 
 		# Get all vertextGroups
 		vGroups = dict()
+		#print "Bone Mesh=", meshName, "vGroups= ", bMesh.getVertGroupNames()
 		for vertexGroupName in bMesh.getVertGroupNames():
 			vwsdict = vGroups[vertexGroupName] = dict()
 			try:
@@ -1132,24 +1146,16 @@
 
 ##				print
 ##				PrintTransforms(Matrix(bArmature.bones[vertexGroupName].matrix['ARMATURESPACE']).transpose().invert(), vertexGroupName)
-				if 0:
-					bindMatrix = Matrix(bArmature.bones[vertexGroupName].matrix['ARMATURESPACE']).transpose()
-					bindMatrix = Matrix(bMeshObject.matrix).transpose() * bindMatrix
-				elif dmitri:	#by dmitri: Use ARAMATURE matrix for a global position/orientation
-					bindMatrix = Matrix(bArmature.bones[vertexGroupName].matrix["ARMATURESPACE"]).resize4x4().transpose()
-					bindMatrix = Matrix(bArmatureObject.getMatrix('localspace')).transpose() * bindMatrix
-				else:
-					headPos = bArmature.bones[vertexGroupName].head["ARMATURESPACE"]
-					bindMatrix = Matrix([1,0,0,headPos.x], [0,1,0,headPos.y], [0,0,1,headPos.z],[0,0,0,1])
-					bindMatrix = Matrix(bArmatureObject.getMatrix('localspace')).transpose() * bindMatrix
-
+				#by dmitri(dynabyte): Use ARAMATURE matrix for a global position/orientation
+                                bindMatrix = Matrix(bArmature.bones[vertexGroupName].matrix["ARMATURESPACE"]).resize4x4().transpose()
+                                bindMatrix = Matrix(bArmatureObject.matrixWorld).transpose() * bindMatrix
 				invBindMatrix = Matrix(bindMatrix).invert()
+				#print "Bone =", vertexGroupName, "Final invBindMatrix= " , invBindMatrix.toEuler(), invBindMatrix.translationPart()
 				poseSourceArray.data.extend(MatrixToList(invBindMatrix))
 				poseAccessor.count += 1
 				for vert in verts:
 					weightAccessor.count += 1
 
-
 		vertJointCount = dict()
 		weightIndex = 0
 		for vert in bMesh.verts:
@@ -1299,193 +1305,99 @@
 			if t[2] == ta[0]:
 				return [t[0],ta]
 		return None
-
-	def GetEulerAnimations(self, ipo, targetDaeNode, joint=None, bPose=None, bParentMatrix=None, bArmatureObject=None):
-		curves = ipo.getCurves()
-		if not curves is None:
-			quatXList = dict()
-			quatYList = dict()
-			quatZList = dict()
-			quatWList = dict()
-
-			#collect quats
-			quatKey = dict()
-			for cur in curves:
-				curName = cur.getName()
-				if curName.startswith("Quat"):
-					quatKey[curName] = []
-					curNameIndex = curName[-1]
-					if curNameIndex == 'X':
-						for point in cur.bezierPoints:
-							quatXList[point.pt[0]] = point.pt[1]
-					elif curNameIndex == 'Y':
-						for point in cur.bezierPoints:
-							quatYList[point.pt[0]] = point.pt[1]
-					elif curNameIndex == 'Z':
-						for point in cur.bezierPoints:
-							quatZList[point.pt[0]] = point.pt[1]
-					elif curNameIndex == 'W':
-						for point in cur.bezierPoints:
-							quatWList[point.pt[0]] = point.pt[1]
-
-			quats = dict()
-			eulers = dict()
-
-			xKeyList = quatXList.keys()
-			yKeyList = quatYList.keys()
-			zKeyList = quatZList.keys()
-			wKeyList = quatWList.keys()
-
-			#Assumption: All the keys are the same!!
-			for xKey in xKeyList:
-				if not quats.has_key(xKey):
-					quats[xKey] = Quaternion()
-
-			#assign value
-			for key in xKeyList:
-				quats[key].x = quatXList[key]
-			for key in yKeyList:
-				quats[key].y = quatYList[key]
-			for key in zKeyList:
-				quats[key].z = quatZList[key]
-			for key in wKeyList:
-				quats[key].w = quatWList[key]
-
-			for key in quats:
-				euler = quats[key].toEuler()
-
-				if joint is not None:
-					if dmitri:
-						bindMatrix = Matrix(joint.matrix["ARMATURESPACE"]).resize4x4().transpose()
-					else:
-						headPos = joint.head["ARMATURESPACE"]
-						bindMatrix = Matrix([1,0,0,headPos.x], [0,1,0,headPos.y], [0,0,1,headPos.z],[0,0,0,1])
-					armMatrix = Matrix(bindMatrix)
-					if not joint.hasParent():
-						armMatrix = Matrix(bArmatureObject.getMatrix('localspace')).transpose().invert()
-						armMatrix *= bindMatrix
-
-					if 1: #migius
-						swap = euler.y
-						euler.y = - euler.z
-						euler.z = swap
-
-					else:
-						poseMatrix = Matrix(bParentMatrix).invert() * armMatrix
-						poseMatrix.transpose()
-
-						poseEuler = poseMatrix.toEuler()
-						euler.x += poseEuler.x
-						euler.y += poseEuler.y
-						euler.z += poseEuler.z
-					#if debprn: print 'deb: getEuler: ', joint.name , poseEuler, euler
-
-				eulers[key] = euler
-
-			# this nodes list of euler angles:
-			return eulers
-		return None
-
-	def SaveToDae(self, ipo, targetDaeNode, joint=None, bPose=None, bParentMatrix=None, bArmatureObject=None):
+	
+        def getLocalPoseMatrix(self, node, bArmatureObject=None):
+                if  type(node) == Blender.Types.BoneType:
+                        pose = bArmatureObject.getPose()
+                        pose_bone = pose.bones[node.name]
+                         
+                        if node.hasParent():
+                                parent_bone = node.parent
+                                pose_bone_pose = pose.bones[parent_bone.name]
+                                if not (pose_bone_pose is None):
+                                        return pose_bone.poseMatrix.copy()  *  pose_bone_pose.poseMatrix.invert()                                                        
+                        else:
+                                return pose_bone.poseMatrix.copy() 
+                else:
+                        parent = node.getParent()
+                        if parent is None:
+                               return  node.matrixWorld.copy()
+                        else:
+                               return  node.matrixWorld.copy()  *  parent.matrixWorld.copy().invert()
+                return None
+        
+	def SaveToDae(self, ipos, targetDaeNode, joint, bPose=None, bArmatureObject=None):
 		global sampleAnimation
-		animations = None
-		curves = ipo.getCurves()
-		if not curves is None:
-			animations = dict()
+		frame_orig = Blender.Get('curframe')
+         				
+                # animations for these object types		
+		animations = dict()
+		
+		for ipo, startFrame in ipos:
+			#print "Ipo=", ipo
+			curves = ipo.getCurves()
+			if not curves is None:
+				for curve in curves:
+					cName = curve.getName()
+					interpolation = curve.getInterpolation()
+					#interpolation = curve.interpolation
+					if debprn: print 'deb: interpolation=', interpolation #--------
 
-			for curve in curves:
-				cName = curve.getName()
-				interpolation = curve.getInterpolation()
-				#interpolation = curve.interpolation
-				if debprn: print 'deb: interpolation=', interpolation #--------
-				if cName.startswith("Loc") or cName.startswith("Rot") or cName.startswith("Scale"):
-					if cName.startswith("Loc"):
-						n = collada.DaeSyntax.TRANSLATE
-					elif cName.startswith("Scale"):
-						n = collada.DaeSyntax.SCALE
-					else:

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list