|
| 1 | +/* |
| 2 | + * This Source Code Form is subject to the terms of the Mozilla Public |
| 3 | + * License, v. 2.0. If a copy of the MPL was not distributed with this |
| 4 | + * file, You can obtain one at https://mozilla.org/MPL/2.0/. |
| 5 | + */ |
| 6 | + |
| 7 | +use crate::itest; |
| 8 | +use godot::prelude::{inner::InnerBasis, *}; |
| 9 | +use godot::private::class_macros::assert_eq_approx; |
| 10 | + |
| 11 | +const TEST_BASIS: Basis = Basis::from_rows( |
| 12 | + Vector3::new(0.942155, -0.270682, 0.197677), |
| 13 | + Vector3::new(0.294044, 0.950564, -0.099833), |
| 14 | + Vector3::new(-0.160881, 0.152184, 0.97517), |
| 15 | +); |
| 16 | + |
| 17 | +pub(crate) fn run() -> bool { |
| 18 | + let mut ok = true; |
| 19 | + ok &= basis_multiply_same(); |
| 20 | + ok &= basis_euler_angles_same(); |
| 21 | + |
| 22 | + ok |
| 23 | +} |
| 24 | + |
| 25 | +#[itest] |
| 26 | +fn basis_multiply_same() { |
| 27 | + let rust_res = TEST_BASIS * Basis::IDENTITY; |
| 28 | + let godot_res = TEST_BASIS |
| 29 | + .to_variant() |
| 30 | + .evaluate(&Basis::IDENTITY.to_variant(), VariantOperator::Multiply) |
| 31 | + .unwrap() |
| 32 | + .to::<Basis>(); |
| 33 | + assert_eq_approx!(rust_res, godot_res, |a, b| Basis::is_equal_approx(&a, &b)); |
| 34 | + |
| 35 | + let rhs = Basis::from_axis_angle(Vector3::new(1.0, 2.0, 3.0).normalized(), 0.5); |
| 36 | + let rust_res = TEST_BASIS * rhs; |
| 37 | + let godot_res = TEST_BASIS |
| 38 | + .to_variant() |
| 39 | + .evaluate(&rhs.to_variant(), VariantOperator::Multiply) |
| 40 | + .unwrap() |
| 41 | + .to::<Basis>(); |
| 42 | + assert_eq_approx!(rust_res, godot_res, |a, b| Basis::is_equal_approx(&a, &b)); |
| 43 | +} |
| 44 | + |
| 45 | +#[itest] |
| 46 | +fn basis_euler_angles_same() { |
| 47 | + let euler_order_to_test: Vec<EulerOrder> = vec![ |
| 48 | + EulerOrder::XYZ, |
| 49 | + EulerOrder::XZY, |
| 50 | + EulerOrder::YZX, |
| 51 | + EulerOrder::YXZ, |
| 52 | + EulerOrder::ZXY, |
| 53 | + EulerOrder::ZYX, |
| 54 | + ]; |
| 55 | + |
| 56 | + let vectors_to_test: Vec<Vector3> = vec![ |
| 57 | + Vector3::new(0.0, 0.0, 0.0), |
| 58 | + Vector3::new(0.5, 0.5, 0.5), |
| 59 | + Vector3::new(-0.5, -0.5, -0.5), |
| 60 | + Vector3::new(40.0, 40.0, 40.0), |
| 61 | + Vector3::new(-40.0, -40.0, -40.0), |
| 62 | + Vector3::new(0.0, 0.0, -90.0), |
| 63 | + Vector3::new(0.0, -90.0, 0.0), |
| 64 | + Vector3::new(-90.0, 0.0, 0.0), |
| 65 | + Vector3::new(0.0, 0.0, 90.0), |
| 66 | + Vector3::new(0.0, 90.0, 0.0), |
| 67 | + Vector3::new(90.0, 0.0, 0.0), |
| 68 | + Vector3::new(0.0, 0.0, -30.0), |
| 69 | + Vector3::new(0.0, -30.0, 0.0), |
| 70 | + Vector3::new(-30.0, 0.0, 0.0), |
| 71 | + Vector3::new(0.0, 0.0, 30.0), |
| 72 | + Vector3::new(0.0, 30.0, 0.0), |
| 73 | + Vector3::new(30.0, 0.0, 0.0), |
| 74 | + Vector3::new(0.5, 50.0, 20.0), |
| 75 | + Vector3::new(-0.5, -50.0, -20.0), |
| 76 | + Vector3::new(0.5, 0.0, 90.0), |
| 77 | + Vector3::new(0.5, 0.0, -90.0), |
| 78 | + Vector3::new(360.0, 360.0, 360.0), |
| 79 | + Vector3::new(-360.0, -360.0, -360.0), |
| 80 | + Vector3::new(-90.0, 60.0, -90.0), |
| 81 | + Vector3::new(90.0, 60.0, -90.0), |
| 82 | + Vector3::new(90.0, -60.0, -90.0), |
| 83 | + Vector3::new(-90.0, -60.0, -90.0), |
| 84 | + Vector3::new(-90.0, 60.0, 90.0), |
| 85 | + Vector3::new(90.0, 60.0, 90.0), |
| 86 | + Vector3::new(90.0, -60.0, 90.0), |
| 87 | + Vector3::new(-90.0, -60.0, 90.0), |
| 88 | + Vector3::new(60.0, 90.0, -40.0), |
| 89 | + Vector3::new(60.0, -90.0, -40.0), |
| 90 | + Vector3::new(-60.0, -90.0, -40.0), |
| 91 | + Vector3::new(-60.0, 90.0, 40.0), |
| 92 | + Vector3::new(60.0, 90.0, 40.0), |
| 93 | + Vector3::new(60.0, -90.0, 40.0), |
| 94 | + Vector3::new(-60.0, -90.0, 40.0), |
| 95 | + Vector3::new(-90.0, 90.0, -90.0), |
| 96 | + Vector3::new(90.0, 90.0, -90.0), |
| 97 | + Vector3::new(90.0, -90.0, -90.0), |
| 98 | + Vector3::new(-90.0, -90.0, -90.0), |
| 99 | + Vector3::new(-90.0, 90.0, 90.0), |
| 100 | + Vector3::new(90.0, 90.0, 90.0), |
| 101 | + Vector3::new(90.0, -90.0, 90.0), |
| 102 | + Vector3::new(20.0, 150.0, 30.0), |
| 103 | + Vector3::new(20.0, -150.0, 30.0), |
| 104 | + Vector3::new(-120.0, -150.0, 30.0), |
| 105 | + Vector3::new(-120.0, -150.0, -130.0), |
| 106 | + Vector3::new(120.0, -150.0, -130.0), |
| 107 | + Vector3::new(120.0, 150.0, -130.0), |
| 108 | + Vector3::new(120.0, 150.0, 130.0), |
| 109 | + ]; |
| 110 | + |
| 111 | + for order in euler_order_to_test.into_iter() { |
| 112 | + for vector in vectors_to_test.iter() { |
| 113 | + let vector = deg_to_rad(*vector); |
| 114 | + let rust_basis = Basis::from_euler(order, vector); |
| 115 | + let godot_basis = InnerBasis::from_euler(vector, order as i64); |
| 116 | + assert!( |
| 117 | + (rust_basis).is_equal_approx(&godot_basis), |
| 118 | + "got = {rust_basis}, expected = {godot_basis}" |
| 119 | + ); |
| 120 | + } |
| 121 | + } |
| 122 | +} |
| 123 | + |
| 124 | +#[itest] |
| 125 | +fn basis_equiv() { |
| 126 | + let inner = InnerBasis::from_outer(&TEST_BASIS); |
| 127 | + let outer = TEST_BASIS; |
| 128 | + let vec = Vector3::new(1.0, 2.0, 3.0); |
| 129 | + |
| 130 | + #[rustfmt::skip] |
| 131 | + let mappings_basis = [ |
| 132 | + ("inverse", inner.inverse(), outer.inverse() ), |
| 133 | + ("transposed", inner.transposed(), outer.transposed() ), |
| 134 | + ("orthonormalized", inner.orthonormalized(), outer.orthonormalized() ), |
| 135 | + ("rotated", inner.rotated(vec.normalized(), 0.1), outer.rotated(vec.normalized(), 0.1)), |
| 136 | + ("scaled", inner.scaled(vec), outer.scaled(vec) ), |
| 137 | + ("slerp", inner.slerp(Basis::IDENTITY, 0.5), outer.slerp(Basis::IDENTITY, 0.5) ), |
| 138 | + ]; |
| 139 | + for (name, inner, outer) in mappings_basis { |
| 140 | + assert_eq_approx!(&inner, &outer, Basis::is_equal_approx, "function: {name}\n"); |
| 141 | + } |
| 142 | + |
| 143 | + #[rustfmt::skip] |
| 144 | + let mappings_float = [ |
| 145 | + ("determinant", inner.determinant(), outer.determinant()), |
| 146 | + ("tdotx", inner.tdotx(vec), outer.tdotx(vec) ), |
| 147 | + ("tdoty", inner.tdoty(vec), outer.tdoty(vec) ), |
| 148 | + ("tdotz", inner.tdotz(vec), outer.tdotz(vec) ), |
| 149 | + ]; |
| 150 | + for (name, inner, outer) in mappings_float { |
| 151 | + assert_eq_approx!( |
| 152 | + inner, |
| 153 | + outer, |
| 154 | + |a, b| is_equal_approx(a as f32, b), |
| 155 | + "function: {name}\n" |
| 156 | + ); |
| 157 | + } |
| 158 | + |
| 159 | + assert_eq_approx!( |
| 160 | + inner.get_scale(), |
| 161 | + outer.scale(), |
| 162 | + Vector3::is_equal_approx, |
| 163 | + "function: get_scale\n" |
| 164 | + ); |
| 165 | + assert_eq_approx!( |
| 166 | + inner.get_euler(EulerOrder::XYZ as i64), |
| 167 | + outer.to_euler(EulerOrder::XYZ), |
| 168 | + Vector3::is_equal_approx, |
| 169 | + "function: get_euler\n" |
| 170 | + ); |
| 171 | + assert_eq_approx!( |
| 172 | + inner.get_rotation_quaternion(), |
| 173 | + outer.to_quat(), |
| 174 | + Quaternion::is_equal_approx, |
| 175 | + "function: get_rotation_quaternion\n" |
| 176 | + ) |
| 177 | +} |
| 178 | + |
| 179 | +fn deg_to_rad(rotation: Vector3) -> Vector3 { |
| 180 | + Vector3::new( |
| 181 | + rotation.x.to_radians(), |
| 182 | + rotation.y.to_radians(), |
| 183 | + rotation.z.to_radians(), |
| 184 | + ) |
| 185 | +} |
0 commit comments