|
|
@@ -1,119 +1,167 @@
|
|
|
-from common import *
|
|
|
import sys
|
|
|
-reload( sys.modules["common"] )
|
|
|
+import os
|
|
|
+from copy import deepcopy
|
|
|
+from Blender import Mathutils
|
|
|
+from Blender.Mathutils import *
|
|
|
+import Blender
|
|
|
|
|
|
|
|
|
+#=======================================================================================================================
|
|
|
+# multMatrix =
|
|
|
+#=======================================================================================================================
|
|
|
+def multMatrix(m, b):
|
|
|
+ c = Matrix()
|
|
|
+ c[0][0] = m[0][0]*b[0][0] + m[0][1]*b[1][0] + m[0][2]*b[2][0] + m[0][3]*b[3][0]
|
|
|
+ c[0][1] = m[0][0]*b[0][1] + m[0][1]*b[1][1] + m[0][2]*b[2][1] + m[0][3]*b[3][1]
|
|
|
+ c[0][2] = m[0][0]*b[0][2] + m[0][1]*b[1][2] + m[0][2]*b[2][2] + m[0][3]*b[3][2]
|
|
|
+ c[0][3] = m[0][0]*b[0][3] + m[0][1]*b[1][3] + m[0][2]*b[2][3] + m[0][3]*b[3][3]
|
|
|
+ c[1][0] = m[1][0]*b[0][0] + m[1][1]*b[1][0] + m[1][2]*b[2][0] + m[1][3]*b[3][0]
|
|
|
+ c[1][1] = m[1][0]*b[0][1] + m[1][1]*b[1][1] + m[1][2]*b[2][1] + m[1][3]*b[3][1]
|
|
|
+ c[1][2] = m[1][0]*b[0][2] + m[1][1]*b[1][2] + m[1][2]*b[2][2] + m[1][3]*b[3][2]
|
|
|
+ c[1][3] = m[1][0]*b[0][3] + m[1][1]*b[1][3] + m[1][2]*b[2][3] + m[1][3]*b[3][3]
|
|
|
+ c[2][0] = m[2][0]*b[0][0] + m[2][1]*b[1][0] + m[2][2]*b[2][0] + m[2][3]*b[3][0]
|
|
|
+ c[2][1] = m[2][0]*b[0][1] + m[2][1]*b[1][1] + m[2][2]*b[2][1] + m[2][3]*b[3][1]
|
|
|
+ c[2][2] = m[2][0]*b[0][2] + m[2][1]*b[1][2] + m[2][2]*b[2][2] + m[2][3]*b[3][2]
|
|
|
+ c[2][3] = m[2][0]*b[0][3] + m[2][1]*b[1][3] + m[2][2]*b[2][3] + m[2][3]*b[3][3]
|
|
|
+ c[3][0] = m[3][0]*b[0][0] + m[3][1]*b[1][0] + m[3][2]*b[2][0] + m[3][3]*b[3][0]
|
|
|
+ c[3][1] = m[3][0]*b[0][1] + m[3][1]*b[1][1] + m[3][2]*b[2][1] + m[3][3]*b[3][1]
|
|
|
+ c[3][2] = m[3][0]*b[0][2] + m[3][1]*b[1][2] + m[3][2]*b[2][2] + m[3][3]*b[3][2]
|
|
|
+ c[3][3] = m[3][0]*b[0][3] + m[3][1]*b[1][3] + m[3][2]*b[2][3] + m[3][3]*b[3][3]
|
|
|
+ return c
|
|
|
|
|
|
|
|
|
-#===================================================================================================
|
|
|
-# GetSkeleton =
|
|
|
-#===================================================================================================
|
|
|
-def GetSkeleton( obj ):
|
|
|
+#=======================================================================================================================
|
|
|
+# rotateMatrix =
|
|
|
+#=======================================================================================================================
|
|
|
+rotMat = Matrix()
|
|
|
+rotMat[0][0] = 1.0
|
|
|
+rotMat[0][1] = 0.0
|
|
|
+rotMat[0][2] = 0.0
|
|
|
+rotMat[0][3] = 0.0
|
|
|
+rotMat[1][0] = 0.0
|
|
|
+rotMat[1][1] = 0.0
|
|
|
+rotMat[1][2] = 1.0
|
|
|
+rotMat[1][3] = 0.0
|
|
|
+rotMat[2][0] = 0.0
|
|
|
+rotMat[2][1] = -1.0
|
|
|
+rotMat[2][2] = 0.0
|
|
|
+rotMat[2][3] = 0.0
|
|
|
+rotMat[3][0] = 0.0
|
|
|
+rotMat[3][1] = 0.0
|
|
|
+rotMat[3][2] = 0.0
|
|
|
+rotMat[3][3] = 1.0
|
|
|
+
|
|
|
+
|
|
|
+#=======================================================================================================================
|
|
|
+# Initializer =
|
|
|
+#=======================================================================================================================
|
|
|
+class Initializer:
|
|
|
+ def __init__(self):
|
|
|
+ self.blSkeleton = None # Blender Armature
|
|
|
+ self.saveDir = "" # the name of the saved file
|
|
|
+ self.flipYZ = 0 #convert from bl to right handed coord system
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+#======================================================================================================================
|
|
|
+# getBlSkeletonFromBlObj =
|
|
|
+#=======================================================================================================================
|
|
|
+def getBlSkeletonFromBlObj(obj):
|
|
|
# check if obj is correct class
|
|
|
- if( obj.__class__.__name__ != "Blender Object" ):
|
|
|
- ERROR( "The given func param is not a \"Blender Object\" class but a \"" + obj.__class__.__name__ + "\"" )
|
|
|
- return 0
|
|
|
+ if(obj.__class__.__name__ != "Blender Object"):
|
|
|
+ raise RuntimeError("The given func param is not a \"Blender Object\" class but a \"" + obj.__class__.__name__ + "\"")
|
|
|
|
|
|
# check modifiers
|
|
|
if len(obj.modifiers) < 1:
|
|
|
- ERROR( "Obj \"" + obj.getName() + "\" doesnt have modifiers so no armature found" )
|
|
|
- return 0
|
|
|
+ raise RuntimeError("Obj \"" + obj.getName() + "\" doesnt have modifiers so no armature found")
|
|
|
|
|
|
# search for modifier of skeleton type
|
|
|
for mod in obj.modifiers:
|
|
|
if mod.type == Blender.Modifier.Types.ARMATURE:
|
|
|
aobj = mod[Blender.Modifier.Settings.OBJECT]
|
|
|
- skeleton = Blender.Object.Get( aobj.name ).getData( 0, 1 ) # set skeleton
|
|
|
+ skeleton = Blender.Object.Get(aobj.name).getData(0, 1) # set skeleton
|
|
|
return skeleton
|
|
|
|
|
|
- ERROR( "Obj \"" + obj.getName() + "\" has no modifier of type armature" )
|
|
|
- return 0
|
|
|
+ raise RuntimeError("Obj \"" + obj.getName() + "\" has no modifier of type armature")
|
|
|
|
|
|
|
|
|
|
|
|
-#===================================================================================================
|
|
|
-# ScriptSkeleton =
|
|
|
-#===================================================================================================
|
|
|
-def ScriptSkeleton( skeleton, b_cmnts ):
|
|
|
- # check if skeleton is correct class
|
|
|
- if( skeleton.__class__.__name__ != "Armature" ):
|
|
|
- ERROR( "The given func param is not a \"Armature\" class but a \"" + skeleton.__class__.__name__ + "\"" )
|
|
|
- return "error"
|
|
|
-
|
|
|
+#=======================================================================================================================
|
|
|
+# getAnkiSkeletonScript =
|
|
|
+#=======================================================================================================================
|
|
|
+def getAnkiSkeletonScript(skeleton, flipYZ):
|
|
|
ftxt = "" # file text
|
|
|
|
|
|
# write the file
|
|
|
- bone_names = skeleton.bones.keys()
|
|
|
- bone_names.sort() # the bones are written in alpabetical order
|
|
|
+ boneNames = skeleton.bones.keys()
|
|
|
+ boneNames.sort() # the bones are written in alpabetical order
|
|
|
|
|
|
- if( b_cmnts ): ftxt += "/*BONES*/ "
|
|
|
- ftxt += str( len(bone_names) ) + "\n"
|
|
|
+ ftxt += str(len(boneNames)) + "\n"
|
|
|
|
|
|
- for bone_nam in bone_names:
|
|
|
- bone = skeleton.bones[ bone_nam ]
|
|
|
- if( b_cmnts ): ftxt += "\t/*\"" + bone.name + "\" BONE_ID " + str(bone_names.index(bone_nam)) + "*/\n"
|
|
|
+ for boneName in boneNames:
|
|
|
+ bone = skeleton.bones[boneName]
|
|
|
|
|
|
# name
|
|
|
- if( b_cmnts ): ftxt += "\t\t/*BONE_NAME*/ "
|
|
|
ftxt += "\"" + bone.name + "\"\n"
|
|
|
|
|
|
# head
|
|
|
co = bone.head["ARMATURESPACE"]
|
|
|
- if( b_cmnts ): ftxt += "\t\t/*HEAD_ARMATURE_SPACE*/ "
|
|
|
- ftxt += str(co.x) + " " + str(co.y) + " " + str(co.z) + "\n"
|
|
|
+ if flipYZ:
|
|
|
+ ftxt += str(co.x) + " " + str(co.z) + " " + str(-co.y) + "\n"
|
|
|
+ else:
|
|
|
+ ftxt += str(co.x) + " " + str(co.y) + " " + str(co.z) + "\n"
|
|
|
|
|
|
# tail
|
|
|
- co = bone.tail["ARMATURESPACE"]
|
|
|
- if( b_cmnts ): ftxt += "\t\t/*TAIL_ARMATURE_SPACE*/ "
|
|
|
+ co = bone.tail["ARMATURESPACE"]
|
|
|
+ if flipYZ:
|
|
|
+ ftxt += str(co.x) + " " + str(co.z) + " " + str(-co.y) + "\n"
|
|
|
+ else:
|
|
|
+ ftxt += str(co.x) + " " + str(co.y) + " " + str(co.z) + "\n"
|
|
|
|
|
|
- ftxt += str(co.x) + " " + str(co.y) + " " + str(co.z) + "\n"
|
|
|
+ # matrix
|
|
|
+ m4 = bone.matrix["ARMATURESPACE"].copy()
|
|
|
+
|
|
|
+ if flipYZ:
|
|
|
+ m4 = multMatrix(rotMat, m4)
|
|
|
|
|
|
- # matrix
|
|
|
- if( b_cmnts ): ftxt += "\t\t/*MATRIX_ARMATURE_SPACE*/ "
|
|
|
-
|
|
|
for i_ in range(0, 4):
|
|
|
for j_ in range(0, 4):
|
|
|
- ftxt += str( bone.matrix["ARMATURESPACE"][j_][i_] ) + " "
|
|
|
+ ftxt += str(m4[j_][i_]) + " "
|
|
|
ftxt += "\n"
|
|
|
|
|
|
# write the parent
|
|
|
- if( b_cmnts ): ftxt += "\t\t/*PARENT_ID*/ "
|
|
|
|
|
|
if not bone.parent:
|
|
|
ftxt += "NULL\n"
|
|
|
else:
|
|
|
- ftxt += str( bone_names.index( bone.parent.name ) )
|
|
|
- if( b_cmnts ): ftxt += " // " + bone.parent.name
|
|
|
- ftxt += "\n"
|
|
|
-
|
|
|
+ ftxt += str(boneNames.index(bone.parent.name)) + "\n"
|
|
|
|
|
|
|
|
|
# write the childs
|
|
|
- if( b_cmnts ): ftxt += "\t\t/*CHILD_IDS_NUM*/ "
|
|
|
- ftxt += str( len(bone.children) ) + " "
|
|
|
- if( b_cmnts ): ftxt += "/*CHILD_IDS*/ "
|
|
|
+ ftxt += str(len(bone.children)) + "\n"
|
|
|
|
|
|
for child in bone.children:
|
|
|
- ftxt += str( bone_names.index( child.name ) ) + " "
|
|
|
- if( b_cmnts ): ftxt += "/*" + child.name + "*/ "
|
|
|
+ ftxt += str(boneNames.index(child.name)) + " "
|
|
|
|
|
|
ftxt += "\n"
|
|
|
|
|
|
return ftxt
|
|
|
|
|
|
|
|
|
-#===================================================================================================
|
|
|
-# ExportSkeleton =
|
|
|
-#===================================================================================================
|
|
|
-def ExportSkeleton( path, skeleton, b_cmnts ):
|
|
|
+#=======================================================================================================================
|
|
|
+# export =
|
|
|
+#=======================================================================================================================
|
|
|
+def export(skeletonInit):
|
|
|
+ skeleton = skeletonInit.skeleton
|
|
|
#check if mesh is the correct class
|
|
|
- if( skeleton.__class__.__name__ != "Armature" ):
|
|
|
- ERROR( "The given func param is not a \"Armature\" class but a \"" + skeleton.__class__.__name__ + "\"" )
|
|
|
- return false
|
|
|
+ if(skeleton.__class__.__name__ != "Armature"):
|
|
|
+ raise RuntimeError("The given func param is not a \"Armature\" class but a \"" + skeleton.__class__.__name__ + "\"")
|
|
|
|
|
|
- INFO( "Trying to export skeleton \"" + skeleton.name + "\"" )
|
|
|
+ print("Trying to export skeleton \"" + skeleton.name + "\"")
|
|
|
|
|
|
- filename = path + skeleton.name + ".skel"
|
|
|
- WriteFile( filename, ScriptSkeleton( skeleton, b_cmnts ) )
|
|
|
+ filename = skeletonInit.saveDir + skeleton.name + ".skel"
|
|
|
+ file = open(filename, "w")
|
|
|
+ file.write(getAnkiSkeletonScript(skeleton, skeletonInit.flipYZ))
|
|
|
|
|
|
- INFO( "Skeleton exported!! \"" + filename + "\"" )
|
|
|
+ print("Skeleton exported!! \"" + filename + "\"")
|
|
|
+
|