Skip to content

Commit 90a8175

Browse files
committed
Generate light attachments for objects in H1 scenario
1 parent 5f86a77 commit 90a8175

2 files changed

Lines changed: 116 additions & 4 deletions

File tree

io_scene_halo/file_tag/build_scene/generate_h1_scenario.py

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,14 @@ class CommandListFlags(Flag):
160160
disable_falling_damage = auto()
161161
manual_bsp_index = auto()
162162

163+
class LightFlags(Flag):
164+
dynamic = auto()
165+
no_specular = auto()
166+
dont_light_own_object = auto()
167+
supersize_in_first_person = auto()
168+
first_person_flashlight = auto()
169+
dont_fade_active_camouflage = auto()
170+
163171
def get_rotation_euler(yaw=0, pitch=0, roll=0):
164172
yaw = -radians(yaw)
165173
pitch = radians(pitch)
@@ -681,6 +689,8 @@ def generate_object_elements(context, level_root, collection_name, scnr_data, as
681689
for element_idx, element in enumerate(tag_block):
682690
tag_path = ""
683691
mesh_data = None
692+
marker_data = None
693+
palette_asset = None
684694
tag_path_no_ext = ""
685695
if element["type"] >= 0 and element["type"] < palette_count:
686696
pallete_item = tag_palette[element["type"]]["name"]
@@ -689,6 +699,7 @@ def generate_object_elements(context, level_root, collection_name, scnr_data, as
689699
palette_asset = tag_interface.get_disk_asset(pallete_item["path"], h1_tag_groups.get(pallete_item["group name"]))
690700
if palette_asset is not None and len(palette_asset["Data"]["model"]["path"]) > 0:
691701
mesh_data = asset_cache[palette_asset["Data"]["model"]["group name"]][palette_asset["Data"]["model"]["path"]]["blender_assets"].get("blender_asset")
702+
marker_data = asset_cache[palette_asset["Data"]["model"]["group name"]][palette_asset["Data"]["model"]["path"]].get("marker_positions")
692703

693704
tag_name = "NONE"
694705
if not global_functions.string_empty_check(tag_path_no_ext):
@@ -717,6 +728,49 @@ def generate_object_elements(context, level_root, collection_name, scnr_data, as
717728
root.hide_set(True)
718729
root.hide_render = True
719730

731+
if collection_name == "Scenery" or collection_name == "Light Fixtures":
732+
if palette_asset is not None and marker_data is not None:
733+
palette_data = palette_asset["Data"]
734+
for attachment in palette_data["attachments"]:
735+
type_field = attachment.get("type")
736+
marker_field = attachment.get("marker", "")
737+
if type_field is not None:
738+
group_name_value = type_field.get("group name")
739+
if group_name_value == "ligh":
740+
light_asset = tag_interface.get_disk_asset(type_field["path"], h1_tag_groups.get(type_field["group name"]))
741+
if light_asset is not None:
742+
light_dict = light_asset["Data"]
743+
marker_entry = marker_data.get(marker_field, [None])
744+
for marker_idx, marker_positions in enumerate(marker_entry):
745+
# We are just taking the index that the collection comes up in our if else check at the start of this function.
746+
# Kinda to mirror the H2 object type enum. - Gen
747+
collection_index = 0
748+
if not collection_name == "Scenery":
749+
collection_index = 7
750+
751+
marker_name = "%s_%s%s%s" % (marker_field, collection_index, element_idx, marker_idx)
752+
light_data = asset_cache[type_field["group name"]][type_field["path"]]["blender_assets"].get("blender_asset")
753+
if not light_data:
754+
light_data = asset_cache[type_field["group name"]][type_field["path"]]["blender_assets"]["blender_asset"] = bpy.data.lights.new(marker_name, "POINT")
755+
light_data.energy = 0
756+
light_data.shadow_soft_size = 0
757+
light_data.color = (0, 0, 0)
758+
759+
if not LightFlags.dynamic in LightFlags(light_dict["flags"]):
760+
# The multiplication values here are made up and just look good to me in Blender. - Gen
761+
light_data.energy = light_dict["intensity"] * 6000000
762+
light_data.shadow_soft_size = light_dict["radius"] * 10
763+
light_data.color = convert_to_blender_color(light_dict["color"], False)
764+
765+
light_ob = bpy.data.objects.new(marker_name, light_data)
766+
asset_collection.objects.link(light_ob)
767+
768+
light_ob.parent = root
769+
if marker_positions is not None:
770+
light_ob.matrix_basis = marker_positions
771+
772+
773+
720774
def generate_netgame_equipment_elements(context, level_root, scnr_data, asset_cache, fix_rotations, report, random_color_gen):
721775
asset_collection = global_functions.get_referenced_collection("Netgame Equipment", context.scene.collection, True)
722776
for element_idx, element in enumerate(scnr_data["netgame equipment"]):
@@ -993,7 +1047,60 @@ def generate_decals(context, level_root, scnr_data):
9931047

9941048
get_data_type(ob, asset_collection, element, scnr_data, tag_path)
9951049

1050+
def generate_marker_positions(parsed_asset):
1051+
asset_data = parsed_asset["Data"]
1052+
marker_positions = {}
1053+
1054+
absolute_frame = [None for node in asset_data["nodes"]]
1055+
for node_idx, node in enumerate(asset_data["nodes"]):
1056+
parent_idx = node["parent node"]
1057+
matrix_rotation = global_functions.convert_quaternion(node["default rotation"]).inverted().to_matrix().to_4x4()
1058+
matrix_translation = Matrix.Translation(Vector(node["default translation"]) * 100)
1059+
1060+
transform_matrix = matrix_translation @ matrix_rotation
1061+
if parent_idx != -1:
1062+
absolute_matrix = absolute_frame[parent_idx] @ transform_matrix
1063+
else:
1064+
absolute_matrix = transform_matrix
1065+
absolute_frame[node_idx] = absolute_matrix
1066+
1067+
for region in asset_data["regions"]:
1068+
permutation_element = None
1069+
for permutation in region["permutations"]:
1070+
if "base" in permutation["name"].lower():
1071+
permutation_element = permutation
1072+
break
1073+
1074+
if permutation_element is None:
1075+
for permutation in region["permutations"]:
1076+
permutation_element = permutation
1077+
break
1078+
1079+
if permutation_element is not None:
1080+
for marker in permutation["markers"]:
1081+
marker_entry = marker_positions.get(marker["name"])
1082+
if marker_entry is None:
1083+
marker_entry = marker_positions[marker["name"]] = []
1084+
1085+
matrix_rotation = global_functions.convert_quaternion(marker["rotation"]).inverted().to_matrix().to_4x4()
1086+
matrix_translation = Matrix.Translation(Vector(marker["translation"]) * 100)
1087+
1088+
transform_matrix = matrix_translation @ matrix_rotation
1089+
1090+
marker_entry.append(transform_matrix)
1091+
1092+
return marker_positions
1093+
9961094
def generate_scenario_scene(context, tag_ref, asset_cache, game_title, fix_rotations, empty_markers, report):
1095+
mod2_group = asset_cache.get("mod2")
1096+
if mod2_group is not None:
1097+
for tag_path in asset_cache["mod2"]:
1098+
mod2_asset = tag_interface.get_disk_asset(tag_path, h1_tag_groups.get("mod2"))
1099+
if mod2_asset is not None:
1100+
marker_positions = asset_cache["mod2"][tag_path].get("marker_positions")
1101+
if marker_positions is None:
1102+
mod2_group[tag_path]["marker_positions"] = generate_marker_positions(mod2_asset)
1103+
9971104
scnr_asset = tag_interface.get_disk_asset(tag_ref["path"], h1_tag_groups.get(tag_ref["group name"]))
9981105
scnr_data = scnr_asset["Data"]
9991106

io_scene_halo/global_functions/shader_generation/halo_1_shader.py

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1886,21 +1886,26 @@ def generate_shader_transparent_generic(mat, shader_asset, permutation_index, as
18861886

18871887
if final_node is not None:
18881888
emission_node = mat.node_tree.nodes.new("ShaderNodeEmission")
1889+
transparency_node = mat.node_tree.nodes.new("ShaderNodeBsdfTransparent")
1890+
add_node = mat.node_tree.nodes.new("ShaderNodeAddShader")
18891891
light_path_node = mat.node_tree.nodes.new("ShaderNodeLightPath")
18901892
mix_node = mat.node_tree.nodes.new("ShaderNodeMixShader")
18911893

1892-
emission_node.location = Vector((-360.0, -140.0))
1894+
emission_node.location = Vector((-540.0, -280.0))
1895+
transparency_node.location = Vector((-540.0, -400.0))
1896+
add_node.location = Vector((-360.0, -140.0))
18931897
light_path_node.location = Vector((-360.0, 380.0))
18941898
mix_node.location = Vector((-180.0, 0.0))
18951899

18961900
connect_inputs(mat.node_tree, light_path_node, "Is Camera Ray", mix_node, 0)
18971901
connect_inputs(mat.node_tree, final_node, "Shader", mix_node, 2)
1898-
connect_inputs(mat.node_tree, emission_node, "Emission", mix_node, 1)
18991902
connect_inputs(mat.node_tree, mix_node, "Shader", output_material_node, "Surface")
1900-
1903+
connect_inputs(mat.node_tree, add_node, "Shader", mix_node, 1)
1904+
connect_inputs(mat.node_tree, emission_node, "Emission", add_node, 0)
1905+
connect_inputs(mat.node_tree, transparency_node, "BSDF", add_node, 1)
1906+
19011907
connect_inputs(mat.node_tree, stg_node, "Power", emission_node, 1)
19021908

1903-
19041909
if len(shader_data["stages"]) == 0:
19051910
connect_inputs(mat.node_tree, stg_node, "Map A", emission_node, 0)
19061911
else:

0 commit comments

Comments
 (0)