Skip to main content

russimp_ng/
lib.rs

1#![crate_name = "russimp_ng"]
2#![crate_type = "lib"]
3
4pub extern crate russimp_sys_ng as sys;
5
6#[cfg(feature = "mint")]
7mod impl_mint;
8#[cfg(feature = "mint")]
9pub use impl_mint::*;
10
11use derivative::Derivative;
12use std::{
13    error::Error,
14    ffi::IntoStringError,
15    fmt,
16    fmt::{Display, Formatter},
17    str::Utf8Error,
18};
19use sys::{aiAABB, aiColor3D, aiColor4D, aiMatrix4x4, aiVector2D, aiVector3D};
20
21#[macro_use]
22extern crate num_derive;
23
24pub mod animation;
25pub mod bone;
26pub mod camera;
27pub mod face;
28pub mod fs;
29pub mod light;
30pub mod material;
31pub mod mesh;
32pub mod metadata;
33pub mod node;
34pub mod property;
35pub mod scene;
36
37#[derive(Derivative)]
38#[derivative(Debug)]
39pub enum RussimpError {
40    Import(String),
41    MetadataError(String),
42    MeterialError(String),
43    Primitive(String),
44    TextureNotFound,
45}
46
47impl Display for RussimpError {
48    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
49        match self {
50            RussimpError::Import(content) => {
51                write!(f, "{}", content)
52            }
53            _ => {
54                write!(f, "unknown error")
55            }
56        }
57    }
58}
59
60#[derive(Clone, Copy, Default, Derivative)]
61#[derivative(Debug)]
62#[repr(C)]
63pub struct AABB {
64    pub min: Vector3D,
65    pub max: Vector3D,
66}
67
68impl From<&aiAABB> for AABB {
69    fn from(aabb: &aiAABB) -> Self {
70        Self {
71            max: (&aabb.mMax).into(),
72            min: (&aabb.mMin).into(),
73        }
74    }
75}
76
77#[derive(Clone, Copy, Default, Derivative)]
78#[derivative(Debug)]
79#[repr(C)]
80pub struct Color4D {
81    pub r: f32,
82    pub g: f32,
83    pub b: f32,
84    pub a: f32,
85}
86
87impl From<&aiColor4D> for Color4D {
88    fn from(color: &aiColor4D) -> Self {
89        Self {
90            r: color.r,
91            g: color.g,
92            b: color.b,
93            a: color.a,
94        }
95    }
96}
97
98#[derive(Clone, Copy, Default, Derivative)]
99#[derivative(Debug)]
100#[repr(C)]
101pub struct Color3D {
102    pub r: f32,
103    pub g: f32,
104    pub b: f32,
105}
106
107impl From<&aiColor3D> for Color3D {
108    fn from(color: &aiColor3D) -> Self {
109        Self {
110            r: color.r,
111            g: color.g,
112            b: color.b,
113        }
114    }
115}
116#[derive(Clone, Copy, Default, Derivative)]
117#[derivative(Debug)]
118#[repr(C)]
119pub struct Matrix4x4 {
120    pub a1: f32,
121    pub a2: f32,
122    pub a3: f32,
123    pub a4: f32,
124    pub b1: f32,
125    pub b2: f32,
126    pub b3: f32,
127    pub b4: f32,
128    pub c1: f32,
129    pub c2: f32,
130    pub c3: f32,
131    pub c4: f32,
132    pub d1: f32,
133    pub d2: f32,
134    pub d3: f32,
135    pub d4: f32,
136}
137
138impl From<&aiMatrix4x4> for Matrix4x4 {
139    fn from(matrix: &aiMatrix4x4) -> Self {
140        Self {
141            a1: matrix.a1,
142            a2: matrix.a2,
143            a3: matrix.a3,
144            a4: matrix.a4,
145            b1: matrix.b1,
146            b2: matrix.b2,
147            b3: matrix.b3,
148            b4: matrix.b4,
149            c1: matrix.c1,
150            c2: matrix.c2,
151            c3: matrix.c3,
152            c4: matrix.c4,
153            d1: matrix.d1,
154            d2: matrix.d2,
155            d3: matrix.d3,
156            d4: matrix.d4,
157        }
158    }
159}
160
161#[derive(Clone, Copy, Default, Derivative)]
162#[derivative(Debug)]
163#[repr(C)]
164pub struct Vector2D {
165    pub x: f32,
166    pub y: f32,
167}
168
169impl From<&aiVector2D> for Vector2D {
170    fn from(color: &aiVector2D) -> Self {
171        Self {
172            x: color.x,
173            y: color.y,
174        }
175    }
176}
177
178impl Error for RussimpError {}
179
180#[derive(Clone, Copy, Default, Derivative, PartialEq)]
181#[derivative(Debug)]
182#[repr(C)]
183pub struct Vector3D {
184    pub x: f32,
185    pub y: f32,
186    pub z: f32,
187}
188
189impl From<&aiVector3D> for Vector3D {
190    fn from(vec: &aiVector3D) -> Self {
191        Self {
192            x: vec.x,
193            y: vec.y,
194            z: vec.z,
195        }
196    }
197}
198
199impl From<Utf8Error> for RussimpError {
200    fn from(val: Utf8Error) -> Self {
201        RussimpError::Primitive(val.to_string())
202    }
203}
204
205impl From<IntoStringError> for RussimpError {
206    fn from(val: IntoStringError) -> Self {
207        RussimpError::Primitive(val.to_string())
208    }
209}
210
211pub type Russult<T> = Result<T, RussimpError>;
212
213mod utils {
214    use std::{os::raw::c_uint, ptr::slice_from_raw_parts};
215
216    pub(crate) fn get_base_type_vec_from_raw<'a, TRaw: 'a>(
217        data: *mut *mut TRaw,
218        len: u32,
219    ) -> Vec<&'a TRaw> {
220        let slice = slice_from_raw_parts(data, len as usize);
221        if slice.is_null() {
222            return vec![];
223        }
224
225        let raw = unsafe { slice.as_ref() }.unwrap();
226        raw.iter().map(|x| unsafe { x.as_ref() }.unwrap()).collect()
227    }
228
229    #[allow(dead_code)]
230    pub(crate) fn get_model(relative_path_from_root: &str) -> String {
231        if let Ok(mut github_root) = std::env::var("GITHUB_WORKSPACE") {
232            github_root.push('/');
233            github_root.push_str(relative_path_from_root);
234
235            github_root
236        } else {
237            relative_path_from_root.into()
238        }
239    }
240
241    pub(crate) fn get_raw<'a, TRaw: 'a, TComponent: From<&'a TRaw>>(
242        raw: *mut TRaw,
243    ) -> Option<TComponent> {
244        unsafe { raw.as_ref() }.map(|x| x.into())
245    }
246
247    pub(crate) fn get_vec<'a, TRaw: 'a, TComponent: From<&'a TRaw>>(
248        raw: *mut TRaw,
249        len: c_uint,
250    ) -> Vec<TComponent> {
251        let slice = slice_from_raw_parts(raw as *const TRaw, len as usize);
252        if slice.is_null() {
253            return vec![];
254        }
255
256        let raw = unsafe { slice.as_ref() }.unwrap();
257        raw.iter().map(|x| x.into()).collect()
258    }
259
260    pub(crate) fn get_raw_vec<TRaw>(raw: *mut TRaw, len: c_uint) -> Vec<TRaw>
261    where
262        TRaw: Clone,
263    {
264        let slice = slice_from_raw_parts(raw as *const TRaw, len as usize);
265        if slice.is_null() {
266            return vec![];
267        }
268
269        let raw = unsafe { slice.as_ref() }.unwrap();
270        raw.to_vec()
271    }
272
273    pub(crate) fn get_vec_from_raw<'a, TComponent: From<&'a TRaw>, TRaw: 'a>(
274        raw_source: *mut *mut TRaw,
275        num_raw_items: c_uint,
276    ) -> Vec<TComponent> {
277        let slice = slice_from_raw_parts(raw_source, num_raw_items as usize);
278        if slice.is_null() {
279            return vec![];
280        }
281
282        let raw = unsafe { slice.as_ref() }.unwrap();
283        raw.iter()
284            .map(|x| (unsafe { x.as_ref() }.unwrap()).into())
285            .collect()
286    }
287
288    pub(crate) fn get_vec_of_vecs_from_raw<'a, TRaw: 'a, TComponent: From<&'a TRaw>>(
289        raw: [*mut TRaw; 8usize],
290        len: c_uint,
291    ) -> Vec<Option<Vec<TComponent>>> {
292        raw.iter()
293            .map(|head| unsafe { head.as_mut() }.map(|head| get_vec(head, len)))
294            .collect()
295    }
296}