[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