diff --git a/export_directx_x.py b/export_directx_x.py index c51166fe1e71dfcb1c4260cdee1e274d84fe806b..2dc9a01dfd0c1f1c6eea57b65312c1817dfa112c 100644 --- a/export_directx_x.py +++ b/export_directx_x.py @@ -1,19 +1,19 @@ - # ***** GPL LICENSE BLOCK ***** - # - # This program is free software: you can redistribute it and/or modify - # it under the terms of the GNU General Public License as published by - # the Free Software Foundation, either version 3 of the License, or - # (at your option) any later version. - # - # This program is distributed in the hope that it will be useful, - # but WITHOUT ANY WARRANTY; without even the implied warranty of - # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - # GNU General Public License for more details. - # - # You should have received a copy of the GNU General Public License - # along with this program. If not, see <http://www.gnu.org/licenses/>. - # All rights reserved. - # ***** GPL LICENSE BLOCK ***** +# ***** GPL LICENSE BLOCK ***** +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. +# All rights reserved. +# ***** GPL LICENSE BLOCK ***** #One line description for early versions of Blender 2.52. "Export: DirectX Model Format (.x)" @@ -37,10 +37,10 @@ Group: 'Export' Tooltip: 'Exports to the DirectX model file format (.x)' """ -__author__="Chris Foster (Kira Vakaan)" -__url__="www.tobedecided.com" -__version__="1.1" -__bpydoc__="""\ +__author__ = "Chris Foster (Kira Vakaan)" +__url__ = "www.tobedecided.com" +__version__ = "1.1" +__bpydoc__ = """\ """ import bpy @@ -64,97 +64,137 @@ class DirectXExporterSettings: ExportAnimation=0, ExportMode=1, Verbose=False): - self.context=context - self.FilePath=FilePath - self.CoordinateSystem=int(CoordinateSystem) - self.RotateX=RotateX - self.FlipNormals=FlipNormals - self.ApplyModifiers=ApplyModifiers - self.IncludeFrameRate=IncludeFrameRate - self.ExportTextures=ExportTextures - self.ExportArmatures=ExportArmatures - self.ExportAnimation=int(ExportAnimation) - self.ExportMode=int(ExportMode) - self.Verbose=Verbose + self.context = context + self.FilePath = FilePath + self.CoordinateSystem = int(CoordinateSystem) + self.RotateX = RotateX + self.FlipNormals = FlipNormals + self.ApplyModifiers = ApplyModifiers + self.IncludeFrameRate = IncludeFrameRate + self.ExportTextures = ExportTextures + self.ExportArmatures = ExportArmatures + self.ExportAnimation = int(ExportAnimation) + self.ExportMode = int(ExportMode) + self.Verbose = Verbose + def LegalName(Name): - NewName=Name.replace(".","_") - NewName=NewName.replace(" ","_") - if NewName[0].isdigit() or NewName in ["ARRAY","DWORD","UCHAR","BINARY","FLOAT","ULONGLONG","BINARY_RESOURCE","SDWORD","UNICODE","CHAR","STRING","WORD","CSTRING","SWORD","DOUBLE","TEMPLATE"]: - NewName="_"+NewName + NewName = Name.replace(".", "_") + NewName = NewName.replace(" ", "_") + if NewName[0].isdigit() or NewName in ["ARRAY", + "DWORD", + "UCHAR", + "BINARY", + "FLOAT", + "ULONGLONG", + "BINARY_RESOURCE", + "SDWORD", + "UNICODE", + "CHAR", + "STRING", + "WORD", + "CSTRING", + "SWORD", + "DOUBLE", + "TEMPLATE"]: + NewName = "_" + NewName return NewName + def ExportDirectX(Config): print("----------\nExporting to {}".format(Config.FilePath)) - if Config.Verbose: print("Opening File...",end=" ") - Config.File=open(Config.FilePath,"w") - if Config.Verbose: print("Done") - - if Config.Verbose: print("Generating Object list for export...",end=" ") - if Config.ExportMode==1: - Config.ExportList=[Object for Object in Config.context.scene.objects if Object.type in ("ARMATURE","EMPTY","MESH") and Object.parent==None] + if Config.Verbose: + print("Opening File...", end=" ") + Config.File = open(Config.FilePath, "w") + if Config.Verbose: + print("Done") + + if Config.Verbose: + print("Generating Object list for export...", end=" ") + if Config.ExportMode == 1: + Config.ExportList = [Object for Object in Config.context.scene.objects + if Object.type in ("ARMATURE", "EMPTY", "MESH") + and Object.parent == None] else: - ExportList=[Object for Object in Config.context.selected_objects if Object.type in ("ARMATURE","EMPTY","MESH")] - Config.ExportList=[Object for Object in ExportList if Object.parent not in ExportList] - if Config.Verbose: print("Done") - - if Config.Verbose: print("Setting up...",end=" ") - Config.SystemMatrix=Matrix() + ExportList = [Object for Object in Config.context.selected_objects + if Object.type in ("ARMATURE", "EMPTY", "MESH")] + Config.ExportList = [Object for Object in ExportList + if Object.parent not in ExportList] + if Config.Verbose: + print("Done") + + if Config.Verbose: + print("Setting up...", end=" ") + Config.SystemMatrix = Matrix() if Config.RotateX: - Config.SystemMatrix*=RotationMatrix(radians(-90),4,"X") - if Config.CoordinateSystem==1: - Config.SystemMatrix*=ScaleMatrix(-1,4,Vector((0,1,0))) - Config.InverseSystemMatrix=Config.SystemMatrix.copy().invert() - + Config.SystemMatrix *= RotationMatrix(radians(-90), 4, "X") + if Config.CoordinateSystem == 1: + Config.SystemMatrix *= ScaleMatrix(-1, 4, Vector((0, 1, 0))) + Config.InverseSystemMatrix = Config.SystemMatrix.copy().invert() + if Config.ExportAnimation: - CurrentFrame=bpy.context.scene.frame_current - bpy.context.scene.frame_current=bpy.context.scene.frame_current - if Config.Verbose: print("Done") - - if Config.Verbose: print("Writing Header...",end=" ") + CurrentFrame = bpy.context.scene.frame_current + bpy.context.scene.frame_current = bpy.context.scene.frame_current + if Config.Verbose: + print("Done") + + if Config.Verbose: + print("Writing Header...", end=" ") WriteHeader(Config) - if Config.Verbose: print("Done") - - Config.Whitespace=0 - Config.ObjectList=[] - if Config.Verbose: print("Writing Objects...") - WriteObjects(Config,Config.ExportList) - if Config.Verbose: print("Done") - + if Config.Verbose: + print("Done") + + Config.Whitespace = 0 + Config.ObjectList = [] + if Config.Verbose: + print("Writing Objects...") + WriteObjects(Config, Config.ExportList) + if Config.Verbose: + print("Done") + if Config.ExportAnimation: if Config.IncludeFrameRate: - if Config.Verbose: print("Writing Frame Rate...",end=" ") - Config.File.write("{}AnimTicksPerSecond {{\n".format(" "*Config.Whitespace)) - Config.Whitespace+=1 - Config.File.write("{}{};\n".format(" "*Config.Whitespace,int(bpy.context.scene.render.fps/bpy.context.scene.render.fps_base))) - Config.Whitespace-=1 - Config.File.write("{}}}\n".format(" "*Config.Whitespace)) - if Config.Verbose: print("Done") - if Config.Verbose: print("Writing Animation...") + if Config.Verbose: + print("Writing Frame Rate...", end=" ") + Config.File.write("{}AnimTicksPerSecond {{\n".format(" " * Config.Whitespace)) + Config.Whitespace += 1 + Config.File.write("{}{};\n".format(" " * Config.Whitespace, int(bpy.context.scene.render.fps / bpy.context.scene.render.fps_base))) + Config.Whitespace -= 1 + Config.File.write("{}}}\n".format(" " * Config.Whitespace)) + if Config.Verbose: + print("Done") + if Config.Verbose: + print("Writing Animation...") WriteAnimationSet(Config) - bpy.context.scene.frame_current=CurrentFrame - if Config.Verbose: print("Done") - + bpy.context.scene.frame_current = CurrentFrame + if Config.Verbose: + print("Done") + CloseFile(Config) print("Finished") + def GetObjectChildren(Parent): - return [Object for Object in Parent.children if Object.type in ("ARMATURE","EMPTY","MESH")] + return [Object for Object in Parent.children + if Object.type in ("ARMATURE", "EMPTY", "MESH")] + def GetMeshVertexCount(Mesh): - VertexCount=0 + VertexCount = 0 for Face in Mesh.faces: - VertexCount+=len(Face.verts) + VertexCount += len(Face.verts) return VertexCount + def GetMaterialTexture(Material): if Material: - ImageTextures=[Material.texture_slots[TextureSlot].texture for TextureSlot in Material.texture_slots.keys() if Material.texture_slots[TextureSlot].texture.type=="IMAGE"] - ImageFiles=[os.path.basename(Texture.image.filename) for Texture in ImageTextures if Texture.image.source=="FILE"] + ImageTextures = [Material.texture_slots[TextureSlot].texture for TextureSlot in Material.texture_slots.keys() if Material.texture_slots[TextureSlot].texture.type == "IMAGE"] + ImageFiles = [os.path.basename(Texture.image.filename) for Texture in ImageTextures if Texture.image.source == "FILE"] if ImageFiles: return ImageFiles[0] return None + def WriteHeader(Config): Config.File.write("xof 0303txt 0032\n\n") if Config.ExportArmatures: @@ -173,698 +213,784 @@ template SkinWeights {\n\ Matrix4x4 matrixOffset;\n\ }\n\n") -def WriteObjects(Config,ObjectList): - Config.ObjectList+=ObjectList - + +def WriteObjects(Config, ObjectList): + Config.ObjectList += ObjectList + for Object in ObjectList: - if Config.Verbose: print(" Writing Object: {}...".format(Object.name)) - Config.File.write("{}Frame {} {{\n".format(" "*Config.Whitespace,LegalName(Object.name))) - - Config.Whitespace+=1 - if Config.Verbose: print(" Writing Local Matrix...",end=" ") - WriteLocalMatrix(Config,Object) - if Config.Verbose: print("Done") - - if Config.ExportArmatures and Object.type=="ARMATURE": - Armature=Object.data - ParentList=[Bone for Bone in Armature.bones if Bone.parent==None] - if Config.Verbose: print(" Writing Armature Bones...") - WriteArmatureBones(Config,Object,ParentList) - if Config.Verbose: print(" Done") - - ChildList=GetObjectChildren(Object) - if Config.Verbose: print(" Writing Children...") - WriteObjects(Config,ChildList) - if Config.Verbose: print(" Done Writing Children") - - if Object.type=="MESH": - if Config.Verbose: print(" Generating Mesh...",end=" ") - Mesh=Object.create_mesh(bpy.context.scene,(Config.ApplyModifiers|Config.ExportArmatures),"PREVIEW") - if Config.Verbose: print("Done") - if Config.Verbose: print(" Writing Mesh...") - WriteMesh(Config,Object,Mesh) - if Config.Verbose: print(" Done") + if Config.Verbose: + print(" Writing Object: {}...".format(Object.name)) + Config.File.write("{}Frame {} {{\n".format(" " * Config.Whitespace, LegalName(Object.name))) + + Config.Whitespace += 1 + if Config.Verbose: + print(" Writing Local Matrix...", end=" ") + WriteLocalMatrix(Config, Object) + if Config.Verbose: + print("Done") + + if Config.ExportArmatures and Object.type == "ARMATURE": + Armature = Object.data + ParentList = [Bone for Bone in Armature.bones if Bone.parent == None] + if Config.Verbose: + print(" Writing Armature Bones...") + WriteArmatureBones(Config, Object, ParentList) + if Config.Verbose: + print(" Done") + + ChildList = GetObjectChildren(Object) + if Config.Verbose: + print(" Writing Children...") + WriteObjects(Config, ChildList) + if Config.Verbose: + print(" Done Writing Children") + + if Object.type == "MESH": + if Config.Verbose: + print(" Generating Mesh...", end=" ") + Mesh = Object.create_mesh(bpy.context.scene, (Config.ApplyModifiers | Config.ExportArmatures), "PREVIEW") + if Config.Verbose: + print("Done") + if Config.Verbose: + print(" Writing Mesh...") + WriteMesh(Config, Object, Mesh) + if Config.Verbose: + print(" Done") bpy.data.meshes.remove(Mesh) - - Config.Whitespace-=1 - Config.File.write("{}}} //End of {}\n".format(" "*Config.Whitespace,LegalName(Object.name))) - if Config.Verbose: print(" Done Writing Object: {}".format(Object.name)) -def WriteLocalMatrix(Config,Object): + Config.Whitespace -= 1 + Config.File.write("{}}} //End of {}\n".format(" " * Config.Whitespace, LegalName(Object.name))) + if Config.Verbose: + print(" Done Writing Object: {}".format(Object.name)) + + +def WriteLocalMatrix(Config, Object): if Object.parent: - LocalMatrix=Object.parent.matrix_world.copy().invert() + LocalMatrix = Object.parent.matrix_world.copy().invert() else: - LocalMatrix=Matrix() - LocalMatrix*=Object.matrix_world - LocalMatrix=Config.SystemMatrix*LocalMatrix*Config.InverseSystemMatrix - - Config.File.write("{}FrameTransformMatrix {{\n".format(" "*Config.Whitespace)) - Config.Whitespace+=1 - Config.File.write("{}{:9f},{:9f},{:9f},{:9f},\n".format(" "*Config.Whitespace,LocalMatrix[0][0],LocalMatrix[0][1],LocalMatrix[0][2],LocalMatrix[0][3])) - Config.File.write("{}{:9f},{:9f},{:9f},{:9f},\n".format(" "*Config.Whitespace,LocalMatrix[1][0],LocalMatrix[1][1],LocalMatrix[1][2],LocalMatrix[1][3])) - Config.File.write("{}{:9f},{:9f},{:9f},{:9f},\n".format(" "*Config.Whitespace,LocalMatrix[2][0],LocalMatrix[2][1],LocalMatrix[2][2],LocalMatrix[2][3])) - Config.File.write("{}{:9f},{:9f},{:9f},{:9f};;\n".format(" "*Config.Whitespace,LocalMatrix[3][0],LocalMatrix[3][1],LocalMatrix[3][2],LocalMatrix[3][3])) - Config.Whitespace-=1 - Config.File.write("{}}}\n".format(" "*Config.Whitespace)) - -def WriteArmatureBones(Config,Object,ChildList): - PoseBones=Object.pose.bones + LocalMatrix = Matrix() + LocalMatrix *= Object.matrix_world + LocalMatrix = Config.SystemMatrix * LocalMatrix * Config.InverseSystemMatrix + + Config.File.write("{}FrameTransformMatrix {{\n".format(" " * Config.Whitespace)) + Config.Whitespace += 1 + Config.File.write("{}{:9f},{:9f},{:9f},{:9f},\n".format(" " * Config.Whitespace, LocalMatrix[0][0], LocalMatrix[0][1], LocalMatrix[0][2], LocalMatrix[0][3])) + Config.File.write("{}{:9f},{:9f},{:9f},{:9f},\n".format(" " * Config.Whitespace, LocalMatrix[1][0], LocalMatrix[1][1], LocalMatrix[1][2], LocalMatrix[1][3])) + Config.File.write("{}{:9f},{:9f},{:9f},{:9f},\n".format(" " * Config.Whitespace, LocalMatrix[2][0], LocalMatrix[2][1], LocalMatrix[2][2], LocalMatrix[2][3])) + Config.File.write("{}{:9f},{:9f},{:9f},{:9f};;\n".format(" " * Config.Whitespace, LocalMatrix[3][0], LocalMatrix[3][1], LocalMatrix[3][2], LocalMatrix[3][3])) + Config.Whitespace -= 1 + Config.File.write("{}}}\n".format(" " * Config.Whitespace)) + + +def WriteArmatureBones(Config, Object, ChildList): + PoseBones = Object.pose.bones for Bone in ChildList: - if Config.Verbose: print(" Writing Bone: {}...".format(Bone.name),end=" ") - Config.File.write("{}Frame {} {{\n".format(" "*Config.Whitespace,LegalName(Object.name)+"_"+LegalName(Bone.name))) - Config.Whitespace+=1 - - PoseBone=PoseBones[Bone.name] - + if Config.Verbose: + print(" Writing Bone: {}...".format(Bone.name), end=" ") + Config.File.write("{}Frame {} {{\n".format(" " * Config.Whitespace, LegalName(Object.name) + "_" + LegalName(Bone.name))) + Config.Whitespace += 1 + + PoseBone = PoseBones[Bone.name] + if Bone.parent: - BoneMatrix=(PoseBone.parent.matrix*RotationMatrix(radians(-90),4,"X")).invert() + BoneMatrix = (PoseBone.parent.matrix * + RotationMatrix(radians(-90), 4, "X")).invert() else: - BoneMatrix=Matrix() - - BoneMatrix*=PoseBone.matrix*RotationMatrix(radians(-90),4,"X") - BoneMatrix=Config.SystemMatrix*BoneMatrix*Config.InverseSystemMatrix - - Config.File.write("{}FrameTransformMatrix {{\n".format(" "*Config.Whitespace)) - Config.Whitespace+=1 - Config.File.write("{}{:9f},{:9f},{:9f},{:9f},\n".format(" "*Config.Whitespace,BoneMatrix[0][0],BoneMatrix[0][1],BoneMatrix[0][2],BoneMatrix[0][3])) - Config.File.write("{}{:9f},{:9f},{:9f},{:9f},\n".format(" "*Config.Whitespace,BoneMatrix[1][0],BoneMatrix[1][1],BoneMatrix[1][2],BoneMatrix[1][3])) - Config.File.write("{}{:9f},{:9f},{:9f},{:9f},\n".format(" "*Config.Whitespace,BoneMatrix[2][0],BoneMatrix[2][1],BoneMatrix[2][2],BoneMatrix[2][3])) - Config.File.write("{}{:9f},{:9f},{:9f},{:9f};;\n".format(" "*Config.Whitespace,BoneMatrix[3][0],BoneMatrix[3][1],BoneMatrix[3][2],BoneMatrix[3][3])) - Config.Whitespace-=1 - Config.File.write("{}}}\n".format(" "*Config.Whitespace)) - - if Config.Verbose: print("Done") - WriteArmatureBones(Config,Object,Bone.children) - Config.Whitespace-=1 - - Config.File.write("{}}} //End of {}\n".format(" "*Config.Whitespace,LegalName(Object.name)+"_"+LegalName(Bone.name))) - -def WriteMesh(Config,Object,Mesh): - Config.File.write("{}Mesh {{ //{} Mesh\n".format(" "*Config.Whitespace,LegalName(Mesh.name))) - Config.Whitespace+=1 - - if Config.Verbose: print(" Writing Mesh Vertices...",end=" ") - WriteMeshVertices(Config,Mesh) - if Config.Verbose: print("Done\n Writing Mesh Normals...",end=" ") - WriteMeshNormals(Config,Mesh) - if Config.Verbose: print("Done\n Writing Mesh Materials...",end=" ") - WriteMeshMaterials(Config,Mesh) - if Config.Verbose: print("Done") + BoneMatrix = Matrix() + + BoneMatrix *= PoseBone.matrix * RotationMatrix(radians(-90), 4, "X") + BoneMatrix = Config.SystemMatrix * BoneMatrix * Config.InverseSystemMatrix + + Config.File.write("{}FrameTransformMatrix {{\n".format(" " * Config.Whitespace)) + Config.Whitespace += 1 + Config.File.write("{}{:9f},{:9f},{:9f},{:9f},\n".format(" " * Config.Whitespace, BoneMatrix[0][0], BoneMatrix[0][1], BoneMatrix[0][2], BoneMatrix[0][3])) + Config.File.write("{}{:9f},{:9f},{:9f},{:9f},\n".format(" " * Config.Whitespace, BoneMatrix[1][0], BoneMatrix[1][1], BoneMatrix[1][2], BoneMatrix[1][3])) + Config.File.write("{}{:9f},{:9f},{:9f},{:9f},\n".format(" " * Config.Whitespace, BoneMatrix[2][0], BoneMatrix[2][1], BoneMatrix[2][2], BoneMatrix[2][3])) + Config.File.write("{}{:9f},{:9f},{:9f},{:9f};;\n".format(" " * Config.Whitespace, BoneMatrix[3][0], BoneMatrix[3][1], BoneMatrix[3][2], BoneMatrix[3][3])) + Config.Whitespace -= 1 + Config.File.write("{}}}\n".format(" " * Config.Whitespace)) + + if Config.Verbose: + print("Done") + WriteArmatureBones(Config, Object, Bone.children) + Config.Whitespace -= 1 + + Config.File.write("{}}} //End of {}\n".format(" " * Config.Whitespace, LegalName(Object.name) + "_" + LegalName(Bone.name))) + + +def WriteMesh(Config, Object, Mesh): + Config.File.write("{}Mesh {{ //{} Mesh\n".format(" " * Config.Whitespace, LegalName(Mesh.name))) + Config.Whitespace += 1 + + if Config.Verbose: + print(" Writing Mesh Vertices...", end=" ") + WriteMeshVertices(Config, Mesh) + if Config.Verbose: + print("Done\n Writing Mesh Normals...", end=" ") + WriteMeshNormals(Config, Mesh) + if Config.Verbose: + print("Done\n Writing Mesh Materials...", end=" ") + WriteMeshMaterials(Config, Mesh) + if Config.Verbose: + print("Done") if Mesh.uv_textures: - if Config.Verbose: print(" Writing Mesh UV Coordinates...",end=" ") - WriteMeshUVCoordinates(Config,Mesh) - if Config.Verbose: print("Done") + if Config.Verbose: + print(" Writing Mesh UV Coordinates...", end=" ") + WriteMeshUVCoordinates(Config, Mesh) + if Config.Verbose: + print("Done") if Config.ExportArmatures: - if Config.Verbose: print(" Writing Mesh Skin Weights...",end=" ") - WriteMeshSkinWeights(Config,Object,Mesh) - if Config.Verbose: print("Done") - - Config.Whitespace-=1 - Config.File.write("{}}} //End of {} Mesh\n".format(" "*Config.Whitespace,LegalName(Mesh.name))) - -def WriteMeshVertices(Config,Mesh): - Index=0 - VertexCount=GetMeshVertexCount(Mesh) - Config.File.write("{}{};\n".format(" "*Config.Whitespace,VertexCount)) - + if Config.Verbose: + print(" Writing Mesh Skin Weights...", end=" ") + WriteMeshSkinWeights(Config, Object, Mesh) + if Config.Verbose: + print("Done") + + Config.Whitespace -= 1 + Config.File.write("{}}} //End of {} Mesh\n".format(" " * Config.Whitespace, LegalName(Mesh.name))) + + +def WriteMeshVertices(Config, Mesh): + Index = 0 + VertexCount = GetMeshVertexCount(Mesh) + Config.File.write("{}{};\n".format(" " * Config.Whitespace, VertexCount)) + for Face in Mesh.faces: - Vertices=list(Face.verts) - - if Config.CoordinateSystem==1: Vertices=Vertices[::-1] + Vertices = list(Face.verts) + + if Config.CoordinateSystem == 1: + Vertices = Vertices[::-1] for Vertex in [Mesh.verts[Vertex] for Vertex in Vertices]: - Position=Config.SystemMatrix*Vertex.co - Config.File.write("{}{:9f};{:9f};{:9f};".format(" "*Config.Whitespace,Position[0],Position[1],Position[2])) - Index+=1 - if Index==VertexCount: Config.File.write(";\n") - else: Config.File.write(",\n") - - Index=0 - Config.File.write("{}{};\n".format(" "*Config.Whitespace,len(Mesh.faces))) - + Position = Config.SystemMatrix * Vertex.co + Config.File.write("{}{:9f};{:9f};{:9f};".format(" " * Config.Whitespace, Position[0], Position[1], Position[2])) + Index += 1 + if Index == VertexCount: + Config.File.write(";\n") + else: + Config.File.write(",\n") + + Index = 0 + Config.File.write("{}{};\n".format(" " * Config.Whitespace, len(Mesh.faces))) + for Face in Mesh.faces: - Config.File.write("{}{};".format(" "*Config.Whitespace,len(Face.verts))) + Config.File.write("{}{};".format(" " * Config.Whitespace, len(Face.verts))) for Vertex in Face.verts: Config.File.write("{};".format(Index)) - Index+=1 - if Index==VertexCount: Config.File.write(";\n") - else: Config.File.write(",\n") - -def WriteMeshNormals(Config,Mesh): - Config.File.write("{}MeshNormals {{ //{} Normals\n".format(" "*Config.Whitespace,LegalName(Mesh.name))) - Config.Whitespace+=1 - - Index=0 - VertexCount=GetMeshVertexCount(Mesh) - Config.File.write("{}{};\n".format(" "*Config.Whitespace,VertexCount)) - + Index += 1 + if Index == VertexCount: + Config.File.write(";\n") + else: + Config.File.write(",\n") + + +def WriteMeshNormals(Config, Mesh): + Config.File.write("{}MeshNormals {{ //{} Normals\n".format(" " * Config.Whitespace, LegalName(Mesh.name))) + Config.Whitespace += 1 + + Index = 0 + VertexCount = GetMeshVertexCount(Mesh) + Config.File.write("{}{};\n".format(" " * Config.Whitespace, VertexCount)) + for Face in Mesh.faces: - Vertices=list(Face.verts) - - if Config.CoordinateSystem==1: Vertices=Vertices[::-1] + Vertices = list(Face.verts) + + if Config.CoordinateSystem == 1: + Vertices = Vertices[::-1] for Vertex in [Mesh.verts[Vertex] for Vertex in Vertices]: - if Face.smooth: Normal=Config.SystemMatrix*Vertex.normal - else: Normal=Config.SystemMatrix*Face.normal - if Config.FlipNormals: Normal=-Normal - Config.File.write("{}{:9f};{:9f};{:9f};".format(" "*Config.Whitespace,Normal[0],Normal[1],Normal[2])) - Index+=1 - if Index==VertexCount: Config.File.write(";\n") - else: Config.File.write(",\n") - - Index=0 - Config.File.write("{}{};\n".format(" "*Config.Whitespace,len(Mesh.faces))) - + if Face.smooth: + Normal = Config.SystemMatrix * Vertex.normal + else: + Normal = Config.SystemMatrix * Face.normal + if Config.FlipNormals: + Normal = -Normal + Config.File.write("{}{:9f};{:9f};{:9f};".format(" " * Config.Whitespace, Normal[0], Normal[1], Normal[2])) + Index += 1 + if Index == VertexCount: + Config.File.write(";\n") + else: + Config.File.write(",\n") + + Index = 0 + Config.File.write("{}{};\n".format(" " * Config.Whitespace, len(Mesh.faces))) + for Face in Mesh.faces: - Config.File.write("{}{};".format(" "*Config.Whitespace,len(Face.verts))) + Config.File.write("{}{};".format(" " * Config.Whitespace, len(Face.verts))) for Vertex in Face.verts: Config.File.write("{};".format(Index)) - Index+=1 - if Index==VertexCount: Config.File.write(";\n") - else: Config.File.write(",\n") - Config.Whitespace-=1 - Config.File.write("{}}} //End of {} Normals\n".format(" "*Config.Whitespace,LegalName(Mesh.name))) - -def WriteMeshMaterials(Config,Mesh): - Config.File.write("{}MeshMaterialList {{ //{} Material List\n".format(" "*Config.Whitespace,LegalName(Mesh.name))) - Config.Whitespace+=1 - - Materials=Mesh.materials + Index += 1 + if Index == VertexCount: + Config.File.write(";\n") + else: + Config.File.write(",\n") + Config.Whitespace -= 1 + Config.File.write("{}}} //End of {} Normals\n".format(" " * Config.Whitespace, LegalName(Mesh.name))) + + +def WriteMeshMaterials(Config, Mesh): + Config.File.write("{}MeshMaterialList {{ //{} Material List\n".format(" " * Config.Whitespace, LegalName(Mesh.name))) + Config.Whitespace += 1 + + Materials = Mesh.materials if Materials.keys(): - MaterialIndexes={} + MaterialIndexes = {} for Face in Mesh.faces: if Materials[Face.material_index] not in MaterialIndexes: - MaterialIndexes[Materials[Face.material_index]]=len(MaterialIndexes) - - FaceCount=len(Mesh.faces) - Index=0 - Config.File.write("{}{};\n{}{};\n".format(" "*Config.Whitespace,len(MaterialIndexes)," "*Config.Whitespace,FaceCount)) + MaterialIndexes[Materials[Face.material_index]] = len(MaterialIndexes) + + FaceCount = len(Mesh.faces) + Index = 0 + Config.File.write("{}{};\n{}{};\n".format(" " * Config.Whitespace, len(MaterialIndexes), " " * Config.Whitespace, FaceCount)) for Face in Mesh.faces: - Config.File.write("{}{}".format(" "*Config.Whitespace,MaterialIndexes[Materials[Face.material_index]])) - Index+=1 - if Index==FaceCount: Config.File.write(";;\n") - else: Config.File.write(",\n") - - Materials=[Item[::-1] for Item in MaterialIndexes.items()] + Config.File.write("{}{}".format(" " * Config.Whitespace, MaterialIndexes[Materials[Face.material_index]])) + Index += 1 + if Index == FaceCount: + Config.File.write(";;\n") + else: + Config.File.write(",\n") + + Materials = [Item[::-1] for Item in MaterialIndexes.items()] Materials.sort() for Material in Materials: - WriteMaterial(Config,Material[1]) + WriteMaterial(Config, Material[1]) else: - Config.File.write("{}1;\n{}1;\n{}0;;\n".format(" "*Config.Whitespace," "*Config.Whitespace," "*Config.Whitespace)) + Config.File.write("{}1;\n{}1;\n{}0;;\n".format(" " * Config.Whitespace, " " * Config.Whitespace, " " * Config.Whitespace)) WriteMaterial(Config) - - Config.Whitespace-=1 - Config.File.write("{}}} //End of {} Material List\n".format(" "*Config.Whitespace,LegalName(Mesh.name))) -def WriteMaterial(Config,Material=None): + Config.Whitespace -= 1 + Config.File.write("{}}} //End of {} Material List\n".format(" " * Config.Whitespace, LegalName(Mesh.name))) + + +def WriteMaterial(Config, Material=None): if Material: - Config.File.write("{}Material {} {{\n".format(" "*Config.Whitespace,LegalName(Material.name))) - Config.Whitespace+=1 - - Diffuse=list(Material.diffuse_color) + Config.File.write("{}Material {} {{\n".format(" " * Config.Whitespace, LegalName(Material.name))) + Config.Whitespace += 1 + + Diffuse = list(Material.diffuse_color) Diffuse.append(Material.alpha) - Specularity=Material.specular_intensity - Specular=list(Material.specular_color) - - Config.File.write("{}{:9f};{:9f};{:9f};{:9f};;\n".format(" "*Config.Whitespace,Diffuse[0],Diffuse[1],Diffuse[2],Diffuse[3])) - Config.File.write("{}{:9f};\n".format(" "*Config.Whitespace,2*(1.0-Specularity))) - Config.File.write("{}{:9f};{:9f};{:9f};;\n".format(" "*Config.Whitespace,Specular[0],Specular[1],Specular[2])) + Specularity = Material.specular_intensity + Specular = list(Material.specular_color) + + Config.File.write("{}{:9f};{:9f};{:9f};{:9f};;\n".format(" " * Config.Whitespace, Diffuse[0], Diffuse[1], Diffuse[2], Diffuse[3])) + Config.File.write("{}{:9f};\n".format(" " * Config.Whitespace, 2 * (1.0 - Specularity))) + Config.File.write("{}{:9f};{:9f};{:9f};;\n".format(" " * Config.Whitespace, Specular[0], Specular[1], Specular[2])) else: - Config.File.write("{}Material Default_Material {{\n".format(" "*Config.Whitespace)) - Config.Whitespace+=1 - Config.File.write("{} 1.000000; 1.000000; 1.000000; 1.000000;;\n".format(" "*Config.Whitespace)) - Config.File.write("{} 1.500000;\n".format(" "*Config.Whitespace)) - Config.File.write("{} 1.000000; 1.000000; 1.000000;;\n".format(" "*Config.Whitespace)) - Config.File.write("{} 0.000000; 0.000000; 0.000000;;\n".format(" "*Config.Whitespace)) + Config.File.write("{}Material Default_Material {{\n".format(" " * Config.Whitespace)) + Config.Whitespace += 1 + Config.File.write("{} 1.000000; 1.000000; 1.000000; 1.000000;;\n".format(" " * Config.Whitespace)) + Config.File.write("{} 1.500000;\n".format(" " * Config.Whitespace)) + Config.File.write("{} 1.000000; 1.000000; 1.000000;;\n".format(" " * Config.Whitespace)) + Config.File.write("{} 0.000000; 0.000000; 0.000000;;\n".format(" " * Config.Whitespace)) if Config.ExportTextures: - Texture=GetMaterialTexture(Material) - if Texture: Config.File.write("{}TextureFilename {{\"{}\";}}\n".format(" "*Config.Whitespace,Texture)) - Config.Whitespace-=1 - Config.File.write("{}}}\n".format(" "*Config.Whitespace)) - -def WriteMeshUVCoordinates(Config,Mesh): - Config.File.write("{}MeshTextureCoords {{ //{} UV Coordinates\n".format(" "*Config.Whitespace,LegalName(Mesh.name))) - Config.Whitespace+=1 - - UVCoordinates=None + Texture = GetMaterialTexture(Material) + if Texture: + Config.File.write("{}TextureFilename {{\"{}\";}}\n".format(" " * Config.Whitespace, Texture)) + Config.Whitespace -= 1 + Config.File.write("{}}}\n".format(" " * Config.Whitespace)) + + +def WriteMeshUVCoordinates(Config, Mesh): + Config.File.write("{}MeshTextureCoords {{ //{} UV Coordinates\n".format(" " * Config.Whitespace, LegalName(Mesh.name))) + Config.Whitespace += 1 + + UVCoordinates = None for UV in Mesh.uv_textures: if UV.active_render: - UVCoordinates=UV.data + UVCoordinates = UV.data break - - Index=0 - VertexCount=GetMeshVertexCount(Mesh) - Config.File.write("{}{};\n".format(" "*Config.Whitespace,VertexCount)) - + + Index = 0 + VertexCount = GetMeshVertexCount(Mesh) + Config.File.write("{}{};\n".format(" " * Config.Whitespace, VertexCount)) + for Face in UVCoordinates: - Vertices=[] + Vertices = [] for Vertex in Face.uv: Vertices.append(tuple(Vertex)) - if Config.CoordinateSystem==1: - Vertices=Vertices[::-1] + if Config.CoordinateSystem == 1: + Vertices = Vertices[::-1] for Vertex in Vertices: - Config.File.write("{}{:9f};{:9f};".format(" "*Config.Whitespace,Vertex[0],1-Vertex[1])) - Index+=1 - if Index==VertexCount: Config.File.write(";\n") - else: Config.File.write(",\n") - Config.Whitespace-=1 - Config.File.write("{}}} //End of {} UV Coordinates\n".format(" "*Config.Whitespace,LegalName(Mesh.name))) - -def WriteMeshSkinWeights(Config,Object,Mesh): - ArmatureList=[Modifier for Modifier in Object.modifiers if Modifier.type=="ARMATURE"] + Config.File.write("{}{:9f};{:9f};".format(" " * Config.Whitespace, Vertex[0], 1 - Vertex[1])) + Index += 1 + if Index == VertexCount: + Config.File.write(";\n") + else: + Config.File.write(",\n") + Config.Whitespace -= 1 + Config.File.write("{}}} //End of {} UV Coordinates\n".format(" " * Config.Whitespace, LegalName(Mesh.name))) + + +def WriteMeshSkinWeights(Config, Object, Mesh): + ArmatureList = [Modifier for Modifier in Object.modifiers if Modifier.type == "ARMATURE"] if ArmatureList: - ArmatureObject=ArmatureList[0].object - Armature=ArmatureObject.data - - PoseBones=ArmatureObject.pose.bones - - MaxInfluences=0 - UsedBones=set() - VertexGroups={} - + ArmatureObject = ArmatureList[0].object + Armature = ArmatureObject.data + + PoseBones = ArmatureObject.pose.bones + + MaxInfluences = 0 + UsedBones = set() + VertexGroups = {} + for Vertex in Mesh.verts: - 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) + 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) for Bone in BoneInfluences: UsedBones.add(Bone) if Bone not in VertexGroups: - VertexGroups[Bone]=[Vertex] + VertexGroups[Bone] = [Vertex] else: VertexGroups[Bone].append(Vertex) - BoneCount=len(UsedBones) - - Config.File.write("{}XSkinMeshHeader {{\n".format(" "*Config.Whitespace)) - Config.Whitespace+=1 - Config.File.write("{}{};\n{}{};\n{}{};\n".format(" "*Config.Whitespace,MaxInfluences," "*Config.Whitespace,MaxInfluences*3," "*Config.Whitespace,BoneCount)) - Config.Whitespace-=1 - Config.File.write("{}}}\n".format(" "*Config.Whitespace)) - + BoneCount = len(UsedBones) + + Config.File.write("{}XSkinMeshHeader {{\n".format(" " * Config.Whitespace)) + Config.Whitespace += 1 + Config.File.write("{}{};\n{}{};\n{}{};\n".format(" " * Config.Whitespace, MaxInfluences, " " * Config.Whitespace, MaxInfluences * 3, " " * Config.Whitespace, BoneCount)) + Config.Whitespace -= 1 + Config.File.write("{}}}\n".format(" " * Config.Whitespace)) + for Bone in UsedBones: - VertexCount=0 - VertexIndexes=[Vertex.index for Vertex in VertexGroups[Bone]] + VertexCount = 0 + VertexIndexes = [Vertex.index for Vertex in VertexGroups[Bone]] for Face in Mesh.faces: for Vertex in Face.verts: - if Vertex in VertexIndexes: VertexCount+=1 - - Config.File.write("{}SkinWeights {{\n".format(" "*Config.Whitespace)) - Config.Whitespace+=1 - Config.File.write("{}\"{}\";\n{}{};\n".format(" "*Config.Whitespace,LegalName(ArmatureObject.name)+"_"+LegalName(Bone.name)," "*Config.Whitespace,VertexCount)) - - VertexWeights=[] - Index=0 - WrittenIndexes=0 + if Vertex in VertexIndexes: + VertexCount += 1 + + Config.File.write("{}SkinWeights {{\n".format(" " * Config.Whitespace)) + Config.Whitespace += 1 + Config.File.write("{}\"{}\";\n{}{};\n".format(" " * Config.Whitespace, LegalName(ArmatureObject.name) + "_" + LegalName(Bone.name), " " * Config.Whitespace, VertexCount)) + + VertexWeights = [] + Index = 0 + WrittenIndexes = 0 for Face in Mesh.faces: - FaceVertices=list(Face.verts) - if Config.CoordinateSystem==1: FaceVertices=FaceVertices[::-1] + FaceVertices = list(Face.verts) + if Config.CoordinateSystem == 1: + FaceVertices = FaceVertices[::-1] for Vertex in FaceVertices: if Vertex in VertexIndexes: - Config.File.write("{}{}".format(" "*Config.Whitespace,Index)) - - GroupIndexes={Object.vertex_groups[Group.group].name:Index for Index,Group in enumerate(Mesh.verts[Vertex].groups) if Object.vertex_groups[Group.group].name in PoseBones} - - WeightTotal=0.0 + Config.File.write("{}{}".format(" " * Config.Whitespace, Index)) + + GroupIndexes = {Object.vertex_groups[Group.group].name: Index for Index, Group in enumerate(Mesh.verts[Vertex].groups) if Object.vertex_groups[Group.group].name in PoseBones} + + WeightTotal = 0.0 for Weight in [Group.weight for Group in Mesh.verts[Vertex].groups if Object.vertex_groups[Group.group].name in PoseBones]: - WeightTotal+=Weight - + WeightTotal += Weight + if WeightTotal: - VertexWeights.append(Mesh.verts[Vertex].groups[GroupIndexes[Bone.name]].weight/WeightTotal) + VertexWeights.append(Mesh.verts[Vertex].groups[GroupIndexes[Bone.name]].weight / WeightTotal) else: VertexWeights.append(0.0) - - WrittenIndexes+=1 - if WrittenIndexes==VertexCount: Config.File.write(";\n") - else: Config.File.write(",\n") - Index+=1 - - for Index,Weight in enumerate(VertexWeights): - Config.File.write("{}{:8f}".format(" "*Config.Whitespace,Weight)) - if Index==(VertexCount-1): Config.File.write(";\n") - else: Config.File.write(",\n") - - PoseBone=PoseBones[Bone.name] - - BoneMatrix=(PoseBone.matrix*RotationMatrix(radians(-90),4,"X")).invert() - BoneMatrix*=ArmatureObject.matrix_world.copy().invert() - - if Object.parent and Object.parent!=ArmatureObject: - BoneMatrix*=Object.parent.matrix_world.copy().invert() - - BoneMatrix*=Object.matrix_world - - BoneMatrix=Config.SystemMatrix*BoneMatrix*Config.InverseSystemMatrix - - Config.File.write("{}{:9f},{:9f},{:9f},{:9f},\n".format(" "*Config.Whitespace,BoneMatrix[0][0],BoneMatrix[0][1],BoneMatrix[0][2],BoneMatrix[0][3])) - Config.File.write("{}{:9f},{:9f},{:9f},{:9f},\n".format(" "*Config.Whitespace,BoneMatrix[1][0],BoneMatrix[1][1],BoneMatrix[1][2],BoneMatrix[1][3])) - Config.File.write("{}{:9f},{:9f},{:9f},{:9f},\n".format(" "*Config.Whitespace,BoneMatrix[2][0],BoneMatrix[2][1],BoneMatrix[2][2],BoneMatrix[2][3])) - Config.File.write("{}{:9f},{:9f},{:9f},{:9f};;\n".format(" "*Config.Whitespace,BoneMatrix[3][0],BoneMatrix[3][1],BoneMatrix[3][2],BoneMatrix[3][3])) - Config.Whitespace-=1 - Config.File.write("{}}} //End of {} Skin Weights\n".format(" "*Config.Whitespace,LegalName(ArmatureObject.name)+"_"+LegalName(Bone.name))) - + + WrittenIndexes += 1 + if WrittenIndexes == VertexCount: + Config.File.write(";\n") + else: + Config.File.write(",\n") + Index += 1 + + for Index, Weight in enumerate(VertexWeights): + Config.File.write("{}{:8f}".format(" " * Config.Whitespace, Weight)) + if Index == (VertexCount - 1): + Config.File.write(";\n") + else: + Config.File.write(",\n") + + PoseBone = PoseBones[Bone.name] + + BoneMatrix = (PoseBone.matrix * RotationMatrix(radians(-90), 4, "X")).invert() + BoneMatrix *= ArmatureObject.matrix_world.copy().invert() + + if Object.parent and Object.parent != ArmatureObject: + BoneMatrix *= Object.parent.matrix_world.copy().invert() + + BoneMatrix *= Object.matrix_world + + BoneMatrix = Config.SystemMatrix * BoneMatrix * Config.InverseSystemMatrix + + Config.File.write("{}{:9f},{:9f},{:9f},{:9f},\n".format(" " * Config.Whitespace, BoneMatrix[0][0], BoneMatrix[0][1], BoneMatrix[0][2], BoneMatrix[0][3])) + Config.File.write("{}{:9f},{:9f},{:9f},{:9f},\n".format(" " * Config.Whitespace, BoneMatrix[1][0], BoneMatrix[1][1], BoneMatrix[1][2], BoneMatrix[1][3])) + Config.File.write("{}{:9f},{:9f},{:9f},{:9f},\n".format(" " * Config.Whitespace, BoneMatrix[2][0], BoneMatrix[2][1], BoneMatrix[2][2], BoneMatrix[2][3])) + Config.File.write("{}{:9f},{:9f},{:9f},{:9f};;\n".format(" " * Config.Whitespace, BoneMatrix[3][0], BoneMatrix[3][1], BoneMatrix[3][2], BoneMatrix[3][3])) + Config.Whitespace -= 1 + Config.File.write("{}}} //End of {} Skin Weights\n".format(" " * Config.Whitespace, LegalName(ArmatureObject.name) + "_" + LegalName(Bone.name))) + def WriteAnimationSet(Config): - Config.File.write("{}AnimationSet {{\n".format(" "*Config.Whitespace)) - Config.Whitespace+=1 + Config.File.write("{}AnimationSet {{\n".format(" " * Config.Whitespace)) + Config.Whitespace += 1 for Object in [Object for Object in Config.ObjectList if Object.animation_data]: - if Config.Verbose: print(" Writing Animation Data for Object: {}".format(Object.name)) - Action=Object.animation_data.action + if Config.Verbose: + print(" Writing Animation Data for Object: {}".format(Object.name)) + Action = Object.animation_data.action if Action: - PositionFCurves=[None,None,None] - RotationFCurves=[None,None,None] - ScaleFCurves=[None,None,None] + PositionFCurves = [None, None, None] + RotationFCurves = [None, None, None] + ScaleFCurves = [None, None, None] for FCurve in Action.fcurves: - if FCurve.data_path=="location": - PositionFCurves[FCurve.array_index]=FCurve - elif FCurve.data_path=="rotation_euler": - RotationFCurves[FCurve.array_index]=FCurve - elif FCurve.data_path=="scale": - ScaleFCurves[FCurve.array_index]=FCurve - if [FCurve for FCurve in PositionFCurves+RotationFCurves+ScaleFCurves if FCurve]: - Config.File.write("{}Animation {{\n".format(" "*Config.Whitespace)) - Config.Whitespace+=1 - Config.File.write("{}{{{}}}\n".format(" "*Config.Whitespace,LegalName(Object.name))) - + if FCurve.data_path == "location": + PositionFCurves[FCurve.array_index] = FCurve + elif FCurve.data_path == "rotation_euler": + RotationFCurves[FCurve.array_index] = FCurve + elif FCurve.data_path == "scale": + ScaleFCurves[FCurve.array_index] = FCurve + if [FCurve for FCurve in PositionFCurves + RotationFCurves + ScaleFCurves if FCurve]: + Config.File.write("{}Animation {{\n".format(" " * Config.Whitespace)) + Config.Whitespace += 1 + Config.File.write("{}{{{}}}\n".format(" " * Config.Whitespace, LegalName(Object.name))) + #Position - if Config.Verbose: print(" Writing Position...",end=" ") - AllKeyframes=set() - for Index,FCurve in enumerate(PositionFCurves): + if Config.Verbose: + print(" Writing Position...", end=" ") + AllKeyframes = set() + for Index, FCurve in enumerate(PositionFCurves): if FCurve: - Keyframes=[] + Keyframes = [] for Keyframe in FCurve.keyframe_points: Keyframes.append(Keyframe.co) AllKeyframes.add(int(Keyframe.co[0])) - PositionFCurves[Index]={int(Keyframe):Value for Keyframe,Value in Keyframes} - Config.File.write("{}AnimationKey {{ //Position\n".format(" "*Config.Whitespace)) - Config.Whitespace+=1 - AllKeyframes=list(AllKeyframes) + PositionFCurves[Index] = {int(Keyframe): Value for Keyframe, Value in Keyframes} + Config.File.write("{}AnimationKey {{ //Position\n".format(" " * Config.Whitespace)) + Config.Whitespace += 1 + AllKeyframes = list(AllKeyframes) AllKeyframes.sort() if len(AllKeyframes): - Config.File.write("{}2;\n{}{};\n".format(" "*Config.Whitespace," "*Config.Whitespace,len(AllKeyframes))) + Config.File.write("{}2;\n{}{};\n".format(" " * Config.Whitespace, " " * Config.Whitespace, len(AllKeyframes))) for Keyframe in AllKeyframes: bpy.context.scene.set_frame(Keyframe) - Position=Vector() - Position[0]=((PositionFCurves[0][Keyframe] if Keyframe in PositionFCurves[0] else Object.location[0]) if PositionFCurves[0] else Object.location[0]) - Position[1]=((PositionFCurves[1][Keyframe] if Keyframe in PositionFCurves[1] else Object.location[1]) if PositionFCurves[1] else Object.location[1]) - Position[2]=((PositionFCurves[2][Keyframe] if Keyframe in PositionFCurves[2] else Object.location[2]) if PositionFCurves[2] else Object.location[2]) - Position=Config.SystemMatrix*Position - Config.File.write("{}{}{:9f},{:9f},{:9f};;\n".format(" "*Config.Whitespace,(str(Keyframe-bpy.context.scene.frame_start)+";3;").ljust(8),Position[0],Position[1],Position[2])) + Position = Vector() + Position[0] = ((PositionFCurves[0][Keyframe] if Keyframe in PositionFCurves[0] else Object.location[0]) if PositionFCurves[0] else Object.location[0]) + Position[1] = ((PositionFCurves[1][Keyframe] if Keyframe in PositionFCurves[1] else Object.location[1]) if PositionFCurves[1] else Object.location[1]) + Position[2] = ((PositionFCurves[2][Keyframe] if Keyframe in PositionFCurves[2] else Object.location[2]) if PositionFCurves[2] else Object.location[2]) + Position = Config.SystemMatrix * Position + Config.File.write("{}{}{:9f},{:9f},{:9f};;\n".format(" " * Config.Whitespace, (str(Keyframe - bpy.context.scene.frame_start) + ";3;").ljust(8), Position[0], Position[1], Position[2])) else: - Config.File.write("{}2;\n{}1;\n".format(" "*Config.Whitespace," "*Config.Whitespace)) + Config.File.write("{}2;\n{}1;\n".format(" " * Config.Whitespace, " " * Config.Whitespace)) bpy.context.scene.set_frame(bpy.context.scene.frame_start) - Position=Config.SystemMatrix*Object.location - Config.File.write("{}{}{:9f},{:9f},{:9f};;\n".format(" "*Config.Whitespace,("0;3;").ljust(8),Position[0],Position[1],Position[2])) - Config.Whitespace-=1 - Config.File.write("{}}}\n".format(" "*Config.Whitespace)) - if Config.Verbose: print("Done") - + Position = Config.SystemMatrix * Object.location + Config.File.write("{}{}{:9f},{:9f},{:9f};;\n".format(" " * Config.Whitespace, ("0;3;").ljust(8), Position[0], Position[1], Position[2])) + Config.Whitespace -= 1 + Config.File.write("{}}}\n".format(" " * Config.Whitespace)) + if Config.Verbose: + print("Done") + #Rotation - if Config.Verbose: print(" Writing Rotation...",end=" ") - AllKeyframes=set() - for Index,FCurve in enumerate(RotationFCurves): + if Config.Verbose: + print(" Writing Rotation...", end=" ") + AllKeyframes = set() + for Index, FCurve in enumerate(RotationFCurves): if FCurve: - Keyframes=[] + Keyframes = [] for Keyframe in FCurve.keyframe_points: Keyframes.append(Keyframe.co) AllKeyframes.add(int(Keyframe.co[0])) - RotationFCurves[Index]={int(Keyframe):Value for Keyframe,Value in Keyframes} - Config.File.write("{}AnimationKey {{ //Rotation\n".format(" "*Config.Whitespace)) - Config.Whitespace+=1 - AllKeyframes=list(AllKeyframes) + RotationFCurves[Index] = {int(Keyframe): Value for Keyframe, Value in Keyframes} + Config.File.write("{}AnimationKey {{ //Rotation\n".format(" " * Config.Whitespace)) + Config.Whitespace += 1 + AllKeyframes = list(AllKeyframes) AllKeyframes.sort() if len(AllKeyframes): - Config.File.write("{}0;\n{}{};\n".format(" "*Config.Whitespace," "*Config.Whitespace,len(AllKeyframes))) + Config.File.write("{}0;\n{}{};\n".format(" " * Config.Whitespace, " " * Config.Whitespace, len(AllKeyframes))) for Keyframe in AllKeyframes: bpy.context.scene.set_frame(Keyframe) - Rotation=Euler() - Rotation[0]=((RotationFCurves[0][Keyframe] if Keyframe in RotationFCurves[0] else Object.rotation_euler[0]) if RotationFCurves[0] else Object.rotation_euler[0]) - Rotation[1]=((RotationFCurves[1][Keyframe] if Keyframe in RotationFCurves[1] else Object.rotation_euler[1]) if RotationFCurves[1] else Object.rotation_euler[1]) - Rotation[2]=((RotationFCurves[2][Keyframe] if Keyframe in RotationFCurves[2] else Object.rotation_euler[2]) if RotationFCurves[2] else Object.rotation_euler[2]) - Rotation=(Config.SystemMatrix*(Rotation.to_matrix().to_4x4())*Config.InverseSystemMatrix).to_quat() - Config.File.write("{}{}{:9f},{:9f},{:9f},{:9f};;\n".format(" "*Config.Whitespace,(str(Keyframe-bpy.context.scene.frame_start)+";4;").ljust(8),-Rotation[0],Rotation[1],Rotation[2],Rotation[3])) + Rotation = Euler() + Rotation[0] = ((RotationFCurves[0][Keyframe] if Keyframe in RotationFCurves[0] else Object.rotation_euler[0]) if RotationFCurves[0] else Object.rotation_euler[0]) + Rotation[1] = ((RotationFCurves[1][Keyframe] if Keyframe in RotationFCurves[1] else Object.rotation_euler[1]) if RotationFCurves[1] else Object.rotation_euler[1]) + Rotation[2] = ((RotationFCurves[2][Keyframe] if Keyframe in RotationFCurves[2] else Object.rotation_euler[2]) if RotationFCurves[2] else Object.rotation_euler[2]) + Rotation = (Config.SystemMatrix * (Rotation.to_matrix().to_4x4()) * Config.InverseSystemMatrix).to_quat() + Config.File.write("{}{}{:9f},{:9f},{:9f},{:9f};;\n".format(" " * Config.Whitespace, (str(Keyframe - bpy.context.scene.frame_start) + ";4;").ljust(8), - Rotation[0], Rotation[1], Rotation[2], Rotation[3])) else: - Config.File.write("{}0;\n{}1;\n".format(" "*Config.Whitespace," "*Config.Whitespace)) + Config.File.write("{}0;\n{}1;\n".format(" " * Config.Whitespace, " " * Config.Whitespace)) bpy.context.scene.set_frame(bpy.context.scene.frame_start) - 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,("0;4;").ljust(8),-Rotation[0],Rotation[1],Rotation[2],Rotation[3])) - Config.Whitespace-=1 - Config.File.write("{}}}\n".format(" "*Config.Whitespace)) - if Config.Verbose: print("Done") - + 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, ("0;4;").ljust(8), -Rotation[0], Rotation[1], Rotation[2], Rotation[3])) + Config.Whitespace -= 1 + Config.File.write("{}}}\n".format(" " * Config.Whitespace)) + if Config.Verbose: + print("Done") + #Scale - if Config.Verbose: print(" Writing Scale...",end=" ") - AllKeyframes=set() - for Index,FCurve in enumerate(ScaleFCurves): + if Config.Verbose: + print(" Writing Scale...", end=" ") + AllKeyframes = set() + for Index, FCurve in enumerate(ScaleFCurves): if FCurve: - Keyframes=[] + Keyframes = [] for Keyframe in FCurve.keyframe_points: Keyframes.append(Keyframe.co) AllKeyframes.add(int(Keyframe.co[0])) - ScaleFCurves[Index]={int(Keyframe):Value for Keyframe,Value in Keyframes} - Config.File.write("{}AnimationKey {{ //Scale\n".format(" "*Config.Whitespace)) - Config.Whitespace+=1 - AllKeyframes=list(AllKeyframes) + ScaleFCurves[Index] = {int(Keyframe): Value for Keyframe, Value in Keyframes} + Config.File.write("{}AnimationKey {{ //Scale\n".format(" " * Config.Whitespace)) + Config.Whitespace += 1 + AllKeyframes = list(AllKeyframes) AllKeyframes.sort() if len(AllKeyframes): - Config.File.write("{}1;\n{}{};\n".format(" "*Config.Whitespace," "*Config.Whitespace,len(AllKeyframes))) + Config.File.write("{}1;\n{}{};\n".format(" " * Config.Whitespace, " " * Config.Whitespace, len(AllKeyframes))) for Keyframe in AllKeyframes: bpy.context.scene.set_frame(Keyframe) - Scale=Vector() - Scale[0]=((ScaleFCurves[0][Keyframe] if Keyframe in ScaleFCurves[0] else Object.scale[0]) if ScaleFCurves[0] else Object.scale[0]) - Scale[1]=((ScaleFCurves[1][Keyframe] if Keyframe in ScaleFCurves[1] else Object.scale[1]) if ScaleFCurves[1] else Object.scale[1]) - Scale[2]=((ScaleFCurves[2][Keyframe] if Keyframe in ScaleFCurves[2] else Object.scale[2]) if ScaleFCurves[2] else Object.scale[2]) - Scale=Config.SystemMatrix*Scale - Config.File.write("{}{}{:9f},{:9f},{:9f};;\n".format(" "*Config.Whitespace,(str(Keyframe-bpy.context.scene.frame_start)+";3;").ljust(8),Scale[0],Scale[1],Scale[2])) + Scale = Vector() + Scale[0] = ((ScaleFCurves[0][Keyframe] if Keyframe in ScaleFCurves[0] else Object.scale[0]) if ScaleFCurves[0] else Object.scale[0]) + Scale[1] = ((ScaleFCurves[1][Keyframe] if Keyframe in ScaleFCurves[1] else Object.scale[1]) if ScaleFCurves[1] else Object.scale[1]) + Scale[2] = ((ScaleFCurves[2][Keyframe] if Keyframe in ScaleFCurves[2] else Object.scale[2]) if ScaleFCurves[2] else Object.scale[2]) + Scale = Config.SystemMatrix * Scale + Config.File.write("{}{}{:9f},{:9f},{:9f};;\n".format(" " * Config.Whitespace, (str(Keyframe - bpy.context.scene.frame_start) + ";3;").ljust(8), Scale[0], Scale[1], Scale[2])) else: - Config.File.write("{}1;\n{}1;\n".format(" "*Config.Whitespace," "*Config.Whitespace)) + Config.File.write("{}1;\n{}1;\n".format(" " * Config.Whitespace, " " * Config.Whitespace)) bpy.context.scene.set_frame(bpy.context.scene.frame_start) - Scale=Config.SystemMatrix*Object.scale - Config.File.write("{}{}{:9f},{:9f},{:9f};;\n".format(" "*Config.Whitespace,("0;3;").ljust(8),Scale[0],Scale[1],Scale[2])) - Config.Whitespace-=1 - Config.File.write("{}}}\n".format(" "*Config.Whitespace)) - if Config.Verbose: print("Done") - - Config.Whitespace-=1 - Config.File.write("{}}}\n".format(" "*Config.Whitespace)) + Scale = Config.SystemMatrix * Object.scale + Config.File.write("{}{}{:9f},{:9f},{:9f};;\n".format(" " * Config.Whitespace, ("0;3;").ljust(8), Scale[0], Scale[1], Scale[2])) + Config.Whitespace -= 1 + Config.File.write("{}}}\n".format(" " * Config.Whitespace)) + if Config.Verbose: + print("Done") + + Config.Whitespace -= 1 + Config.File.write("{}}}\n".format(" " * Config.Whitespace)) else: - if Config.Verbose: print(" Object has no useable animation data.") - - if Config.ExportArmatures and Object.type=="ARMATURE": - if Config.Verbose: print(" Writing Armature Bone Animation Data...") - PoseBones=Object.pose.bones + if Config.Verbose: + print(" Object has no useable animation data.") + + if Config.ExportArmatures and Object.type == "ARMATURE": + if Config.Verbose: + print(" Writing Armature Bone Animation Data...") + PoseBones = Object.pose.bones for Bone in PoseBones: - if Config.Verbose: print(" Writing Bone: {}...".format(Bone.name)) - PositionFCurves=[None,None,None] - RotationFCurves=[None,None,None,None] - ScaleFCurves=[None,None,None] + if Config.Verbose: + print(" Writing Bone: {}...".format(Bone.name)) + PositionFCurves = [None, None, None] + RotationFCurves = [None, None, None, None] + ScaleFCurves = [None, None, None] for FCurve in Action.fcurves: - if FCurve.data_path=="pose.bones[\"{}\"].location".format(Bone.name): - PositionFCurves[FCurve.array_index]=FCurve - elif FCurve.data_path=="pose.bones[\"{}\"].rotation_quaternion".format(Bone.name): - RotationFCurves[FCurve.array_index]=FCurve - elif FCurve.data_path=="pose.bones[\"{}\"].scale".format(Bone.name): - ScaleFCurves[FCurve.array_index]=FCurve - if not [FCurve for FCurve in PositionFCurves+RotationFCurves+ScaleFCurves if FCurve]: - if Config.Verbose: print(" Bone has no useable animation data.\n Done") + if FCurve.data_path == "pose.bones[\"{}\"].location".format(Bone.name): + PositionFCurves[FCurve.array_index] = FCurve + elif FCurve.data_path == "pose.bones[\"{}\"].rotation_quaternion".format(Bone.name): + RotationFCurves[FCurve.array_index] = FCurve + elif FCurve.data_path == "pose.bones[\"{}\"].scale".format(Bone.name): + ScaleFCurves[FCurve.array_index] = FCurve + if not [FCurve for FCurve in PositionFCurves + RotationFCurves + ScaleFCurves if FCurve]: + if Config.Verbose: + print(" Bone has no useable animation data.\n Done") continue - - Config.File.write("{}Animation {{\n".format(" "*Config.Whitespace)) - Config.Whitespace+=1 - Config.File.write("{}{{{}}}\n".format(" "*Config.Whitespace,LegalName(Object.name)+"_"+LegalName(Bone.name))) - + + Config.File.write("{}Animation {{\n".format(" " * Config.Whitespace)) + Config.Whitespace += 1 + Config.File.write("{}{{{}}}\n".format(" " * Config.Whitespace, LegalName(Object.name) + "_" + LegalName(Bone.name))) + #Position - if Config.Verbose: print(" Writing Position...",end=" ") - AllKeyframes=set() - for Index,FCurve in enumerate(PositionFCurves): + if Config.Verbose: + print(" Writing Position...", end=" ") + AllKeyframes = set() + for Index, FCurve in enumerate(PositionFCurves): if FCurve: - Keyframes=[] + Keyframes = [] for Keyframe in FCurve.keyframe_points: Keyframes.append(Keyframe.co) AllKeyframes.add(int(Keyframe.co[0])) - PositionFCurves[Index]={int(Keyframe):Value for Keyframe,Value in Keyframes} - Config.File.write("{}AnimationKey {{ //Position\n".format(" "*Config.Whitespace)) - Config.Whitespace+=1 - AllKeyframes=list(AllKeyframes) + PositionFCurves[Index] = {int(Keyframe): Value for Keyframe, Value in Keyframes} + Config.File.write("{}AnimationKey {{ //Position\n".format(" " * Config.Whitespace)) + Config.Whitespace += 1 + AllKeyframes = list(AllKeyframes) AllKeyframes.sort() if not len(AllKeyframes): - AllKeyframes=[bpy.context.scene.frame_start] - Config.File.write("{}2;\n{}{};\n".format(" "*Config.Whitespace," "*Config.Whitespace,len(AllKeyframes))) + AllKeyframes = [bpy.context.scene.frame_start] + Config.File.write("{}2;\n{}{};\n".format(" " * Config.Whitespace, " " * Config.Whitespace, len(AllKeyframes))) for Keyframe in AllKeyframes: bpy.context.scene.set_frame(Keyframe) - + if Bone.parent: - PoseMatrix=(Bone.parent.matrix*RotationMatrix(radians(-90),4,"X")).invert() + PoseMatrix = (Bone.parent.matrix * RotationMatrix(radians(-90), 4, "X")).invert() else: - PoseMatrix=Matrix() - PoseMatrix*=Bone.matrix*RotationMatrix(radians(-90),4,"X") - - PoseMatrix=Config.SystemMatrix*PoseMatrix*Config.InverseSystemMatrix - - Position=PoseMatrix.translation_part() - Config.File.write("{}{}{:9f},{:9f},{:9f};;\n".format(" "*Config.Whitespace,(str(Keyframe-bpy.context.scene.frame_start)+";3;").ljust(8),Position[0],Position[1],Position[2])) - Config.Whitespace-=1 - Config.File.write("{}}}\n".format(" "*Config.Whitespace)) - if Config.Verbose: print("Done") - + PoseMatrix = Matrix() + PoseMatrix *= Bone.matrix * RotationMatrix(radians(-90), 4, "X") + + PoseMatrix = Config.SystemMatrix * PoseMatrix * Config.InverseSystemMatrix + + Position = PoseMatrix.translation_part() + Config.File.write("{}{}{:9f},{:9f},{:9f};;\n".format(" " * Config.Whitespace, (str(Keyframe - bpy.context.scene.frame_start) + ";3;").ljust(8), Position[0], Position[1], Position[2])) + Config.Whitespace -= 1 + Config.File.write("{}}}\n".format(" " * Config.Whitespace)) + if Config.Verbose: + print("Done") + #Rotation - if Config.Verbose: print(" Writing Rotation...",end=" ") - AllKeyframes=set() - for Index,FCurve in enumerate(RotationFCurves): + if Config.Verbose: + print(" Writing Rotation...", end=" ") + AllKeyframes = set() + for Index, FCurve in enumerate(RotationFCurves): if FCurve: - Keyframes=[] + Keyframes = [] for Keyframe in FCurve.keyframe_points: Keyframes.append(Keyframe.co) AllKeyframes.add(int(Keyframe.co[0])) - RotationFCurves[Index]={int(Keyframe):Value for Keyframe,Value in Keyframes} - Config.File.write("{}AnimationKey {{ //Rotation\n".format(" "*Config.Whitespace)) - Config.Whitespace+=1 - AllKeyframes=list(AllKeyframes) + RotationFCurves[Index] = {int(Keyframe): Value for Keyframe, Value in Keyframes} + Config.File.write("{}AnimationKey {{ //Rotation\n".format(" " * Config.Whitespace)) + Config.Whitespace += 1 + AllKeyframes = list(AllKeyframes) AllKeyframes.sort() if not len(AllKeyframes): - AllKeyframes=[bpy.context.scene.frame_start] - Config.File.write("{}0;\n{}{};\n".format(" "*Config.Whitespace," "*Config.Whitespace,len(AllKeyframes))) + AllKeyframes = [bpy.context.scene.frame_start] + Config.File.write("{}0;\n{}{};\n".format(" " * Config.Whitespace, " " * Config.Whitespace, len(AllKeyframes))) for Keyframe in AllKeyframes: bpy.context.scene.set_frame(Keyframe) - + if Bone.parent: - PoseMatrix=(Bone.parent.matrix*RotationMatrix(radians(-90),4,"X")).invert() + PoseMatrix = (Bone.parent.matrix * RotationMatrix(radians(-90), 4, "X")).invert() else: - PoseMatrix=Matrix() - PoseMatrix*=Bone.matrix*RotationMatrix(radians(-90),4,"X") - - PoseMatrix=Config.SystemMatrix*PoseMatrix*Config.InverseSystemMatrix - - Rotation=PoseMatrix.rotation_part().to_quat() - Config.File.write("{}{}{:9f},{:9f},{:9f},{:9f};;\n".format(" "*Config.Whitespace,(str(Keyframe-bpy.context.scene.frame_start)+";4;").ljust(8),-Rotation[0],Rotation[1],Rotation[2],Rotation[3])) - Config.Whitespace-=1 - Config.File.write("{}}}\n".format(" "*Config.Whitespace)) - if Config.Verbose: print("Done") - + PoseMatrix = Matrix() + PoseMatrix *= Bone.matrix * RotationMatrix(radians(-90), 4, "X") + + PoseMatrix = Config.SystemMatrix * PoseMatrix * Config.InverseSystemMatrix + + Rotation = PoseMatrix.rotation_part().to_quat() + Config.File.write("{}{}{:9f},{:9f},{:9f},{:9f};;\n".format(" " * Config.Whitespace, (str(Keyframe - bpy.context.scene.frame_start) + ";4;").ljust(8), -Rotation[0], Rotation[1], Rotation[2], Rotation[3])) + Config.Whitespace -= 1 + Config.File.write("{}}}\n".format(" " * Config.Whitespace)) + if Config.Verbose: + print("Done") + #Scale - if Config.Verbose: print(" Writing Scale...",end=" ") - AllKeyframes=set() - for Index,FCurve in enumerate(ScaleFCurves): + if Config.Verbose: + print(" Writing Scale...", end=" ") + AllKeyframes = set() + for Index, FCurve in enumerate(ScaleFCurves): if FCurve: - Keyframes=[] + Keyframes = [] for Keyframe in FCurve.keyframe_points: Keyframes.append(Keyframe.co) AllKeyframes.add(int(Keyframe.co[0])) - ScaleFCurves[Index]={int(Keyframe):Value for Keyframe,Value in Keyframes} - Config.File.write("{}AnimationKey {{ //Scale\n".format(" "*Config.Whitespace)) - Config.Whitespace+=1 - AllKeyframes=list(AllKeyframes) + ScaleFCurves[Index] = {int(Keyframe): Value for Keyframe, Value in Keyframes} + Config.File.write("{}AnimationKey {{ //Scale\n".format(" " * Config.Whitespace)) + Config.Whitespace += 1 + AllKeyframes = list(AllKeyframes) AllKeyframes.sort() if not len(AllKeyframes): - AllKeyframes=[bpy.context.scene.frame_start] - Config.File.write("{}1;\n{}{};\n".format(" "*Config.Whitespace," "*Config.Whitespace,len(AllKeyframes))) + AllKeyframes = [bpy.context.scene.frame_start] + Config.File.write("{}1;\n{}{};\n".format(" " * Config.Whitespace, " " * Config.Whitespace, len(AllKeyframes))) for Keyframe in AllKeyframes: bpy.context.scene.set_frame(Keyframe) - + if Bone.parent: - PoseMatrix=(Bone.parent.matrix*RotationMatrix(radians(-90),4,"X")).invert() + PoseMatrix = (Bone.parent.matrix * RotationMatrix(radians(-90), 4, "X")).invert() else: - PoseMatrix=Matrix() - PoseMatrix*=Bone.matrix*RotationMatrix(radians(-90),4,"X") - - PoseMatrix=Config.SystemMatrix*PoseMatrix*Config.InverseSystemMatrix - - Scale=PoseMatrix.scale_part() - Config.File.write("{}{}{:9f},{:9f},{:9f};;\n".format(" "*Config.Whitespace,(str(Keyframe-bpy.context.scene.frame_start)+";3;").ljust(8),Scale[0],Scale[1],Scale[2])) - Config.Whitespace-=1 - Config.File.write("{}}}\n".format(" "*Config.Whitespace)) - if Config.Verbose: print("Done") - - Config.Whitespace-=1 - Config.File.write("{}}}\n".format(" "*Config.Whitespace)) - if Config.Verbose: print(" Done") - if Config.Verbose: print(" Done") - if Config.Verbose: print(" Done") - - Config.Whitespace-=1 - Config.File.write("{}}} //End of AnimationSet\n".format(" "*Config.Whitespace)) + PoseMatrix = Matrix() + PoseMatrix *= Bone.matrix * RotationMatrix(radians(-90), 4, "X") + + PoseMatrix = Config.SystemMatrix * PoseMatrix * Config.InverseSystemMatrix + + Scale = PoseMatrix.scale_part() + Config.File.write("{}{}{:9f},{:9f},{:9f};;\n".format(" " * Config.Whitespace, (str(Keyframe - bpy.context.scene.frame_start) + ";3;").ljust(8), Scale[0], Scale[1], Scale[2])) + Config.Whitespace -= 1 + Config.File.write("{}}}\n".format(" " * Config.Whitespace)) + if Config.Verbose: + print("Done") + + Config.Whitespace -= 1 + Config.File.write("{}}}\n".format(" " * Config.Whitespace)) + if Config.Verbose: + print(" Done") + if Config.Verbose: + print(" Done") + if Config.Verbose: + print(" Done") + + Config.Whitespace -= 1 + Config.File.write("{}}} //End of AnimationSet\n".format(" " * Config.Whitespace)) + def CloseFile(Config): - if Config.Verbose: print("Closing File...",end=" ") + if Config.Verbose: + print("Closing File...", end=" ") Config.File.close() - if Config.Verbose: print("Done") + if Config.Verbose: + print("Done") -CoordinateSystems=[] -CoordinateSystems.append(("1","Left-Handed","")) -CoordinateSystems.append(("2","Right-Handed","")) +CoordinateSystems = [] +CoordinateSystems.append(("1", "Left-Handed", "")) +CoordinateSystems.append(("2", "Right-Handed", "")) -AnimationModes=[] -AnimationModes.append(("0","None","")) -AnimationModes.append(("1","Keyframes Only","")) -#AnimationModes.append(("2","Full Animation","")) +AnimationModes = [] +AnimationModes.append(("0", "None", "")) +AnimationModes.append(("1", "Keyframes Only", "")) +#AnimationModes.append(("2", "Full Animation", "")) -ExportModes=[] -ExportModes.append(("1","All Objects","")) -ExportModes.append(("2","Selected Objects","")) +ExportModes = [] +ExportModes.append(("1", "All Objects", "")) +ExportModes.append(("2", "Selected Objects", "")) from bpy.props import * + class DirectXExporter(bpy.types.Operator): """Export to the DirectX model format (.x)""" - - bl_idname="export.directx" - bl_label="Export DirectX" - - filepath=StringProperty() - filename=StringProperty() - directory=StringProperty() - + + bl_idname = "export.directx" + bl_label = "Export DirectX" + + filepath = StringProperty() + filename = StringProperty() + directory = StringProperty() + #Coordinate System - CoordinateSystem=EnumProperty(name="System",description="Select a coordinate system to export to",items=CoordinateSystems,default="1") - + CoordinateSystem = EnumProperty(name="System", description="Select a coordinate system to export to", items=CoordinateSystems, default="1") + #General Options - RotateX=BoolProperty(name="Rotate X 90 Degrees",description="Rotate the entire scene 90 degrees around the X axis so Y is up",default=True) - FlipNormals=BoolProperty(name="Flip Normals",description="",default=False) - ApplyModifiers=BoolProperty(name="Apply Modifiers",description="Apply all object modifiers before export.",default=False) - IncludeFrameRate=BoolProperty(name="Include Frame Rate",description="Include the AnimTicksPerSecond template which is used by some engines to control animation speed.",default=False) - ExportTextures=BoolProperty(name="Export Textures",description="Reference external image files to be used by the model",default=True) - ExportArmatures=BoolProperty(name="Export Armatures",description="Export the bones of any armatures to deform meshes. Warning: This option also applies all modifiers.",default=False) - ExportAnimation=EnumProperty(name="Animations",description="Select the type of animations to export. Only object and armature bone animations can be exported.",items=AnimationModes,default="0") - + RotateX = BoolProperty(name="Rotate X 90 Degrees", description="Rotate the entire scene 90 degrees around the X axis so Y is up", default=True) + FlipNormals = BoolProperty(name="Flip Normals", description="", default=False) + ApplyModifiers = BoolProperty(name="Apply Modifiers", description="Apply all object modifiers before export.", default=False) + IncludeFrameRate = BoolProperty(name="Include Frame Rate", description="Include the AnimTicksPerSecond template which is used by some engines to control animation speed.", default=False) + ExportTextures = BoolProperty(name="Export Textures", description="Reference external image files to be used by the model", default=True) + ExportArmatures = BoolProperty(name="Export Armatures", description="Export the bones of any armatures to deform meshes. Warning: This option also applies all modifiers.", default=False) + ExportAnimation = EnumProperty(name="Animations", description="Select the type of animations to export. Only object and armature bone animations can be exported.", items=AnimationModes, default="0") + #Export Mode - ExportMode=EnumProperty(name="Export",description="Select which objects to export. Only Mesh, Empty, and Armature objects will be exported.",items=ExportModes,default="1") - - Verbose=BoolProperty(name="Verbose",description="Run the exporter in debug mode. Check the console for output.",default=False) - - def execute(self,context): + ExportMode = EnumProperty(name="Export", description="Select which objects to export. Only Mesh, Empty, and Armature objects will be exported.", items=ExportModes, default="1") + + Verbose = BoolProperty(name="Verbose", description="Run the exporter in debug mode. Check the console for output.", default=False) + + def execute(self, context): #Append .x if needed - FilePath=self.properties.filepath + FilePath = self.properties.filepath if not FilePath.lower().endswith(".x"): - FilePath+=".x" - - Config=DirectXExporterSettings(context, - FilePath, - CoordinateSystem=self.properties.CoordinateSystem, - RotateX=self.properties.RotateX, - FlipNormals=self.properties.FlipNormals, - ApplyModifiers=self.properties.ApplyModifiers, - IncludeFrameRate=self.properties.IncludeFrameRate, - ExportTextures=self.properties.ExportTextures, - ExportArmatures=self.properties.ExportArmatures, - ExportAnimation=self.properties.ExportAnimation, - ExportMode=self.properties.ExportMode, - Verbose=self.properties.Verbose) + FilePath += ".x" + + Config = DirectXExporterSettings(context, + FilePath, + CoordinateSystem=self.properties.CoordinateSystem, + RotateX=self.properties.RotateX, + FlipNormals=self.properties.FlipNormals, + ApplyModifiers=self.properties.ApplyModifiers, + IncludeFrameRate=self.properties.IncludeFrameRate, + ExportTextures=self.properties.ExportTextures, + ExportArmatures=self.properties.ExportArmatures, + ExportAnimation=self.properties.ExportAnimation, + ExportMode=self.properties.ExportMode, + Verbose=self.properties.Verbose) ExportDirectX(Config) return {"FINISHED"} - - def invoke(self,context,event): - WindowManager=context.manager + + def invoke(self, context, event): + WindowManager = context.manager WindowManager.add_fileselect(self) return {"RUNNING_MODAL"} -def menu_func(self,context): - DefaultPath=bpy.data.filepath + +def menu_func(self, context): + DefaultPath = bpy.data.filepath if DefaultPath.endswith(".blend"): - DefaultPath=DefaultPath[:-6]+".x" - self.layout.operator(DirectXExporter.bl_idname,text="DirectX (.x)").filepath=DefaultPath + DefaultPath = DefaultPath[:-6] + ".x" + self.layout.operator(DirectXExporter.bl_idname, text="DirectX (.x)").filepath = DefaultPath + def register(): bpy.types.register(DirectXExporter) bpy.types.INFO_MT_file_export.append(menu_func) + def unregister(): bpy.types.unregister(DirectXExporter) bpy.types.INFO_MT_file_export.remove(menu_func) -if __name__=="__main__": + +if __name__ == "__main__": register()