[Bf-extensions-cvs] SVN commit: /data/svn/bf-extensions [3279] contrib/py/scripts/addons/ io_export_marmalade.py: New feature, Option to Export multiple Animation actions for Armatures.

Benoit Muller benoit.muller at laposte.net
Wed Apr 18 18:42:14 CEST 2012


Revision: 3279
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-extensions&revision=3279
Author:   benoitmuller
Date:     2012-04-18 16:42:14 +0000 (Wed, 18 Apr 2012)
Log Message:
-----------
New feature, Option to Export multiple Animation actions for Armatures.
Fix issues thanks to marmalade users feedbacks:
- Rest pose was wrong (it was the first Pose Frame, so export was wrong when Animation was not started by the Rest pose)
- Rotation is now applied before export (scale was already applied)
- Clamp material exported colors to 255
- Skin export, Exclude VertexGroup that doesn't match any Bone Name.

Modified Paths:
--------------
    contrib/py/scripts/addons/io_export_marmalade.py

Modified: contrib/py/scripts/addons/io_export_marmalade.py
===================================================================
--- contrib/py/scripts/addons/io_export_marmalade.py	2012-04-18 15:34:16 UTC (rev 3278)
+++ contrib/py/scripts/addons/io_export_marmalade.py	2012-04-18 16:42:14 UTC (rev 3279)
@@ -22,7 +22,7 @@
 bl_info = {
     "name": "Marmalade Cross-platform Apps (.group)",
     "author": "Benoit Muller",
-    "version": (0, 6, 0),
+    "version": (0, 6, 1),
     "blender": (2, 6, 3),
     "location": "File > Export > Marmalade cross-platform Apps (.group)",
     "description": "Export Marmalade Format files (.group)",
@@ -64,7 +64,8 @@
                  ExportTextures=True,
                  CopyTextureFiles=True,
                  ExportArmatures=False,
-                 ExportAnimation=0,
+                 ExportAnimationFrames=0,
+                 ExportAnimationActions=0,
                  ExportMode=1,
                  MergeModes=0,
                  Verbose=False):
@@ -80,7 +81,8 @@
         self.ExportTextures = ExportTextures
         self.CopyTextureFiles = CopyTextureFiles
         self.ExportArmatures = ExportArmatures
-        self.ExportAnimation = int(ExportAnimation)
+        self.ExportAnimationFrames = int(ExportAnimationFrames)
+        self.ExportAnimationActions = int(ExportAnimationActions)
         self.ExportMode = int(ExportMode)
         self.MergeModes = int(MergeModes)
         self.Verbose = Verbose
@@ -120,7 +122,7 @@
     if Config.Verbose:
         print("Setting up...")
 
-    if Config.ExportAnimation:
+    if Config.ExportAnimationFrames:
         if Config.Verbose:
             print(bpy.context.scene)
             print(bpy.context.scene.frame_current)
@@ -139,7 +141,7 @@
     if Config.Verbose:
         print("Objects Exported: {}".format(Config.ExportList))
 
-    if Config.ExportAnimation:
+    if Config.ExportAnimationFrames:
         if Config.Verbose:
             print("Writing Animation...")
         WriteKeyedAnimationSet(Config, bpy.context.scene)
@@ -265,7 +267,8 @@
                 scalematrix[1][1] = meshScale.y * Config.Scale
                 scalematrix[2][2] = meshScale.z * Config.Scale
 
-                Mesh.transform(scalematrix * X_ROT)
+                meshRot = Object.matrix_world.to_quaternion()  # Export is working, even if user doesn't have use apply Rotation in Edit mode.
+                Mesh.transform(X_ROT * meshRot.to_matrix().to_4x4() * scalematrix)
             else:
                 # In Merge mode, we need to keep relative postion of each objects, so we export in WORLD SPACE
                 SCALE_MAT = mathutils.Matrix.Scale(Config.Scale, 4)
@@ -793,11 +796,13 @@
             #if bpy.context.scene.world:
             #    MatAmbientColor = Material.ambient * bpy.context.scene.world.ambient_color
             MatAmbientColor = Material.ambient * Material.diffuse_color
-            mtlFile.write("\tcolAmbient {%.2f,%.2f,%.2f,%.2f} \n" % (MatAmbientColor[0] * 255, MatAmbientColor[1] * 255, MatAmbientColor[2] * 255, Material.alpha * 255))
-            MatDiffuseColor = Material.diffuse_intensity * Material.diffuse_color
-            mtlFile.write("\tcolDiffuse  {%.2f,%.2f,%.2f} \n" % (MatDiffuseColor * 255)[:])
-            MatSpecularColor = Material.specular_intensity * Material.specular_color
-            mtlFile.write("\tcolSpecular  {%.2f,%.2f,%.2f} \n" % (MatSpecularColor * 255)[:])
+            mtlFile.write("\tcolAmbient {%.2f,%.2f,%.2f,%.2f} \n" % (min(255, MatAmbientColor[0] * 255), min(255, MatAmbientColor[1] * 255), min(255, MatAmbientColor[2] * 255), min(255, Material.alpha * 255)))
+            MatDiffuseColor = 255 * Material.diffuse_intensity * Material.diffuse_color
+            MatDiffuseColor = min((255, 255, 255)[:],MatDiffuseColor[:])
+            mtlFile.write("\tcolDiffuse  {%.2f,%.2f,%.2f} \n" % (MatDiffuseColor[:]))
+            MatSpecularColor = 255 * Material.specular_intensity * Material.specular_color
+            MatSpecularColor = min((255, 255, 255)[:],MatSpecularColor[:])
+            mtlFile.write("\tcolSpecular  {%.2f,%.2f,%.2f} \n" % (MatSpecularColor[:]))
             # EmitColor = Material.emit * Material.diffuse_color
             # mtlFile.write("\tcolEmissive {%.2f,%.2f,%.2f} \n" % (EmitColor* 255)[:])    
     else:
@@ -834,12 +839,20 @@
 
 def GetVertexGroupFromBone(Object, Bone):
     if Bone:
-        rootBoneList = [VertexGroup for VertexGroup in Object.vertex_groups  if VertexGroup.name == Bone.name]
-        if rootBoneList:
-            return rootBoneList[0]
+        vertexGroupList = [VertexGroup for VertexGroup in Object.vertex_groups  if VertexGroup.name == Bone.name]
+        if vertexGroupList:
+            return vertexGroupList[0]
     return None
 
 
+def GetBoneListNames(Bones):
+    boneList = []
+    for Bone in Bones:
+        boneList.append(Bone.name)
+        boneList += GetBoneListNames(Bone.children)
+    return boneList
+
+
 def FindUniqueIndexForRootBone(Object, RootVertexGroup):
     if RootVertexGroup:
         return RootVertexGroup.index
@@ -857,6 +870,7 @@
             return
         RootBone = GetFirstRootBone(ArmatureObject)
         RootVertexGroup = GetVertexGroupFromBone(Object, RootBone)
+        BoneNames = GetBoneListNames(ArmatureObject.data.bones)
 
         GeoModel.armatureObjectName = StripName(ArmatureObject.name)
         if RootBone:
@@ -869,7 +883,7 @@
         
         for Vertex in Mesh.vertices:
             VertexIndex = Vertex.index + GeoModel.vbaseIndex
-            AddVertexToDicionarySkinWeights(Config, Object, Mesh, Vertex, GeoModel.useBonesDict, GeoModel.mapVertexGroupNames, VertexIndex, RootBone, RootVertexGroup)
+            AddVertexToDicionarySkinWeights(Config, Object, Mesh, Vertex, GeoModel.useBonesDict, GeoModel.mapVertexGroupNames, VertexIndex, RootBone, RootVertexGroup, BoneNames)
             GeoModel.skinnedVertices.append(VertexIndex)
 
         if Config.MergeModes != 1:
@@ -909,7 +923,7 @@
         skinFile.close()
 
 
-def AddVertexToDicionarySkinWeights(Config, Object, Mesh, Vertex, useBonesDict, mapVertexGroupNames, VertexIndex, RootBone, RootVertexGroup):
+def AddVertexToDicionarySkinWeights(Config, Object, Mesh, Vertex, useBonesDict, mapVertexGroupNames, VertexIndex, RootBone, RootVertexGroup, BoneNames):
     #build useBones
     useBonesKey = 0
     vertexGroupIndices = []
@@ -918,11 +932,13 @@
         print ("ERROR Vertex %d is influenced by more than 4 bones\n" % (VertexIndex))
     for VertexGroup in Vertex.groups:
         if (VertexGroup.weight > 0):
-            mapVertexGroupNames[VertexGroup.group] = StripBoneName(Object.vertex_groups[VertexGroup.group].name)
-            if (len(vertexGroupIndices))<4:  #ignore if more 4 bones are influencing the vertex
-                useBonesKey = useBonesKey + pow(2, VertexGroup.group)
-                vertexGroupIndices.append(VertexGroup.group)
-                weightTotal = weightTotal + VertexGroup.weight
+            groupName = Object.vertex_groups[VertexGroup.group].name
+            if groupName in BoneNames:
+                mapVertexGroupNames[VertexGroup.group] = StripBoneName(groupName)
+                if (len(vertexGroupIndices))<4:  #ignore if more 4 bones are influencing the vertex
+                    useBonesKey = useBonesKey + pow(2, VertexGroup.group)
+                    vertexGroupIndices.append(VertexGroup.group)
+                    weightTotal = weightTotal + VertexGroup.weight
     if (weightTotal == 0):
         bWeightTotZero = True  #avoid divide by zero later on
         if (RootBone):
@@ -990,7 +1006,6 @@
 
         PoseBone = PoseBones[Bone.name]
         WriteBonePosition(Config, Object, Bone, PoseBones, PoseBone, skelFile, True)
-        #WriteOneBoneRestPosition(Config, Object, Bone, PoseBones, PoseBone, skelFile, True, Vector(),Quaternion())
         if Config.Verbose:
             print("      Done")
         WriteArmatureChildBones(Config, Object, Bone.children, skelFile)
@@ -1003,57 +1018,57 @@
             print("      Writing Child Bone: {}...".format(Bone.name))
         PoseBone = PoseBones[Bone.name]
         WriteBonePosition(Config, Object, Bone, PoseBones, PoseBone, skelFile, True)
-        #WriteOneBoneRestPosition(Config, Object, Bone, PoseBones, PoseBone, skelFile, True, Vector(),Quaternion())
         if Config.Verbose:
             print("      Done")
             
         WriteArmatureChildBones(Config, Object, Bone.children, skelFile)
 
 
-def WriteBonePosition(Config, Object, Bone, PoseBones, PoseBone, File, isSkelFileNotAnimFile):
+def WriteBonePosition(Config, Object, Bone, PoseBones, PoseBone, File, isRestPoseNotAnimPose):
     # Compute armature scale : 
     # Many others exporter require sthe user to do Apply Scale in Object Mode to have 1,1,1 scale and so that anim data are correctly scaled
     # Here we retreive the Scale of the Armture Object.matrix_world.to_scale() and we use it to scale the bones :-)
     # So new Blender user should not complain about bad animation export if they forgot to apply the Scale to 1,1,1
-
+    
     armScale = Object.matrix_world.to_scale()
-    ## scalematrix = Matrix()
-    ## scalematrix[0][0] = armScale.x * Config.Scale
-    ## scalematrix[1][1] = armScale.y * Config.Scale
-    ## scalematrix[2][2] = armScale.z * Config.Scale
-
-    if isSkelFileNotAnimFile:
+    armRot = Object.matrix_world.to_quaternion()
+    if isRestPoseNotAnimPose:
         #skel file, bone header
         File.write("\tCIwAnimBone\n")
         File.write("\t{\n")
         File.write("\t\tname \"%s\"\n" % StripBoneName(Bone.name))
+        #get bone local matrix for rest pose
         if Bone.parent:
             File.write("\t\tparent \"%s\"\n" % StripBoneName(Bone.parent.name))
+            localmat = Bone.parent.matrix_local.inverted() * Bone.matrix_local
+        else:
+            localmat = Bone.matrix_local
     else:
         #anim file, bone header
         File.write("\t\t\n")
         File.write("\t\tbone \"%s\" \n" % StripBoneName(Bone.name))
+        localmat = PoseBone.matrix
+        #get bone local matrix for current anim pose
+        if Bone.parent:
+            ParentPoseBone = PoseBones[Bone.parent.name]
+            localmat = ParentPoseBone.matrix.inverted() * PoseBone.matrix
+        else:
+            localmat = PoseBone.matrix
 
-    if Bone.parent:
-        ParentPoseBone = PoseBones[Bone.parent.name]

@@ Diff output truncated at 10240 characters. @@


More information about the Bf-extensions-cvs mailing list