AnimTestbed/3rdparty/ozz-animation/test/base/maths/soa_quaternion_tests.cc

170 lines
9.3 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/soa_quaternion.h"
#include "gtest/gtest.h"
#include "ozz/base/gtest_helper.h"
#include "ozz/base/maths/gtest_math_helper.h"
using ozz::math::SoaQuaternion;
using ozz::math::SoaFloat4;
using ozz::math::SoaFloat3;
TEST(SoaQuaternionConstant, ozz_soa_math) {
EXPECT_SOAQUATERNION_EQ(SoaQuaternion::identity(), 0.f, 0.f, 0.f, 0.f, 0.f,
0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 1.f, 1.f, 1.f,
1.f);
}
TEST(SoaQuaternionArithmetic, ozz_soa_math) {
const SoaQuaternion a = SoaQuaternion::Load(
ozz::math::simd_float4::Load(.70710677f, 0.f, 0.f, .382683432f),
ozz::math::simd_float4::Load(0.f, 0.f, .70710677f, 0.f),
ozz::math::simd_float4::Load(0.f, 0.f, 0.f, 0.f),
ozz::math::simd_float4::Load(.70710677f, 1.f, .70710677f, .9238795f));
const SoaQuaternion b = SoaQuaternion::Load(
ozz::math::simd_float4::Load(0.f, .70710677f, 0.f, -.382683432f),
ozz::math::simd_float4::Load(0.f, 0.f, .70710677f, 0.f),
ozz::math::simd_float4::Load(0.f, 0.f, 0.f, 0.f),
ozz::math::simd_float4::Load(1.f, .70710677f, .70710677f, .9238795f));
const SoaQuaternion denorm =
SoaQuaternion::Load(ozz::math::simd_float4::Load(.5f, 0.f, 2.f, 3.f),
ozz::math::simd_float4::Load(4.f, 0.f, 6.f, 7.f),
ozz::math::simd_float4::Load(8.f, 0.f, 10.f, 11.f),
ozz::math::simd_float4::Load(12.f, 1.f, 14.f, 15.f));
EXPECT_TRUE(ozz::math::AreAllTrue(IsNormalized(a)));
EXPECT_TRUE(ozz::math::AreAllTrue(IsNormalized(b)));
EXPECT_SIMDINT_EQ(ozz::math::IsNormalized(denorm), 0, 0xffffffff, 0, 0);
const SoaQuaternion conjugate = Conjugate(a);
EXPECT_SOAQUATERNION_EQ(conjugate, -.70710677f, -0.f, -0.f, -.382683432f,
-0.f, -0.f, -.70710677f, -0.f, -0.f, -0.f, -0.f, -0.f,
.70710677f, 1.f, .70710677f, .9238795f);
EXPECT_TRUE(ozz::math::AreAllTrue(IsNormalized(conjugate)));
const SoaQuaternion negate = -a;
EXPECT_SOAQUATERNION_EQ(negate, -.70710677f, 0.f, 0.f, -.382683432f, 0.f, 0.f,
-.70710677f, 0.f, 0.f, 0.f, 0.f, 0.f, -.70710677f,
-1.f, -.70710677f, -.9238795f);
const SoaQuaternion add = a + b;
EXPECT_SOAQUATERNION_EQ(add, .70710677f, .70710677f, 0.f, 0.f, 0.f, 0.f,
1.41421354f, 0.f, 0.f, 0.f, 0.f, 0.f, 1.70710677f,
1.70710677f, 1.41421354f, 1.847759f);
const SoaQuaternion muls = a * ozz::math::simd_float4::Load1(2.f);
EXPECT_SOAQUATERNION_EQ(muls, 1.41421354f, 0.f, 0.f, .765366864f, 0.f, 0.f,
1.41421354f, 0.f, 0.f, 0.f, 0.f, 0.f, 1.41421354f,
2.f, 1.41421354f, 1.847759f);
const SoaQuaternion mul0 = a * conjugate;
EXPECT_SOAQUATERNION_EQ(mul0, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f,
0.f, 0.f, 0.f, 1.f, 1.f, 1.f, 1.f);
EXPECT_TRUE(ozz::math::AreAllTrue(IsNormalized(mul0)));
const SoaQuaternion mul1 = conjugate * a;
EXPECT_SOAQUATERNION_EQ(mul1, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f,
0.f, 0.f, 0.f, 1.f, 1.f, 1.f, 1.f);
EXPECT_TRUE(ozz::math::AreAllTrue(IsNormalized(mul1)));
const ozz::math::SimdFloat4 dot = Dot(a, b);
EXPECT_SOAFLOAT1_EQ(dot, .70710677f, .70710677f, 1.f, .70710677f);
const SoaQuaternion normalize = Normalize(denorm);
EXPECT_TRUE(ozz::math::AreAllTrue(IsNormalized(normalize)));
EXPECT_SOAQUATERNION_EQ(normalize, .033389f, 0.f, .1091089f, .1492555f,
.267112f, 0.f, .3273268f, .348263f, .53422445f, 0.f,
.545544f, .547270f, .80133667f, 1.f, .763762f,
.74627789f);
const SoaQuaternion normalize_est = NormalizeEst(denorm);
EXPECT_SOAQUATERNION_EQ_EST(normalize_est, .033389f, 0.f, .1091089f,
.1492555f, .267112f, 0.f, .3273268f, .348263f,
.53422445f, 0.f, .545544f, .547270f, .80133667f,
1.f, .763762f, .74627789f);
EXPECT_TRUE(ozz::math::AreAllTrue(IsNormalizedEst(normalize_est)));
const SoaQuaternion lerp_0 = Lerp(a, b, ozz::math::simd_float4::zero());
EXPECT_SOAQUATERNION_EQ(lerp_0, .70710677f, 0.f, 0.f, .382683432f, 0.f, 0.f,
.70710677f, 0.f, 0.f, 0.f, 0.f, 0.f, .70710677f, 1.f,
.70710677f, .9238795f);
const SoaQuaternion lerp_1 = Lerp(a, b, ozz::math::simd_float4::one());
EXPECT_SOAQUATERNION_EQ(lerp_1, 0.f, .70710677f, 0.f, -.382683432f, 0.f, 0.f,
.70710677f, 0.f, 0.f, 0.f, 0.f, 0.f, 1.f, .70710677f,
.70710677f, .9238795f);
const SoaQuaternion lerp_0_2 = Lerp(a, b, ozz::math::simd_float4::Load1(.2f));
EXPECT_SOAQUATERNION_EQ(lerp_0_2, .565685416f, .14142136f, 0.f, .22961006f,
0.f, 0.f, .70710677f, 0.f, 0.f, 0.f, 0.f, 0.f,
.76568544f, .94142133f, .70710677f, .92387950f);
const SoaQuaternion lerp_m =
Lerp(a, b, ozz::math::simd_float4::Load(0.f, 1.f, 1.f, .2f));
EXPECT_SOAQUATERNION_EQ(lerp_m, .70710677f, .70710677f, 0.f, .22961006f, 0.f,
0.f, .70710677f, 0.f, 0.f, 0.f, 0.f, 0.f, .70710677f,
.70710677f, .70710677f, .92387950f);
const SoaQuaternion nlerp_0 = NLerp(a, b, ozz::math::simd_float4::zero());
EXPECT_SOAQUATERNION_EQ(nlerp_0, .70710677f, 0.f, 0.f, .382683432f, 0.f, 0.f,
.70710677f, 0.f, 0.f, 0.f, 0.f, 0.f, .70710677f, 1.f,
.70710677f, .9238795f);
EXPECT_TRUE(ozz::math::AreAllTrue(IsNormalized(nlerp_0)));
const SoaQuaternion nlerp_1 = NLerp(a, b, ozz::math::simd_float4::one());
EXPECT_SOAQUATERNION_EQ(nlerp_1, 0.f, .70710677f, 0.f, -.382683432f, 0.f, 0.f,
.70710677f, 0.f, 0.f, 0.f, 0.f, 0.f, 1.f, .70710677f,
.70710677f, .9238795f);
EXPECT_TRUE(ozz::math::AreAllTrue(IsNormalized(nlerp_1)));
const SoaQuaternion nlerp_0_2 =
NLerp(a, b, ozz::math::simd_float4::Load1(.2f));
EXPECT_TRUE(ozz::math::AreAllTrue(IsNormalized(nlerp_0_2)));
EXPECT_SOAQUATERNION_EQ(nlerp_0_2, .59421712f, .14855431f, 0.f, .24119100f,
0.f, 0.f, .70710683f, 0.f, 0.f, 0.f, 0.f, 0.f,
.80430466f, .98890430f, .70710683f, .97047764f);
EXPECT_TRUE(ozz::math::AreAllTrue(IsNormalized(nlerp_0_2)));
const SoaQuaternion nlerp_m =
NLerp(a, b, ozz::math::simd_float4::Load(0.f, 1.f, 1.f, .2f));
EXPECT_SOAQUATERNION_EQ(nlerp_m, .70710677f, .70710677f, 0.f, .24119100f, 0.f,
0.f, .70710677f, 0.f, 0.f, 0.f, 0.f, 0.f, .70710677f,
.70710677f, .70710677f, .97047764f);
EXPECT_TRUE(ozz::math::AreAllTrue(IsNormalized(nlerp_m)));
const SoaQuaternion nlerp_est_m =
NLerpEst(a, b, ozz::math::simd_float4::Load(0.f, 1.f, 1.f, .2f));
EXPECT_SOAQUATERNION_EQ_EST(nlerp_est_m, .70710677f, .70710677f, 0.f,
.24119100f, 0.f, 0.f, .70710677f, 0.f, 0.f, 0.f,
0.f, 0.f, .70710677f, .70710677f, .70710677f,
.97047764f);
EXPECT_TRUE(ozz::math::AreAllTrue(IsNormalizedEst(nlerp_est_m)));
}