diff --git a/expected/blend/blend+0.00.rkyv b/expected/blend/blend+0.00.rkyv index 3471dc3..51fb0ac 100644 Binary files a/expected/blend/blend+0.00.rkyv and b/expected/blend/blend+0.00.rkyv differ diff --git a/expected/blend/blend+0.10.rkyv b/expected/blend/blend+0.10.rkyv index de85bf4..5ffa28b 100644 Binary files a/expected/blend/blend+0.10.rkyv and b/expected/blend/blend+0.10.rkyv differ diff --git a/expected/blend/blend+0.20.rkyv b/expected/blend/blend+0.20.rkyv index bb9c453..3c01950 100644 Binary files a/expected/blend/blend+0.20.rkyv and b/expected/blend/blend+0.20.rkyv differ diff --git a/expected/blend/blend+0.30.rkyv b/expected/blend/blend+0.30.rkyv index 370eb89..903c570 100644 Binary files a/expected/blend/blend+0.30.rkyv and b/expected/blend/blend+0.30.rkyv differ diff --git a/expected/blend/blend+0.40.rkyv b/expected/blend/blend+0.40.rkyv index 48ea86c..32b53e4 100644 Binary files a/expected/blend/blend+0.40.rkyv and b/expected/blend/blend+0.40.rkyv differ diff --git a/expected/blend/blend+0.50.rkyv b/expected/blend/blend+0.50.rkyv index fefb407..a61395d 100644 Binary files a/expected/blend/blend+0.50.rkyv and b/expected/blend/blend+0.50.rkyv differ diff --git a/expected/blend/blend+0.60.rkyv b/expected/blend/blend+0.60.rkyv index 295dd8c..cae2573 100644 Binary files a/expected/blend/blend+0.60.rkyv and b/expected/blend/blend+0.60.rkyv differ diff --git a/expected/blend/blend+0.70.rkyv b/expected/blend/blend+0.70.rkyv index d116225..9093720 100644 Binary files a/expected/blend/blend+0.70.rkyv and b/expected/blend/blend+0.70.rkyv differ diff --git a/expected/blend/blend+0.80.rkyv b/expected/blend/blend+0.80.rkyv index 256a1de..9633119 100644 Binary files a/expected/blend/blend+0.80.rkyv and b/expected/blend/blend+0.80.rkyv differ diff --git a/expected/blend/blend+0.90.rkyv b/expected/blend/blend+0.90.rkyv index 238891a..a2abddb 100644 Binary files a/expected/blend/blend+0.90.rkyv and b/expected/blend/blend+0.90.rkyv differ diff --git a/expected/blend/blend+1.00.rkyv b/expected/blend/blend+1.00.rkyv index 3bf7461..f433795 100644 Binary files a/expected/blend/blend+1.00.rkyv and b/expected/blend/blend+1.00.rkyv differ diff --git a/expected/blend/blend+1.10.rkyv b/expected/blend/blend+1.10.rkyv index 84d0c06..eca537f 100644 Binary files a/expected/blend/blend+1.10.rkyv and b/expected/blend/blend+1.10.rkyv differ diff --git a/expected/blend/blend-0.10.rkyv b/expected/blend/blend-0.10.rkyv index ef93af2..ca1acae 100644 Binary files a/expected/blend/blend-0.10.rkyv and b/expected/blend/blend-0.10.rkyv differ diff --git a/expected/blend/blend_cpp.bin b/expected/blend/blend_cpp.bin new file mode 100644 index 0000000..1a61578 Binary files /dev/null and b/expected/blend/blend_cpp.bin differ diff --git a/expected/look_at/look_at_00.rkyv b/expected/look_at/look_at_00.rkyv new file mode 100644 index 0000000..32a3a03 Binary files /dev/null and b/expected/look_at/look_at_00.rkyv differ diff --git a/expected/look_at/look_at_01.rkyv b/expected/look_at/look_at_01.rkyv new file mode 100644 index 0000000..b325ffa Binary files /dev/null and b/expected/look_at/look_at_01.rkyv differ diff --git a/expected/look_at/look_at_02.rkyv b/expected/look_at/look_at_02.rkyv new file mode 100644 index 0000000..52947fb Binary files /dev/null and b/expected/look_at/look_at_02.rkyv differ diff --git a/expected/look_at/look_at_03.rkyv b/expected/look_at/look_at_03.rkyv new file mode 100644 index 0000000..37e4a40 Binary files /dev/null and b/expected/look_at/look_at_03.rkyv differ diff --git a/expected/look_at/look_at_04.rkyv b/expected/look_at/look_at_04.rkyv new file mode 100644 index 0000000..dc94a08 Binary files /dev/null and b/expected/look_at/look_at_04.rkyv differ diff --git a/expected/look_at/look_at_05.rkyv b/expected/look_at/look_at_05.rkyv new file mode 100644 index 0000000..e762484 Binary files /dev/null and b/expected/look_at/look_at_05.rkyv differ diff --git a/expected/look_at/look_at_06.rkyv b/expected/look_at/look_at_06.rkyv new file mode 100644 index 0000000..425f10b Binary files /dev/null and b/expected/look_at/look_at_06.rkyv differ diff --git a/expected/look_at/look_at_07.rkyv b/expected/look_at/look_at_07.rkyv new file mode 100644 index 0000000..88e7eb6 Binary files /dev/null and b/expected/look_at/look_at_07.rkyv differ diff --git a/expected/look_at/look_at_08.rkyv b/expected/look_at/look_at_08.rkyv new file mode 100644 index 0000000..aec9402 Binary files /dev/null and b/expected/look_at/look_at_08.rkyv differ diff --git a/expected/look_at/look_at_09.rkyv b/expected/look_at/look_at_09.rkyv new file mode 100644 index 0000000..4588913 Binary files /dev/null and b/expected/look_at/look_at_09.rkyv differ diff --git a/expected/look_at/look_at_10.rkyv b/expected/look_at/look_at_10.rkyv new file mode 100644 index 0000000..7f30130 Binary files /dev/null and b/expected/look_at/look_at_10.rkyv differ diff --git a/expected/look_at/look_at_cpp.bin b/expected/look_at/look_at_cpp.bin new file mode 100644 index 0000000..cab19c6 Binary files /dev/null and b/expected/look_at/look_at_cpp.bin differ diff --git a/expected/look_at/look_at_ik_00.rkyv b/expected/look_at/look_at_ik_00.rkyv deleted file mode 100644 index d84ae81..0000000 Binary files a/expected/look_at/look_at_ik_00.rkyv and /dev/null differ diff --git a/expected/look_at/look_at_ik_01.rkyv b/expected/look_at/look_at_ik_01.rkyv deleted file mode 100644 index 000cbbf..0000000 Binary files a/expected/look_at/look_at_ik_01.rkyv and /dev/null differ diff --git a/expected/look_at/look_at_ik_02.rkyv b/expected/look_at/look_at_ik_02.rkyv deleted file mode 100644 index 3c0169e..0000000 Binary files a/expected/look_at/look_at_ik_02.rkyv and /dev/null differ diff --git a/expected/look_at/look_at_ik_03.rkyv b/expected/look_at/look_at_ik_03.rkyv deleted file mode 100644 index 8d3a71f..0000000 Binary files a/expected/look_at/look_at_ik_03.rkyv and /dev/null differ diff --git a/expected/look_at/look_at_ik_04.rkyv b/expected/look_at/look_at_ik_04.rkyv deleted file mode 100644 index c39e209..0000000 Binary files a/expected/look_at/look_at_ik_04.rkyv and /dev/null differ diff --git a/expected/look_at/look_at_ik_05.rkyv b/expected/look_at/look_at_ik_05.rkyv deleted file mode 100644 index 94c1dd8..0000000 Binary files a/expected/look_at/look_at_ik_05.rkyv and /dev/null differ diff --git a/expected/look_at/look_at_ik_06.rkyv b/expected/look_at/look_at_ik_06.rkyv deleted file mode 100644 index 50f0606..0000000 Binary files a/expected/look_at/look_at_ik_06.rkyv and /dev/null differ diff --git a/expected/look_at/look_at_ik_07.rkyv b/expected/look_at/look_at_ik_07.rkyv deleted file mode 100644 index f24d06b..0000000 Binary files a/expected/look_at/look_at_ik_07.rkyv and /dev/null differ diff --git a/expected/look_at/look_at_ik_08.rkyv b/expected/look_at/look_at_ik_08.rkyv deleted file mode 100644 index 8284ff8..0000000 Binary files a/expected/look_at/look_at_ik_08.rkyv and /dev/null differ diff --git a/expected/look_at/look_at_ik_09.rkyv b/expected/look_at/look_at_ik_09.rkyv deleted file mode 100644 index 2fe9811..0000000 Binary files a/expected/look_at/look_at_ik_09.rkyv and /dev/null differ diff --git a/expected/look_at/look_at_ik_10.rkyv b/expected/look_at/look_at_ik_10.rkyv deleted file mode 100644 index b9af24a..0000000 Binary files a/expected/look_at/look_at_ik_10.rkyv and /dev/null differ diff --git a/expected/playback/playback+0.00.rkyv b/expected/playback/playback+0.00.rkyv index a9ccc11..67114f5 100644 Binary files a/expected/playback/playback+0.00.rkyv and b/expected/playback/playback+0.00.rkyv differ diff --git a/expected/playback/playback+0.10.rkyv b/expected/playback/playback+0.10.rkyv index 4dfa06d..444e781 100644 Binary files a/expected/playback/playback+0.10.rkyv and b/expected/playback/playback+0.10.rkyv differ diff --git a/expected/playback/playback+0.20.rkyv b/expected/playback/playback+0.20.rkyv index 76613ee..ad372d3 100644 Binary files a/expected/playback/playback+0.20.rkyv and b/expected/playback/playback+0.20.rkyv differ diff --git a/expected/playback/playback+0.30.rkyv b/expected/playback/playback+0.30.rkyv index 5a75a5b..b5479ac 100644 Binary files a/expected/playback/playback+0.30.rkyv and b/expected/playback/playback+0.30.rkyv differ diff --git a/expected/playback/playback+0.40.rkyv b/expected/playback/playback+0.40.rkyv index a4344d9..2acc761 100644 Binary files a/expected/playback/playback+0.40.rkyv and b/expected/playback/playback+0.40.rkyv differ diff --git a/expected/playback/playback+0.50.rkyv b/expected/playback/playback+0.50.rkyv index f2c5529..cb2fdf8 100644 Binary files a/expected/playback/playback+0.50.rkyv and b/expected/playback/playback+0.50.rkyv differ diff --git a/expected/playback/playback+0.60.rkyv b/expected/playback/playback+0.60.rkyv index d5530c4..a5aeae5 100644 Binary files a/expected/playback/playback+0.60.rkyv and b/expected/playback/playback+0.60.rkyv differ diff --git a/expected/playback/playback+0.70.rkyv b/expected/playback/playback+0.70.rkyv index 17b1a95..762b017 100644 Binary files a/expected/playback/playback+0.70.rkyv and b/expected/playback/playback+0.70.rkyv differ diff --git a/expected/playback/playback+0.80.rkyv b/expected/playback/playback+0.80.rkyv index 1ec3570..5d1e1a6 100644 Binary files a/expected/playback/playback+0.80.rkyv and b/expected/playback/playback+0.80.rkyv differ diff --git a/expected/playback/playback+0.90.rkyv b/expected/playback/playback+0.90.rkyv index d867060..4039cbe 100644 Binary files a/expected/playback/playback+0.90.rkyv and b/expected/playback/playback+0.90.rkyv differ diff --git a/expected/playback/playback+1.00.rkyv b/expected/playback/playback+1.00.rkyv index a4bfa2d..bb7152d 100644 Binary files a/expected/playback/playback+1.00.rkyv and b/expected/playback/playback+1.00.rkyv differ diff --git a/expected/playback/playback+1.10.rkyv b/expected/playback/playback+1.10.rkyv index 48fbc20..f784808 100644 Binary files a/expected/playback/playback+1.10.rkyv and b/expected/playback/playback+1.10.rkyv differ diff --git a/expected/playback/playback-0.10.rkyv b/expected/playback/playback-0.10.rkyv index 565d7f3..1970d71 100644 Binary files a/expected/playback/playback-0.10.rkyv and b/expected/playback/playback-0.10.rkyv differ diff --git a/expected/playback/playback_cpp.bin b/expected/playback/playback_cpp.bin new file mode 100644 index 0000000..0cd9a8f Binary files /dev/null and b/expected/playback/playback_cpp.bin differ diff --git a/expected/two_bone_ik/two_bone_ik_00.rkyv b/expected/two_bone_ik/two_bone_ik_00.rkyv index b3034d6..7b6db17 100644 Binary files a/expected/two_bone_ik/two_bone_ik_00.rkyv and b/expected/two_bone_ik/two_bone_ik_00.rkyv differ diff --git a/expected/two_bone_ik/two_bone_ik_01.rkyv b/expected/two_bone_ik/two_bone_ik_01.rkyv index 71f45b8..773ccd2 100644 Binary files a/expected/two_bone_ik/two_bone_ik_01.rkyv and b/expected/two_bone_ik/two_bone_ik_01.rkyv differ diff --git a/expected/two_bone_ik/two_bone_ik_05.rkyv b/expected/two_bone_ik/two_bone_ik_05.rkyv index 3355b88..4391ba8 100644 Binary files a/expected/two_bone_ik/two_bone_ik_05.rkyv and b/expected/two_bone_ik/two_bone_ik_05.rkyv differ diff --git a/expected/two_bone_ik/two_bone_ik_06.rkyv b/expected/two_bone_ik/two_bone_ik_06.rkyv index 2a3d5ae..fcd9b8a 100644 Binary files a/expected/two_bone_ik/two_bone_ik_06.rkyv and b/expected/two_bone_ik/two_bone_ik_06.rkyv differ diff --git a/expected/two_bone_ik/two_bone_ik_07.rkyv b/expected/two_bone_ik/two_bone_ik_07.rkyv index a5a6437..c0528b7 100644 Binary files a/expected/two_bone_ik/two_bone_ik_07.rkyv and b/expected/two_bone_ik/two_bone_ik_07.rkyv differ diff --git a/expected/two_bone_ik/two_bone_ik_cpp.bin b/expected/two_bone_ik/two_bone_ik_cpp.bin new file mode 100644 index 0000000..e2e3cc1 Binary files /dev/null and b/expected/two_bone_ik/two_bone_ik_cpp.bin differ diff --git a/src/animation.rs b/src/animation.rs index 6f60b1a..c0848f4 100644 --- a/src/animation.rs +++ b/src/animation.rs @@ -120,10 +120,10 @@ impl QuaternionKey { k3: &QuaternionKey, soa: &mut SoaQuat, ) { - const INT_2_FLOAT: f32x4 = f32x4::from_array([1.0f32 / (32767.0f32 * core::f32::consts::SQRT_2); 4]); + const INT_2_FLOAT: f32x4 = f32x4::from_array([1.0 / (32767.0 * core::f32::consts::SQRT_2); 4]); - const ONE: f32x4 = f32x4::from_array([1.0f32; 4]); - const SMALL: f32x4 = f32x4::from_array([1e-16f32; 4]); + const ONE: f32x4 = f32x4::from_array([1.0; 4]); + const SMALL: f32x4 = f32x4::from_array([1e-16; 4]); const MASK_F000:i32x4 = i32x4::from_array([-1i32, 0, 0, 0]); const MASK_0F00:i32x4 = i32x4::from_array([0, -1i32, 0, 0]); @@ -137,11 +137,11 @@ impl QuaternionKey { let m2 = &MAPPING[k2.largest() as usize]; let m3 = &MAPPING[k3.largest() as usize]; - let mut cmp_keys: [[f32; 4]; 4] = [ - [ k0.value[m0[0]] as f32, k1.value[m1[0]] as f32, k2.value[m2[0]] as f32, k3.value[m3[0]] as f32 ], - [ k0.value[m0[1]] as f32, k1.value[m1[1]] as f32, k2.value[m2[1]] as f32, k3.value[m3[1]] as f32 ], - [ k0.value[m0[2]] as f32, k1.value[m1[2]] as f32, k2.value[m2[2]] as f32, k3.value[m3[2]] as f32 ], - [ k0.value[m0[3]] as f32, k1.value[m1[3]] as f32, k2.value[m2[3]] as f32, k3.value[m3[3]] as f32 ], + let mut cmp_keys: [f32x4; 4] = [ + f32x4::from_array([ k0.value[m0[0]] as f32, k1.value[m1[0]] as f32, k2.value[m2[0]] as f32, k3.value[m3[0]] as f32 ]), + f32x4::from_array([ k0.value[m0[1]] as f32, k1.value[m1[1]] as f32, k2.value[m2[1]] as f32, k3.value[m3[1]] as f32 ]), + f32x4::from_array([ k0.value[m0[2]] as f32, k1.value[m1[2]] as f32, k2.value[m2[2]] as f32, k3.value[m3[2]] as f32 ]), + f32x4::from_array([ k0.value[m0[3]] as f32, k1.value[m1[3]] as f32, k2.value[m2[3]] as f32, k3.value[m3[3]] as f32 ]), ]; // TODO: simd int to float cmp_keys[k0.largest() as usize][0] = 0.0f32; cmp_keys[k1.largest() as usize][1] = 0.0f32; @@ -149,14 +149,14 @@ impl QuaternionKey { cmp_keys[k3.largest() as usize][3] = 0.0f32; let mut cpnt = [ - INT_2_FLOAT * f32x4::from_array(cmp_keys[0]), - INT_2_FLOAT * f32x4::from_array(cmp_keys[1]), - INT_2_FLOAT * f32x4::from_array(cmp_keys[2]), - INT_2_FLOAT * f32x4::from_array(cmp_keys[3]), + INT_2_FLOAT * cmp_keys[0], + INT_2_FLOAT * cmp_keys[1], + INT_2_FLOAT * cmp_keys[2], + INT_2_FLOAT * cmp_keys[3], ]; let dot = cpnt[0] * cpnt[0] + cpnt[1] * cpnt[1] + cpnt[2] * cpnt[2] + cpnt[3] * cpnt[3]; let ww0 = f32x4::simd_max(SMALL, ONE - dot); - let w0 = ww0 * ww0.recip().sqrt(); + let w0 = ww0.sqrt(); let sign = i32x4::from_array([k0.sign() as i32, k1.sign() as i32, k2.sign() as i32, k3.sign() as i32]) << 31; let restored = ix4(w0) | sign; @@ -229,7 +229,10 @@ impl ArchiveReader for Animation { let rotation_count: i32 = archive.read()?; let scale_count: i32 = archive.read()?; - let name: String = archive.read_string(name_len as usize)?; + let mut name = String::new(); + if name_len != 0 { + name = archive.read_string(name_len as usize)?; + } let translations: Vec = archive.read_vec(translation_count as usize)?; let rotations: Vec = archive.read_vec(rotation_count as usize)?; let scales: Vec = archive.read_vec(scale_count as usize)?; @@ -436,10 +439,10 @@ mod tests { assert_eq!( soa, SoaQuat { - x: f32x4::from_array([0.008545618438802194, 0.767303715540273, 0.00000000, -0.501839280]), - y: f32x4::from_array([0.008826156417853781, 0.11342366291501094, 0.00000000, -0.507083178]), - z: f32x4::from_array([0.006085516160965199, -0.3139651582478109, -0.00420806976, -0.525850952]), - w: f32x4::from_array([0.9999060145140845, 0.5475453955750709, 0.999991119, 0.463146627]), + x: f32x4::from_array([0.0085456185, 0.7673037, 0.0, -0.5018393]), + y: f32x4::from_array([0.008826156, 0.11342366, 0.0, -0.5070832]), + z: f32x4::from_array([0.006085516, -0.31396517, -0.0042080698, -0.52585095]), + w: f32x4::from_array([0.999906, 0.5475454, 0.9999911, 0.46314663]), } ); } diff --git a/src/ik_aim_job.rs b/src/ik_aim_job.rs index 76f1b92..8227dac 100644 --- a/src/ik_aim_job.rs +++ b/src/ik_aim_job.rs @@ -159,7 +159,7 @@ impl IKAimJob { let rotate_plane_axis_js; let rotate_plane_js; if denoms.simd_ne(ZERO).to_bitmask() & 0x7 == 0x7 { - let rsqrts = denoms.recip().sqrt(); + let rsqrts = denoms.sqrt().recip(); rotate_plane_axis_js = joint_to_target_js * fx4_splat_x(rsqrts); let rotate_plane_cos_angle = vec3_dot_s( @@ -173,7 +173,7 @@ impl IKAimJob { rotate_plane_cos_angle.simd_clamp(NEG_ONE, ONE), ); } else { - rotate_plane_axis_js = joint_to_target_js * fx4_splat_x(denoms.sqrt()); + rotate_plane_axis_js = joint_to_target_js * fx4_splat_x(denoms.sqrt().recip()); rotate_plane_js = QUAT_UNIT; } diff --git a/src/ik_two_bone_job.rs b/src/ik_two_bone_job.rs index 2067e66..f670784 100644 --- a/src/ik_two_bone_job.rs +++ b/src/ik_two_bone_job.rs @@ -257,7 +257,7 @@ impl IKTwoBoneJob { fn compute_mid_joint(&self, setup: &IKConstantSetup, start_target_ss_len2: f32x4) -> f32x4 { let start_mid_end_sum_ss_len2 = setup.start_mid_ss_len2 + setup.mid_end_ss_len2; // [x] let start_mid_end_ss_half_rlen = - fx4_splat_x(FRAC_1_2 * (setup.start_mid_ss_len2 * setup.mid_end_ss_len2).recip().sqrt()); // [x] + fx4_splat_x(FRAC_1_2 * (setup.start_mid_ss_len2 * setup.mid_end_ss_len2).sqrt().recip()); // [x] let mid_cos_angles_unclamped = (fx4_splat_x(start_mid_end_sum_ss_len2) - fx4_set_y(start_target_ss_len2, setup.start_end_ss_len2)) @@ -309,8 +309,8 @@ impl IKTwoBoneJob { fx4_set_y(start_target_ss_len2, ref_plane_normal_ss_len2), joint_plane_normal_ss_len2, ) - .recip() - .sqrt(); // [x y z] + .sqrt() + .recip(); // [x y z] let rotate_plane_cos_angle = vec3_dot_s( ref_plane_normal_ss * fx4_splat_y(rsqrts), @@ -353,8 +353,8 @@ impl IKTwoBoneJob { 0.0, 0.0, ]) - .recip() - .sqrt(); + .sqrt() + .recip(); self.start_joint_correction = start_lerp * fx4_splat_x(rsqrts); self.mid_joint_correction = mid_lerp * fx4_splat_y(rsqrts); diff --git a/src/math.rs b/src/math.rs index f121300..314514a 100644 --- a/src/math.rs +++ b/src/math.rs @@ -1049,8 +1049,8 @@ pub(crate) fn fx4_sin_cos(v: f32x4) -> (f32x4, f32x4) { let cos_sign = bit1 ^ bit2; // Correct the signs - let out_sin = sin_sign.simd_eq(SIGN).select(-s, s); - let out_cos = cos_sign.simd_eq(SIGN).select(-c, c); + let out_sin = fx4_xor(s, sin_sign); + let out_cos = fx4_xor(c, cos_sign); return (out_sin, out_cos); } @@ -1083,7 +1083,7 @@ pub(crate) fn fx4_asin(v: f32x4) -> f32x4 { const N5: f32x4 = f32x4::from_array([1.6666752422e-1; 4]); // Make argument positive - let non_neg = v.simd_ge(ZERO); + let asin_sign = fx4_sign(v); let mut a = v.abs(); // ASin is not defined outside the range [-1, 1] but it often happens that a value is slightly above 1 so we just clamp here @@ -1109,7 +1109,7 @@ pub(crate) fn fx4_asin(v: f32x4) -> f32x4 { z = greater.select(FRAC_PI_2 - (z + z), z); // Put the sign back - return non_neg.select(z, -z); + return fx4_xor(z, asin_sign); } #[inline] diff --git a/tests/blend.rs b/tests/blend.rs index e515668..3ea8d32 100644 --- a/tests/blend.rs +++ b/tests/blend.rs @@ -1,11 +1,8 @@ -#![cfg(feature = "rkyv")] - use glam::Mat4; use ozz_animation_rs::*; -use rkyv::{Archive, Deserialize, Serialize}; use std::rc::Rc; -#[derive(Debug, PartialEq, Archive, Serialize, Deserialize)] +#[derive(Debug, PartialEq, rkyv::Archive, rkyv::Serialize, rkyv::Deserialize)] struct TestData { ratio: f32, sample_out1: Vec, @@ -19,7 +16,25 @@ struct TestData { } #[test] -fn test_deterministic_blend() { +fn test_blend() { + run_blend(2..=2, |_, data| { + test_utils::compare_with_cpp("blend", "blend", &data.l2m_out, 1e-6).unwrap(); + }); +} + +#[cfg(feature = "rkyv")] +#[test] +fn test_blend_deterministic() { + run_blend(-1..=11, |ratio, data| { + test_utils::compare_with_rkyv("blend", &format!("blend{:+.2}", ratio), data).unwrap(); + }); +} + +fn run_blend(range: I, tester: T) +where + I: Iterator, + T: Fn(f32, &TestData), +{ let skeleton = Rc::new(Skeleton::from_file("./resource/blend/skeleton.ozz").unwrap()); let animation1 = Rc::new(Animation::from_file("./resource/blend/animation1.ozz").unwrap()); let animation2 = Rc::new(Animation::from_file("./resource/blend/animation2.ozz").unwrap()); @@ -57,40 +72,41 @@ fn test_deterministic_blend() { let l2m_out = ozz_buf(vec![Mat4::default(); skeleton.num_joints()]); l2m_job.set_output(l2m_out.clone()); - for i in -1..=11 { - let r = i as f32 / 10.0; + for i in range { + let ratio = i as f32 / 10.0; - sample_job1.set_ratio(r); + sample_job1.set_ratio(ratio); sample_job1.run().unwrap(); - sample_job2.set_ratio(r); + sample_job2.set_ratio(ratio); sample_job2.run().unwrap(); - sample_job3.set_ratio(r); + sample_job3.set_ratio(ratio); sample_job3.run().unwrap(); - blending_job.layers_mut()[0].weight = (1.0 - 2.0 * r).clamp(0.0, 1.0); // 0%=1.0, 50%=0.0, 100%=0.0 - blending_job.layers_mut()[2].weight = (2.0 * r - 1.0).clamp(0.0, 1.0); // 0%=0.0, 50%=0.0, 100%=1.0 - // 0%=0.0, 50%=1.0, 100%=0.0 - if r < 0.5 { - blending_job.layers_mut()[1].weight = (2.0 * r).clamp(0.0, 1.0); + blending_job.layers_mut()[0].weight = (1.0 - 2.0 * ratio).clamp(0.0, 1.0); // 0%=1.0, 50%=0.0, 100%=0.0 + blending_job.layers_mut()[2].weight = (2.0 * ratio - 1.0).clamp(0.0, 1.0); // 0%=0.0, 50%=0.0, 100%=1.0 + // 0%=0.0, 50%=1.0, 100%=0.0 + if ratio < 0.5 { + blending_job.layers_mut()[1].weight = (2.0 * ratio).clamp(0.0, 1.0); } else { - blending_job.layers_mut()[1].weight = (2.0 * (1.0 - r)).clamp(0.0, 1.0); + blending_job.layers_mut()[1].weight = (2.0 * (1.0 - ratio)).clamp(0.0, 1.0); } blending_job.run().unwrap(); l2m_job.run().unwrap(); - let data = TestData { - ratio: r, - sample_out1: sample_out1.vec().unwrap().clone(), - sample_ctx1: sample_job1.context().unwrap().clone_without_animation_id(), - sample_out2: sample_out2.vec().unwrap().clone(), - sample_ctx2: sample_job2.context().unwrap().clone_without_animation_id(), - sample_out3: sample_out3.vec().unwrap().clone(), - sample_ctx3: sample_job3.context().unwrap().clone_without_animation_id(), - blending_out: blending_out.vec().unwrap().clone(), - l2m_out: l2m_out.vec().unwrap().clone(), - }; - - test_utils::compare_with_rkyv("blend", &format!("blend{:+.2}", r), &data).unwrap(); + tester( + ratio, + &TestData { + ratio, + sample_out1: sample_out1.vec().unwrap().clone(), + sample_ctx1: sample_job1.context().unwrap().clone_without_animation_id(), + sample_out2: sample_out2.vec().unwrap().clone(), + sample_ctx2: sample_job2.context().unwrap().clone_without_animation_id(), + sample_out3: sample_out3.vec().unwrap().clone(), + sample_ctx3: sample_job3.context().unwrap().clone_without_animation_id(), + blending_out: blending_out.vec().unwrap().clone(), + l2m_out: l2m_out.vec().unwrap().clone(), + }, + ); } } diff --git a/tests/look_at.rs b/tests/look_at.rs index 00d2dc6..1946dd0 100644 --- a/tests/look_at.rs +++ b/tests/look_at.rs @@ -1,11 +1,8 @@ -#![cfg(feature = "rkyv")] - use glam::{Mat4, Quat, Vec3A}; use ozz_animation_rs::*; -use rkyv::{Archive, Deserialize, Serialize}; use std::rc::Rc; -#[derive(Debug, PartialEq, Archive, Serialize, Deserialize)] +#[derive(Debug, PartialEq, rkyv::Archive, rkyv::Serialize, rkyv::Deserialize)] struct TestData { locals1: Vec, locals2: Vec, @@ -22,7 +19,25 @@ const TARGET_OFFSET: Vec3A = Vec3A::new(0.2, 1.5, -0.3); const EYES_OFFSET: Vec3A = Vec3A::new(0.07, 0.1, 0.0); #[test] -fn test_deterministic_look_at() { +fn test_look_at() { + run_look_at(1..=1, |_, data| { + test_utils::compare_with_cpp("look_at", "look_at", &data.models2, 1.5e-4).unwrap(); + }); +} + +#[cfg(feature = "rkyv")] +#[test] +fn test_look_at_deterministic() { + run_look_at(0..=10, |idx, data| { + test_utils::compare_with_rkyv("look_at", &format!("look_at_{:02}", idx), data).unwrap(); + }); +} + +fn run_look_at(range: I, tester: T) +where + I: Iterator, + T: Fn(i32, &TestData), +{ let skeleton = Rc::new(Skeleton::from_file("./resource/look_at/skeleton.ozz").unwrap()); let animation = Rc::new(Animation::from_file("./resource/look_at/animation.ozz").unwrap()); @@ -58,8 +73,8 @@ fn test_deterministic_look_at() { l2m_job2.set_input(locals2.clone()); l2m_job2.set_output(models2.clone()); - for i in 0..=10 { - let time = i as f32; + for idx in range { + let time = idx as f32; let delta = (time / 5.0).fract(); let animated_target = Vec3A::new(f32_sin(time * 0.5), f32_cos(time * 0.25), f32_cos(time) * 0.5 + 0.5); @@ -70,6 +85,7 @@ fn test_deterministic_look_at() { l2m_job1.run().unwrap(); locals2.borrow_mut().clone_from_slice(locals1.borrow().as_slice()); + models2.borrow_mut().clone_from_slice(models1.borrow().as_slice()); ik_job.set_pole_vector(Vec3A::Y); ik_job.set_target(target); @@ -121,16 +137,17 @@ fn test_deterministic_look_at() { l2m_job2.set_from(previous_joint); l2m_job2.run().unwrap(); - let data = TestData { - locals1: locals1.vec().unwrap().clone(), - locals2: locals2.vec().unwrap().clone(), - models1: models1.vec().unwrap().clone(), - models2: models2.vec().unwrap().clone(), - joint_corrections, - reacheds, - }; - - test_utils::compare_with_rkyv("look_at", &format!("look_at_ik_{:02}", i), &data).unwrap(); + tester( + idx, + &TestData { + locals1: locals1.vec().unwrap().clone(), + locals2: locals2.vec().unwrap().clone(), + models1: models1.vec().unwrap().clone(), + models2: models2.vec().unwrap().clone(), + joint_corrections, + reacheds, + }, + ); } } diff --git a/tests/playback.rs b/tests/playback.rs index 7f43b66..1fa46db 100644 --- a/tests/playback.rs +++ b/tests/playback.rs @@ -1,11 +1,8 @@ -#![cfg(feature = "rkyv")] - use glam::Mat4; use ozz_animation_rs::*; -use rkyv::{Archive, Deserialize, Serialize}; use std::rc::Rc; -#[derive(Debug, PartialEq, Archive, Serialize, Deserialize)] +#[derive(Debug, PartialEq, rkyv::Archive, rkyv::Serialize, rkyv::Deserialize)] struct TestData { ratio: f32, sample_out: Vec, @@ -14,7 +11,25 @@ struct TestData { } #[test] -fn test_deterministic_playback() { +fn test_playback() { + run_playback(5..=5, |_, data| { + test_utils::compare_with_cpp("playback", "playback", &data.l2m_out, 1e-5).unwrap() + }); +} + +#[cfg(feature = "rkyv")] +#[test] +fn test_playback_deterministic() { + run_playback(-1..=11, |ratio, data| { + test_utils::compare_with_rkyv("playback", &format!("playback{:+.2}", ratio), data).unwrap() + }); +} + +fn run_playback(range: I, tester: T) +where + I: Iterator, + T: Fn(f32, &TestData), +{ let skeleton = Rc::new(Skeleton::from_file("./resource/playback/skeleton.ozz").unwrap()); let animation = Rc::new(Animation::from_file("./resource/playback/animation.ozz").unwrap()); @@ -34,19 +49,20 @@ fn test_deterministic_playback() { let l2m_out = ozz_buf(vec![Mat4::default(); skeleton.num_joints()]); l2m_job.set_output(l2m_out.clone()); - for i in -1..=11 { - let r = i as f32 / 10.0; - sample_job.set_ratio(r); + for i in range { + let ratio = i as f32 / 10.0; + sample_job.set_ratio(ratio); sample_job.run().unwrap(); l2m_job.run().unwrap(); - let data = TestData { - ratio: r, - sample_out: sample_out.vec().unwrap().clone(), - sample_ctx: sample_job.context().unwrap().clone_without_animation_id(), - l2m_out: l2m_out.vec().unwrap().clone(), - }; - - test_utils::compare_with_rkyv("playback", &format!("playback{:+.2}", r), &data).unwrap(); + tester( + ratio, + &TestData { + ratio, + sample_out: sample_out.vec().unwrap().clone(), + sample_ctx: sample_job.context().unwrap().clone_without_animation_id(), + l2m_out: l2m_out.vec().unwrap().clone(), + }, + ); } } diff --git a/tests/two_bone_ik.rs b/tests/two_bone_ik.rs index 753eb20..eb769aa 100644 --- a/tests/two_bone_ik.rs +++ b/tests/two_bone_ik.rs @@ -1,11 +1,8 @@ -#![cfg(feature = "rkyv")] - use glam::{Mat4, Quat, Vec3A}; use ozz_animation_rs::*; -use rkyv::{Archive, Deserialize, Serialize}; use std::rc::Rc; -#[derive(Debug, PartialEq, Archive, Serialize, Deserialize)] +#[derive(Debug, PartialEq, rkyv::Archive, rkyv::Serialize, rkyv::Deserialize)] struct TestData { locals: Vec, models1: Vec, @@ -19,7 +16,25 @@ const TARGET_EXTENT: f32 = 0.5; const TARGET_OFFSET: Vec3A = Vec3A::new(0.0, 0.2, 0.1); #[test] -fn test_deterministic_two_bone_ik() { +fn test_two_bone_ik() { + run_two_bone_ik(1..=1, |_, data| { + test_utils::compare_with_cpp("two_bone_ik", "two_bone_ik", &data.models2, 1e-6).unwrap(); + }); +} + +#[cfg(feature = "rkyv")] +#[test] +fn test_two_bone_ik_deterministic() { + run_two_bone_ik(0..=10, |idx, data| { + test_utils::compare_with_rkyv("two_bone_ik", &format!("two_bone_ik_{:02}", idx), data).unwrap(); + }); +} + +fn run_two_bone_ik(range: I, tester: T) +where + I: Iterator, + T: Fn(i32, &TestData), +{ let skeleton = Rc::new(Skeleton::from_file("./resource/two_bone_ik/skeleton.ozz").unwrap()); let start_joint = skeleton.joint_by_name("shoulder").unwrap(); @@ -42,8 +57,8 @@ fn test_deterministic_two_bone_ik() { l2m_job2.set_input(locals.clone()); l2m_job2.set_output(models2.clone()); - for i in 0..=10 { - let time = i as f32; + for idx in range { + let time = idx as f32; let anim_extent: f32 = (1.0 - f32_cos(time)) * 0.5 * TARGET_EXTENT; let floor: usize = (time.abs() / (2.0 * core::f32::consts::PI)) as usize; @@ -91,14 +106,16 @@ fn test_deterministic_two_bone_ik() { // compare and save results - let data = TestData { - locals: locals.vec().unwrap().clone(), - models1: models1.vec().unwrap().clone(), - models2: models2.vec().unwrap().clone(), - start_correction: ik_job.start_joint_correction(), - mid_correction: ik_job.mid_joint_correction(), - reached: ik_job.reached(), - }; - test_utils::compare_with_rkyv("two_bone_ik", &format!("two_bone_ik_{:02}", i), &data).unwrap(); + tester( + idx, + &TestData { + locals: locals.vec().unwrap().clone(), + models1: models1.vec().unwrap().clone(), + models2: models2.vec().unwrap().clone(), + start_correction: ik_job.start_joint_correction(), + mid_correction: ik_job.mid_joint_correction(), + reached: ik_job.reached(), + }, + ); } }