diff options
author | Daniel Weipert <git@mail.dweipert.de> | 2025-01-05 16:54:36 +0100 |
---|---|---|
committer | Daniel Weipert <git@mail.dweipert.de> | 2025-01-05 16:54:36 +0100 |
commit | 35b0f811f23f029110373798b19d9d0895d907f0 (patch) | |
tree | 2e4906a992c2569fa0f89dbe0f079010a734cc41 /extractor/rsm_format.gd | |
parent | e08a29e73ea4f7e6d78e8e7f5a6e7033dbc1f542 (diff) |
next commit
Diffstat (limited to 'extractor/rsm_format.gd')
-rw-r--r-- | extractor/rsm_format.gd | 521 |
1 files changed, 521 insertions, 0 deletions
diff --git a/extractor/rsm_format.gd b/extractor/rsm_format.gd index d3dabb0..cf83af9 100644 --- a/extractor/rsm_format.gd +++ b/extractor/rsm_format.gd @@ -73,10 +73,56 @@ static func from_bytes(bytes: ByteStream) -> RSMFormat: version.minor = bytes.decode_u8() rsm_format.version = version + rsm_format.animation_length = bytes.decode_u32() + rsm_format.shade_type = bytes.decode_u32() + + if version.higher_than(1, 3): # >= 1.4 + rsm_format.alpha = bytes.decode_u8() + + if version.lower_than(2, 2): # < 2.2 + rsm_format.reserved = bytes.get_buffer(16).bytes + + if version.higher_than(2, 1): # >= 2.2 + rsm_format.frames_per_second = bytes.decode_float() + + if version.lower_than(2, 3): # < 2.3 + rsm_format.texture_count = bytes.decode_u32() + + rsm_format.texture_names = [] as Array[String] + for _n in rsm_format.texture_count: + rsm_format.texture_names.append(bytes.get_string_from_utf8(40)) + + rsm_format.root_node_name = bytes.get_string_from_utf8(40) + + if version.higher_than(2, 1): # >= 2.2 + rsm_format.root_node_count = bytes.decode_u32() + + rsm_format.root_node_names = [] as Array[String] + for _n in rsm_format.root_node_count: + rsm_format.root_node_names.append(bytes.get_string_from_utf8(40)) + + rsm_format.node_count = bytes.decode_u32() + rsm_format.nodes = [] as Array[ModelNode] + for _n in rsm_format.node_count: + rsm_format.nodes.append(ModelNode.from_bytes(bytes, version)) + print(inst_to_dict(rsm_format)) + #print(inst_to_dict(rsm_format.nodes[0].texture_coordinates[0])) + #rsm_format.nodes[0].texture_coordinates.clear() + #print(inst_to_dict(rsm_format.nodes[0].faces[0])) + #rsm_format.nodes[0].faces.clear() + #print(inst_to_dict(rsm_format.nodes[0])) return rsm_format +func convert() -> Node3D: + var node := Node3D.new() + node.name = root_node_name + #node.set_script(load("res://extractor/model.gd")) + + return node + + class ModelNode: ## Byte Type: u8 [br] ## Byte Length: 40 @@ -85,3 +131,478 @@ class ModelNode: ## Byte Type: u8 [br] ## Byte Length: 40 var parent_node_name: String + + ## Byte Type: u32 [br] + ## Byte Length: 4 [br] + ## Versions: [<2.3] + var texture_count: int + + ## Byte Type: u32 [br] + ## Byte Length: 4 [br] + ## Length: [member texture_count] [br] + ## Versions: [<2.3] + var texture_indices: Array[int] + + ## Byte Type: u32 [br] + ## Byte Length: 4 [br] + ## Versions: [>=2.3] + var texture_name_count: int + + ## Byte Length: 40 [br] + ## Length: [member texture_name_count] [br] + ## Versions: [>=2.3] + var texture_names: Array[String] + + ## Byte Type: f32 [br] + ## Byte Length: 4 * 9 [br] + ## Length: 9 [br] + ## 3 x 3 Matrix. Each element represents a column. + var offset_matrix: Array[Vector3] + + ## Byte Type: f32 [br] + ## Byte Length: 4 * 3 [br] + ## Versions: [<2.2] + var translation_1: Vector3 + + ## Byte Type: f32 [br] + ## Byte Length: 4 * 3 [br] + var translation_2: Vector3 + + ## Byte Type: f32 [br] + ## Byte Length: 4 [br] + ## Versions: [<2.2] + var rotation_angle: float + + ## Byte Type: f32 [br] + ## Byte Length: 4 * 3 [br] + ## Versions: [<2.2] + var rotation_axis: Vector3 + + ## Byte Type: f32 [br] + ## Byte Length: 4 * 3 [br] + ## Versions: [<2.2] + var scale: Vector3 + + ## Byte Type: u32 [br] + ## Byte Length: 4 + var vertex_position_count: int + + ## Byte Type: f32 [br] + ## Byte Length: 4 * 3 * [member vertex_position_count] [br] + ## Length: [member vertex_position_count] + var vertex_positions: Array[Vector3] + + ## Byte Type: u32 [br] + ## Byte Length: 4 + var texture_coordinate_count: int + + ## Length: [member texture_coordinate_count] + var texture_coordinates: Array[TextureCoordinate] + + ## Byte Type: u32 [br] + ## Byte Length: 4 + var face_count: int + + ## Length: [member face_count] + var faces: Array[Face] + + ## Byte Type: u32 [br] + ## Byte Length: 4 + ## Versions: [>=1.6] + var scale_keyframe_count: int + + ## Length: [member scale_keyframe_count] + ## Versions: [>=1.6] + var scale_keyframes: Array[ScaleKeyframe] + + ## Byte Type: u32 [br] + ## Byte Length: 4 + var rotation_keyframe_count: int + + ## Length: [member scale_keyframe_count] + var rotation_keyframes: Array[RotationKeyframe] + + ## Byte Type: u32 [br] + ## Byte Length: 4 + ## Versions: [>=2.2] + var translation_keyframe_count: int + + ## Length: [member scale_keyframe_count] + ## Versions: [>=2.2] + var translation_keyframes: Array[TranslationKeyframe] + + ## Byte Type: u32 [br] + ## Byte Length: 4 + ## Versions: [>=2.3] + var textures_keyframe_count: int + + ## Length: [member scale_keyframe_count] + ## Versions: [>=2.3] + var textures_keyframes: Array[TexturesKeyframe] + + + static func from_bytes(bytes: ByteStream, version: Version) -> ModelNode: + var node = ModelNode.new() + + node.node_name = bytes.get_string_from_utf8(40) + node.parent_node_name = bytes.get_string_from_utf8(40) + + if version.lower_than(2, 3): # < 2.3 + node.texture_count = bytes.decode_u32() + + node.texture_indices = [] as Array[int] + for _n in node.texture_count: + node.texture_indices.append(bytes.decode_u32()) + + if version.higher_than(2, 2): # >= 2.3 + node.texture_name_count = bytes.decode_u32() + + node.texture_names = [] as Array[String] + for _n in node.texture_name_count: + node.texture_names.append(bytes.get_string_from_utf8(40)) + + node.offset_matrix = [] as Array[Vector3] + for _in in 3: + node.offset_matrix.append(Vector3( + bytes.decode_float(), + bytes.decode_float(), + bytes.decode_float() + )) + + if version.lower_than(2, 2): + node.translation_1 = Vector3( + bytes.decode_float(), + bytes.decode_float(), + bytes.decode_float() + ) + + node.translation_2 = Vector3( + bytes.decode_float(), + bytes.decode_float(), + bytes.decode_float() + ) + + if version.lower_than(2, 2): + node.rotation_angle = bytes.decode_float() + node.rotation_axis = Vector3( + bytes.decode_float(), + bytes.decode_float(), + bytes.decode_float() + ) + node.scale = Vector3( + bytes.decode_float(), + bytes.decode_float(), + bytes.decode_float() + ) + + node.vertex_position_count = bytes.decode_u32() + node.vertex_positions = [] as Array[Vector3] + + for _n in node.vertex_position_count: + node.vertex_positions.append(Vector3( + bytes.decode_float(), + bytes.decode_float(), + bytes.decode_float() + )) + + node.texture_coordinate_count = bytes.decode_u32() + node.texture_coordinates = [] as Array[TextureCoordinate] + + for _n in node.texture_coordinate_count: + node.texture_coordinates.append(TextureCoordinate.from_bytes(bytes, version)) + + node.face_count = bytes.decode_u32() + node.faces = [] as Array[Face] + + for _n in node.face_count: + node.faces.append(Face.from_bytes(bytes, version)) + + if version.higher_than(1, 5): # >= 1.6 + node.scale_keyframe_count = bytes.decode_u32() + node.scale_keyframes = [] as Array[ScaleKeyframe] + + for _n in node.scale_keyframe_count: + node.scale_keyframes.append(ScaleKeyframe.from_bytes(bytes)) + + node.rotation_keyframe_count = bytes.decode_u32() + node.rotation_keyframes = [] as Array[RotationKeyframe] + + for _n in node.rotation_keyframe_count: + node.rotation_keyframes.append(RotationKeyframe.from_bytes(bytes)) + + if version.higher_than(2, 1): # >= 2.2 + node.translation_keyframe_count = bytes.decode_u32() + node.translation_keyframes = [] as Array[ScaleKeyframe] + + for _n in node.translation_keyframe_count: + node.translation_keyframes.append(TranslationKeyframe.from_bytes(bytes)) + + if version.higher_than(2, 2): # >= 2.3 + node.textures_keyframe_count = bytes.decode_u32() + node.textures_keyframes = [] as Array[TexturesKeyframe] + + for _n in node.textures_keyframe_count: + node.textures_keyframes.append(TexturesKeyframe.from_bytes(bytes)) + + return node + + +class TextureCoordinate: + ## Byte Type: u32 [br] + ## Byte Length: 4 [br] + ## Versions: [>=1.2] + var color: int + + ## Byte Type: f32 [br] + ## Byte Length: 4 * 2 [br] + ## Note: possibly wrong if version < 1.2 + var coordinates: Vector2 + + + static func from_bytes(bytes: ByteStream, version: Version) -> TextureCoordinate: + var data = TextureCoordinate.new() + + if version.higher_than(1, 1): + data.color = bytes.decode_u32() + + data.coordinates = Vector2( + bytes.decode_float(), + bytes.decode_float() + ) + + return data + + +class Face: + ## Byte Type: u32 [br] + ## Byte Length: 4 [br] + ## Versions: [>=2.2] + var length: int + + ## Byte Type: u16 [br] + ## Byte Length: 2 * 3 + ## Length: 3 + var vertex_position_indices: Array[int] + + ## Byte Type: u16 [br] + ## Byte Length: 2 * 3 + ## Length: 3 + var texture_coordinate_indices: Array[int] + + ## Byte Type: u16 [br] + ## Byte Length: 2 + var texture_index: int + + ## Byte Type: u16 [br] + ## Byte Length: 2 + var padding: int + + ## Byte Type: i32 [br] + ## Byte Length: 4 + var two_sided: int + + ## Byte Type: i32 [br] + ## Byte Length: 4 + var smooth_group: int + + ## Byte Type: i32 [br] + ## Length: ([member length] - 24) / 4 [br] + ## Versions: [>=2.2] + # TODO: saturating_sub? + var smooth_group_extra: Array[int] + + + static func from_bytes(bytes: ByteStream, version: Version) -> Face: + var data = Face.new() + + if version.higher_than(2, 1): + data.length = bytes.decode_u32() + + data.vertex_position_indices = [] as Array[int] + for _in in 3: + data.vertex_position_indices.append(bytes.decode_u16()) + + data.texture_coordinate_indices = [] as Array[int] + for _in in 3: + data.texture_coordinate_indices.append(bytes.decode_u16()) + + data.texture_index = bytes.decode_u16() + data.padding = bytes.decode_u16() + data.two_sided = bytes.decode_s32() + data.smooth_group = bytes.decode_s32() + + if version.higher_than(2, 1): + data.smooth_group_extra = [] as Array[int] + + for _n in ((data.length - 24) / 4): + data.smooth_group_extra.append(bytes.decode_s32()) + + return data + + +class ScaleKeyframe: + ## Byte Type: u32 [br] + ## Byte Length: 4 [br] + var frame: int + + ## Byte Type: f32 [br] + ## Byte Length: 4 * 3 [br] + var scale: Vector3 + + ## Byte Type: f32 [br] + ## Byte Length: 4 [br] + var reserved: float + + + static func from_bytes(bytes: ByteStream) -> ScaleKeyframe: + var data = ScaleKeyframe.new() + + data.frame = bytes.decode_u32() + data.scale = Vector3( + bytes.decode_float(), + bytes.decode_float(), + bytes.decode_float() + ) + data.reserved = bytes.decode_float() + + return data + + +class RotationKeyframe: + ## Byte Type: u32 [br] + ## Byte Length: 4 [br] + var frame: int + + ## Byte Type: f32 [br] + ## Byte Length: 4 * 3 [br] + var rotation: Vector4 + + + static func from_bytes(bytes: ByteStream) -> RotationKeyframe: + var data = RotationKeyframe.new() + + data.frame = bytes.decode_u32() + data.rotation = Vector4( + bytes.decode_float(), + bytes.decode_float(), + bytes.decode_float(), + bytes.decode_float() + ) + + return data + + +class TranslationKeyframe: + ## Byte Type: u32 [br] + ## Byte Length: 4 [br] + var frame: int + + ## Byte Type: f32 [br] + ## Byte Length: 4 * 3 [br] + var translation: Vector3 + + ## Byte Type: f32 [br] + ## Byte Length: 4 [br] + var reserved: float + + + static func from_bytes(bytes: ByteStream) -> ScaleKeyframe: + var data = ScaleKeyframe.new() + + data.frame = bytes.decode_u32() + data.translation = Vector3( + bytes.decode_float(), + bytes.decode_float(), + bytes.decode_float() + ) + data.reserved = bytes.decode_float() + + return data + + +enum TextureOperation { + ## Texture translation on the X axis. The texture is tiled. + Translation_X, + + ## Texture translation on the Y axis. The texture is tiled. + Translation_Y, + + ## Texture multiplication on the X axis. The texture is tiled. + Scale_X, + + ## Texture multiplication on the Y axis. The texture is tiled. + Scale_Y, + + ## Texture rotation around (0, 0). The texture is not tiled. + Rotation, +} + + +class TexturesKeyframe: + ## Byte Type: u32 [br] + ## Byte Length: 4 + var texture_index: int + + ## Byte Type: u32 [br] + ## Byte Length: 4 + var texture_keyframe_count: int + + ## Length: [member texture_keyframe_count] + var texture_keyframes: Array[TextureKeyframe] + + + static func from_bytes(bytes: ByteStream) -> TexturesKeyframe: + var data = TexturesKeyframe.new() + + data.texture_index = bytes.decode_u32() + data.texture_keyframe_count = bytes.decode_u32() + + data.texture_keyframes = [] as Array[TextureKeyframe] + for _n in data.texture_keyframe_count: + data.texture_keyframes.append(TextureKeyframe.from_bytes(bytes)) + + return data + + +class TextureKeyframe: + ## Byte Type: u8 + var operation_type: TextureOperation + + ## Byte Type: u32 [br] + ## Byte Length: 4 + var frame_count: int + + ## Length: [member frame_count] + var texture_frames: Array[TextureFrame] + + + static func from_bytes(bytes: ByteStream) -> TextureKeyframe: + var data = TextureKeyframe.new() + + data.operation_type = bytes.decode_u8() + data.frame_count = bytes.decode_u32() + + data.texture_frames = [] as Array[TextureFrame] + for _n in data.frame_count: + data.texture_frames.append(TextureFrame.from_bytes(bytes)) + + return data + + +class TextureFrame: + ## Byte Type: u32 [br] + ## Byte Length: 4 [br] + var frame: int + + ## Byte Type: f32 [br] + ## Byte Length: 4 [br] + var translation: float + + + static func from_bytes(bytes: ByteStream) -> TextureFrame: + var data = TextureFrame.new() + + data.frame = bytes.decode_u32() + data.translation = bytes.decode_float() + + return data |