wow_m2/chunks/
sequence.rs1use crate::io_ext::{ReadExt, WriteExt};
2use std::io::{Read, Write};
3
4use crate::error::Result;
5use crate::version::M2Version;
6
7#[derive(Debug, Clone)]
9pub struct M2Sequence {
10 pub animation_id: u16,
12 pub sub_animation_id: u16,
14 pub start: u32,
16 pub end: u32,
18 pub movement_speed: f32,
20 pub flags: u32,
22 pub frequency: i16,
24 pub padding: u16,
26 pub replay: M2AnimationRepeat,
28 pub blend_time: u16,
30 pub bounds: M2Bounds,
32 pub variation_next: i16,
34 pub alias_next: u16,
36}
37
38#[derive(Debug, Clone)]
40pub struct M2AnimationRepeat {
41 pub minimum: u32,
43 pub maximum: u32,
45}
46
47impl M2AnimationRepeat {
48 pub fn parse<R: Read>(reader: &mut R) -> Result<Self> {
50 let minimum = reader.read_u32_le()?;
51 let maximum = reader.read_u32_le()?;
52
53 Ok(Self { minimum, maximum })
54 }
55
56 pub fn write<W: Write>(&self, writer: &mut W) -> Result<()> {
58 writer.write_u32_le(self.minimum)?;
59 writer.write_u32_le(self.maximum)?;
60
61 Ok(())
62 }
63}
64
65#[derive(Debug, Clone)]
67pub struct M2Bounds {
68 pub minimum: [f32; 3],
70 pub maximum: [f32; 3],
72 pub radius: f32,
74}
75
76impl M2Bounds {
77 pub fn parse<R: Read>(reader: &mut R) -> Result<Self> {
79 let mut minimum = [0.0; 3];
80 let mut maximum = [0.0; 3];
81
82 for item in &mut minimum {
83 *item = reader.read_f32_le()?;
84 }
85
86 for item in &mut maximum {
87 *item = reader.read_f32_le()?;
88 }
89
90 let radius = reader.read_f32_le()?;
91
92 Ok(Self {
93 minimum,
94 maximum,
95 radius,
96 })
97 }
98
99 pub fn write<W: Write>(&self, writer: &mut W) -> Result<()> {
101 for &value in &self.minimum {
102 writer.write_f32_le(value)?;
103 }
104
105 for &value in &self.maximum {
106 writer.write_f32_le(value)?;
107 }
108
109 writer.write_f32_le(self.radius)?;
110
111 Ok(())
112 }
113}
114
115impl M2Sequence {
116 pub fn parse<R: Read>(reader: &mut R, _version: u32) -> Result<Self> {
118 let animation_id = reader.read_u16_le()?;
119 let sub_animation_id = reader.read_u16_le()?;
120 let start = reader.read_u32_le()?;
121 let end = reader.read_u32_le()?;
122 let movement_speed = reader.read_f32_le()?;
123 let flags = reader.read_u32_le()?;
124 let frequency = reader.read_i16_le()?;
125 let padding = reader.read_u16_le()?;
126 let replay = M2AnimationRepeat::parse(reader)?;
127 let blend_time = reader.read_u16_le()?;
128 reader.read_u16_le()?;
130 let bounds = M2Bounds::parse(reader)?;
131 let variation_next = reader.read_i16_le()?;
132 let alias_next = reader.read_u16_le()?;
133
134 Ok(Self {
135 animation_id,
136 sub_animation_id,
137 start,
138 end,
139 movement_speed,
140 flags,
141 frequency,
142 padding,
143 replay,
144 blend_time,
145 bounds,
146 variation_next,
147 alias_next,
148 })
149 }
150
151 pub fn write<W: Write>(&self, writer: &mut W) -> Result<()> {
153 writer.write_u16_le(self.animation_id)?;
154 writer.write_u16_le(self.sub_animation_id)?;
155 writer.write_u32_le(self.start)?;
156 writer.write_u32_le(self.end)?;
157 writer.write_f32_le(self.movement_speed)?;
158 writer.write_u32_le(self.flags)?;
159 writer.write_i16_le(self.frequency)?;
160 writer.write_u16_le(self.padding)?;
161 self.replay.write(writer)?;
162 writer.write_u16_le(self.blend_time)?;
163 writer.write_u16_le(0)?;
165 self.bounds.write(writer)?;
166 writer.write_i16_le(self.variation_next)?;
167 writer.write_u16_le(self.alias_next)?;
168
169 Ok(())
170 }
171
172 pub fn convert(&self, _target_version: M2Version) -> Self {
174 self.clone()
175 }
176
177 pub fn new(animation_id: u16, sub_animation_id: u16, start: u32, end: u32) -> Self {
179 Self {
180 animation_id,
181 sub_animation_id,
182 start,
183 end,
184 movement_speed: 0.0,
185 flags: 0,
186 frequency: 0,
187 padding: 0,
188 replay: M2AnimationRepeat {
189 minimum: 0,
190 maximum: 0,
191 },
192 blend_time: 0,
193 bounds: M2Bounds {
194 minimum: [0.0, 0.0, 0.0],
195 maximum: [0.0, 0.0, 0.0],
196 radius: 0.0,
197 },
198 variation_next: -1,
199 alias_next: 0,
200 }
201 }
202}
203
204#[cfg(test)]
205mod tests {
206 use super::*;
207 use std::io::Cursor;
208
209 #[test]
210 fn test_sequence_parse_write() {
211 let sequence = M2Sequence::new(1, 0, 0, 30);
212
213 let mut buffer = Vec::new();
215 sequence.write(&mut buffer).unwrap();
216
217 let mut cursor = Cursor::new(buffer);
219 let parsed =
220 M2Sequence::parse(&mut cursor, M2Version::Vanilla.to_header_version()).unwrap();
221
222 assert_eq!(parsed.animation_id, 1);
224 assert_eq!(parsed.sub_animation_id, 0);
225 assert_eq!(parsed.start, 0);
226 assert_eq!(parsed.end, 30);
227 }
228}