Newer
Older
else:
Config.File.write(",\n")
Config.Whitespace -= 1
Config.File.write("{}}}\n".format(" " * Config.Whitespace))
if Config.Verbose:
print(" Done")
#Rotation
if Config.Verbose:
print(" Writing 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.frame_set(Frame + bpy.context.scene.frame_start)
Rotation = Object.rotation_euler.to_quaternion()
Config.File.write("{}{}{:9f},{:9f},{:9f},{:9f};;".format(" " * Config.Whitespace, (str(Frame) + ";4;").ljust(8), -Rotation[0], Rotation[1], Rotation[2], Rotation[3]))
if Frame == KeyframeCount-1:
Config.File.write(";\n")
else:
Config.File.write(",\n")
Config.Whitespace -= 1
Config.File.write("{}}}\n".format(" " * Config.Whitespace))
if Config.Verbose:
print(" Done")
#Scale
if Config.Verbose:
print(" Writing 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.frame_set(Frame + bpy.context.scene.frame_start)
Scale = Object.matrix_local.to_scale()
Config.File.write("{}{}{:9f},{:9f},{:9f};;".format(" " * Config.Whitespace, (str(Frame) + ";3;").ljust(8), Scale[0], Scale[1], Scale[2]))
if Frame == KeyframeCount-1:
Config.File.write(";\n")
else:
Config.File.write(",\n")
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.ExportArmatures and Object.type == "ARMATURE":
if Config.Verbose:
print(" Writing Armature Bone Animation Data...")
PoseBones = Object.pose.bones
Bones = Object.data.bones
for Bone in PoseBones:
if Config.Verbose:
print(" Writing Bone: {}...".format(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...")
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.frame_set(Frame + bpy.context.scene.frame_start)
if Bone.parent:
PoseMatrix = Bone.parent.matrix.inverted()
else:
PoseMatrix = Matrix()
PoseMatrix *= Bone.matrix
Position = PoseMatrix.to_translation()
Config.File.write("{}{}{:9f},{:9f},{:9f};;".format(" " * Config.Whitespace, (str(Frame) + ";3;").ljust(8), Position[0], Position[1], Position[2]))
if Frame == KeyframeCount-1:
Config.File.write(";\n")
else:
Config.File.write(",\n")
Config.Whitespace -= 1
Config.File.write("{}}}\n".format(" " * Config.Whitespace))
if Config.Verbose:
print(" Done")
#Rotation
if Config.Verbose:
print(" Writing 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.frame_set(Frame + bpy.context.scene.frame_start)
Rotation = Bones[Bone.name].matrix.to_quaternion() * Bone.rotation_quaternion
Config.File.write("{}{}{:9f},{:9f},{:9f},{:9f};;".format(" " * Config.Whitespace, (str(Frame) + ";4;").ljust(8), -Rotation[0], Rotation[1], Rotation[2], Rotation[3]))
if Frame == KeyframeCount-1:
Config.File.write(";\n")
else:
Config.File.write(",\n")
Config.Whitespace -= 1
Config.File.write("{}}}\n".format(" " * Config.Whitespace))
if Config.Verbose:
print(" Done")
#Scale
if Config.Verbose:
print(" Writing Scale...")
Config.File.write("{}AnimationKey {{ //Scale\n".format(" " * Config.Whitespace, KeyframeCount))
Config.Whitespace += 1
Config.File.write("{}1;\n{}{};\n".format(" " * Config.Whitespace, " " * Config.Whitespace, KeyframeCount))
for Frame in range(0, KeyframeCount):
bpy.context.scene.frame_set(Frame + bpy.context.scene.frame_start)
if Bone.parent:
PoseMatrix = Bone.parent.matrix.inverted()
else:
PoseMatrix = Matrix()
PoseMatrix *= Bone.matrix
Config.File.write("{}{}{:9f},{:9f},{:9f};;".format(" " * Config.Whitespace, (str(Frame) + ";3;").ljust(8), Scale[0], Scale[1], Scale[2]))
if Frame == KeyframeCount-1:
Config.File.write(";\n")
else:
Config.File.write(",\n")
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") #Done with Armature Bone
if Config.Verbose:
print(" Done") #Done with Armature Bone data
if Config.Verbose:
print(" Done") #Done with Object
Config.Whitespace -= 1
Config.File.write("{}}} //End of AnimationSet\n".format(" " * Config.Whitespace))
print("Closing File...")
if Config.Verbose:
print("Done")
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", ""))
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(subtype='FILE_PATH')
CoordinateSystem = EnumProperty(name="System", description="Select a coordinate system to export to", items=CoordinateSystems, default="1")
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)
Chris Foster
committed
ApplyModifiers = BoolProperty(name="Apply Modifiers", description="Apply 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)
Chris Foster
committed
ExportArmatures = BoolProperty(name="Export Armatures", description="Export the bones of any armatures to deform meshes.", default=False)
ExportAnimation = EnumProperty(name="Animations", description="Select the type of animations to export. Only object and armature bone animations can be exported. Full Animation exports every frame.", items=AnimationModes, default="0")
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):
Thomas Dinges
committed
FilePath = self.filepath
if not FilePath.lower().endswith(".x"):
FilePath += ".x"
Config = DirectXExporterSettings(context,
FilePath,
Thomas Dinges
committed
CoordinateSystem=self.CoordinateSystem,
RotateX=self.RotateX,
FlipNormals=self.FlipNormals,
ApplyModifiers=self.ApplyModifiers,
IncludeFrameRate=self.IncludeFrameRate,
ExportTextures=self.ExportTextures,
ExportArmatures=self.ExportArmatures,
ExportAnimation=self.ExportAnimation,
ExportMode=self.ExportMode,
Verbose=self.Verbose)
ExportDirectX(Config)
return {"FINISHED"}
def invoke(self, context, event):
WindowManager.fileselect_add(self)
return {"RUNNING_MODAL"}
def menu_func(self, context):
default_path = os.path.splitext(bpy.data.filepath)[0] + ".x"
self.layout.operator(DirectXExporter.bl_idname, text="DirectX (.x)").filepath = default_path
Campbell Barton
committed
bpy.utils.register_module(__name__)
bpy.types.INFO_MT_file_export.append(menu_func)
Campbell Barton
committed
bpy.utils.unregister_module(__name__)
bpy.types.INFO_MT_file_export.remove(menu_func)
if __name__ == "__main__":