Bump because update and because I don't know why the heck isn't this working.
problem. Now the meshes seems to have some problems with vertex distortion (despite being better now) and the vertices don't get out of some cubic area. So if someone experienced with those could help...
Code: Select all
from struct import pack, calcsize
from time import strftime
from shutil import rmtree
import os
import bpy
import bpy_extras
bl_info = {
"name" : "Export to Unreal Mesh (_a.3d, _d.3d)",
"category" : "Import-Export",
"description" : "Exports a mesh to Unreal Engine 1 (vertex-animation) format.",
"version" : (0, 2),
"blender" : (2, 7, 7),
"location" : "Operator",
"warning" : "This is a test addon and it is known to export meshes with a mess of polygons. Use on your own discretion or to export the class file with the #exec directives.",
"support" : "TESTING",
}
def log(file_, logging, print_it=False):
if print_it:
print("[{}] {}".format(strftime("%I:%M:%S"), logging))
return file_.write("[{}] {}\n".format(strftime("%I:%M:%S"), logging))
class UnrealMeshException(BaseException):
pass
class NotTrianglePolygonError(UnrealMeshException):
pass
class NoUVError(UnrealMeshException):
pass
def ensure_dir(dirpath):
if not os.path.isdir(dirpath):
os.makedirs(dirpath)
print("Dir ensured: " + dirpath)
def unreal_vertex(coord):
return int( int(coord[0] * 8.0) & int("0x7ff", 16) | ( ( int(coord[1] * 8.0) & int("0x7ff", 16) ) << 11 ) | ( ( int(coord[2] * 4.0) & int("0x3ff", 16) ) << 22 ))
class UnrealMeshExport(bpy.types.Operator):
bl_idname = "io.ue1_mesh"
bl_label = "Export to Unreal format (_a.3d, _d.3d)"
scale = bpy.props.FloatProperty(name="Scale", default=16, min=1, max=8192, description="Scale, in Blender Units -> Unreal Units metrics.")
package_name = bpy.props.StringProperty(name="Package Name", default="MyPackage", description="The name of the package to contain the mesh and the actor.")
unreal_path = bpy.props.StringProperty(name="Unreal|UT Path", description="The path to your Unreal Engine 1 game (without a backslash in the end!).", subtype="DIR_PATH", default="C:\\UnrealTournament")
mesh_name = bpy.props.StringProperty(name="Mesh Name", description="Name of the mesh to export")
class_name = bpy.props.StringProperty(name="Class Name", description="Name of the Unreal class to export (and therefore of the UnrealScript file).")
def execute(self, context):
unreal_path = self.unreal_path
package_name = self.package_name
print(self.package_name)
print(self.unreal_path)
ensure_dir(unreal_path + "\\{}\\".format(package_name))
ensure_dir(unreal_path + "\\{}\\Models\\".format(package_name))
ensure_dir(unreal_path + "\\{}\\Help\\".format(package_name))
ensure_dir(unreal_path + "\\{}\\Skins\\".format(package_name))
ensure_dir(unreal_path + "\\{}\\Classes\\".format(package_name))
with open(unreal_path + "\\{}\\Help\\log.txt".format(package_name), "w") as log_file:
log(log_file, "Getting selected object and triangulating mesh.", True)
mesh = context.object
with open(unreal_path + "\\{}\\Models\\{}_a.3d".format(package_name, self.mesh_name), "wb") as Aniv:
Aniv.write(pack("=I", bpy.context.scene.frame_end - bpy.context.scene.frame_start))
Aniv.write(pack("=L", len(mesh.data.vertices) * calcsize("L")))
log(log_file, "Aniv file header written!", True)
old_frame = bpy.context.scene.frame_current
bpy.context.scene.frame_set(bpy.context.scene.frame_start)
while bpy.context.scene.frame_current <= bpy.context.scene.frame_end:
log(log_file, u"frame {} (".format(bpy.context.scene.frame_current))
for i, v in enumerate(mesh.data.vertices):
coord = [x * self.scale for x in v.co]
log(log_file, u" vertex {} coord=({},{},{}) -> {}".format(i, coord[0], coord[1], coord[2], unreal_vertex(coord)))
Aniv.write(pack("=L", unreal_vertex(coord)))
log(log_file, ")")
bpy.context.scene.frame_set(bpy.context.scene.frame_current + 1)
bpy.context.scene.frame_set(old_frame)
log(log_file, "Aniv file written! Writing to data file...", True)
with open(unreal_path + "\\{}\\Models\\{}_d.3d".format(package_name, self.mesh_name), "wb") as Data_File:
Data_File.write(pack("4H7L12B", len(mesh.data.polygons), len(mesh.data.vertices), *([0] * 21)))
log(log_file, "Data file header written!", True)
for i, poly in enumerate(mesh.data.polygons):
uvs = []
for x in poly.vertices:
try:
uvs.append(int(mesh.data.uv_layers.active.data[x].uv[0] * 255))
uvs.append(int(mesh.data.uv_layers.active.data[x].uv[1] * 255))
except AttributeError:
raise NoUVError("Mesh has no UV coordinates!")
log(log_file, "poly {} vertexes {} {} {}".format(i, *poly.vertices))
Data_File.write(pack("3H2b6B2b", poly.vertices[0], poly.vertices[1], poly.vertices[2], 1, 0, *uvs, 1, 0))
log(log_file, "Data file written! Writing class file...", True)
with open(unreal_path + "\\{}\\Classes\\{}.uc".format(package_name, self.class_name), "w") as Class_File:
Class_File.write("#exec MESH IMPORT MESH={0} ANIVFILE=Models\{0}_a.3d DATAFILE=Models\{0}_d.3d X=0 Y=0 Z=0\n".format(self.mesh_name))
Class_File.write("#exec MESH ORIGIN MESH={} X=0 Y=0 Z=0 ROLL=0\n\n".format(self.mesh_name))
Class_File.write("#exec MESH SEQUENCE MESH={} SEQ=All STARTFRAME=0 NUMFRAMES={}\n".format(self.mesh_name, bpy.context.scene.frame_end - bpy.context.scene.frame_start))
Class_File.write("#exec MESH SEQUENCE MESH={} SEQ=Still STARTFRAME=0 NUMFRAMES=1\n\n".format(self.mesh_name))
Class_File.write("#exec TEXTURE IMPORT NAME=J{0} FILE=Skins\{0}skin.bmp GROUP=\"Skins\"\n\n".format(self.mesh_name))
Class_File.write("#exec MESHMAP SCALE MESHMAP={} X=1 Y=1 Z=1\n".format(self.mesh_name))
Class_File.write("#exec MESHMAP SETTEXTURE MESHMAP={0} NUM=1 TEXTURE=J{0}\n\n".format(self.mesh_name))
Class_File.write("class {} extends Decoration;\n".format(self.class_name))
log(log_file, "Class file written! Operation succesfull! Now all that remains is adding 256-bit skin, adding to editpackages and compiling in UCC!", True)
log_file.close()
return {'FINISHED'}
def invoke(self, context, event):
wm = context.window_manager
return wm.invoke_props_dialog(self)
def register():
bpy.utils.register_class(UnrealMeshExport)
def unregister():
bpy.utils.unregister_class(UnrealMeshExport)
if __name__ == "__main__":
register()