[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [11760] trunk/blender/release/scripts/ export_fbx.py: FBX armature + mesh + weights works now.

Campbell Barton cbarton at metavr.com
Tue Aug 21 01:38:39 CEST 2007


Revision: 11760
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=11760
Author:   campbellbarton
Date:     2007-08-21 01:38:39 +0200 (Tue, 21 Aug 2007)

Log Message:
-----------
FBX armature + mesh + weights works now.
So it can be used to export walk cycles etc.
Animated armatures also work (import BVH and export as FBX for instance)

Pose data is transformation is key'd on every frame at the moment, so IK's and constraints are applied but blenders keyframes are not used.

at the moment one armature applied multiple meshes wont work properly and armatures cant have transformation.

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-20 22:38:10 UTC (rev 11759)
+++ trunk/blender/release/scripts/export_fbx.py	2007-08-20 23:38:39 UTC (rev 11760)
@@ -1,7 +1,7 @@
 #!BPY
 """
 Name: 'Autodesk FBX (.fbx)...'
-Blender: 243
+Blender: 244
 Group: 'Export'
 Tooltip: 'Selection to an ASCII Autodesk FBX '
 """
@@ -18,7 +18,6 @@
 All objects that can be represented as a mesh (mesh, curve, metaball, surface, text3d)
 will be exported as mesh data.
 """
-
 # --------------------------------------------------------------------------
 # FBX Export v0.1 by Campbell Barton (AKA Ideasman)
 # --------------------------------------------------------------------------
@@ -50,7 +49,6 @@
 from math import degrees, atan, pi
 from Blender.Mathutils import Matrix, Vector, Euler, RotationMatrix, TranslationMatrix
 
-
 mtx_z90 = RotationMatrix(90, 3, 'z')
 mtx_x90 = RotationMatrix(90, 3, 'x')
 
@@ -77,12 +75,32 @@
 ZVEC  = Vector(0, 0,  1)
 ZVECN = Vector(0, 0, -1)
 
+ROT_ORDER = [\
+(0,1,2),\
+(1,2,0),\
+(2,0,1),\
+(2,1,0),\
+(1,0,2),\
+(0,2,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 = {}
 
+# Change the order rotation is applied.
+MATRIX_IDENTITY_3x3 = Matrix([1,0,0],[0,1,0],[0,0,1])
+MATRIX_IDENTITY_4x4 = Matrix([1,0,0,0],[0,1,0,0],[0,0,1,0],[0,0,0,1])
+
+def eulerRotate(x,y,z, rot_order): 
+	# Clamp all values between 0 and 360, values outside this raise an error.
+	mats=[RotationMatrix(x%360,3,'x'), RotationMatrix(y%360,3,'y'), RotationMatrix(z%360,3,'z')]
+	# print rot_order
+	# Standard BVH multiplication order, apply the rotation in the order Z,X,Y
+	return (mats[rot_order[2]]*(mats[rot_order[1]]* (mats[rot_order[0]]* MATRIX_IDENTITY_3x3))).toEuler()
+
 def strip_path(p):
 	return p.split('\\')[-1].split('/')[-1]
 
@@ -139,7 +157,7 @@
 	
 	# get pose from frame.
 	def getPoseMatrix(self, f):
-		#return mtx4_z90 * self.__pose_bone.poseMatrix
+		#return mtx4_z90 * self.__pose_bone.poseMatrix.copy()
 		#return self.__pose_bone.poseMatrix.copy()
 		return self.__anim_poselist[f][0].copy()
 	def getPoseHead(self, f):
@@ -170,106 +188,58 @@
 		else:
 			return self.getPoseMatrix(frame)
 	
+	def getPoseMatrixTip(self, frame):
+		vec = self.getPoseHead(frame) - self.getPoseTail(frame)
+		return TranslationMatrix(vec) * self.getPoseMatrix(frame)
+	
+	# This works in 1 test but not for all
+	
 	def getPoseMatrixLocal_RestRelative(self, frame):
 		
 		matrix= self.getPoseMatrix(frame)
 		rest_matrix = self.restMatrix.copy()
 		
 		if self.parent:
-			matrix=						matrix * self.parent.getPoseMatrix(frame).invert()
+			#matrix=						matrix * self.parent.getPoseMatrix(frame).invert()
+			matrix=						matrix * self.parent.getPoseMatrixTip(frame).invert()
 			rest_matrix=				rest_matrix * self.parent.restMatrixInv
-			rest_matrix = mtx4_x90n * rest_matrix
+			rest_matrix = mtx4_x90 * rest_matrix
 		else:
-			rest_matrix = mtx4_z90 * rest_matrix
+			rest_matrix = mtx4_z90n * 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):
+	def getPoseMatrix_RestRelative(self, frame):
+		return self.getPoseMatrix(frame) * self.restMatrix.copy().invert()
 		
-		# return mtx4_z90 * self.getPoseMatrix(frame)
+	def getPoseMatrix_RestRelative_ZROT(self, frame):
+		# Works for rest bones with no loc/size/rot
+		# but failes othwrwise.
+		return (mtx4_z90 * self.getPoseMatrix(frame)) * (mtx4_z90 * self.restMatrix.copy()).invert()
 		
-		#if not self.parent:
-		#	return mtx4_z90 * self.getPoseMatrix()
+		v = Vector(0,0,1) * self.restMatrix.copy().invert().rotationPart()
+		rest_z90 = RotationMatrix(90, 4, 'r', v)
 		
-		#return (mtx4_z90n * self.getPoseMatrixLocal()).invert()
-		#return mtx4_z90n * self.getPoseMatrixLocal_RestRelative()
-		#mod = Euler(90,0,90).toMatrix().resize4x4()
+		return (mtx4_z90 * self.getPoseMatrix(frame)) * (rest_z90 * self.restMatrix.copy()).invert()
 		
-		# 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 = [\
-(0,1,2),\
-(1,2,0),\
-(2,0,1),\
-(2,1,0),\
-(1,0,2),\
-(0,2,1),\
-]
-MATRIX_IDENTITY_3x3 = Matrix([1,0,0],[0,1,0],[0,0,1])
-MATRIX_IDENTITY_4x4 = Matrix([1,0,0,0],[0,1,0,0],[0,0,1,0],[0,0,0,1])
-
-def eulerRotate(x,y,z, rot_order): 
-	# Clamp all values between 0 and 360, values outside this raise an error.
-	mats=[RotationMatrix(x%360,3,'x'), RotationMatrix(y%360,3,'y'), RotationMatrix(z%360,3,'z')]
-	# print rot_order
-	# Standard BVH multiplication order, apply the rotation in the order Z,X,Y
-	return (mats[rot_order[2]]*(mats[rot_order[1]]* (mats[rot_order[0]]* MATRIX_IDENTITY_3x3))).toEuler()
+	def getSomeMatrix2(self, frame):
+		return self.getPoseMatrixLocal(frame) * self.restMatrixLocal.copy()
 	
-def eulerMat(mat, rot_order): 
-	x,y,z = tuple(mat.toEuler())
-	# Clamp all values between 0 and 360, values outside this raise an error.
-	mats=[RotationMatrix(x%360,3,'x'), RotationMatrix(y%360,3,'y'), RotationMatrix(z%360,3,'z')]
-	# print rot_order
-	# Standard BVH multiplication order, apply the rotation in the order Z,X,Y
-	return mats[rot_order[2]]*(mats[rot_order[1]]* (mats[rot_order[0]]* MATRIX_IDENTITY_3x3))
-'''
+	def getAnimMatrix(self, frame):
+		if not self.parent:
+			return mtx4_z90 * self.getPoseMatrix(frame)
+		else:
+			return (mtx4_z90 * self.getPoseMatrix(frame)) * (mtx4_z90 * self.parent.getPoseMatrix(frame)).invert()
 
 
-
-
 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 ])
-	
-# May use this later
-"""
-# Auto class, use for datastorage only, a like a dictionary but with limited slots
-def auto_class(slots):
-	exec('class container_class(object): __slots__=%s' % slots)
-	return container_class
-"""
 
 
 header_comment = \
 '''; FBX 6.1.0 project file
 ; Created by Blender FBX Exporter
-; for support mail cbarton at metavr.com
+; for support mail: ideasman42 at gmail.com
 ; ----------------------------------------------------
 
 '''
@@ -302,9 +272,10 @@
 	file.write('\nCreator: "Blender3D version %.2f"' % Blender.Get('version'))
 
 
-
-
-def write_scene(file, sce, world):
+def write_scene(file, sce, world,\
+		EXPORT_APPLY_MODIFIERS=False,\
+		EXPORT_ANIMATION=True,\
+		EXPORT_NORMALS_HQ=False):
 	
 	def object_tx(ob, loc, matrix, matrix_mod = None):
 		'''
@@ -379,15 +350,15 @@
 		
 		loc, rot, scale, matrix, matrix_rot = write_object_tx(ob, loc, matrix, matrix_mod)
 		
-		# Rotation order
-		# eEULER_XYZ
+		# Rotation order, note, for FBX files Iv loaded normal order is 1
+		# setting to zero.
+		# eEULER_XYZ = 0
 		# eEULER_XZY
 		# eEULER_YZX
 		# eEULER_YXZ
 		# eEULER_ZXY
-		# eEULER_ZYX 
+		# eEULER_ZYX
 		
-		
 		file.write('''
 			Property: "RotationOffset", "Vector3D", "",0,0,0
 			Property: "RotationPivot", "Vector3D", "",0,0,0
@@ -402,7 +373,7 @@
 			Property: "TranslationMaxX", "bool", "",0
 			Property: "TranslationMaxY", "bool", "",0
 			Property: "TranslationMaxZ", "bool", "",0
-			Property: "RotationOrder", "enum", "",1
+			Property: "RotationOrder", "enum", "",0
 			Property: "RotationSpaceForLimitOnly", "bool", "",0
 			Property: "AxisLen", "double", "",10
 			Property: "PreRotation", "Vector3D", "",0,0,0
@@ -463,15 +434,15 @@
 	
 	# -------------------------------------------- Armatures
 	def write_bone(bone, name, matrix_mod):
-		file.write('\n\tModel: "Model::%s", "LimbNode" {' % name)
+		file.write('\n\tModel: "Model::%s", "Limb" {' % name)
 		file.write('\n\t\tVersion: 232')
 		
 		write_object_props(bone, None, None, matrix_mod)
 		
-		file.write('\n\t\t\tProperty: "Size", "double", "",%.6f' % ((bone.head['ARMATURESPACE']-bone.tail['ARMATURESPACE']) * matrix_mod).length)
-		#file.write('\n\t\t\tProperty: "Size", "double", "",1')
-		#file.write('\n\t\t\tProperty: "LimbLength", "double", "",%.6f' % (bone.head['ARMATURESPACE']-bone.tail['ARMATURESPACE']).length)
-		file.write('\n\t\t\tProperty: "LimbLength", "double", "",1')
+		#file.write('\n\t\t\tProperty: "Size", "double", "",%.6f' % ((bone.head['ARMATURESPACE']-bone.tail['ARMATURESPACE']) * matrix_mod).length)
+		file.write('\n\t\t\tProperty: "Size", "double", "",1')
+		file.write('\n\t\t\tProperty: "LimbLength", "double", "",%.6f' % (bone.head['ARMATURESPACE']-bone.tail['ARMATURESPACE']).length)
+		#file.write('\n\t\t\tProperty: "LimbLength", "double", "",1')
 		file.write('\n\t\t\tProperty: "Color", "ColorRGB", "",0.8,0.8,0.8')
 		file.write('\n\t\t\tProperty: "Color", "Color", "A",0.8,0.8,0.8')
 		file.write('\n\t\t}')
@@ -849,11 +820,11 @@
 			file.write('\n\t\t\tProperty: "ShininessExponent", "double", "",80.0')
 			file.write('\n\t\t\tProperty: "ReflectionColor", "ColorRGB", "",0,0,0')
 			file.write('\n\t\t\tProperty: "ReflectionFactor", "double", "",1')
-		file.write('\n\t\t\tProperty: "Emissive", "Vector3D", "",0,0,0')
-		file.write('\n\t\t\tProperty: "Ambient", "Vector3D", "",%.1f,%.1f,%.1f' % mat_colamb)
-		file.write('\n\t\t\tProperty: "Diffuse", "Vector3D", "",%.1f,%.1f,%.1f' % mat_cold)
+		file.write('\n\t\t\tProperty: "Emissive", "ColorRGB", "",0,0,0')
+		file.write('\n\t\t\tProperty: "Ambient", "ColorRGB", "",%.1f,%.1f,%.1f' % mat_colamb)
+		file.write('\n\t\t\tProperty: "Diffuse", "ColorRGB", "",%.1f,%.1f,%.1f' % mat_cold)
 		if not mat_shadeless:

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list