citro3d/
math.rs

1//! Safe wrappers for working with matrix and vector types provided by `citro3d`.
2
3// TODO: bench FFI calls into `inline statics` generated by bindgen, vs
4// reimplementing some of those calls. Many of them are pretty trivial impls
5
6mod fvec;
7mod matrix;
8mod ops;
9mod projection;
10
11pub use fvec::{FVec, FVec3, FVec4};
12pub use matrix::Matrix4;
13pub use projection::{
14    AspectRatio, ClipPlanes, CoordinateOrientation, Orthographic, Perspective, Projection,
15    ScreenOrientation, StereoDisplacement,
16};
17
18/// A 4-vector of `u8`s.
19///
20/// # Layout
21/// Uses the PICA layout of WZYX
22#[doc(alias = "C3D_IVec")]
23#[repr(transparent)]
24#[derive(Clone, Copy, PartialEq, Eq, Debug)]
25pub struct IVec(citro3d_sys::C3D_IVec);
26
27impl IVec {
28    pub fn new(x: u8, y: u8, z: u8, w: u8) -> Self {
29        Self(unsafe { citro3d_sys::IVec_Pack(x, y, z, w) })
30    }
31    pub fn as_raw(&self) -> &citro3d_sys::C3D_IVec {
32        &self.0
33    }
34    pub fn x(self) -> u8 {
35        self.0 as u8
36    }
37    pub fn y(self) -> u8 {
38        (self.0 >> 8) as u8
39    }
40    pub fn z(self) -> u8 {
41        (self.0 >> 16) as u8
42    }
43    pub fn w(self) -> u8 {
44        (self.0 >> 24) as u8
45    }
46}
47
48/// A quaternion, internally represented the same way as [`FVec`].
49#[allow(dead_code)]
50#[doc(alias = "C3D_FQuat")]
51pub struct FQuat(citro3d_sys::C3D_FQuat);
52
53#[cfg(test)]
54mod tests {
55    use super::IVec;
56
57    #[test]
58    fn ivec_getters_work() {
59        let iv = IVec::new(1, 2, 3, 4);
60        assert_eq!(iv.x(), 1);
61        assert_eq!(iv.y(), 2);
62        assert_eq!(iv.z(), 3);
63        assert_eq!(iv.w(), 4);
64    }
65}