Skip to content

Commit

Permalink
Adjust API to support wasm
Browse files Browse the repository at this point in the history
  • Loading branch information
Nan committed Mar 13, 2024
1 parent cfa4dcf commit 84ee7a0
Show file tree
Hide file tree
Showing 13 changed files with 130 additions and 39 deletions.
7 changes: 6 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "ozz-animation-rs"
version = "0.8.0"
version = "0.8.1"
authors = ["SlimeYummy <zzzcccnnn@outlook.com>"]
edition = "2021"
rust-version = "1.75"
Expand All @@ -16,13 +16,18 @@ resolver = "2"
[features]
default = ["rkyv"]
rkyv = ["dep:rkyv", "dep:bytecheck", "glam/rkyv", "glam/bytecheck"]
wasm = []
nodejs = ["wasm", "dep:js-sys", "dep:wasm-bindgen"]

[dependencies]
bytecheck = { version = "0.6", optional = true, default-features = false }
glam = { version = "0.25", features = [ "core-simd", "libm" ] }
js-sys = { version = "0.3", optional = true }
rkyv = { version = "0.7.43", optional = true, features = [ "validation" ] }
static_assertions = "1.1"
thiserror = "1.0"
wasm-bindgen = { version = "0.2", optional = true }

[dev-dependencies]
miniz_oxide = "0.7"
wasm-bindgen-test = "0.3"
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ The library supports almost all runtime features supported by C++ version ozz, i
- Two bone IK
- Aim (Look-at) IK
- Multi-threading
- SIMD
- SIMD (SSE2 + NEON)
- WASM

The following functions are not supported yet:
- User channels (developing)
Expand Down Expand Up @@ -91,4 +92,4 @@ Maybe you can run cross-platform deterministic test cases under [./tests](https:

Initially, I tried to implement similar functionality using fixed point numbers. But fixed-point performance is worse, and it is difficult to be compatible with other libraries.

With further research, I found that x64/arm63 platforms now have good support for the IEEE floating point standard. So I reimplemented this library based on f32.
With further research, I found that x64/arm64 platforms now have good support for the IEEE floating point standard. So I reimplemented this library based on f32.
18 changes: 16 additions & 2 deletions src/animation.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
use glam::{Quat, Vec3, Vec4};
use std::io::Read;
use std::mem;
use std::path::Path;
use std::simd::prelude::*;
use std::simd::*;

Expand Down Expand Up @@ -277,7 +276,15 @@ impl Animation {
}

/// Reads an `Animation` from a file path.
pub fn from_path<P: AsRef<Path>>(path: P) -> Result<Animation, OzzError> {
#[cfg(not(feature = "wasm"))]
pub fn from_path<P: AsRef<std::path::Path>>(path: P) -> Result<Animation, OzzError> {
let mut archive = Archive::from_path(path)?;
return Animation::from_archive(&mut archive);
}

/// Reads an `Animation` from a file path.
#[cfg(all(feature = "wasm", feature = "nodejs"))]
pub fn from_path(path: &str) -> Result<Animation, OzzError> {
let mut archive = Archive::from_path(path)?;
return Animation::from_archive(&mut archive);
}
Expand Down Expand Up @@ -336,9 +343,12 @@ impl Animation {

#[cfg(test)]
mod tests {
use wasm_bindgen_test::*;

use super::*;

#[test]
#[wasm_bindgen_test]
fn test_float3_key_decompress() {
let res = Float3Key {
ratio: 0.0,
Expand All @@ -358,6 +368,7 @@ mod tests {
}

#[test]
#[wasm_bindgen_test]
fn test_simd_decompress_float3() {
let k0 = Float3Key {
ratio: 0.0,
Expand Down Expand Up @@ -397,6 +408,7 @@ mod tests {
}

#[test]
#[wasm_bindgen_test]
fn test_quaternion_key_decompress() {
let quat = QuaternionKey {
ratio: 0.0,
Expand Down Expand Up @@ -454,6 +466,7 @@ mod tests {
}

#[test]
#[wasm_bindgen_test]
fn test_simd_decompress_quaternion() {
let quat0 = QuaternionKey {
ratio: 0.0,
Expand Down Expand Up @@ -489,6 +502,7 @@ mod tests {
}

#[test]
#[wasm_bindgen_test]
fn test_read_animation() {
let animation = Animation::from_path("./resource/playback/animation.ozz").unwrap();

Expand Down
47 changes: 15 additions & 32 deletions src/archive.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#[cfg(not(feature = "wasm"))]
use std::fs::File;
use std::io::{Cursor, Read};
#[cfg(not(feature = "wasm"))]
use std::path::Path;
use std::{mem, slice, str};

Expand Down Expand Up @@ -65,40 +67,9 @@ impl<R: Read> Archive<R> {
pub fn version(&self) -> u32 {
return self.version;
}

// /// Reads a vector from the archive.
// /// * `count` - The number of elements to read.
// pub fn read_vec<T: ArchiveRead<T>>(&mut self, count: usize) -> Result<Vec<T>, OzzError> {
// let mut buffer = Vec::with_capacity(count);
// for _ in 0..count {
// buffer.push(self.read()?);
// }
// return Ok(buffer);
// }

// /// Reads a string from the archive.
// /// * `count` - The number of characters to read. If 0, the string is null-terminated.
// pub fn read_string(&mut self, count: usize) -> Result<String, OzzError> {
// if count != 0 {
// let buffer = self.read_vec::<u8>(count)?;
// let text = String::from_utf8(buffer)?;
// return Ok(text);
// } else {
// let mut buffer = Vec::new();
// loop {
// let char = self.read::<u8>()?;
// if char != 0 {
// buffer.push(char);
// } else {
// break;
// }
// }
// let text = String::from_utf8(buffer)?;
// return Ok(text);
// }
// }
}

#[cfg(not(feature = "wasm"))]
impl Archive<File> {
/// Creates an `Archive` from a path.
pub fn from_path<P: AsRef<Path>>(path: P) -> Result<Archive<File>, OzzError> {
Expand All @@ -118,6 +89,15 @@ impl Archive<Cursor<Vec<u8>>> {
let cursor = Cursor::new(buf);
return Archive::new(cursor);
}

/// Creates an `Archive` from a path.
#[cfg(all(feature = "wasm", feature = "nodejs"))]
pub fn from_path(path: &str) -> Result<Archive<Cursor<Vec<u8>>>, OzzError> {
match crate::nodejs::read_file(path) {
Ok(buf) => return Archive::from_vec(buf),
Err(err) => return Err(OzzError::Custom(err.as_string().unwrap_or("".into()).into())),
};
}
}

impl Archive<Cursor<&[u8]>> {
Expand Down Expand Up @@ -192,9 +172,12 @@ impl ArchiveRead<String> for String {

#[cfg(test)]
mod tests {
use wasm_bindgen_test::*;

use super::*;

#[test]
#[wasm_bindgen_test]
fn test_archive_new() {
let archive = Archive::from_path("./resource/playback/animation.ozz").unwrap();
assert_eq!(archive.endian_swap, false);
Expand Down
9 changes: 9 additions & 0 deletions src/blending_job.rs
Original file line number Diff line number Diff line change
Expand Up @@ -497,6 +497,7 @@ mod blending_tests {
use glam::Vec4;
use std::collections::HashMap;
use std::mem;
use wasm_bindgen_test::*;

use super::*;
use crate::base::{ozz_buf, DeterministicState};
Expand All @@ -509,6 +510,7 @@ mod blending_tests {
};

#[test]
#[wasm_bindgen_test]
fn test_validity() {
let skeleton = Rc::new(Skeleton::from_path("./resource/skeleton-blending.ozz").unwrap());
let num_bind_pose = skeleton.joint_rest_poses().len();
Expand Down Expand Up @@ -717,6 +719,7 @@ mod blending_tests {
}

#[test]
#[wasm_bindgen_test]
fn test_empty() {
let mut joint_rest_poses = vec![SoaTransform::default(); 2];
joint_rest_poses[0].translation =
Expand Down Expand Up @@ -763,6 +766,7 @@ mod blending_tests {
}

#[test]
#[wasm_bindgen_test]
fn test_weight() {
let mut input1 = vec![IDENTITY; 2];
input1[0].translation = SoaVec3::new([0.0, 1.0, 2.0, 3.0], [4.0, 5.0, 6.0, 7.0], [8.0, 9.0, 10.0, 11.0]);
Expand Down Expand Up @@ -860,6 +864,7 @@ mod blending_tests {
}

#[test]
#[wasm_bindgen_test]
fn test_joint_weights() {
let mut input1 = vec![IDENTITY; 2];
input1[0].translation = SoaVec3::new([0.0, 1.0, 2.0, 3.0], [4.0, 5.0, 6.0, 7.0], [8.0, 9.0, 10.0, 11.0]);
Expand Down Expand Up @@ -961,6 +966,7 @@ mod blending_tests {
));
}
#[test]
#[wasm_bindgen_test]
fn test_normalize() {
let skeleton = new_skeleton1();

Expand Down Expand Up @@ -1074,6 +1080,7 @@ mod blending_tests {
}

#[test]
#[wasm_bindgen_test]
fn test_threshold() {
let skeleton = new_skeleton1();

Expand Down Expand Up @@ -1170,6 +1177,7 @@ mod blending_tests {
// }

#[test]
#[wasm_bindgen_test]
fn test_additive_weight() {
let skeleton = Rc::new(Skeleton::from_raw(
vec![IDENTITY; 1],
Expand Down Expand Up @@ -1340,6 +1348,7 @@ mod blending_tests {
}

#[test]
#[wasm_bindgen_test]
fn test_additive_joint_weight() {
let skeleton = Rc::new(Skeleton::from_raw(
vec![IDENTITY; 1],
Expand Down
13 changes: 13 additions & 0 deletions src/ik_aim_job.rs
Original file line number Diff line number Diff line change
Expand Up @@ -306,10 +306,12 @@ impl IKAimJob {
mod ik_aim_job_tests {
use core::f32::consts;
use glam::Vec3;
use wasm_bindgen_test::*;

use super::*;

#[test]
#[wasm_bindgen_test]
fn test_validity() {
let mut job = IKAimJob::default();
job.set_forward(Vec3A::new(0.5, 0.0, 0.0));
Expand All @@ -321,6 +323,7 @@ mod ik_aim_job_tests {
}

#[test]
#[wasm_bindgen_test]
fn test_correction() {
let parents = [
Mat4::IDENTITY,
Expand Down Expand Up @@ -393,6 +396,7 @@ mod ik_aim_job_tests {
}

#[test]
#[wasm_bindgen_test]
fn test_forward() {
let mut job = IKAimJob::default();
job.set_joint(Mat4::IDENTITY);
Expand Down Expand Up @@ -424,6 +428,7 @@ mod ik_aim_job_tests {
}

#[test]
#[wasm_bindgen_test]
fn test_up() {
let mut job = IKAimJob::default();
job.set_joint(Mat4::IDENTITY);
Expand Down Expand Up @@ -480,6 +485,7 @@ mod ik_aim_job_tests {
}

#[test]
#[wasm_bindgen_test]
fn test_pole() {
let mut job = IKAimJob::default();
job.set_joint(Mat4::IDENTITY);
Expand Down Expand Up @@ -530,6 +536,7 @@ mod ik_aim_job_tests {
}

#[test]
#[wasm_bindgen_test]
fn test_offset() {
let mut job = IKAimJob::default();
job.set_joint(Mat4::IDENTITY);
Expand Down Expand Up @@ -616,6 +623,7 @@ mod ik_aim_job_tests {
}

#[test]
#[wasm_bindgen_test]
fn test_twist() {
let mut job = IKAimJob::default();
job.set_joint(Mat4::IDENTITY);
Expand Down Expand Up @@ -650,6 +658,7 @@ mod ik_aim_job_tests {
}

#[test]
#[wasm_bindgen_test]
fn test_aligned_target_up() {
let mut job = IKAimJob::default();
job.set_joint(Mat4::IDENTITY);
Expand Down Expand Up @@ -696,6 +705,7 @@ mod ik_aim_job_tests {
}

#[test]
#[wasm_bindgen_test]
fn test_aligned_target_pole() {
let mut job = IKAimJob::default();
job.set_joint(Mat4::IDENTITY);
Expand All @@ -720,6 +730,7 @@ mod ik_aim_job_tests {
}

#[test]
#[wasm_bindgen_test]
fn test_target_too_close() {
let mut job = IKAimJob::default();
job.set_joint(Mat4::IDENTITY);
Expand All @@ -732,6 +743,7 @@ mod ik_aim_job_tests {
}

#[test]
#[wasm_bindgen_test]
fn test_weight() {
let mut job = IKAimJob::default();
job.set_joint(Mat4::IDENTITY);
Expand Down Expand Up @@ -783,6 +795,7 @@ mod ik_aim_job_tests {
}

#[test]
#[wasm_bindgen_test]
fn test_zero_scale() {
let mut job = IKAimJob::default();
job.set_joint(Mat4::ZERO);
Expand Down
Loading

0 comments on commit 84ee7a0

Please sign in to comment.