Skip to content

Commit

Permalink
add rust wasm vec exports
Browse files Browse the repository at this point in the history
  • Loading branch information
andykswong committed Mar 11, 2024
1 parent dd7bbf5 commit 97e5818
Show file tree
Hide file tree
Showing 15 changed files with 356 additions and 76 deletions.
2 changes: 2 additions & 0 deletions .cargo/config.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[target.wasm32-unknown-unknown]
rustflags = ["-C", "link-args=-z stack-size=65536"]
5 changes: 3 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,14 @@ jsmath = []

[dependencies]
num = { version = "0.4", default-features = false }
paste = { version = "1.0" }
serde = { version = "1.0", optional = true, default-features = false, features = ["derive"] }

[dev-dependencies]
serde_json = "1.0"

[target.'cfg(target_family = "wasm")'.lib]
crate-type = ["cdylib"]
[lib]
crate-type = ["cdylib", "rlib"]

[profile.release]
lto = true
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ Features:
- `libm` - enables trigonometry related functions in `no_std` environment using `libm`.
- `jsmath` - enables trigonometry related functions in `no_std` WebAssembly environment using JS Math binding.
- `serde` - enables `serde` serialize/deserialize implementations
- `wasm` - (WIP) enables WebAssembly export bindings
- `wasm` - (WIP) produces standalone WebAssembly component

---

Expand Down
17 changes: 14 additions & 3 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
"scripts": {
"prepublishOnly": "npm run build && npm test && npm run docs",
"clean": "rimraf coverage/ docs/ dist/ target/ **/__tests__/**/*.spec.map **/__tests__/**/*.spec.wat",
"build:rust": "cargo build --release --target wasm32-unknown-unknown --features jsmath,wasm --no-default-features",
"postbuild:rust": "wasm-opt -Oz -o dist/munum.wasm target/wasm32-unknown-unknown/release/munum.wasm",
"prebuild": "npm run lint",
"build": "npm run tsc",
"lint": "eslint assembly --ext .ts,.tsx",
Expand Down Expand Up @@ -69,6 +71,7 @@
"assemblyscript": "^0.27",
"babel-jest": "^29.5",
"babel-plugin-add-import-extension": "^1.6",
"binaryen": "^116.0",
"copyfiles": "^2.4",
"cross-env": "^7.0",
"eslint": "^8.50",
Expand Down
8 changes: 4 additions & 4 deletions src/float.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
//! Float type helpers.
use crate::{Matrix, Quaternion};
use num::traits::{float::FloatCore, NumAssign, NumCast};
use num::{traits::{float::FloatCore, NumAssign, NumCast}, Zero};

/// Standard tolerance epsilon
pub const EPSILON: f32 = 128. * f32::EPSILON;

/// Returns a standard tolerance epsilon
pub fn epsilon<T: NumCast>() -> T {
NumCast::from(EPSILON).expect("incompatible type")
pub fn epsilon<T: NumCast + Zero>() -> T {
NumCast::from(EPSILON).unwrap_or(T::zero())
}

/// Trait for float operations
Expand All @@ -29,7 +29,7 @@ pub trait FloatOps: Copy {
fn tan(self) -> Self;
}

#[cfg(any(feature = "std", feature = "libm"))]
#[cfg(all(any(feature = "std", feature = "libm"), not(feature = "jsmath")))]
impl<T: num::traits::Float> FloatOps for T {
#[inline]
fn acos(self) -> T {
Expand Down
6 changes: 6 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,9 @@ pub use quat::{quat, Quaternion};

#[cfg(target_arch = "wasm32")]
mod wasm;

#[cfg(all(target_arch = "wasm32", feature = "wasm", not(test)))]
#[panic_handler]
fn panic(_panic: &core::panic::PanicInfo<'_>) -> ! {
core::arch::wasm32::unreachable()
}
4 changes: 2 additions & 2 deletions src/matrix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ impl<T: Copy + NumAssign, const R: usize, const C: usize> Index<(usize, usize)>
/// Indexing into the `Matrix` by (row, column).
#[inline]
fn index(&self, (row, col): (usize, usize)) -> &Self::Output {
&self.0[col][row]
&self.0[col % C][row % R]
}
}

Expand All @@ -146,7 +146,7 @@ impl<T: Copy + NumAssign, const R: usize, const C: usize> IndexMut<(usize, usize
/// Mutably indexing into the `Matrix` by (row, column).
#[inline]
fn index_mut(&mut self, (row, col): (usize, usize)) -> &mut Self::Output {
&mut self.0[col][row]
&mut self.0[col % C][row % R]
}
}

Expand Down
58 changes: 58 additions & 0 deletions src/matrix_special.rs
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,64 @@ impl<T: Copy + NumAssign, const R: usize> From<Vector<T, R>> for [T; R] {
}
}

impl<T: Copy + NumAssign> From<Vec2<T>> for Vec3<T> {
/// Augments a `Vec2` into a `Vec3`
/// The resulting `Vec3` contains the given `Vec2` with z = 1.
///
/// # Examples
/// ```
/// # use munum::{Vec2, Vec3};
/// let v = Vec3::from(Vec2::<i32>::from_slice(&[2, 3]));
/// assert_eq!(*v.as_ref(), [2, 3, 1]);
/// ```
fn from(v: Vec2<T>) -> Self {
Vec3::new([[v[0], v[1], T::one()]])
}
}

impl<T: Copy + NumAssign> From<Vec3<T>> for Vec2<T> {
/// Creates a `Vec2` from the (x, y) of a `Vec3`
///
/// # Examples
/// ```
/// # use munum::{Vec2, Vec3};
/// let v = Vec2::from(Vec3::<i32>::from_slice(&[2, 3, 4]));
/// assert_eq!(*v.as_ref(), [2, 3]);
/// ```
fn from(v: Vec3<T>) -> Self {
Vec2::new([[v[0], v[1]]])
}
}

impl<T: Copy + NumAssign> From<Vec3<T>> for Vec4<T> {
/// Augments a `Vec3` into a `Vec4`
/// The resulting `Vec4` contains the given `Vec3` with w = 1.
///
/// # Examples
/// ```
/// # use munum::{Vec3, Vec4};
/// let v = Vec4::from(Vec3::<i32>::from_slice(&[2, 3, 4]));
/// assert_eq!(*v.as_ref(), [2, 3, 4, 1]);
/// ```
fn from(v: Vec3<T>) -> Self {
Vec4::new([[v[0], v[1], v[2], T::one()]])
}
}

impl<T: Copy + NumAssign> From<Vec4<T>> for Vec3<T> {
/// Creates a `Vec3` from the (x, y, z) of a `Vec4`
///
/// # Examples
/// ```
/// # use munum::{Vec3, Vec4};
/// let v = Vec3::from(Vec4::<i32>::from_slice(&[2, 3, 4, 1]));
/// assert_eq!(*v.as_ref(), [2, 3, 4]);
/// ```
fn from(v: Vec4<T>) -> Self {
Vec3::new([[v[0], v[1], v[2]]])
}
}

impl<T: Copy + NumAssign> From<Mat2<T>> for Mat3<T> {
/// Augments a `Mat2` into a `Mat3`
/// The resulting `Mat3` contains the given `Mat2` on upper-left with the lower-right element = 1.
Expand Down
Empty file removed src/wasm/bindings.rs
Empty file.
56 changes: 0 additions & 56 deletions src/wasm/float.rs

This file was deleted.

66 changes: 61 additions & 5 deletions src/wasm/jsmath.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,64 @@
use crate::FloatOps;

#[link(wasm_import_module = "jsmath")]
extern "C" {
fn acos(x: f64) -> f64;
fn cos(x: f64) -> f64;
fn sin(x: f64) -> f64;
fn sqrt(x: f64) -> f64;
fn tan(x: f64) -> f64;
pub fn acos(x: f64) -> f64;
pub fn cos(x: f64) -> f64;
pub fn sin(x: f64) -> f64;
pub fn sqrt(x: f64) -> f64;
pub fn tan(x: f64) -> f64;
}

impl FloatOps for f64 {
#[inline]
fn acos(self) -> f64 {
unsafe { acos(self) }
}

#[inline]
fn cos(self) -> f64 {
unsafe { cos(self) }
}

#[inline]
fn sin(self) -> f64 {
unsafe { sin(self) }
}

#[inline]
fn sqrt(self) -> f64 {
unsafe { sqrt(self) }
}

#[inline]
fn tan(self) -> f64 {
unsafe { tan(self) }
}
}

impl FloatOps for f32 {
#[inline]
fn acos(self) -> f32 {
unsafe { acos(self.into()) as f32 }
}

#[inline]
fn cos(self) -> f32 {
unsafe { cos(self.into()) as f32 }
}

#[inline]
fn sin(self) -> f32 {
unsafe { sin(self.into()) as f32 }
}

#[inline]
fn sqrt(self) -> f32 {
unsafe { sqrt(self.into()) as f32 }
}

#[inline]
fn tan(self) -> f32 {
unsafe { tan(self.into()) as f32 }
}
}
6 changes: 3 additions & 3 deletions src/wasm/mod.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
//! WebAssembly bindings.
mod ptr;

#[cfg(feature = "jsmath")]
mod jsmath;
#[cfg(feature = "jsmath")]
mod float;

#[cfg(feature = "wasm")]
mod bindings;
mod vec;
21 changes: 21 additions & 0 deletions src/wasm/ptr.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
use crate::Matrix;
use num::traits::NumAssign;

/// Trait for loading a value from a pointer.
pub trait Load<T> {
/// Loads the value from the pointer.
fn load(&self) -> T;
}

impl<T: Copy + NumAssign, const R: usize, const C: usize> Load<Matrix<T, R, C>>
for *const Matrix<T, R, C>
{
#[inline]
fn load(&self) -> Matrix<T, R, C> {
if let Some(&m) = unsafe { self.as_ref() } {
m
} else {
Matrix::<T, R, C>::default()
}
}
}
Loading

0 comments on commit 97e5818

Please sign in to comment.