[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [11606] trunk/blender/release/scripts/ export_fbx.py: initial support for baked bone animation - works for simple tests

Campbell Barton cbarton at metavr.com
Wed Aug 15 02:48:34 CEST 2007


Revision: 11606
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=11606
Author:   campbellbarton
Date:     2007-08-15 02:48:33 +0200 (Wed, 15 Aug 2007)

Log Message:
-----------
initial support for baked bone animation - works for simple tests

Modified Paths:
--------------
    trunk/blender/release/scripts/export_fbx.py

Modified: trunk/blender/release/scripts/export_fbx.py
===================================================================
--- trunk/blender/release/scripts/export_fbx.py	2007-08-14 22:42:21 UTC (rev 11605)
+++ trunk/blender/release/scripts/export_fbx.py	2007-08-15 00:48:33 UTC (rev 11606)
@@ -48,10 +48,180 @@
 import BPyMessages
 import time
 from math import degrees, atan, pi
-from Blender.Mathutils import Matrix, Vector, Euler, RotationMatrix
+from Blender.Mathutils import Matrix, Vector, Euler, RotationMatrix, TranslationMatrix
 
 
+mtx_z90 = RotationMatrix(90, 3, 'z')
+mtx_x90 = RotationMatrix(90, 3, 'x')
 
+# testing
+mtx_x90		= RotationMatrix( 90, 3, 'x')
+mtx_x90n	= RotationMatrix(-90, 3, 'x')
+mtx_y90		= RotationMatrix( 90, 3, 'y')
+mtx_y90n	= RotationMatrix(-90, 3, 'y')
+mtx_z90		= RotationMatrix( 90, 3, 'z')
+mtx_z90n	= RotationMatrix(-90, 3, 'z')
+
+
+mtx4_x90	= RotationMatrix( 90, 4, 'x')
+mtx4_x90n	= RotationMatrix(-90, 4, 'x')
+mtx4_y90	= RotationMatrix( 90, 4, 'y')
+mtx4_y90n	= RotationMatrix(-90, 4, 'y')
+mtx4_z90	= RotationMatrix( 90, 4, 'z')
+mtx4_z90n	= RotationMatrix(-90, 4, 'z')
+
+XVEC  = Vector(1,  0, 0)
+XVECN = Vector(-1, 0, 0)
+YVEC  = Vector(0,  1, 0)
+YVECN = Vector(0, -1, 0)
+ZVEC  = Vector(0, 0,  1)
+ZVECN = Vector(0, 0, -1)
+
+# Used to add the scene name into the filename without using odd chars
+
+sane_name_mapping_ob = {}
+sane_name_mapping_mat = {}
+sane_name_mapping_tex = {}
+
+def strip_path(p):
+	return p.split('\\')[-1].split('/')[-1]
+
+# todo - Disallow the name 'Scene' and 'blend_root' - it will bugger things up.
+def sane_name(data, dct):
+	if not data: return None
+	name = data.name
+	try:		return dct[name]
+	except:		pass
+	
+	orig_name = name
+	name = BPySys.cleanName(name)
+	dct[orig_name] = name
+	return name
+
+def sane_obname(data):		return sane_name(data, sane_name_mapping_ob)
+def sane_matname(data):		return sane_name(data, sane_name_mapping_mat)
+def sane_texname(data):		return sane_name(data, sane_name_mapping_tex)
+
+
+# storage classes
+class my_bone_class:
+	def __init__(self, blenBone, blenArmature, blenMesh, fbxObName):
+		self.blenName =			blenBone.name
+		self.blenBone =			blenBone
+		self.blenBoneParent =	blenBone.parent
+		self.blenMesh =			blenMesh
+		self.blenArmature =		blenArmature
+		self.restMatrix =		blenBone.matrix['ARMATURESPACE']
+		self.restMatrixInv =	self.restMatrix.copy().invert()
+		self.restMatrixLocal =	None # set later, need parent matrix
+		self.parent =			None
+		self.fbxName =			sane_obname(blenBone)
+		self.fbxObName =		fbxObName
+		
+		# not public
+		pose = blenArmature.getPose()
+		self.__pose_bone =		pose.bones[self.blenName]
+		self.__bone_parent =	blenBone.parent
+		self.__anim_poselist = {} # store a list if matricies here, (poseMatrix, head, tail)
+	
+	def calcRestMatrixLocal(self):
+		if self.parent:
+			self.restMatrixLocal = self.restMatrix * self.parent.restMatrix.copy().invert()
+		else:
+			self.restMatrixLocal = self.restMatrix.copy()
+	
+	def setPoseFrame(self, f):
+		# cache pose info here, frame must be set beforehand
+		self.__anim_poselist[f] = (\
+			self.__pose_bone.poseMatrix.copy(),\
+			self.__pose_bone.head.copy(),\
+			self.__pose_bone.tail.copy() )
+	
+	# get pose from frame.
+	def getPoseMatrix(self, f):
+		#return mtx4_z90 * self.__pose_bone.poseMatrix
+		#return self.__pose_bone.poseMatrix.copy()
+		return self.__anim_poselist[f][0].copy()
+	def getPoseHead(self, f):
+		#return self.__pose_bone.head.copy()
+		return self.__anim_poselist[f][1].copy()
+	def getPoseTail(self, f):
+		#return self.__pose_bone.tail.copy()
+		return self.__anim_poselist[f][2].copy()
+	# end
+
+	def getPoseMatrixLocal(self, frame):
+		if self.parent:
+			return self.getPoseMatrix(frame) * self.parent.getPoseMatrix(frame).invert()
+		else:
+			return self.getPoseMatrix(frame)
+		#return mtx4_z90 * mat
+	
+	def getPoseMatrixLocalTip(self):
+		#print "ASAS"
+		if self.parent:
+			
+			vec = self.parent.getPoseTail(frame) - self.parent.getPoseHead(frame)
+			#vec = self.parent.getPoseHead(frame) - self.parent.getPoseTail(frame)
+			mat = TranslationMatrix(vec) * self.parent.getPoseMatrix(frame)
+			#mat = self.parent.getPoseMatrix() * TranslationMatrix(vec).invert()
+			#print "  ASAS"
+			return mat * self.getPoseMatrix(frame)
+		else:
+			return self.getPoseMatrix(frame)
+	
+	def getPoseMatrixLocal_RestRelative(self, frame):
+		
+		matrix= self.getPoseMatrix(frame)
+		rest_matrix = self.restMatrix.copy()
+		
+		if self.parent:
+			matrix=						matrix * self.parent.getPoseMatrix(frame).invert()
+			rest_matrix=				rest_matrix * self.parent.restMatrixInv
+			rest_matrix = mtx4_x90n * rest_matrix
+		else:
+			rest_matrix = mtx4_z90 * rest_matrix
+		
+		# print rest_matrix.toEuler()
+		return matrix * rest_matrix.invert()
+	
+	def getSomeMatrix(self, frame):
+		return self.restMatrixLocal * self.getPoseMatrixLocal(frame).invert()
+	
+	def getSomeMatrix2(self, frame):
+		return self.getPoseMatrixLocal(frame) * self.restMatrixLocal.copy()
+	
+	def getAnimMatrix(self, frame):
+		
+		# return mtx4_z90 * self.getPoseMatrix(frame)
+		
+		#if not self.parent:
+		#	return mtx4_z90 * self.getPoseMatrix()
+		
+		#return (mtx4_z90n * self.getPoseMatrixLocal()).invert()
+		#return mtx4_z90n * self.getPoseMatrixLocal_RestRelative()
+		#mod = Euler(90,0,90).toMatrix().resize4x4()
+		
+		# Verry good except initial rotations are wrong.
+		# attempt to seperate the rotation and translation 
+		#return mtx4_z90 * (mtx4_x90 * (mtx4_y90 * self.getPoseMatrixLocal_RestRelative(frame)))
+		#return mtx4_z90 * (mtx4_y90 * self.getPoseMatrixLocal_RestRelative())
+		#return mtx4_x90 * (mtx4_y90 * ( mtx4_z90 * self.getPoseMatrixLocal_RestRelative(frame)))
+		return mtx4_z90 * self.getPoseMatrixLocal_RestRelative(frame)
+		
+		'''
+		mat = self.getPoseMatrixLocal_RestRelative()
+		tx = (mtx4_z90 * (mtx4_x90 * (mtx4_y90 * mat))).translationPart()
+		mat = TranslationMatrix(tx) * mat.rotationPart().resize4x4()
+		return mat
+		'''
+	def getAnimMatrixRot(self, frame):
+		#return self.getPoseMatrixLocal_RestRelative()
+		return self.getAnimMatrix(frame)
+		#return Matrix()
+
+
+
 # Change the order rotation is applied.
 '''
 ROT_ORDER = [\
@@ -83,31 +253,7 @@
 
 
 
-# Used to add the scene name into the filename without using odd chars
 
-sane_name_mapping_ob = {}
-sane_name_mapping_mat = {}
-sane_name_mapping_tex = {}
-
-def strip_path(p):
-	return p.split('\\')[-1].split('/')[-1]
-
-# todo - Disallow the name 'Scene' and 'blend_root' - it will bugger things up.
-def sane_name(data, dct):
-	if not data: return None
-	name = data.name
-	try:		return dct[name]
-	except:		pass
-	
-	orig_name = name
-	name = BPySys.cleanName(name)
-	dct[orig_name] = name
-	return name
-
-def sane_obname(data):		return sane_name(data, sane_name_mapping_ob)
-def sane_matname(data):		return sane_name(data, sane_name_mapping_mat)
-def sane_texname(data):		return sane_name(data, sane_name_mapping_tex)
-
 def mat4x4str(mat):
 	return '%.15f,%.15f,%.15f,%.15f,%.15f,%.15f,%.15f,%.15f,%.15f,%.15f,%.15f,%.15f,%.15f,%.15f,%.15f,%.15f' % tuple([ f for v in mat for f in v ])
 	
@@ -157,32 +303,7 @@
 
 
 
-mtx_z90 = RotationMatrix(90, 3, 'z')
-mtx_x90 = RotationMatrix(90, 3, 'x')
 
-# testing
-mtx_x90		= RotationMatrix( 90, 3, 'x')
-mtx_x90n	= RotationMatrix(-90, 3, 'x')
-mtx_y90		= RotationMatrix( 90, 3, 'y')
-mtx_y90n	= RotationMatrix(-90, 3, 'y')
-mtx_z90		= RotationMatrix( 90, 3, 'z')
-mtx_z90n	= RotationMatrix(-90, 3, 'z')
-
-
-mtx4_x90	= RotationMatrix( 90, 4, 'x')
-mtx4_x90n	= RotationMatrix(-90, 4, 'x')
-mtx4_y90	= RotationMatrix( 90, 4, 'y')
-mtx4_y90n	= RotationMatrix(-90, 4, 'y')
-mtx4_z90	= RotationMatrix( 90, 4, 'z')
-mtx4_z90n	= RotationMatrix(-90, 4, 'z')
-
-XVEC  = Vector(1,  0, 0)
-XVECN = Vector(-1, 0, 0)
-YVEC  = Vector(0,  1, 0)
-YVECN = Vector(0, -1, 0)
-ZVEC  = Vector(0, 0,  1)
-ZVECN = Vector(0, 0, -1)
-
 def write_scene(file, sce, world):
 	
 	def object_tx(ob, loc, matrix, matrix_mod = None):
@@ -665,16 +786,10 @@
 		Culling: "CullingOff"
 		TypeFlags: "Null"
 	}''')
-		
-		
 	
-	
-	
 	# Material Settings
-	if world:
-		world_amb = world.getAmb()
-	else:
-		world_amb = (0,0,0) # Default value
+	if world:	world_amb = world.getAmb()
+	else:		world_amb = (0,0,0) # Default value
 	
 	def write_material(matname, mat):
 		file.write('\n\tMaterial: "Material::%s", "" {' % matname)
@@ -828,8 +943,7 @@
 		Texture_Alpha_Source: "None"
 		Cropping: 0,0,0,0
 	}''')
-	
-	
+
 	def write_deformer_skin(obname):
 		file.write('\n\tDeformer: "Deformer::Skin %s", "Skin" {' % obname)
 		file.write('''
@@ -896,222 +1010,8 @@
 		file.write('\n\t\tTransformLink: %s' % matstr)
 		file.write('\n\t}')
 	
-	ob_meshes = []
-	ob_lights = []
-	ob_cameras = []
-	# in fbx we export bones as children of the mesh
-	# armatures not a part of a mesh, will be added to ob_arms
-	ob_bones = [] 
-	ob_arms = []
-	ob_null = [] # emptys
-	materials = {}
-	textures = {}
-	
-	ob_type = None # incase no objects are exported, so as not to raise an error
-	
-	for ob_base in sce.objects.context:
-		for ob, mtx in BPyObject.getDerivedObjects(ob_base):
-			#for ob in [ob_base,]:
-			ob_type = ob.type
-			if ob_type == 'Camera':
-				ob_cameras.append((sane_obname(ob), ob))
-			elif ob_type == 'Lamp':
-				ob_lights.append((sane_obname(ob), ob))
-			elif ob_type == 'Armature':
-				#ob_arms.append(sane_obname(ob), ob)
-				ob_arms.append(ob) # replace later.
-			elif ob_type == 'Empty':
-				ob_null.append((sane_obname(ob), ob))
-			else:
-				if ob_type == 'Mesh':	me = ob.getData(mesh=1)
-				else:					me = BPyMesh.getMeshFromObject(ob)
-				
-				if me:
-					mats = me.materials
-					for mat in mats:
-						# 2.44 use mat.lib too for uniqueness
-						if mat: materials[mat.name] = mat
-					
-					if me.faceUV:
-						uvlayer_orig = me.activeUVLayer
-						for uvlayer in me.getUVLayerNames():
-							me.activeUVLayer = uvlayer
-							for f in me.faces:
-								img = f.image
-								if img: textures[img.name] = img
-							
-							me.activeUVLayer = uvlayer_orig
-					
-					obname = sane_obname(ob)
-					
-					armob = BPyObject.getObjectArmature(ob)
-					
-					if armob:
-						armname = sane_obname(armob)
-						bones = armob.data.bones.values()
-						# armatures.append((arm, armname, bones))
-						# arm_name = BPySys.cleanName(arm.name)
-						
-						for bone in bones:
-							#name = sane_obname(arm_name + ' ' + b.name)
-							ob_bones.append( (sane_obname(bone), bone, obname, me, armob) )
-					else:
-						armname = None
-					

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list