461 lines
20 KiB
C++
461 lines
20 KiB
C++
|
//----------------------------------------------------------------------------//
|
||
|
// //
|
||
|
// ozz-animation is hosted at http://github.com/guillaumeblanc/ozz-animation //
|
||
|
// and distributed under the MIT License (MIT). //
|
||
|
// //
|
||
|
// Copyright (c) Guillaume Blanc //
|
||
|
// //
|
||
|
// Permission is hereby granted, free of charge, to any person obtaining a //
|
||
|
// copy of this software and associated documentation files (the "Software"), //
|
||
|
// to deal in the Software without restriction, including without limitation //
|
||
|
// the rights to use, copy, modify, merge, publish, distribute, sublicense, //
|
||
|
// and/or sell copies of the Software, and to permit persons to whom the //
|
||
|
// Software is furnished to do so, subject to the following conditions: //
|
||
|
// //
|
||
|
// The above copyright notice and this permission notice shall be included in //
|
||
|
// all copies or substantial portions of the Software. //
|
||
|
// //
|
||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR //
|
||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, //
|
||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL //
|
||
|
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER //
|
||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING //
|
||
|
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER //
|
||
|
// DEALINGS IN THE SOFTWARE. //
|
||
|
// //
|
||
|
//----------------------------------------------------------------------------//
|
||
|
|
||
|
#include "ozz/base/maths/simd_quaternion.h"
|
||
|
|
||
|
#include <limits>
|
||
|
|
||
|
#include "gtest/gtest.h"
|
||
|
|
||
|
#include "ozz/base/gtest_helper.h"
|
||
|
#include "ozz/base/maths/gtest_math_helper.h"
|
||
|
#include "ozz/base/maths/math_constant.h"
|
||
|
#include "ozz/base/maths/math_ex.h"
|
||
|
|
||
|
using ozz::math::SimdQuaternion;
|
||
|
|
||
|
TEST(QuaternionConstant, ozz_simd_math) {
|
||
|
EXPECT_SIMDQUATERNION_EQ(SimdQuaternion::identity(), 0.f, 0.f, 0.f, 1.f);
|
||
|
}
|
||
|
|
||
|
TEST(QuaternionArithmetic, ozz_simd_math) {
|
||
|
const SimdQuaternion a = {
|
||
|
ozz::math::simd_float4::Load(.70710677f, 0.f, 0.f, .70710677f)};
|
||
|
const SimdQuaternion b = {
|
||
|
ozz::math::simd_float4::Load(0.f, .70710677f, 0.f, .70710677f)};
|
||
|
const SimdQuaternion c = {
|
||
|
ozz::math::simd_float4::Load(0.f, .70710677f, 0.f, -.70710677f)};
|
||
|
const SimdQuaternion denorm = {
|
||
|
ozz::math::simd_float4::Load(1.414212f, 0.f, 0.f, 1.414212f)};
|
||
|
const SimdQuaternion zero = {ozz::math::simd_float4::zero()};
|
||
|
|
||
|
EXPECT_SIMDINT_EQ(IsNormalized(a), 0xffffffff, 0, 0, 0);
|
||
|
EXPECT_SIMDINT_EQ(IsNormalized(b), 0xffffffff, 0, 0, 0);
|
||
|
EXPECT_SIMDINT_EQ(IsNormalized(c), 0xffffffff, 0, 0, 0);
|
||
|
EXPECT_SIMDINT_EQ(IsNormalized(denorm), 0, 0, 0, 0);
|
||
|
|
||
|
const SimdQuaternion conjugate = Conjugate(a);
|
||
|
EXPECT_SIMDQUATERNION_EQ(conjugate, -.70710677f, 0.f, 0.f, .70710677f);
|
||
|
|
||
|
const SimdQuaternion negate = -a;
|
||
|
EXPECT_SIMDQUATERNION_EQ(negate, -.70710677f, 0.f, 0.f, -.70710677f);
|
||
|
|
||
|
const SimdQuaternion mul0 = a * conjugate;
|
||
|
EXPECT_SIMDQUATERNION_EQ(mul0, 0.f, 0.f, 0.f, 1.f);
|
||
|
|
||
|
const SimdQuaternion mul1 = conjugate * a;
|
||
|
EXPECT_SIMDQUATERNION_EQ(mul1, 0.f, 0.f, 0.f, 1.f);
|
||
|
|
||
|
const SimdQuaternion q1234 = {
|
||
|
ozz::math::simd_float4::Load(1.f, 2.f, 3.f, 4.f)};
|
||
|
const SimdQuaternion q5678 = {
|
||
|
ozz::math::simd_float4::Load(5.f, 6.f, 7.f, 8.f)};
|
||
|
const SimdQuaternion mul12345678 = q1234 * q5678;
|
||
|
EXPECT_SIMDQUATERNION_EQ(mul12345678, 24.f, 48.f, 48.f, -6.f);
|
||
|
|
||
|
EXPECT_ASSERTION(Normalize(zero), "is not normalizable");
|
||
|
const SimdQuaternion norm = Normalize(denorm);
|
||
|
EXPECT_SIMDINT_EQ(IsNormalized(norm), 0xffffffff, 0, 0, 0);
|
||
|
EXPECT_SIMDQUATERNION_EQ(norm, .7071068f, 0.f, 0.f, .7071068f);
|
||
|
|
||
|
// EXPECT_ASSERTION(NormalizeSafe(denorm, zero), "_safer is not normalized");
|
||
|
const SimdQuaternion norm_safe = NormalizeSafe(denorm, b);
|
||
|
EXPECT_SIMDINT_EQ(IsNormalized(norm_safe), 0xffffffff, 0, 0, 0);
|
||
|
EXPECT_SIMDQUATERNION_EQ(norm_safe, .7071068f, 0.f, 0.f, .7071068f);
|
||
|
const SimdQuaternion norm_safer = NormalizeSafe(zero, b);
|
||
|
EXPECT_SIMDINT_EQ(IsNormalized(norm_safer), 0xffffffff, 0, 0, 0);
|
||
|
EXPECT_SIMDQUATERNION_EQ(norm_safer, 0.f, .70710677f, 0.f, .70710677f);
|
||
|
|
||
|
EXPECT_ASSERTION(NormalizeEst(zero), "is not normalizable");
|
||
|
const SimdQuaternion norm_est = NormalizeEst(denorm);
|
||
|
EXPECT_SIMDINT_EQ(IsNormalizedEst(norm_est), 0xffffffff, 0, 0, 0);
|
||
|
EXPECT_SIMDQUATERNION_EQ_EST(norm_est, .7071068f, 0.f, 0.f, .7071068f);
|
||
|
|
||
|
// EXPECT_ASSERTION(NormalizeSafe(denorm, zero), "_safer is not normalized");
|
||
|
const SimdQuaternion norm_safe_est = NormalizeSafeEst(denorm, b);
|
||
|
EXPECT_SIMDINT_EQ(IsNormalizedEst(norm_safe_est), 0xffffffff, 0, 0, 0);
|
||
|
EXPECT_SIMDQUATERNION_EQ_EST(norm_safe_est, .7071068f, 0.f, 0.f, .7071068f);
|
||
|
const SimdQuaternion norm_safer_est = NormalizeSafeEst(zero, b);
|
||
|
EXPECT_SIMDINT_EQ(IsNormalizedEst(norm_safer_est), 0xffffffff, 0, 0, 0);
|
||
|
EXPECT_SIMDQUATERNION_EQ_EST(norm_safer_est, 0.f, .70710677f, 0.f,
|
||
|
.70710677f);
|
||
|
}
|
||
|
|
||
|
TEST(QuaternionFromVectors, ozz_simd_math) {
|
||
|
// Returns identity for a 0 length vector
|
||
|
EXPECT_SIMDQUATERNION_EQ(
|
||
|
SimdQuaternion::FromVectors(ozz::math::simd_float4::zero(),
|
||
|
ozz::math::simd_float4::x_axis()),
|
||
|
0.f, 0.f, 0.f, 1.f);
|
||
|
|
||
|
// pi/2 around y
|
||
|
EXPECT_SIMDQUATERNION_EQ(
|
||
|
SimdQuaternion::FromVectors(ozz::math::simd_float4::z_axis(),
|
||
|
ozz::math::simd_float4::x_axis()),
|
||
|
0.f, 0.707106769f, 0.f, 0.707106769f);
|
||
|
|
||
|
// Non unit pi/2 around y
|
||
|
EXPECT_SIMDQUATERNION_EQ(
|
||
|
SimdQuaternion::FromVectors(ozz::math::simd_float4::z_axis(),
|
||
|
ozz::math::simd_float4::x_axis() *
|
||
|
ozz::math::simd_float4::Load1(27.f)),
|
||
|
0.f, 0.707106769f, 0.f, 0.707106769f);
|
||
|
|
||
|
// Minus pi/2 around y
|
||
|
EXPECT_SIMDQUATERNION_EQ(
|
||
|
SimdQuaternion::FromVectors(ozz::math::simd_float4::x_axis(),
|
||
|
ozz::math::simd_float4::z_axis()),
|
||
|
0.f, -0.707106769f, 0.f, 0.707106769f);
|
||
|
|
||
|
// pi/2 around x
|
||
|
EXPECT_SIMDQUATERNION_EQ(
|
||
|
SimdQuaternion::FromVectors(ozz::math::simd_float4::y_axis(),
|
||
|
ozz::math::simd_float4::z_axis()),
|
||
|
0.707106769f, 0.f, 0.f, 0.707106769f);
|
||
|
|
||
|
// pi/2 around z
|
||
|
EXPECT_SIMDQUATERNION_EQ(
|
||
|
SimdQuaternion::FromVectors(ozz::math::simd_float4::x_axis(),
|
||
|
ozz::math::simd_float4::y_axis()),
|
||
|
0.f, 0.f, 0.707106769f, 0.707106769f);
|
||
|
|
||
|
// pi/2 around z also
|
||
|
EXPECT_SIMDQUATERNION_EQ(
|
||
|
SimdQuaternion::FromVectors(
|
||
|
ozz::math::simd_float4::Load(0.707106769f, 0.707106769f, 0.f, 99.f),
|
||
|
ozz::math::simd_float4::Load(-0.707106769f, 0.707106769f, 0.f, 93.f)),
|
||
|
0.f, 0.f, 0.707106769f, 0.707106769f);
|
||
|
|
||
|
// Non unit pi/2 around z also
|
||
|
EXPECT_SIMDQUATERNION_EQ(
|
||
|
SimdQuaternion::FromVectors(
|
||
|
ozz::math::simd_float4::Load(0.707106769f, 0.707106769f, 0.f, 99.f) *
|
||
|
ozz::math::simd_float4::Load1(9.f),
|
||
|
ozz::math::simd_float4::Load(-0.707106769f, 0.707106769f, 0.f, 93.f) *
|
||
|
ozz::math::simd_float4::Load1(46.f)),
|
||
|
0.f, 0.f, 0.707106769f, 0.707106769f);
|
||
|
|
||
|
// Non-unit pi/2 around z
|
||
|
EXPECT_SIMDQUATERNION_EQ(
|
||
|
SimdQuaternion::FromVectors(ozz::math::simd_float4::x_axis(),
|
||
|
ozz::math::simd_float4::y_axis() *
|
||
|
ozz::math::simd_float4::Load1(2.f)),
|
||
|
0.f, 0.f, 0.707106769f, 0.707106769f);
|
||
|
|
||
|
// Aligned vectors
|
||
|
EXPECT_SIMDQUATERNION_EQ(
|
||
|
SimdQuaternion::FromVectors(ozz::math::simd_float4::x_axis(),
|
||
|
ozz::math::simd_float4::x_axis()),
|
||
|
0.f, 0.f, 0.f, 1.f);
|
||
|
|
||
|
// Non-unit aligned vectors
|
||
|
EXPECT_SIMDQUATERNION_EQ(
|
||
|
SimdQuaternion::FromVectors(ozz::math::simd_float4::x_axis(),
|
||
|
ozz::math::simd_float4::x_axis() *
|
||
|
ozz::math::simd_float4::Load1(2.f)),
|
||
|
0.f, 0.f, 0.f, 1.f);
|
||
|
|
||
|
// Opposed vectors
|
||
|
EXPECT_SIMDQUATERNION_EQ(
|
||
|
SimdQuaternion::FromVectors(ozz::math::simd_float4::x_axis(),
|
||
|
-ozz::math::simd_float4::x_axis()),
|
||
|
0.f, 1.f, 0.f, 0);
|
||
|
EXPECT_SIMDQUATERNION_EQ(
|
||
|
SimdQuaternion::FromVectors(-ozz::math::simd_float4::x_axis(),
|
||
|
ozz::math::simd_float4::x_axis()),
|
||
|
0.f, -1.f, 0.f, 0);
|
||
|
EXPECT_SIMDQUATERNION_EQ(
|
||
|
SimdQuaternion::FromVectors(ozz::math::simd_float4::y_axis(),
|
||
|
-ozz::math::simd_float4::y_axis()),
|
||
|
0.f, 0.f, 1.f, 0);
|
||
|
EXPECT_SIMDQUATERNION_EQ(
|
||
|
SimdQuaternion::FromVectors(-ozz::math::simd_float4::y_axis(),
|
||
|
ozz::math::simd_float4::y_axis()),
|
||
|
0.f, 0.f, -1.f, 0);
|
||
|
EXPECT_SIMDQUATERNION_EQ(
|
||
|
SimdQuaternion::FromVectors(ozz::math::simd_float4::z_axis(),
|
||
|
-ozz::math::simd_float4::z_axis()),
|
||
|
0.f, -1.f, 0.f, 0);
|
||
|
EXPECT_SIMDQUATERNION_EQ(
|
||
|
SimdQuaternion::FromVectors(-ozz::math::simd_float4::z_axis(),
|
||
|
ozz::math::simd_float4::z_axis()),
|
||
|
0.f, 1.f, 0.f, 0);
|
||
|
EXPECT_SIMDQUATERNION_EQ(
|
||
|
SimdQuaternion::FromVectors(
|
||
|
ozz::math::simd_float4::Load(0.707106769f, 0.707106769f, 0.f, 93.f),
|
||
|
-ozz::math::simd_float4::Load(0.707106769f, 0.707106769f, 0.f, 99.f)),
|
||
|
-0.707106769f, 0.707106769f, 0.f, 0.f);
|
||
|
EXPECT_SIMDQUATERNION_EQ(
|
||
|
SimdQuaternion::FromVectors(
|
||
|
ozz::math::simd_float4::Load(0.f, 0.707106769f, 0.707106769f, 93.f),
|
||
|
-ozz::math::simd_float4::Load(0.f, 0.707106769f, 0.707106769f, 99.f)),
|
||
|
0.f, -0.707106769f, 0.707106769f, 0.f);
|
||
|
|
||
|
// Non-unit opposed vectors
|
||
|
EXPECT_SIMDQUATERNION_EQ(
|
||
|
SimdQuaternion::FromVectors(
|
||
|
ozz::math::simd_float4::Load(2.f, 2.f, 2.f, 0.f),
|
||
|
ozz::math::simd_float4::Load(-2.f, -2.f, -2.f, 0.f)),
|
||
|
0.f, -0.707106769f, 0.707106769f, 0);
|
||
|
}
|
||
|
|
||
|
TEST(QuaternionFromUnitVectors, ozz_simd_math) {
|
||
|
// assert 0 length vectors
|
||
|
EXPECT_ASSERTION(
|
||
|
SimdQuaternion::FromUnitVectors(ozz::math::simd_float4::zero(),
|
||
|
ozz::math::simd_float4::x_axis()),
|
||
|
"Input vectors must be normalized.");
|
||
|
EXPECT_ASSERTION(
|
||
|
SimdQuaternion::FromUnitVectors(ozz::math::simd_float4::x_axis(),
|
||
|
ozz::math::simd_float4::zero()),
|
||
|
"Input vectors must be normalized.");
|
||
|
// assert non unit vectors
|
||
|
EXPECT_ASSERTION(
|
||
|
SimdQuaternion::FromUnitVectors(
|
||
|
ozz::math::simd_float4::x_axis() * ozz::math::simd_float4::Load1(2.f),
|
||
|
ozz::math::simd_float4::x_axis()),
|
||
|
"Input vectors must be normalized.");
|
||
|
EXPECT_ASSERTION(
|
||
|
SimdQuaternion::FromUnitVectors(ozz::math::simd_float4::x_axis(),
|
||
|
ozz::math::simd_float4::x_axis() *
|
||
|
ozz::math::simd_float4::Load1(.5f)),
|
||
|
"Input vectors must be normalized.");
|
||
|
|
||
|
// pi/2 around y
|
||
|
EXPECT_SIMDQUATERNION_EQ(
|
||
|
SimdQuaternion::FromUnitVectors(ozz::math::simd_float4::z_axis(),
|
||
|
ozz::math::simd_float4::x_axis()),
|
||
|
0.f, 0.707106769f, 0.f, 0.707106769f);
|
||
|
|
||
|
// Minus pi/2 around y
|
||
|
EXPECT_SIMDQUATERNION_EQ(
|
||
|
SimdQuaternion::FromUnitVectors(ozz::math::simd_float4::x_axis(),
|
||
|
ozz::math::simd_float4::z_axis()),
|
||
|
0.f, -0.707106769f, 0.f, 0.707106769f);
|
||
|
|
||
|
// pi/2 around x
|
||
|
EXPECT_SIMDQUATERNION_EQ(
|
||
|
SimdQuaternion::FromUnitVectors(ozz::math::simd_float4::y_axis(),
|
||
|
ozz::math::simd_float4::z_axis()),
|
||
|
0.707106769f, 0.f, 0.f, 0.707106769f);
|
||
|
|
||
|
// pi/2 around z
|
||
|
EXPECT_SIMDQUATERNION_EQ(
|
||
|
SimdQuaternion::FromUnitVectors(ozz::math::simd_float4::x_axis(),
|
||
|
ozz::math::simd_float4::y_axis()),
|
||
|
0.f, 0.f, 0.707106769f, 0.707106769f);
|
||
|
|
||
|
// pi/2 around z also
|
||
|
EXPECT_SIMDQUATERNION_EQ(
|
||
|
SimdQuaternion::FromUnitVectors(
|
||
|
ozz::math::simd_float4::Load(0.707106769f, 0.707106769f, 0.f, 99.f),
|
||
|
ozz::math::simd_float4::Load(-0.707106769f, 0.707106769f, 0.f, 93.f)),
|
||
|
0.f, 0.f, 0.707106769f, 0.707106769f);
|
||
|
|
||
|
// Aligned vectors
|
||
|
EXPECT_SIMDQUATERNION_EQ(
|
||
|
SimdQuaternion::FromUnitVectors(ozz::math::simd_float4::x_axis(),
|
||
|
ozz::math::simd_float4::x_axis()),
|
||
|
0.f, 0.f, 0.f, 1.f);
|
||
|
|
||
|
// Opposed vectors
|
||
|
EXPECT_SIMDQUATERNION_EQ(
|
||
|
SimdQuaternion::FromUnitVectors(ozz::math::simd_float4::x_axis(),
|
||
|
-ozz::math::simd_float4::x_axis()),
|
||
|
0.f, 1.f, 0.f, 0);
|
||
|
EXPECT_SIMDQUATERNION_EQ(
|
||
|
SimdQuaternion::FromUnitVectors(-ozz::math::simd_float4::x_axis(),
|
||
|
ozz::math::simd_float4::x_axis()),
|
||
|
0.f, -1.f, 0.f, 0);
|
||
|
EXPECT_SIMDQUATERNION_EQ(
|
||
|
SimdQuaternion::FromUnitVectors(ozz::math::simd_float4::y_axis(),
|
||
|
-ozz::math::simd_float4::y_axis()),
|
||
|
0.f, 0.f, 1.f, 0);
|
||
|
EXPECT_SIMDQUATERNION_EQ(
|
||
|
SimdQuaternion::FromUnitVectors(-ozz::math::simd_float4::y_axis(),
|
||
|
ozz::math::simd_float4::y_axis()),
|
||
|
0.f, 0.f, -1.f, 0);
|
||
|
EXPECT_SIMDQUATERNION_EQ(
|
||
|
SimdQuaternion::FromUnitVectors(ozz::math::simd_float4::z_axis(),
|
||
|
-ozz::math::simd_float4::z_axis()),
|
||
|
0.f, -1.f, 0.f, 0);
|
||
|
EXPECT_SIMDQUATERNION_EQ(
|
||
|
SimdQuaternion::FromUnitVectors(-ozz::math::simd_float4::z_axis(),
|
||
|
ozz::math::simd_float4::z_axis()),
|
||
|
0.f, 1.f, 0.f, 0);
|
||
|
EXPECT_SIMDQUATERNION_EQ(
|
||
|
SimdQuaternion::FromUnitVectors(
|
||
|
ozz::math::simd_float4::Load(0.707106769f, 0.707106769f, 0.f, 93.f),
|
||
|
-ozz::math::simd_float4::Load(0.707106769f, 0.707106769f, 0.f, 99.f)),
|
||
|
-0.707106769f, 0.707106769f, 0.f, 0.f);
|
||
|
EXPECT_SIMDQUATERNION_EQ(
|
||
|
SimdQuaternion::FromUnitVectors(
|
||
|
ozz::math::simd_float4::Load(0.f, 0.707106769f, 0.707106769f, 93.f),
|
||
|
-ozz::math::simd_float4::Load(0.f, 0.707106769f, 0.707106769f, 99.f)),
|
||
|
0.f, -0.707106769f, 0.707106769f, 0.f);
|
||
|
}
|
||
|
|
||
|
TEST(QuaternionAxisAngle, ozz_simd_math) {
|
||
|
// Expect assertions from invalid inputs
|
||
|
EXPECT_ASSERTION(
|
||
|
SimdQuaternion::FromAxisAngle(ozz::math::simd_float4::zero(),
|
||
|
ozz::math::simd_float4::zero()),
|
||
|
"axis is not normalized.");
|
||
|
#ifndef NDEBUG
|
||
|
const SimdQuaternion unorm = {
|
||
|
ozz::math::simd_float4::Load(0.f, 0.f, 0.f, 2.f)};
|
||
|
#endif // NDEBUG
|
||
|
EXPECT_ASSERTION(ToAxisAngle(unorm), "_q is not normalized.");
|
||
|
|
||
|
// Identity
|
||
|
EXPECT_SIMDQUATERNION_EQ(
|
||
|
SimdQuaternion::FromAxisAngle(ozz::math::simd_float4::x_axis(),
|
||
|
ozz::math::simd_float4::zero()),
|
||
|
0.f, 0.f, 0.f, 1.f);
|
||
|
EXPECT_SIMDFLOAT_EQ(ToAxisAngle(SimdQuaternion::identity()), 1.f, 0.f, 0.f,
|
||
|
0.f);
|
||
|
|
||
|
// Other axis angles
|
||
|
const ozz::math::SimdFloat4 pi_2 =
|
||
|
ozz::math::simd_float4::LoadX(ozz::math::kPi_2);
|
||
|
const SimdQuaternion qy_pi_2 =
|
||
|
SimdQuaternion::FromAxisAngle(ozz::math::simd_float4::y_axis(), pi_2);
|
||
|
EXPECT_SIMDQUATERNION_EQ(qy_pi_2, 0.f, .70710677f, 0.f, .70710677f);
|
||
|
EXPECT_SIMDFLOAT_EQ(ToAxisAngle(qy_pi_2), 0.f, 1.f, 0.f, ozz::math::kPi_2);
|
||
|
|
||
|
const SimdQuaternion qy_mpi_2 =
|
||
|
SimdQuaternion::FromAxisAngle(ozz::math::simd_float4::y_axis(), -pi_2);
|
||
|
EXPECT_SIMDQUATERNION_EQ(qy_mpi_2, 0.f, -.70710677f, 0.f, .70710677f);
|
||
|
EXPECT_SIMDFLOAT_EQ(ToAxisAngle(qy_mpi_2), 0.f, -1.f, 0.f,
|
||
|
ozz::math::kPi_2); // q = -q
|
||
|
const SimdQuaternion qmy_pi_2 =
|
||
|
SimdQuaternion::FromAxisAngle(-ozz::math::simd_float4::y_axis(), pi_2);
|
||
|
EXPECT_SIMDQUATERNION_EQ(qmy_pi_2, 0.f, -.70710677f, 0.f, .70710677f);
|
||
|
|
||
|
const ozz::math::SimdFloat4 any_axis =
|
||
|
ozz::math::simd_float4::Load(.819865f, .033034f, -.571604f, 99.f);
|
||
|
const ozz::math::SimdFloat4 any_angle =
|
||
|
ozz::math::simd_float4::Load(1.123f, 99.f, 26.f, 93.f);
|
||
|
const SimdQuaternion qany =
|
||
|
SimdQuaternion::FromAxisAngle(any_axis, any_angle);
|
||
|
EXPECT_SIMDQUATERNION_EQ(qany, .4365425f, .017589169f, -.30435428f,
|
||
|
.84645736f);
|
||
|
EXPECT_SIMDFLOAT_EQ(ToAxisAngle(qany), .819865f, .033034f, -.571604f, 1.123f);
|
||
|
}
|
||
|
|
||
|
TEST(QuaternionAxisCosAngle, ozz_simd_math) {
|
||
|
// Expect assertions from invalid inputs
|
||
|
EXPECT_ASSERTION(
|
||
|
SimdQuaternion::FromAxisCosAngle(ozz::math::simd_float4::zero(),
|
||
|
ozz::math::simd_float4::Load1(0.f)),
|
||
|
"axis is not normalized");
|
||
|
EXPECT_ASSERTION(SimdQuaternion::FromAxisCosAngle(
|
||
|
ozz::math::simd_float4::y_axis(),
|
||
|
ozz::math::simd_float4::Load1(-1.0000001f)),
|
||
|
"cos is not in \\[-1,1\\] range.");
|
||
|
EXPECT_ASSERTION(SimdQuaternion::FromAxisCosAngle(
|
||
|
ozz::math::simd_float4::y_axis(),
|
||
|
ozz::math::simd_float4::Load1(1.0000001f)),
|
||
|
"cos is not in \\[-1,1\\] range.");
|
||
|
|
||
|
// Identity
|
||
|
EXPECT_SIMDQUATERNION_EQ(
|
||
|
SimdQuaternion::FromAxisCosAngle(
|
||
|
ozz::math::simd_float4::y_axis(),
|
||
|
ozz::math::simd_float4::Load(1.f, 99.f, 93.f, 5.f)),
|
||
|
0.f, 0.f, 0.f, 1.f);
|
||
|
|
||
|
// Other axis angles
|
||
|
EXPECT_SIMDQUATERNION_EQ(
|
||
|
SimdQuaternion::FromAxisCosAngle(
|
||
|
ozz::math::simd_float4::y_axis(),
|
||
|
ozz::math::simd_float4::Load(std::cos(ozz::math::kPi_2), 99.f, 93.f,
|
||
|
5.f)),
|
||
|
0.f, .70710677f, 0.f, .70710677f);
|
||
|
EXPECT_SIMDQUATERNION_EQ(
|
||
|
SimdQuaternion::FromAxisCosAngle(
|
||
|
-ozz::math::simd_float4::y_axis(),
|
||
|
ozz::math::simd_float4::Load(std::cos(ozz::math::kPi_2), 99.f, 93.f,
|
||
|
5.f)),
|
||
|
0.f, -.70710677f, 0.f, .70710677f);
|
||
|
|
||
|
EXPECT_SIMDQUATERNION_EQ(
|
||
|
SimdQuaternion::FromAxisCosAngle(
|
||
|
ozz::math::simd_float4::y_axis(),
|
||
|
ozz::math::simd_float4::Load(std::cos(3.f * ozz::math::kPi_4), 99.f,
|
||
|
93.f, 5.f)),
|
||
|
0.f, 0.923879504f, 0.f, 0.382683426f);
|
||
|
|
||
|
EXPECT_SIMDQUATERNION_EQ(
|
||
|
SimdQuaternion::FromAxisCosAngle(
|
||
|
ozz::math::simd_float4::Load(.819865f, .033034f, -.571604f, 99.f),
|
||
|
ozz::math::simd_float4::Load(std::cos(1.123f), 99.f, 93.f, 5.f)),
|
||
|
.4365425f, .017589169f, -.30435428f, .84645736f);
|
||
|
}
|
||
|
|
||
|
TEST(QuaternionTransformVector, ozz_simd_math) {
|
||
|
// 0 length
|
||
|
EXPECT_SIMDFLOAT3_EQ(TransformVector(SimdQuaternion::FromAxisAngle(
|
||
|
ozz::math::simd_float4::y_axis(),
|
||
|
ozz::math::simd_float4::zero()),
|
||
|
ozz::math::simd_float4::zero()),
|
||
|
0, 0, 0);
|
||
|
|
||
|
// Unit length
|
||
|
EXPECT_SIMDFLOAT3_EQ(TransformVector(SimdQuaternion::FromAxisAngle(
|
||
|
ozz::math::simd_float4::y_axis(),
|
||
|
ozz::math::simd_float4::zero()),
|
||
|
ozz::math::simd_float4::z_axis()),
|
||
|
0, 0, 1);
|
||
|
|
||
|
const ozz::math::SimdFloat4 pi_2 =
|
||
|
ozz::math::simd_float4::LoadX(ozz::math::kPi_2);
|
||
|
EXPECT_SIMDFLOAT3_EQ(
|
||
|
TransformVector(
|
||
|
SimdQuaternion::FromAxisAngle(ozz::math::simd_float4::y_axis(), pi_2),
|
||
|
ozz::math::simd_float4::y_axis()),
|
||
|
0, 1, 0);
|
||
|
EXPECT_SIMDFLOAT3_EQ(
|
||
|
TransformVector(
|
||
|
SimdQuaternion::FromAxisAngle(ozz::math::simd_float4::y_axis(), pi_2),
|
||
|
ozz::math::simd_float4::x_axis()),
|
||
|
0, 0, -1);
|
||
|
EXPECT_SIMDFLOAT3_EQ(
|
||
|
TransformVector(
|
||
|
SimdQuaternion::FromAxisAngle(ozz::math::simd_float4::y_axis(), pi_2),
|
||
|
ozz::math::simd_float4::z_axis()),
|
||
|
1, 0, 0);
|
||
|
|
||
|
// Non unit
|
||
|
EXPECT_SIMDFLOAT3_EQ(
|
||
|
TransformVector(
|
||
|
SimdQuaternion::FromAxisAngle(ozz::math::simd_float4::z_axis(), pi_2),
|
||
|
ozz::math::simd_float4::x_axis() *
|
||
|
ozz::math::simd_float4::Load1(2.f)),
|
||
|
0, 2, 0);
|
||
|
}
|