[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