1use std::io::Read;
9
10use anyhow::{Result, bail};
11
12use crate::resource::prp::PlasmaRead;
13
14#[derive(Debug, Clone, Copy, PartialEq, Eq)]
16#[repr(u8)]
17pub enum KeyType {
18 Unknown = 0,
19 Point3 = 1,
20 BezPoint3 = 2,
21 Scalar = 3,
22 BezScalar = 4,
23 Scale = 5,
24 BezScale = 6,
25 Quat = 7,
26 CompressedQuat32 = 8,
27 CompressedQuat64 = 9,
28 MaxKey = 10,
29 Matrix33 = 11,
30 Matrix44 = 12,
31}
32
33impl KeyType {
34 pub fn from_u8(v: u8) -> Result<Self> {
35 match v {
36 0 => Ok(Self::Unknown),
37 1 => Ok(Self::Point3),
38 2 => Ok(Self::BezPoint3),
39 3 => Ok(Self::Scalar),
40 4 => Ok(Self::BezScalar),
41 5 => Ok(Self::Scale),
42 6 => Ok(Self::BezScale),
43 7 => Ok(Self::Quat),
44 8 => Ok(Self::CompressedQuat32),
45 9 => Ok(Self::CompressedQuat64),
46 10 => Ok(Self::MaxKey),
47 11 => Ok(Self::Matrix33),
48 12 => Ok(Self::Matrix44),
49 _ => bail!("Unknown key type: {}", v),
50 }
51 }
52}
53
54#[derive(Debug, Clone)]
56pub enum KeyFrame {
57 Scalar {
58 frame: u16,
59 value: f32,
60 },
61 BezScalar {
62 frame: u16,
63 in_tan: f32,
64 out_tan: f32,
65 value: f32,
66 },
67 Point3 {
68 frame: u16,
69 value: [f32; 3],
70 },
71 BezPoint3 {
72 frame: u16,
73 in_tan: [f32; 3],
74 out_tan: [f32; 3],
75 value: [f32; 3],
76 },
77 Quat {
78 frame: u16,
79 value: [f32; 4], },
81 CompressedQuat32 {
82 frame: u16,
83 data: u32,
84 },
85 CompressedQuat64 {
86 frame: u16,
87 data: [u32; 2],
88 },
89 Scale {
90 frame: u16,
91 scale: [f32; 3],
92 quat: [f32; 4],
93 },
94 BezScale {
95 frame: u16,
96 in_tan: [f32; 3],
97 out_tan: [f32; 3],
98 scale: [f32; 3],
99 quat: [f32; 4],
100 },
101 Matrix44 {
102 frame: u16,
103 value: [f32; 16],
104 },
105}
106
107impl KeyFrame {
108 pub fn frame(&self) -> u16 {
109 match self {
110 KeyFrame::Scalar { frame, .. }
111 | KeyFrame::BezScalar { frame, .. }
112 | KeyFrame::Point3 { frame, .. }
113 | KeyFrame::BezPoint3 { frame, .. }
114 | KeyFrame::Quat { frame, .. }
115 | KeyFrame::CompressedQuat32 { frame, .. }
116 | KeyFrame::CompressedQuat64 { frame, .. }
117 | KeyFrame::Scale { frame, .. }
118 | KeyFrame::BezScale { frame, .. }
119 | KeyFrame::Matrix44 { frame, .. } => *frame,
120 }
121 }
122}
123
124pub fn read_keys(reader: &mut impl Read, key_type: KeyType, count: u32) -> Result<Vec<KeyFrame>> {
126 let mut keys = Vec::with_capacity(count as usize);
127
128 for _ in 0..count {
129 let frame = reader.read_u16()?;
130 let key = match key_type {
131 KeyType::Scalar => KeyFrame::Scalar {
132 frame,
133 value: reader.read_f32()?,
134 },
135 KeyType::BezScalar => KeyFrame::BezScalar {
136 frame,
137 in_tan: reader.read_f32()?,
138 out_tan: reader.read_f32()?,
139 value: reader.read_f32()?,
140 },
141 KeyType::Point3 => KeyFrame::Point3 {
142 frame,
143 value: [
144 reader.read_f32()?,
145 reader.read_f32()?,
146 reader.read_f32()?,
147 ],
148 },
149 KeyType::BezPoint3 => KeyFrame::BezPoint3 {
150 frame,
151 in_tan: [
152 reader.read_f32()?,
153 reader.read_f32()?,
154 reader.read_f32()?,
155 ],
156 out_tan: [
157 reader.read_f32()?,
158 reader.read_f32()?,
159 reader.read_f32()?,
160 ],
161 value: [
162 reader.read_f32()?,
163 reader.read_f32()?,
164 reader.read_f32()?,
165 ],
166 },
167 KeyType::Quat => KeyFrame::Quat {
168 frame,
169 value: [
170 reader.read_f32()?,
171 reader.read_f32()?,
172 reader.read_f32()?,
173 reader.read_f32()?,
174 ],
175 },
176 KeyType::CompressedQuat32 => KeyFrame::CompressedQuat32 {
177 frame,
178 data: reader.read_u32()?,
179 },
180 KeyType::CompressedQuat64 => KeyFrame::CompressedQuat64 {
181 frame,
182 data: [reader.read_u32()?, reader.read_u32()?],
183 },
184 KeyType::Scale => {
185 let scale = [
186 reader.read_f32()?,
187 reader.read_f32()?,
188 reader.read_f32()?,
189 ];
190 let quat = [
191 reader.read_f32()?,
192 reader.read_f32()?,
193 reader.read_f32()?,
194 reader.read_f32()?,
195 ];
196 KeyFrame::Scale { frame, scale, quat }
197 }
198 KeyType::BezScale => {
199 let in_tan = [
200 reader.read_f32()?,
201 reader.read_f32()?,
202 reader.read_f32()?,
203 ];
204 let out_tan = [
205 reader.read_f32()?,
206 reader.read_f32()?,
207 reader.read_f32()?,
208 ];
209 let scale = [
210 reader.read_f32()?,
211 reader.read_f32()?,
212 reader.read_f32()?,
213 ];
214 let quat = [
215 reader.read_f32()?,
216 reader.read_f32()?,
217 reader.read_f32()?,
218 reader.read_f32()?,
219 ];
220 KeyFrame::BezScale {
221 frame,
222 in_tan,
223 out_tan,
224 scale,
225 quat,
226 }
227 }
228 KeyType::Matrix44 => {
229 let flag = reader.read_u8()?;
231 let value = if flag == 0 {
232 [
233 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0,
234 0.0, 1.0,
235 ]
236 } else {
237 let mut m = [0f32; 16];
238 for val in &mut m {
239 *val = reader.read_f32()?;
240 }
241 m
242 };
243 KeyFrame::Matrix44 { frame, value }
244 }
245 KeyType::MaxKey => {
246 for _ in 0..15 {
250 reader.read_f32()?;
251 }
252 KeyFrame::Scale {
253 frame,
254 scale: [1.0, 1.0, 1.0],
255 quat: [0.0, 0.0, 0.0, 1.0],
256 }
257 }
258 KeyType::Unknown => {
259 bail!("Cannot read unknown key type");
260 }
261 _ => {
262 bail!("Unsupported key type: {:?}", key_type);
263 }
264 };
265 keys.push(key);
266 }
267
268 Ok(keys)
269}
270
271pub fn decompress_quat32(data: u32) -> [f32; 4] {
273 let comp = (data >> 30) as usize;
274 let scale = 0.707107f32 * 2.0 / 1023.0;
275
276 let a = ((data >> 20) & 0x3FF) as f32 * scale - 0.707107;
277 let b = ((data >> 10) & 0x3FF) as f32 * scale - 0.707107;
278 let c = (data & 0x3FF) as f32 * scale - 0.707107;
279 let d = (1.0 - a * a - b * b - c * c).max(0.0).sqrt();
280
281 match comp {
282 0 => [d, a, b, c],
283 1 => [a, d, b, c],
284 2 => [a, b, d, c],
285 _ => [a, b, c, d],
286 }
287}
288
289pub fn decompress_quat64(data: [u32; 2]) -> [f32; 4] {
291 let comp = (data[0] >> 30) as usize;
292 let scale20 = 0.707107f32 * 2.0 / 1048575.0;
293 let scale21 = 0.707107f32 * 2.0 / 2097151.0;
294
295 let a = ((data[0] >> 10) & 0xFFFFF) as f32 * scale20 - 0.707107;
296 let b_hi = (data[0] & 0x3FF) as u32;
297 let b_lo = (data[1] >> 21) as u32;
298 let b = ((b_hi << 11) | b_lo) as f32 * scale21 - 0.707107;
299 let c = (data[1] & 0x1FFFFF) as f32 * scale21 - 0.707107;
300 let d = (1.0 - a * a - b * b - c * c).max(0.0).sqrt();
301
302 match comp {
303 0 => [d, a, b, c],
304 1 => [a, d, b, c],
305 2 => [a, b, d, c],
306 _ => [a, b, c, d],
307 }
308}