Skip to content

Commit

Permalink
Drop transparent geo from lightmap mesh import and some bitmap versio…
Browse files Browse the repository at this point in the history
…ning stuff
  • Loading branch information
Steven Garcia committed Dec 10, 2023
1 parent e4a7aee commit 7ae3666
Show file tree
Hide file tree
Showing 8 changed files with 237 additions and 247 deletions.
6 changes: 6 additions & 0 deletions io_scene_halo/file_tag/build_scene/build_bsp.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ def build_scene(context, LEVEL, game_version, game_title, file_version, fix_rota

mesh.from_pydata(vertices, [], triangles)
mesh.normals_split_custom_set_from_vertices(normals)
mesh.use_auto_smooth = True
for tri_idx, poly in enumerate(mesh.polygons):
poly.use_smooth = True

Expand Down Expand Up @@ -284,6 +285,8 @@ def build_scene(context, LEVEL, game_version, game_title, file_version, fix_rota
cluster_name = "cluster_%s" % cluster_idx
full_mesh = bpy.data.meshes.new(cluster_name)
object_mesh = bpy.data.objects.new(cluster_name, full_mesh)
object_mesh.tag_view.data_type_enum = '1'

object_mesh.parent = level_root
for cluster_data in cluster.cluster_data:
triangles = []
Expand Down Expand Up @@ -435,6 +438,9 @@ def build_scene(context, LEVEL, game_version, game_title, file_version, fix_rota
ob_name = instanced_geometry_instance.name

object_mesh = bpy.data.objects.new(ob_name, mesh)
object_mesh.tag_view.data_type_enum = '16'
object_mesh.tag_view.instance_lightmap_policy_enum = str(instanced_geometry_instance.lightmapping_policy)

object_mesh.parent = level_root
cluster_collection_override.objects.link(object_mesh)

Expand Down
257 changes: 117 additions & 140 deletions io_scene_halo/file_tag/build_scene/build_lightmap.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,59 +28,84 @@
import bpy

from mathutils import Matrix
from ..h2.file_scenario_structure_lightmap.format import PartTypeEnum
from ...global_functions import global_functions

def build_clusters(lightmap_group, SBSP_ASSET, level_root, random_color_gen, collection):
if len(lightmap_group.clusters) > 0:
material_count = 0
if not SBSP_ASSET == None:
material_count = len(SBSP_ASSET.materials)

for cluster_idx, cluster in enumerate(lightmap_group.clusters):
cluster_name = "cluster_%s" % cluster_idx
full_mesh = bpy.data.meshes.new(cluster_name)
object_mesh = bpy.data.objects.new(cluster_name, full_mesh)
object_mesh.parent = level_root
for cache_data in cluster.cache_data:
triangles = []
vertices = [raw_vertex.position for raw_vertex in cache_data.raw_vertices]

triangle_length = int(len(cache_data.strip_indices) / 3)
for idx in range(triangle_length):
triangle_index = (idx * 3)
v0 = cache_data.strip_indices[triangle_index]
v1 = cache_data.strip_indices[triangle_index + 1]
v2 = cache_data.strip_indices[triangle_index + 2]
triangles.append((v0, v1, v2))

full_mesh.from_pydata(vertices, [], triangles)
for poly in full_mesh.polygons:
poly.use_smooth = True

uv_name = 'UVMap_%s' % 0
layer_uv = full_mesh.uv_layers.get(uv_name)
if layer_uv is None:
layer_uv = full_mesh.uv_layers.new(name=uv_name)

def process_mesh(SBSP_ASSET, random_color_gen, tag_block, poop_name, material_count):
mesh = None
for render_data in tag_block.cache_data:
vertex_map = [-1 for raw_vertex in render_data.raw_vertices]
vertices = []
triangles = []
triangle_materials = []
vertex_idx = 0
for part in render_data.parts:
if not PartTypeEnum.transparent.value == part.part_type:
strip_length = part.strip_length
strip_start = part.strip_start_index

triangle_indices = render_data.strip_indices[strip_start : (strip_start + strip_length)]
triangle_length = int(len(triangle_indices) / 3)
for idx in range(triangle_length):
triangle_index = (idx * 3)
v0 = cache_data.strip_indices[triangle_index]
v1 = cache_data.strip_indices[triangle_index + 1]
v2 = cache_data.strip_indices[triangle_index + 2]

vertex_list = [cache_data.raw_vertices[v0], cache_data.raw_vertices[v1], cache_data.raw_vertices[v2]]
for vertex_idx, vertex in enumerate(vertex_list):
loop_index = triangle_index + vertex_idx

U = vertex.primary_lightmap_texcoord[0]
V = vertex.primary_lightmap_texcoord[1]

layer_uv.data[loop_index].uv = (U, V)

triangle_start = 0
for part in cache_data.parts:
part_indices = cache_data.strip_indices[part.strip_start_index : (part.strip_start_index + part.strip_length)]
part_triangle_length = int(len(part_indices) / 3)
v0 = triangle_indices[triangle_index]
if vertex_map[v0] == -1:
vertex_map[v0] = vertex_idx
vertices.append(render_data.raw_vertices[v0])
vertex_idx += 1

v1 = triangle_indices[triangle_index + 1]
if vertex_map[v1] == -1:
vertex_map[v1] = vertex_idx
vertices.append(render_data.raw_vertices[v1])
vertex_idx += 1

v2 = triangle_indices[triangle_index + 2]
if vertex_map[v2] == -1:
vertex_map[v2] = vertex_idx
vertices.append(render_data.raw_vertices[v2])
vertex_idx += 1

triangles.append((vertex_map[v0], vertex_map[v1], vertex_map[v2]))
triangle_materials.append(part.material_index)

if len(vertices) > 0:
mesh = bpy.data.meshes.new(poop_name)
mesh.from_pydata([vertex.position for vertex in vertices], [], triangles)
for poly in mesh.polygons:
poly.use_smooth = True

mesh.normals_split_custom_set_from_vertices([vertex.normal for vertex in vertices])
mesh.use_auto_smooth = True

uv_name = 'UVMap_%s' % 0
layer_uv = mesh.uv_layers.get(uv_name)
if layer_uv is None:
layer_uv = mesh.uv_layers.new(name=uv_name)

triangle_start = 0
for part in render_data.parts:
if not PartTypeEnum.transparent.value == part.part_type:
strip_length = part.strip_length
strip_start = part.strip_start_index

triangle_indices = render_data.strip_indices[strip_start : (strip_start + strip_length)]
triangle_length = int(len(triangle_indices) / 3)
for idx in range(triangle_length):
triangle_index = (idx * 3)
v0 = triangle_indices[triangle_index]
v1 = triangle_indices[triangle_index + 1]
v2 = triangle_indices[triangle_index + 2]

vertex_list = [vertices[vertex_map[v0]], vertices[vertex_map[v1]], vertices[vertex_map[v2]]]
for vertex_idx, vertex in enumerate(vertex_list):
loop_index = triangle_index + vertex_idx

U = vertex.primary_lightmap_texcoord[0]
V = vertex.primary_lightmap_texcoord[1]

layer_uv.data[loop_index].uv = (U, V)

material = None
if not part.material_index == -1 and material_count > 0:
material = SBSP_ASSET.materials[part.material_index]
Expand All @@ -96,18 +121,32 @@ def build_clusters(lightmap_group, SBSP_ASSET, level_root, random_color_gen, col
if mat is None:
mat = bpy.data.materials.new(name=material_name)

if not material_name in object_mesh.data.materials.keys():
object_mesh.data.materials.append(mat)
if not material_name in mesh.materials.keys():
mesh.materials.append(mat)

mat.diffuse_color = random_color_gen.next()
material_index = object_mesh.data.materials.keys().index(material_name)
material_index = mesh.materials.keys().index(material_name)

for triangle_idx in range(triangle_length):
mesh.polygons[triangle_start + triangle_idx].material_index = material_index

for triangle_idx in range(part_triangle_length):
full_mesh.polygons[triangle_start + triangle_idx].material_index = material_index
triangle_start += triangle_length

triangle_start += part_triangle_length
return mesh

def build_clusters(lightmap_group, SBSP_ASSET, level_root, random_color_gen, collection):
if len(lightmap_group.clusters) > 0:
material_count = 0
if not SBSP_ASSET == None:
material_count = len(SBSP_ASSET.materials)

for cluster_idx, cluster in enumerate(lightmap_group.clusters):
cluster_name = "cluster_%s" % cluster_idx
mesh = process_mesh(SBSP_ASSET, random_color_gen, cluster, cluster_name, material_count)
if not mesh == None:
object_mesh = bpy.data.objects.new(cluster_name, mesh)
collection.objects.link(object_mesh)
object_mesh.parent = level_root

def build_poops(lightmap_group, SBSP_ASSET, level_root, random_color_gen, collection):
if len(lightmap_group.poop_definitions) > 0:
Expand All @@ -117,93 +156,31 @@ def build_poops(lightmap_group, SBSP_ASSET, level_root, random_color_gen, collec
material_count = len(SBSP_ASSET.materials)

for poop_definition_idx, poop_definition in enumerate(lightmap_group.poop_definitions):
cluster_name = "instanced_geometry_definition_%s" % poop_definition_idx
mesh = bpy.data.meshes.new(cluster_name)
for render_data in poop_definition.cache_data:
triangles = []
vertices = [raw_vertex.position for raw_vertex in render_data.raw_vertices]

triangle_length = int(len(render_data.strip_indices) / 3)
for idx in range(triangle_length):
triangle_index = (idx * 3)
v0 = render_data.strip_indices[triangle_index]
v1 = render_data.strip_indices[triangle_index + 1]
v2 = render_data.strip_indices[triangle_index + 2]
triangles.append((v0, v1, v2))

mesh.from_pydata(vertices, [], triangles)
for poly in mesh.polygons:
poly.use_smooth = True

uv_name = 'UVMap_%s' % 0
layer_uv = mesh.uv_layers.get(uv_name)
if layer_uv is None:
layer_uv = mesh.uv_layers.new(name=uv_name)

for idx in range(triangle_length):
triangle_index = (idx * 3)
v0 = render_data.strip_indices[triangle_index]
v1 = render_data.strip_indices[triangle_index + 1]
v2 = render_data.strip_indices[triangle_index + 2]

vertex_list = [render_data.raw_vertices[v0], render_data.raw_vertices[v1], render_data.raw_vertices[v2]]
for vertex_idx, vertex in enumerate(vertex_list):
loop_index = triangle_index + vertex_idx

U = vertex.primary_lightmap_texcoord[0]
V = vertex.primary_lightmap_texcoord[1]

layer_uv.data[loop_index].uv = (U, V)

triangle_start = 0
for part in render_data.parts:
part_indices = render_data.strip_indices[part.strip_start_index : (part.strip_start_index + part.strip_length)]
part_triangle_length = int(len(part_indices) / 3)
material = None
if not part.material_index == -1 and material_count > 0:
material = SBSP_ASSET.materials[part.material_index]

if material:
if len(material.shader.name) > 0:
material_name = os.path.basename(material.shader.name)

else:
material_name = "invalid_material_%s" % part.material_index

mat = bpy.data.materials.get(material_name)
if mat is None:
mat = bpy.data.materials.new(name=material_name)

if not material_name in mesh.materials.keys():
mesh.materials.append(mat)

mat.diffuse_color = random_color_gen.next()
material_index = mesh.materials.keys().index(material_name)

for triangle_idx in range(part_triangle_length):
mesh.polygons[triangle_start + triangle_idx].material_index = material_index

triangle_start += part_triangle_length

poop_name = "instanced_geometry_definition_%s" % poop_definition_idx
mesh = process_mesh(SBSP_ASSET, random_color_gen, poop_definition, poop_name, material_count)
meshes.append(mesh)

for instanced_geometry_instance_idx, instanced_geometry_instance in enumerate(SBSP_ASSET.instanced_geometry_instances):
mesh = meshes[instanced_geometry_instance.instance_definition]
ob_name = instanced_geometry_instance.name

object_mesh = bpy.data.objects.new(ob_name, mesh)
object_mesh.parent = level_root
collection.objects.link(object_mesh)

matrix_scale = Matrix.Scale(instanced_geometry_instance.scale, 4)
matrix_rotation = Matrix()
matrix_rotation[0] = *instanced_geometry_instance.forward, 0
matrix_rotation[1] = *instanced_geometry_instance.left, 0
matrix_rotation[2] = *instanced_geometry_instance.up, 0
matrix_rotation = matrix_rotation.inverted()
matrix_translation = Matrix.Translation(instanced_geometry_instance.position)
transform_matrix = (matrix_translation @ matrix_rotation @ matrix_scale)
object_mesh.matrix_world = transform_matrix
for instanced_geometry_instance in SBSP_ASSET.instanced_geometry_instances:
if not instanced_geometry_instance.instance_definition == -1:
mesh = meshes[instanced_geometry_instance.instance_definition]
ob_name = instanced_geometry_instance.name
if not mesh == None:
object_mesh = bpy.data.objects.new(ob_name, mesh)
object_mesh.parent = level_root
collection.objects.link(object_mesh)

object_mesh.tag_view.data_type_enum = '16'
object_mesh.tag_view.instance_lightmap_policy_enum = str(instanced_geometry_instance.lightmapping_policy)

matrix_scale = Matrix.Scale(instanced_geometry_instance.scale, 4)
matrix_rotation = Matrix()
matrix_rotation[0] = *instanced_geometry_instance.forward, 0
matrix_rotation[1] = *instanced_geometry_instance.left, 0
matrix_rotation[2] = *instanced_geometry_instance.up, 0
matrix_rotation = matrix_rotation.inverted()
matrix_translation = Matrix.Translation(instanced_geometry_instance.position)
transform_matrix = (matrix_translation @ matrix_rotation @ matrix_scale)
object_mesh.matrix_world = transform_matrix

def build_scene(context, LTMP_ASSET, game_version, game_title, file_version, fix_rotations, empty_markers, report, collection_override=None, cluster_collection_override=None, SBSP_ASSET=None):
random_color_gen = global_functions.RandomColorGenerator() # generates a random sequence of colors
Expand Down
12 changes: 7 additions & 5 deletions io_scene_halo/file_tag/h1/file_bitmap/process_file.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,12 +78,14 @@ def process_file(input_stream, report):
BITMAP.bitmap_body.sequences_tag_block = TAG.TagBlock().read(input_stream, TAG, tag_format.XMLData(tag_node, "sequences"))
BITMAP.bitmap_body.bitmaps_tag_block = TAG.TagBlock().read(input_stream, TAG, tag_format.XMLData(tag_node, "bitmaps"))

size = input_stream.read(4) # Padding
color_plate_length = BITMAP.bitmap_body.compressed_color_plate_data.size - 4
if color_plate_length < 0:
color_plate_length = 0
if BITMAP.bitmap_body.compressed_color_plate_data.size > 0:
size = input_stream.read(4) # Padding
color_plate_length = BITMAP.bitmap_body.compressed_color_plate_data.size - 4
if color_plate_length < 0:
color_plate_length = 0

BITMAP.bitmap_body.compressed_color_plate = input_stream.read(color_plate_length)

BITMAP.bitmap_body.compressed_color_plate = input_stream.read(color_plate_length)
BITMAP.bitmap_body.processed_pixels = input_stream.read(BITMAP.bitmap_body.processed_pixel_data.size)

BITMAP.sequences = []
Expand Down
1 change: 1 addition & 0 deletions io_scene_halo/file_tag/h1/file_scenario/format.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ class DataTypesEnum(Enum):
netgame_equipment = auto()
decals = auto()
encounters = auto()
instances = auto()

class ScenarioTypeEnum(Enum):
solo = 0
Expand Down
2 changes: 1 addition & 1 deletion io_scene_halo/file_tag/h2/file_bitmap/build_asset.py
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ def write_bitmaps(output_stream, BITMAP, TAG):
output_stream.write(struct.pack('<i', native_mipmap_info.pitch_row))
output_stream.write(struct.pack('<i', native_mipmap_info.pitch_slice))

def build_asset(output_stream, BITMAP):
def build_asset(output_stream, BITMAP, report):
TAG = tag_format.TagAsset()
TAG.big_endian = False

Expand Down
Loading

0 comments on commit 7ae3666

Please sign in to comment.