diff --git a/art/Exporter.py b/art/Exporter.py index 0e399e2..9425fc4 100644 --- a/art/Exporter.py +++ b/art/Exporter.py @@ -1,6 +1,7 @@ import bpy import bmesh import os +import shutil import struct from mathutils import *; from math import * from bpy_extras.io_utils import (axis_conversion) @@ -8,18 +9,33 @@ from bpy_extras.io_utils import (axis_conversion) C = bpy.context D = bpy.data +LEVEL_EXPORT_NAME = "level" EXPORT_DIRECTORY = "exported" -if not os.path.exists(bpy.path.abspath(f"//{EXPORT_DIRECTORY}")): - os.makedirs(bpy.path.abspath(f"//{EXPORT_DIRECTORY}")) +print("\n\nLet's get it started") + +if os.path.exists(bpy.path.abspath(f"//{EXPORT_DIRECTORY}")): + shutil.rmtree(bpy.path.abspath(f"//{EXPORT_DIRECTORY}")) +os.makedirs(bpy.path.abspath(f"//{EXPORT_DIRECTORY}")) def write_f32(f, number: float): f.write(bytes(struct.pack("f", number))) + def write_u64(f, number: int): f.write(bytes(struct.pack("Q", number))) +def write_string(f, s: str): + encoded = s.encode("utf8") + write_u64(f, len(encoded)) + f.write(encoded) + +# for the level.bin +level_object_data = [] +collision_cubes = [] +saved_meshes = set() + for o in D.objects: mapping = axis_conversion( from_forward = "Y", @@ -27,34 +43,80 @@ for o in D.objects: to_forward = "-Z", to_up = "Y", ) - mapping.resize_4x4() - print(mapping) - output_filepath = bpy.path.abspath(f"//{EXPORT_DIRECTORY}/{o.name}.bin") - print(f"\n\nExporting {output_filepath}") - with open(output_filepath, "wb") as f: - bm = bmesh.new() - mesh = o.to_mesh() - bm.from_mesh(mesh) - bmesh.ops.triangulate(bm, faces=bm.faces) - bm.transform(mapping) - bm.to_mesh(mesh) + mesh_name = o.to_mesh().name # use this over o.name so instanced objects which refer to the same mesh, both use the same serialized mesh. + + if o.users_collection[0].name == 'Level' and mesh_name == "CollisionCube": + collision_cubes.append((o.location, o.dimensions)) + else: + if o.users_collection[0].name == 'Level': + print(f"Object {o.name} has mesh name {o.to_mesh().name}") + assert(o.rotation_euler.order == 'XYZ') + level_object_data.append((mesh_name, mapping @ o.location, o.rotation_euler, o.scale)) + if mesh_name in saved_meshes: + continue + saved_meshes.add(mesh_name) + + mapping.resize_4x4() + assert(mesh_name != LEVEL_EXPORT_NAME) + output_filepath = bpy.path.abspath(f"//{EXPORT_DIRECTORY}/{mesh_name}.bin") + print(f"Exporting {output_filepath}") + with open(output_filepath, "wb") as f: + bm = bmesh.new() + mesh = o.to_mesh() + bm.from_mesh(mesh) + bmesh.ops.triangulate(bm, faces=bm.faces) + bm.transform(mapping) + bm.to_mesh(mesh) + + + vertices = [] + + for polygon in mesh.polygons: + if len(polygon.loop_indices) == 3: + for loopIndex in polygon.loop_indices: + loop = mesh.loops[loopIndex] + position = mesh.vertices[loop.vertex_index].undeformed_co + uv = mesh.uv_layers.active.data[loop.index].uv + normal = loop.normal + + vertices.append((position, uv)) + + write_u64(f, len(vertices)) + for v_and_uv in vertices: + v, uv = v_and_uv + write_f32(f, v.x) + write_f32(f, v.y) + write_f32(f, v.z) + write_f32(f, uv.x) + write_f32(f, uv.y) + print(f"Wrote {len(vertices)} vertices") + +with open(bpy.path.abspath(f"//{EXPORT_DIRECTORY}/{LEVEL_EXPORT_NAME}.bin"), "wb") as f: + write_u64(f, len(level_object_data)) + for o in level_object_data: + name, v, rotation, scale = o + print(f"Writing instanced object {name}") + write_string(f, name) + write_f32(f, v.x) + write_f32(f, v.y) + write_f32(f, v.z) - vertices = [] - - for polygon in mesh.polygons: - if len(polygon.loop_indices) == 3: - for loopIndex in polygon.loop_indices: - loop = mesh.loops[loopIndex] - position = mesh.vertices[loop.vertex_index].undeformed_co - uv = mesh.uv_layers.active.data[loop.index].uv - normal = loop.normal - - vertices.append(position) + # rotation fields different because y+ is up now + write_f32(f, rotation.x) + write_f32(f, rotation.y) + write_f32(f, rotation.z) - write_u64(f, len(vertices)) - for v in vertices: - write_f32(f, v.x) - write_f32(f, v.y) - write_f32(f, v.z) - print(f"Wrote {len(vertices)} vertices") \ No newline at end of file + write_f32(f, scale.x) + write_f32(f, scale.y) + write_f32(f, scale.z) + + write_u64(f, len(collision_cubes)) + for c in collision_cubes: + blender_pos, blender_dims = c + write_f32(f, blender_pos.x) + write_f32(f, -blender_pos.y) + write_f32(f, blender_dims.x) + write_f32(f, blender_dims.y) + assert(blender_dims.x > 0.0) + assert(blender_dims.y > 0.0) \ No newline at end of file diff --git a/art/art.blend b/art/art.blend index b958386..edde59d 100644 --- a/art/art.blend +++ b/art/art.blend @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ff3012766f4c242818e5d889f41c268feeb184986e4f90415c92448ea077a04c -size 1126444 +oid sha256:341412f1daaa52f32cc8a00736e68335b288d5c74d9b64b31b62b8dc54254dcf +size 1118880