From 2afc158e68486909a86b64e607a80e52626d92bf Mon Sep 17 00:00:00 2001 From: Chris Foster <cdbfoster@gmail.com> Date: Sun, 11 Jul 2010 17:41:31 +0000 Subject: [PATCH] Begun work on Full Animation. Having trouble with axis flipping. --- export_directx_x.py | 87 +++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 80 insertions(+), 7 deletions(-) diff --git a/export_directx_x.py b/export_directx_x.py index a697f5ca1..2a42b4c47 100644 --- a/export_directx_x.py +++ b/export_directx_x.py @@ -15,6 +15,15 @@ # All rights reserved. # ***** GPL LICENSE BLOCK ***** + +#NOTE: ======================================================== +#I've begun work on a Full Animation feature to more accurately export +#FCurve data. It's going pretty well, but I'm having some trouble with +#axis flipping. To "enable" the feature, uncomment line #988 +#The problem is in the WriteFullAnimationSet function at line #948 +# - Chris (2010-7-11) + + #One line description for early versions of Blender 2.52. "Export: DirectX Model Format (.x)" @@ -30,6 +39,7 @@ bl_addon_info = { 'tracker_url': 'https://projects.blender.org/tracker/index.php?'\ 'func=detail&aid=22795&group_id=153&atid=469', 'category': 'Import/Export'} + """ Name: 'DirectX Exporter' Blender: 252 @@ -38,7 +48,8 @@ Tooltip: 'Exports to the DirectX model file format (.x)' """ __author__ = "Chris Foster (Kira Vakaan)" -__url__ = "www.tobedecided.com" +__url__ = "http://wiki.blender.org/index.php/Extensions:2.5/Py/" \ + "Scripts/File_I-O/DirectX_Exporter" __version__ = "1.1" __bpydoc__ = """\ """ @@ -165,7 +176,10 @@ def ExportDirectX(Config): print("Done") if Config.Verbose: print("Writing Animation...") - WriteAnimationSet(Config) + if Config.ExportAnimation==1: + WriteKeyedAnimationSet(Config) + else: + WriteFullAnimationSet(Config) bpy.context.scene.frame_current = CurrentFrame if Config.Verbose: print("Done") @@ -178,17 +192,19 @@ def GetObjectChildren(Parent): return [Object for Object in Parent.children if Object.type in ("ARMATURE", "EMPTY", "MESH")] - +#Returns the vertex count of Mesh, counting each vertex for every face. def GetMeshVertexCount(Mesh): VertexCount = 0 for Face in Mesh.faces: VertexCount += len(Face.verts) return VertexCount - +#Returns the file path of first image texture from Material. def GetMaterialTexture(Material): if Material: + #Create a list of Textures that have type "IMAGE" ImageTextures = [Material.texture_slots[TextureSlot].texture for TextureSlot in Material.texture_slots.keys() if Material.texture_slots[TextureSlot].texture.type == "IMAGE"] + #Refine a new list with only image textures that have a file source ImageFiles = [os.path.basename(Texture.image.filename) for Texture in ImageTextures if Texture.image.source == "FILE"] if ImageFiles: return ImageFiles[0] @@ -529,9 +545,11 @@ def WriteMeshSkinWeights(Config, Object, Mesh): MaxInfluences = 0 UsedBones = set() + #Maps bones to a list of vertices they affect VertexGroups = {} - + for Vertex in Mesh.verts: + #BoneInfluences contains the bones of the armature that affect the current vertex BoneInfluences = [PoseBones[Object.vertex_groups[Group.group].name] for Group in Vertex.groups if Object.vertex_groups[Group.group].name in PoseBones] if len(BoneInfluences) > MaxInfluences: MaxInfluences = len(BoneInfluences) @@ -617,7 +635,7 @@ def WriteMeshSkinWeights(Config, Object, Mesh): Config.File.write("{}}} //End of {} Skin Weights\n".format(" " * Config.Whitespace, LegalName(ArmatureObject.name) + "_" + LegalName(Bone.name))) -def WriteAnimationSet(Config): +def WriteKeyedAnimationSet(Config): Config.File.write("{}AnimationSet {{\n".format(" " * Config.Whitespace)) Config.Whitespace += 1 for Object in [Object for Object in Config.ObjectList if Object.animation_data]: @@ -896,6 +914,61 @@ def WriteAnimationSet(Config): Config.Whitespace -= 1 Config.File.write("{}}} //End of AnimationSet\n".format(" " * Config.Whitespace)) + + +def WriteFullAnimationSet(Config): + Config.File.write("{}AnimationSet {{\n".format(" " * Config.Whitespace)) + Config.Whitespace += 1 + + KeyframeCount = bpy.context.scene.frame_end - bpy.context.scene.frame_start + 1 + + for Object in Config.ObjectList: + Config.File.write("{}Animation {{\n".format(" " * Config.Whitespace)) + Config.Whitespace += 1 + Config.File.write("{}{{{}}}\n".format(" " * Config.Whitespace, LegalName(Object.name))) + + #Position + Config.File.write("{}AnimationKey {{ //Position\n".format(" " * Config.Whitespace)) + Config.Whitespace += 1 + Config.File.write("{}2;\n{}{};\n".format(" " * Config.Whitespace," " * Config.Whitespace,KeyframeCount)) + for Frame in range(0, KeyframeCount): + bpy.context.scene.set_frame(Frame) + Position = Config.SystemMatrix * Object.location + Config.File.write("{}{}{:9f},{:9f},{:9f};;\n".format(" " * Config.Whitespace, (str(Frame) + ";3;").ljust(8), Position[0], Position[1], Position[2])) + Config.Whitespace -= 1 + Config.File.write("{}}}\n".format(" " * Config.Whitespace)) + + #Rotation + Config.File.write("{}AnimationKey {{ //Rotation\n".format(" " * Config.Whitespace)) + Config.Whitespace += 1 + Config.File.write("{}0;\n{}{};\n".format(" " * Config.Whitespace, " " * Config.Whitespace, KeyframeCount)) + for Frame in range(0, KeyframeCount): + bpy.context.scene.set_frame(Frame) + #Works pretty well, but causes a slightly noticeable axis flip at 180* + Rotation = (Config.SystemMatrix * (Object.rotation_euler.to_matrix().to_4x4()) * Config.InverseSystemMatrix).to_quat() + Config.File.write("{}{}{:9f},{:9f},{:9f},{:9f};;\n".format(" " * Config.Whitespace,(str(Frame) + ";4;").ljust(8), -Rotation[0], Rotation[1], Rotation[2], Rotation[3])) + Config.Whitespace -= 1 + Config.File.write("{}}}\n".format(" " * Config.Whitespace)) + + #Scale + Config.File.write("{}AnimationKey {{ //Scale\n".format(" " * Config.Whitespace)) + Config.Whitespace += 1 + Config.File.write("{}1;\n{}{};\n".format(" " * Config.Whitespace, " " * Config.Whitespace, KeyframeCount)) + for Frame in range(0, KeyframeCount): + bpy.context.scene.set_frame(Frame) + Scale = Config.SystemMatrix * Object.scale + Config.File.write("{}{}{:9f},{:9f},{:9f};;\n".format(" " * Config.Whitespace,(str(Frame) + ";3;").ljust(8), Scale[0], Scale[1], Scale[2])) + Config.Whitespace -= 1 + Config.File.write("{}}}\n".format(" " * Config.Whitespace)) + + Config.Whitespace -= 1 + Config.File.write("{}}}\n".format(" " * Config.Whitespace)) + + if Config.ExportArmatures and Object.type == "ARMATURE": + pass + + Config.Whitespace -= 1 + Config.File.write("{}}} //End of AnimationSet\n".format(" " * Config.Whitespace)) def CloseFile(Config): @@ -993,4 +1066,4 @@ def unregister(): if __name__ == "__main__": - register() + register() \ No newline at end of file -- GitLab