summaryrefslogtreecommitdiff
path: root/extractor/gnd_format.gd
diff options
context:
space:
mode:
authorDaniel Weipert <git@mail.dweipert.de>2024-12-22 18:38:11 +0100
committerDaniel Weipert <git@mail.dweipert.de>2024-12-22 18:38:11 +0100
commit7b3f386449aeab124d84d2aff4c273e646e68763 (patch)
tree9d24a7de247d190edcd8e315fc3e45ab8a4a8d34 /extractor/gnd_format.gd
parentf4e07d090cded56ebab54363f1b47f1ea45c8682 (diff)
next commitHEADmain
Diffstat (limited to 'extractor/gnd_format.gd')
-rw-r--r--extractor/gnd_format.gd294
1 files changed, 294 insertions, 0 deletions
diff --git a/extractor/gnd_format.gd b/extractor/gnd_format.gd
new file mode 100644
index 0000000..f13956e
--- /dev/null
+++ b/extractor/gnd_format.gd
@@ -0,0 +1,294 @@
+class_name GNDFormat
+
+
+## Byte Length: 4 [br]
+## GRAT
+var signature: String = "GRGN"
+
+## Byte Type: u8 [br]
+## Byte Length: 2
+var version: Version
+
+## Byte Type: i32 [br]
+## Byte Length: 4
+var width: int
+
+## Byte Type: i32 [br]
+## Byte Length: 4
+var height: int
+
+## Byte Type: f32 [br]
+## Byte Length: 4 [br]
+## Always 10.
+var scale: float
+
+## Byte Type: i32 [br]
+## Byte Length: 4
+var texture_count: int
+
+## Byte Type: i32 [br]
+## Byte Length: 4
+## Always 80.
+var texture_path_length: int
+
+## Byte Length: [member texture_count] * [member texture_path_length] [br]
+var texture_paths: Array
+
+## Byte Type: i32 [br]
+## Byte Length: 4
+var light_map_slice_count: int
+
+## Byte Type: i32 [br]
+## Byte Length: 4
+var light_map_width: int
+
+## Byte Type: i32 [br]
+## Byte Length: 4
+var light_map_slice_height: int
+
+## Byte Type: i32 [br]
+## Byte Length: 4
+var light_map_cells_per_grid: int
+
+## Length: [member light_map_slice_count]
+var light_map_slices: Array
+
+## Byte Type: i32 [br]
+## Byte Length: 4
+var surface_count: int
+
+## Length: [member surface_count]
+var surfaces: Array[Surface]
+
+## Length: [member width] * [member height]
+var ground_mesh_cubes: Array[GroundMeshCube]
+
+
+static func from_bytes(bytes: ByteStream) -> GNDFormat:
+ var gnd_format = GNDFormat.new()
+
+ bytes.advance(gnd_format.signature.length())
+
+ @warning_ignore("shadowed_variable")
+ var version = Version.new()
+ version.major = bytes.decode_u8()
+ version.minor = bytes.decode_u8()
+ gnd_format.version = version
+
+ if version.minor > 7:
+ print(version)
+ return gnd_format
+
+ gnd_format.width = bytes.decode_s32()
+ gnd_format.height = bytes.decode_s32()
+ gnd_format.scale = bytes.decode_float()
+ gnd_format.texture_count = bytes.decode_s32()
+ gnd_format.texture_path_length = bytes.decode_s32()
+
+ gnd_format.texture_paths = []
+ for _n in gnd_format.texture_count:
+ gnd_format.texture_paths.append(
+ bytes.get_string_from_ascii(gnd_format.texture_path_length)
+ )
+
+ gnd_format.light_map_slice_count = bytes.decode_s32()
+ gnd_format.light_map_width = bytes.decode_s32()
+ gnd_format.light_map_slice_height = bytes.decode_s32()
+ gnd_format.light_map_cells_per_grid = bytes.decode_s32()
+
+ #gnd_format.light_map_slices = []
+ #for _n in gnd_format.light_map_slice_count:
+ #gnd_format.light_map_slices.append(LightMapSlice.from_bytes(bytes))
+ bytes.advance(
+ gnd_format.light_map_slice_count *
+ gnd_format.light_map_width *
+ gnd_format.light_map_slice_height *
+ 4
+ )
+
+ gnd_format.surface_count = bytes.decode_s32()
+
+ gnd_format.surfaces = [] as Array[Surface]
+ for _n in gnd_format.surface_count:
+ gnd_format.surfaces.append(Surface.from_bytes(bytes))
+
+ gnd_format.ground_mesh_cubes = [] as Array[GroundMeshCube]
+ for _n in (gnd_format.width * gnd_format.height):
+ gnd_format.ground_mesh_cubes.append(GroundMeshCube.from_bytes(bytes))
+
+ #print(inst_to_dict(gnd_format))
+ return gnd_format
+
+
+class LightMapSlice:
+ ## Byte Type: i32 [br]
+ ## Byte Length: 4
+ var pixel_format: int
+
+ ## Byte Type: i32 [br]
+ ## Byte Length: 4
+ var width: int
+
+ ## Byte Type: i32 [br]
+ ## Byte Length: 4
+ var height: int
+
+ ## Byte Length: [member width] * [member height]
+ var shadow_map_pixels: ByteStream
+
+ ## Byte Length: [member width] * [member height]
+ var light_map_pixels: ByteStream
+
+
+ static func from_bytes(bytes: ByteStream) -> LightMapSlice:
+ var slice = LightMapSlice.new()
+
+ slice.pixel_format = bytes.decode_s32()
+ slice.width = bytes.decode_s32()
+ slice.height = bytes.decode_s32()
+ slice.shadow_map_pixels = bytes.get_buffer(slice.width * slice.height)
+ slice.light_map_pixels = bytes.get_buffer(slice.width * slice.height)
+
+ #print(inst_to_dict(slice))
+ return slice
+
+
+class Surface:
+ ## Byte Type: f32 [br]
+ ## Byte Length: 4
+ var u_bottom_left: float
+
+ ## Byte Type: f32 [br]
+ ## Byte Length: 4
+ var u_bottom_right: float
+
+ ## Byte Type: f32 [br]
+ ## Byte Length: 4
+ var u_top_left: float
+
+ ## Byte Type: f32 [br]
+ ## Byte Length: 4
+ var u_top_right: float
+
+ ## Byte Type: f32 [br]
+ ## Byte Length: 4
+ var v_bottom_left: float
+
+ ## Byte Type: f32 [br]
+ ## Byte Length: 4
+ var v_bottom_right: float
+
+ ## Byte Type: f32 [br]
+ ## Byte Length: 4
+ var v_top_left: float
+
+ ## Byte Type: f32 [br]
+ ## Byte Length: 4
+ var v_top_right: float
+
+ ## Byte Type: i16 [br]
+ ## Byte Length: 2
+ var texture_index: int
+
+ ## Byte Type: i16 [br]
+ ## Byte Length: 2
+ var light_map_index: int
+
+ ## Byte Type: u8 [br]
+ ## Byte Length: 1
+ var vertex_color_blue: int
+
+ ## Byte Type: u8 [br]
+ ## Byte Length: 1
+ var vertex_color_green: int
+
+ ## Byte Type: u8 [br]
+ ## Byte Length: 1
+ var vertex_color_red: int
+
+ ## Byte Type: u8 [br]
+ ## Byte Length: 1
+ var vertex_color_alpha: int
+
+
+ func get_uvs() -> Dictionary: # Dictionary[Vector2, Vector2]
+ return {
+ Vector2(0, 0): Vector2(u_top_left, v_top_left),
+ Vector2(1, 0): Vector2(u_top_right, v_top_right),
+ Vector2(0, 1): Vector2(u_bottom_left, v_bottom_left),
+ Vector2(1, 1): Vector2(u_bottom_right, v_bottom_right),
+ }
+
+
+ static func from_bytes(bytes: ByteStream) -> Surface:
+ var surface = Surface.new()
+
+ surface.u_bottom_left = bytes.decode_float()
+ surface.u_bottom_right = bytes.decode_float()
+ surface.u_top_left = bytes.decode_float()
+ surface.u_top_right = bytes.decode_float()
+ surface.v_bottom_left = bytes.decode_float()
+ surface.v_bottom_right = bytes.decode_float()
+ surface.v_top_left = bytes.decode_float()
+ surface.v_top_right = bytes.decode_float()
+ surface.texture_index = bytes.decode_s16()
+ surface.light_map_index = bytes.decode_s16()
+ surface.vertex_color_blue = bytes.decode_u8()
+ surface.vertex_color_green = bytes.decode_u8()
+ surface.vertex_color_red = bytes.decode_u8()
+ surface.vertex_color_alpha = bytes.decode_u8()
+
+ #print(inst_to_dict(surface))
+ return surface
+
+
+class GroundMeshCube:
+ ## Byte Type: f32 [br]
+ ## Byte Length: 4
+ ## upper left?
+ var bottom_left_height: float
+
+ ## Byte Type: f32 [br]
+ ## Byte Length: 4
+ ## upper right?
+ var bottom_right_height: float
+
+ ## Byte Type: f32 [br]
+ ## Byte Length: 4
+ ## lower left?
+ var top_left_height: float
+
+ ## Byte Type: f32 [br]
+ ## Byte Length: 4
+ ## lower right?
+ var top_right_height: float
+
+ ## Byte Type: i32 [br]
+ ## Byte Length: 4
+ ## top surface index?
+ var upwards_facing_surface_index: int
+
+ ## Byte Type: i32 [br]
+ ## Byte Length: 4
+ ## front surface index?
+ var northern_wall_surface_index: int
+
+ ## Byte Type: i32 [br]
+ ## Byte Length: 4
+ ## right surface index?
+ var eastern_wall_surface_index: int
+
+
+ static func from_bytes(bytes: ByteStream) -> GroundMeshCube:
+ var mesh = GroundMeshCube.new()
+
+ mesh.bottom_left_height = bytes.decode_float()
+ mesh.bottom_right_height = bytes.decode_float()
+ mesh.top_left_height = bytes.decode_float()
+ mesh.top_right_height = bytes.decode_float()
+ mesh.upwards_facing_surface_index = bytes.decode_s32()
+ mesh.northern_wall_surface_index = bytes.decode_s32()
+ mesh.eastern_wall_surface_index = bytes.decode_s32()
+
+ #print(inst_to_dict(mesh))
+ return mesh