1use std::{
4 collections::HashMap,
5 convert::{
6 TryFrom,
7 TryInto,
8 },
9 fmt,
10 io::{
11 Read,
12 Write,
13 },
14 ops::Index,
15};
16
17use byteorder::{
18 ReadBytesExt,
19 WriteBytesExt,
20 LE,
21};
22#[cfg(feature = "serialize")]
23use serde::{
24 Deserialize,
25 Serialize,
26};
27use thiserror::Error;
28
29use crate::{
30 default_palette::DEFAULT_PALETTE,
31 reader::Error as ReadError,
32 writer::Error as WriteError,
33};
34
35#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
38#[cfg_attr(
39 feature = "serialize",
40 derive(Serialize, Deserialize),
41 serde(transparent)
42)]
43pub struct Version(pub u32);
44
45impl Version {
46 pub fn is_supported(&self) -> bool {
48 *self == Self::default()
49 }
50}
51
52impl Default for Version {
53 fn default() -> Self {
54 Self(150)
55 }
56}
57
58impl fmt::Display for Version {
59 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
60 self.0.fmt(f)
61 }
62}
63
64impl Version {
65 pub fn read<R: Read>(mut reader: R) -> Result<Self, ReadError> {
67 Ok(Self(reader.read_u32::<LE>()?))
68 }
69
70 pub fn write<W: Write>(&self, mut writer: W) -> Result<(), WriteError> {
72 writer.write_u32::<LE>(self.0)?;
73 Ok(())
74 }
75}
76
77#[derive(Clone, Debug)]
78#[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))]
79pub struct Model {
88 pub size: Size,
90 pub voxels: Vec<Voxel>,
91}
92
93impl Model {
94 pub fn get_voxel(&self, point: Vector<i8>) -> Option<&Voxel> {
98 self.voxels.iter().find(|voxel| voxel.point == point)
99 }
100}
101
102#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
103#[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))]
104pub struct Voxel {
105 pub point: Point,
106 pub color_index: ColorIndex,
107}
108
109impl Voxel {
110 pub fn new(point: impl Into<Point>, color_index: impl Into<ColorIndex>) -> Self {
121 Self {
122 point: point.into(),
123 color_index: color_index.into(),
124 }
125 }
126
127 pub fn read<R: Read>(mut reader: R) -> Result<Self, ReadError> {
129 Ok(Self {
130 point: Point::read(&mut reader)?,
131 color_index: ColorIndex::read(&mut reader)?,
132 })
133 }
134
135 pub fn write<W: Write>(&self, mut writer: W) -> Result<(), WriteError> {
137 self.point.write(&mut writer)?;
138 self.color_index.write(&mut writer)?;
139 Ok(())
140 }
141}
142
143#[derive(Copy, Clone, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
144#[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))]
145pub struct Vector<T> {
146 pub x: T,
147 pub y: T,
148 pub z: T,
149}
150
151impl<T> Vector<T> {
152 pub fn new(x: T, y: T, z: T) -> Self {
154 Self { x, y, z }
155 }
156}
157
158impl Vector<i8> {
159 pub fn read<R: Read>(mut reader: R) -> Result<Self, ReadError> {
161 Ok(Self {
162 x: reader.read_i8()?,
163 y: reader.read_i8()?,
164 z: reader.read_i8()?,
165 })
166 }
167
168 pub fn write<W: Write>(&self, mut writer: W) -> Result<(), WriteError> {
170 writer.write_i8(self.x)?;
171 writer.write_i8(self.y)?;
172 writer.write_i8(self.z)?;
173 Ok(())
174 }
175}
176
177impl Vector<u32> {
178 pub fn read<R: Read>(mut reader: R) -> Result<Self, ReadError> {
180 Ok(Self {
181 x: reader.read_u32::<LE>()?,
182 y: reader.read_u32::<LE>()?,
183 z: reader.read_u32::<LE>()?,
184 })
185 }
186
187 pub fn write<W: Write>(&self, mut writer: W) -> Result<(), WriteError> {
189 writer.write_u32::<LE>(self.x)?;
190 writer.write_u32::<LE>(self.y)?;
191 writer.write_u32::<LE>(self.z)?;
192 Ok(())
193 }
194}
195
196impl<T> From<[T; 3]> for Vector<T> {
197 fn from(v: [T; 3]) -> Self {
198 let [x, y, z] = v;
199 Self::new(x, y, z)
200 }
201}
202
203impl<T> From<Vector<T>> for [T; 3] {
204 fn from(v: Vector<T>) -> Self {
205 [v.x, v.y, v.z]
206 }
207}
208
209impl<T: fmt::Debug> fmt::Debug for Vector<T> {
210 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
211 write!(f, "({:?}, {:?}, {:?})", self.x, self.y, self.z)
212 }
213}
214
215pub type Point = Vector<i8>;
216pub type Size = Vector<u32>;
217
218#[derive(Clone, Debug)]
224#[cfg_attr(
225 feature = "serialize",
226 derive(Serialize, Deserialize),
227 serde(transparent)
228)]
229pub struct Palette {
230 #[cfg_attr(feature = "serialize", serde(with = "serde_big_array::BigArray"))]
235 pub colors: [Color; 256],
236}
237
238impl Default for Palette {
239 fn default() -> Self {
240 DEFAULT_PALETTE.clone()
241 }
242}
243
244impl Palette {
245 pub fn is_default(&self) -> bool {
247 self.colors == DEFAULT_PALETTE.colors
248 }
249
250 pub fn get(&self, color_index: ColorIndex) -> Color {
253 self.colors[color_index.0 as usize]
254 }
255
256 pub fn iter(&self) -> PaletteIter {
265 PaletteIter {
266 inner: self.colors.iter().enumerate(),
267 }
268 }
269
270 pub fn read<R: Read>(mut reader: R) -> Result<Self, ReadError> {
272 let mut palette = Palette::default();
273
274 for i in 0..255 {
275 palette.colors[i + 1] = Color::read(&mut reader)?;
276 }
277
278 Ok(palette)
279 }
280
281 pub fn write<W: Write>(&self, mut writer: W) -> Result<(), WriteError> {
287 for color in &self.colors[1..] {
288 color.write(&mut writer)?;
289 }
290
291 Ok(())
292 }
293}
294
295#[derive(Debug)]
298pub struct PaletteIter<'a> {
299 inner: std::iter::Enumerate<std::slice::Iter<'a, Color>>,
300}
301
302impl<'a> Iterator for PaletteIter<'a> {
303 type Item = (ColorIndex, Color);
304
305 fn next(&mut self) -> Option<Self::Item> {
306 let (index, color) = self.inner.next()?;
307 Some((ColorIndex(index as u8), *color))
308 }
309}
310
311impl Index<ColorIndex> for Palette {
312 type Output = Color;
313
314 fn index(&self, color_index: ColorIndex) -> &Self::Output {
315 &self.colors[color_index.0 as usize]
316 }
317}
318
319#[derive(Clone, Debug, Default)]
326#[cfg_attr(
327 feature = "serialize",
328 derive(Serialize, Deserialize),
329 serde(transparent)
330)]
331pub struct MaterialPalette {
332 materials: HashMap<ColorIndex, Material>,
334}
335
336impl MaterialPalette {
337 pub fn is_empty(&self) -> bool {
339 self.materials.is_empty()
340 }
341
342 pub fn get(&self, material_id: ColorIndex) -> Option<&Material> {
346 self.materials.get(&material_id)
347 }
348
349 pub fn iter(&self) -> MaterialPaletteIter {
363 MaterialPaletteIter {
364 inner: self.materials.iter(),
365 }
366 }
367}
368
369#[derive(Debug)]
372pub struct MaterialPaletteIter<'a> {
373 inner: std::collections::hash_map::Iter<'a, ColorIndex, Material>,
374}
375
376impl<'a> Iterator for MaterialPaletteIter<'a> {
377 type Item = (ColorIndex, &'a Material);
378
379 fn next(&mut self) -> Option<Self::Item> {
380 let (index, material) = self.inner.next()?;
381 Some((*index, material))
382 }
383}
384
385#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
387#[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))]
388pub struct Color {
389 pub r: u8,
391
392 pub g: u8,
394
395 pub b: u8,
397
398 pub a: u8,
400}
401
402impl Color {
403 pub fn new(r: u8, g: u8, b: u8, a: u8) -> Self {
405 Self { r, g, b, a }
406 }
407
408 pub fn read<R: Read>(mut reader: R) -> Result<Self, ReadError> {
410 Ok(Self {
412 r: reader.read_u8()?,
413 g: reader.read_u8()?,
414 b: reader.read_u8()?,
415 a: reader.read_u8()?,
416 })
417 }
418
419 pub fn write<W: Write>(&self, mut writer: W) -> Result<(), WriteError> {
421 writer.write_u8(self.r)?;
423 writer.write_u8(self.g)?;
424 writer.write_u8(self.b)?;
425 writer.write_u8(self.a)?;
426 Ok(())
427 }
428
429 pub fn light_blue() -> Self {
433 Self {
434 r: 153,
435 g: 204,
436 b: 255,
437 a: 255,
438 }
439 }
440}
441
442impl From<Color> for [u8; 4] {
443 fn from(color: Color) -> Self {
444 [color.r, color.g, color.b, color.a]
445 }
446}
447
448impl From<[u8; 4]> for Color {
449 fn from(color: [u8; 4]) -> Self {
450 Self {
451 r: color[0],
452 g: color[1],
453 b: color[2],
454 a: color[3],
455 }
456 }
457}
458
459#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
460#[cfg_attr(
461 feature = "serialize",
462 derive(Serialize, Deserialize),
463 serde(transparent)
464)]
465pub struct ColorIndex(pub u8);
466
467impl ColorIndex {
468 pub fn read<R: Read>(mut reader: R) -> Result<Self, ReadError> {
470 Ok(Self(reader.read_u8()?))
471 }
472
473 pub fn write<W: Write>(&self, mut writer: W) -> Result<(), WriteError> {
475 writer.write_u8(self.0)?;
476 Ok(())
477 }
478
479 pub fn default_index() -> Self {
482 Self(79)
483 }
484}
485
486impl From<u8> for ColorIndex {
487 fn from(x: u8) -> Self {
488 Self(x)
489 }
490}
491
492impl From<ColorIndex> for u8 {
493 fn from(x: ColorIndex) -> Self {
494 x.0
495 }
496}
497
498impl fmt::Display for ColorIndex {
499 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
500 self.0.fmt(f)
501 }
502}
503
504#[derive(Clone, Debug)]
511#[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))]
512pub struct Material {
513 pub ty: MaterialType,
515
516 pub weight: f32,
526
527 pub plastic: Option<f32>,
528 pub roughness: Option<f32>,
529 pub specular: Option<f32>,
530 pub ior: Option<f32>,
531 pub attenuation: Option<f32>,
532 pub power: Option<f32>,
533 pub glow: Option<f32>,
534 pub is_total_power: bool,
535}
536
537impl Material {
538 pub fn read<R: Read>(mut reader: R) -> Result<Self, ReadError> {
540 let ty = MaterialType::read(&mut reader)?;
541 let weight = reader.read_f32::<LE>()?;
542 let flags = reader.read_u32::<LE>()?;
543
544 let plastic = (flags & 1 != 0)
545 .then(|| reader.read_f32::<LE>())
546 .transpose()?;
547 let roughness = (flags & 2 != 0)
548 .then(|| reader.read_f32::<LE>())
549 .transpose()?;
550 let specular = (flags & 4 != 0)
551 .then(|| reader.read_f32::<LE>())
552 .transpose()?;
553 let ior = (flags & 8 != 0)
554 .then(|| reader.read_f32::<LE>())
555 .transpose()?;
556 let attenuation = (flags & 16 != 0)
557 .then(|| reader.read_f32::<LE>())
558 .transpose()?;
559 let power = (flags & 32 != 0)
560 .then(|| reader.read_f32::<LE>())
561 .transpose()?;
562 let glow = (flags & 64 != 0)
563 .then(|| reader.read_f32::<LE>())
564 .transpose()?;
565
566 Ok(Material {
567 ty,
568 weight,
569 plastic,
570 roughness,
571 specular,
572 ior,
573 attenuation,
574 power,
575 glow,
576 is_total_power: (flags & 128 != 0),
577 })
578 }
579}
580
581#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
588#[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))]
589pub enum MaterialType {
590 Diffuse,
591 Metal,
592 Glass,
593 Emissive,
594}
595
596impl TryFrom<u8> for MaterialType {
597 type Error = MaterialTryFromError;
598
599 fn try_from(x: u8) -> Result<Self, Self::Error> {
600 match x {
601 0 => Ok(MaterialType::Diffuse),
602 1 => Ok(MaterialType::Metal),
603 2 => Ok(MaterialType::Glass),
604 3 => Ok(MaterialType::Emissive),
605 x => Err(MaterialTryFromError(x)),
606 }
607 }
608}
609
610impl From<MaterialType> for u8 {
611 fn from(ty: MaterialType) -> Self {
612 match ty {
613 MaterialType::Diffuse => 0,
614 MaterialType::Metal => 1,
615 MaterialType::Glass => 2,
616 MaterialType::Emissive => 3,
617 }
618 }
619}
620
621impl MaterialType {
622 pub fn read<R: Read>(mut reader: R) -> Result<Self, ReadError> {
624 reader
625 .read_u8()?
626 .try_into()
627 .map_err(|e: MaterialTryFromError| ReadError::InvalidMaterial { material_type: e.0 })
628 }
629
630 pub fn write<W: Write>(&self, mut writer: W) -> Result<(), WriteError> {
631 writer.write_u8((*self).into())?;
632 Ok(())
633 }
634}
635
636#[derive(Debug, Error)]
643#[error("Invalid material type: {0}")]
644pub struct MaterialTryFromError(pub u8);
645
646#[derive(Clone, Debug)]
647#[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))]
648pub struct Transform {
649 pub node_id: u32,
650 pub attributes: Attributes,
651 pub child_node_id: u32,
652 pub reserved_id: Option<u32>,
653 pub layer_id: Option<u32>,
654 pub frames: Vec<Attributes>,
655}
656
657impl Transform {
658 pub fn read<R: Read>(mut reader: R) -> Result<Self, ReadError> {
660 let node_id = reader.read_u32::<LE>()?;
661 let attributes = Attributes::read(&mut reader)?;
662 let child_node_id = reader.read_u32::<LE>()?;
663 let reserved_id = read_id_opt(&mut reader)?;
664 let layer_id = read_id_opt(&mut reader)?;
665
666 let num_frames = reader.read_u32::<LE>()?;
667 let mut frames = vec![];
668 for _ in 0..num_frames {
669 frames.push(Attributes::read(&mut reader)?);
670 }
671
672 Ok(Self {
673 node_id,
674 attributes,
675 child_node_id,
676 reserved_id,
677 layer_id,
678 frames,
679 })
680 }
681
682 pub fn get_transform(&self, frame: usize) -> Option<Vector<i32>> {
683 let mut parts = self.frames.get(frame)?.get("_t")?.split_whitespace();
684 let x = parts.next()?.parse().ok()?;
685 let y = parts.next()?.parse().ok()?;
686 let z = parts.next()?.parse().ok()?;
687
688 parts.next().is_none().then(|| Vector::new(x, y, z))
689 }
690}
691
692#[derive(Clone, Debug)]
699#[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))]
700pub struct Group {
701 pub node_id: u32,
702 pub attributes: Attributes,
703 pub children: Vec<u32>,
704}
705
706impl Group {
707 pub fn read<R: Read>(mut reader: R) -> Result<Self, ReadError> {
709 let node_id = reader.read_u32::<LE>()?;
710 let attributes = Attributes::read(&mut reader)?;
711 let num_children = reader.read_u32::<LE>()?;
712 let mut children = Vec::with_capacity(num_children as usize);
713
714 for _ in 0..num_children {
715 children.push(reader.read_u32::<LE>()?);
716 }
717
718 Ok(Self {
719 node_id,
720 attributes,
721 children,
722 })
723 }
724}
725
726#[derive(Clone, Debug)]
733#[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))]
734pub struct Shape {
735 pub node_id: u32,
736 pub attributes: Attributes,
737}
738
739impl Shape {
740 pub fn read<R: Read>(mut reader: R) -> Result<Self, ReadError> {
742 Ok(Self {
743 node_id: reader.read_u32::<LE>()?,
744 attributes: Attributes::read(reader)?,
745 })
746 }
747}
748
749#[derive(Clone, Debug)]
756#[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))]
757pub struct Layer {
758 pub node_id: u32,
759 pub attributes: Attributes,
760 pub reserved_id: Option<u32>,
761}
762
763impl Layer {
764 pub fn read<R: Read>(mut reader: R) -> Result<Self, ReadError> {
766 Ok(Self {
767 node_id: reader.read_u32::<LE>()?,
768 attributes: Attributes::read(&mut reader)?,
769 reserved_id: read_id_opt(reader)?,
770 })
771 }
772}
773
774#[derive(Clone, Debug, Default)]
777#[cfg_attr(
778 feature = "serialize",
779 derive(Serialize, Deserialize),
780 serde(transparent)
781)]
782pub struct Attributes {
783 inner: HashMap<String, String>,
784}
785
786impl Attributes {
787 pub fn read<R: Read>(mut reader: R) -> Result<Self, ReadError> {
789 let mut inner = HashMap::new();
793 let num_items = reader.read_u32::<LE>()?;
794 log::trace!("Attributes::read: num_items={}", num_items);
795 for _ in 0..num_items {
796 let key = Self::read_string(&mut reader)?;
797 let value = Self::read_string(&mut reader)?;
798 log::trace!("Attributes::read: key={}, value={}", key, value);
799 inner.insert(key, value);
800 }
801
802 Ok(Attributes { inner })
803 }
804
805 fn read_string<R: Read>(mut reader: R) -> Result<String, ReadError> {
806 let len = reader.read_u32::<LE>()?;
807 log::trace!("Attributes::read_string: len={}", len);
808 let mut buf = vec![0; len.try_into().expect("int overflow")];
809 reader.read_exact(&mut buf)?;
810 log::trace!("Attributes::read_string: buf={:?}", buf);
811 Ok(String::from_utf8(buf)?)
812 }
813
814 pub fn get(&self, key: impl AsRef<str>) -> Option<&str> {
817 Some(self.inner.get(key.as_ref())?.as_str())
818 }
819
820 pub fn iter(&self) -> AttributesIter {
823 AttributesIter {
824 inner: self.inner.iter(),
825 }
826 }
827}
828
829#[derive(Debug)]
831pub struct AttributesIter<'a> {
832 inner: std::collections::hash_map::Iter<'a, String, String>,
833}
834
835impl<'a> Iterator for AttributesIter<'a> {
836 type Item = (&'a str, &'a str);
837
838 fn next(&mut self) -> Option<Self::Item> {
839 let (key, value) = self.inner.next()?;
840 Some((key.as_ref(), value.as_ref()))
841 }
842}
843
844fn read_id_opt<R: Read>(mut reader: R) -> Result<Option<u32>, ReadError> {
845 Ok(reader.read_i32::<LE>()?.try_into().ok())
846}