[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [11970] branches/2-44-stable/blender/ release/scripts/export_fbx.py: * added support for parent/child hierarchy ( see wiki docs for notes)
Campbell Barton
cbarton at metavr.com
Sat Sep 8 10:48:15 CEST 2007
Revision: 11970
http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=11970
Author: campbellbarton
Date: 2007-09-08 10:48:13 +0200 (Sat, 08 Sep 2007)
Log Message:
-----------
* added support for parent/child hierarchy (see wiki docs for notes)
* skinned meshes + armatures no longer have their matrix applied (to bones verts)
* lamps dist value is scaled by the global matrix
Modified Paths:
--------------
branches/2-44-stable/blender/release/scripts/export_fbx.py
Modified: branches/2-44-stable/blender/release/scripts/export_fbx.py
===================================================================
--- branches/2-44-stable/blender/release/scripts/export_fbx.py 2007-09-08 02:08:51 UTC (rev 11969)
+++ branches/2-44-stable/blender/release/scripts/export_fbx.py 2007-09-08 08:48:13 UTC (rev 11970)
@@ -416,16 +416,19 @@
'''
# end
- def getAnimMatrix(self, frame):
- arm_mat = self.fbxArm.matrixWorld
+ def getAnimParRelMatrix(self, frame):
+ #arm_mat = self.fbxArm.matrixWorld
+ #arm_mat = self.fbxArm.parRelMatrix()
if not self.parent:
- return mtx4_z90 * (self.getPoseMatrix(frame) * arm_mat)
+ #return mtx4_z90 * (self.getPoseMatrix(frame) * arm_mat) # dont apply arm matrix anymore
+ return mtx4_z90 * self.getPoseMatrix(frame)
else:
- return (mtx4_z90 * ((self.getPoseMatrix(frame) * arm_mat))) * (mtx4_z90 * (self.parent.getPoseMatrix(frame) * arm_mat)).invert()
+ #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()
# we need thes because cameras and lights modified rotations
- def getAnimMatrixRot(self, frame):
- return self.getAnimMatrix(frame)
+ def getAnimParRelMatrixRot(self, frame):
+ return self.getAnimParRelMatrix(frame)
def flushAnimData(self):
self.__anim_poselist.clear()
@@ -437,19 +440,33 @@
self.fbxName = sane_obname(ob)
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.matrixWorld * GLOBAL_MATRIX
- self.__anim_poselist = {}
+ self.__anim_poselist = {} # we should only access this
+ def parRelMatrix(self):
+ if self.fbxParent:
+ return self.matrixWorld * self.fbxParent.matrixWorld.copy().invert()
+ else:
+ return self.matrixWorld
+
def setPoseFrame(self, f):
self.__anim_poselist[f] = self.blenObject.matrixWorld.copy()
- def getAnimMatrix(self, frame):
- return self.__anim_poselist[frame] * GLOBAL_MATRIX
+ 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()
+ else:
+ return self.__anim_poselist[frame] * GLOBAL_MATRIX
- def getAnimMatrixRot(self, frame):
+ def getAnimParRelMatrixRot(self, frame):
type = self.blenObject.type
- matrix_rot = (self.__anim_poselist[frame] * GLOBAL_MATRIX).rotationPart()
+ if self.fbxParent:
+ matrix_rot = (((self.__anim_poselist[frame] * GLOBAL_MATRIX) * (self.fbxParent.__anim_poselist[frame] * GLOBAL_MATRIX).invert())).rotationPart()
+ else:
+ matrix_rot = (self.__anim_poselist[frame] * GLOBAL_MATRIX).rotationPart()
# Lamps need to be rotated
if type =='Lamp':
@@ -468,7 +485,11 @@
print '\nFBX export starting...', filename
start_time = Blender.sys.time()
- file = open(filename, 'w')
+ try:
+ file = open(filename, 'w')
+ except:
+ return False
+
sce = bpy.data.scenes.active
world = sce.world
@@ -513,11 +534,13 @@
if isinstance(ob, Blender.Types.BoneType):
# we know we have a matrix
- matrix = mtx4_z90 * (ob.matrix['ARMATURESPACE'] * matrix_mod)
+ # matrix = mtx4_z90 * (ob.matrix['ARMATURESPACE'] * matrix_mod)
+ 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['ARMATURESPACE'] * matrix_mod)
+ par_matrix = mtx4_z90 * parent.matrix['ARMATURESPACE'] # dont apply armature matrix anymore
matrix = matrix * par_matrix.copy().invert()
matrix_rot = matrix.rotationPart()
@@ -527,7 +550,10 @@
rot = tuple(matrix_rot.toEuler())
else:
- if ob and not matrix: matrix = ob.matrixWorld * GLOBAL_MATRIX
+ # This is bad because we need the parent relative matrix from the fbx parent (if we have one), dont use anymore
+ #if ob and not matrix: matrix = ob.matrixWorld * GLOBAL_MATRIX
+ if ob and not matrix: raise "error: this should never happen!"
+
matrix_rot = matrix
#if matrix:
# matrix = matrix_scale * matrix
@@ -666,18 +692,19 @@
file.write('\n\tModel: "Model::%s", "Limb" {' % my_bone.fbxName)
file.write('\n\t\tVersion: 232')
- poseMatrix = write_object_props(my_bone.blenBone, None, None, my_bone.fbxArm.matrixWorld)[3]
+ #poseMatrix = write_object_props(my_bone.blenBone, None, None, my_bone.fbxArm.parRelMatrix())[3]
+ poseMatrix = write_object_props(my_bone.blenBone)[3] # dont apply bone matricies anymore
pose_items.append( (my_bone.fbxName, poseMatrix) )
- # file.write('\n\t\t\tProperty: "Size", "double", "",%.6f' % ((my_bone.blenData.head['ARMATURESPACE'] - my_bone.blenData.tail['ARMATURESPACE']) * my_bone.fbxArm.matrixWorld).length)
+ # file.write('\n\t\t\tProperty: "Size", "double", "",%.6f' % ((my_bone.blenData.head['ARMATURESPACE'] - my_bone.blenData.tail['ARMATURESPACE']) * my_bone.fbxArm.parRelMatrix()).length)
file.write('\n\t\t\tProperty: "Size", "double", "",1')
- #((my_bone.blenData.head['ARMATURESPACE'] * my_bone.fbxArm.matrixWorld) - (my_bone.blenData.tail['ARMATURESPACE'] * my_bone.fbxArm.matrixWorld)).length)
+ #((my_bone.blenData.head['ARMATURESPACE'] * my_bone.fbxArm.matrixWorld) - (my_bone.blenData.tail['ARMATURESPACE'] * my_bone.fbxArm.parRelMatrix())).length)
"""
file.write('\n\t\t\tProperty: "LimbLength", "double", "",%.6f' %\
- ((my_bone.blenBone.head['ARMATURESPACE'] - my_bone.blenBone.tail['ARMATURESPACE']) * my_bone.fbxArm.matrixWorld).length)
+ ((my_bone.blenBone.head['ARMATURESPACE'] - my_bone.blenBone.tail['ARMATURESPACE']) * my_bone.fbxArm.parRelMatrix()).length)
"""
file.write('\n\t\t\tProperty: "LimbLength", "double", "",%.6f' %\
@@ -829,7 +856,7 @@
file.write('\n\tModel: "Model::%s", "Camera" {' % my_cam.fbxName )
file.write('\n\t\tVersion: 232')
- loc, rot, scale, matrix, matrix_rot = write_object_props(my_cam.blenObject)
+ loc, rot, scale, matrix, matrix_rot = write_object_props(my_cam.blenObject, None, my_cam.parRelMatrix())
file.write('\n\t\t\tProperty: "Roll", "Roll", "A+",0')
file.write('\n\t\t\tProperty: "FieldOfView", "FieldOfView", "A+",%.6f' % data.angle)
@@ -934,7 +961,7 @@
file.write('\n\tModel: "Model::%s", "Light" {' % my_light.fbxName)
file.write('\n\t\tVersion: 232')
- write_object_props(my_light.blenObject)
+ write_object_props(my_light.blenObject, None, my_light.parRelMatrix())
# Why are these values here twice?????? - oh well, follow the holy sdk's output
@@ -957,6 +984,8 @@
else:
do_light = 1
+ scale = abs(GLOBAL_MATRIX.scalePart()[0]) # scale is always uniform in this case
+
file.write('\n\t\t\tProperty: "LightType", "enum", "",%i' % light_type)
file.write('\n\t\t\tProperty: "CastLightOnObject", "bool", "",1')
file.write('\n\t\t\tProperty: "DrawVolumetricLight", "bool", "",1')
@@ -965,11 +994,11 @@
file.write('\n\t\t\tProperty: "GoboProperty", "object", ""')
file.write('\n\t\t\tProperty: "Color", "Color", "A+",1,1,1')
file.write('\n\t\t\tProperty: "Intensity", "Intensity", "A+",%.2f' % (min(light.energy*100, 200))) # clamp below 200
- file.write('\n\t\t\tProperty: "Cone angle", "Cone angle", "A+",%.2f' % light.spotSize)
+ file.write('\n\t\t\tProperty: "Cone angle", "Cone angle", "A+",%.2f' % light.spotSize * scale)
file.write('\n\t\t\tProperty: "Fog", "Fog", "A+",50')
file.write('\n\t\t\tProperty: "Color", "Color", "A",%.2f,%.2f,%.2f' % tuple(light.col))
file.write('\n\t\t\tProperty: "Intensity", "Intensity", "A+",%.2f' % (min(light.energy*100, 200))) # clamp below 200
- file.write('\n\t\t\tProperty: "Cone angle", "Cone angle", "A+",%.2f' % light.spotSize)
+ file.write('\n\t\t\tProperty: "Cone angle", "Cone angle", "A+",%.2f' % (light.spotSize * scale))
file.write('\n\t\t\tProperty: "Fog", "Fog", "A+",50')
file.write('\n\t\t\tProperty: "LightType", "enum", "",%i' % light_type)
file.write('\n\t\t\tProperty: "CastLightOnObject", "bool", "",%i' % do_light)
@@ -1009,7 +1038,7 @@
poseMatrix = write_object_props(None, None, matrixOnly)[3]
else: # all other Null's
- if my_null: poseMatrix = write_object_props(my_null.blenObject)[3]
+ if my_null: poseMatrix = write_object_props(my_null.blenObject, None, my_null.parRelMatrix())[3]
else: poseMatrix = write_object_props()[3]
pose_items.append((fbxName, poseMatrix))
@@ -1203,8 +1232,6 @@
}''')
# in the example was 'Bip01 L Thigh_2'
- #def write_sub_deformer_skin(obname, group_name, bone, me, matrix_mod):
- #def write_sub_deformer_skin(obname, group_name, bone, weights, matrix_mod):
def write_sub_deformer_skin(my_mesh, my_bone, weights):
'''
@@ -1274,8 +1301,14 @@
file.write(',%.8f' % vg[1])
i+=1
+ 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() )
+ 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 = mtx4_z90 * (my_bone.restMatrix * my_bone.fbxArm.matrixWorld)
+ #m = mtx4_z90 * my_bone.restMatrix
matstr = mat4x4str(m)
matstr_i = mat4x4str(m.invert())
@@ -1298,27 +1331,8 @@
file.write('\n\tModel: "Model::%s", "Mesh" {' % my_mesh.fbxName)
file.write('\n\t\tVersion: 232') # newline is added in write_object_props
- if my_mesh.fbxArm:
- if my_mesh.origData:
- do_tx_write = True
- else:
- do_tx_write = False
- me.transform(my_mesh.matrixWorld)
-
- else:
- do_tx_write = False
+ write_object_props(my_mesh.blenObject, None, my_mesh.parRelMatrix())
-
- # When we have an armature...
- if my_mesh.fbxArm:
- # Apply the mesh matrix because bones arnt applied correctly if we use object transformation
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list