1use nom::bytes::complete::take;
2use nom::error::Error;
3use nom::number::complete::le_u32;
4use serde::{Deserialize, Serialize};
5use std::error;
6
7pub type BoneId = u16;
8pub type TransVal = f32;
9
10#[derive(Debug, PartialEq, Serialize, Deserialize)]
11pub struct SkeletonPacket {
12 pub head: Head,
13 pub info: Info,
14 pub skeleton: Skeleton,
15}
16
17#[derive(Debug, PartialEq, Serialize, Deserialize)]
18pub struct Head {
19 pub format: String,
20 pub ver: u8,
21}
22
23#[derive(Debug, PartialEq, Serialize, Deserialize)]
24pub struct Info {
25 pub addr: u64,
26 pub port: u16,
27}
28
29#[derive(Debug, PartialEq, Serialize, Deserialize)]
30pub struct Skeleton {
31 pub bones: Vec<Bone>,
32}
33
34#[derive(Debug, PartialEq, Serialize, Deserialize)]
35pub struct Bone {
36 pub id: BoneId,
37 pub parent: BoneId,
38 pub trans: Transform,
39}
40
41#[derive(Debug, PartialEq, Serialize, Deserialize)]
42pub struct FramePacket {
43 pub head: Head,
44 pub info: Info,
45 pub frame: Frame,
46}
47
48#[derive(Debug, PartialEq, Serialize, Deserialize)]
49pub struct Frame {
50 pub num: u32,
51 pub time: u32,
52 pub bones: Vec<BoneTrans>,
53}
54
55#[derive(Debug, PartialEq, Serialize, Deserialize)]
56pub struct BoneTrans {
57 pub id: BoneId,
58 pub trans: Transform,
59}
60
61#[derive(Debug, PartialEq, Serialize, Deserialize)]
62pub struct Transform {
63 pub rot: Rotation,
64 pub pos: Position,
65}
66
67#[derive(Debug, PartialEq, Serialize, Deserialize)]
68pub struct Rotation {
69 pub x: TransVal,
70 pub y: TransVal,
71 pub z: TransVal,
72 pub w: TransVal,
73}
74
75#[derive(Debug, PartialEq, Serialize, Deserialize)]
76pub struct Position {
77 pub x: TransVal,
78 pub y: TransVal,
79 pub z: TransVal,
80}
81
82#[derive(Debug, PartialEq, Serialize, Deserialize)]
83pub struct Data<'a> {
84 pub len: u32,
85 pub name: String,
86 pub data: &'a [u8],
87 pub rem: &'a [u8],
88}
89
90pub enum SkeletonOrFrame {
91 Skeleton(SkeletonPacket),
92 Frame(FramePacket),
93}
94
95fn parse_value(data: &[u8]) -> Result<Data, Box<dyn error::Error + '_>> {
97 let (data, length) = le_u32::<_, Error<_>>(data)? as (&[u8], u32);
99
100 let (data, name) = take::<_, _, Error<_>>(4usize)(data)?;
102 let name_str = String::from_utf8(name.to_vec())?;
103
104 let (rem, data) = take::<_, _, Error<_>>(length)(data)?;
106
107 Ok(Data {
108 len: length,
109 name: name_str,
110 data,
111 rem,
112 })
113}
114
115fn parse_head(data: &[u8]) -> Result<(u32, Head), Box<dyn error::Error + '_>> {
116 let data = parse_value(data)?;
117 let len = data.len;
118
119 let data = parse_value(data.data)?;
121 let format = String::from_utf8(data.data.to_vec())?;
122
123 let data = parse_value(data.rem)?;
125 let ver = data.data[0];
126
127 Ok((len, Head { format, ver }))
128}
129
130fn parse_info(data: &[u8]) -> Result<(u32, Info), Box<dyn error::Error + '_>> {
131 let data = parse_value(data)?;
132 let len = data.len;
133
134 let data = parse_value(data.data)?;
136 let addr = u64::from_le_bytes(data.data.try_into()?);
137
138 let data = parse_value(data.rem)?;
140 let port = u16::from_le_bytes(data.data.try_into()?);
141
142 Ok((len, Info { addr, port }))
143}
144
145fn parse_skeleton(data: &[u8]) -> Result<(u32, Skeleton), Box<dyn error::Error + '_>> {
146 let data = parse_value(data)?;
148 let len = data.len;
149
150 let (_, bones) = parse_bones(data.data)?;
152
153 Ok((len, Skeleton { bones: *bones }))
154}
155
156fn parse_frame(data: &[u8]) -> Result<(u32, Frame), Box<dyn error::Error + '_>> {
157 let data = parse_value(data)?;
159 let len = data.len;
160
161 let data = parse_value(data.data)?;
163 let num = u32::from_le_bytes(data.data.try_into()?);
164
165 let data = parse_value(data.rem)?;
167 let time = u32::from_le_bytes(data.data.try_into()?);
168
169 let (_, bones) = parse_bone_trans(data.rem)?;
171
172 Ok((
173 len,
174 Frame {
175 num,
176 time,
177 bones: *bones,
178 },
179 ))
180}
181
182fn parse_bone_trans(data: &[u8]) -> Result<(u32, Box<Vec<BoneTrans>>), Box<dyn error::Error + '_>> {
183 let btrs_data = parse_value(data)?;
185 let btrs_len = btrs_data.len;
186
187 let mut bones: Vec<BoneTrans> = Vec::new();
189 let mut read_bytes: u32 = 0;
190 loop {
191 let part = &btrs_data.data[(read_bytes as usize)..];
192
193 let data = parse_value(part)?;
195 let len = data.len;
196
197 let data = parse_value(data.data)?;
199 let id = u16::from_le_bytes(data.data.try_into()?);
200
201 let (_, trans) = parse_trans(data.rem)?;
203
204 bones.push(BoneTrans { id, trans });
205
206 read_bytes += len + 8;
207 if read_bytes == btrs_len {
208 break;
209 }
210 }
211
212 Ok((btrs_len, Box::new(bones)))
213}
214
215fn parse_bones(data: &[u8]) -> Result<(u32, Box<Vec<Bone>>), Box<dyn error::Error + '_>> {
216 let bons_data = parse_value(data)?;
218 let bons_len = bons_data.len;
219
220 let mut bones: Vec<Bone> = Vec::new();
222 let mut read_bytes: u32 = 0;
223 loop {
224 let part = &bons_data.data[(read_bytes as usize)..];
225
226 let data = parse_value(part)?;
228 let len = data.len;
229
230 let data = parse_value(data.data)?;
232 let id = u16::from_le_bytes(data.data.try_into()?);
233
234 let data = parse_value(data.rem)?;
236 let parent = u16::from_le_bytes(data.data.try_into()?);
237
238 let (_, trans) = parse_trans(part)?;
240
241 bones.push(Bone { id, parent, trans });
242
243 read_bytes += len + 8;
244 if read_bytes == bons_len {
245 break;
246 }
247 }
248
249 Ok((bons_len, Box::new(bones)))
250}
251
252fn parse_trans(data: &[u8]) -> Result<(u32, Transform), Box<dyn error::Error + '_>> {
253 let data = parse_value(data)?;
255
256 let mut values = [0.0; 7];
258 for (i, v) in values.iter_mut().enumerate() {
259 let b = &data.data[i * 4..(i * 4 + 4)];
260 *v = f32::from_le_bytes(b.try_into()?);
261 }
262
263 Ok((
264 data.len,
265 Transform {
266 rot: Rotation {
267 x: values[0],
268 y: values[1],
269 z: values[2],
270 w: values[3],
271 },
272 pos: Position {
273 x: values[4],
274 y: values[5],
275 z: values[6],
276 },
277 },
278 ))
279}
280
281pub fn parse(data: &mut [u8]) -> Result<SkeletonOrFrame, Box<dyn error::Error + '_>> {
302 let (len, head) = parse_head(data)?;
303 let mut remain = &data[((len + 8) as usize)..];
304
305 let (len, info) = parse_info(remain)?;
306 remain = &remain[((len + 8) as usize)..];
307
308 let name = parse_value(data)?.name;
309
310 if name == "skdf" {
311 let (_, skeleton) = parse_skeleton(remain)?;
312 Ok(SkeletonOrFrame::Skeleton(SkeletonPacket {
313 head,
314 info,
315 skeleton,
316 }))
317 } else {
318 let (_, frame) = parse_frame(remain)?;
319 Ok(SkeletonOrFrame::Frame(FramePacket { head, info, frame }))
320 }
321}
322
323#[cfg(test)]
324mod tests {
325 use super::*;
326
327 #[test]
328 fn test_parse_value() {
329 let raw = [
330 0x04, 0x00, 0x00, 0x00,
331 0x62, 0x6e, 0x64, 0x74,
332 0x02, 0x00, 0x00, 0x00,
333 0x01, 0x00, 0x00, 0x00
334 ];
335
336 let data = parse_value(&raw).unwrap();
337
338 assert_eq!(data.len, 4);
339 assert_eq!(data.name, "bndt");
340 assert_eq!(data.data, [0x02, 0x00, 0x00, 0x00]);
341 assert_eq!(data.rem, [0x01, 0x00, 0x00, 0x00]);
342 }
343
344 #[test]
345 fn test_parse_trans() {
346 let raw = [
347 0x1c, 0x00, 0x00, 0x00,
348
349 0x74, 0x72, 0x61, 0x6e,
350
351 0x00, 0x00, 0x9c, 0xa2,
352 0x00, 0xc0, 0xfe, 0xa4,
353 0x00, 0x00, 0xd0, 0xa3,
354 0x00, 0x00, 0x80, 0x3f,
355
356 0x17, 0x56, 0x03, 0xbc,
357 0x7c, 0x48, 0xd0, 0xbd,
358 0x0c, 0xa8, 0x03, 0x3e,
359 ];
360
361 let (len, data) = parse_trans(&raw).unwrap();
362
363 assert_eq!(len, 28);
364
365 assert_eq!(data.rot.x, -4.22838847e-18);
366 assert_eq!(data.rot.y, -1.104802e-16);
367 assert_eq!(data.rot.z, -2.25514052e-17);
368 assert_eq!(data.rot.w, 1.0);
369
370 assert_eq!(data.pos.x, -0.008016131);
371 assert_eq!(data.pos.y, -0.101700753);
372 assert_eq!(data.pos.z, 0.128570735);
373 }
374}