meshopt_rs/lib.rs
1//! meshopt-rs
2//!
3//! # Features
4//!
5//! * `experimental`: Enables experimental APIs which have unstable interface and might have implementation that's not fully tested or optimized
6
7#[cfg(feature = "experimental")]
8pub mod cluster;
9pub mod index;
10pub mod overdraw;
11pub mod quantize;
12#[cfg(feature = "experimental")]
13pub mod simplify;
14#[cfg(feature = "experimental")]
15pub mod spatial_order;
16pub mod stripify;
17pub mod util;
18pub mod vertex;
19
20use std::ops::Range;
21
22pub const INVALID_INDEX: u32 = u32::MAX;
23
24/// A stream of value groups which are meant to be used together (e.g. 3 floats representing a vertex position).
25pub struct Stream<'a> {
26 data: &'a [u8],
27 stride: usize,
28 subset: Range<usize>,
29}
30
31impl<'a> Stream<'a> {
32 /// Creates a stream from a slice.
33 ///
34 /// # Example
35 ///
36 /// ```
37 /// use meshopt_rs::Stream;
38 ///
39 /// let positions = vec![[1.0, 2.0, 3.0], [2.0, 3.0, 4.0], [5.0, 6.0, 7.0]];
40 /// let stream = Stream::from_slice(&positions);
41 ///
42 /// assert_eq!(stream.len(), positions.len());
43 /// ```
44 pub fn from_slice<T>(slice: &'a [T]) -> Self {
45 let value_size = std::mem::size_of::<T>();
46
47 let data = util::as_bytes(slice);
48
49 Self::from_bytes(data, value_size, 0..value_size)
50 }
51
52 /// Creates a stream from a slice with the given byte subset.
53 ///
54 /// # Arguments
55 ///
56 /// * `subset`: subset of data to use inside a `T`
57 ///
58 /// # Example
59 ///
60 /// ```
61 /// use meshopt_rs::Stream;
62 ///
63 /// #[derive(Clone, Default)]
64 /// #[repr(C)]
65 /// struct Vertex {
66 /// position: [f32; 3],
67 /// normal: [f32; 3],
68 /// uv: [f32; 2],
69 /// }
70 ///
71 /// let normals_offset = std::mem::size_of::<f32>() * 3;
72 /// let normals_size = std::mem::size_of::<f32>() * 3;
73 ///
74 /// let vertices = vec![Vertex::default(); 1];
75 /// let normal_stream = Stream::from_slice_with_subset(&vertices, normals_offset..normals_offset+normals_size);
76 ///
77 /// assert_eq!(normal_stream.len(), 1);
78 /// ```
79 pub fn from_slice_with_subset<T>(slice: &'a [T], subset: Range<usize>) -> Self {
80 let value_size = std::mem::size_of::<T>();
81
82 let data = util::as_bytes(slice);
83
84 Self::from_bytes(data, value_size, subset)
85 }
86
87 /// Creates a stream from raw bytes.
88 ///
89 /// # Arguments
90 ///
91 /// * `stride`: stride between value groups
92 /// * `subset`: subset of data to use inside a value group
93 pub fn from_bytes<T>(slice: &'a [T], stride: usize, subset: Range<usize>) -> Self {
94 assert!(subset.end <= stride);
95
96 let value_size = std::mem::size_of::<T>();
97
98 let stride = stride * value_size;
99 let subset = subset.start * value_size..subset.end * value_size;
100
101 let data = util::as_bytes(slice);
102
103 Self { data, stride, subset }
104 }
105
106 fn get(&self, index: usize) -> &'a [u8] {
107 let i = index * self.stride;
108 &self.data[i + self.subset.start..i + self.subset.end]
109 }
110
111 /// Returns length of the stream in value groups.
112 pub fn len(&self) -> usize {
113 self.data.len() / self.stride
114 }
115}
116
117#[derive(Clone, Copy, Default)]
118struct Vector3 {
119 x: f32,
120 y: f32,
121 z: f32,
122}
123
124impl Vector3 {
125 pub fn new(x: f32, y: f32, z: f32) -> Vector3 {
126 Self { x, y, z }
127 }
128
129 #[cfg(feature = "experimental")]
130 pub fn normalize(&mut self) -> f32 {
131 let length = (self.x * self.x + self.y * self.y + self.z * self.z).sqrt();
132
133 if length > 0.0 {
134 self.x /= length;
135 self.y /= length;
136 self.z /= length;
137 }
138
139 length
140 }
141}