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}