bunny_codec/compressed/
view.rs1use bunny_geom::FixedAabb3;
2use bunny_mesh::{QuantizedVertex, Triangle16, Triangle32};
3
4use super::error::CompressedMeshError;
5use super::read::{read_triangle, read_vertex, take_record};
6use super::{TRIANGLE16_STRIDE, TRIANGLE32_STRIDE, VERTEX_STRIDE};
7
8#[derive(Clone, Copy, Debug, PartialEq, Eq)]
10pub enum CompressedIndexWidth {
11 Width16,
13 Width32,
15}
16
17impl CompressedIndexWidth {
18 pub(super) const fn stride(self) -> usize {
19 match self {
20 Self::Width16 => TRIANGLE16_STRIDE,
21 Self::Width32 => TRIANGLE32_STRIDE,
22 }
23 }
24}
25
26#[derive(Clone, Copy, Debug, PartialEq, Eq)]
28pub enum CompressedTriangle {
29 Width16(Triangle16),
31 Width32(Triangle32),
33}
34
35#[derive(Clone, Copy, Debug, PartialEq, Eq)]
37pub struct CompressedMesh<'a> {
38 bounds: FixedAabb3,
39 vertex_bytes: &'a [u8],
40 triangle_bytes: &'a [u8],
41 vertex_count: usize,
42 triangle_count: usize,
43 index_width: CompressedIndexWidth,
44}
45
46impl<'a> CompressedMesh<'a> {
47 pub(super) const fn new(
48 bounds: FixedAabb3,
49 vertex_bytes: &'a [u8],
50 triangle_bytes: &'a [u8],
51 vertex_count: usize,
52 triangle_count: usize,
53 index_width: CompressedIndexWidth,
54 ) -> Self {
55 Self {
56 bounds,
57 vertex_bytes,
58 triangle_bytes,
59 vertex_count,
60 triangle_count,
61 index_width,
62 }
63 }
64
65 #[must_use]
67 pub const fn bounds(self) -> FixedAabb3 {
68 self.bounds
69 }
70
71 #[must_use]
73 pub const fn vertex_count(self) -> usize {
74 self.vertex_count
75 }
76
77 #[must_use]
79 pub const fn triangle_count(self) -> usize {
80 self.triangle_count
81 }
82
83 #[must_use]
85 pub const fn index_width(self) -> CompressedIndexWidth {
86 self.index_width
87 }
88
89 #[must_use]
91 pub const fn vertex_bytes(self) -> &'a [u8] {
92 self.vertex_bytes
93 }
94
95 #[must_use]
97 pub const fn triangle_bytes(self) -> &'a [u8] {
98 self.triangle_bytes
99 }
100
101 pub fn vertex(self, index: usize) -> Result<QuantizedVertex, CompressedMeshError> {
107 if index >= self.vertex_count {
108 return Err(CompressedMeshError::IndexOutOfBounds);
109 }
110 read_vertex(take_record(self.vertex_bytes, index, VERTEX_STRIDE)?)
111 }
112
113 pub fn triangle(self, index: usize) -> Result<CompressedTriangle, CompressedMeshError> {
119 if index >= self.triangle_count {
120 return Err(CompressedMeshError::IndexOutOfBounds);
121 }
122 let bytes = take_record(self.triangle_bytes, index, self.index_width.stride())?;
123 read_triangle(bytes, self.index_width)
124 }
125}