summaryrefslogtreecommitdiff
path: root/extractor/rsm_format.gd
diff options
context:
space:
mode:
Diffstat (limited to 'extractor/rsm_format.gd')
-rw-r--r--extractor/rsm_format.gd521
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