Skip to main content

rpfm_lib/files/rigidmodel/materials/
weighted_cloth.rs

1//---------------------------------------------------------------------------//
2// Copyright (c) 2017-2026 Ismael Gutiérrez González. All rights reserved.
3//
4// This file is part of the Rusted PackFile Manager (RPFM) project,
5// which can be found here: https://github.com/Frodo45127/rpfm.
6//
7// This file is licensed under the MIT license, which can be found here:
8// https://github.com/Frodo45127/rpfm/blob/master/LICENSE.
9//---------------------------------------------------------------------------//
10
11use super::*;
12
13/// Size in bytes of the name of a cloth bone.
14const CLOTH_BONE_NAME_SIZE: usize = 32;
15
16//---------------------------------------------------------------------------//
17//                            Implementation
18//---------------------------------------------------------------------------//
19
20/// Weighted cloth materials of version 6 RigidModels: the default material, followed by the bones of the cloth simulation.
21impl Material {
22    pub fn read_weighted_cloth<R: ReadBytes>(data: &mut R, version: u32) -> Result<Self> {
23        let mut material = Self::read_default(data, version)?;
24
25        let bone_count = data.read_u32()?;
26        material.uk_1 = data.read_u32()?;
27        material.cloth_bones = Vec::with_capacity(bone_count as usize);
28
29        for _ in 0..bone_count {
30            let (name, name_padding) = read_string_0padded_with_tail(data, CLOTH_BONE_NAME_SIZE, true)?;
31            material.cloth_bones.push(ClothBone {
32                name,
33                name_padding,
34                uk_1: Vector3::new(data.read_f32()?, data.read_f32()?, data.read_f32()?),
35                uk_2: data.read_u32()?,
36                uk_3: data.read_u32()?,
37                uk_4: data.read_u32()?,
38                uk_5: data.read_u32()?,
39                uk_6: data.read_u32()?,
40                uk_7: data.read_f32()?,
41                matrix: Matrix3x4::new(
42                    data.read_f32()?, data.read_f32()?, data.read_f32()?, data.read_f32()?,
43                    data.read_f32()?, data.read_f32()?, data.read_f32()?, data.read_f32()?,
44                    data.read_f32()?, data.read_f32()?, data.read_f32()?, data.read_f32()?
45                ),
46                parent_index: data.read_i32()?,
47                vertex_index: data.read_u32()?,
48            });
49        }
50
51        Ok(material)
52    }
53
54    pub fn write_weighted_cloth<W: WriteBytes>(&self, buffer: &mut W, version: u32) -> Result<()> {
55        self.write_default(buffer, version)?;
56
57        buffer.write_u32(self.cloth_bones.len() as u32)?;
58        buffer.write_u32(self.uk_1)?;
59
60        for bone in &self.cloth_bones {
61            write_string_0padded_with_tail(buffer, &bone.name, &bone.name_padding, CLOTH_BONE_NAME_SIZE, true)?;
62            buffer.write_f32(bone.uk_1.x)?;
63            buffer.write_f32(bone.uk_1.y)?;
64            buffer.write_f32(bone.uk_1.z)?;
65            buffer.write_u32(bone.uk_2)?;
66            buffer.write_u32(bone.uk_3)?;
67            buffer.write_u32(bone.uk_4)?;
68            buffer.write_u32(bone.uk_5)?;
69            buffer.write_u32(bone.uk_6)?;
70            buffer.write_f32(bone.uk_7)?;
71
72            // The matrix is stored row by row, while nalgebra iterates matrices column by column.
73            for row in bone.matrix.row_iter() {
74                for value in row.iter() {
75                    buffer.write_f32(*value)?;
76                }
77            }
78
79            buffer.write_i32(bone.parent_index)?;
80            buffer.write_u32(bone.vertex_index)?;
81        }
82
83        Ok(())
84    }
85}