Skip to content

Commit

Permalink
Merge pull request #43 from 0x00002a/0x2a/feat/improve-matrix-api
Browse files Browse the repository at this point in the history
  • Loading branch information
ian-h-chamberlain authored Feb 18, 2024
2 parents cb2a2a6 + 52f0019 commit a57fdf1
Show file tree
Hide file tree
Showing 9 changed files with 354 additions and 208 deletions.
5 changes: 4 additions & 1 deletion citro3d/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ version = "0.1.0"
edition = "2021"

[dependencies]
glam = { version = "0.24.2", optional = true }
approx = { version = "0.5.1", optional = true }
bitflags = "1.3.2"
bytemuck = { version = "1.10.0", features = ["extern_crate_std"] }
Expand All @@ -17,9 +18,11 @@ document-features = "0.2.7"
libc = "0.2.125"

[features]
default = []
default = ["glam"]
## Enable this feature to use the `approx` crate for comparing vectors and matrices.
approx = ["dep:approx"]
## Enable for glam support in uniforms
glam = ["dep:glam"]

[dev-dependencies]
test-runner = { git = "https://github.com/rust3ds/test-runner.git" }
Expand Down
8 changes: 4 additions & 4 deletions citro3d/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -223,8 +223,8 @@ impl Instance {
/// let mtx = Matrix::identity();
/// instance.bind_vertex_uniform(idx, &mtx);
/// ```
pub fn bind_vertex_uniform(&mut self, index: uniform::Index, uniform: impl Uniform) {
uniform.bind(self, shader::Type::Vertex, index);
pub fn bind_vertex_uniform(&mut self, index: uniform::Index, uniform: impl Into<Uniform>) {
uniform.into().bind(self, shader::Type::Vertex, index);
}

/// Bind a uniform to the given `index` in the geometry shader for the next draw call.
Expand All @@ -241,8 +241,8 @@ impl Instance {
/// let mtx = Matrix::identity();
/// instance.bind_geometry_uniform(idx, &mtx);
/// ```
pub fn bind_geometry_uniform(&mut self, index: uniform::Index, uniform: impl Uniform) {
uniform.bind(self, shader::Type::Geometry, index);
pub fn bind_geometry_uniform(&mut self, index: uniform::Index, uniform: impl Into<Uniform>) {
uniform.into().bind(self, shader::Type::Geometry, index);
}

/// Retrieve the [`TexEnv`] for the given stage, initializing it first if necessary.
Expand Down
42 changes: 41 additions & 1 deletion citro3d/src/math.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,56 @@ mod ops;
mod projection;

pub use fvec::{FVec, FVec3, FVec4};
pub use matrix::{Matrix, Matrix3, Matrix4};
pub use matrix::Matrix4;
pub use projection::{
AspectRatio, ClipPlanes, CoordinateOrientation, Orthographic, Perspective, Projection,
ScreenOrientation, StereoDisplacement,
};

/// A 4-vector of `u8`s.
///
/// # Layout
/// Uses the PICA layout of WZYX
#[doc(alias = "C3D_IVec")]
#[repr(transparent)]
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
pub struct IVec(citro3d_sys::C3D_IVec);

impl IVec {
pub fn new(x: u8, y: u8, z: u8, w: u8) -> Self {
Self(unsafe { citro3d_sys::IVec_Pack(x, y, z, w) })
}
pub fn as_raw(&self) -> &citro3d_sys::C3D_IVec {
&self.0
}
pub fn x(self) -> u8 {
self.0 as u8
}
pub fn y(self) -> u8 {
(self.0 >> 8) as u8
}
pub fn z(self) -> u8 {
(self.0 >> 16) as u8
}
pub fn w(self) -> u8 {
(self.0 >> 24) as u8
}
}

/// A quaternion, internally represented the same way as [`FVec`].
#[doc(alias = "C3D_FQuat")]
pub struct FQuat(citro3d_sys::C3D_FQuat);

#[cfg(test)]
mod tests {
use super::IVec;

#[test]
fn ivec_getters_work() {
let iv = IVec::new(1, 2, 3, 4);
assert_eq!(iv.x(), 1);
assert_eq!(iv.y(), 2);
assert_eq!(iv.z(), 3);
assert_eq!(iv.w(), 4);
}
}
38 changes: 38 additions & 0 deletions citro3d/src/math/fvec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,15 @@
use std::fmt;

/// A vector of `f32`s.
///
/// # Layout
/// Note that this matches the PICA layout so is actually WZYX, this means using it
/// in vertex data as an attribute it will be reversed
///
/// It is guaranteed to have the same layout as [`citro3d_sys::C3D_FVec`] in memory
#[derive(Clone, Copy)]
#[doc(alias = "C3D_FVec")]
#[repr(transparent)]
pub struct FVec<const N: usize>(pub(crate) citro3d_sys::C3D_FVec);

/// A 3-vector of `f32`s.
Expand Down Expand Up @@ -48,6 +55,11 @@ impl FVec4 {
unsafe { self.0.__bindgen_anon_1.w }
}

/// Wrap a raw [`citro3d_sys::C3D_FVec`]
pub fn from_raw(raw: citro3d_sys::C3D_FVec) -> Self {
Self(raw)
}

/// Create a new [`FVec4`] from its components.
///
/// # Example
Expand Down Expand Up @@ -243,6 +255,32 @@ impl FVec3 {
}
}

#[cfg(feature = "glam")]
impl From<glam::Vec4> for FVec4 {
fn from(value: glam::Vec4) -> Self {
Self::new(value.x, value.y, value.z, value.w)
}
}
#[cfg(feature = "glam")]
impl From<glam::Vec3> for FVec3 {
fn from(value: glam::Vec3) -> Self {
Self::new(value.x, value.y, value.z)
}
}
#[cfg(feature = "glam")]
impl From<FVec4> for glam::Vec4 {
fn from(value: FVec4) -> Self {
glam::Vec4::new(value.x(), value.y(), value.z(), value.w())
}
}

#[cfg(feature = "glam")]
impl From<FVec3> for glam::Vec3 {
fn from(value: FVec3) -> Self {
glam::Vec3::new(value.x(), value.y(), value.z())
}
}

#[cfg(test)]
mod tests {
use approx::assert_abs_diff_eq;
Expand Down
Loading

0 comments on commit a57fdf1

Please sign in to comment.