From e8f03c4d6a94aa16b3587bdce525cf0cf7c6c6c3 Mon Sep 17 00:00:00 2001 From: Daniel Weipert Date: Tue, 14 Jan 2025 14:38:52 +0100 Subject: next commit --- extractor/actions.gd | 1 + extractor/extractor_interface.gd | 43 +++++++++++++++++ extractor/extractor_interface.tscn | 98 ++++++++++++++++++++++++++++++++++++++ extractor/gnd_format.gd | 21 ++++---- extractor/grf.gd | 26 +++++++++- extractor/rsm_format.gd | 11 +++-- extractor/rsw_format.gd | 46 +++--------------- 7 files changed, 193 insertions(+), 53 deletions(-) create mode 100644 extractor/extractor_interface.gd create mode 100644 extractor/extractor_interface.tscn (limited to 'extractor') diff --git a/extractor/actions.gd b/extractor/actions.gd index 5c94cef..e5dafda 100644 --- a/extractor/actions.gd +++ b/extractor/actions.gd @@ -1,3 +1,4 @@ +class_name Actions extends Node2D diff --git a/extractor/extractor_interface.gd b/extractor/extractor_interface.gd new file mode 100644 index 0000000..e987ed3 --- /dev/null +++ b/extractor/extractor_interface.gd @@ -0,0 +1,43 @@ +extends Control + + +func _ready() -> void: + var grf = GRF.open("res://client_data/data.grf") + grf.extract()#"user://client_data") + #grf.convert()#"user://client_data") + + #Sprite.from_bytes(FileAccess.get_file_as_bytes("res://client_data/data/sprite/cursors.spr")) + #ActionFormat.from_bytes( + #ByteStream.from_bytes( + #FileAccess.get_file_as_bytes("res://client_data/data/sprite/cursors.act") + #) + #) + #GATFormat.from_bytes( + #ByteStream.from_bytes( + #FileAccess.get_file_as_bytes("res://client_data/data/int_land02.gat") + #) + #) + #GNDFormat.from_bytes( + #ByteStream.from_bytes( + #FileAccess.get_file_as_bytes("res://client_data/data/int_land02.gnd") + #) + #) + var rsw = RSWFormat.from_bytes( + ByteStream.from_bytes( + #FileAccess.get_file_as_bytes("res://client_data/data/int_land02.rsw") + FileAccess.get_file_as_bytes("res://client_data/data/pay_dun00.rsw") + ) + ) + #RSMFormat.from_bytes( + #ByteStream.from_bytes( + ##FileAccess.get_file_as_bytes("res://client_data/data/model/prontera/chair_01.rsm") + #FileAccess.get_file_as_bytes("res://client_data/data/model/izlude/iz_academy.rsm") + ## TODO: not parseable + ##FileAccess.get_file_as_bytes("res://client_data/data/model/graywolf/bridge_e_01.rsm2") + #) + #) + + var scene_root := rsw.convert("pay_dun00", "res://client_data") + var scene := PackedScene.new() + scene.pack(scene_root) + ResourceSaver.save(scene, "res://extractor/test/pay_dun00.tscn") diff --git a/extractor/extractor_interface.tscn b/extractor/extractor_interface.tscn new file mode 100644 index 0000000..7220d5c --- /dev/null +++ b/extractor/extractor_interface.tscn @@ -0,0 +1,98 @@ +[gd_scene load_steps=3 format=3 uid="uid://bfi14ujn6fe1n"] + +[ext_resource type="Script" uid="uid://db2yelol3joq0" path="res://extractor/extractor_interface.gd" id="1_hyoq1"] + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_hyoq1"] +bg_color = Color(0.287085, 0.287085, 0.287085, 1) +border_width_left = 1 +border_width_top = 1 +border_width_right = 1 +border_width_bottom = 1 +border_color = Color(0.47166, 0.47166, 0.471659, 1) + +[node name="ExtractorInterface" type="Control"] +layout_mode = 3 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +script = ExtResource("1_hyoq1") + +[node name="HBoxContainer" type="HBoxContainer" parent="."] +layout_mode = 2 +offset_left = 387.0 +offset_top = 307.0 +offset_right = 765.0 +offset_bottom = 340.0 + +[node name="PanelContainer" type="PanelContainer" parent="HBoxContainer"] +layout_mode = 2 +theme_override_styles/panel = SubResource("StyleBoxFlat_hyoq1") + +[node name="HBoxContainer" type="HBoxContainer" parent="HBoxContainer/PanelContainer"] +layout_mode = 2 +theme_override_constants/separation = 0 + +[node name="LineEdit" type="LineEdit" parent="HBoxContainer/PanelContainer/HBoxContainer"] +layout_mode = 2 +text = "res://client_data/data.grf" +expand_to_text_length = true + +[node name="Button" type="Button" parent="HBoxContainer/PanelContainer/HBoxContainer"] +layout_mode = 2 +text = "Select File" + +[node name="Button" type="Button" parent="HBoxContainer"] +layout_mode = 2 +text = "Open GRF" + +[node name="VBoxContainer" type="VBoxContainer" parent="."] +layout_mode = 0 +offset_left = 386.0 +offset_top = 349.0 +offset_right = 754.0 +offset_bottom = 389.0 + +[node name="HBoxContainer2" type="HBoxContainer" parent="VBoxContainer"] +layout_mode = 2 + +[node name="PanelContainer2" type="PanelContainer" parent="VBoxContainer/HBoxContainer2"] +layout_mode = 2 +theme_override_styles/panel = SubResource("StyleBoxFlat_hyoq1") + +[node name="HBoxContainer" type="HBoxContainer" parent="VBoxContainer/HBoxContainer2/PanelContainer2"] +layout_mode = 2 +theme_override_constants/separation = 0 + +[node name="LineEdit" type="LineEdit" parent="VBoxContainer/HBoxContainer2/PanelContainer2/HBoxContainer"] +layout_mode = 2 +text = "res://client_data" +expand_to_text_length = true + +[node name="Button" type="Button" parent="VBoxContainer/HBoxContainer2/PanelContainer2/HBoxContainer"] +layout_mode = 2 +text = "Select Directory" + +[node name="Button" type="Button" parent="VBoxContainer/HBoxContainer2"] +layout_mode = 2 +text = "Extract GRF" + +[node name="ProgressBar" type="ProgressBar" parent="VBoxContainer"] +layout_mode = 2 + +[node name="Button" type="Button" parent="."] +layout_mode = 0 +offset_left = 272.0 +offset_top = 433.0 +offset_right = 476.0 +offset_bottom = 464.0 +text = "Convert Sprites & Actions" + +[node name="Button2" type="Button" parent="."] +layout_mode = 0 +offset_left = 498.0 +offset_top = 434.0 +offset_right = 614.0 +offset_bottom = 465.0 +text = "Convert Maps" diff --git a/extractor/gnd_format.gd b/extractor/gnd_format.gd index 65635cf..faad9ae 100644 --- a/extractor/gnd_format.gd +++ b/extractor/gnd_format.gd @@ -124,6 +124,8 @@ static func from_bytes(bytes: ByteStream) -> GNDFormat: func get_cubes() -> Array: + # TODO: return custom type with helper functions for getting neighboring cubes and building a full cube + var cubes := [] for cube in ground_mesh_cubes: cubes.append({ @@ -163,6 +165,9 @@ func convert(data_path: String) -> GridMap: for x in width: for y in height: var cube = cubes[x + y * width] + + # TODO: get all sides of a cube and add that mesh to the library + # TODO: so a single mesh per cube for surface_type in [Vector3(0, 1, 0)]: var mesh: ArrayMesh = cube[surface_type].mesh var material := StandardMaterial3D.new() @@ -300,8 +305,6 @@ class Surface: var uvs = get_uvs() var color = get_vertex_color() - var tiles_per_surface := 2 * 2 - surface_tool.add_triangle_fan( PackedVector3Array([ vertices[Vector2(0, 0)], @@ -309,9 +312,9 @@ class Surface: vertices[Vector2(1, 1)], ]), PackedVector2Array([ - uvs[Vector2(0, 0)] * tiles_per_surface, - uvs[Vector2(1, 0)] * tiles_per_surface, - uvs[Vector2(1, 1)] * tiles_per_surface, + uvs[Vector2(0, 0)], + uvs[Vector2(1, 0)], + uvs[Vector2(1, 1)], ]), PackedColorArray([ color, color, color, @@ -324,9 +327,9 @@ class Surface: vertices[Vector2(0, 1)], ]), PackedVector2Array([ - uvs[Vector2(0, 0)] * tiles_per_surface, - uvs[Vector2(1, 1)] * tiles_per_surface, - uvs[Vector2(0, 1)] * tiles_per_surface, + uvs[Vector2(0, 0)], + uvs[Vector2(1, 1)], + uvs[Vector2(0, 1)], ]), PackedColorArray([ color, color, color, @@ -420,3 +423,5 @@ class GroundMeshCube: #print(inst_to_dict(mesh)) return mesh + + # TODO: convert function to build cube mesh? or at least with neighbor input build full cube struct diff --git a/extractor/grf.gd b/extractor/grf.gd index a723fdc..84918de 100644 --- a/extractor/grf.gd +++ b/extractor/grf.gd @@ -190,17 +190,29 @@ static func open(path: String): return grf +signal extracted_file(index: int) + func extract(destination: String = "user://client_data"): DirAccess.make_dir_recursive_absolute(destination) - for file_entry in file_entries: + for idx in file_entries.size(): + var file_entry := file_entries[idx] var file_path: String = file_entry.get_file_path() var base_directory = DirAccess.open(destination) base_directory.make_dir_recursive(file_path.get_base_dir()) var file = FileAccess.open("%s/%s" % [destination, file_path], FileAccess.WRITE_READ) + + #if file_path.ends_with(".bmp"): + #var img := Image.create_empty(1, 1, false, Image.FORMAT_RGBA8) + #img.load_bmp_from_buffer(file_entry.get_contents(file_access)) + #img.save_png(file.get_path()) + #return + #else: file.store_buffer(file_entry.get_contents(file_access)) + + extracted_file.emit(idx) func convert(destination: String = "res://client_data"): @@ -220,6 +232,18 @@ func convert(destination: String = "res://client_data"): #DirAccess.make_dir_recursive_absolute(base_file_directory_path) + # BMP + if file_path.ends_with(".bmp"): + if not FileAccess.file_exists("%s/%s" % [destination, file_path]): + continue + + var image := BMPTexture.convert_image( + Image.load_from_file("%s/%s" % [destination, file_path]), + [Color.MAGENTA] + ) + image.save_png("%s/%s" % [destination, file_path.replace(".bmp", ".png")]) + + continue # Sprite.spr and Action.act var player_head_path_part = "¸Ó¸®Åë" diff --git a/extractor/rsm_format.gd b/extractor/rsm_format.gd index 2eccbd2..7eb41f0 100644 --- a/extractor/rsm_format.gd +++ b/extractor/rsm_format.gd @@ -178,6 +178,7 @@ class ModelNode: ## Byte Type: f32 [br] ## Byte Length: 4 [br] ## Versions: [<2.2] + ## Type: Radiants var rotation_angle: float ## Byte Type: f32 [br] @@ -361,7 +362,7 @@ class ModelNode: node.translate(translation_2) if rotation_axis != Vector3.ZERO: - node.rotate(rotation_axis, rotation_angle) + node.rotate_object_local(rotation_axis, rotation_angle) node.scale = scale @@ -373,11 +374,11 @@ class ModelNode: var face := faces[idx] surface_tool.add_triangle_fan( - PackedVector3Array(face.vertex_position_indices.map(func(idx): - return vertex_positions[idx]) + PackedVector3Array(face.vertex_position_indices.map(func(item_idx): + return vertex_positions[item_idx]) ), - PackedVector2Array(face.texture_coordinate_indices.map(func(idx): - return texture_coordinates[idx].coordinates) + PackedVector2Array(face.texture_coordinate_indices.map(func(item_idx): + return texture_coordinates[item_idx].coordinates) ) ) surface_tool.commit(mesh) diff --git a/extractor/rsw_format.gd b/extractor/rsw_format.gd index e38dad9..1066168 100644 --- a/extractor/rsw_format.gd +++ b/extractor/rsw_format.gd @@ -127,9 +127,9 @@ func convert(name: String, data_path: String) -> Node3D: var model_root := Node3D.new() model_root.name = resource.name model_root.position = resource.get_position() * Vector3(-1, 1, 1) - model_root.rotate_x(resource.get_rotation().x) - model_root.rotate_y(resource.get_rotation().y) - model_root.rotate_z(resource.get_rotation().z) + model_root.rotate_x(deg_to_rad(resource.get_rotation().x)) + model_root.rotate_y(deg_to_rad(resource.get_rotation().y)) + model_root.rotate_z(deg_to_rad(resource.get_rotation().z)) model_root.scale = resource.get_scale() node.add_child(model_root) @@ -177,43 +177,8 @@ func convert(name: String, data_path: String) -> Node3D: node.add_child(particles, true) particles.owner = node - #var ground := MeshInstance3D.new() - #var mesh := ArrayMesh.new() - #var surface_tool := SurfaceTool.new() - #surface_tool.begin(Mesh.PRIMITIVE_TRIANGLES) - #for surface_idx in gnd.surfaces.size(): - #if surface_idx < 1: - #continue - # - #var surface: GNDFormat.Surface = gnd.surfaces[surface_idx] - # - #surface_tool.add_triangle_fan( - #PackedVector3Array([Vector3(-0.5, -0.5, 0), Vector3(0.5, -0.5, 0), Vector3(-0.5, -0.5, -0.5)]), - #PackedVector2Array([surface.get_uvs()[Vector2(0, 0)], surface.get_uvs()[Vector2(1, 0)], surface.get_uvs()[Vector2(0, 1)]]), - #PackedColorArray([surface.get_vertex_color(),surface.get_vertex_color(),surface.get_vertex_color()]) - #) - #surface_tool.add_triangle_fan( - #PackedVector3Array([Vector3(0.5, -0.5, 0), Vector3(0.5, -0.5, -0.5), Vector3(-0.5, -0.5, -0.5)]), - #PackedVector2Array([surface.get_uvs()[Vector2(1, 0)], surface.get_uvs()[Vector2(1, 1)], surface.get_uvs()[Vector2(0, 1)]]), - #PackedColorArray([surface.get_vertex_color(),surface.get_vertex_color(),surface.get_vertex_color()]) - #) - #surface_tool.commit(mesh) - #var material := StandardMaterial3D.new() - #material.albedo_texture = load("%s/data/texture/%s" % [data_path, gnd.texture_paths[surface.texture_index]]) - #mesh.surface_set_material(0, material) - #print(surface.get_uvs()) - #break - - - #grid_map.owner = node - - #ground.mesh = mesh - # - #node.add_child(ground) - #ground.owner = node - var grid_map := gnd.convert(data_path) - grid_map.name = gnd_file_path.get_basename() + grid_map.name = "Ground" node.add_child(grid_map) grid_map.owner = node @@ -393,14 +358,17 @@ class Animated3DModel extends MapResource: ## Byte Type: f32 [br] ## Byte Length: 4 + ## Type: Degrees var rotation_x: float ## Byte Type: f32 [br] ## Byte Length: 4 + ## Type: Degrees var rotation_y: float ## Byte Type: f32 [br] ## Byte Length: 4 + ## Type: Degrees var rotation_z: float ## Byte Type: f32 [br] -- cgit v1.2.3