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}