Initial commit
This commit is contained in:
@@ -0,0 +1,45 @@
|
||||
add_executable(test_math
|
||||
math_ex_tests.cc
|
||||
box_tests.cc
|
||||
rect_tests.cc
|
||||
vec_float_tests.cc
|
||||
quaternion_tests.cc
|
||||
transform_tests.cc)
|
||||
target_link_libraries(test_math
|
||||
ozz_base
|
||||
gtest)
|
||||
add_test(NAME test_math COMMAND test_math)
|
||||
set_target_properties(test_math PROPERTIES FOLDER "ozz/tests/base")
|
||||
|
||||
add_executable(test_simd_math
|
||||
simd_int_math_tests.cc
|
||||
simd_float_math_tests.cc
|
||||
simd_float4x4_tests.cc
|
||||
simd_quaternion_math_tests.cc
|
||||
simd_math_transpose_tests.cc)
|
||||
target_link_libraries(test_simd_math
|
||||
ozz_base
|
||||
gtest)
|
||||
add_test(NAME test_simd_math COMMAND test_simd_math)
|
||||
set_target_properties(test_simd_math PROPERTIES FOLDER "ozz/tests/base")
|
||||
|
||||
add_executable(test_soa_math
|
||||
soa_float_tests.cc
|
||||
soa_quaternion_tests.cc
|
||||
soa_transform_tests.cc
|
||||
soa_float4x4_tests.cc)
|
||||
target_link_libraries(test_soa_math
|
||||
ozz_base
|
||||
gtest)
|
||||
add_test(NAME test_soa_math COMMAND test_soa_math)
|
||||
set_target_properties(test_soa_math PROPERTIES FOLDER "ozz/tests/base")
|
||||
|
||||
add_executable(test_archive_maths
|
||||
math_archive_tests.cc
|
||||
simd_math_archive_tests.cc
|
||||
soa_math_archive_tests.cc)
|
||||
target_link_libraries(test_archive_maths
|
||||
ozz_base
|
||||
gtest)
|
||||
add_test(NAME test_archive_maths COMMAND test_archive_maths)
|
||||
set_target_properties(test_archive_maths PROPERTIES FOLDER "ozz/tests/base")
|
||||
+148
@@ -0,0 +1,148 @@
|
||||
//----------------------------------------------------------------------------//
|
||||
// //
|
||||
// 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/box.h"
|
||||
#include "ozz/base/maths/simd_math.h"
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include "ozz/base/gtest_helper.h"
|
||||
#include "ozz/base/maths/gtest_math_helper.h"
|
||||
|
||||
TEST(BoxValidity, ozz_math) {
|
||||
EXPECT_FALSE(ozz::math::Box().is_valid());
|
||||
EXPECT_FALSE(ozz::math::Box(ozz::math::Float3(0.f, 1.f, 2.f),
|
||||
ozz::math::Float3(0.f, -1.f, 2.f))
|
||||
.is_valid());
|
||||
EXPECT_TRUE(ozz::math::Box(ozz::math::Float3(0.f, -1.f, 2.f),
|
||||
ozz::math::Float3(0.f, 1.f, 2.f))
|
||||
.is_valid());
|
||||
EXPECT_TRUE(ozz::math::Box(ozz::math::Float3(0.f, 1.f, 2.f),
|
||||
ozz::math::Float3(0.f, 1.f, 2.f))
|
||||
.is_valid());
|
||||
}
|
||||
|
||||
TEST(BoxInside, ozz_math) {
|
||||
const ozz::math::Box invalid(ozz::math::Float3(0.f, 1.f, 2.f),
|
||||
ozz::math::Float3(0.f, -1.f, 2.f));
|
||||
EXPECT_FALSE(invalid.is_valid());
|
||||
EXPECT_FALSE(invalid.is_inside(ozz::math::Float3(0.f, 1.f, 2.f)));
|
||||
EXPECT_FALSE(invalid.is_inside(ozz::math::Float3(0.f, -.5f, 2.f)));
|
||||
EXPECT_FALSE(invalid.is_inside(ozz::math::Float3(-1.f, -2.f, -3.f)));
|
||||
|
||||
const ozz::math::Box valid(ozz::math::Float3(-1.f, -2.f, -3.f),
|
||||
ozz::math::Float3(1.f, 2.f, 3.f));
|
||||
EXPECT_TRUE(valid.is_valid());
|
||||
EXPECT_FALSE(valid.is_inside(ozz::math::Float3(0.f, -3.f, 0.f)));
|
||||
EXPECT_FALSE(valid.is_inside(ozz::math::Float3(0.f, 3.f, 0.f)));
|
||||
EXPECT_TRUE(valid.is_inside(ozz::math::Float3(-1.f, -2.f, -3.f)));
|
||||
EXPECT_TRUE(valid.is_inside(ozz::math::Float3(0.f, 0.f, 0.f)));
|
||||
}
|
||||
|
||||
TEST(BoxMerge, ozz_math) {
|
||||
const ozz::math::Box invalid1(ozz::math::Float3(0.f, 1.f, 2.f),
|
||||
ozz::math::Float3(0.f, -1.f, 2.f));
|
||||
EXPECT_FALSE(invalid1.is_valid());
|
||||
const ozz::math::Box invalid2(ozz::math::Float3(0.f, -1.f, 2.f),
|
||||
ozz::math::Float3(0.f, 1.f, -2.f));
|
||||
EXPECT_FALSE(invalid2.is_valid());
|
||||
|
||||
const ozz::math::Box valid1(ozz::math::Float3(-1.f, -2.f, -3.f),
|
||||
ozz::math::Float3(1.f, 2.f, 3.f));
|
||||
EXPECT_TRUE(valid1.is_valid());
|
||||
const ozz::math::Box valid2(ozz::math::Float3(0.f, 5.f, -8.f),
|
||||
ozz::math::Float3(1.f, 6.f, 0.f));
|
||||
EXPECT_TRUE(valid2.is_valid());
|
||||
|
||||
// Both boxes are invalid.
|
||||
EXPECT_FALSE(Merge(invalid1, invalid2).is_valid());
|
||||
|
||||
// One box is invalid.
|
||||
EXPECT_TRUE(Merge(invalid1, valid1).is_valid());
|
||||
EXPECT_TRUE(Merge(valid1, invalid1).is_valid());
|
||||
|
||||
// Both boxes are valid.
|
||||
const ozz::math::Box merge = Merge(valid1, valid2);
|
||||
EXPECT_FLOAT3_EQ(merge.min, -1.f, -2.f, -8.f);
|
||||
EXPECT_FLOAT3_EQ(merge.max, 1.f, 6.f, 3.f);
|
||||
}
|
||||
|
||||
TEST(BoxTransform, ozz_math) {
|
||||
const ozz::math::Box a(ozz::math::Float3(1.f, 2.f, 3.f),
|
||||
ozz::math::Float3(4.f, 5.f, 6.f));
|
||||
|
||||
const ozz::math::Box ia = TransformBox(ozz::math::Float4x4::identity(), a);
|
||||
EXPECT_FLOAT3_EQ(ia.min, 1.f, 2.f, 3.f);
|
||||
EXPECT_FLOAT3_EQ(ia.max, 4.f, 5.f, 6.f);
|
||||
|
||||
const ozz::math::Box ta =
|
||||
TransformBox(ozz::math::Float4x4::Translation(
|
||||
ozz::math::simd_float4::Load(2.f, -2.f, 3.f, 0.f)),
|
||||
a);
|
||||
EXPECT_FLOAT3_EQ(ta.min, 3.f, 0.f, 6.f);
|
||||
EXPECT_FLOAT3_EQ(ta.max, 6.f, 3.f, 9.f);
|
||||
|
||||
const ozz::math::Box ra =
|
||||
TransformBox(ozz::math::Float4x4::FromAxisAngle(
|
||||
ozz::math::simd_float4::y_axis(),
|
||||
ozz::math::simd_float4::LoadX(ozz::math::kPi)),
|
||||
a);
|
||||
EXPECT_FLOAT3_EQ(ra.min, -4.f, 2.f, -6.f);
|
||||
EXPECT_FLOAT3_EQ(ra.max, -1.f, 5.f, -3.f);
|
||||
}
|
||||
|
||||
TEST(BoxBuild, ozz_math) {
|
||||
const struct {
|
||||
ozz::math::Float3 value;
|
||||
char pad;
|
||||
} points[] = {
|
||||
{ozz::math::Float3(0.f, 0.f, 0.f), 0},
|
||||
{ozz::math::Float3(1.f, -1.f, 0.f), 0},
|
||||
{ozz::math::Float3(0.f, 0.f, 46.f), 0},
|
||||
{ozz::math::Float3(-27.f, 0.f, 0.f), 0},
|
||||
{ozz::math::Float3(0.f, 58.f, 0.f), 0},
|
||||
};
|
||||
|
||||
// Builds from a single point
|
||||
const ozz::math::Box single_valid(points[1].value);
|
||||
EXPECT_TRUE(single_valid.is_valid());
|
||||
EXPECT_FLOAT3_EQ(single_valid.min, 1.f, -1.f, 0.f);
|
||||
EXPECT_FLOAT3_EQ(single_valid.max, 1.f, -1.f, 0.f);
|
||||
|
||||
// Builds from multiple points
|
||||
EXPECT_ASSERTION(ozz::math::Box(&points->value, 1, OZZ_ARRAY_SIZE(points)),
|
||||
"_stride must be greater or equal to sizeof\\(Float3\\)");
|
||||
|
||||
const ozz::math::Box multi_invalid(&points->value, sizeof(points[0]), 0);
|
||||
EXPECT_FALSE(multi_invalid.is_valid());
|
||||
|
||||
const ozz::math::Box multi_valid(&points->value, sizeof(points[0]),
|
||||
OZZ_ARRAY_SIZE(points));
|
||||
EXPECT_TRUE(multi_valid.is_valid());
|
||||
EXPECT_FLOAT3_EQ(multi_valid.min, -27.f, -1.f, 0.f);
|
||||
EXPECT_FLOAT3_EQ(multi_valid.max, 1.f, 58.f, 46.f);
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
//----------------------------------------------------------------------------//
|
||||
// //
|
||||
// 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/math_archive.h"
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include "ozz/base/maths/gtest_math_helper.h"
|
||||
|
||||
#include "ozz/base/io/archive.h"
|
||||
#include "ozz/base/maths/box.h"
|
||||
#include "ozz/base/maths/quaternion.h"
|
||||
#include "ozz/base/maths/rect.h"
|
||||
#include "ozz/base/maths/transform.h"
|
||||
#include "ozz/base/maths/vec_float.h"
|
||||
|
||||
TEST(MathArchive, ozz_math) {
|
||||
for (int e = 0; e < 2; ++e) {
|
||||
ozz::Endianness endianess = e == 0 ? ozz::kBigEndian : ozz::kLittleEndian;
|
||||
|
||||
ozz::io::MemoryStream stream;
|
||||
ASSERT_TRUE(stream.opened());
|
||||
|
||||
// Write math types.
|
||||
ozz::io::OArchive o(&stream, endianess);
|
||||
const ozz::math::Float2 of2(46.f, 69.f);
|
||||
o << of2;
|
||||
const ozz::math::Float3 of3(46.f, 69.f, 58.f);
|
||||
o << of3;
|
||||
const ozz::math::Float4 of4(46.f, 69.f, 58.f, 35.f);
|
||||
o << of4;
|
||||
const ozz::math::Quaternion oquat(46.f, 69.f, 58.f, 35.f);
|
||||
o << oquat;
|
||||
const ozz::math::Transform otrans = {of3, oquat, of3};
|
||||
o << otrans;
|
||||
const ozz::math::Box o_box(ozz::math::Float3(14.f, 26.f, 46.f),
|
||||
ozz::math::Float3(58.f, 69.f, 99.f));
|
||||
o << o_box;
|
||||
const ozz::math::RectFloat o_rect_float(46.f, 69.f, 58.f, 35.f);
|
||||
o << o_rect_float;
|
||||
const ozz::math::RectInt o_rect_int(46, 69, 58, 35);
|
||||
o << o_rect_int;
|
||||
|
||||
// Reads math types.
|
||||
stream.Seek(0, ozz::io::Stream::kSet);
|
||||
ozz::io::IArchive i(&stream);
|
||||
ozz::math::Float2 if2;
|
||||
i >> if2;
|
||||
EXPECT_FLOAT2_EQ(if2, 46.f, 69.f);
|
||||
ozz::math::Float3 if3;
|
||||
i >> if3;
|
||||
EXPECT_FLOAT3_EQ(if3, 46.f, 69.f, 58.f);
|
||||
ozz::math::Float4 if4;
|
||||
i >> if4;
|
||||
EXPECT_FLOAT4_EQ(if4, 46.f, 69.f, 58.f, 35.f);
|
||||
ozz::math::Quaternion iquat;
|
||||
i >> iquat;
|
||||
EXPECT_QUATERNION_EQ(iquat, 46.f, 69.f, 58.f, 35.f);
|
||||
ozz::math::Transform itrans;
|
||||
i >> itrans;
|
||||
EXPECT_FLOAT3_EQ(itrans.translation, 46.f, 69.f, 58.f);
|
||||
EXPECT_QUATERNION_EQ(itrans.rotation, 46.f, 69.f, 58.f, 35.f);
|
||||
EXPECT_FLOAT3_EQ(itrans.scale, 46.f, 69.f, 58.f);
|
||||
ozz::math::Box i_box;
|
||||
i >> i_box;
|
||||
EXPECT_FLOAT3_EQ(i_box.min, 14.f, 26.f, 46.f);
|
||||
EXPECT_FLOAT3_EQ(i_box.max, 58.f, 69.f, 99.f);
|
||||
ozz::math::RectFloat i_rect_float;
|
||||
i >> i_rect_float;
|
||||
EXPECT_FLOAT_EQ(i_rect_float.left, 46.f);
|
||||
EXPECT_FLOAT_EQ(i_rect_float.bottom, 69.f);
|
||||
EXPECT_FLOAT_EQ(i_rect_float.width, 58.f);
|
||||
EXPECT_FLOAT_EQ(i_rect_float.height, 35.f);
|
||||
ozz::math::RectInt i_rect_int;
|
||||
i >> i_rect_int;
|
||||
EXPECT_EQ(i_rect_int.left, 46);
|
||||
EXPECT_EQ(i_rect_int.bottom, 69);
|
||||
EXPECT_EQ(i_rect_int.width, 58);
|
||||
EXPECT_EQ(i_rect_int.height, 35);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
//----------------------------------------------------------------------------//
|
||||
// //
|
||||
// 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/math_constant.h"
|
||||
#include "ozz/base/maths/math_ex.h"
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include "ozz/base/gtest_helper.h"
|
||||
|
||||
TEST(Trigonometry, ozz_math_ex) {
|
||||
EXPECT_FLOAT_EQ(ozz::math::kPi, 3.1415926535897932384626433832795f);
|
||||
EXPECT_FLOAT_EQ(ozz::math::kPi * ozz::math::kRadianToDegree, 180.f);
|
||||
EXPECT_FLOAT_EQ(180.f * ozz::math::kDegreeToRadian, ozz::math::kPi);
|
||||
}
|
||||
|
||||
TEST(FloatArithmetic, ozz_math_ex) {
|
||||
EXPECT_FLOAT_EQ(ozz::math::Lerp(0.f, 1.f, 0.f), 0.f);
|
||||
EXPECT_FLOAT_EQ(ozz::math::Lerp(0.f, 1.f, 1.f), 1.f);
|
||||
EXPECT_FLOAT_EQ(ozz::math::Lerp(0.f, 1.f, .3f), .3f);
|
||||
EXPECT_FLOAT_EQ(ozz::math::Lerp(0.f, 1.f, 12.f), 12.f);
|
||||
EXPECT_FLOAT_EQ(ozz::math::Lerp(0.f, 1.f, -12.f), -12.f);
|
||||
}
|
||||
|
||||
TEST(FloatComparison, ozz_math_ex) {
|
||||
const float a = {.5f};
|
||||
const float b = {4.f};
|
||||
const float c = {2.f};
|
||||
|
||||
const float min = ozz::math::Min(a, b);
|
||||
EXPECT_FLOAT_EQ(min, a);
|
||||
|
||||
const float max = ozz::math::Max(a, b);
|
||||
EXPECT_FLOAT_EQ(max, b);
|
||||
|
||||
const float clamp = ozz::math::Clamp(a, c, b);
|
||||
EXPECT_FLOAT_EQ(clamp, c);
|
||||
|
||||
const float clamp0 = ozz::math::Clamp(a, b, c);
|
||||
EXPECT_FLOAT_EQ(clamp0, c);
|
||||
|
||||
const float clamp1 = ozz::math::Clamp(c, a, b);
|
||||
EXPECT_FLOAT_EQ(clamp1, c);
|
||||
}
|
||||
|
||||
TEST(Select, ozz_math_ex) {
|
||||
int a = -27, b = 46;
|
||||
int *pa = &a, *pb = &b;
|
||||
int *cpa = &a, *cpb = &b;
|
||||
|
||||
{ // Integer select
|
||||
EXPECT_EQ(ozz::math::Select(true, a, b), a);
|
||||
EXPECT_EQ(ozz::math::Select(true, b, a), b);
|
||||
EXPECT_EQ(ozz::math::Select(false, a, b), b);
|
||||
}
|
||||
|
||||
{ // Float select
|
||||
EXPECT_FLOAT_EQ(ozz::math::Select(true, 46.f, 27.f), 46.f);
|
||||
EXPECT_FLOAT_EQ(ozz::math::Select(false, 99.f, 46.f), 46.f);
|
||||
}
|
||||
|
||||
{ // Pointer select
|
||||
EXPECT_EQ(ozz::math::Select(true, pa, pb), pa);
|
||||
EXPECT_EQ(ozz::math::Select(true, pb, pa), pb);
|
||||
EXPECT_EQ(ozz::math::Select(false, pa, pb), pb);
|
||||
}
|
||||
|
||||
{ // Const pointer select
|
||||
EXPECT_EQ(ozz::math::Select(true, cpa, cpb), cpa);
|
||||
EXPECT_EQ(ozz::math::Select(true, cpb, cpa), cpb);
|
||||
EXPECT_EQ(ozz::math::Select(false, cpa, cpb), cpb);
|
||||
EXPECT_EQ(ozz::math::Select(false, pa, cpb), cpb);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,469 @@
|
||||
//----------------------------------------------------------------------------//
|
||||
// //
|
||||
// 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/quaternion.h"
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include "ozz/base/gtest_helper.h"
|
||||
#include "ozz/base/maths/gtest_math_helper.h"
|
||||
|
||||
using ozz::math::Float3;
|
||||
using ozz::math::Float4;
|
||||
using ozz::math::Quaternion;
|
||||
|
||||
TEST(QuaternionConstant, ozz_math) {
|
||||
EXPECT_QUATERNION_EQ(Quaternion::identity(), 0.f, 0.f, 0.f, 1.f);
|
||||
}
|
||||
|
||||
TEST(QuaternionAxisAngle, ozz_math) {
|
||||
// Expect assertions from invalid inputs
|
||||
EXPECT_ASSERTION(Quaternion::FromAxisAngle(Float3::zero(), 0.f),
|
||||
"axis is not normalized");
|
||||
EXPECT_ASSERTION(ToAxisAngle(Quaternion(0.f, 0.f, 0.f, 2.f)), "IsNormalized");
|
||||
|
||||
// Identity
|
||||
EXPECT_QUATERNION_EQ(Quaternion::FromAxisAngle(Float3::y_axis(), 0.f), 0.f,
|
||||
0.f, 0.f, 1.f);
|
||||
EXPECT_FLOAT4_EQ(ToAxisAngle(Quaternion::identity()), 1.f, 0.f, 0.f, 0.f);
|
||||
|
||||
// Other axis angles
|
||||
EXPECT_QUATERNION_EQ(
|
||||
Quaternion::FromAxisAngle(Float3::y_axis(), ozz::math::kPi_2), 0.f,
|
||||
.70710677f, 0.f, .70710677f);
|
||||
EXPECT_FLOAT4_EQ(ToAxisAngle(Quaternion(0.f, .70710677f, 0.f, .70710677f)),
|
||||
0.f, 1.f, 0.f, ozz::math::kPi_2);
|
||||
|
||||
EXPECT_QUATERNION_EQ(
|
||||
Quaternion::FromAxisAngle(Float3::y_axis(), -ozz::math::kPi_2), 0.f,
|
||||
-.70710677f, 0.f, .70710677f);
|
||||
EXPECT_QUATERNION_EQ(
|
||||
Quaternion::FromAxisAngle(-Float3::y_axis(), ozz::math::kPi_2), 0.f,
|
||||
-.70710677f, 0.f, .70710677f);
|
||||
EXPECT_FLOAT4_EQ(ToAxisAngle(Quaternion(0.f, -.70710677f, 0.f, .70710677f)),
|
||||
0.f, -1.f, 0.f, ozz::math::kPi_2);
|
||||
|
||||
EXPECT_QUATERNION_EQ(
|
||||
Quaternion::FromAxisAngle(Float3::y_axis(), 3.f * ozz::math::kPi_4), 0.f,
|
||||
0.923879504f, 0.f, 0.382683426f);
|
||||
EXPECT_FLOAT4_EQ(
|
||||
ToAxisAngle(Quaternion(0.f, 0.923879504f, 0.f, 0.382683426f)), 0.f, 1.f,
|
||||
0.f, 3.f * ozz::math::kPi_4);
|
||||
|
||||
EXPECT_QUATERNION_EQ(
|
||||
Quaternion::FromAxisAngle(Float3(.819865f, .033034f, -.571604f), 1.123f),
|
||||
.4365425f, .017589169f, -.30435428f, .84645736f);
|
||||
EXPECT_FLOAT4_EQ(
|
||||
ToAxisAngle(Quaternion(.4365425f, .017589169f, -.30435428f, .84645736f)),
|
||||
.819865f, .033034f, -.571604f, 1.123f);
|
||||
}
|
||||
|
||||
TEST(QuaternionAxisCosAngle, ozz_math) {
|
||||
// Expect assertions from invalid inputs
|
||||
EXPECT_ASSERTION(Quaternion::FromAxisCosAngle(Float3::zero(), 0.f),
|
||||
"axis is not normalized");
|
||||
EXPECT_ASSERTION(Quaternion::FromAxisCosAngle(Float3::y_axis(), -1.0000001f),
|
||||
"cos is not in \\[-1,1\\] range.");
|
||||
EXPECT_ASSERTION(Quaternion::FromAxisCosAngle(Float3::y_axis(), 1.0000001f),
|
||||
"cos is not in \\[-1,1\\] range.");
|
||||
|
||||
// Identity
|
||||
EXPECT_QUATERNION_EQ(Quaternion::FromAxisCosAngle(Float3::y_axis(), 1.f), 0.f,
|
||||
0.f, 0.f, 1.f);
|
||||
|
||||
// Other axis angles
|
||||
EXPECT_QUATERNION_EQ(Quaternion::FromAxisCosAngle(Float3::y_axis(),
|
||||
std::cos(ozz::math::kPi_2)),
|
||||
0.f, .70710677f, 0.f, .70710677f);
|
||||
EXPECT_QUATERNION_EQ(Quaternion::FromAxisCosAngle(-Float3::y_axis(),
|
||||
std::cos(ozz::math::kPi_2)),
|
||||
0.f, -.70710677f, 0.f, .70710677f);
|
||||
|
||||
EXPECT_QUATERNION_EQ(Quaternion::FromAxisCosAngle(
|
||||
Float3::y_axis(), std::cos(3.f * ozz::math::kPi_4)),
|
||||
0.f, 0.923879504f, 0.f, 0.382683426f);
|
||||
|
||||
EXPECT_QUATERNION_EQ(
|
||||
Quaternion::FromAxisCosAngle(Float3(.819865f, .033034f, -.571604f),
|
||||
std::cos(1.123f)),
|
||||
.4365425f, .017589169f, -.30435428f, .84645736f);
|
||||
}
|
||||
|
||||
TEST(QuaternionQuaternionEuler, ozz_math) {
|
||||
// Identity
|
||||
EXPECT_QUATERNION_EQ(Quaternion::FromEuler(0.f, 0.f, 0.f), 0.f, 0.f, 0.f,
|
||||
1.f);
|
||||
EXPECT_FLOAT3_EQ(ToEuler(Quaternion::identity()), 0.f, 0.f, 0.f);
|
||||
|
||||
// Heading
|
||||
EXPECT_QUATERNION_EQ(Quaternion::FromEuler(ozz::math::kPi_2, 0.f, 0.f), 0.f,
|
||||
.70710677f, 0.f, .70710677f);
|
||||
EXPECT_FLOAT3_EQ(ToEuler(Quaternion(0.f, .70710677f, 0.f, .70710677f)),
|
||||
ozz::math::kPi_2, 0.f, 0.f);
|
||||
|
||||
// Elevation
|
||||
EXPECT_QUATERNION_EQ(Quaternion::FromEuler(0.f, ozz::math::kPi_2, 0.f), 0.f,
|
||||
0.f, .70710677f, .70710677f);
|
||||
EXPECT_FLOAT3_EQ(ToEuler(Quaternion(0.f, 0.f, .70710677f, .70710677f)), 0.f,
|
||||
ozz::math::kPi_2, 0.f);
|
||||
|
||||
// Bank
|
||||
EXPECT_QUATERNION_EQ(Quaternion::FromEuler(0.f, 0.f, ozz::math::kPi_2),
|
||||
.70710677f, 0.f, 0.f, .70710677f);
|
||||
EXPECT_FLOAT3_EQ(ToEuler(Quaternion(.70710677f, 0.f, 0.f, .70710677f)), 0.f,
|
||||
0.f, ozz::math::kPi_2);
|
||||
|
||||
// Any rotation
|
||||
EXPECT_QUATERNION_EQ(
|
||||
Quaternion::FromEuler(ozz::math::kPi / 4.f, -ozz::math::kPi / 6.f,
|
||||
ozz::math::kPi_2),
|
||||
.56098551f, .092295974f, -0.43045932f, .70105737f);
|
||||
EXPECT_FLOAT3_EQ(
|
||||
ToEuler(Quaternion(.56098551f, .092295974f, -0.43045932f, .70105737f)),
|
||||
ozz::math::kPi / 4.f, -ozz::math::kPi / 6.f, ozz::math::kPi_2);
|
||||
}
|
||||
|
||||
TEST(QuaternionFromVectors, ozz_math) {
|
||||
// Returns identity for a 0 length vector
|
||||
EXPECT_QUATERNION_EQ(
|
||||
Quaternion::FromVectors(Float3::zero(), Float3::x_axis()), 0.f, 0.f, 0.f,
|
||||
1.f);
|
||||
|
||||
// pi/2 around y
|
||||
EXPECT_QUATERNION_EQ(
|
||||
Quaternion::FromVectors(Float3::z_axis(), Float3::x_axis()), 0.f,
|
||||
0.707106769f, 0.f, 0.707106769f);
|
||||
|
||||
// Non unit pi/2 around y
|
||||
EXPECT_QUATERNION_EQ(
|
||||
Quaternion::FromVectors(Float3::z_axis() * 7.f, Float3::x_axis()), 0.f,
|
||||
0.707106769f, 0.f, 0.707106769f);
|
||||
|
||||
// Minus pi/2 around y
|
||||
EXPECT_QUATERNION_EQ(
|
||||
Quaternion::FromVectors(Float3::x_axis(), Float3::z_axis()), 0.f,
|
||||
-0.707106769f, 0.f, 0.707106769f);
|
||||
|
||||
// pi/2 around x
|
||||
EXPECT_QUATERNION_EQ(
|
||||
Quaternion::FromVectors(Float3::y_axis(), Float3::z_axis()), 0.707106769f,
|
||||
0.f, 0.f, 0.707106769f);
|
||||
|
||||
// Non unit pi/2 around x
|
||||
EXPECT_QUATERNION_EQ(
|
||||
Quaternion::FromVectors(Float3::y_axis() * 9.f, Float3::z_axis() * 13.f),
|
||||
0.707106769f, 0.f, 0.f, 0.707106769f);
|
||||
|
||||
// pi/2 around z
|
||||
EXPECT_QUATERNION_EQ(
|
||||
Quaternion::FromVectors(Float3::x_axis(), Float3::y_axis()), 0.f, 0.f,
|
||||
0.707106769f, 0.707106769f);
|
||||
|
||||
// pi/2 around z also
|
||||
EXPECT_QUATERNION_EQ(
|
||||
Quaternion::FromVectors(Float3(0.707106769f, 0.707106769f, 0.f),
|
||||
Float3(-0.707106769f, 0.707106769f, 0.f)),
|
||||
0.f, 0.f, 0.707106769f, 0.707106769f);
|
||||
|
||||
// Aligned vectors
|
||||
EXPECT_QUATERNION_EQ(
|
||||
Quaternion::FromVectors(Float3::x_axis(), Float3::x_axis()), 0.f, 0.f,
|
||||
0.f, 1.f);
|
||||
|
||||
// Non-unit aligned vectors
|
||||
EXPECT_QUATERNION_EQ(
|
||||
Quaternion::FromVectors(Float3::x_axis(), Float3::x_axis() * 2.f), 0.f,
|
||||
0.f, 0.f, 1.f);
|
||||
|
||||
// Opposed vectors
|
||||
EXPECT_QUATERNION_EQ(
|
||||
Quaternion::FromVectors(Float3::x_axis(), -Float3::x_axis()), 0.f, 1.f,
|
||||
0.f, 0);
|
||||
EXPECT_QUATERNION_EQ(
|
||||
Quaternion::FromVectors(-Float3::x_axis(), Float3::x_axis()), 0.f, -1.f,
|
||||
0.f, 0);
|
||||
EXPECT_QUATERNION_EQ(
|
||||
Quaternion::FromVectors(Float3::y_axis(), -Float3::y_axis()), 0.f, 0.f,
|
||||
1.f, 0);
|
||||
EXPECT_QUATERNION_EQ(
|
||||
Quaternion::FromVectors(-Float3::y_axis(), Float3::y_axis()), 0.f, 0.f,
|
||||
-1.f, 0);
|
||||
EXPECT_QUATERNION_EQ(
|
||||
Quaternion::FromVectors(Float3::z_axis(), -Float3::z_axis()), 0.f, -1.f,
|
||||
0.f, 0);
|
||||
EXPECT_QUATERNION_EQ(
|
||||
Quaternion::FromVectors(-Float3::z_axis(), Float3::z_axis()), 0.f, 1.f,
|
||||
0.f, 0);
|
||||
EXPECT_QUATERNION_EQ(
|
||||
Quaternion::FromVectors(Float3(0.707106769f, 0.707106769f, 0.f),
|
||||
-Float3(0.707106769f, 0.707106769f, 0.f)),
|
||||
-0.707106769f, 0.707106769f, 0.f, 0);
|
||||
EXPECT_QUATERNION_EQ(
|
||||
Quaternion::FromVectors(Float3(0.f, 0.707106769f, 0.707106769f),
|
||||
-Float3(0.f, 0.707106769f, 0.707106769f)),
|
||||
0.f, -0.707106769f, 0.707106769f, 0);
|
||||
|
||||
// Non-unit opposed vectors
|
||||
EXPECT_QUATERNION_EQ(
|
||||
Quaternion::FromVectors(Float3(2.f, 2.f, 2.f), -Float3(2.f, 2.f, 2.f)),
|
||||
0.f, -0.707106769f, 0.707106769f, 0);
|
||||
}
|
||||
|
||||
TEST(QuaternionFromUnitVectors, ozz_math) {
|
||||
// assert 0 length vectors
|
||||
EXPECT_ASSERTION(
|
||||
Quaternion::FromUnitVectors(Float3::zero(), Float3::x_axis()),
|
||||
"Input vectors must be normalized.");
|
||||
EXPECT_ASSERTION(
|
||||
Quaternion::FromUnitVectors(Float3::x_axis(), Float3::zero()),
|
||||
"Input vectors must be normalized.");
|
||||
// assert non unit vectors
|
||||
EXPECT_ASSERTION(
|
||||
Quaternion::FromUnitVectors(Float3::x_axis() * 2.f, Float3::x_axis()),
|
||||
"Input vectors must be normalized.");
|
||||
EXPECT_ASSERTION(
|
||||
Quaternion::FromUnitVectors(Float3::x_axis(), Float3::x_axis() * .5f),
|
||||
"Input vectors must be normalized.");
|
||||
|
||||
// pi/2 around y
|
||||
EXPECT_QUATERNION_EQ(
|
||||
Quaternion::FromUnitVectors(Float3::z_axis(), Float3::x_axis()), 0.f,
|
||||
0.707106769f, 0.f, 0.707106769f);
|
||||
|
||||
// Minus pi/2 around y
|
||||
EXPECT_QUATERNION_EQ(
|
||||
Quaternion::FromUnitVectors(Float3::x_axis(), Float3::z_axis()), 0.f,
|
||||
-0.707106769f, 0.f, 0.707106769f);
|
||||
|
||||
// pi/2 around x
|
||||
EXPECT_QUATERNION_EQ(
|
||||
Quaternion::FromUnitVectors(Float3::y_axis(), Float3::z_axis()),
|
||||
0.707106769f, 0.f, 0.f, 0.707106769f);
|
||||
|
||||
// pi/2 around z
|
||||
EXPECT_QUATERNION_EQ(
|
||||
Quaternion::FromUnitVectors(Float3::x_axis(), Float3::y_axis()), 0.f, 0.f,
|
||||
0.707106769f, 0.707106769f);
|
||||
|
||||
// pi/2 around z also
|
||||
EXPECT_QUATERNION_EQ(
|
||||
Quaternion::FromUnitVectors(Float3(0.707106769f, 0.707106769f, 0.f),
|
||||
Float3(-0.707106769f, 0.707106769f, 0.f)),
|
||||
0.f, 0.f, 0.707106769f, 0.707106769f);
|
||||
|
||||
// Aligned vectors
|
||||
EXPECT_QUATERNION_EQ(
|
||||
Quaternion::FromUnitVectors(Float3::x_axis(), Float3::x_axis()), 0.f, 0.f,
|
||||
0.f, 1.f);
|
||||
|
||||
// Opposed vectors
|
||||
EXPECT_QUATERNION_EQ(
|
||||
Quaternion::FromUnitVectors(Float3::x_axis(), -Float3::x_axis()), 0.f,
|
||||
1.f, 0.f, 0);
|
||||
EXPECT_QUATERNION_EQ(
|
||||
Quaternion::FromUnitVectors(-Float3::x_axis(), Float3::x_axis()), 0.f,
|
||||
-1.f, 0.f, 0);
|
||||
EXPECT_QUATERNION_EQ(
|
||||
Quaternion::FromUnitVectors(Float3::y_axis(), -Float3::y_axis()), 0.f,
|
||||
0.f, 1.f, 0);
|
||||
EXPECT_QUATERNION_EQ(
|
||||
Quaternion::FromUnitVectors(-Float3::y_axis(), Float3::y_axis()), 0.f,
|
||||
0.f, -1.f, 0);
|
||||
EXPECT_QUATERNION_EQ(
|
||||
Quaternion::FromUnitVectors(Float3::z_axis(), -Float3::z_axis()), 0.f,
|
||||
-1.f, 0.f, 0);
|
||||
EXPECT_QUATERNION_EQ(
|
||||
Quaternion::FromUnitVectors(-Float3::z_axis(), Float3::z_axis()), 0.f,
|
||||
1.f, 0.f, 0);
|
||||
EXPECT_QUATERNION_EQ(
|
||||
Quaternion::FromUnitVectors(Float3(0.707106769f, 0.707106769f, 0.f),
|
||||
-Float3(0.707106769f, 0.707106769f, 0.f)),
|
||||
-0.707106769f, 0.707106769f, 0.f, 0);
|
||||
EXPECT_QUATERNION_EQ(
|
||||
Quaternion::FromUnitVectors(Float3(0.f, 0.707106769f, 0.707106769f),
|
||||
-Float3(0.f, 0.707106769f, 0.707106769f)),
|
||||
0.f, -0.707106769f, 0.707106769f, 0);
|
||||
}
|
||||
|
||||
TEST(QuaternionCompare, ozz_math) {
|
||||
EXPECT_TRUE(Quaternion::identity() == Quaternion(0.f, 0.f, 0.f, 1.f));
|
||||
EXPECT_TRUE(Quaternion::identity() != Quaternion(1.f, 0.f, 0.f, 0.f));
|
||||
EXPECT_TRUE(Compare(Quaternion::identity(), Quaternion::identity(), std::cos(.5f * 0.f)));
|
||||
EXPECT_TRUE(Compare(Quaternion::identity(),
|
||||
Quaternion::FromEuler(0.f, 0.f, ozz::math::kPi / 100.f),
|
||||
std::cos(.5f * ozz::math::kPi / 50.f)));
|
||||
EXPECT_TRUE(Compare(Quaternion::identity(),
|
||||
-Quaternion::FromEuler(0.f, 0.f, ozz::math::kPi / 100.f),
|
||||
std::cos(.5f * ozz::math::kPi / 50.f)));
|
||||
EXPECT_FALSE(Compare(Quaternion::identity(),
|
||||
Quaternion::FromEuler(0.f, 0.f, ozz::math::kPi / 100.f),
|
||||
std::cos(.5f * ozz::math::kPi / 200.f)));
|
||||
}
|
||||
|
||||
TEST(QuaternionArithmetic, ozz_math) {
|
||||
const Quaternion a(.70710677f, 0.f, 0.f, .70710677f);
|
||||
const Quaternion b(0.f, .70710677f, 0.f, .70710677f);
|
||||
const Quaternion c(0.f, .70710677f, 0.f, -.70710677f);
|
||||
const Quaternion denorm(1.414212f, 0.f, 0.f, 1.414212f);
|
||||
|
||||
EXPECT_TRUE(IsNormalized(a));
|
||||
EXPECT_TRUE(IsNormalized(b));
|
||||
EXPECT_TRUE(IsNormalized(c));
|
||||
EXPECT_FALSE(IsNormalized(denorm));
|
||||
|
||||
const Quaternion conjugate = Conjugate(a);
|
||||
EXPECT_QUATERNION_EQ(conjugate, -a.x, -a.y, -a.z, a.w);
|
||||
EXPECT_TRUE(IsNormalized(conjugate));
|
||||
|
||||
const Quaternion negate = -a;
|
||||
EXPECT_QUATERNION_EQ(negate, -a.x, -a.y, -a.z, -a.w);
|
||||
EXPECT_TRUE(IsNormalized(negate));
|
||||
|
||||
const Quaternion add = a + b;
|
||||
EXPECT_QUATERNION_EQ(add, .70710677f, .70710677f, 0.f, 1.41421354f);
|
||||
|
||||
const Quaternion mul0 = a * conjugate;
|
||||
EXPECT_QUATERNION_EQ(mul0, 0.f, 0.f, 0.f, 1.f);
|
||||
EXPECT_TRUE(IsNormalized(mul0));
|
||||
|
||||
const Quaternion muls = a * 2.f;
|
||||
EXPECT_QUATERNION_EQ(muls, 1.41421354f, 0.f, 0.f, 1.41421354f);
|
||||
|
||||
const Quaternion mul1 = conjugate * a;
|
||||
EXPECT_QUATERNION_EQ(mul1, 0.f, 0.f, 0.f, 1.f);
|
||||
EXPECT_TRUE(IsNormalized(mul1));
|
||||
|
||||
const Quaternion q1234(1.f, 2.f, 3.f, 4.f);
|
||||
const Quaternion q5678(5.f, 6.f, 7.f, 8.f);
|
||||
const Quaternion mul12345678 = q1234 * q5678;
|
||||
EXPECT_QUATERNION_EQ(mul12345678, 24.f, 48.f, 48.f, -6.f);
|
||||
|
||||
EXPECT_ASSERTION(Normalize(Quaternion(0.f, 0.f, 0.f, 0.f)),
|
||||
"is not normalizable");
|
||||
const Quaternion normalize = Normalize(denorm);
|
||||
EXPECT_TRUE(IsNormalized(normalize));
|
||||
EXPECT_QUATERNION_EQ(normalize, .7071068f, 0.f, 0.f, .7071068f);
|
||||
|
||||
EXPECT_ASSERTION(NormalizeSafe(denorm, Quaternion(0.f, 0.f, 0.f, 0.f)),
|
||||
"_safer is not normalized");
|
||||
const Quaternion normalize_safe =
|
||||
NormalizeSafe(denorm, Quaternion::identity());
|
||||
EXPECT_TRUE(IsNormalized(normalize_safe));
|
||||
EXPECT_QUATERNION_EQ(normalize_safe, .7071068f, 0.f, 0.f, .7071068f);
|
||||
|
||||
const Quaternion normalize_safer =
|
||||
NormalizeSafe(Quaternion(0.f, 0.f, 0.f, 0.f), Quaternion::identity());
|
||||
EXPECT_TRUE(IsNormalized(normalize_safer));
|
||||
EXPECT_QUATERNION_EQ(normalize_safer, 0.f, 0.f, 0.f, 1.f);
|
||||
|
||||
const Quaternion lerp_0 = Lerp(a, b, 0.f);
|
||||
EXPECT_QUATERNION_EQ(lerp_0, a.x, a.y, a.z, a.w);
|
||||
|
||||
const Quaternion lerp_1 = Lerp(a, b, 1.f);
|
||||
EXPECT_QUATERNION_EQ(lerp_1, b.x, b.y, b.z, b.w);
|
||||
|
||||
const Quaternion lerp_0_2 = Lerp(a, b, .2f);
|
||||
EXPECT_QUATERNION_EQ(lerp_0_2, .5656853f, .1414213f, 0.f, .7071068f);
|
||||
|
||||
const Quaternion nlerp_0 = NLerp(a, b, 0.f);
|
||||
EXPECT_TRUE(IsNormalized(nlerp_0));
|
||||
EXPECT_QUATERNION_EQ(nlerp_0, a.x, a.y, a.z, a.w);
|
||||
|
||||
const Quaternion nlerp_1 = NLerp(a, b, 1.f);
|
||||
EXPECT_TRUE(IsNormalized(nlerp_1));
|
||||
EXPECT_QUATERNION_EQ(nlerp_1, b.x, b.y, b.z, b.w);
|
||||
|
||||
const Quaternion nlerp_0_2 = NLerp(a, b, .2f);
|
||||
EXPECT_TRUE(IsNormalized(nlerp_0_2));
|
||||
EXPECT_QUATERNION_EQ(nlerp_0_2, .6172133f, .1543033f, 0.f, .7715167f);
|
||||
|
||||
EXPECT_ASSERTION(SLerp(denorm, b, 0.f), "IsNormalized\\(_a\\)");
|
||||
EXPECT_ASSERTION(SLerp(a, denorm, 0.f), "IsNormalized\\(_b\\)");
|
||||
|
||||
const Quaternion slerp_0 = SLerp(a, b, 0.f);
|
||||
EXPECT_TRUE(IsNormalized(slerp_0));
|
||||
EXPECT_QUATERNION_EQ(slerp_0, a.x, a.y, a.z, a.w);
|
||||
|
||||
const Quaternion slerp_c_0 = SLerp(a, c, 0.f);
|
||||
EXPECT_TRUE(IsNormalized(slerp_c_0));
|
||||
EXPECT_QUATERNION_EQ(slerp_c_0, a.x, a.y, a.z, a.w);
|
||||
|
||||
const Quaternion slerp_c_1 = SLerp(a, c, 1.f);
|
||||
EXPECT_TRUE(IsNormalized(slerp_c_1));
|
||||
EXPECT_QUATERNION_EQ(slerp_c_1, c.x, c.y, c.z, c.w);
|
||||
|
||||
const Quaternion slerp_c_0_6 = SLerp(a, c, .6f);
|
||||
EXPECT_TRUE(IsNormalized(slerp_c_0_6));
|
||||
EXPECT_QUATERNION_EQ(slerp_c_0_6, .6067752f, .7765344f, 0.f, -.1697592f);
|
||||
|
||||
const Quaternion slerp_1 = SLerp(a, b, 1.f);
|
||||
EXPECT_TRUE(IsNormalized(slerp_1));
|
||||
EXPECT_QUATERNION_EQ(slerp_1, b.x, b.y, b.z, b.w);
|
||||
|
||||
const Quaternion slerp_0_2 = SLerp(a, b, .2f);
|
||||
EXPECT_TRUE(IsNormalized(slerp_0_2));
|
||||
EXPECT_QUATERNION_EQ(slerp_0_2, .6067752f, .1697592f, 0.f, .7765344f);
|
||||
|
||||
const Quaternion slerp_0_7 = SLerp(a, b, .7f);
|
||||
EXPECT_TRUE(IsNormalized(slerp_0_7));
|
||||
EXPECT_QUATERNION_EQ(slerp_0_7, .2523113f, .5463429f, 0.f, .798654f);
|
||||
|
||||
const float dot = Dot(a, b);
|
||||
EXPECT_FLOAT_EQ(dot, .5f);
|
||||
}
|
||||
|
||||
TEST(QuaternionTransformVector, ozz_math) {
|
||||
// 0 length
|
||||
EXPECT_FLOAT3_EQ(
|
||||
TransformVector(Quaternion::FromAxisAngle(Float3::y_axis(), 0.f),
|
||||
Float3::zero()),
|
||||
0, 0, 0);
|
||||
|
||||
// Unit length
|
||||
EXPECT_FLOAT3_EQ(
|
||||
TransformVector(Quaternion::FromAxisAngle(Float3::y_axis(), 0.f),
|
||||
Float3::z_axis()),
|
||||
0, 0, 1);
|
||||
EXPECT_FLOAT3_EQ(TransformVector(Quaternion::FromAxisAngle(Float3::y_axis(),
|
||||
ozz::math::kPi_2),
|
||||
Float3::y_axis()),
|
||||
0, 1, 0);
|
||||
EXPECT_FLOAT3_EQ(TransformVector(Quaternion::FromAxisAngle(Float3::y_axis(),
|
||||
ozz::math::kPi_2),
|
||||
Float3::x_axis()),
|
||||
0, 0, -1);
|
||||
EXPECT_FLOAT3_EQ(TransformVector(Quaternion::FromAxisAngle(Float3::y_axis(),
|
||||
ozz::math::kPi_2),
|
||||
Float3::z_axis()),
|
||||
1, 0, 0);
|
||||
|
||||
// Non unit
|
||||
EXPECT_FLOAT3_EQ(TransformVector(Quaternion::FromAxisAngle(Float3::z_axis(),
|
||||
ozz::math::kPi_2),
|
||||
Float3::x_axis() * 2),
|
||||
0, 2, 0);
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
//----------------------------------------------------------------------------//
|
||||
// //
|
||||
// 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/rect.h"
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include "ozz/base/gtest_helper.h"
|
||||
|
||||
TEST(RectInt, ozz_math) {
|
||||
ozz::math::RectInt rect(10, 20, 30, 40);
|
||||
|
||||
EXPECT_EQ(rect.right(), 40);
|
||||
EXPECT_EQ(rect.top(), 60);
|
||||
|
||||
EXPECT_TRUE(rect.is_inside(10, 20));
|
||||
EXPECT_TRUE(rect.is_inside(39, 59));
|
||||
|
||||
EXPECT_FALSE(rect.is_inside(9, 20));
|
||||
EXPECT_FALSE(rect.is_inside(10, 19));
|
||||
EXPECT_FALSE(rect.is_inside(40, 59));
|
||||
EXPECT_FALSE(rect.is_inside(39, 60));
|
||||
}
|
||||
|
||||
TEST(RectFloat, ozz_math) {
|
||||
ozz::math::RectFloat rect(10.f, 20.f, 30.f, 40.f);
|
||||
|
||||
EXPECT_FLOAT_EQ(rect.right(), 40.f);
|
||||
EXPECT_FLOAT_EQ(rect.top(), 60.f);
|
||||
|
||||
EXPECT_TRUE(rect.is_inside(10.f, 20.f));
|
||||
EXPECT_TRUE(rect.is_inside(39.f, 59.f));
|
||||
|
||||
EXPECT_FALSE(rect.is_inside(9.f, 20.f));
|
||||
EXPECT_FALSE(rect.is_inside(10.f, 19.f));
|
||||
EXPECT_FALSE(rect.is_inside(40.f, 59.f));
|
||||
EXPECT_FALSE(rect.is_inside(39.f, 60.f));
|
||||
}
|
||||
@@ -0,0 +1,488 @@
|
||||
//----------------------------------------------------------------------------//
|
||||
// //
|
||||
// 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_math.h"
|
||||
|
||||
#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::Float4x4;
|
||||
using ozz::math::SimdFloat4;
|
||||
|
||||
TEST(Float4x4Constant, ) {
|
||||
const Float4x4 identity = Float4x4::identity();
|
||||
EXPECT_FLOAT4x4_EQ(identity, 1.f, 0.f, 0.f, 0.f, 0.f, 1.f, 0.f, 0.f, 0.f, 0.f,
|
||||
1.f, 0.f, 0.f, 0.f, 0.f, 1.f);
|
||||
}
|
||||
|
||||
TEST(Float4x4Arithmetic, ozz_simd_math) {
|
||||
const Float4x4 m0 = {{ozz::math::simd_float4::Load(0.f, 1.f, 2.f, 3.f),
|
||||
ozz::math::simd_float4::Load(4.f, 5.f, 6.f, 7.f),
|
||||
ozz::math::simd_float4::Load(8.f, 9.f, 10.f, 11.f),
|
||||
ozz::math::simd_float4::Load(12.f, 13.f, 14.f, 15.f)}};
|
||||
const Float4x4 m1 = {
|
||||
{ozz::math::simd_float4::Load(-0.f, -1.f, -2.f, -3.f),
|
||||
ozz::math::simd_float4::Load(-4.f, -5.f, -6.f, -7.f),
|
||||
ozz::math::simd_float4::Load(-8.f, -9.f, -10.f, -11.f),
|
||||
ozz::math::simd_float4::Load(-12.f, -13.f, -14.f, -15.f)}};
|
||||
const Float4x4 m2 = {
|
||||
{ozz::math::simd_float4::Load(0.f, -1.f, 2.f, 3.f),
|
||||
ozz::math::simd_float4::Load(-4.f, 5.f, 6.f, -7.f),
|
||||
ozz::math::simd_float4::Load(8.f, -9.f, -10.f, 11.f),
|
||||
ozz::math::simd_float4::Load(-12.f, 13.f, -14.f, 15.f)}};
|
||||
const SimdFloat4 v = ozz::math::simd_float4::Load(-0.f, -1.f, -2.f, -3.f);
|
||||
|
||||
const SimdFloat4 mul_vector = m0 * v;
|
||||
EXPECT_SIMDFLOAT_EQ(mul_vector, -56.f, -62.f, -68.f, -74.f);
|
||||
|
||||
const SimdFloat4 transform_point = TransformPoint(m0, v);
|
||||
EXPECT_SIMDFLOAT_EQ(transform_point, -8.f, -10.f, -12.f, -14.f);
|
||||
|
||||
const SimdFloat4 transform_vector = TransformVector(m0, v);
|
||||
EXPECT_SIMDFLOAT_EQ(transform_vector, -20.f, -23.f, -26.f, -29.f);
|
||||
|
||||
const Float4x4 mul_mat = m0 * m1;
|
||||
EXPECT_FLOAT4x4_EQ(mul_mat, -56.f, -62.f, -68.f, -74.f, -152.f, -174.f,
|
||||
-196.f, -218.f, -248.f, -286.f, -324.f, -362.f, -344.f,
|
||||
-398.f, -452.f, -506.f);
|
||||
|
||||
const Float4x4 add_mat = m0 + m1;
|
||||
EXPECT_FLOAT4x4_EQ(add_mat, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f,
|
||||
0.f, 0.f, 0.f, 0.f, 0.f, 0.f);
|
||||
|
||||
const Float4x4 sub_mat = m0 - m1;
|
||||
EXPECT_FLOAT4x4_EQ(sub_mat, 0.f, 2.f, 4.f, 6.f, 8.f, 10.f, 12.f, 14.f, 16.f,
|
||||
18.f, 20.f, 22.f, 24.f, 26.f, 28.f, 30.f);
|
||||
|
||||
const Float4x4 transpose = Transpose(m0);
|
||||
EXPECT_FLOAT4x4_EQ(transpose, 0.f, 4.f, 8.f, 12.f, 1.f, 5.f, 9.f, 13.f, 2.f,
|
||||
6.f, 10.f, 14.f, 3.f, 7.f, 11.f, 15.f);
|
||||
|
||||
// Invertible
|
||||
const Float4x4 invert_ident = Invert(Float4x4::identity());
|
||||
EXPECT_FLOAT4x4_EQ(invert_ident, 1.f, 0.f, 0.f, 0.f, 0.f, 1.f, 0.f, 0.f, 0.f,
|
||||
0.f, 1.f, 0.f, 0.f, 0.f, 0.f, 1.f);
|
||||
|
||||
const Float4x4 invert = Invert(m2);
|
||||
EXPECT_FLOAT4x4_EQ(invert, .216667f, 2.75f, 1.6f, .066666f, .2f, 2.5f, 1.4f,
|
||||
.1f, .25f, .5f, .25f, 0.f, .233333f, .5f, .3f, .03333f);
|
||||
|
||||
const Float4x4 invert_mul = m2 * invert;
|
||||
EXPECT_FLOAT4x4_EQ(invert_mul, 1.f, 0.f, 0.f, 0.f, 0.f, 1.f, 0.f, 0.f, 0.f,
|
||||
0.f, 1.f, 0.f, 0.f, 0.f, 0.f, 1.f);
|
||||
|
||||
ozz::math::SimdInt4 invertible;
|
||||
EXPECT_FLOAT4x4_EQ(Invert(m2, &invertible), 0.216667f, 2.75f, 1.6f, .066666f,
|
||||
.2f, 2.5f, 1.4f, .1f, .25f, .5f, .25f, 0.f, .233333f, .5f,
|
||||
.3f, .03333f);
|
||||
EXPECT_TRUE(ozz::math::AreAllTrue1(invertible));
|
||||
|
||||
// Non invertible
|
||||
EXPECT_ASSERTION(Invert(m0), "Matrix is not invertible");
|
||||
|
||||
ozz::math::SimdInt4 not_invertible;
|
||||
EXPECT_FLOAT4x4_EQ(Invert(m0, ¬_invertible), 0.f, 0.f, 0.f, 0.f, 0.f, 0.f,
|
||||
0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f);
|
||||
EXPECT_FALSE(ozz::math::AreAllTrue1(not_invertible));
|
||||
}
|
||||
|
||||
TEST(Float4x4Normal, ozz_simd_math) {
|
||||
const Float4x4 not_orthogonal = {
|
||||
{ozz::math::simd_float4::Load(1.f, 0.f, 0.f, 0.f),
|
||||
ozz::math::simd_float4::Load(1.f, 0.f, 0.f, 0.f),
|
||||
ozz::math::simd_float4::Load(0.f, 0.f, 1.f, 0.f),
|
||||
ozz::math::simd_float4::Load(0.f, 0.f, 0.f, 1.f)}};
|
||||
EXPECT_TRUE(ozz::math::AreAllTrue3(IsNormalized(not_orthogonal)));
|
||||
EXPECT_TRUE(ozz::math::AreAllTrue3(IsNormalized(
|
||||
Float4x4::Scaling(ozz::math::simd_float4::Load(1.f, -1.f, 1.f, 0.f)))));
|
||||
EXPECT_FALSE(ozz::math::AreAllTrue3(IsNormalized(
|
||||
Float4x4::Scaling(ozz::math::simd_float4::Load(1.f, 46.f, 1.f, 0.f)))));
|
||||
EXPECT_TRUE(ozz::math::AreAllTrue3(IsNormalized(Float4x4::identity())));
|
||||
EXPECT_TRUE(ozz::math::AreAllTrue3(IsNormalized(
|
||||
Float4x4::FromAxisAngle(ozz::math::simd_float4::x_axis(),
|
||||
ozz::math::simd_float4::LoadX(1.24f)))));
|
||||
EXPECT_TRUE(ozz::math::AreAllTrue3(IsNormalized(Float4x4::Translation(
|
||||
ozz::math::simd_float4::Load(46.f, 0.f, 0.f, 1.f)))));
|
||||
}
|
||||
|
||||
TEST(Float4x4Orthogonal, ozz_simd_math) {
|
||||
const Float4x4 zero = {{ozz::math::simd_float4::Load(0.f, 0.f, 0.f, 0.f),
|
||||
ozz::math::simd_float4::Load(0.f, 1.f, 0.f, 0.f),
|
||||
ozz::math::simd_float4::Load(0.f, 0.f, 1.f, 0.f),
|
||||
ozz::math::simd_float4::Load(0.f, 0.f, 0.f, 1.f)}};
|
||||
const Float4x4 not_orthogonal = {
|
||||
{ozz::math::simd_float4::Load(1.f, 0.f, 0.f, 0.f),
|
||||
ozz::math::simd_float4::Load(1.f, 0.f, 0.f, 0.f),
|
||||
ozz::math::simd_float4::Load(0.f, 0.f, 1.f, 0.f),
|
||||
ozz::math::simd_float4::Load(0.f, 0.f, 0.f, 1.f)}};
|
||||
|
||||
EXPECT_FALSE(ozz::math::AreAllTrue1(IsOrthogonal(not_orthogonal)));
|
||||
EXPECT_FALSE(ozz::math::AreAllTrue1(IsOrthogonal(zero)));
|
||||
|
||||
const Float4x4 reflexion1x =
|
||||
Float4x4::Scaling(ozz::math::simd_float4::Load(-1.f, 1.f, 1.f, 0.f));
|
||||
EXPECT_FALSE(ozz::math::AreAllTrue1(IsOrthogonal(reflexion1x)));
|
||||
const Float4x4 reflexion1y =
|
||||
Float4x4::Scaling(ozz::math::simd_float4::Load(1.f, -1.f, 1.f, 0.f));
|
||||
EXPECT_FALSE(ozz::math::AreAllTrue1(IsOrthogonal(reflexion1y)));
|
||||
const Float4x4 reflexion1z =
|
||||
Float4x4::Scaling(ozz::math::simd_float4::Load(1.f, 1.f, -1.f, 0.f));
|
||||
EXPECT_FALSE(ozz::math::AreAllTrue1(IsOrthogonal(reflexion1z)));
|
||||
const Float4x4 reflexion2x =
|
||||
Float4x4::Scaling(ozz::math::simd_float4::Load(1.f, -1.f, -1.f, 0.f));
|
||||
EXPECT_TRUE(ozz::math::AreAllTrue1(IsOrthogonal(reflexion2x)));
|
||||
const Float4x4 reflexion2y =
|
||||
Float4x4::Scaling(ozz::math::simd_float4::Load(-1.f, 1.f, -1.f, 0.f));
|
||||
EXPECT_TRUE(ozz::math::AreAllTrue1(IsOrthogonal(reflexion2y)));
|
||||
const Float4x4 reflexion2z =
|
||||
Float4x4::Scaling(ozz::math::simd_float4::Load(-1.f, -1.f, 1.f, 0.f));
|
||||
EXPECT_TRUE(ozz::math::AreAllTrue1(IsOrthogonal(reflexion2z)));
|
||||
const Float4x4 reflexion3 =
|
||||
Float4x4::Scaling(ozz::math::simd_float4::Load(-1.f, -1.f, -1.f, 0.f));
|
||||
EXPECT_FALSE(ozz::math::AreAllTrue1(IsOrthogonal(reflexion3)));
|
||||
|
||||
EXPECT_TRUE(ozz::math::AreAllTrue1(IsOrthogonal(Float4x4::identity())));
|
||||
EXPECT_TRUE(ozz::math::AreAllTrue1(IsOrthogonal(Float4x4::Translation(
|
||||
ozz::math::simd_float4::Load(46.f, 0.f, 0.f, 1.f)))));
|
||||
EXPECT_TRUE(ozz::math::AreAllTrue1(IsOrthogonal(
|
||||
Float4x4::FromAxisAngle(ozz::math::simd_float4::x_axis(),
|
||||
ozz::math::simd_float4::LoadX(1.24f)))));
|
||||
}
|
||||
|
||||
TEST(Float4x4Translate, ozz_simd_math) {
|
||||
const SimdFloat4 v = ozz::math::simd_float4::Load(-1.f, 1.f, 2.f, 3.f);
|
||||
const Float4x4 m0 = {{ozz::math::simd_float4::Load(0.f, 1.f, 2.f, 3.f),
|
||||
ozz::math::simd_float4::Load(4.f, 5.f, 6.f, 7.f),
|
||||
ozz::math::simd_float4::Load(8.f, 9.f, 10.f, 11.f),
|
||||
ozz::math::simd_float4::Load(12.f, 13.f, 14.f, 15.f)}};
|
||||
|
||||
const Float4x4 translation = Float4x4::Translation(v);
|
||||
EXPECT_FLOAT4x4_EQ(translation, 1.f, 0.f, 0.f, 0.f, 0.f, 1.f, 0.f, 0.f, 0.f,
|
||||
0.f, 1.f, 0.f, -1.f, 1.f, 2.f, 1.f);
|
||||
|
||||
const Float4x4 translate_mul = m0 * translation;
|
||||
EXPECT_FLOAT4x4_EQ(translate_mul, 0.f, 1.f, 2.f, 3.f, 4.f, 5.f, 6.f, 7.f, 8.f,
|
||||
9.f, 10.f, 11.f, 32.f, 35.f, 38.f, 41.f);
|
||||
|
||||
const Float4x4 translate = Translate(m0, v);
|
||||
EXPECT_FLOAT4x4_EQ(translate, 0.f, 1.f, 2.f, 3.f, 4.f, 5.f, 6.f, 7.f, 8.f,
|
||||
9.f, 10.f, 11.f, 32.f, 35.f, 38.f, 41.f);
|
||||
}
|
||||
|
||||
TEST(Float4x4Scale, ozz_simd_math) {
|
||||
const SimdFloat4 v = ozz::math::simd_float4::Load(-1.f, 1.f, 2.f, 3.f);
|
||||
const Float4x4 m0 = {{ozz::math::simd_float4::Load(0.f, 1.f, 2.f, 3.f),
|
||||
ozz::math::simd_float4::Load(4.f, 5.f, 6.f, 7.f),
|
||||
ozz::math::simd_float4::Load(8.f, 9.f, 10.f, 11.f),
|
||||
ozz::math::simd_float4::Load(12.f, 13.f, 14.f, 15.f)}};
|
||||
|
||||
const Float4x4 scaling = Float4x4::Scaling(v);
|
||||
EXPECT_FLOAT4x4_EQ(scaling, -1.f, 0.f, 0.f, 0.f, 0.f, 1.f, 0.f, 0.f, 0.f, 0.f,
|
||||
2.f, 0.f, 0.f, 0.f, 0.f, 1.f);
|
||||
|
||||
const Float4x4 scale_mul = m0 * scaling;
|
||||
EXPECT_FLOAT4x4_EQ(scale_mul, 0.f, -1.f, -2.f, -3.f, 4.f, 5.f, 6.f, 7.f, 16.f,
|
||||
18.f, 20.f, 22.f, 12.f, 13.f, 14.f, 15.f);
|
||||
|
||||
const Float4x4 scale = Scale(m0, v);
|
||||
EXPECT_FLOAT4x4_EQ(scale, 0.f, -1.f, -2.f, -3.f, 4.f, 5.f, 6.f, 7.f, 16.f,
|
||||
18.f, 20.f, 22.f, 12.f, 13.f, 14.f, 15.f);
|
||||
}
|
||||
|
||||
TEST(Float4x4ColumnMultiply, ozz_simd_math) {
|
||||
const SimdFloat4 v = ozz::math::simd_float4::Load(-1.f, -2.f, -3.f, -4.f);
|
||||
const Float4x4 m0 = {{ozz::math::simd_float4::Load(0.f, 1.f, 2.f, 3.f),
|
||||
ozz::math::simd_float4::Load(4.f, 5.f, 6.f, 7.f),
|
||||
ozz::math::simd_float4::Load(8.f, 9.f, 10.f, 11.f),
|
||||
ozz::math::simd_float4::Load(12.f, 13.f, 14.f, 15.f)}};
|
||||
|
||||
const Float4x4 column_multiply = ozz::math::ColumnMultiply(m0, v);
|
||||
EXPECT_FLOAT4x4_EQ(column_multiply, 0.f, -2.f, -6.f, -12.f, -4.f, -10.f,
|
||||
-18.f, -28.f, -8.f, -18.f, -30.f, -44.f, -12.f, -26.f,
|
||||
-42.f, -60.f);
|
||||
}
|
||||
|
||||
TEST(Float4x4Rotate, ozz_simd_math) {
|
||||
const Float4x4 euler_identity =
|
||||
Float4x4::FromEuler(ozz::math::simd_float4::Load(0.f, 0.f, 0.f, 0.f));
|
||||
EXPECT_FLOAT4x4_EQ(euler_identity, 1.f, 0.f, 0.f, 0.f, 0.f, 1.f, 0.f, 0.f,
|
||||
0.f, 0.f, 1.f, 0.f, 0.f, 0.f, 0.f, 1.f);
|
||||
|
||||
const Float4x4 euler = Float4x4::FromEuler(
|
||||
ozz::math::simd_float4::Load(ozz::math::kPi_2, 0.f, 0.f, 0.f));
|
||||
EXPECT_FLOAT4x4_EQ(euler, 0.f, 0.f, 1.f, 0.f, 0.f, 1.f, 0.f, 0.f, -1.f, 0.f,
|
||||
0.f, 0.f, 0.f, 0.f, 0.f, 1.f);
|
||||
EXPECT_TRUE(ozz::math::AreAllTrue3(IsNormalized(euler)));
|
||||
EXPECT_TRUE(ozz::math::AreAllTrue1(IsOrthogonal(euler)));
|
||||
|
||||
EXPECT_ASSERTION(Float4x4::FromQuaternion(
|
||||
ozz::math::simd_float4::Load(1.f, 0.f, 0.f, 1.f)),
|
||||
"IsNormalized");
|
||||
const Float4x4 quaternion_identity = Float4x4::FromQuaternion(
|
||||
ozz::math::simd_float4::Load(0.f, 0.f, 0.f, 1.f));
|
||||
EXPECT_FLOAT4x4_EQ(quaternion_identity, 1.f, 0.f, 0.f, 0.f, 0.f, 1.f, 0.f,
|
||||
0.f, 0.f, 0.f, 1.f, 0.f, 0.f, 0.f, 0.f, 1.f);
|
||||
EXPECT_TRUE(ozz::math::AreAllTrue3(IsNormalized(quaternion_identity)));
|
||||
EXPECT_TRUE(ozz::math::AreAllTrue1(IsOrthogonal(quaternion_identity)));
|
||||
|
||||
const Float4x4 quaternion = Float4x4::FromQuaternion(
|
||||
ozz::math::simd_float4::Load(0.f, .70710677f, 0.f, .70710677f));
|
||||
EXPECT_FLOAT4x4_EQ(quaternion, 0.f, 0.f, -1.f, 0.f, 0.f, 1.f, 0.f, 0.f, 1.f,
|
||||
0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 1.f);
|
||||
|
||||
EXPECT_ASSERTION(
|
||||
Float4x4::FromAxisAngle(ozz::math::simd_float4::Load(1.f, 1.f, 0.f, 0.f),
|
||||
ozz::math::simd_float4::zero()),
|
||||
"IsNormalized");
|
||||
const Float4x4 axis_angle_identity = Float4x4::FromAxisAngle(
|
||||
ozz::math::simd_float4::y_axis(), ozz::math::simd_float4::zero());
|
||||
EXPECT_FLOAT4x4_EQ(axis_angle_identity, 1.f, 0.f, 0.f, 0.f, 0.f, 1.f, 0.f,
|
||||
0.f, 0.f, 0.f, 1.f, 0.f, 0.f, 0.f, 0.f, 1.f);
|
||||
|
||||
const Float4x4 axis_angle =
|
||||
Float4x4::FromAxisAngle(ozz::math::simd_float4::y_axis(),
|
||||
ozz::math::simd_float4::LoadX(ozz::math::kPi_2));
|
||||
EXPECT_FLOAT4x4_EQ(axis_angle, 0.f, 0.f, -1.f, 0.f, 0.f, 1.f, 0.f, 0.f, 1.f,
|
||||
0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 1.f);
|
||||
EXPECT_TRUE(ozz::math::AreAllTrue3(IsNormalized(axis_angle)));
|
||||
EXPECT_TRUE(ozz::math::AreAllTrue1(IsOrthogonal(axis_angle)));
|
||||
}
|
||||
|
||||
TEST(Float4x4Affine, ozz_simd_math) {
|
||||
EXPECT_ASSERTION(
|
||||
Float4x4::FromAffine(ozz::math::simd_float4::Load(0.f, 0.f, 0.f, 0.f),
|
||||
ozz::math::simd_float4::Load(0.f, 1.f, 0.f, 1.f),
|
||||
ozz::math::simd_float4::Load(1.f, 1.f, 1.f, 1.f)),
|
||||
"IsNormalized");
|
||||
|
||||
const Float4x4 identity =
|
||||
Float4x4::FromAffine(ozz::math::simd_float4::Load(0.f, 0.f, 0.f, 0.f),
|
||||
ozz::math::simd_float4::Load(0.f, 0.f, 0.f, 1.f),
|
||||
ozz::math::simd_float4::Load(1.f, 1.f, 1.f, 1.f));
|
||||
EXPECT_FLOAT4x4_EQ(identity, 1.f, 0.f, 0.f, 0.f, 0.f, 1.f, 0.f, 0.f, 0.f, 0.f,
|
||||
1.f, 0.f, 0.f, 0.f, 0.f, 1.f);
|
||||
|
||||
const Float4x4 affine = Float4x4::FromAffine(
|
||||
ozz::math::simd_float4::Load(-12.f, 46.f, 12.f, 9.f),
|
||||
ozz::math::simd_float4::Load(0.f, .70710677f, 0.f, .70710677f),
|
||||
ozz::math::simd_float4::Load(2.f, 46.f, 3.f, 1.f));
|
||||
EXPECT_FLOAT4x4_EQ(affine, 0.f, 0.f, -2.f, 0.f, 0.f, 46.f, 0.f, 0.f, 3.f, 0.f,
|
||||
0.f, 0.f, -12.f, 46.f, 12.f, 1.f);
|
||||
EXPECT_FALSE(ozz::math::AreAllTrue3(IsNormalized(affine)));
|
||||
EXPECT_TRUE(ozz::math::AreAllTrue1(IsOrthogonal(affine)));
|
||||
|
||||
const Float4x4 affine_reflexion = Float4x4::FromAffine(
|
||||
ozz::math::simd_float4::Load(-12.f, 46.f, 12.f, 9.f),
|
||||
ozz::math::simd_float4::Load(0.f, .70710677f, 0.f, .70710677f),
|
||||
ozz::math::simd_float4::Load(2.f, -1.f, 3.f, 1.f));
|
||||
EXPECT_FLOAT4x4_EQ(affine_reflexion, 0.f, 0.f, -2.f, 0.f, 0.f, -1.f, 0.f, 0.f,
|
||||
3.f, 0.f, 0.f, 0.f, -12.f, 46.f, 12.f, 1.f);
|
||||
EXPECT_FALSE(ozz::math::AreAllTrue3(IsNormalized(affine_reflexion)));
|
||||
EXPECT_FALSE(ozz::math::AreAllTrue1(IsOrthogonal(affine_reflexion)));
|
||||
}
|
||||
|
||||
TEST(Float4x4ToQuaternion, ozz_simd_math) {
|
||||
#ifndef NDEBUG
|
||||
const Float4x4 not_normalized = {
|
||||
{ozz::math::simd_float4::Load(1.1f, 0.f, 0.f, 0.f),
|
||||
ozz::math::simd_float4::Load(0.f, 1.f, 0.f, 0.f),
|
||||
ozz::math::simd_float4::Load(0.f, 0.f, 1.f, 0.f),
|
||||
ozz::math::simd_float4::Load(0.f, 0.f, 0.f, 1.f)}};
|
||||
const Float4x4 not_orthogonal = {
|
||||
{ozz::math::simd_float4::Load(1.f, 0.f, 0.f, 0.f),
|
||||
ozz::math::simd_float4::Load(1.f, 0.f, 0.f, 0.f),
|
||||
ozz::math::simd_float4::Load(0.f, 0.f, 1.f, 0.f),
|
||||
ozz::math::simd_float4::Load(0.f, 0.f, 0.f, 1.f)}};
|
||||
#endif // NDEBUG
|
||||
|
||||
EXPECT_ASSERTION(ToQuaternion(not_normalized), "IsNormalized");
|
||||
EXPECT_ASSERTION(ToQuaternion(not_orthogonal), "IsOrthogonal");
|
||||
EXPECT_SIMDFLOAT_EQ(ToQuaternion(Float4x4::identity()), 0.f, 0.f, 0.f, 1.f);
|
||||
EXPECT_SIMDFLOAT_EQ(ToQuaternion(Float4x4::FromQuaternion(
|
||||
ozz::math::simd_float4::Load(0.f, 0.f, 1.f, 0.f))),
|
||||
0.f, 0.f, 1.f, 0.f);
|
||||
EXPECT_SIMDFLOAT_EQ(ToQuaternion(Float4x4::FromQuaternion(
|
||||
ozz::math::simd_float4::Load(0.f, 1.f, 0.f, 0.f))),
|
||||
0.f, 1.f, 0.f, 0.f);
|
||||
EXPECT_SIMDFLOAT_EQ(ToQuaternion(Float4x4::FromQuaternion(
|
||||
ozz::math::simd_float4::Load(1.f, 0.f, 0.f, 0.f))),
|
||||
1.f, 0.f, 0.f, 0.f);
|
||||
EXPECT_SIMDFLOAT_EQ(
|
||||
ToQuaternion(Float4x4::FromQuaternion(
|
||||
ozz::math::simd_float4::Load(.70710677f, 0.f, 0.f, .70710677f))),
|
||||
.70710677f, 0.f, 0.f, .70710677f);
|
||||
EXPECT_SIMDFLOAT_EQ(
|
||||
ToQuaternion(Float4x4::FromQuaternion(ozz::math::simd_float4::Load(
|
||||
.4365425f, .017589169f, -.30435428f, .84645736f))),
|
||||
.4365425f, .017589169f, -.30435428f, .84645736f);
|
||||
EXPECT_SIMDFLOAT_EQ(
|
||||
ToQuaternion(Float4x4::FromQuaternion(ozz::math::simd_float4::Load(
|
||||
.56098551f, -.092295974f, 0.43045932f, .70105737f))),
|
||||
.56098551f, -.092295974f, 0.43045932f, .70105737f);
|
||||
EXPECT_SIMDFLOAT_EQ(
|
||||
ToQuaternion(Float4x4::FromQuaternion(ozz::math::simd_float4::Load(
|
||||
-.6172133f, -.1543033f, 0.f, .7715167f))),
|
||||
-.6172133f, -.1543033f, 0.f, .7715167f);
|
||||
}
|
||||
|
||||
TEST(Float4x4ToAffine, ozz_simd_math) {
|
||||
SimdFloat4 translate = ozz::math::simd_float4::zero();
|
||||
SimdFloat4 rotate = ozz::math::simd_float4::zero();
|
||||
SimdFloat4 scale = ozz::math::simd_float4::zero();
|
||||
|
||||
EXPECT_FALSE(ToAffine(
|
||||
Float4x4::Scaling(ozz::math::simd_float4::Load(0.f, 0.f, 1.f, 0.f)),
|
||||
&translate, &rotate, &scale));
|
||||
EXPECT_FALSE(ToAffine(
|
||||
Float4x4::Scaling(ozz::math::simd_float4::Load(1.f, 0.f, 0.f, 0.f)),
|
||||
&translate, &rotate, &scale));
|
||||
EXPECT_FALSE(ToAffine(
|
||||
Float4x4::Scaling(ozz::math::simd_float4::Load(0.f, 1.f, 0.f, 0.f)),
|
||||
&translate, &rotate, &scale));
|
||||
|
||||
EXPECT_TRUE(ToAffine(Float4x4::identity(), &translate, &rotate, &scale));
|
||||
EXPECT_SIMDFLOAT_EQ(translate, 0.f, 0.f, 0.f, 1.f);
|
||||
EXPECT_SIMDFLOAT_EQ(rotate, 0.f, 0.f, 0.f, 1.f);
|
||||
EXPECT_SIMDFLOAT_EQ(scale, 1.f, 1.f, 1.f, 1.f);
|
||||
|
||||
EXPECT_TRUE(ToAffine(
|
||||
Float4x4::Scaling(ozz::math::simd_float4::Load(0.f, 1.f, 1.f, 0.f)),
|
||||
&translate, &rotate, &scale));
|
||||
EXPECT_SIMDFLOAT_EQ(translate, 0.f, 0.f, 0.f, 1.f);
|
||||
EXPECT_SIMDFLOAT_EQ(rotate, 0.f, 0.f, 0.f, 1.f);
|
||||
EXPECT_SIMDFLOAT_EQ(scale, 0.f, 1.f, 1.f, 1.f);
|
||||
|
||||
EXPECT_TRUE(ToAffine(
|
||||
Float4x4::Scaling(ozz::math::simd_float4::Load(1.f, 0.f, 1.f, 0.f)),
|
||||
&translate, &rotate, &scale));
|
||||
EXPECT_SIMDFLOAT_EQ(translate, 0.f, 0.f, 0.f, 1.f);
|
||||
EXPECT_SIMDFLOAT_EQ(rotate, 0.f, 0.f, 0.f, 1.f);
|
||||
EXPECT_SIMDFLOAT_EQ(scale, 1.f, 0.f, 1.f, 1.f);
|
||||
|
||||
EXPECT_TRUE(ToAffine(
|
||||
Float4x4::Scaling(ozz::math::simd_float4::Load(1.f, 1.f, 0.f, 0.f)),
|
||||
&translate, &rotate, &scale));
|
||||
EXPECT_SIMDFLOAT_EQ(translate, 0.f, 0.f, 0.f, 1.f);
|
||||
EXPECT_SIMDFLOAT_EQ(rotate, 0.f, 0.f, 0.f, 1.f);
|
||||
EXPECT_SIMDFLOAT_EQ(scale, 1.f, 1.f, 0.f, 1.f);
|
||||
|
||||
EXPECT_TRUE(ToAffine(
|
||||
Float4x4::Translation(
|
||||
ozz::math::simd_float4::Load(46.f, 69.f, 58.f, 1.f)) *
|
||||
Float4x4::Scaling(ozz::math::simd_float4::Load(2.f, 3.f, 4.f, 0.f)),
|
||||
&translate, &rotate, &scale));
|
||||
EXPECT_SIMDFLOAT_EQ(translate, 46.f, 69.f, 58.f, 1.f);
|
||||
EXPECT_SIMDFLOAT_EQ(rotate, 0.f, 0.f, 0.f, 1.f);
|
||||
EXPECT_SIMDFLOAT_EQ(scale, 2.f, 3.f, 4.f, 1.f);
|
||||
|
||||
EXPECT_TRUE(ToAffine(
|
||||
Float4x4::Translation(
|
||||
ozz::math::simd_float4::Load(46.f, -69.f, -58.f, 1.f)) *
|
||||
Float4x4::Scaling(ozz::math::simd_float4::Load(-2.f, 3.f, 4.f, 0.f)),
|
||||
&translate, &rotate, &scale));
|
||||
EXPECT_SIMDFLOAT_EQ(translate, 46.f, -69.f, -58.f, 1.f);
|
||||
EXPECT_SIMDFLOAT_EQ(rotate, 0.f, 0.f, 1.f, 0.f);
|
||||
EXPECT_SIMDFLOAT_EQ(scale, 2.f, -3.f, 4.f, 1.f);
|
||||
|
||||
EXPECT_TRUE(ToAffine(
|
||||
Float4x4::Scaling(ozz::math::simd_float4::Load(2.f, -3.f, 4.f, 0.f)),
|
||||
&translate, &rotate, &scale));
|
||||
EXPECT_SIMDFLOAT_EQ(translate, 0.f, 0.f, 0.f, 1.f);
|
||||
EXPECT_SIMDFLOAT_EQ(rotate, 0.f, 0.f, 0.f, 1.f);
|
||||
EXPECT_SIMDFLOAT_EQ(scale, 2.f, -3.f, 4.f, 1.f);
|
||||
|
||||
EXPECT_TRUE(ToAffine(
|
||||
Float4x4::Scaling(ozz::math::simd_float4::Load(2.f, 3.f, -4.f, 0.f)),
|
||||
&translate, &rotate, &scale));
|
||||
EXPECT_SIMDFLOAT_EQ(translate, 0.f, 0.f, 0.f, 1.f);
|
||||
EXPECT_SIMDFLOAT_EQ(rotate, 1.f, 0.f, 0.f, 0.f);
|
||||
EXPECT_SIMDFLOAT_EQ(scale, 2.f, -3.f, 4.f, 1.f);
|
||||
|
||||
// This one is not a reflexion.
|
||||
EXPECT_TRUE(ToAffine(
|
||||
Float4x4::Scaling(ozz::math::simd_float4::Load(-2.f, -3.f, 4.f, 0.f)),
|
||||
&translate, &rotate, &scale));
|
||||
EXPECT_SIMDFLOAT_EQ(translate, 0.f, 0.f, 0.f, 1.f);
|
||||
EXPECT_SIMDFLOAT_EQ(rotate, 0.f, 0.f, 1.f, 0.f);
|
||||
EXPECT_SIMDFLOAT_EQ(scale, 2.f, 3.f, 4.f, 1.f);
|
||||
|
||||
// This one is not a reflexion.
|
||||
EXPECT_TRUE(ToAffine(
|
||||
Float4x4::Scaling(ozz::math::simd_float4::Load(2.f, -3.f, -4.f, 0.f)),
|
||||
&translate, &rotate, &scale));
|
||||
EXPECT_SIMDFLOAT_EQ(translate, 0.f, 0.f, 0.f, 1.f);
|
||||
EXPECT_SIMDFLOAT_EQ(rotate, 1.f, 0.f, 0.f, 0.f);
|
||||
EXPECT_SIMDFLOAT_EQ(scale, 2.f, 3.f, 4.f, 1.f);
|
||||
|
||||
EXPECT_TRUE(ToAffine(
|
||||
Float4x4::Translation(
|
||||
ozz::math::simd_float4::Load(46.f, -69.f, -58.f, 1.f)) *
|
||||
Float4x4::FromQuaternion(ozz::math::simd_float4::Load(
|
||||
-.6172133f, -.1543033f, 0.f, .7715167f)) *
|
||||
Float4x4::Scaling(ozz::math::simd_float4::Load(2.f, 3.f, 4.f, 0.f)),
|
||||
&translate, &rotate, &scale));
|
||||
EXPECT_SIMDFLOAT_EQ(translate, 46.f, -69.f, -58.f, 1.f);
|
||||
EXPECT_SIMDFLOAT_EQ(rotate, -.6172133f, -.1543033f, 0.f, .7715167f);
|
||||
EXPECT_SIMDFLOAT_EQ(scale, 2.f, 3.f, 4.f, 1.f);
|
||||
|
||||
EXPECT_TRUE(ToAffine(
|
||||
Float4x4::Translation(
|
||||
ozz::math::simd_float4::Load(46.f, -69.f, -58.f, 1.f)) *
|
||||
Float4x4::FromQuaternion(
|
||||
ozz::math::simd_float4::Load(.70710677f, 0.f, 0.f, .70710677f)) *
|
||||
Float4x4::Scaling(ozz::math::simd_float4::Load(2.f, -3.f, 4.f, 0.f)),
|
||||
&translate, &rotate, &scale));
|
||||
EXPECT_SIMDFLOAT_EQ(translate, 46.f, -69.f, -58.f, 1.f);
|
||||
EXPECT_SIMDFLOAT_EQ(rotate, .70710677f, 0.f, 0.f, .70710677f);
|
||||
EXPECT_SIMDFLOAT_EQ(scale, 2.f, -3.f, 4.f, 1.f);
|
||||
|
||||
const Float4x4 trace = {
|
||||
{ozz::math::simd_float4::Load(-.916972f, 0.f, -.398952f, 0.f),
|
||||
ozz::math::simd_float4::Load(0.f, -1, 0.f, 0.f),
|
||||
ozz::math::simd_float4::Load(-.398952f, 0, .916972f, 0.f),
|
||||
ozz::math::simd_float4::Load(0.f, 0.f, 0.f, 1.f)}};
|
||||
EXPECT_TRUE(ToAffine(trace, &translate, &rotate, &scale));
|
||||
EXPECT_SIMDFLOAT_EQ(translate, 0.f, 0.f, 0.f, 1.f);
|
||||
EXPECT_SIMDFLOAT_EQ(rotate, -.20375007f, 0.f, .97902298f, 0.f);
|
||||
EXPECT_SIMDFLOAT_EQ(scale, 1.f, 1.f, 1.f, 1.f);
|
||||
|
||||
const Float4x4 small = {
|
||||
{ozz::math::simd_float4::Load(.000907520065f, 0.f, 0.f, 0.f),
|
||||
ozz::math::simd_float4::Load(0.f, .000959928846f, 0.f, 0.f),
|
||||
ozz::math::simd_float4::Load(0.f, 0.f, .0159599986f, 0.f),
|
||||
ozz::math::simd_float4::Load(.00649994006f, .00719946623f,
|
||||
-.000424541620f, .999999940f)}};
|
||||
EXPECT_TRUE(ToAffine(small, &translate, &rotate, &scale));
|
||||
EXPECT_SIMDFLOAT_EQ(translate, .00649994006f, .00719946623f, -.000424541620f,
|
||||
1.f);
|
||||
EXPECT_SIMDFLOAT_EQ(rotate, 0.f, 0.f, 0.f, 1.f);
|
||||
EXPECT_SIMDFLOAT_EQ(scale, .000907520065f, .000959928846f, .0159599986f, 1.f);
|
||||
}
|
||||
@@ -0,0 +1,839 @@
|
||||
//----------------------------------------------------------------------------//
|
||||
// //
|
||||
// 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_math.h"
|
||||
|
||||
#include <stdint.h>
|
||||
#include <cmath>
|
||||
#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::SimdFloat4;
|
||||
using ozz::math::SimdInt4;
|
||||
|
||||
static_assert(sizeof(SimdFloat4) == 4 * sizeof(float),
|
||||
"Expects SimdFloat4 to be the size of 4 floats.");
|
||||
static_assert(alignof(SimdFloat4) == 16,
|
||||
"Expects SimdFloat4 to be the size of 16 bytes.");
|
||||
|
||||
TEST(Name, ozz_simd_math) {
|
||||
EXPECT_TRUE(ozz::math::SimdImplementationName() != nullptr);
|
||||
}
|
||||
|
||||
TEST(LoadFloat, ozz_simd_math) {
|
||||
const SimdFloat4 fX = ozz::math::simd_float4::LoadX(15.f);
|
||||
EXPECT_SIMDFLOAT_EQ(fX, 15.f, 0.f, 0.f, 0.f);
|
||||
|
||||
const SimdFloat4 f1 = ozz::math::simd_float4::Load1(15.f);
|
||||
EXPECT_SIMDFLOAT_EQ(f1, 15.f, 15.f, 15.f, 15.f);
|
||||
|
||||
const SimdFloat4 f4 = ozz::math::simd_float4::Load(1.f, -1.f, 2.f, -3.f);
|
||||
EXPECT_SIMDFLOAT_EQ(f4, 1.f, -1.f, 2.f, -3.f);
|
||||
}
|
||||
|
||||
TEST(LoadFloatPtr, ozz_simd_math) {
|
||||
union Data {
|
||||
float f[4 + 5];
|
||||
char c[(4 + 5) * sizeof(float)]; // The 2nd char isn't aligned to a float.
|
||||
};
|
||||
const Data d_in = {{-1.f, 1.f, 2.f, 3.f, 4.f, 5.f, 6.f, 7.f, 8.f}};
|
||||
const int aligned_offset =
|
||||
(16 - (reinterpret_cast<intptr_t>(d_in.f) & 0xf)) / sizeof(float);
|
||||
assert(aligned_offset > 0 && aligned_offset <= 4);
|
||||
|
||||
EXPECT_SIMDFLOAT_EQ(ozz::math::simd_float4::LoadPtr(d_in.f + aligned_offset),
|
||||
d_in.f[aligned_offset + 0], d_in.f[aligned_offset + 1],
|
||||
d_in.f[aligned_offset + 2], d_in.f[aligned_offset + 3]);
|
||||
EXPECT_ASSERTION(ozz::math::simd_float4::LoadPtr(d_in.f + aligned_offset - 1),
|
||||
"alignment");
|
||||
|
||||
EXPECT_SIMDFLOAT_EQ(
|
||||
ozz::math::simd_float4::LoadPtrU(d_in.f + aligned_offset + 1),
|
||||
d_in.f[aligned_offset + 1], d_in.f[aligned_offset + 2],
|
||||
d_in.f[aligned_offset + 3], d_in.f[aligned_offset + 4]);
|
||||
EXPECT_ASSERTION(ozz::math::simd_float4::LoadPtrU(
|
||||
reinterpret_cast<const float*>(d_in.c + 1)),
|
||||
"alignment");
|
||||
EXPECT_SIMDFLOAT_EQ(
|
||||
ozz::math::simd_float4::LoadXPtrU(d_in.f + aligned_offset + 1),
|
||||
d_in.f[aligned_offset + 1], 0.f, 0.f, 0.f);
|
||||
EXPECT_ASSERTION(ozz::math::simd_float4::LoadXPtrU(
|
||||
reinterpret_cast<const float*>(d_in.c + 1)),
|
||||
"alignment");
|
||||
EXPECT_SIMDFLOAT_EQ(
|
||||
ozz::math::simd_float4::Load1PtrU(d_in.f + aligned_offset + 1),
|
||||
d_in.f[aligned_offset + 1], d_in.f[aligned_offset + 1],
|
||||
d_in.f[aligned_offset + 1], d_in.f[aligned_offset + 1]);
|
||||
EXPECT_ASSERTION(ozz::math::simd_float4::Load1PtrU(
|
||||
reinterpret_cast<const float*>(d_in.c + 1)),
|
||||
"alignment");
|
||||
EXPECT_SIMDFLOAT_EQ(
|
||||
ozz::math::simd_float4::Load2PtrU(d_in.f + aligned_offset + 1),
|
||||
d_in.f[aligned_offset + 1], d_in.f[aligned_offset + 2], 0.f, 0.f);
|
||||
EXPECT_ASSERTION(ozz::math::simd_float4::Load2PtrU(
|
||||
reinterpret_cast<const float*>(d_in.c + 1)),
|
||||
"alignment");
|
||||
EXPECT_SIMDFLOAT_EQ(
|
||||
ozz::math::simd_float4::Load3PtrU(d_in.f + aligned_offset + 1),
|
||||
d_in.f[aligned_offset + 1], d_in.f[aligned_offset + 2],
|
||||
d_in.f[aligned_offset + 3], 0.f);
|
||||
EXPECT_ASSERTION(ozz::math::simd_float4::Load3PtrU(
|
||||
reinterpret_cast<const float*>(d_in.c + 1)),
|
||||
"alignment");
|
||||
}
|
||||
|
||||
TEST(GetFloat, ozz_simd_math) {
|
||||
const SimdFloat4 f = ozz::math::simd_float4::Load(1.f, 2.f, 3.f, 4.f);
|
||||
|
||||
EXPECT_FLOAT_EQ(ozz::math::GetX(f), 1.f);
|
||||
EXPECT_FLOAT_EQ(ozz::math::GetY(f), 2.f);
|
||||
EXPECT_FLOAT_EQ(ozz::math::GetZ(f), 3.f);
|
||||
EXPECT_FLOAT_EQ(ozz::math::GetW(f), 4.f);
|
||||
}
|
||||
|
||||
TEST(SetFloat, ozz_simd_math) {
|
||||
const SimdFloat4 a = ozz::math::simd_float4::Load(1.f, 2.f, 3.f, 4.f);
|
||||
const SimdFloat4 b = ozz::math::simd_float4::Load(5.f, 6.f, 7.f, 8.f);
|
||||
|
||||
EXPECT_SIMDFLOAT_EQ(ozz::math::SetX(a, b), 5.f, 2.f, 3.f, 4.f);
|
||||
EXPECT_SIMDFLOAT_EQ(ozz::math::SetY(a, b), 1.f, 5.f, 3.f, 4.f);
|
||||
EXPECT_SIMDFLOAT_EQ(ozz::math::SetZ(a, b), 1.f, 2.f, 5.f, 4.f);
|
||||
EXPECT_SIMDFLOAT_EQ(ozz::math::SetW(a, b), 1.f, 2.f, 3.f, 5.f);
|
||||
|
||||
EXPECT_ASSERTION(ozz::math::SetI(a, b, 4), "Invalid index, out of range.");
|
||||
EXPECT_SIMDFLOAT_EQ(ozz::math::SetI(a, b, 0), 5.f, 2.f, 3.f, 4.f);
|
||||
EXPECT_SIMDFLOAT_EQ(ozz::math::SetI(a, b, 1), 1.f, 5.f, 3.f, 4.f);
|
||||
EXPECT_SIMDFLOAT_EQ(ozz::math::SetI(a, b, 2), 1.f, 2.f, 5.f, 4.f);
|
||||
EXPECT_SIMDFLOAT_EQ(ozz::math::SetI(a, b, 3), 1.f, 2.f, 3.f, 5.f);
|
||||
}
|
||||
|
||||
TEST(StoreFloatPtr, ozz_simd_math) {
|
||||
const SimdFloat4 f4 = ozz::math::simd_float4::Load(-1.f, 1.f, 2.f, 3.f);
|
||||
|
||||
union Data {
|
||||
float f[4 + 4]; // The 2nd float isn't aligned to a SimdFloat4.
|
||||
SimdFloat4 f4[2]; // Forces alignment.
|
||||
char c[(4 + 4) * sizeof(float)]; // The 2nd char isn't aligned to a float.
|
||||
};
|
||||
|
||||
{
|
||||
Data d_out = {};
|
||||
ozz::math::StorePtrU(f4, d_out.f + 1);
|
||||
EXPECT_FLOAT_EQ(d_out.f[0], 0.f);
|
||||
EXPECT_FLOAT_EQ(d_out.f[1], -1.f);
|
||||
EXPECT_FLOAT_EQ(d_out.f[2], 1.f);
|
||||
EXPECT_FLOAT_EQ(d_out.f[3], 2.f);
|
||||
EXPECT_FLOAT_EQ(d_out.f[4], 3.f);
|
||||
EXPECT_ASSERTION(
|
||||
ozz::math::StorePtrU(f4, reinterpret_cast<float*>(d_out.c + 1)),
|
||||
"alignment");
|
||||
}
|
||||
{
|
||||
Data d_out = {};
|
||||
ozz::math::Store1PtrU(f4, d_out.f + 1);
|
||||
EXPECT_FLOAT_EQ(d_out.f[0], 0.f);
|
||||
EXPECT_FLOAT_EQ(d_out.f[1], -1.f);
|
||||
EXPECT_FLOAT_EQ(d_out.f[2], 0.f);
|
||||
EXPECT_FLOAT_EQ(d_out.f[3], 0.f);
|
||||
EXPECT_FLOAT_EQ(d_out.f[4], 0.f);
|
||||
EXPECT_ASSERTION(
|
||||
ozz::math::Store1PtrU(f4, reinterpret_cast<float*>(d_out.c + 1)),
|
||||
"alignment");
|
||||
}
|
||||
{
|
||||
Data d_out = {};
|
||||
ozz::math::Store2PtrU(f4, d_out.f + 1);
|
||||
EXPECT_FLOAT_EQ(d_out.f[0], 0.f);
|
||||
EXPECT_FLOAT_EQ(d_out.f[1], -1.f);
|
||||
EXPECT_FLOAT_EQ(d_out.f[2], 1.f);
|
||||
EXPECT_FLOAT_EQ(d_out.f[3], 0.f);
|
||||
EXPECT_FLOAT_EQ(d_out.f[4], 0.f);
|
||||
EXPECT_ASSERTION(
|
||||
ozz::math::Store2Ptr(f4, reinterpret_cast<float*>(d_out.c + 1)),
|
||||
"alignment");
|
||||
}
|
||||
{
|
||||
Data d_out = {};
|
||||
ozz::math::Store3PtrU(f4, d_out.f + 1);
|
||||
EXPECT_FLOAT_EQ(d_out.f[0], 0.f);
|
||||
EXPECT_FLOAT_EQ(d_out.f[1], -1.f);
|
||||
EXPECT_FLOAT_EQ(d_out.f[2], 1.f);
|
||||
EXPECT_FLOAT_EQ(d_out.f[3], 2.f);
|
||||
EXPECT_FLOAT_EQ(d_out.f[4], 0.f);
|
||||
EXPECT_ASSERTION(
|
||||
ozz::math::Store3Ptr(f4, reinterpret_cast<float*>(d_out.c + 1)),
|
||||
"alignment");
|
||||
}
|
||||
{
|
||||
Data d_out = {};
|
||||
ozz::math::StorePtr(f4, d_out.f);
|
||||
EXPECT_FLOAT_EQ(d_out.f[0], -1.f);
|
||||
EXPECT_FLOAT_EQ(d_out.f[1], 1.f);
|
||||
EXPECT_FLOAT_EQ(d_out.f[2], 2.f);
|
||||
EXPECT_FLOAT_EQ(d_out.f[3], 3.f);
|
||||
EXPECT_FLOAT_EQ(d_out.f[4], 0.f);
|
||||
EXPECT_ASSERTION(ozz::math::StorePtr(f4, d_out.f + 1), "alignment");
|
||||
}
|
||||
{
|
||||
Data d_out = {};
|
||||
ozz::math::Store1Ptr(f4, d_out.f);
|
||||
EXPECT_FLOAT_EQ(d_out.f[0], -1.f);
|
||||
EXPECT_FLOAT_EQ(d_out.f[1], 0.f);
|
||||
EXPECT_FLOAT_EQ(d_out.f[2], 0.f);
|
||||
EXPECT_FLOAT_EQ(d_out.f[3], 0.f);
|
||||
EXPECT_FLOAT_EQ(d_out.f[4], 0.f);
|
||||
EXPECT_ASSERTION(ozz::math::Store1Ptr(f4, d_out.f + 1), "alignment");
|
||||
}
|
||||
{
|
||||
Data d_out = {};
|
||||
ozz::math::Store2Ptr(f4, d_out.f);
|
||||
EXPECT_FLOAT_EQ(d_out.f[0], -1.f);
|
||||
EXPECT_FLOAT_EQ(d_out.f[1], 1.f);
|
||||
EXPECT_FLOAT_EQ(d_out.f[2], 0.f);
|
||||
EXPECT_FLOAT_EQ(d_out.f[3], 0.f);
|
||||
EXPECT_FLOAT_EQ(d_out.f[4], 0.f);
|
||||
EXPECT_ASSERTION(ozz::math::Store2Ptr(f4, d_out.f + 1), "alignment");
|
||||
}
|
||||
{
|
||||
Data d_out = {};
|
||||
ozz::math::Store3Ptr(f4, d_out.f);
|
||||
EXPECT_FLOAT_EQ(d_out.f[0], -1.f);
|
||||
EXPECT_FLOAT_EQ(d_out.f[1], 1.f);
|
||||
EXPECT_FLOAT_EQ(d_out.f[2], 2.f);
|
||||
EXPECT_FLOAT_EQ(d_out.f[3], 0.f);
|
||||
EXPECT_FLOAT_EQ(d_out.f[4], 0.f);
|
||||
EXPECT_ASSERTION(ozz::math::Store3Ptr(f4, d_out.f + 1), "alignment");
|
||||
}
|
||||
}
|
||||
|
||||
TEST(ConstantFloat, ozz_simd_math) {
|
||||
const SimdFloat4 zero = ozz::math::simd_float4::zero();
|
||||
EXPECT_SIMDFLOAT_EQ(zero, 0.f, 0.f, 0.f, 0.f);
|
||||
|
||||
const SimdFloat4 one = ozz::math::simd_float4::one();
|
||||
EXPECT_SIMDFLOAT_EQ(one, 1.f, 1.f, 1.f, 1.f);
|
||||
|
||||
const SimdFloat4 x_axis = ozz::math::simd_float4::x_axis();
|
||||
EXPECT_SIMDFLOAT_EQ(x_axis, 1.f, 0.f, 0.f, 0.f);
|
||||
|
||||
const SimdFloat4 y_axis = ozz::math::simd_float4::y_axis();
|
||||
EXPECT_SIMDFLOAT_EQ(y_axis, 0.f, 1.f, 0.f, 0.f);
|
||||
|
||||
const SimdFloat4 z_axis = ozz::math::simd_float4::z_axis();
|
||||
EXPECT_SIMDFLOAT_EQ(z_axis, 0.f, 0.f, 1.f, 0.f);
|
||||
|
||||
const SimdFloat4 w_axis = ozz::math::simd_float4::w_axis();
|
||||
EXPECT_SIMDFLOAT_EQ(w_axis, 0.f, 0.f, 0.f, 1.f);
|
||||
}
|
||||
|
||||
TEST(SplatFloat, ozz_simd_math) {
|
||||
const SimdFloat4 f = ozz::math::simd_float4::Load(1.f, -1.f, 2.f, -3.f);
|
||||
|
||||
const SimdFloat4 x = ozz::math::SplatX(f);
|
||||
EXPECT_SIMDFLOAT_EQ(x, 1.f, 1.f, 1.f, 1.f);
|
||||
|
||||
const SimdFloat4 y = ozz::math::SplatY(f);
|
||||
EXPECT_SIMDFLOAT_EQ(y, -1.f, -1.f, -1.f, -1.f);
|
||||
|
||||
const SimdFloat4 z = ozz::math::SplatZ(f);
|
||||
EXPECT_SIMDFLOAT_EQ(z, 2.f, 2.f, 2.f, 2.f);
|
||||
|
||||
const SimdFloat4 w = ozz::math::SplatW(f);
|
||||
EXPECT_SIMDFLOAT_EQ(w, -3.f, -3.f, -3.f, -3.f);
|
||||
|
||||
const SimdFloat4 s3210 = ozz::math::Swizzle<3, 2, 1, 0>(f);
|
||||
EXPECT_SIMDFLOAT_EQ(s3210, -3.f, 2.f, -1.f, 1.f);
|
||||
|
||||
const SimdFloat4 s0123 = ozz::math::Swizzle<0, 1, 2, 3>(f);
|
||||
EXPECT_SIMDFLOAT_EQ(s0123, 1.f, -1.f, 2.f, -3.f);
|
||||
|
||||
const SimdFloat4 s0011 = ozz::math::Swizzle<0, 0, 1, 1>(f);
|
||||
EXPECT_SIMDFLOAT_EQ(s0011, 1.f, 1.f, -1.f, -1.f);
|
||||
|
||||
const SimdFloat4 s2233 = ozz::math::Swizzle<2, 2, 3, 3>(f);
|
||||
EXPECT_SIMDFLOAT_EQ(s2233, 2.f, 2.f, -3.f, -3.f);
|
||||
|
||||
const SimdFloat4 s0101 = ozz::math::Swizzle<0, 1, 0, 1>(f);
|
||||
EXPECT_SIMDFLOAT_EQ(s0101, 1.f, -1.f, 1.f, -1.f);
|
||||
|
||||
const SimdFloat4 s2323 = ozz::math::Swizzle<2, 3, 2, 3>(f);
|
||||
EXPECT_SIMDFLOAT_EQ(s2323, 2.f, -3.f, 2.f, -3.f);
|
||||
}
|
||||
|
||||
TEST(FromInt, ozz_simd_math) {
|
||||
const ozz::math::SimdInt4 i = ozz::math::simd_int4::Load(0, 46, -93, 9926429);
|
||||
EXPECT_SIMDFLOAT_EQ(ozz::math::simd_float4::FromInt(i), 0.f, 46.f, -93.f,
|
||||
9926429.f);
|
||||
}
|
||||
|
||||
TEST(ArithmeticFloat, ozz_simd_math) {
|
||||
const ozz::math::SimdFloat4 a =
|
||||
ozz::math::simd_float4::Load(0.5f, 1.f, 2.f, 3.f);
|
||||
const ozz::math::SimdFloat4 b =
|
||||
ozz::math::simd_float4::Load(4.f, 5.f, -6.f, 0.f);
|
||||
const ozz::math::SimdFloat4 c =
|
||||
ozz::math::simd_float4::Load(-8.f, 9.f, 10.f, 11.f);
|
||||
|
||||
const ozz::math::SimdFloat4 add = a + b;
|
||||
EXPECT_SIMDFLOAT_EQ(add, 4.5f, 6.f, -4.f, 3.f);
|
||||
|
||||
const ozz::math::SimdFloat4 sub = a - b;
|
||||
EXPECT_SIMDFLOAT_EQ(sub, -3.5f, -4.f, 8.f, 3.f);
|
||||
|
||||
const ozz::math::SimdFloat4 neg = -b;
|
||||
EXPECT_SIMDFLOAT_EQ(neg, -4.f, -5.f, 6.f, -0.f);
|
||||
|
||||
const ozz::math::SimdFloat4 mul = a * b;
|
||||
EXPECT_SIMDFLOAT_EQ(mul, 2.f, 5.f, -12.f, 0.f);
|
||||
|
||||
const ozz::math::SimdFloat4 div = a / b;
|
||||
EXPECT_SIMDFLOAT3_EQ(div, 0.5f / 4.f, 1.f / 5.f, -2.f / 6.f);
|
||||
|
||||
const ozz::math::SimdFloat4 madd = ozz::math::MAdd(a, b, c);
|
||||
EXPECT_SIMDFLOAT_EQ(madd, -6.f, 14.f, -2.f, 11.f);
|
||||
|
||||
const ozz::math::SimdFloat4 msub = ozz::math::MSub(a, b, c);
|
||||
EXPECT_SIMDFLOAT_EQ(msub, 10.f, -4.f, -22.f, -11.f);
|
||||
|
||||
const ozz::math::SimdFloat4 nmadd = ozz::math::NMAdd(a, b, c);
|
||||
EXPECT_SIMDFLOAT_EQ(nmadd, -10.f, 4.f, 22.f, 11.f);
|
||||
|
||||
const ozz::math::SimdFloat4 nmsub = ozz::math::NMSub(a, b, c);
|
||||
EXPECT_SIMDFLOAT_EQ(nmsub, 6.f, -14.f, 2.f, -11.f);
|
||||
|
||||
const ozz::math::SimdFloat4 divx = ozz::math::DivX(a, b);
|
||||
EXPECT_SIMDFLOAT_EQ(divx, 0.5f / 4.f, 1.f, 2.f, 3.f);
|
||||
|
||||
const ozz::math::SimdFloat4 hadd2 = ozz::math::HAdd2(a);
|
||||
EXPECT_SIMDFLOAT_EQ(hadd2, 1.5f, 1.f, 2.f, 3.f);
|
||||
|
||||
const ozz::math::SimdFloat4 hadd3 = ozz::math::HAdd3(a);
|
||||
EXPECT_SIMDFLOAT_EQ(hadd3, 3.5f, 1.f, 2.f, 3.f);
|
||||
|
||||
const ozz::math::SimdFloat4 hadd4 = ozz::math::HAdd4(a);
|
||||
EXPECT_FLOAT_EQ(ozz::math::GetX(hadd4), 6.5f);
|
||||
|
||||
const ozz::math::SimdFloat4 dot2 = ozz::math::Dot2(a, b);
|
||||
EXPECT_FLOAT_EQ(ozz::math::GetX(dot2), 7.f);
|
||||
|
||||
const ozz::math::SimdFloat4 dot3 = ozz::math::Dot3(a, b);
|
||||
EXPECT_FLOAT_EQ(ozz::math::GetX(dot3), -5.f);
|
||||
|
||||
const ozz::math::SimdFloat4 dot4 = ozz::math::Dot4(a, b);
|
||||
EXPECT_FLOAT_EQ(ozz::math::GetX(dot4), -5.f);
|
||||
|
||||
const ozz::math::SimdFloat4 cross =
|
||||
ozz::math::Cross3(ozz::math::simd_float4::Load(1.f, -2.f, 3.f, 46.f),
|
||||
ozz::math::simd_float4::Load(4.f, 5.f, 6.f, 27.f));
|
||||
EXPECT_FLOAT_EQ(ozz::math::GetX(cross), -27.f);
|
||||
EXPECT_FLOAT_EQ(ozz::math::GetY(cross), 6.f);
|
||||
EXPECT_FLOAT_EQ(ozz::math::GetZ(cross), 13.f);
|
||||
|
||||
const ozz::math::SimdFloat4 rcp = ozz::math::RcpEst(b);
|
||||
EXPECT_SIMDFLOAT3_EQ_EST(rcp, 1.f / 4.f, 1.f / 5.f, -1.f / 6.f);
|
||||
|
||||
const ozz::math::SimdFloat4 rcpnr = ozz::math::RcpEstNR(b);
|
||||
EXPECT_SIMDFLOAT3_EQ(rcpnr, 1.f / 4.f, 1.f / 5.f, -1.f / 6.f);
|
||||
|
||||
const ozz::math::SimdFloat4 rcpxnr = ozz::math::RcpEstXNR(b);
|
||||
EXPECT_FLOAT_EQ(ozz::math::GetX(rcpxnr), 1.f / 4.f);
|
||||
|
||||
const ozz::math::SimdFloat4 rcpx = ozz::math::RcpEstX(b);
|
||||
EXPECT_SIMDFLOAT_EQ_EST(rcpx, 1.f / 4.f, 5.f, -6.f, 0.f);
|
||||
|
||||
const ozz::math::SimdFloat4 sqrt = ozz::math::Sqrt(a);
|
||||
EXPECT_SIMDFLOAT_EQ(sqrt, .7071068f, 1.f, 1.4142135f, 1.7320508f);
|
||||
|
||||
const ozz::math::SimdFloat4 sqrtx = ozz::math::SqrtX(b);
|
||||
EXPECT_SIMDFLOAT_EQ(sqrtx, 2.f, 5.f, -6.f, 0.f);
|
||||
|
||||
const ozz::math::SimdFloat4 rsqrt = ozz::math::RSqrtEst(b);
|
||||
EXPECT_SIMDFLOAT2_EQ_EST(rsqrt, 1.f / 2.f, 1.f / 2.23606798f);
|
||||
|
||||
const ozz::math::SimdFloat4 rsqrtnr = ozz::math::RSqrtEstNR(b);
|
||||
EXPECT_SIMDFLOAT2_EQ_EST(rsqrtnr, 1.f / 2.f, 1.f / 2.23606798f);
|
||||
|
||||
const ozz::math::SimdFloat4 rsqrtx = ozz::math::RSqrtEstX(a);
|
||||
EXPECT_SIMDFLOAT_EQ_EST(rsqrtx, 1.f / .7071068f, 1.f, 2.f, 3.f);
|
||||
|
||||
const ozz::math::SimdFloat4 rsqrtxnr = ozz::math::RSqrtEstXNR(a);
|
||||
EXPECT_FLOAT_EQ(ozz::math::GetX(rsqrtxnr), 1.f / .7071068f);
|
||||
|
||||
const ozz::math::SimdFloat4 abs = ozz::math::Abs(b);
|
||||
EXPECT_SIMDFLOAT_EQ(abs, 4.f, 5.f, 6.f, 0.f);
|
||||
|
||||
const SimdInt4 sign = ozz::math::Sign(b);
|
||||
EXPECT_SIMDINT_EQ(sign, 0, 0, 0x80000000, 0);
|
||||
}
|
||||
|
||||
TEST(LengthFloat, ozz_simd_math) {
|
||||
const SimdFloat4 f = ozz::math::simd_float4::Load(1.f, 2.f, 4.f, 8.f);
|
||||
|
||||
const SimdFloat4 len2 = ozz::math::Length2(f);
|
||||
EXPECT_FLOAT_EQ(ozz::math::GetX(len2), 2.236068f);
|
||||
|
||||
const SimdFloat4 len3 = ozz::math::Length3(f);
|
||||
EXPECT_FLOAT_EQ(ozz::math::GetX(len3), 4.5825758f);
|
||||
|
||||
const SimdFloat4 len4 = ozz::math::Length4(f);
|
||||
EXPECT_FLOAT_EQ(ozz::math::GetX(len4), 9.2195444f);
|
||||
|
||||
const SimdFloat4 len2sqr = ozz::math::Length2Sqr(f);
|
||||
EXPECT_FLOAT_EQ(ozz::math::GetX(len2sqr), 5.f);
|
||||
|
||||
const SimdFloat4 len3sqr = ozz::math::Length3Sqr(f);
|
||||
EXPECT_FLOAT_EQ(ozz::math::GetX(len3sqr), 21.f);
|
||||
|
||||
const SimdFloat4 len4sqr = ozz::math::Length4Sqr(f);
|
||||
EXPECT_FLOAT_EQ(ozz::math::GetX(len4sqr), 85.f);
|
||||
}
|
||||
|
||||
TEST(NormalizeFloat, ozz_simd_math) {
|
||||
const SimdFloat4 f = ozz::math::simd_float4::Load(1.f, 2.f, 4.f, 8.f);
|
||||
const SimdFloat4 unit = ozz::math::simd_float4::x_axis();
|
||||
const SimdFloat4 zero = ozz::math::simd_float4::zero();
|
||||
|
||||
EXPECT_SIMDINT_EQ(ozz::math::IsNormalized2(f), 0, 0, 0, 0);
|
||||
const SimdFloat4 norm2 = ozz::math::Normalize2(f);
|
||||
EXPECT_SIMDFLOAT_EQ(norm2, .44721359f, .89442718f, 4.f, 8.f);
|
||||
EXPECT_SIMDINT_EQ(ozz::math::IsNormalized2(norm2), 0xffffffff, 0, 0, 0);
|
||||
|
||||
const SimdFloat4 norm_est2 = ozz::math::NormalizeEst2(f);
|
||||
EXPECT_SIMDFLOAT_EQ_EST(norm_est2, .44721359f, .89442718f, 4.f, 8.f);
|
||||
EXPECT_SIMDINT_EQ(ozz::math::IsNormalizedEst2(norm_est2), 0xffffffff, 0, 0,
|
||||
0);
|
||||
|
||||
EXPECT_ASSERTION(ozz::math::Normalize2(zero), "_v is not normalizable");
|
||||
EXPECT_ASSERTION(ozz::math::NormalizeEst2(zero), "_v is not normalizable");
|
||||
|
||||
EXPECT_SIMDINT_EQ(ozz::math::IsNormalized3(f), 0, 0, 0, 0);
|
||||
const SimdFloat4 norm3 = ozz::math::Normalize3(f);
|
||||
EXPECT_SIMDFLOAT_EQ(norm3, .21821788f, .43643576f, .87287152f, 8.f);
|
||||
EXPECT_SIMDINT_EQ(ozz::math::IsNormalized3(norm3), 0xffffffff, 0, 0, 0);
|
||||
|
||||
const SimdFloat4 norm_est3 = ozz::math::NormalizeEst3(f);
|
||||
EXPECT_SIMDFLOAT_EQ_EST(norm_est3, .21821788f, .43643576f, .87287152f, 8.f);
|
||||
EXPECT_SIMDINT_EQ(ozz::math::IsNormalizedEst3(norm_est3), 0xffffffff, 0, 0,
|
||||
0);
|
||||
|
||||
EXPECT_ASSERTION(ozz::math::Normalize3(zero), "_v is not normalizable");
|
||||
EXPECT_ASSERTION(ozz::math::NormalizeEst3(zero), "_v is not normalizable");
|
||||
|
||||
EXPECT_SIMDINT_EQ(ozz::math::IsNormalized4(f), 0, 0, 0, 0);
|
||||
const SimdFloat4 norm4 = ozz::math::Normalize4(f);
|
||||
EXPECT_SIMDFLOAT_EQ(norm4, .1084652f, .2169304f, .4338609f, .86772186f);
|
||||
EXPECT_SIMDINT_EQ(ozz::math::IsNormalized4(norm4), 0xffffffff, 0, 0, 0);
|
||||
|
||||
const SimdFloat4 norm_est4 = ozz::math::NormalizeEst4(f);
|
||||
EXPECT_SIMDFLOAT_EQ_EST(norm_est4, .1084652f, .2169304f, .4338609f,
|
||||
.86772186f);
|
||||
EXPECT_SIMDINT_EQ(ozz::math::IsNormalizedEst4(norm_est4), 0xffffffff, 0, 0,
|
||||
0);
|
||||
|
||||
EXPECT_ASSERTION(ozz::math::Normalize4(zero), "_v is not normalizable");
|
||||
EXPECT_ASSERTION(ozz::math::NormalizeEst4(zero), "_v is not normalizable");
|
||||
|
||||
const SimdFloat4 safe2 = ozz::math::NormalizeSafe2(f, unit);
|
||||
EXPECT_SIMDFLOAT_EQ(safe2, .4472136f, .8944272f, 4.f, 8.f);
|
||||
EXPECT_SIMDINT_EQ(ozz::math::IsNormalized2(safe2), 0xffffffff, 0, 0, 0);
|
||||
const SimdFloat4 safer2 = ozz::math::NormalizeSafe2(zero, unit);
|
||||
EXPECT_SIMDFLOAT_EQ(safer2, 1.f, 0.f, 0.f, 0.f);
|
||||
const SimdFloat4 safe_est2 = ozz::math::NormalizeSafeEst2(f, unit);
|
||||
EXPECT_SIMDFLOAT_EQ_EST(safe_est2, .4472136f, .8944272f, 4.f, 8.f);
|
||||
EXPECT_SIMDINT_EQ(ozz::math::IsNormalizedEst2(safe_est2), 0xffffffff, 0, 0,
|
||||
0);
|
||||
const SimdFloat4 safer_est2 = ozz::math::NormalizeSafeEst2(zero, unit);
|
||||
EXPECT_SIMDFLOAT_EQ_EST(safer_est2, 1.f, 0.f, 0.f, 0.f);
|
||||
|
||||
const SimdFloat4 safe3 = ozz::math::NormalizeSafe3(f, unit);
|
||||
EXPECT_SIMDFLOAT_EQ(safe3, .21821788f, .43643576f, .87287152f, 8.f);
|
||||
EXPECT_SIMDINT_EQ(ozz::math::IsNormalized3(safe3), 0xffffffff, 0, 0, 0);
|
||||
const SimdFloat4 safer3 = ozz::math::NormalizeSafe3(zero, unit);
|
||||
EXPECT_SIMDFLOAT_EQ(safer3, 1.f, 0.f, 0.f, 0.f);
|
||||
const SimdFloat4 safe_est3 = ozz::math::NormalizeSafeEst3(f, unit);
|
||||
EXPECT_SIMDFLOAT_EQ_EST(safe_est3, .21821788f, .43643576f, .87287152f, 8.f);
|
||||
EXPECT_SIMDINT_EQ(ozz::math::IsNormalizedEst3(safe_est3), 0xffffffff, 0, 0,
|
||||
0);
|
||||
const SimdFloat4 safer_est3 = ozz::math::NormalizeSafeEst3(zero, unit);
|
||||
EXPECT_SIMDFLOAT_EQ_EST(safer_est3, 1.f, 0.f, 0.f, 0.f);
|
||||
|
||||
const SimdFloat4 safe4 = ozz::math::NormalizeSafe4(f, unit);
|
||||
EXPECT_SIMDFLOAT_EQ(safe4, .1084652f, .2169305f, .433861f, .8677219f);
|
||||
EXPECT_SIMDINT_EQ(ozz::math::IsNormalized4(safe4), 0xffffffff, 0, 0, 0);
|
||||
const SimdFloat4 safer4 = ozz::math::NormalizeSafe4(zero, unit);
|
||||
EXPECT_SIMDFLOAT_EQ(safer4, 1.f, 0.f, 0.f, 0.f);
|
||||
const SimdFloat4 safe_est4 = ozz::math::NormalizeSafeEst4(f, unit);
|
||||
EXPECT_SIMDFLOAT_EQ_EST(safe_est4, .1084652f, .2169305f, .433861f, .8677219f);
|
||||
EXPECT_SIMDINT_EQ(ozz::math::IsNormalizedEst4(safe_est4), 0xffffffff, 0, 0,
|
||||
0);
|
||||
const SimdFloat4 safer_est4 = ozz::math::NormalizeSafeEst4(zero, unit);
|
||||
EXPECT_SIMDFLOAT_EQ_EST(safer_est4, 1.f, 0.f, 0.f, 0.f);
|
||||
}
|
||||
|
||||
TEST(CompareFloat, ozz_simd_math) {
|
||||
const SimdFloat4 a = ozz::math::simd_float4::Load(0.5f, 1.f, 2.f, 3.f);
|
||||
const SimdFloat4 b = ozz::math::simd_float4::Load(4.f, 1.f, -6.f, 7.f);
|
||||
const SimdFloat4 c = ozz::math::simd_float4::Load(4.f, 5.f, 6.f, 7.f);
|
||||
|
||||
const SimdFloat4 min = ozz::math::Min(a, b);
|
||||
EXPECT_SIMDFLOAT_EQ(min, 0.5f, 1.f, -6.f, 3.f);
|
||||
|
||||
const SimdFloat4 max = ozz::math::Max(a, b);
|
||||
EXPECT_SIMDFLOAT_EQ(max, 4.f, 1.f, 2.f, 7.f);
|
||||
|
||||
const SimdFloat4 min0 = ozz::math::Min0(b);
|
||||
EXPECT_SIMDFLOAT_EQ(min0, 0.f, 0.f, -6.f, 0.f);
|
||||
|
||||
const SimdFloat4 max0 = ozz::math::Max0(b);
|
||||
EXPECT_SIMDFLOAT_EQ(max0, 4.f, 1.f, 0.f, 7.f);
|
||||
|
||||
EXPECT_SIMDFLOAT_EQ(
|
||||
ozz::math::Clamp(a, ozz::math::simd_float4::Load(-12.f, 2.f, 9.f, 3.f),
|
||||
c),
|
||||
.5f, 2.f, 6.f, 3.f);
|
||||
|
||||
const SimdInt4 eq1 = ozz::math::CmpEq(a, b);
|
||||
EXPECT_SIMDINT_EQ(eq1, 0, 0xffffffff, 0, 0);
|
||||
|
||||
const SimdInt4 eq2 = ozz::math::CmpEq(a, a);
|
||||
EXPECT_SIMDINT_EQ(eq2, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff);
|
||||
|
||||
const SimdInt4 neq1 = ozz::math::CmpNe(a, b);
|
||||
EXPECT_SIMDINT_EQ(neq1, 0xffffffff, 0, 0xffffffff, 0xffffffff);
|
||||
|
||||
const SimdInt4 neq2 = ozz::math::CmpNe(a, a);
|
||||
EXPECT_SIMDINT_EQ(neq2, 0, 0, 0, 0);
|
||||
|
||||
const SimdInt4 lt = ozz::math::CmpLt(a, b);
|
||||
EXPECT_SIMDINT_EQ(lt, 0xffffffff, 0, 0, 0xffffffff);
|
||||
|
||||
const SimdInt4 le = ozz::math::CmpLe(a, b);
|
||||
EXPECT_SIMDINT_EQ(le, 0xffffffff, 0xffffffff, 0u, 0xffffffff);
|
||||
|
||||
const SimdInt4 gt = ozz::math::CmpGt(a, b);
|
||||
EXPECT_SIMDINT_EQ(gt, 0u, 0u, 0xffffffff, 0u);
|
||||
|
||||
const SimdInt4 ge = ozz::math::CmpGe(a, b);
|
||||
EXPECT_SIMDINT_EQ(ge, 0u, 0xffffffff, 0xffffffff, 0u);
|
||||
}
|
||||
|
||||
TEST(LerpFloat, ozz_simd_math) {
|
||||
const SimdFloat4 a = ozz::math::simd_float4::Load(0.f, 1.f, 2.f, 4.f);
|
||||
const SimdFloat4 b = ozz::math::simd_float4::Load(0.f, -1.f, -2.f, -4.f);
|
||||
const SimdFloat4 zero = ozz::math::simd_float4::Load1(0.f);
|
||||
const SimdFloat4 one = ozz::math::simd_float4::Load1(1.f);
|
||||
|
||||
const SimdFloat4 lerp0 = ozz::math::Lerp(a, b, zero);
|
||||
EXPECT_SIMDFLOAT_EQ(lerp0, 0.f, 1.f, 2.f, 4.f);
|
||||
|
||||
const SimdFloat4 lerp1 = ozz::math::Lerp(a, b, one);
|
||||
EXPECT_SIMDFLOAT_EQ(lerp1, 0.f, -1.f, -2.f, -4.f);
|
||||
|
||||
const SimdFloat4 lhalf =
|
||||
ozz::math::Lerp(a, b, ozz::math::simd_float4::Load1(0.5f));
|
||||
EXPECT_SIMDFLOAT_EQ(lhalf, 0.f, 0.f, 0.f, 0.f);
|
||||
|
||||
const SimdFloat4 lmixed =
|
||||
ozz::math::Lerp(a, b, ozz::math::simd_float4::Load(0.f, -1.f, 0.5f, 2.f));
|
||||
EXPECT_SIMDFLOAT_EQ(lmixed, 0.f, 3.f, 0.f, -12.f);
|
||||
}
|
||||
|
||||
TEST(TrigonometryFloat, ozz_simd_math) {
|
||||
using ozz::math::k2Pi;
|
||||
using ozz::math::kPi;
|
||||
using ozz::math::kPi_2;
|
||||
|
||||
const SimdFloat4 angle =
|
||||
ozz::math::simd_float4::Load(kPi, kPi / 6.f, -kPi_2, 5.f * kPi_2);
|
||||
const SimdFloat4 cos =
|
||||
ozz::math::simd_float4::Load(-1.f, .86602539f, 0.f, 0.f);
|
||||
const SimdFloat4 sin = ozz::math::simd_float4::Load(0.f, .5f, -1.f, 1.f);
|
||||
|
||||
const SimdFloat4 angle_tan =
|
||||
ozz::math::simd_float4::Load(0.f, kPi / 6.f, -kPi / 3.f, 9.f * kPi / 4.f);
|
||||
const SimdFloat4 tan =
|
||||
ozz::math::simd_float4::Load(0.f, .57735f, -1.73205f, 1.f);
|
||||
|
||||
EXPECT_SIMDFLOAT_EQ(ozz::math::Cos(angle), -1.f, .86602539f, 0.f, 0.f);
|
||||
EXPECT_SIMDFLOAT_EQ(
|
||||
ozz::math::Cos(angle + ozz::math::simd_float4::Load1(k2Pi)), -1.f,
|
||||
.86602539f, 0.f, 0.f);
|
||||
EXPECT_SIMDFLOAT_EQ(
|
||||
ozz::math::Cos(angle + ozz::math::simd_float4::Load1(k2Pi * 12.f)), -1.f,
|
||||
.86602539f, 0.f, 0.f);
|
||||
EXPECT_SIMDFLOAT_EQ(
|
||||
ozz::math::Cos(angle - ozz::math::simd_float4::Load1(k2Pi * 24.f)), -1.f,
|
||||
.86602539f, 0.f, 0.f);
|
||||
|
||||
EXPECT_SIMDFLOAT_EQ(ozz::math::CosX(angle), -1.f, kPi / 6.f, -kPi_2,
|
||||
5.f * kPi_2);
|
||||
EXPECT_SIMDFLOAT_EQ(
|
||||
ozz::math::CosX(angle + ozz::math::simd_float4::LoadX(k2Pi)), -1.f,
|
||||
kPi / 6.f, -kPi_2, 5.f * kPi_2);
|
||||
EXPECT_SIMDFLOAT_EQ(
|
||||
ozz::math::CosX(angle + ozz::math::simd_float4::LoadX(k2Pi * 12.f)), -1.f,
|
||||
kPi / 6.f, -kPi_2, 5.f * kPi_2);
|
||||
EXPECT_SIMDFLOAT_EQ(
|
||||
ozz::math::CosX(angle - ozz::math::simd_float4::LoadX(k2Pi * 24.f)), -1.f,
|
||||
kPi / 6.f, -kPi_2, 5.f * kPi_2);
|
||||
|
||||
EXPECT_SIMDFLOAT_EQ(ozz::math::Sin(angle), 0.f, .5f, -1.f, 1.f);
|
||||
EXPECT_SIMDFLOAT_EQ(
|
||||
ozz::math::Sin(angle + ozz::math::simd_float4::Load1(k2Pi)), 0.f, 0.5f,
|
||||
-1.f, 1.f);
|
||||
EXPECT_SIMDFLOAT_EQ(
|
||||
ozz::math::Sin(angle + ozz::math::simd_float4::Load1(k2Pi * 12.f)), 0.f,
|
||||
.5f, -1.f, 1.f);
|
||||
EXPECT_SIMDFLOAT_EQ(
|
||||
ozz::math::Sin(angle - ozz::math::simd_float4::Load1(k2Pi * 24.f)), 0.f,
|
||||
.5f, -1.f, 1.f);
|
||||
|
||||
EXPECT_SIMDFLOAT_EQ(ozz::math::SinX(angle), 0.f, kPi / 6.f, -kPi_2,
|
||||
5.f * kPi_2);
|
||||
EXPECT_SIMDFLOAT_EQ(
|
||||
ozz::math::SinX(angle + ozz::math::simd_float4::LoadX(k2Pi)), 0.f,
|
||||
kPi / 6.f, -kPi_2, 5.f * kPi_2);
|
||||
EXPECT_SIMDFLOAT_EQ(
|
||||
ozz::math::SinX(angle + ozz::math::simd_float4::LoadX(k2Pi * 12.f)), 0.f,
|
||||
kPi / 6.f, -kPi_2, 5.f * kPi_2);
|
||||
EXPECT_SIMDFLOAT_EQ(
|
||||
ozz::math::SinX(angle - ozz::math::simd_float4::LoadX(k2Pi * 24.f)), 0.f,
|
||||
kPi / 6.f, -kPi_2, 5.f * kPi_2);
|
||||
|
||||
EXPECT_SIMDFLOAT_EQ(ozz::math::ACos(cos), kPi, kPi / 6.f, kPi_2, kPi_2);
|
||||
EXPECT_SIMDFLOAT_EQ(ozz::math::ACosX(cos), kPi, .86602539f, 0.f, 0.f);
|
||||
|
||||
EXPECT_SIMDFLOAT_EQ(ozz::math::ASin(sin), 0.f, kPi / 6.f, -kPi_2, kPi_2);
|
||||
EXPECT_SIMDFLOAT_EQ(ozz::math::ASinX(sin), 0.f, .5f, -1.f, 1.f);
|
||||
|
||||
EXPECT_SIMDFLOAT_EQ(ozz::math::Tan(angle_tan), 0.f, 0.57735f, -1.73205f, 1.f);
|
||||
EXPECT_SIMDFLOAT_EQ(ozz::math::TanX(angle_tan), 0.f, kPi / 6.f, -kPi / 3.f,
|
||||
9.f * kPi / 4.f);
|
||||
|
||||
EXPECT_SIMDFLOAT_EQ(ozz::math::ATan(tan), 0.f, kPi / 6.f, -kPi / 3.f,
|
||||
kPi / 4.f);
|
||||
EXPECT_SIMDFLOAT_EQ(ozz::math::ATanX(tan), 0.f, .57735f, -1.73205f, 1.f);
|
||||
}
|
||||
|
||||
TEST(LogicalFloat, ozz_simd_math) {
|
||||
const SimdFloat4 a = ozz::math::simd_float4::Load(0.f, 1.f, 2.f, 3.f);
|
||||
const SimdFloat4 b = ozz::math::simd_float4::Load(1.f, -1.f, -3.f, -4.f);
|
||||
const SimdInt4 mbool =
|
||||
ozz::math::simd_int4::Load(0xffffffff, 0, 0, 0xffffffff);
|
||||
const SimdInt4 mbit =
|
||||
ozz::math::simd_int4::Load(0xffffffff, 0, 0x80000000, 0x7fffffff);
|
||||
const SimdFloat4 mfloat = ozz::math::simd_float4::Load(1.f, 0.f, -0.f, 3.f);
|
||||
|
||||
const SimdFloat4 select = ozz::math::Select(mbool, a, b);
|
||||
EXPECT_SIMDFLOAT_EQ(select, 0.f, -1.f, -3.f, 3.f);
|
||||
|
||||
const SimdFloat4 andm = ozz::math::And(b, mbit);
|
||||
EXPECT_SIMDFLOAT_EQ(andm, 1.f, 0.f, 0.f, 4.f);
|
||||
|
||||
const SimdFloat4 andnm = ozz::math::AndNot(b, mbit);
|
||||
EXPECT_SIMDFLOAT_EQ(andnm, 0.f, -1.f, 3.f, -0.f);
|
||||
|
||||
const SimdFloat4 andf = ozz::math::And(b, mfloat);
|
||||
EXPECT_SIMDFLOAT_EQ(andf, 1.f, 0.f, -0.f, 2.f);
|
||||
|
||||
const SimdFloat4 orm = ozz::math::Or(a, mbit);
|
||||
union {
|
||||
float f;
|
||||
unsigned int i;
|
||||
} orx = {ozz::math::GetX(orm)};
|
||||
EXPECT_EQ(orx.i, 0xffffffff);
|
||||
EXPECT_FLOAT_EQ(ozz::math::GetY(orm), 1.f);
|
||||
EXPECT_FLOAT_EQ(ozz::math::GetZ(orm), -2.f);
|
||||
union {
|
||||
float f;
|
||||
int i;
|
||||
} orw = {ozz::math::GetW(orm)};
|
||||
EXPECT_TRUE(orw.i == 0x7fffffff);
|
||||
|
||||
const SimdFloat4 ormf = ozz::math::Or(a, mfloat);
|
||||
EXPECT_SIMDFLOAT_EQ(ormf, 1.f, 1.f, -2.f, 3.f);
|
||||
|
||||
const SimdFloat4 xorm = ozz::math::Xor(a, mbit);
|
||||
union {
|
||||
float f;
|
||||
unsigned int i;
|
||||
} xorx = {ozz::math::GetX(xorm)};
|
||||
EXPECT_TRUE(xorx.i == 0xffffffff);
|
||||
EXPECT_FLOAT_EQ(ozz::math::GetY(xorm), 1.f);
|
||||
EXPECT_FLOAT_EQ(ozz::math::GetZ(xorm), -2.f);
|
||||
union {
|
||||
float f;
|
||||
unsigned int i;
|
||||
} xorw = {ozz::math::GetW(xorm)};
|
||||
EXPECT_TRUE(xorw.i == 0x3fbfffff);
|
||||
|
||||
const SimdFloat4 xormf = ozz::math::Xor(a, mfloat);
|
||||
EXPECT_SIMDFLOAT_EQ(xormf, 1.f, 1.f, -2.f, 0.f);
|
||||
}
|
||||
|
||||
TEST(Half, ozz_simd_math) {
|
||||
// 0
|
||||
EXPECT_EQ(ozz::math::FloatToHalf(0.f), 0);
|
||||
EXPECT_FLOAT_EQ(ozz::math::HalfToFloat(0), 0.f);
|
||||
EXPECT_EQ(ozz::math::FloatToHalf(-0.f), 0x8000);
|
||||
EXPECT_FLOAT_EQ(ozz::math::HalfToFloat(0x8000), -0.f);
|
||||
EXPECT_EQ(ozz::math::FloatToHalf(std::numeric_limits<float>::min()), 0);
|
||||
EXPECT_EQ(ozz::math::FloatToHalf(std::numeric_limits<float>::denorm_min()),
|
||||
0);
|
||||
EXPECT_EQ(
|
||||
ozz::math::FloatToHalf(std::numeric_limits<float>::denorm_min() / 10.f),
|
||||
0);
|
||||
|
||||
// 1
|
||||
EXPECT_EQ(ozz::math::FloatToHalf(1.f), 0x3c00);
|
||||
EXPECT_FLOAT_EQ(ozz::math::HalfToFloat(0x3c00), 1.f);
|
||||
EXPECT_EQ(ozz::math::FloatToHalf(-1.f), 0xbc00);
|
||||
EXPECT_FLOAT_EQ(ozz::math::HalfToFloat(0xbc00), -1.f);
|
||||
|
||||
// Bounds
|
||||
EXPECT_EQ(ozz::math::FloatToHalf(65504.f), 0x7bff);
|
||||
EXPECT_EQ(ozz::math::FloatToHalf(-65504.f), 0xfbff);
|
||||
|
||||
// Min, Max, Infinity
|
||||
EXPECT_EQ(ozz::math::FloatToHalf(10e-16f), 0);
|
||||
EXPECT_EQ(ozz::math::FloatToHalf(10e+16f), 0x7c00);
|
||||
EXPECT_FLOAT_EQ(ozz::math::HalfToFloat(0x7c00),
|
||||
std::numeric_limits<float>::infinity());
|
||||
EXPECT_EQ(ozz::math::FloatToHalf(std::numeric_limits<float>::max()), 0x7c00);
|
||||
EXPECT_EQ(ozz::math::FloatToHalf(std::numeric_limits<float>::infinity()),
|
||||
0x7c00);
|
||||
EXPECT_EQ(ozz::math::FloatToHalf(-10e+16f), 0xfc00);
|
||||
EXPECT_EQ(ozz::math::FloatToHalf(-std::numeric_limits<float>::infinity()),
|
||||
0xfc00);
|
||||
EXPECT_EQ(ozz::math::FloatToHalf(-std::numeric_limits<float>::max()), 0xfc00);
|
||||
EXPECT_FLOAT_EQ(ozz::math::HalfToFloat(0xfc00),
|
||||
-std::numeric_limits<float>::infinity());
|
||||
|
||||
// Nan
|
||||
EXPECT_EQ(ozz::math::FloatToHalf(std::numeric_limits<float>::quiet_NaN()),
|
||||
0x7e00);
|
||||
EXPECT_EQ(ozz::math::FloatToHalf(std::numeric_limits<float>::signaling_NaN()),
|
||||
0x7e00);
|
||||
// According to the IEEE standard, NaN values have the odd property that
|
||||
// comparisons involving them are always false
|
||||
EXPECT_FALSE(ozz::math::HalfToFloat(0x7e00) ==
|
||||
ozz::math::HalfToFloat(0x7e00));
|
||||
|
||||
// Random tries in range [10e-4,10e4].
|
||||
for (float pow = -4.f; pow <= 4.f; pow += 1.f) {
|
||||
const float max = powf(10.f, pow);
|
||||
// Expect a 1/1000 precision over floats.
|
||||
const float precision = max / 1000.f;
|
||||
|
||||
const int n = 1000;
|
||||
for (int i = 0; i < n; ++i) {
|
||||
const float frand = max * (2.f * i / n - 1.f);
|
||||
|
||||
const uint16_t h = ozz::math::FloatToHalf(frand);
|
||||
const float f = ozz::math::HalfToFloat(h);
|
||||
EXPECT_NEAR(frand, f, precision);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST(SimdHalf, ozz_simd_math) {
|
||||
// 0
|
||||
EXPECT_SIMDINT_EQ(ozz::math::FloatToHalf(ozz::math::simd_float4::Load(
|
||||
0.f, -0.f, std::numeric_limits<float>::min(),
|
||||
std::numeric_limits<float>::denorm_min())),
|
||||
0, 0x00008000, 0, 0);
|
||||
EXPECT_SIMDFLOAT_EQ(
|
||||
ozz::math::HalfToFloat(ozz::math::simd_int4::Load(0, 0x00008000, 0, 0)),
|
||||
0.f, -0.f, 0.f, 0.f);
|
||||
|
||||
// 1
|
||||
EXPECT_SIMDINT_EQ(ozz::math::FloatToHalf(
|
||||
ozz::math::simd_float4::Load(1.f, -1.f, 0.f, -0.f)),
|
||||
0x00003c00, 0x0000bc00, 0, 0x00008000);
|
||||
EXPECT_SIMDFLOAT_EQ(ozz::math::HalfToFloat(ozz::math::simd_int4::Load(
|
||||
0x3c00, 0xbc00, 0, 0x00008000)),
|
||||
1.f, -1.f, 0.f, -0.f);
|
||||
|
||||
// Bounds
|
||||
EXPECT_SIMDINT_EQ(ozz::math::FloatToHalf(ozz::math::simd_float4::Load(
|
||||
65504.f, -65504.f, 65604.f, -65604.f)),
|
||||
0x00007bff, 0x0000fbff, 0x00007c00, 0x0000fc00);
|
||||
|
||||
// Min, Max, Infinity
|
||||
EXPECT_SIMDINT_EQ(ozz::math::FloatToHalf(ozz::math::simd_float4::Load(
|
||||
10e-16f, 10e+16f, std::numeric_limits<float>::max(),
|
||||
std::numeric_limits<float>::infinity())),
|
||||
0, 0x00007c00, 0x00007c00, 0x00007c00);
|
||||
EXPECT_SIMDINT_EQ(ozz::math::FloatToHalf(ozz::math::simd_float4::Load(
|
||||
-10e-16f, -10e+16f, -std::numeric_limits<float>::max(),
|
||||
-std::numeric_limits<float>::max())),
|
||||
0x00008000, 0x0000fc00, 0x0000fc00, 0x0000fc00);
|
||||
|
||||
// Nan
|
||||
EXPECT_SIMDINT_EQ(ozz::math::FloatToHalf(ozz::math::simd_float4::Load(
|
||||
std::numeric_limits<float>::quiet_NaN(),
|
||||
std::numeric_limits<float>::signaling_NaN(), 0, 0)),
|
||||
0x00007e00, 0x00007e00, 0, 0);
|
||||
|
||||
// Inf and NAN
|
||||
const SimdFloat4 infnan = ozz::math::HalfToFloat(
|
||||
ozz::math::simd_int4::Load(0x00007c00, 0x0000fc00, 0x00007e00, 0));
|
||||
EXPECT_FLOAT_EQ(ozz::math::GetX(infnan),
|
||||
std::numeric_limits<float>::infinity());
|
||||
EXPECT_FLOAT_EQ(ozz::math::GetY(infnan),
|
||||
-std::numeric_limits<float>::infinity());
|
||||
EXPECT_FALSE(ozz::math::GetZ(infnan) == ozz::math::GetZ(infnan));
|
||||
|
||||
// Random tries in range [10e-4,10e4].
|
||||
srand(0);
|
||||
for (float pow = -4.f; pow <= 4.f; pow += 1.f) {
|
||||
const float max = powf(10.f, pow);
|
||||
// Expect a 1/1000 precision over floats.
|
||||
const float precision = max / 1000.f;
|
||||
|
||||
const int n = 1000;
|
||||
for (int i = 0; i < n; ++i) {
|
||||
const SimdFloat4 frand = ozz::math::simd_float4::Load(
|
||||
max * (.5f * i / n - .25f), max * (1.f * i / n - .5f),
|
||||
max * (1.5f * i / n - .75f), max * (2.f * i / n - 1.f));
|
||||
|
||||
const SimdInt4 h = ozz::math::FloatToHalf(frand);
|
||||
const SimdFloat4 f = ozz::math::HalfToFloat(h);
|
||||
|
||||
EXPECT_NEAR(ozz::math::GetX(frand), ozz::math::GetX(f), precision);
|
||||
EXPECT_NEAR(ozz::math::GetY(frand), ozz::math::GetY(f), precision);
|
||||
EXPECT_NEAR(ozz::math::GetZ(frand), ozz::math::GetZ(f), precision);
|
||||
EXPECT_NEAR(ozz::math::GetW(frand), ozz::math::GetW(f), precision);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,524 @@
|
||||
//----------------------------------------------------------------------------//
|
||||
// //
|
||||
// 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_math.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#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::SimdInt4;
|
||||
|
||||
static_assert(sizeof(SimdInt4) == 4 * sizeof(int32_t),
|
||||
"Expects SimdInt4 to be the size of 4 int32_t.");
|
||||
static_assert(alignof(SimdInt4) == 16,
|
||||
"Expects SimdInt4 to be the size of 16 bytes.");
|
||||
|
||||
TEST(LoadInt, ozz_simd_math) {
|
||||
const SimdInt4 iX = ozz::math::simd_int4::LoadX(15);
|
||||
EXPECT_SIMDINT_EQ(iX, 15, 0, 0, 0);
|
||||
|
||||
const SimdInt4 i1 = ozz::math::simd_int4::Load1(15);
|
||||
EXPECT_SIMDINT_EQ(i1, 15, 15, 15, 15);
|
||||
|
||||
const SimdInt4 i4 = ozz::math::simd_int4::Load(1, -1, 2, -3);
|
||||
EXPECT_SIMDINT_EQ(i4, 1, -1, 2, -3);
|
||||
|
||||
const SimdInt4 itX = ozz::math::simd_int4::LoadX(true);
|
||||
EXPECT_SIMDINT_EQ(itX, 0xffffffff, 0, 0, 0);
|
||||
|
||||
const SimdInt4 ifX = ozz::math::simd_int4::LoadX(false);
|
||||
EXPECT_SIMDINT_EQ(ifX, 0, 0, 0, 0);
|
||||
|
||||
const SimdInt4 it1 = ozz::math::simd_int4::Load1(true);
|
||||
EXPECT_SIMDINT_EQ(it1, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff);
|
||||
|
||||
const SimdInt4 if1 = ozz::math::simd_int4::Load1(false);
|
||||
EXPECT_SIMDINT_EQ(if1, 0, 0, 0, 0);
|
||||
|
||||
const SimdInt4 ibttff = ozz::math::simd_int4::Load(true, true, false, false);
|
||||
EXPECT_SIMDINT_EQ(ibttff, 0xffffffff, 0xffffffff, 0, 0);
|
||||
|
||||
const SimdInt4 ibftft = ozz::math::simd_int4::Load(false, true, false, true);
|
||||
EXPECT_SIMDINT_EQ(ibftft, 0, 0xffffffff, 0, 0xffffffff);
|
||||
}
|
||||
|
||||
TEST(LoadIntPtr, ozz_simd_math) {
|
||||
union Data {
|
||||
int i[4 + 5];
|
||||
char c[(4 + 5) * sizeof(int)]; // The 2nd char isn't aligned to an integer.
|
||||
};
|
||||
const Data d_in = {{-1, 1, 2, 3, 4, 5, 6, 7, 8}};
|
||||
const int aligned_offset =
|
||||
(16 - (reinterpret_cast<intptr_t>(d_in.i) & 0xf)) / sizeof(float);
|
||||
assert(aligned_offset > 0 && aligned_offset <= 4);
|
||||
|
||||
EXPECT_SIMDINT_EQ(ozz::math::simd_int4::LoadPtrU(d_in.i + aligned_offset + 1),
|
||||
d_in.i[aligned_offset + 1], d_in.i[aligned_offset + 2],
|
||||
d_in.i[aligned_offset + 3], d_in.i[aligned_offset + 4]);
|
||||
EXPECT_ASSERTION(
|
||||
ozz::math::simd_int4::LoadPtrU(reinterpret_cast<const int*>(d_in.c + 1)),
|
||||
"alignment");
|
||||
EXPECT_SIMDINT_EQ(ozz::math::simd_int4::LoadPtr(d_in.i + aligned_offset),
|
||||
d_in.i[aligned_offset], d_in.i[aligned_offset + 1],
|
||||
d_in.i[aligned_offset + 2], d_in.i[aligned_offset + 3]);
|
||||
EXPECT_ASSERTION(ozz::math::simd_int4::LoadPtr(d_in.i + aligned_offset + 1),
|
||||
"alignment");
|
||||
|
||||
EXPECT_SIMDINT_EQ(ozz::math::simd_int4::LoadXPtrU(d_in.i + aligned_offset),
|
||||
d_in.i[aligned_offset], 0, 0, 0);
|
||||
EXPECT_ASSERTION(
|
||||
ozz::math::simd_int4::LoadXPtrU(reinterpret_cast<const int*>(d_in.c + 1)),
|
||||
"alignment");
|
||||
EXPECT_SIMDINT_EQ(ozz::math::simd_int4::Load1PtrU(d_in.i + aligned_offset),
|
||||
d_in.i[aligned_offset], d_in.i[aligned_offset],
|
||||
d_in.i[aligned_offset], d_in.i[aligned_offset]);
|
||||
EXPECT_ASSERTION(
|
||||
ozz::math::simd_int4::Load1PtrU(reinterpret_cast<const int*>(d_in.c + 1)),
|
||||
"alignment");
|
||||
|
||||
EXPECT_SIMDINT_EQ(ozz::math::simd_int4::LoadXPtr(d_in.i + aligned_offset),
|
||||
d_in.i[aligned_offset], 0, 0, 0);
|
||||
EXPECT_ASSERTION(ozz::math::simd_int4::LoadXPtr(d_in.i + aligned_offset + 1),
|
||||
"alignment");
|
||||
EXPECT_SIMDINT_EQ(ozz::math::simd_int4::Load1Ptr(d_in.i + aligned_offset),
|
||||
d_in.i[aligned_offset], d_in.i[aligned_offset],
|
||||
d_in.i[aligned_offset], d_in.i[aligned_offset]);
|
||||
EXPECT_ASSERTION(ozz::math::simd_int4::Load1Ptr(d_in.i + aligned_offset + 1),
|
||||
"alignment");
|
||||
|
||||
EXPECT_SIMDINT_EQ(ozz::math::simd_int4::Load2Ptr(d_in.i + aligned_offset),
|
||||
d_in.i[aligned_offset], d_in.i[aligned_offset + 1], 0, 0);
|
||||
EXPECT_ASSERTION(ozz::math::simd_int4::Load2Ptr(d_in.i + aligned_offset + 1),
|
||||
"alignment");
|
||||
EXPECT_SIMDINT_EQ(
|
||||
ozz::math::simd_int4::Load2PtrU(d_in.i + aligned_offset + 1),
|
||||
d_in.i[aligned_offset + 1], d_in.i[aligned_offset + 2], 0, 0);
|
||||
EXPECT_ASSERTION(
|
||||
ozz::math::simd_int4::Load2PtrU(reinterpret_cast<const int*>(d_in.c + 1)),
|
||||
"alignment");
|
||||
|
||||
EXPECT_SIMDINT_EQ(ozz::math::simd_int4::Load3Ptr(d_in.i + aligned_offset),
|
||||
d_in.i[aligned_offset], d_in.i[aligned_offset + 1],
|
||||
d_in.i[aligned_offset + 2], 0);
|
||||
EXPECT_ASSERTION(ozz::math::simd_int4::Load3Ptr(d_in.i + aligned_offset + 1),
|
||||
"alignment");
|
||||
EXPECT_SIMDINT_EQ(
|
||||
ozz::math::simd_int4::Load3PtrU(d_in.i + aligned_offset + 1),
|
||||
d_in.i[aligned_offset + 1], d_in.i[aligned_offset + 2],
|
||||
d_in.i[aligned_offset + 3], 0);
|
||||
EXPECT_ASSERTION(
|
||||
ozz::math::simd_int4::Load3PtrU(reinterpret_cast<const int*>(d_in.c + 1)),
|
||||
"alignment");
|
||||
}
|
||||
|
||||
TEST(GetInt, ozz_simd_math) {
|
||||
const SimdInt4 i = ozz::math::simd_int4::Load(1, 2, 3, 4);
|
||||
|
||||
EXPECT_EQ(ozz::math::GetX(i), 1);
|
||||
EXPECT_EQ(ozz::math::GetY(i), 2);
|
||||
EXPECT_EQ(ozz::math::GetZ(i), 3);
|
||||
EXPECT_EQ(ozz::math::GetW(i), 4);
|
||||
}
|
||||
|
||||
TEST(SetInt, ozz_simd_math) {
|
||||
const SimdInt4 a = ozz::math::simd_int4::Load(1, 2, 3, 4);
|
||||
const SimdInt4 b = ozz::math::simd_int4::Load(5, 6, 7, 8);
|
||||
|
||||
EXPECT_SIMDINT_EQ(ozz::math::SetX(a, b), 5, 2, 3, 4);
|
||||
EXPECT_SIMDINT_EQ(ozz::math::SetY(a, b), 1, 5, 3, 4);
|
||||
EXPECT_SIMDINT_EQ(ozz::math::SetZ(a, b), 1, 2, 5, 4);
|
||||
EXPECT_SIMDINT_EQ(ozz::math::SetW(a, b), 1, 2, 3, 5);
|
||||
|
||||
EXPECT_ASSERTION(ozz::math::SetI(a, b, 4), "Invalid index, out of range.");
|
||||
EXPECT_SIMDINT_EQ(ozz::math::SetI(a, b, 0), 5, 2, 3, 4);
|
||||
EXPECT_SIMDINT_EQ(ozz::math::SetI(a, b, 1), 1, 5, 3, 4);
|
||||
EXPECT_SIMDINT_EQ(ozz::math::SetI(a, b, 2), 1, 2, 5, 4);
|
||||
EXPECT_SIMDINT_EQ(ozz::math::SetI(a, b, 3), 1, 2, 3, 5);
|
||||
}
|
||||
|
||||
TEST(StoreIntPtr, ozz_simd_math) {
|
||||
const SimdInt4 i4 = ozz::math::simd_int4::Load(-1, 1, 2, 3);
|
||||
|
||||
union Data {
|
||||
int i[4 + 4]; // The 2nd float isn't aligned to a SimdInt4.
|
||||
SimdInt4 i4[2]; // Forces alignment.
|
||||
char c[(4 + 4) * sizeof(int)]; // The 2nd char isn't aligned to an integer.
|
||||
};
|
||||
|
||||
{
|
||||
Data d_out = {};
|
||||
ozz::math::StorePtrU(i4, d_out.i + 1);
|
||||
EXPECT_EQ(d_out.i[0], 0);
|
||||
EXPECT_EQ(d_out.i[1], -1);
|
||||
EXPECT_EQ(d_out.i[2], 1);
|
||||
EXPECT_EQ(d_out.i[3], 2);
|
||||
EXPECT_EQ(d_out.i[4], 3);
|
||||
EXPECT_ASSERTION(
|
||||
ozz::math::StorePtrU(i4, reinterpret_cast<int*>(d_out.c + 1)),
|
||||
"alignment");
|
||||
}
|
||||
{
|
||||
Data d_out = {};
|
||||
ozz::math::Store1PtrU(i4, d_out.i + 1);
|
||||
EXPECT_EQ(d_out.i[0], 0);
|
||||
EXPECT_EQ(d_out.i[1], -1);
|
||||
EXPECT_EQ(d_out.i[2], 0);
|
||||
EXPECT_EQ(d_out.i[3], 0);
|
||||
EXPECT_EQ(d_out.i[4], 0);
|
||||
EXPECT_ASSERTION(
|
||||
ozz::math::Store1PtrU(i4, reinterpret_cast<int*>(d_out.c + 1)),
|
||||
"alignment");
|
||||
}
|
||||
{
|
||||
Data d_out = {};
|
||||
ozz::math::Store2PtrU(i4, d_out.i + 1);
|
||||
EXPECT_EQ(d_out.i[0], 0);
|
||||
EXPECT_EQ(d_out.i[1], -1);
|
||||
EXPECT_EQ(d_out.i[2], 1);
|
||||
EXPECT_EQ(d_out.i[3], 0);
|
||||
EXPECT_EQ(d_out.i[4], 0);
|
||||
EXPECT_ASSERTION(
|
||||
ozz::math::Store2Ptr(i4, reinterpret_cast<int*>(d_out.c + 1)),
|
||||
"alignment");
|
||||
}
|
||||
{
|
||||
Data d_out = {};
|
||||
ozz::math::Store3PtrU(i4, d_out.i + 1);
|
||||
EXPECT_EQ(d_out.i[0], 0);
|
||||
EXPECT_EQ(d_out.i[1], -1);
|
||||
EXPECT_EQ(d_out.i[2], 1);
|
||||
EXPECT_EQ(d_out.i[3], 2);
|
||||
EXPECT_EQ(d_out.i[4], 0);
|
||||
EXPECT_ASSERTION(
|
||||
ozz::math::Store3Ptr(i4, reinterpret_cast<int*>(d_out.c + 1)),
|
||||
"alignment");
|
||||
}
|
||||
{
|
||||
Data d_out = {};
|
||||
ozz::math::StorePtr(i4, d_out.i);
|
||||
EXPECT_EQ(d_out.i[0], -1);
|
||||
EXPECT_EQ(d_out.i[1], 1);
|
||||
EXPECT_EQ(d_out.i[2], 2);
|
||||
EXPECT_EQ(d_out.i[3], 3);
|
||||
EXPECT_EQ(d_out.i[4], 0);
|
||||
EXPECT_ASSERTION(ozz::math::StorePtr(i4, d_out.i + 1), "alignment");
|
||||
}
|
||||
{
|
||||
Data d_out = {};
|
||||
ozz::math::Store1Ptr(i4, d_out.i);
|
||||
EXPECT_EQ(d_out.i[0], -1);
|
||||
EXPECT_EQ(d_out.i[1], 0);
|
||||
EXPECT_EQ(d_out.i[2], 0);
|
||||
EXPECT_EQ(d_out.i[3], 0);
|
||||
EXPECT_EQ(d_out.i[4], 0);
|
||||
EXPECT_ASSERTION(ozz::math::Store1Ptr(i4, d_out.i + 1), "alignment");
|
||||
}
|
||||
{
|
||||
Data d_out = {};
|
||||
ozz::math::Store2Ptr(i4, d_out.i);
|
||||
EXPECT_EQ(d_out.i[0], -1);
|
||||
EXPECT_EQ(d_out.i[1], 1);
|
||||
EXPECT_EQ(d_out.i[2], 0);
|
||||
EXPECT_EQ(d_out.i[3], 0);
|
||||
EXPECT_EQ(d_out.i[4], 0);
|
||||
EXPECT_ASSERTION(ozz::math::Store2Ptr(i4, d_out.i + 1), "alignment");
|
||||
}
|
||||
{
|
||||
Data d_out = {};
|
||||
ozz::math::Store3Ptr(i4, d_out.i);
|
||||
EXPECT_EQ(d_out.i[0], -1);
|
||||
EXPECT_EQ(d_out.i[1], 1);
|
||||
EXPECT_EQ(d_out.i[2], 2);
|
||||
EXPECT_EQ(d_out.i[3], 0);
|
||||
EXPECT_EQ(d_out.i[4], 0);
|
||||
EXPECT_ASSERTION(ozz::math::Store3Ptr(i4, d_out.i + 1), "alignment");
|
||||
}
|
||||
}
|
||||
|
||||
TEST(ConstantInt, ozz_simd_math) {
|
||||
const SimdInt4 zero = ozz::math::simd_int4::zero();
|
||||
EXPECT_SIMDINT_EQ(zero, 0, 0, 0, 0);
|
||||
|
||||
const SimdInt4 one = ozz::math::simd_int4::one();
|
||||
EXPECT_SIMDINT_EQ(one, 1, 1, 1, 1);
|
||||
|
||||
const SimdInt4 x_axis = ozz::math::simd_int4::x_axis();
|
||||
EXPECT_SIMDINT_EQ(x_axis, 1, 0, 0, 0);
|
||||
|
||||
const SimdInt4 y_axis = ozz::math::simd_int4::y_axis();
|
||||
EXPECT_SIMDINT_EQ(y_axis, 0, 1, 0, 0);
|
||||
|
||||
const SimdInt4 z_axis = ozz::math::simd_int4::z_axis();
|
||||
EXPECT_SIMDINT_EQ(z_axis, 0, 0, 1, 0);
|
||||
|
||||
const SimdInt4 w_axis = ozz::math::simd_int4::w_axis();
|
||||
EXPECT_SIMDINT_EQ(w_axis, 0, 0, 0, 1);
|
||||
|
||||
const SimdInt4 all_true = ozz::math::simd_int4::all_true();
|
||||
EXPECT_SIMDINT_EQ(all_true, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff);
|
||||
|
||||
const SimdInt4 all_false = ozz::math::simd_int4::all_false();
|
||||
EXPECT_SIMDINT_EQ(all_false, 0, 0, 0, 0);
|
||||
|
||||
const SimdInt4 mask_sign = ozz::math::simd_int4::mask_sign();
|
||||
EXPECT_SIMDINT_EQ(mask_sign, 0x80000000, 0x80000000, 0x80000000, 0x80000000);
|
||||
|
||||
const SimdInt4 mask_sign_xyz = ozz::math::simd_int4::mask_sign_xyz();
|
||||
EXPECT_SIMDINT_EQ(mask_sign_xyz, 0x80000000, 0x80000000, 0x80000000,
|
||||
0x00000000);
|
||||
|
||||
const SimdInt4 mask_sign_w = ozz::math::simd_int4::mask_sign_w();
|
||||
EXPECT_SIMDINT_EQ(mask_sign_w, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x80000000);
|
||||
|
||||
const SimdInt4 mask_not_sign = ozz::math::simd_int4::mask_not_sign();
|
||||
EXPECT_SIMDINT_EQ(mask_not_sign, 0x7fffffff, 0x7fffffff, 0x7fffffff,
|
||||
0x7fffffff);
|
||||
|
||||
const SimdInt4 mask_ffff = ozz::math::simd_int4::mask_ffff();
|
||||
EXPECT_SIMDINT_EQ(mask_ffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff);
|
||||
|
||||
const SimdInt4 mask_0000 = ozz::math::simd_int4::mask_0000();
|
||||
EXPECT_SIMDINT_EQ(mask_0000, 0, 0, 0, 0);
|
||||
|
||||
const SimdInt4 mask_fff0 = ozz::math::simd_int4::mask_fff0();
|
||||
EXPECT_SIMDINT_EQ(mask_fff0, 0xffffffff, 0xffffffff, 0xffffffff, 0);
|
||||
|
||||
const SimdInt4 mask_f000 = ozz::math::simd_int4::mask_f000();
|
||||
EXPECT_SIMDINT_EQ(mask_f000, 0xffffffff, 0, 0, 0);
|
||||
|
||||
const SimdInt4 mask_0f00 = ozz::math::simd_int4::mask_0f00();
|
||||
EXPECT_SIMDINT_EQ(mask_0f00, 0, 0xffffffff, 0, 0);
|
||||
|
||||
const SimdInt4 mask_00f0 = ozz::math::simd_int4::mask_00f0();
|
||||
EXPECT_SIMDINT_EQ(mask_00f0, 0, 0, 0xffffffff, 0);
|
||||
|
||||
const SimdInt4 mask_000f = ozz::math::simd_int4::mask_000f();
|
||||
EXPECT_SIMDINT_EQ(mask_000f, 0, 0, 0, 0xffffffff);
|
||||
}
|
||||
|
||||
TEST(SplatInt, ozz_simd_math) {
|
||||
const SimdInt4 i = ozz::math::simd_int4::Load(1, -1, 2, -3);
|
||||
|
||||
const SimdInt4 x = ozz::math::SplatX(i);
|
||||
EXPECT_SIMDINT_EQ(x, 1, 1, 1, 1);
|
||||
|
||||
const SimdInt4 y = ozz::math::SplatY(i);
|
||||
EXPECT_SIMDINT_EQ(y, -1, -1, -1, -1);
|
||||
|
||||
const SimdInt4 z = ozz::math::SplatZ(i);
|
||||
EXPECT_SIMDINT_EQ(z, 2, 2, 2, 2);
|
||||
|
||||
const SimdInt4 w = ozz::math::SplatW(i);
|
||||
EXPECT_SIMDINT_EQ(w, -3, -3, -3, -3);
|
||||
|
||||
const SimdInt4 s3210 = ozz::math::Swizzle<3, 2, 1, 0>(i);
|
||||
EXPECT_SIMDINT_EQ(s3210, -3, 2, -1, 1);
|
||||
|
||||
const SimdInt4 s0123 = ozz::math::Swizzle<0, 1, 2, 3>(i);
|
||||
EXPECT_SIMDINT_EQ(s0123, 1, -1, 2, -3);
|
||||
|
||||
const SimdInt4 s0011 = ozz::math::Swizzle<0, 0, 1, 1>(i);
|
||||
EXPECT_SIMDINT_EQ(s0011, 1, 1, -1, -1);
|
||||
|
||||
const SimdInt4 s2233 = ozz::math::Swizzle<2, 2, 3, 3>(i);
|
||||
EXPECT_SIMDINT_EQ(s2233, 2, 2, -3, -3);
|
||||
|
||||
const SimdInt4 s0101 = ozz::math::Swizzle<0, 1, 0, 1>(i);
|
||||
EXPECT_SIMDINT_EQ(s0101, 1, -1, 1, -1);
|
||||
|
||||
const SimdInt4 s2323 = ozz::math::Swizzle<2, 3, 2, 3>(i);
|
||||
EXPECT_SIMDINT_EQ(s2323, 2, -3, 2, -3);
|
||||
}
|
||||
|
||||
TEST(FromFloat, ozz_simd_math) {
|
||||
const ozz::math::SimdFloat4 f =
|
||||
ozz::math::simd_float4::Load(0.f, 46.93f, 46.26f, -93.99f);
|
||||
EXPECT_SIMDINT_EQ(ozz::math::simd_int4::FromFloatRound(f), 0, 47, 46, -94);
|
||||
EXPECT_SIMDINT_EQ(ozz::math::simd_int4::FromFloatTrunc(f), 0, 46, 46, -93);
|
||||
}
|
||||
|
||||
TEST(ArithmeticInt, ozz_simd_math) {
|
||||
const SimdInt4 a = ozz::math::simd_int4::Load(0, 1, 2, 3);
|
||||
const SimdInt4 b = ozz::math::simd_int4::Load(4, 5, -6, 7);
|
||||
|
||||
const SimdInt4 hadd2 = ozz::math::HAdd2(a);
|
||||
EXPECT_SIMDINT_EQ(hadd2, 1, 1, 2, 3);
|
||||
|
||||
const SimdInt4 hadd3 = ozz::math::HAdd3(a);
|
||||
EXPECT_SIMDINT_EQ(hadd3, 3, 1, 2, 3);
|
||||
|
||||
const SimdInt4 hadd4 = ozz::math::HAdd4(a);
|
||||
EXPECT_SIMDINT_EQ(hadd4, 6, 1, 2, 3);
|
||||
|
||||
const SimdInt4 abs = ozz::math::Abs(b);
|
||||
EXPECT_SIMDINT_EQ(abs, 4, 5, 6, 7);
|
||||
|
||||
const SimdInt4 sign = ozz::math::Sign(b);
|
||||
EXPECT_SIMDINT_EQ(sign, 0, 0, 0x80000000, 0);
|
||||
}
|
||||
|
||||
TEST(CompareInt, ozz_simd_math) {
|
||||
const SimdInt4 a = ozz::math::simd_int4::Load(0, 1, 2, 3);
|
||||
const SimdInt4 b = ozz::math::simd_int4::Load(4, 1, -6, 7);
|
||||
const SimdInt4 c = ozz::math::simd_int4::Load(4, 5, 6, 7);
|
||||
|
||||
const SimdInt4 min = ozz::math::Min(a, b);
|
||||
EXPECT_SIMDINT_EQ(min, 0, 1, -6, 3);
|
||||
|
||||
const SimdInt4 max = ozz::math::Max(a, b);
|
||||
EXPECT_SIMDINT_EQ(max, 4, 1, 2, 7);
|
||||
|
||||
const SimdInt4 min0 = ozz::math::Min0(b);
|
||||
EXPECT_SIMDINT_EQ(min0, 0, 0, -6, 0);
|
||||
|
||||
const SimdInt4 max0 = ozz::math::Max0(b);
|
||||
EXPECT_SIMDINT_EQ(max0, 4, 1, 0, 7);
|
||||
|
||||
EXPECT_SIMDINT_EQ(
|
||||
ozz::math::Clamp(a, ozz::math::simd_int4::Load(-12, 2, 9, 3), c), 0, 2, 6,
|
||||
3);
|
||||
|
||||
const SimdInt4 eq1 = ozz::math::CmpEq(a, b);
|
||||
EXPECT_SIMDINT_EQ(eq1, 0, 0xffffffff, 0, 0);
|
||||
|
||||
const SimdInt4 eq2 = ozz::math::CmpEq(a, a);
|
||||
EXPECT_SIMDINT_EQ(eq2, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff);
|
||||
|
||||
const SimdInt4 neq1 = ozz::math::CmpNe(a, b);
|
||||
EXPECT_SIMDINT_EQ(neq1, 0xffffffff, 0, 0xffffffff, 0xffffffff);
|
||||
|
||||
const SimdInt4 neq2 = ozz::math::CmpNe(a, a);
|
||||
EXPECT_SIMDINT_EQ(neq2, 0, 0, 0, 0);
|
||||
|
||||
const SimdInt4 lt = ozz::math::CmpLt(a, b);
|
||||
EXPECT_SIMDINT_EQ(lt, 0xffffffff, 0, 0, 0xffffffff);
|
||||
|
||||
const SimdInt4 le = ozz::math::CmpLe(a, b);
|
||||
EXPECT_SIMDINT_EQ(le, 0xffffffff, 0xffffffff, 0, 0xffffffff);
|
||||
|
||||
const SimdInt4 gt = ozz::math::CmpGt(a, b);
|
||||
EXPECT_SIMDINT_EQ(gt, 0, 0, 0xffffffff, 0);
|
||||
|
||||
const SimdInt4 ge = ozz::math::CmpGe(a, b);
|
||||
EXPECT_SIMDINT_EQ(ge, 0, 0xffffffff, 0xffffffff, 0);
|
||||
}
|
||||
|
||||
TEST(MaskInt, ozz_simd_math) {
|
||||
EXPECT_EQ(ozz::math::MoveMask(ozz::math::simd_int4::all_false()), 0x00000000);
|
||||
EXPECT_EQ(ozz::math::MoveMask(ozz::math::simd_int4::all_true()), 0x0000000f);
|
||||
EXPECT_EQ(ozz::math::MoveMask(ozz::math::simd_int4::mask_f000()), 0x00000001);
|
||||
EXPECT_EQ(ozz::math::MoveMask(ozz::math::simd_int4::mask_0f00()), 0x00000002);
|
||||
EXPECT_EQ(ozz::math::MoveMask(ozz::math::simd_int4::mask_00f0()), 0x00000004);
|
||||
EXPECT_EQ(ozz::math::MoveMask(ozz::math::simd_int4::mask_000f()), 0x00000008);
|
||||
EXPECT_EQ(ozz::math::MoveMask(ozz::math::simd_int4::Load(
|
||||
0xffffffff, 0x00000000, 0x80000001, 0x7fffffff)),
|
||||
0x00000005);
|
||||
EXPECT_EQ(ozz::math::MoveMask(ozz::math::simd_int4::Load(
|
||||
0xffffffff, 0x1000000f, 0x80000001, 0x8ffffffe)),
|
||||
0x0000000d);
|
||||
EXPECT_TRUE(ozz::math::AreAllFalse(ozz::math::simd_int4::all_false()));
|
||||
EXPECT_FALSE(ozz::math::AreAllFalse(ozz::math::simd_int4::all_true()));
|
||||
EXPECT_FALSE(ozz::math::AreAllFalse(ozz::math::simd_int4::mask_000f()));
|
||||
|
||||
EXPECT_TRUE(ozz::math::AreAllTrue(ozz::math::simd_int4::all_true()));
|
||||
EXPECT_FALSE(ozz::math::AreAllTrue(ozz::math::simd_int4::all_false()));
|
||||
EXPECT_FALSE(ozz::math::AreAllTrue(ozz::math::simd_int4::mask_000f()));
|
||||
|
||||
EXPECT_TRUE(ozz::math::AreAllFalse3(ozz::math::simd_int4::all_false()));
|
||||
EXPECT_TRUE(ozz::math::AreAllFalse3(ozz::math::simd_int4::mask_000f()));
|
||||
EXPECT_FALSE(ozz::math::AreAllFalse3(ozz::math::simd_int4::all_true()));
|
||||
EXPECT_FALSE(ozz::math::AreAllFalse3(ozz::math::simd_int4::mask_f000()));
|
||||
|
||||
EXPECT_TRUE(ozz::math::AreAllTrue3(ozz::math::simd_int4::all_true()));
|
||||
EXPECT_FALSE(ozz::math::AreAllTrue3(ozz::math::simd_int4::all_false()));
|
||||
EXPECT_FALSE(ozz::math::AreAllTrue3(ozz::math::simd_int4::mask_f000()));
|
||||
|
||||
EXPECT_TRUE(ozz::math::AreAllFalse2(ozz::math::simd_int4::all_false()));
|
||||
EXPECT_TRUE(ozz::math::AreAllFalse2(ozz::math::simd_int4::mask_000f()));
|
||||
EXPECT_FALSE(ozz::math::AreAllFalse2(ozz::math::simd_int4::all_true()));
|
||||
EXPECT_FALSE(ozz::math::AreAllFalse2(ozz::math::simd_int4::mask_f000()));
|
||||
|
||||
EXPECT_TRUE(ozz::math::AreAllTrue2(ozz::math::simd_int4::all_true()));
|
||||
EXPECT_FALSE(ozz::math::AreAllTrue2(ozz::math::simd_int4::all_false()));
|
||||
EXPECT_FALSE(ozz::math::AreAllTrue2(ozz::math::simd_int4::mask_f000()));
|
||||
|
||||
EXPECT_TRUE(ozz::math::AreAllFalse1(ozz::math::simd_int4::all_false()));
|
||||
EXPECT_TRUE(ozz::math::AreAllFalse1(ozz::math::simd_int4::mask_000f()));
|
||||
EXPECT_FALSE(ozz::math::AreAllFalse1(ozz::math::simd_int4::all_true()));
|
||||
EXPECT_FALSE(ozz::math::AreAllFalse1(ozz::math::simd_int4::mask_f000()));
|
||||
|
||||
EXPECT_TRUE(ozz::math::AreAllTrue1(ozz::math::simd_int4::all_true()));
|
||||
EXPECT_FALSE(ozz::math::AreAllTrue1(ozz::math::simd_int4::all_false()));
|
||||
EXPECT_TRUE(ozz::math::AreAllTrue1(ozz::math::simd_int4::mask_f000()));
|
||||
}
|
||||
|
||||
TEST(LogicalInt, ozz_simd_math) {
|
||||
const SimdInt4 a = ozz::math::simd_int4::Load(0xffffffff, 0x00000000,
|
||||
0x80000001, 0x7fffffff);
|
||||
const SimdInt4 b = ozz::math::simd_int4::Load(0x80000001, 0xffffffff,
|
||||
0x7fffffff, 0x00000000);
|
||||
const SimdInt4 c = ozz::math::simd_int4::Load(0x01234567, 0x89abcdef,
|
||||
0x01234567, 0x89abcdef);
|
||||
const SimdInt4 cond = ozz::math::simd_int4::Load(0xffffffff, 0x00000000,
|
||||
0xffffffff, 0x00000000);
|
||||
|
||||
const SimdInt4 andm = ozz::math::And(a, b);
|
||||
EXPECT_SIMDINT_EQ(andm, 0x80000001, 0x00000000, 0x00000001, 0x00000000);
|
||||
|
||||
const SimdInt4 andnm = ozz::math::AndNot(a, b);
|
||||
EXPECT_SIMDINT_EQ(andnm, 0x7ffffffe, 0x00000000, 0x80000000, 0x7fffffff);
|
||||
|
||||
const SimdInt4 orm = ozz::math::Or(a, b);
|
||||
EXPECT_SIMDINT_EQ(orm, 0xffffffff, 0xffffffff, 0xffffffff, 0x7fffffff);
|
||||
|
||||
const SimdInt4 xorm = ozz::math::Xor(a, b);
|
||||
EXPECT_SIMDINT_EQ(xorm, 0x7ffffffe, 0xffffffff, 0xfffffffe, 0x7fffffff);
|
||||
|
||||
const SimdInt4 select = ozz::math::Select(cond, b, c);
|
||||
EXPECT_SIMDINT_EQ(select, 0x80000001, 0x89abcdef, 0x7fffffff, 0x89abcdef);
|
||||
}
|
||||
|
||||
TEST(ShiftInt, ozz_simd_math) {
|
||||
const SimdInt4 a = ozz::math::simd_int4::Load(0xffffffff, 0x00000000,
|
||||
0x80000001, 0x7fffffff);
|
||||
|
||||
const SimdInt4 shift_l = ozz::math::ShiftL(a, 3);
|
||||
EXPECT_SIMDINT_EQ(shift_l, 0xfffffff8, 0x00000000, 0x00000008, 0xfffffff8);
|
||||
|
||||
const SimdInt4 shift_r = ozz::math::ShiftR(a, 3);
|
||||
EXPECT_SIMDINT_EQ(shift_r, 0xffffffff, 0x00000000, 0xf0000000, 0x0fffffff);
|
||||
|
||||
const SimdInt4 shift_ru = ozz::math::ShiftRu(a, 3);
|
||||
EXPECT_SIMDINT_EQ(shift_ru, 0x1fffffff, 0x00000000, 0x10000000, 0x0fffffff);
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
//----------------------------------------------------------------------------//
|
||||
// //
|
||||
// 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_math_archive.h"
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include "ozz/base/maths/gtest_math_helper.h"
|
||||
|
||||
#include "ozz/base/io/archive.h"
|
||||
#include "ozz/base/maths/simd_math.h"
|
||||
|
||||
TEST(SimdMathArchive, ozz_simd_math) {
|
||||
for (int e = 0; e < 2; ++e) {
|
||||
ozz::Endianness endianess = e == 0 ? ozz::kBigEndian : ozz::kLittleEndian;
|
||||
|
||||
ozz::io::MemoryStream stream;
|
||||
ASSERT_TRUE(stream.opened());
|
||||
|
||||
// Write soa math types.
|
||||
ozz::io::OArchive o(&stream, endianess);
|
||||
const ozz::math::SimdFloat4 of4 =
|
||||
ozz::math::simd_float4::Load(46.f, 58.f, 14.f, 5.f);
|
||||
o << of4;
|
||||
const ozz::math::SimdInt4 oi4 = ozz::math::simd_int4::Load(46, 58, 14, 5);
|
||||
o << oi4;
|
||||
const ozz::math::Float4x4 of44 = {
|
||||
{ozz::math::simd_float4::Load(46.f, 58.f, 14.f, 5.f),
|
||||
ozz::math::simd_float4::Load(26.f, 35.f, 1.f, 27.f),
|
||||
ozz::math::simd_float4::Load(99.f, 11.f, 4.f, 46.f),
|
||||
ozz::math::simd_float4::Load(58.f, 26.f, 14.f, 99.f)}};
|
||||
o << of44;
|
||||
|
||||
// Reads soa math types.
|
||||
stream.Seek(0, ozz::io::Stream::kSet);
|
||||
ozz::io::IArchive i(&stream);
|
||||
ozz::math::SimdFloat4 if4;
|
||||
i >> if4;
|
||||
EXPECT_SIMDFLOAT_EQ(if4, 46.f, 58.f, 14.f, 5.f);
|
||||
ozz::math::SimdInt4 ii4;
|
||||
i >> ii4;
|
||||
EXPECT_SIMDINT_EQ(ii4, 46, 58, 14, 5);
|
||||
ozz::math::Float4x4 if44;
|
||||
i >> if44;
|
||||
EXPECT_FLOAT4x4_EQ(if44, 46.f, 58.f, 14.f, 5.f, 26.f, 35.f, 1.f, 27.f, 99.f,
|
||||
11.f, 4.f, 46.f, 58.f, 26.f, 14.f, 99.f);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,122 @@
|
||||
//----------------------------------------------------------------------------//
|
||||
// //
|
||||
// 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_math.h"
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include "ozz/base/gtest_helper.h"
|
||||
#include "ozz/base/maths/gtest_math_helper.h"
|
||||
|
||||
using ozz::math::SimdFloat4;
|
||||
|
||||
TEST(TransposeFloat, ozz_simd_math) {
|
||||
const SimdFloat4 src[4] = {
|
||||
ozz::math::simd_float4::Load(0.f, 1.f, 2.f, 3.f),
|
||||
ozz::math::simd_float4::Load(4.f, 5.f, 6.f, 7.f),
|
||||
ozz::math::simd_float4::Load(8.f, 9.f, 10.f, 11.f),
|
||||
ozz::math::simd_float4::Load(12.f, 13.f, 14.f, 15.f)};
|
||||
|
||||
SimdFloat4 t4x1[1];
|
||||
ozz::math::Transpose4x1(src, t4x1);
|
||||
EXPECT_SIMDFLOAT_EQ(t4x1[0], 0.f, 4.f, 8.f, 12.f);
|
||||
|
||||
SimdFloat4 t1x4[4];
|
||||
ozz::math::Transpose1x4(src, t1x4);
|
||||
EXPECT_SIMDFLOAT_EQ(t1x4[0], 0.f, 0.f, 0.f, 0.f);
|
||||
EXPECT_SIMDFLOAT_EQ(t1x4[1], 1.f, 0.f, 0.f, 0.f);
|
||||
EXPECT_SIMDFLOAT_EQ(t1x4[2], 2.f, 0.f, 0.f, 0.f);
|
||||
EXPECT_SIMDFLOAT_EQ(t1x4[3], 3.f, 0.f, 0.f, 0.f);
|
||||
|
||||
SimdFloat4 t4x2[2];
|
||||
ozz::math::Transpose4x2(src, t4x2);
|
||||
EXPECT_SIMDFLOAT_EQ(t4x2[0], 0.f, 4.f, 8.f, 12.f);
|
||||
EXPECT_SIMDFLOAT_EQ(t4x2[1], 1.f, 5.f, 9.f, 13.f);
|
||||
|
||||
SimdFloat4 t2x4[4];
|
||||
ozz::math::Transpose2x4(src, t2x4);
|
||||
EXPECT_SIMDFLOAT_EQ(t2x4[0], 0.f, 4.f, 0.f, 0.f);
|
||||
EXPECT_SIMDFLOAT_EQ(t2x4[1], 1.f, 5.f, 0.f, 0.f);
|
||||
EXPECT_SIMDFLOAT_EQ(t2x4[2], 2.f, 6.f, 0.f, 0.f);
|
||||
EXPECT_SIMDFLOAT_EQ(t2x4[3], 3.f, 7.f, 0.f, 0.f);
|
||||
|
||||
SimdFloat4 t4x3[3];
|
||||
ozz::math::Transpose4x3(src, t4x3);
|
||||
EXPECT_SIMDFLOAT_EQ(t4x3[0], 0.f, 4.f, 8.f, 12.f);
|
||||
EXPECT_SIMDFLOAT_EQ(t4x3[1], 1.f, 5.f, 9.f, 13.f);
|
||||
EXPECT_SIMDFLOAT_EQ(t4x3[2], 2.f, 6.f, 10.f, 14.f);
|
||||
|
||||
SimdFloat4 t3x4[4];
|
||||
ozz::math::Transpose3x4(src, t3x4);
|
||||
EXPECT_SIMDFLOAT_EQ(t3x4[0], 0.f, 4.f, 8.f, 0.f);
|
||||
EXPECT_SIMDFLOAT_EQ(t3x4[1], 1.f, 5.f, 9.f, 0.f);
|
||||
EXPECT_SIMDFLOAT_EQ(t3x4[2], 2.f, 6.f, 10.f, 0.f);
|
||||
EXPECT_SIMDFLOAT_EQ(t3x4[3], 3.f, 7.f, 11.f, 0.f);
|
||||
|
||||
SimdFloat4 t4x4[4];
|
||||
ozz::math::Transpose4x4(src, t4x4);
|
||||
EXPECT_SIMDFLOAT_EQ(t4x4[0], 0.f, 4.f, 8.f, 12.f);
|
||||
EXPECT_SIMDFLOAT_EQ(t4x4[1], 1.f, 5.f, 9.f, 13.f);
|
||||
EXPECT_SIMDFLOAT_EQ(t4x4[2], 2.f, 6.f, 10.f, 14.f);
|
||||
EXPECT_SIMDFLOAT_EQ(t4x4[3], 3.f, 7.f, 11.f, 15.f);
|
||||
|
||||
const SimdFloat4 src2[16] = {
|
||||
ozz::math::simd_float4::Load(0.f, 16.f, 32.f, 48.f),
|
||||
ozz::math::simd_float4::Load(1.f, 17.f, 33.f, 49.f),
|
||||
ozz::math::simd_float4::Load(2.f, 18.f, 34.f, 50.f),
|
||||
ozz::math::simd_float4::Load(3.f, 19.f, 35.f, 51.f),
|
||||
ozz::math::simd_float4::Load(4.f, 20.f, 36.f, 52.f),
|
||||
ozz::math::simd_float4::Load(5.f, 21.f, 37.f, 53.f),
|
||||
ozz::math::simd_float4::Load(6.f, 22.f, 38.f, 54.f),
|
||||
ozz::math::simd_float4::Load(7.f, 23.f, 39.f, 55.f),
|
||||
ozz::math::simd_float4::Load(8.f, 24.f, 40.f, 56.f),
|
||||
ozz::math::simd_float4::Load(9.f, 25.f, 41.f, 57.f),
|
||||
ozz::math::simd_float4::Load(10.f, 26.f, 42.f, 58.f),
|
||||
ozz::math::simd_float4::Load(11.f, 27.f, 43.f, 59.f),
|
||||
ozz::math::simd_float4::Load(12.f, 28.f, 44.f, 60.f),
|
||||
ozz::math::simd_float4::Load(13.f, 29.f, 45.f, 61.f),
|
||||
ozz::math::simd_float4::Load(14.f, 30.f, 46.f, 62.f),
|
||||
ozz::math::simd_float4::Load(15.f, 31.f, 47.f, 63.f)};
|
||||
SimdFloat4 t16x16[16];
|
||||
ozz::math::Transpose16x16(src2, t16x16);
|
||||
EXPECT_SIMDFLOAT_EQ(t16x16[0], 0.f, 1.f, 2.f, 3.f);
|
||||
EXPECT_SIMDFLOAT_EQ(t16x16[1], 4.f, 5.f, 6.f, 7.f);
|
||||
EXPECT_SIMDFLOAT_EQ(t16x16[2], 8.f, 9.f, 10.f, 11.f);
|
||||
EXPECT_SIMDFLOAT_EQ(t16x16[3], 12.f, 13.f, 14.f, 15.f);
|
||||
EXPECT_SIMDFLOAT_EQ(t16x16[4], 16.f, 17.f, 18.f, 19.f);
|
||||
EXPECT_SIMDFLOAT_EQ(t16x16[5], 20.f, 21.f, 22.f, 23.f);
|
||||
EXPECT_SIMDFLOAT_EQ(t16x16[6], 24.f, 25.f, 26.f, 27.f);
|
||||
EXPECT_SIMDFLOAT_EQ(t16x16[7], 28.f, 29.f, 30.f, 31.f);
|
||||
EXPECT_SIMDFLOAT_EQ(t16x16[8], 32.f, 33.f, 34.f, 35.f);
|
||||
EXPECT_SIMDFLOAT_EQ(t16x16[9], 36.f, 37.f, 38.f, 39.f);
|
||||
EXPECT_SIMDFLOAT_EQ(t16x16[10], 40.f, 41.f, 42.f, 43.f);
|
||||
EXPECT_SIMDFLOAT_EQ(t16x16[11], 44.f, 45.f, 46.f, 47.f);
|
||||
EXPECT_SIMDFLOAT_EQ(t16x16[12], 48.f, 49.f, 50.f, 51.f);
|
||||
EXPECT_SIMDFLOAT_EQ(t16x16[13], 52.f, 53.f, 54.f, 55.f);
|
||||
EXPECT_SIMDFLOAT_EQ(t16x16[14], 56.f, 57.f, 58.f, 59.f);
|
||||
EXPECT_SIMDFLOAT_EQ(t16x16[15], 60.f, 61.f, 62.f, 63.f);
|
||||
}
|
||||
@@ -0,0 +1,460 @@
|
||||
//----------------------------------------------------------------------------//
|
||||
// //
|
||||
// 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);
|
||||
}
|
||||
@@ -0,0 +1,306 @@
|
||||
//----------------------------------------------------------------------------//
|
||||
// //
|
||||
// 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_float4x4.h"
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include "ozz/base/gtest_helper.h"
|
||||
#include "ozz/base/maths/gtest_math_helper.h"
|
||||
|
||||
using ozz::math::SoaFloat3;
|
||||
using ozz::math::SoaFloat4;
|
||||
using ozz::math::SoaFloat4x4;
|
||||
using ozz::math::SoaQuaternion;
|
||||
|
||||
TEST(SoaFloat4x4Constant, ozz_soa_math) {
|
||||
const SoaFloat4x4 identity = SoaFloat4x4::identity();
|
||||
EXPECT_SOAFLOAT4x4_EQ(identity, 1.f, 1.f, 1.f, 1.f, 0.f, 0.f, 0.f, 0.f, 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, 0.f, 0.f, 0.f, 0.f, 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, 0.f, 0.f, 0.f, 0.f, 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(SoaFloat4x4Arithmetic, ozz_soa_math) {
|
||||
const SoaFloat4x4 m0 = {
|
||||
{{ozz::math::simd_float4::Load(0.f, 1.f, 0.f, 0.f),
|
||||
ozz::math::simd_float4::Load(1.f, 0.f, 0.f, 0.f),
|
||||
ozz::math::simd_float4::Load(2.f, 0.f, 0.f, -1.f),
|
||||
ozz::math::simd_float4::Load(3.f, 0.f, 0.f, 0.f)},
|
||||
{ozz::math::simd_float4::Load(4.f, 0.f, 0.f, 0.f),
|
||||
ozz::math::simd_float4::Load(5.f, 1.f, 0.f, 1.f),
|
||||
ozz::math::simd_float4::Load(6.f, 0.f, 0.f, 0.f),
|
||||
ozz::math::simd_float4::Load(7.f, 0.f, 0.f, 0.f)},
|
||||
{ozz::math::simd_float4::Load(8.f, 0.f, 0.f, 1.f),
|
||||
ozz::math::simd_float4::Load(9.f, 0.f, 0.f, 0.f),
|
||||
ozz::math::simd_float4::Load(10.f, 1.f, 0.f, 0.f),
|
||||
ozz::math::simd_float4::Load(11.f, 0.f, 0.f, 0.f)},
|
||||
{ozz::math::simd_float4::Load(12.f, 0.f, 0.f, 0.f),
|
||||
ozz::math::simd_float4::Load(13.f, 0.f, 0.f, 0.f),
|
||||
ozz::math::simd_float4::Load(14.f, 0.f, 0.f, 0.f),
|
||||
ozz::math::simd_float4::Load(15.f, 1.f, 0.f, 1.f)}}};
|
||||
const SoaFloat4x4 m1 = {
|
||||
{{ozz::math::simd_float4::Load(-0.f, 0.f, 0.f, 1.f),
|
||||
ozz::math::simd_float4::Load(-1.f, -1.f, 0.f, 0.f),
|
||||
ozz::math::simd_float4::Load(-2.f, 2.f, -1.f, 0.f),
|
||||
ozz::math::simd_float4::Load(-3.f, 3.f, 0.f, 0.f)},
|
||||
{ozz::math::simd_float4::Load(-4.f, -4.f, 0.f, 0.f),
|
||||
ozz::math::simd_float4::Load(-5.f, 5.f, 1.f, 1.f),
|
||||
ozz::math::simd_float4::Load(-6.f, 6.f, 0.f, 0.f),
|
||||
ozz::math::simd_float4::Load(-7.f, -7.f, 0.f, 0.f)},
|
||||
{ozz::math::simd_float4::Load(-8.f, 8.f, 1.f, 0.f),
|
||||
ozz::math::simd_float4::Load(-9.f, -9.f, 0.f, 0.f),
|
||||
ozz::math::simd_float4::Load(-10.f, -10.f, 0.f, 1.f),
|
||||
ozz::math::simd_float4::Load(-11.f, 11.f, 0.f, 0.f)},
|
||||
{ozz::math::simd_float4::Load(-12.f, -12.f, 0.f, 0.f),
|
||||
ozz::math::simd_float4::Load(-13.f, 13.f, 0.f, 0.f),
|
||||
ozz::math::simd_float4::Load(-14.f, -14.f, 0.f, 0.f),
|
||||
ozz::math::simd_float4::Load(-15.f, 15.f, 1.f, 1.f)}}};
|
||||
const SoaFloat4x4 m2 = {
|
||||
{{ozz::math::simd_float4::Load(2.f, 0.f, 0.f, 1.f),
|
||||
ozz::math::simd_float4::Load(0.f, -1.f, 0.f, 0.f),
|
||||
ozz::math::simd_float4::Load(0.f, 2.f, -1.f, 0.f),
|
||||
ozz::math::simd_float4::Load(0.f, 3.f, 0.f, 0.f)},
|
||||
{ozz::math::simd_float4::Load(0.f, -4.f, 0.f, 0.f),
|
||||
ozz::math::simd_float4::Load(0.f, 5.f, 1.f, 1.f),
|
||||
ozz::math::simd_float4::Load(-2.f, 6.f, 0.f, 0.f),
|
||||
ozz::math::simd_float4::Load(0.f, -7.f, 0.f, 0.f)},
|
||||
{ozz::math::simd_float4::Load(0.f, 8.f, 1.f, 0.f),
|
||||
ozz::math::simd_float4::Load(3.f, -9.f, 0.f, 0.f),
|
||||
ozz::math::simd_float4::Load(0.f, -10.f, 0.f, 1.f),
|
||||
ozz::math::simd_float4::Load(0.f, 11.f, 0.f, 0.f)},
|
||||
{ozz::math::simd_float4::Load(0.f, -12.f, 0.f, 0.f),
|
||||
ozz::math::simd_float4::Load(46.f, 13.f, 0.f, 0.f),
|
||||
ozz::math::simd_float4::Load(12.f, -14.f, 0.f, 0.f),
|
||||
ozz::math::simd_float4::Load(1.f, 15.f, 1.f, 1.f)}}};
|
||||
const SoaFloat4 v = {ozz::math::simd_float4::Load(0.f, 1.f, -2.f, 3.f),
|
||||
ozz::math::simd_float4::Load(-1.f, 2.f, 5.f, 46.f),
|
||||
ozz::math::simd_float4::Load(-2.f, 3.f, 7.f, -1.f),
|
||||
ozz::math::simd_float4::Load(-3.f, 4.f, 0.f, 1.f)};
|
||||
const SoaFloat4 mul_vector = m0 * v;
|
||||
EXPECT_SOAFLOAT4_EQ(mul_vector, -56.f, 1.f, 0.f, -1.f, -62.f, 2.f, 0.f, 46,
|
||||
-68.f, 3.f, 0.f, -3.f, -74.f, 4.f, 0.f, 1.f);
|
||||
|
||||
const SoaFloat4x4 mul_mat = m0 * m1;
|
||||
EXPECT_SOAFLOAT4x4_EQ(
|
||||
mul_mat, -56.f, 0.f, 0.f, 0.f, -62.f, -1.f, 0.f, 0.f, -68.f, 2.f, 0.f,
|
||||
-1.f, -74.f, 3.f, 0.f, 0.f, -152.f, -4.f, 0.f, 0.f, -174.f, 5.f, 0.f, 1.f,
|
||||
-196.f, 6.f, 0.f, 0.f, -218.f, -7.f, 0.f, 0.f, -248.f, 8.f, 0.f, 1.f,
|
||||
-286.f, -9.f, 0.f, 0.f, -324.f, -10.f, 0.f, 0.f, -362.f, 11.f, 0.f, 0.f,
|
||||
-344.f, -12.f, 0.f, 0.f, -398.f, 13.f, 0.f, 0.f, -452.f, -14.f, 0.f, 0.f,
|
||||
-506.f, 15.f, 0.f, 1.f);
|
||||
|
||||
const SoaFloat4x4 add_mat = m0 + m1;
|
||||
EXPECT_SOAFLOAT4x4_EQ(
|
||||
add_mat, 0.f, 1.f, 0.f, 1.f, 0.f, -1.f, 0.f, 0.f, 0.f, 2.f, -1.f, -1.f,
|
||||
0.f, 3.f, 0.f, 0.f, 0.f, -4.f, 0.f, 0.f, 0.f, 6.f, 1.f, 2.f, 0.f, 6.f,
|
||||
0.f, 0.f, 0.f, -7.f, 0.f, 0.f, 0.f, 8.f, 1.f, 1.f, 0.f, -9.f, 0.f, 0.f,
|
||||
0.f, -9.f, 0.f, 1.f, 0.f, 11.f, 0.f, 0.f, 0.f, -12.f, 0.f, 0.f, 0.f, 13.f,
|
||||
0.f, 0.f, 0.f, -14.f, 0.f, 0.f, 0.f, 16.f, 1.f, 2.f);
|
||||
|
||||
const SoaFloat4x4 sub_mat = m0 - m1;
|
||||
EXPECT_SOAFLOAT4x4_EQ(
|
||||
sub_mat, 0.f, 1.f, 0.f, -1.f, 2.f, 1.f, 0.f, 0.f, 4.f, -2.f, 1.f, -1.f,
|
||||
6.f, -3.f, 0.f, 0.f, 8.f, 4.f, 0.f, 0.f, 10.f, -4.f, -1.f, 0.f, 12.f,
|
||||
-6.f, 0.f, 0.f, 14.f, 7.f, 0.f, 0.f, 16.f, -8.f, -1.f, 1.f, 18.f, 9.f,
|
||||
0.f, 0.f, 20.f, 11.f, 0.f, -1.f, 22.f, -11.f, 0.f, 0.f, 24.f, 12.f, 0.f,
|
||||
0.f, 26.f, -13.f, 0.f, 0.f, 28.f, 14.f, 0.f, 0.f, 30.f, -14.f, -1.f, 0.f);
|
||||
|
||||
const SoaFloat4x4 transpose = Transpose(m0);
|
||||
EXPECT_SOAFLOAT4x4_EQ(
|
||||
transpose, 0.f, 1.f, 0.f, 0.f, 4.f, 0.f, 0.f, 0.f, 8.f, 0.f, 0.f, 1.f,
|
||||
12.f, 0.f, 0.f, 0.f, 1.f, 0.f, 0.f, 0.f, 5.f, 1.f, 0.f, 1.f, 9.f, 0.f,
|
||||
0.f, 0.f, 13.f, 0.f, 0.f, 0.f, 2.f, 0.f, 0.f, -1.f, 6.f, 0.f, 0.f, 0.f,
|
||||
10.f, 1.f, 0.f, 0.f, 14.f, 0.f, 0.f, 0.f, 3.f, 0.f, 0.f, 0.f, 7.f, 0.f,
|
||||
0.f, 0.f, 11.f, 0.f, 0.f, 0.f, 15.f, 1.f, 0.f, 1.f);
|
||||
|
||||
const SoaFloat4x4 invert_ident = Invert(SoaFloat4x4::identity());
|
||||
EXPECT_SOAFLOAT4x4_EQ(
|
||||
invert_ident, 1.f, 1.f, 1.f, 1.f, 0.f, 0.f, 0.f, 0.f, 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, 0.f, 0.f, 0.f,
|
||||
0.f, 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, 0.f, 0.f, 0.f, 0.f, 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);
|
||||
|
||||
const SoaFloat4x4 invert = Invert(m2);
|
||||
EXPECT_SOAFLOAT4x4_EQ(invert, .5f, .216667f, 0.f, 1.f, 0.f, 2.75f, 0.f, 0.f,
|
||||
0.f, 1.6f, 1.f, 0.f, 0.f, .066666f, 0.f, 0.f, 0.f, .2f,
|
||||
0.f, 0.f, 0.f, 2.5f, 1.f, 1.f, .333333f, 1.4f, 0.f, 0.f,
|
||||
0.f, .1f, 0.f, 0.f, 0.f, .25f, -1.f, 0.f, -.5f, .5f,
|
||||
0.f, 0.f, 0.f, .25f, 0.f, 1.f, 0.f, 0.f, 0.f, 0.f, 0.f,
|
||||
.233333f, 0.f, 0.f, 6.f, .5f, 0.f, 0.f, -15.33333f, .3f,
|
||||
0.f, 0.f, 1.f, .03333f, 1.f, 1.f);
|
||||
|
||||
const SoaFloat4x4 invert_mul = m2 * invert;
|
||||
EXPECT_SOAFLOAT4x4_EQ(invert_mul, 1.f, 1.f, 1.f, 1.f, 0.f, 0.f, 0.f, 0.f, 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, 0.f, 0.f, 0.f, 0.f, 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, 0.f, 0.f, 0.f, 0.f, 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_ASSERTION(Invert(m0), "Matrix is not invertible");
|
||||
|
||||
// Invertible
|
||||
ozz::math::SimdInt4 invertible;
|
||||
EXPECT_SOAFLOAT4x4_EQ(
|
||||
Invert(m2, &invertible), .5f, .216667f, 0.f, 1.f, 0.f, 2.75f, 0.f, 0.f,
|
||||
0.f, 1.6f, 1.f, 0.f, 0.f, .066666f, 0.f, 0.f, 0.f, .2f, 0.f, 0.f, 0.f,
|
||||
2.5f, 1.f, 1.f, .333333f, 1.4f, 0.f, 0.f, 0.f, .1f, 0.f, 0.f, 0.f, .25f,
|
||||
-1.f, 0.f, -.5f, .5f, 0.f, 0.f, 0.f, .25f, 0.f, 1.f, 0.f, 0.f, 0.f, 0.f,
|
||||
0.f, .233333f, 0.f, 0.f, 6.f, .5f, 0.f, 0.f, -15.33333f, .3f, 0.f, 0.f,
|
||||
1.f, .03333f, 1.f, 1.f);
|
||||
EXPECT_SIMDINT_EQ(invertible, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff);
|
||||
|
||||
// Non invertible
|
||||
EXPECT_ASSERTION(Invert(m0), "Matrix is not invertible");
|
||||
|
||||
ozz::math::SimdInt4 not_invertible;
|
||||
EXPECT_SOAFLOAT4x4_EQ(
|
||||
Invert(m0, ¬_invertible), 0.f, 1.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f,
|
||||
0.f, 0.f, 1.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 1.f, 0.f, 1.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, 0.f, 0.f,
|
||||
0.f, 0.f, 0.f, 1.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 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, 0.f, 1.f);
|
||||
EXPECT_SIMDINT_EQ(not_invertible, 0, 0xffffffff, 0, 0xffffffff);
|
||||
}
|
||||
|
||||
TEST(SoaFloat4x4Scale, ozz_soa_math) {
|
||||
const SoaFloat4x4 m0 = {
|
||||
{{ozz::math::simd_float4::Load(0.f, 1.f, 0.f, 0.f),
|
||||
ozz::math::simd_float4::Load(1.f, 0.f, -1.f, 0.f),
|
||||
ozz::math::simd_float4::Load(2.f, 0.f, 2.f, -1.f),
|
||||
ozz::math::simd_float4::Load(3.f, 0.f, 3.f, 0.f)},
|
||||
{ozz::math::simd_float4::Load(4.f, 0.f, -4.f, 0.f),
|
||||
ozz::math::simd_float4::Load(5.f, 1.f, 5.f, 1.f),
|
||||
ozz::math::simd_float4::Load(6.f, 0.f, 6.f, 0.f),
|
||||
ozz::math::simd_float4::Load(7.f, 0.f, -7.f, 0.f)},
|
||||
{ozz::math::simd_float4::Load(8.f, 0.f, 8.f, 1.f),
|
||||
ozz::math::simd_float4::Load(9.f, 0.f, -9.f, 0.f),
|
||||
ozz::math::simd_float4::Load(10.f, 1.f, -10.f, 0.f),
|
||||
ozz::math::simd_float4::Load(11.f, 0.f, 11.f, 0.f)},
|
||||
{ozz::math::simd_float4::Load(12.f, 0.f, -12.f, 0.f),
|
||||
ozz::math::simd_float4::Load(13.f, 0.f, 13.f, 0.f),
|
||||
ozz::math::simd_float4::Load(14.f, 0.f, -14.f, 0.f),
|
||||
ozz::math::simd_float4::Load(15.f, 1.f, 15.f, 1.f)}}};
|
||||
const SoaFloat4 v = {ozz::math::simd_float4::Load(0.f, 1.f, -2.f, 3.f),
|
||||
ozz::math::simd_float4::Load(-1.f, 2.f, 5.f, 46.f),
|
||||
ozz::math::simd_float4::Load(-2.f, 3.f, 7.f, -1.f),
|
||||
ozz::math::simd_float4::Load(-3.f, 4.f, 0.f, 1.f)};
|
||||
|
||||
const SoaFloat4x4 scaling = SoaFloat4x4::Scaling(v);
|
||||
EXPECT_SOAFLOAT4x4_EQ(scaling, 0.f, 1.f, -2.f, 3.f, 0.f, 0.f, 0.f, 0.f, 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, 2.f, 5.f, 46.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f,
|
||||
0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, -2.f, 3.f,
|
||||
7.f, -1.f, 0.f, 0.f, 0.f, 0.f, 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);
|
||||
|
||||
const SoaFloat4x4 scale_mul = m0 * scaling;
|
||||
EXPECT_SOAFLOAT4x4_EQ(scale_mul, 0.f, 1.f, 0.f, 0.f, 0.f, 0.f, 2.f, 0.f, 0.f,
|
||||
0.f, -4.f, -3.f, 0.f, 0.f, -6.f, 0.f, -4.f, 0.f, -20.f,
|
||||
0.f, -5.f, 2.f, 25.f, 46.f, -6.f, 0.f, 30.f, 0.f, -7.f,
|
||||
0.f, -35.f, 0.f, -16.f, 0.f, 56.f, -1.f, -18.f, 0.f,
|
||||
-63.f, 0.f, -20.f, 3.f, -70.f, 0.f, -22.f, 0.f, 77.f,
|
||||
0.f, 12.f, 0.f, -12.f, 0.f, 13.f, 0.f, 13.f, 0.f, 14.f,
|
||||
0.f, -14.f, 0.f, 15.f, 1.f, 15.f, 1.f);
|
||||
|
||||
const SoaFloat4x4 scale = Scale(m0, v);
|
||||
EXPECT_SOAFLOAT4x4_EQ(scale, 0.f, 1.f, 0.f, 0.f, 0.f, 0.f, 2.f, 0.f, 0.f, 0.f,
|
||||
-4.f, -3.f, 0.f, 0.f, -6.f, 0.f, -4.f, 0.f, -20.f, 0.f,
|
||||
-5.f, 2.f, 25.f, 46.f, -6.f, 0.f, 30.f, 0.f, -7.f, 0.f,
|
||||
-35.f, 0.f, -16.f, 0.f, 56.f, -1.f, -18.f, 0.f, -63.f,
|
||||
0.f, -20.f, 3.f, -70.f, 0.f, -22.f, 0.f, 77.f, 0.f,
|
||||
12.f, 0.f, -12.f, 0.f, 13.f, 0.f, 13.f, 0.f, 14.f, 0.f,
|
||||
-14.f, 0.f, 15.f, 1.f, 15.f, 1.f);
|
||||
}
|
||||
|
||||
TEST(SoaFloat4x4Rotate, ozz_soa_math) {
|
||||
#ifndef NDEBUG
|
||||
const SoaQuaternion unormalized =
|
||||
SoaQuaternion::Load(ozz::math::simd_float4::Load(0.f, 0.f, 0.f, 0.f),
|
||||
ozz::math::simd_float4::Load(0.f, 0.f, 1.f, 0.f),
|
||||
ozz::math::simd_float4::Load(0.f, 0.f, 0.f, 0.f),
|
||||
ozz::math::simd_float4::Load(1.f, 1.f, 1.f, 1.f));
|
||||
#endif // NDEBUG
|
||||
EXPECT_ASSERTION(SoaFloat4x4::FromQuaternion(unormalized), "IsNormalized");
|
||||
|
||||
const SoaFloat4x4 identity =
|
||||
SoaFloat4x4::FromQuaternion(SoaQuaternion::identity());
|
||||
EXPECT_SOAFLOAT4x4_EQ(identity, 1.f, 1.f, 1.f, 1.f, 0.f, 0.f, 0.f, 0.f, 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, 0.f, 0.f, 0.f, 0.f, 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, 0.f, 0.f, 0.f, 0.f, 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);
|
||||
const SoaQuaternion quaternion = SoaQuaternion::Load(
|
||||
ozz::math::simd_float4::Load(.70710677f, 0.f, 0.f, -.382683432f),
|
||||
ozz::math::simd_float4::Load(0.f, .70710677f, 0.f, 0.f),
|
||||
ozz::math::simd_float4::Load(.70710677f, 0.f, 0.f, 0.f),
|
||||
ozz::math::simd_float4::Load(0.f, .70710677f, 1.f, .9238795f));
|
||||
const SoaFloat4x4 matrix = SoaFloat4x4::FromQuaternion(quaternion);
|
||||
EXPECT_SOAFLOAT4x4_EQ(
|
||||
matrix, 0.f, 0.f, 1.f, 1.f, 0.f, 0.f, 0.f, 0.f, 1.f, -1.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, .707106f, 0.f, 0.f,
|
||||
0.f, -.707106f, 0.f, 0.f, 0.f, 0.f, 1.f, 1.f, 0.f, 0.f, 0.f, 0.f, 0.f,
|
||||
.707106f, 0.f, 0.f, 1.f, .707106f, 0.f, 0.f, 0.f, 0.f, 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(SoaFloat4x4Affine, ozz_soa_math) {
|
||||
const SoaFloat4x4 identity = SoaFloat4x4::FromAffine(
|
||||
SoaFloat3::zero(), SoaQuaternion::identity(), SoaFloat3::one());
|
||||
EXPECT_SOAFLOAT4x4_EQ(identity, 1.f, 1.f, 1.f, 1.f, 0.f, 0.f, 0.f, 0.f, 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, 0.f, 0.f, 0.f, 0.f, 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, 0.f, 0.f, 0.f, 0.f, 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);
|
||||
const SoaFloat3 translation =
|
||||
SoaFloat3::Load(ozz::math::simd_float4::Load(0.f, 46.f, 7.f, -12.f),
|
||||
ozz::math::simd_float4::Load(0.f, 12.f, 7.f, -46.f),
|
||||
ozz::math::simd_float4::Load(0.f, 0.f, 7.f, 46.f));
|
||||
const SoaFloat3 scale =
|
||||
SoaFloat3::Load(ozz::math::simd_float4::Load(1.f, 1.f, -1.f, 0.1f),
|
||||
ozz::math::simd_float4::Load(1.f, 2.f, -1.f, 0.1f),
|
||||
ozz::math::simd_float4::Load(1.f, 3.f, -1.f, 0.1f));
|
||||
const SoaQuaternion quaternion = SoaQuaternion::Load(
|
||||
ozz::math::simd_float4::Load(.70710677f, 0.f, 0.f, -.382683432f),
|
||||
ozz::math::simd_float4::Load(0.f, .70710677f, 0.f, 0.f),
|
||||
ozz::math::simd_float4::Load(.70710677f, 0.f, 0.f, 0.f),
|
||||
ozz::math::simd_float4::Load(0.f, .70710677f, 1.f, .9238795f));
|
||||
const SoaFloat4x4 matrix =
|
||||
SoaFloat4x4::FromAffine(translation, quaternion, scale);
|
||||
EXPECT_SOAFLOAT4x4_EQ(
|
||||
matrix, 0.f, 0.f, -1.f, .1f, 0.f, 0.f, 0.f, 0.f, 1.f, -1.f, 0.f, 0.f, 0.f,
|
||||
0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, -1.f, 2.f, -1.f, .0707106f, 0.f, 0.f,
|
||||
0.f, -.0707106f, 0.f, 0.f, 0.f, 0.f, 1.f, 3.f, 0.f, 0.f, 0.f, 0.f, 0.f,
|
||||
.0707106f, 0.f, 0.f, -1.f, .0707106f, 0.f, 0.f, 0.f, 0.f, 0.f, 46.f, 7.f,
|
||||
-12.f, 0.f, 12.f, 7.f, -46.f, 0.f, 0.f, 7.f, 46.f, 1.f, 1.f, 1.f, 1.f);
|
||||
}
|
||||
@@ -0,0 +1,515 @@
|
||||
//----------------------------------------------------------------------------//
|
||||
// //
|
||||
// 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_float.h"
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include "ozz/base/gtest_helper.h"
|
||||
#include "ozz/base/maths/gtest_math_helper.h"
|
||||
|
||||
using ozz::math::SimdFloat4;
|
||||
using ozz::math::SoaFloat2;
|
||||
using ozz::math::SoaFloat3;
|
||||
using ozz::math::SoaFloat4;
|
||||
|
||||
TEST(SoaFloatLoad4, ozz_soa_math) {
|
||||
EXPECT_SOAFLOAT4_EQ(
|
||||
SoaFloat4::Load(ozz::math::simd_float4::Load(0.f, 1.f, 2.f, 3.f),
|
||||
ozz::math::simd_float4::Load(4.f, 5.f, 6.f, 7.f),
|
||||
ozz::math::simd_float4::Load(8.f, 9.f, 10.f, 11.f),
|
||||
ozz::math::simd_float4::Load(12.f, 13.f, 14.f, 15.f)),
|
||||
0.f, 1.f, 2.f, 3.f, 4.f, 5.f, 6.f, 7.f, 8.f, 9.f, 10.f, 11.f, 12.f, 13.f,
|
||||
14.f, 15.f);
|
||||
EXPECT_SOAFLOAT4_EQ(
|
||||
SoaFloat4::Load(
|
||||
SoaFloat3::Load(ozz::math::simd_float4::Load(0.f, 1.f, 2.f, 3.f),
|
||||
ozz::math::simd_float4::Load(4.f, 5.f, 6.f, 7.f),
|
||||
ozz::math::simd_float4::Load(8.f, 9.f, 10.f, 11.f)),
|
||||
ozz::math::simd_float4::Load(12.f, 13.f, 14.f, 15.f)),
|
||||
0.f, 1.f, 2.f, 3.f, 4.f, 5.f, 6.f, 7.f, 8.f, 9.f, 10.f, 11.f, 12.f, 13.f,
|
||||
14.f, 15.f);
|
||||
EXPECT_SOAFLOAT4_EQ(
|
||||
SoaFloat4::Load(
|
||||
SoaFloat2::Load(ozz::math::simd_float4::Load(0.f, 1.f, 2.f, 3.f),
|
||||
ozz::math::simd_float4::Load(4.f, 5.f, 6.f, 7.f)),
|
||||
ozz::math::simd_float4::Load(8.f, 9.f, 10.f, 11.f),
|
||||
ozz::math::simd_float4::Load(12.f, 13.f, 14.f, 15.f)),
|
||||
0.f, 1.f, 2.f, 3.f, 4.f, 5.f, 6.f, 7.f, 8.f, 9.f, 10.f, 11.f, 12.f, 13.f,
|
||||
14.f, 15.f);
|
||||
}
|
||||
|
||||
TEST(SoaFloatLoad3, ozz_soa_math) {
|
||||
EXPECT_SOAFLOAT3_EQ(
|
||||
SoaFloat3::Load(ozz::math::simd_float4::Load(0.f, 1.f, 2.f, 3.f),
|
||||
ozz::math::simd_float4::Load(4.f, 5.f, 6.f, 7.f),
|
||||
ozz::math::simd_float4::Load(8.f, 9.f, 10.f, 11.f)),
|
||||
0.f, 1.f, 2.f, 3.f, 4.f, 5.f, 6.f, 7.f, 8.f, 9.f, 10.f, 11.f);
|
||||
EXPECT_SOAFLOAT3_EQ(
|
||||
SoaFloat3::Load(
|
||||
SoaFloat2::Load(ozz::math::simd_float4::Load(0.f, 1.f, 2.f, 3.f),
|
||||
ozz::math::simd_float4::Load(4.f, 5.f, 6.f, 7.f)),
|
||||
ozz::math::simd_float4::Load(8.f, 9.f, 10.f, 11.f)),
|
||||
0.f, 1.f, 2.f, 3.f, 4.f, 5.f, 6.f, 7.f, 8.f, 9.f, 10.f, 11.f);
|
||||
}
|
||||
|
||||
TEST(SoaFloatLoad2, ozz_soa_math) {
|
||||
EXPECT_SOAFLOAT2_EQ(
|
||||
SoaFloat2::Load(ozz::math::simd_float4::Load(0.f, 1.f, 2.f, 3.f),
|
||||
ozz::math::simd_float4::Load(4.f, 5.f, 6.f, 7.f)),
|
||||
0.f, 1.f, 2.f, 3.f, 4.f, 5.f, 6.f, 7.f);
|
||||
}
|
||||
|
||||
TEST(SoaFloatConstant4, ozz_soa_math) {
|
||||
EXPECT_SOAFLOAT4_EQ(SoaFloat4::zero(), 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f,
|
||||
0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f);
|
||||
EXPECT_SOAFLOAT4_EQ(SoaFloat4::one(), 1.f, 1.f, 1.f, 1.f, 1.f, 1.f, 1.f, 1.f,
|
||||
1.f, 1.f, 1.f, 1.f, 1.f, 1.f, 1.f, 1.f);
|
||||
EXPECT_SOAFLOAT4_EQ(SoaFloat4::x_axis(), 1.f, 1.f, 1.f, 1.f, 0.f, 0.f, 0.f,
|
||||
0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f);
|
||||
EXPECT_SOAFLOAT4_EQ(SoaFloat4::y_axis(), 0.f, 0.f, 0.f, 0.f, 1.f, 1.f, 1.f,
|
||||
1.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f);
|
||||
EXPECT_SOAFLOAT4_EQ(SoaFloat4::z_axis(), 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f,
|
||||
0.f, 1.f, 1.f, 1.f, 1.f, 0.f, 0.f, 0.f, 0.f);
|
||||
EXPECT_SOAFLOAT4_EQ(SoaFloat4::w_axis(), 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(SoaFloatConstant3, ozz_soa_math) {
|
||||
EXPECT_SOAFLOAT3_EQ(SoaFloat3::zero(), 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f,
|
||||
0.f, 0.f, 0.f, 0.f);
|
||||
EXPECT_SOAFLOAT3_EQ(SoaFloat3::one(), 1.f, 1.f, 1.f, 1.f, 1.f, 1.f, 1.f, 1.f,
|
||||
1.f, 1.f, 1.f, 1.f);
|
||||
EXPECT_SOAFLOAT3_EQ(SoaFloat3::x_axis(), 1.f, 1.f, 1.f, 1.f, 0.f, 0.f, 0.f,
|
||||
0.f, 0.f, 0.f, 0.f, 0.f);
|
||||
EXPECT_SOAFLOAT3_EQ(SoaFloat3::y_axis(), 0.f, 0.f, 0.f, 0.f, 1.f, 1.f, 1.f,
|
||||
1.f, 0.f, 0.f, 0.f, 0.f);
|
||||
EXPECT_SOAFLOAT3_EQ(SoaFloat3::z_axis(), 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(SoaFloatConstant2, ozz_soa_math) {
|
||||
EXPECT_SOAFLOAT2_EQ(SoaFloat2::zero(), 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f,
|
||||
0.f);
|
||||
EXPECT_SOAFLOAT2_EQ(SoaFloat2::one(), 1.f, 1.f, 1.f, 1.f, 1.f, 1.f, 1.f, 1.f);
|
||||
EXPECT_SOAFLOAT2_EQ(SoaFloat2::x_axis(), 1.f, 1.f, 1.f, 1.f, 0.f, 0.f, 0.f,
|
||||
0.f);
|
||||
EXPECT_SOAFLOAT2_EQ(SoaFloat2::y_axis(), 0.f, 0.f, 0.f, 0.f, 1.f, 1.f, 1.f,
|
||||
1.f);
|
||||
}
|
||||
|
||||
TEST(SoaFloatArithmetic4, ozz_soa_math) {
|
||||
const SoaFloat4 a = {ozz::math::simd_float4::Load(.5f, 1.f, 2.f, 3.f),
|
||||
ozz::math::simd_float4::Load(4.f, 5.f, 6.f, 7.f),
|
||||
ozz::math::simd_float4::Load(8.f, 9.f, 10.f, 11.f),
|
||||
ozz::math::simd_float4::Load(12.f, 13.f, 14.f, 15.f)};
|
||||
const SoaFloat4 b = {
|
||||
ozz::math::simd_float4::Load(-.5f, -1.f, -2.f, -3.f),
|
||||
ozz::math::simd_float4::Load(-4.f, -5.f, -6.f, -7.f),
|
||||
ozz::math::simd_float4::Load(-8.f, -9.f, -10.f, -11.f),
|
||||
ozz::math::simd_float4::Load(-12.f, -13.f, -14.f, -15.f)};
|
||||
const SoaFloat4 c = {ozz::math::simd_float4::Load(.05f, .1f, .2f, .3f),
|
||||
ozz::math::simd_float4::Load(.4f, .5f, .6f, .7f),
|
||||
ozz::math::simd_float4::Load(.8f, .9f, 1.f, 1.1f),
|
||||
ozz::math::simd_float4::Load(1.2f, 1.3f, 1.4f, 1.5f)};
|
||||
|
||||
const SoaFloat4 add = a + b;
|
||||
EXPECT_SOAFLOAT4_EQ(add, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f,
|
||||
0.f, 0.f, 0.f, 0.f, 0.f, 0.f);
|
||||
|
||||
const SoaFloat4 sub = a - b;
|
||||
EXPECT_SOAFLOAT4_EQ(sub, 1.f, 2.f, 4.f, 6.f, 8.f, 10.f, 12.f, 14.f, 16.f,
|
||||
18.f, 20.f, 22.f, 24.f, 26.f, 28.f, 30.f);
|
||||
|
||||
const SoaFloat4 neg = -a;
|
||||
EXPECT_SOAFLOAT4_EQ(neg, -.5f, -1.f, -2.f, -3.f, -4.f, -5.f, -6.f, -7.f, -8.f,
|
||||
-9.f, -10.f, -11.f, -12.f, -13.f, -14.f, -15.f);
|
||||
|
||||
const SoaFloat4 mul = a * b;
|
||||
EXPECT_SOAFLOAT4_EQ(mul, -0.25f, -1.f, -4.f, -9.f, -16.f, -25.f, -36.f, -49.f,
|
||||
-64.f, -81.f, -100.f, -121.f, -144.f, -169.f, -196.f,
|
||||
-225.f);
|
||||
|
||||
const SoaFloat4 mul_add = MAdd(a, b, c);
|
||||
EXPECT_SOAFLOAT4_EQ(mul_add, -0.2f, -.9f, -3.8f, -8.7f, -15.6f, -24.5f,
|
||||
-35.4f, -48.3f, -63.2f, -80.1f, -99.f, -119.9f, -142.8f,
|
||||
-167.7f, -194.6f, -223.5f);
|
||||
|
||||
const SoaFloat4 mul_scal = a * ozz::math::simd_float4::Load1(2.f);
|
||||
EXPECT_SOAFLOAT4_EQ(mul_scal, 1.f, 2.f, 4.f, 6.f, 8.f, 10.f, 12.f, 14.f, 16.f,
|
||||
18.f, 20.f, 22.f, 24.f, 26.f, 28.f, 30.f);
|
||||
|
||||
const SoaFloat4 div = a / b;
|
||||
EXPECT_SOAFLOAT4_EQ(div, -1.f, -1.f, -1.f, -1.f, -1.f, -1.f, -1.f, -1.f, -1.f,
|
||||
-1.f, -1.f, -1.f, -1.f, -1.f, -1.f, -1.f);
|
||||
|
||||
const SoaFloat4 div_scal = a / ozz::math::simd_float4::Load1(2.f);
|
||||
EXPECT_SOAFLOAT4_EQ(div_scal, 0.25f, .5f, 1.f, 1.5f, 2.f, 2.5f, 3.f, 3.5f,
|
||||
4.f, 4.5, 5.f, 5.5f, 6.f, 6.5f, 7.f, 7.5f);
|
||||
|
||||
const SimdFloat4 hadd4 = HAdd(a);
|
||||
EXPECT_SOAFLOAT1_EQ(hadd4, 24.5f, 28.f, 32.f, 36.f);
|
||||
|
||||
const SimdFloat4 dot = Dot(a, b);
|
||||
EXPECT_SOAFLOAT1_EQ(dot, -224.25f, -276.f, -336.f, -404.f);
|
||||
|
||||
const SimdFloat4 length = Length(a);
|
||||
EXPECT_SOAFLOAT1_EQ(length, 14.974979f, 16.613247f, 18.3303f, 20.09975f);
|
||||
|
||||
const SimdFloat4 length2 = LengthSqr(a);
|
||||
EXPECT_SOAFLOAT1_EQ(length2, 224.25f, 276.f, 336.f, 404.f);
|
||||
|
||||
EXPECT_ASSERTION(Normalize(SoaFloat4::zero()), "_v is not normalizable");
|
||||
EXPECT_TRUE(ozz::math::AreAllFalse(IsNormalized(a)));
|
||||
EXPECT_TRUE(ozz::math::AreAllFalse(IsNormalizedEst(a)));
|
||||
const SoaFloat4 normalize = Normalize(a);
|
||||
EXPECT_TRUE(ozz::math::AreAllTrue(IsNormalized(normalize)));
|
||||
EXPECT_TRUE(ozz::math::AreAllTrue(IsNormalizedEst(normalize)));
|
||||
EXPECT_SOAFLOAT4_EQ(normalize, .033389f, .0601929f, .1091089f, .1492555f,
|
||||
.267112f, .300964f, .3273268f, .348263f, .53422445f,
|
||||
.541736f, .545544f, .547270f, .80133667f, .782508f,
|
||||
.763762f, .74627789f);
|
||||
|
||||
EXPECT_ASSERTION(NormalizeSafe(a, a), "_safer is not normalized");
|
||||
const SoaFloat4 safe = ozz::math::SoaFloat4::x_axis();
|
||||
const SoaFloat4 normalize_safe = NormalizeSafe(a, safe);
|
||||
EXPECT_TRUE(ozz::math::AreAllTrue(IsNormalized(normalize_safe)));
|
||||
EXPECT_TRUE(ozz::math::AreAllTrue(IsNormalizedEst(normalize_safe)));
|
||||
EXPECT_SOAFLOAT4_EQ(normalize_safe, .033389f, .0601929f, .1091089f, .1492555f,
|
||||
.267112f, .300964f, .3273268f, .348263f, .53422445f,
|
||||
.541736f, .545544f, .547270f, .80133667f, .782508f,
|
||||
.763762f, .74627789f);
|
||||
|
||||
const SoaFloat4 normalize_safer = NormalizeSafe(SoaFloat4::zero(), safe);
|
||||
EXPECT_TRUE(ozz::math::AreAllTrue(IsNormalized(normalize_safer)));
|
||||
EXPECT_TRUE(ozz::math::AreAllTrue(IsNormalizedEst(normalize_safer)));
|
||||
EXPECT_SOAFLOAT4_EQ(normalize_safer, 1.f, 1.f, 1.f, 1.f, 0.f, 0.f, 0.f, 0.f,
|
||||
0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f);
|
||||
|
||||
const SoaFloat4 lerp_0 = Lerp(a, b, ozz::math::simd_float4::zero());
|
||||
EXPECT_SOAFLOAT4_EQ(lerp_0, .5f, 1.f, 2.f, 3.f, 4.f, 5.f, 6.f, 7.f, 8.f, 9.f,
|
||||
10.f, 11.f, 12.f, 13.f, 14.f, 15.f);
|
||||
|
||||
const SoaFloat4 lerp_1 = Lerp(a, b, ozz::math::simd_float4::one());
|
||||
EXPECT_SOAFLOAT4_EQ(lerp_1, -.5f, -1.f, -2.f, -3.f, -4.f, -5.f, -6.f, -7.f,
|
||||
-8.f, -9.f, -10.f, -11.f, -12.f, -13.f, -14.f, -15.f);
|
||||
|
||||
const SoaFloat4 lerp_0_5 = Lerp(a, b, ozz::math::simd_float4::Load1(.5f));
|
||||
EXPECT_SOAFLOAT4_EQ(lerp_0_5, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f,
|
||||
0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f);
|
||||
}
|
||||
|
||||
TEST(SoaFloatArithmetic3, ozz_soa_math) {
|
||||
const SoaFloat3 a = {ozz::math::simd_float4::Load(.5f, 1.f, 2.f, 3.f),
|
||||
ozz::math::simd_float4::Load(4.f, 5.f, 6.f, 7.f),
|
||||
ozz::math::simd_float4::Load(8.f, 9.f, 10.f, 11.f)};
|
||||
const SoaFloat3 b = {ozz::math::simd_float4::Load(-.5f, -1.f, -2.f, -3.f),
|
||||
ozz::math::simd_float4::Load(-4.f, -5.f, -6.f, -7.f),
|
||||
ozz::math::simd_float4::Load(-8.f, -9.f, -10.f, -11.f)};
|
||||
const SoaFloat3 c = {ozz::math::simd_float4::Load(.05f, .1f, .2f, .3f),
|
||||
ozz::math::simd_float4::Load(.4f, .5f, .6f, .7f),
|
||||
ozz::math::simd_float4::Load(.8f, .9f, 1.f, 1.1f)};
|
||||
|
||||
const SoaFloat3 add = a + b;
|
||||
EXPECT_SOAFLOAT3_EQ(add, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f,
|
||||
0.f, 0.f);
|
||||
|
||||
const SoaFloat3 sub = a - b;
|
||||
EXPECT_SOAFLOAT3_EQ(sub, 1.f, 2.f, 4.f, 6.f, 8.f, 10.f, 12.f, 14.f, 16.f,
|
||||
18.f, 20.f, 22.f);
|
||||
|
||||
const SoaFloat3 neg = -a;
|
||||
EXPECT_SOAFLOAT3_EQ(neg, -.5f, -1.f, -2.f, -3.f, -4.f, -5.f, -6.f, -7.f, -8.f,
|
||||
-9.f, -10.f, -11.f);
|
||||
|
||||
const SoaFloat3 mul = a * b;
|
||||
EXPECT_SOAFLOAT3_EQ(mul, -0.25f, -1.f, -4.f, -9.f, -16.f, -25.f, -36.f, -49.f,
|
||||
-64.f, -81.f, -100.f, -121.f);
|
||||
|
||||
const SoaFloat3 mul_add = MAdd(a, b, c);
|
||||
EXPECT_SOAFLOAT3_EQ(mul_add, -0.2f, -.9f, -3.8f, -8.7f, -15.6f, -24.5f,
|
||||
-35.4f, -48.3f, -63.2f, -80.1f, -99.f, -119.9f);
|
||||
|
||||
const SoaFloat3 mul_scal = a * ozz::math::simd_float4::Load1(2.f);
|
||||
EXPECT_SOAFLOAT3_EQ(mul_scal, 1.f, 2.f, 4.f, 6.f, 8.f, 10.f, 12.f, 14.f, 16.f,
|
||||
18.f, 20.f, 22.f);
|
||||
|
||||
const SoaFloat3 div = a / b;
|
||||
EXPECT_SOAFLOAT3_EQ(div, -1.f, -1.f, -1.f, -1.f, -1.f, -1.f, -1.f, -1.f, -1.f,
|
||||
-1.f, -1.f, -1.f);
|
||||
|
||||
const SoaFloat3 div_scal = a / ozz::math::simd_float4::Load1(2.f);
|
||||
EXPECT_SOAFLOAT3_EQ(div_scal, 0.25f, .5f, 1.f, 1.5f, 2.f, 2.5f, 3.f, 3.5f,
|
||||
4.f, 4.5, 5.f, 5.5f);
|
||||
|
||||
const SimdFloat4 hadd4 = HAdd(a);
|
||||
EXPECT_SOAFLOAT1_EQ(hadd4, 12.5f, 15.f, 18.f, 21.f);
|
||||
|
||||
const SimdFloat4 dot = Dot(a, b);
|
||||
EXPECT_SOAFLOAT1_EQ(dot, -80.25f, -107.f, -140.f, -179.f);
|
||||
|
||||
const SimdFloat4 length = Length(a);
|
||||
EXPECT_SOAFLOAT1_EQ(length, 8.958236f, 10.34408f, 11.83216f, 13.37909f);
|
||||
|
||||
const SimdFloat4 length2 = LengthSqr(a);
|
||||
EXPECT_SOAFLOAT1_EQ(length2, 80.25f, 107.f, 140.f, 179.f);
|
||||
|
||||
const SoaFloat3 cross = Cross(a, b);
|
||||
EXPECT_SOAFLOAT3_EQ(cross, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f,
|
||||
0.f, 0.f);
|
||||
|
||||
EXPECT_ASSERTION(Normalize(SoaFloat3::zero()), "_v is not normalizable");
|
||||
EXPECT_TRUE(ozz::math::AreAllFalse(IsNormalized(a)));
|
||||
EXPECT_TRUE(ozz::math::AreAllFalse(IsNormalizedEst(a)));
|
||||
const SoaFloat3 normalize = Normalize(a);
|
||||
EXPECT_TRUE(ozz::math::AreAllTrue(IsNormalized(normalize)));
|
||||
EXPECT_TRUE(ozz::math::AreAllTrue(IsNormalizedEst(normalize)));
|
||||
EXPECT_SOAFLOAT3_EQ(normalize, .055814f, .096673f, .16903f, .22423f, .446516f,
|
||||
.483368f, .50709f, .52320f, .893033f, .870063f, .84515f,
|
||||
.822178f);
|
||||
|
||||
EXPECT_ASSERTION(NormalizeSafe(a, a), "_safer is not normalized");
|
||||
const SoaFloat3 safe = ozz::math::SoaFloat3::x_axis();
|
||||
const SoaFloat3 normalize_safe = NormalizeSafe(a, safe);
|
||||
EXPECT_TRUE(ozz::math::AreAllTrue(IsNormalized(normalize_safe)));
|
||||
EXPECT_TRUE(ozz::math::AreAllTrue(IsNormalizedEst(normalize_safe)));
|
||||
EXPECT_SOAFLOAT3_EQ(normalize_safe, .055814f, .096673f, .16903f, .22423f,
|
||||
.446516f, .483368f, .50709f, .52320f, .893033f, .870063f,
|
||||
.84515f, .822178f);
|
||||
|
||||
const SoaFloat3 normalize_safer = NormalizeSafe(SoaFloat3::zero(), safe);
|
||||
EXPECT_TRUE(ozz::math::AreAllTrue(IsNormalized(normalize_safer)));
|
||||
EXPECT_TRUE(ozz::math::AreAllTrue(IsNormalizedEst(normalize_safer)));
|
||||
EXPECT_SOAFLOAT3_EQ(normalize_safer, 1.f, 1.f, 1.f, 1.f, 0.f, 0.f, 0.f, 0.f,
|
||||
0.f, 0.f, 0.f, 0.f);
|
||||
|
||||
const SoaFloat3 lerp_0 = Lerp(a, b, ozz::math::simd_float4::zero());
|
||||
EXPECT_SOAFLOAT3_EQ(lerp_0, .5f, 1.f, 2.f, 3.f, 4.f, 5.f, 6.f, 7.f, 8.f, 9.f,
|
||||
10.f, 11.f);
|
||||
|
||||
const SoaFloat3 lerp_1 = Lerp(a, b, ozz::math::simd_float4::one());
|
||||
EXPECT_SOAFLOAT3_EQ(lerp_1, -.5f, -1.f, -2.f, -3.f, -4.f, -5.f, -6.f, -7.f,
|
||||
-8.f, -9.f, -10.f, -11.f);
|
||||
|
||||
const SoaFloat3 lerp_0_5 = Lerp(a, b, ozz::math::simd_float4::Load1(.5f));
|
||||
EXPECT_SOAFLOAT3_EQ(lerp_0_5, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f,
|
||||
0.f, 0.f, 0.f);
|
||||
}
|
||||
|
||||
TEST(SoaFloatArithmetic2, ozz_soa_math) {
|
||||
const SoaFloat2 a = {ozz::math::simd_float4::Load(.5f, 1.f, 2.f, 3.f),
|
||||
ozz::math::simd_float4::Load(4.f, 5.f, 6.f, 7.f)};
|
||||
const SoaFloat2 b = {ozz::math::simd_float4::Load(-.5f, -1.f, -2.f, -3.f),
|
||||
ozz::math::simd_float4::Load(-4.f, -5.f, -6.f, -7.f)};
|
||||
const SoaFloat2 c = {ozz::math::simd_float4::Load(.05f, .1f, .2f, .3f),
|
||||
ozz::math::simd_float4::Load(.4f, .5f, .6f, .7f)};
|
||||
|
||||
const SoaFloat2 add = a + b;
|
||||
EXPECT_SOAFLOAT2_EQ(add, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f);
|
||||
|
||||
const SoaFloat2 sub = a - b;
|
||||
EXPECT_SOAFLOAT2_EQ(sub, 1.f, 2.f, 4.f, 6.f, 8.f, 10.f, 12.f, 14.f);
|
||||
|
||||
const SoaFloat2 neg = -a;
|
||||
EXPECT_SOAFLOAT2_EQ(neg, -.5f, -1.f, -2.f, -3.f, -4.f, -5.f, -6.f, -7.f);
|
||||
|
||||
const SoaFloat2 mul = a * b;
|
||||
EXPECT_SOAFLOAT2_EQ(mul, -0.25f, -1.f, -4.f, -9.f, -16.f, -25.f, -36.f,
|
||||
-49.f);
|
||||
|
||||
const SoaFloat2 mul_add = MAdd(a, b, c);
|
||||
EXPECT_SOAFLOAT2_EQ(mul_add, -0.2f, -.9f, -3.8f, -8.7f, -15.6f, -24.5f,
|
||||
-35.4f, -48.3f);
|
||||
|
||||
const SoaFloat2 mul_scal = a * ozz::math::simd_float4::Load1(2.f);
|
||||
EXPECT_SOAFLOAT2_EQ(mul_scal, 1.f, 2.f, 4.f, 6.f, 8.f, 10.f, 12.f, 14.f);
|
||||
|
||||
const SoaFloat2 div = a / b;
|
||||
EXPECT_SOAFLOAT2_EQ(div, -1.f, -1.f, -1.f, -1.f, -1.f, -1.f, -1.f, -1.f);
|
||||
|
||||
const SoaFloat2 div_scal = a / ozz::math::simd_float4::Load1(2.f);
|
||||
EXPECT_SOAFLOAT2_EQ(div_scal, 0.25f, .5f, 1.f, 1.5f, 2.f, 2.5f, 3.f, 3.5f);
|
||||
|
||||
const SimdFloat4 hadd4 = HAdd(a);
|
||||
EXPECT_SOAFLOAT1_EQ(hadd4, 4.5f, 6.f, 8.f, 10.f);
|
||||
|
||||
const SimdFloat4 dot = Dot(a, b);
|
||||
EXPECT_SOAFLOAT1_EQ(dot, -16.25f, -26.f, -40.f, -58.f);
|
||||
|
||||
const SimdFloat4 length = Length(a);
|
||||
EXPECT_SOAFLOAT1_EQ(length, 4.031129f, 5.09902f, 6.324555f, 7.615773f);
|
||||
|
||||
const SimdFloat4 length2 = LengthSqr(a);
|
||||
EXPECT_SOAFLOAT1_EQ(length2, 16.25f, 26.f, 40.f, 58.f);
|
||||
|
||||
EXPECT_ASSERTION(Normalize(SoaFloat2::zero()), "_v is not normalizable");
|
||||
EXPECT_TRUE(ozz::math::AreAllFalse(IsNormalized(a)));
|
||||
EXPECT_TRUE(ozz::math::AreAllFalse(IsNormalizedEst(a)));
|
||||
const SoaFloat2 normalize = Normalize(a);
|
||||
EXPECT_TRUE(ozz::math::AreAllTrue(IsNormalized(normalize)));
|
||||
EXPECT_TRUE(ozz::math::AreAllTrue(IsNormalizedEst(normalize)));
|
||||
EXPECT_SOAFLOAT2_EQ(normalize, .124034f, .196116f, .316227f, .393919f,
|
||||
.992277f, .980580f, .9486832f, .919145f);
|
||||
|
||||
EXPECT_ASSERTION(NormalizeSafe(a, a), "_safer is not normalized");
|
||||
const SoaFloat2 safe = ozz::math::SoaFloat2::x_axis();
|
||||
const SoaFloat2 normalize_safe = NormalizeSafe(a, safe);
|
||||
EXPECT_TRUE(ozz::math::AreAllTrue(IsNormalized(normalize_safe)));
|
||||
EXPECT_TRUE(ozz::math::AreAllTrue(IsNormalizedEst(normalize_safe)));
|
||||
EXPECT_SOAFLOAT2_EQ(normalize, .124034f, .196116f, .316227f, .393919f,
|
||||
.992277f, .980580f, .9486832f, .919145f);
|
||||
|
||||
const SoaFloat2 normalize_safer = NormalizeSafe(SoaFloat2::zero(), safe);
|
||||
EXPECT_TRUE(ozz::math::AreAllTrue(IsNormalized(normalize_safer)));
|
||||
EXPECT_TRUE(ozz::math::AreAllTrue(IsNormalizedEst(normalize_safer)));
|
||||
EXPECT_SOAFLOAT2_EQ(normalize_safer, 1.f, 1.f, 1.f, 1.f, 0.f, 0.f, 0.f, 0.f);
|
||||
|
||||
const SoaFloat2 lerp_0 = Lerp(a, b, ozz::math::simd_float4::zero());
|
||||
EXPECT_SOAFLOAT2_EQ(lerp_0, .5f, 1.f, 2.f, 3.f, 4.f, 5.f, 6.f, 7.f);
|
||||
|
||||
const SoaFloat2 lerp_1 = Lerp(a, b, ozz::math::simd_float4::one());
|
||||
EXPECT_SOAFLOAT2_EQ(lerp_1, -.5f, -1.f, -2.f, -3.f, -4.f, -5.f, -6.f, -7.f);
|
||||
|
||||
const SoaFloat2 lerp_0_5 = Lerp(a, b, ozz::math::simd_float4::Load1(.5f));
|
||||
EXPECT_SOAFLOAT2_EQ(lerp_0_5, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f);
|
||||
}
|
||||
|
||||
TEST(SoaFloatComparison4, ozz_soa_math) {
|
||||
const SoaFloat4 a = {ozz::math::simd_float4::Load(.5f, 1.f, 2.f, 3.f),
|
||||
ozz::math::simd_float4::Load(1.f, 5.f, 6.f, 7.f),
|
||||
ozz::math::simd_float4::Load(2.f, 9.f, 10.f, 11.f),
|
||||
ozz::math::simd_float4::Load(3.f, 13.f, 14.f, 15.f)};
|
||||
const SoaFloat4 b = {ozz::math::simd_float4::Load(4.f, 3.f, 7.f, 3.f),
|
||||
ozz::math::simd_float4::Load(2.f, -5.f, 6.f, 5.f),
|
||||
ozz::math::simd_float4::Load(-6.f, 9.f, -10.f, 2.f),
|
||||
ozz::math::simd_float4::Load(7.f, -8.f, 1.f, 5.f)};
|
||||
const SoaFloat4 c = {ozz::math::simd_float4::Load(7.5f, 12.f, 46.f, 31.f),
|
||||
ozz::math::simd_float4::Load(1.f, 58.f, 16.f, 78.f),
|
||||
ozz::math::simd_float4::Load(2.5f, 9.f, 111.f, 22.f),
|
||||
ozz::math::simd_float4::Load(8.f, 23.f, 41.f, 18.f)};
|
||||
const SoaFloat4 min = Min(a, b);
|
||||
EXPECT_SOAFLOAT4_EQ(min, .5f, 1.f, 2.f, 3.f, 1.f, -5.f, 6.f, 5.f, -6.f, 9.f,
|
||||
-10.f, 2.f, 3.f, -8.f, 1.f, 5.f);
|
||||
|
||||
const SoaFloat4 max = Max(a, b);
|
||||
EXPECT_SOAFLOAT4_EQ(max, 4.f, 3.f, 7.f, 3.f, 2.f, 5.f, 6.f, 7.f, 2.f, 9.f,
|
||||
10.f, 11.f, 7.f, 13.f, 14.f, 15.f);
|
||||
|
||||
EXPECT_SOAFLOAT4_EQ(
|
||||
Clamp(a, SoaFloat4::Load(
|
||||
ozz::math::simd_float4::Load(1.5f, 5.f, -2.f, 24.f),
|
||||
ozz::math::simd_float4::Load(2.f, -5.f, 7.f, 1.f),
|
||||
ozz::math::simd_float4::Load(-3.f, 1.f, 200.f, 0.f),
|
||||
ozz::math::simd_float4::Load(-9.f, 15.f, 46.f, -1.f)),
|
||||
c),
|
||||
1.5f, 5.f, 2.f, 24.f, 1.f, 5.f, 7.f, 7.f, 2.f, 9.f, 111.f, 11.f, 3.f,
|
||||
15.f, 41.f, 15.f);
|
||||
|
||||
EXPECT_SIMDINT_EQ(a < c, 0, 0, 0xffffffff, 0xffffffff);
|
||||
EXPECT_SIMDINT_EQ(a <= c, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff);
|
||||
EXPECT_SIMDINT_EQ(c <= c, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff);
|
||||
|
||||
EXPECT_SIMDINT_EQ(c > a, 0, 0, 0xffffffff, 0xffffffff);
|
||||
EXPECT_SIMDINT_EQ(c >= a, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff);
|
||||
EXPECT_SIMDINT_EQ(a >= a, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff);
|
||||
|
||||
EXPECT_SIMDINT_EQ(a == a, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff);
|
||||
EXPECT_SIMDINT_EQ(a == c, 0, 0, 0, 0);
|
||||
EXPECT_SIMDINT_EQ(a != b, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff);
|
||||
}
|
||||
|
||||
TEST(SoaFloatComparison3, ozz_soa_math) {
|
||||
const SoaFloat3 a = {ozz::math::simd_float4::Load(.5f, 1.f, 2.f, 3.f),
|
||||
ozz::math::simd_float4::Load(1.f, 5.f, 6.f, 7.f),
|
||||
ozz::math::simd_float4::Load(2.f, 9.f, 10.f, 11.f)};
|
||||
const SoaFloat3 b = {ozz::math::simd_float4::Load(4.f, 3.f, 7.f, 3.f),
|
||||
ozz::math::simd_float4::Load(2.f, -5.f, 6.f, 5.f),
|
||||
ozz::math::simd_float4::Load(-6.f, 9.f, -10.f, 2.f)};
|
||||
const SoaFloat3 c = {ozz::math::simd_float4::Load(7.5f, 12.f, 46.f, 31.f),
|
||||
ozz::math::simd_float4::Load(1.f, 58.f, 16.f, 78.f),
|
||||
ozz::math::simd_float4::Load(2.5f, 9.f, 111.f, 22.f)};
|
||||
const SoaFloat3 min = Min(a, b);
|
||||
EXPECT_SOAFLOAT3_EQ(min, .5f, 1.f, 2.f, 3.f, 1.f, -5.f, 6.f, 5.f, -6.f, 9.f,
|
||||
-10.f, 2.f);
|
||||
|
||||
const SoaFloat3 max = Max(a, b);
|
||||
EXPECT_SOAFLOAT3_EQ(max, 4.f, 3.f, 7.f, 3.f, 2.f, 5.f, 6.f, 7.f, 2.f, 9.f,
|
||||
10.f, 11.f);
|
||||
|
||||
EXPECT_SOAFLOAT3_EQ(
|
||||
Clamp(a, SoaFloat3::Load(
|
||||
ozz::math::simd_float4::Load(1.5f, 5.f, -2.f, 24.f),
|
||||
ozz::math::simd_float4::Load(2.f, -5.f, 7.f, 1.f),
|
||||
ozz::math::simd_float4::Load(-3.f, 1.f, 200.f, 0.f)),
|
||||
c),
|
||||
1.5f, 5.f, 2.f, 24.f, 1.f, 5.f, 7.f, 7.f, 2.f, 9.f, 111.f, 11.f);
|
||||
|
||||
EXPECT_SIMDINT_EQ(a < c, 0, 0, 0xffffffff, 0xffffffff);
|
||||
EXPECT_SIMDINT_EQ(a <= c, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff);
|
||||
EXPECT_SIMDINT_EQ(c <= c, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff);
|
||||
|
||||
EXPECT_SIMDINT_EQ(c > a, 0, 0, 0xffffffff, 0xffffffff);
|
||||
EXPECT_SIMDINT_EQ(c >= a, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff);
|
||||
EXPECT_SIMDINT_EQ(a >= a, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff);
|
||||
|
||||
EXPECT_SIMDINT_EQ(a == a, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff);
|
||||
EXPECT_SIMDINT_EQ(a == c, 0, 0, 0, 0);
|
||||
EXPECT_SIMDINT_EQ(a != b, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff);
|
||||
}
|
||||
|
||||
TEST(SoaFloatComparison2, ozz_soa_math) {
|
||||
const SoaFloat2 a = {ozz::math::simd_float4::Load(.5f, 1.f, 2.f, 3.f),
|
||||
ozz::math::simd_float4::Load(1.f, 5.f, 6.f, 7.f)};
|
||||
const SoaFloat2 b = {ozz::math::simd_float4::Load(4.f, 3.f, 7.f, 3.f),
|
||||
ozz::math::simd_float4::Load(2.f, -5.f, 6.f, 5.f)};
|
||||
const SoaFloat2 c = {ozz::math::simd_float4::Load(7.5f, 12.f, 46.f, 31.f),
|
||||
ozz::math::simd_float4::Load(1.f, 58.f, 16.f, 78.f)};
|
||||
const SoaFloat2 min = Min(a, b);
|
||||
EXPECT_SOAFLOAT2_EQ(min, .5f, 1.f, 2.f, 3.f, 1.f, -5.f, 6.f, 5.f);
|
||||
|
||||
const SoaFloat2 max = Max(a, b);
|
||||
EXPECT_SOAFLOAT2_EQ(max, 4.f, 3.f, 7.f, 3.f, 2.f, 5.f, 6.f, 7.f);
|
||||
|
||||
EXPECT_SOAFLOAT2_EQ(
|
||||
Clamp(a,
|
||||
SoaFloat2::Load(ozz::math::simd_float4::Load(1.5f, 5.f, -2.f, 24.f),
|
||||
ozz::math::simd_float4::Load(2.f, -5.f, 7.f, 1.f)),
|
||||
c),
|
||||
1.5f, 5.f, 2.f, 24.f, 1.f, 5.f, 7.f, 7.f);
|
||||
|
||||
EXPECT_SIMDINT_EQ(a < c, 0, 0xffffffff, 0xffffffff, 0xffffffff);
|
||||
EXPECT_SIMDINT_EQ(a <= c, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff);
|
||||
EXPECT_SIMDINT_EQ(c <= c, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff);
|
||||
|
||||
EXPECT_SIMDINT_EQ(c > a, 0, 0xffffffff, 0xffffffff, 0xffffffff);
|
||||
EXPECT_SIMDINT_EQ(c >= a, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff);
|
||||
EXPECT_SIMDINT_EQ(a >= a, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff);
|
||||
|
||||
EXPECT_SIMDINT_EQ(a == a, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff);
|
||||
EXPECT_SIMDINT_EQ(a == c, 0, 0, 0, 0);
|
||||
EXPECT_SIMDINT_EQ(a != b, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff);
|
||||
}
|
||||
@@ -0,0 +1,126 @@
|
||||
//----------------------------------------------------------------------------//
|
||||
// //
|
||||
// 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_math_archive.h"
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include "ozz/base/maths/gtest_math_helper.h"
|
||||
|
||||
#include "ozz/base/io/archive.h"
|
||||
#include "ozz/base/maths/soa_float.h"
|
||||
#include "ozz/base/maths/soa_float4x4.h"
|
||||
#include "ozz/base/maths/soa_quaternion.h"
|
||||
#include "ozz/base/maths/soa_transform.h"
|
||||
|
||||
TEST(SoaMathArchive, ozz_soa_math) {
|
||||
for (int e = 0; e < 2; ++e) {
|
||||
ozz::Endianness endianess = e == 0 ? ozz::kBigEndian : ozz::kLittleEndian;
|
||||
|
||||
ozz::io::MemoryStream stream;
|
||||
ASSERT_TRUE(stream.opened());
|
||||
|
||||
// Write soa math types.
|
||||
ozz::io::OArchive o(&stream, endianess);
|
||||
const ozz::math::SoaFloat2 of2 = ozz::math::SoaFloat2::Load(
|
||||
ozz::math::simd_float4::Load(0.f, 1.f, 2.f, 3.f),
|
||||
ozz::math::simd_float4::Load(4.f, 5.f, 6.f, 7.f));
|
||||
o << of2;
|
||||
const ozz::math::SoaFloat3 of3 = ozz::math::SoaFloat3::Load(
|
||||
ozz::math::simd_float4::Load(0.f, 1.f, 2.f, 3.f),
|
||||
ozz::math::simd_float4::Load(4.f, 5.f, 6.f, 7.f),
|
||||
ozz::math::simd_float4::Load(8.f, 9.f, 10.f, 11.f));
|
||||
o << of3;
|
||||
const ozz::math::SoaFloat4 of4 = ozz::math::SoaFloat4::Load(
|
||||
ozz::math::simd_float4::Load(0.f, 1.f, 2.f, 3.f),
|
||||
ozz::math::simd_float4::Load(4.f, 5.f, 6.f, 7.f),
|
||||
ozz::math::simd_float4::Load(8.f, 9.f, 10.f, 11.f),
|
||||
ozz::math::simd_float4::Load(12.f, 13.f, 14.f, 15.f));
|
||||
o << of4;
|
||||
const ozz::math::SoaQuaternion oquat = ozz::math::SoaQuaternion::Load(
|
||||
ozz::math::simd_float4::Load(0.f, 1.f, 2.f, 3.f),
|
||||
ozz::math::simd_float4::Load(4.f, 5.f, 6.f, 7.f),
|
||||
ozz::math::simd_float4::Load(8.f, 9.f, 10.f, 11.f),
|
||||
ozz::math::simd_float4::Load(12.f, 13.f, 14.f, 15.f));
|
||||
o << oquat;
|
||||
const ozz::math::SoaTransform otrans = {of3, oquat, of3};
|
||||
o << otrans;
|
||||
const ozz::math::SoaFloat4x4 of44 = {
|
||||
{{ozz::math::simd_float4::Load(0.f, 1.f, 0.f, 0.f),
|
||||
ozz::math::simd_float4::Load(1.f, 0.f, -1.f, 0.f),
|
||||
ozz::math::simd_float4::Load(2.f, 0.f, 2.f, -1.f),
|
||||
ozz::math::simd_float4::Load(3.f, 0.f, 3.f, 0.f)},
|
||||
{ozz::math::simd_float4::Load(4.f, 0.f, -4.f, 0.f),
|
||||
ozz::math::simd_float4::Load(5.f, 1.f, 5.f, 1.f),
|
||||
ozz::math::simd_float4::Load(6.f, 0.f, 6.f, 0.f),
|
||||
ozz::math::simd_float4::Load(7.f, 0.f, -7.f, 0.f)},
|
||||
{ozz::math::simd_float4::Load(8.f, 0.f, 8.f, 1.f),
|
||||
ozz::math::simd_float4::Load(9.f, 0.f, -9.f, 0.f),
|
||||
ozz::math::simd_float4::Load(10.f, 1.f, -10.f, 0.f),
|
||||
ozz::math::simd_float4::Load(11.f, 0.f, 11.f, 0.f)},
|
||||
{ozz::math::simd_float4::Load(12.f, 0.f, -12.f, 0.f),
|
||||
ozz::math::simd_float4::Load(13.f, 0.f, 13.f, 0.f),
|
||||
ozz::math::simd_float4::Load(14.f, 0.f, -14.f, 0.f),
|
||||
ozz::math::simd_float4::Load(15.f, 1.f, 15.f, 1.f)}}};
|
||||
o << of44;
|
||||
|
||||
// Reads soa math types.
|
||||
stream.Seek(0, ozz::io::Stream::kSet);
|
||||
ozz::io::IArchive i(&stream);
|
||||
ozz::math::SoaFloat2 if2;
|
||||
i >> if2;
|
||||
EXPECT_SOAFLOAT2_EQ(if2, 0.f, 1.f, 2.f, 3.f, 4.f, 5.f, 6.f, 7.f);
|
||||
ozz::math::SoaFloat3 if3;
|
||||
i >> if3;
|
||||
EXPECT_SOAFLOAT3_EQ(if3, 0.f, 1.f, 2.f, 3.f, 4.f, 5.f, 6.f, 7.f, 8.f, 9.f,
|
||||
10.f, 11.f);
|
||||
ozz::math::SoaFloat4 if4;
|
||||
i >> if4;
|
||||
EXPECT_SOAFLOAT4_EQ(if4, 0.f, 1.f, 2.f, 3.f, 4.f, 5.f, 6.f, 7.f, 8.f, 9.f,
|
||||
10.f, 11.f, 12.f, 13.f, 14.f, 15.f);
|
||||
ozz::math::SoaQuaternion iquat;
|
||||
i >> iquat;
|
||||
EXPECT_SOAQUATERNION_EQ(iquat, 0.f, 1.f, 2.f, 3.f, 4.f, 5.f, 6.f, 7.f, 8.f,
|
||||
9.f, 10.f, 11.f, 12.f, 13.f, 14.f, 15.f);
|
||||
ozz::math::SoaTransform itrans;
|
||||
i >> itrans;
|
||||
EXPECT_SOAFLOAT3_EQ(itrans.translation, 0.f, 1.f, 2.f, 3.f, 4.f, 5.f, 6.f,
|
||||
7.f, 8.f, 9.f, 10.f, 11.f);
|
||||
EXPECT_SOAQUATERNION_EQ(itrans.rotation, 0.f, 1.f, 2.f, 3.f, 4.f, 5.f, 6.f,
|
||||
7.f, 8.f, 9.f, 10.f, 11.f, 12.f, 13.f, 14.f, 15.f);
|
||||
EXPECT_SOAFLOAT3_EQ(itrans.scale, 0.f, 1.f, 2.f, 3.f, 4.f, 5.f, 6.f, 7.f,
|
||||
8.f, 9.f, 10.f, 11.f);
|
||||
ozz::math::SoaFloat4x4 if44;
|
||||
i >> if44;
|
||||
EXPECT_SOAFLOAT4x4_EQ(
|
||||
if44, 0.f, 1.f, 0.f, 0.f, 1.f, 0.f, -1.f, 0.f, 2.f, 0.f, 2.f, -1.f, 3.f,
|
||||
0.f, 3.f, 0.f, 4.f, 0.f, -4.f, 0.f, 5.f, 1.f, 5.f, 1.f, 6.f, 0.f, 6.f,
|
||||
0.f, 7.f, 0.f, -7.f, 0.f, 8.f, 0.f, 8.f, 1.f, 9.f, 0.f, -9.f, 0.f, 10.f,
|
||||
1.f, -10.f, 0.f, 11.f, 0.f, 11.f, 0.f, 12.f, 0.f, -12.f, 0.f, 13.f, 0.f,
|
||||
13.f, 0.f, 14.f, 0.f, -14.f, 0.f, 15.f, 1.f, 15.f, 1.f);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,169 @@
|
||||
//----------------------------------------------------------------------------//
|
||||
// //
|
||||
// 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)));
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
//----------------------------------------------------------------------------//
|
||||
// //
|
||||
// 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_transform.h"
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include "ozz/base/gtest_helper.h"
|
||||
#include "ozz/base/maths/gtest_math_helper.h"
|
||||
|
||||
using ozz::math::SoaTransform;
|
||||
|
||||
TEST(SoaTransformConstant, ozz_soa_math) {
|
||||
EXPECT_SOAFLOAT3_EQ(SoaTransform::identity().translation, 0.f, 0.f, 0.f, 0.f,
|
||||
0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f);
|
||||
EXPECT_SOAQUATERNION_EQ(SoaTransform::identity().rotation, 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_SOAFLOAT3_EQ(SoaTransform::identity().scale, 1.f, 1.f, 1.f, 1.f, 1.f,
|
||||
1.f, 1.f, 1.f, 1.f, 1.f, 1.f, 1.f);
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
//----------------------------------------------------------------------------//
|
||||
// //
|
||||
// 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/transform.h"
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include "ozz/base/gtest_helper.h"
|
||||
#include "ozz/base/maths/gtest_math_helper.h"
|
||||
|
||||
using ozz::math::Transform;
|
||||
|
||||
TEST(TransformConstant, ozz_math) {
|
||||
EXPECT_FLOAT3_EQ(Transform::identity().translation, 0.f, 0.f, 0.f);
|
||||
EXPECT_QUATERNION_EQ(Transform::identity().rotation, 0.f, 0.f, 0.f, 1.f);
|
||||
EXPECT_FLOAT3_EQ(Transform::identity().scale, 1.f, 1.f, 1.f);
|
||||
}
|
||||
@@ -0,0 +1,377 @@
|
||||
//----------------------------------------------------------------------------//
|
||||
// //
|
||||
// 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/vec_float.h"
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include "ozz/base/gtest_helper.h"
|
||||
#include "ozz/base/maths/gtest_math_helper.h"
|
||||
|
||||
using ozz::math::Float2;
|
||||
using ozz::math::Float3;
|
||||
using ozz::math::Float4;
|
||||
|
||||
TEST(VectorLoad4, ozz_math) {
|
||||
EXPECT_FLOAT4_EQ(Float4(46.f), 46.f, 46.f, 46.f, 46.f);
|
||||
EXPECT_FLOAT4_EQ(Float4(-1.f, 0.f, 1.f, 2.f), -1.f, 0.f, 1.f, 2.f);
|
||||
const Float3 f3(-1.f, 0.f, 1.f);
|
||||
EXPECT_FLOAT4_EQ(Float4(f3, 2.f), -1.f, 0.f, 1.f, 2.f);
|
||||
const Float2 f2(-1.f, 0.f);
|
||||
EXPECT_FLOAT4_EQ(Float4(f2, 1.f, 2.f), -1.f, 0.f, 1.f, 2.f);
|
||||
}
|
||||
|
||||
TEST(VectorLoad3, ozz_math) {
|
||||
EXPECT_FLOAT3_EQ(Float3(46.f), 46.f, 46.f, 46.f);
|
||||
EXPECT_FLOAT3_EQ(Float3(-1.f, 0.f, 1.f), -1.f, 0.f, 1.f);
|
||||
const Float2 f2(-1.f, 0.f);
|
||||
EXPECT_FLOAT3_EQ(Float3(f2, 1.f), -1.f, 0.f, 1.f);
|
||||
}
|
||||
|
||||
TEST(VectorLoad2, ozz_math) {
|
||||
EXPECT_FLOAT2_EQ(Float2(46.f), 46.f, 46.f);
|
||||
EXPECT_FLOAT2_EQ(Float2(-1.f, 0.f), -1.f, 0.f);
|
||||
}
|
||||
|
||||
TEST(VectorConstant4, ozz_math) {
|
||||
EXPECT_FLOAT4_EQ(Float4::zero(), 0.f, 0.f, 0.f, 0.f);
|
||||
EXPECT_FLOAT4_EQ(Float4::one(), 1.f, 1.f, 1.f, 1.f);
|
||||
EXPECT_FLOAT4_EQ(Float4::x_axis(), 1.f, 0.f, 0.f, 0.f);
|
||||
EXPECT_FLOAT4_EQ(Float4::y_axis(), 0.f, 1.f, 0.f, 0.f);
|
||||
EXPECT_FLOAT4_EQ(Float4::z_axis(), 0.f, 0.f, 1.f, 0.f);
|
||||
EXPECT_FLOAT4_EQ(Float4::w_axis(), 0.f, 0.f, 0.f, 1.f);
|
||||
}
|
||||
|
||||
TEST(VectorConstant3, ozz_math) {
|
||||
EXPECT_FLOAT3_EQ(Float3::zero(), 0.f, 0.f, 0.f);
|
||||
EXPECT_FLOAT3_EQ(Float3::one(), 1.f, 1.f, 1.f);
|
||||
EXPECT_FLOAT3_EQ(Float3::x_axis(), 1.f, 0.f, 0.f);
|
||||
EXPECT_FLOAT3_EQ(Float3::y_axis(), 0.f, 1.f, 0.f);
|
||||
EXPECT_FLOAT3_EQ(Float3::z_axis(), 0.f, 0.f, 1.f);
|
||||
}
|
||||
|
||||
TEST(VectorConstant2, ozz_math) {
|
||||
EXPECT_FLOAT2_EQ(Float2::zero(), 0.f, 0.f);
|
||||
EXPECT_FLOAT2_EQ(Float2::one(), 1.f, 1.f);
|
||||
EXPECT_FLOAT2_EQ(Float2::x_axis(), 1.f, 0.f);
|
||||
EXPECT_FLOAT2_EQ(Float2::y_axis(), 0.f, 1.f);
|
||||
}
|
||||
|
||||
TEST(VectorArithmetic4, ozz_math) {
|
||||
const Float4 a(.5f, 1.f, 2.f, 3.f);
|
||||
const Float4 b(4.f, 5.f, -6.f, 7.f);
|
||||
|
||||
const Float4 add = a + b;
|
||||
EXPECT_FLOAT4_EQ(add, 4.5f, 6.f, -4.f, 10.f);
|
||||
|
||||
const Float4 sub = a - b;
|
||||
EXPECT_FLOAT4_EQ(sub, -3.5f, -4.f, 8.f, -4.f);
|
||||
|
||||
const Float4 neg = -b;
|
||||
EXPECT_FLOAT4_EQ(neg, -4.f, -5.f, 6.f, -7.f);
|
||||
|
||||
const Float4 mul = a * b;
|
||||
EXPECT_FLOAT4_EQ(mul, 2.f, 5.f, -12.f, 21.f);
|
||||
|
||||
const Float4 mul_scal = a * 2.f;
|
||||
EXPECT_FLOAT4_EQ(mul_scal, 1.f, 2.f, 4.f, 6.f);
|
||||
|
||||
const Float4 div = a / b;
|
||||
EXPECT_FLOAT4_EQ(div, .5f / 4.f, 1.f / 5.f, -2.f / 6.f, 3.f / 7.f);
|
||||
|
||||
const Float4 div_scal = a / 2.f;
|
||||
EXPECT_FLOAT4_EQ(div_scal, .5f / 2.f, 1.f / 2.f, 2.f / 2.f, 3.f / 2.f);
|
||||
|
||||
const float hadd4 = HAdd(a);
|
||||
EXPECT_FLOAT_EQ(hadd4, 6.5f);
|
||||
|
||||
const float dot = Dot(a, b);
|
||||
EXPECT_FLOAT_EQ(dot, 16.f);
|
||||
|
||||
const float length = Length(a);
|
||||
EXPECT_FLOAT_EQ(length, std::sqrt(14.25f));
|
||||
|
||||
const float length2 = LengthSqr(a);
|
||||
EXPECT_FLOAT_EQ(length2, 14.25f);
|
||||
|
||||
EXPECT_ASSERTION(Normalize(Float4::zero()), "is not normalizable");
|
||||
EXPECT_FALSE(IsNormalized(a));
|
||||
const Float4 normalize = Normalize(a);
|
||||
EXPECT_TRUE(IsNormalized(normalize));
|
||||
EXPECT_FLOAT4_EQ(normalize, .13245323f, .26490647f, .52981293f, .79471946f);
|
||||
|
||||
EXPECT_ASSERTION(NormalizeSafe(a, a), "_safer is not normalized");
|
||||
const Float4 safe(1.f, 0.f, 0.f, 0.f);
|
||||
const Float4 normalize_safe = NormalizeSafe(a, safe);
|
||||
EXPECT_TRUE(IsNormalized(normalize_safe));
|
||||
EXPECT_FLOAT4_EQ(normalize_safe, .13245323f, .26490647f, .52981293f,
|
||||
.79471946f);
|
||||
|
||||
const Float4 normalize_safer = NormalizeSafe(Float4::zero(), safe);
|
||||
EXPECT_TRUE(IsNormalized(normalize_safer));
|
||||
EXPECT_FLOAT4_EQ(normalize_safer, safe.x, safe.y, safe.z, safe.w);
|
||||
|
||||
const Float4 lerp_0 = Lerp(a, b, 0.f);
|
||||
EXPECT_FLOAT4_EQ(lerp_0, a.x, a.y, a.z, a.w);
|
||||
|
||||
const Float4 lerp_1 = Lerp(a, b, 1.f);
|
||||
EXPECT_FLOAT4_EQ(lerp_1, b.x, b.y, b.z, b.w);
|
||||
|
||||
const Float4 lerp_0_5 = Lerp(a, b, .5f);
|
||||
EXPECT_FLOAT4_EQ(lerp_0_5, (a.x + b.x) * .5f, (a.y + b.y) * .5f,
|
||||
(a.z + b.z) * .5f, (a.w + b.w) * .5f);
|
||||
|
||||
const Float4 lerp_2 = Lerp(a, b, 2.f);
|
||||
EXPECT_FLOAT4_EQ(lerp_2, 2.f * b.x - a.x, 2.f * b.y - a.y, 2.f * b.z - a.z,
|
||||
2.f * b.w - a.w);
|
||||
}
|
||||
|
||||
TEST(VectorArithmetic3, ozz_math) {
|
||||
const Float3 a(.5f, 1.f, 2.f);
|
||||
const Float3 b(4.f, 5.f, -6.f);
|
||||
|
||||
const Float3 add = a + b;
|
||||
EXPECT_FLOAT3_EQ(add, 4.5f, 6.f, -4.f);
|
||||
|
||||
const Float3 sub = a - b;
|
||||
EXPECT_FLOAT3_EQ(sub, -3.5f, -4.f, 8.f);
|
||||
|
||||
const Float3 neg = -b;
|
||||
EXPECT_FLOAT3_EQ(neg, -4.f, -5.f, 6.f);
|
||||
|
||||
const Float3 mul = a * b;
|
||||
EXPECT_FLOAT3_EQ(mul, 2.f, 5.f, -12.f);
|
||||
|
||||
const Float3 mul_scal = a * 2.f;
|
||||
EXPECT_FLOAT3_EQ(mul_scal, 1.f, 2.f, 4.f);
|
||||
|
||||
const Float3 div = a / b;
|
||||
EXPECT_FLOAT3_EQ(div, .5f / 4.f, 1.f / 5.f, -2.f / 6.f);
|
||||
|
||||
const Float3 div_scal = a / 2.f;
|
||||
EXPECT_FLOAT3_EQ(div_scal, .5f / 2.f, 1.f / 2.f, 2.f / 2.f);
|
||||
|
||||
const float hadd4 = HAdd(a);
|
||||
EXPECT_FLOAT_EQ(hadd4, 3.5f);
|
||||
|
||||
const float dot = Dot(a, b);
|
||||
EXPECT_FLOAT_EQ(dot, -5.f);
|
||||
|
||||
const Float3 cross = Cross(a, b);
|
||||
EXPECT_FLOAT3_EQ(cross, -16.f, 11.f, -1.5f);
|
||||
|
||||
const float length = Length(a);
|
||||
EXPECT_FLOAT_EQ(length, std::sqrt(5.25f));
|
||||
|
||||
const float length2 = LengthSqr(a);
|
||||
EXPECT_FLOAT_EQ(length2, 5.25f);
|
||||
|
||||
EXPECT_ASSERTION(Normalize(Float3::zero()), "is not normalizable");
|
||||
EXPECT_FALSE(IsNormalized(a));
|
||||
const Float3 normalize = Normalize(a);
|
||||
EXPECT_TRUE(IsNormalized(normalize));
|
||||
EXPECT_FLOAT3_EQ(normalize, .21821788f, .43643576f, .87287152f);
|
||||
|
||||
EXPECT_ASSERTION(NormalizeSafe(a, a), "_safer is not normalized");
|
||||
const Float3 safe(1.f, 0.f, 0.f);
|
||||
const Float3 normalize_safe = NormalizeSafe(a, safe);
|
||||
EXPECT_TRUE(IsNormalized(normalize_safe));
|
||||
EXPECT_FLOAT3_EQ(normalize_safe, .21821788f, .43643576f, .87287152f);
|
||||
|
||||
const Float3 normalize_safer = NormalizeSafe(Float3::zero(), safe);
|
||||
EXPECT_TRUE(IsNormalized(normalize_safer));
|
||||
EXPECT_FLOAT3_EQ(normalize_safer, safe.x, safe.y, safe.z);
|
||||
|
||||
const Float3 lerp_0 = Lerp(a, b, 0.f);
|
||||
EXPECT_FLOAT3_EQ(lerp_0, a.x, a.y, a.z);
|
||||
|
||||
const Float3 lerp_1 = Lerp(a, b, 1.f);
|
||||
EXPECT_FLOAT3_EQ(lerp_1, b.x, b.y, b.z);
|
||||
|
||||
const Float3 lerp_0_5 = Lerp(a, b, .5f);
|
||||
EXPECT_FLOAT3_EQ(lerp_0_5, (a.x + b.x) * .5f, (a.y + b.y) * .5f,
|
||||
(a.z + b.z) * .5f);
|
||||
|
||||
const Float3 lerp_2 = Lerp(a, b, 2.f);
|
||||
EXPECT_FLOAT3_EQ(lerp_2, 2.f * b.x - a.x, 2.f * b.y - a.y, 2.f * b.z - a.z);
|
||||
}
|
||||
|
||||
TEST(VectorArithmetic2, ozz_math) {
|
||||
const Float2 a(.5f, 1.f);
|
||||
const Float2 b(4.f, 5.f);
|
||||
|
||||
const Float2 add = a + b;
|
||||
EXPECT_FLOAT2_EQ(add, 4.5f, 6.f);
|
||||
|
||||
const Float2 sub = a - b;
|
||||
EXPECT_FLOAT2_EQ(sub, -3.5f, -4.f);
|
||||
|
||||
const Float2 neg = -b;
|
||||
EXPECT_FLOAT2_EQ(neg, -4.f, -5.f);
|
||||
|
||||
const Float2 mul = a * b;
|
||||
EXPECT_FLOAT2_EQ(mul, 2.f, 5.f);
|
||||
|
||||
const Float2 mul_scal = a * 2.f;
|
||||
EXPECT_FLOAT2_EQ(mul_scal, 1.f, 2.f);
|
||||
|
||||
const Float2 div = a / b;
|
||||
EXPECT_FLOAT2_EQ(div, .5f / 4.f, 1.f / 5.f);
|
||||
const Float2 div_scal = a / 2.f;
|
||||
EXPECT_FLOAT2_EQ(div_scal, .5f / 2.f, 1.f / 2.f);
|
||||
|
||||
const float hadd4 = HAdd(a);
|
||||
EXPECT_FLOAT_EQ(hadd4, 1.5f);
|
||||
|
||||
const float dot = Dot(a, b);
|
||||
EXPECT_FLOAT_EQ(dot, 7.f);
|
||||
|
||||
const float length = Length(a);
|
||||
EXPECT_FLOAT_EQ(length, std::sqrt(1.25f));
|
||||
|
||||
const float length2 = LengthSqr(a);
|
||||
EXPECT_FLOAT_EQ(length2, 1.25f);
|
||||
|
||||
EXPECT_ASSERTION(Normalize(Float2::zero()), "is not normalizable");
|
||||
EXPECT_FALSE(IsNormalized(a));
|
||||
const Float2 normalize = Normalize(a);
|
||||
EXPECT_TRUE(IsNormalized(normalize));
|
||||
EXPECT_FLOAT2_EQ(normalize, .44721359f, .89442718f);
|
||||
|
||||
EXPECT_ASSERTION(NormalizeSafe(a, a), "_safer is not normalized");
|
||||
const Float2 safe(1.f, 0.f);
|
||||
const Float2 normalize_safe = NormalizeSafe(a, safe);
|
||||
EXPECT_TRUE(IsNormalized(normalize_safe));
|
||||
EXPECT_FLOAT2_EQ(normalize_safe, .44721359f, .89442718f);
|
||||
|
||||
const Float2 normalize_safer = NormalizeSafe(Float2::zero(), safe);
|
||||
EXPECT_TRUE(IsNormalized(normalize_safer));
|
||||
EXPECT_FLOAT2_EQ(normalize_safer, safe.x, safe.y);
|
||||
|
||||
const Float2 lerp_0 = Lerp(a, b, 0.f);
|
||||
EXPECT_FLOAT2_EQ(lerp_0, a.x, a.y);
|
||||
|
||||
const Float2 lerp_1 = Lerp(a, b, 1.f);
|
||||
EXPECT_FLOAT2_EQ(lerp_1, b.x, b.y);
|
||||
|
||||
const Float2 lerp_0_5 = Lerp(a, b, .5f);
|
||||
EXPECT_FLOAT2_EQ(lerp_0_5, (a.x + b.x) * .5f, (a.y + b.y) * .5f);
|
||||
|
||||
const Float2 lerp_2 = Lerp(a, b, 2.f);
|
||||
EXPECT_FLOAT2_EQ(lerp_2, 2.f * b.x - a.x, 2.f * b.y - a.y);
|
||||
}
|
||||
|
||||
TEST(VectorComparison4, ozz_math) {
|
||||
const Float4 a(.5f, 1.f, 2.f, 3.f);
|
||||
const Float4 b(4.f, 5.f, -6.f, 7.f);
|
||||
const Float4 c(4.f, 5.f, 6.f, 7.f);
|
||||
const Float4 d(4.f, 5.f, 6.f, 7.1f);
|
||||
|
||||
const Float4 min = Min(a, b);
|
||||
EXPECT_FLOAT4_EQ(min, .5f, 1.f, -6.f, 3.f);
|
||||
|
||||
const Float4 max = Max(a, b);
|
||||
EXPECT_FLOAT4_EQ(max, 4.f, 5.f, 2.f, 7.f);
|
||||
|
||||
EXPECT_FLOAT4_EQ(Clamp(a, Float4(-12.f, 2.f, 9.f, 3.f), c), .5f, 2.f, 6.f,
|
||||
3.f);
|
||||
|
||||
EXPECT_TRUE(a < c);
|
||||
EXPECT_TRUE(a <= c);
|
||||
EXPECT_TRUE(c <= c);
|
||||
|
||||
EXPECT_TRUE(c > a);
|
||||
EXPECT_TRUE(c >= a);
|
||||
EXPECT_TRUE(a >= a);
|
||||
|
||||
EXPECT_TRUE(a == a);
|
||||
EXPECT_TRUE(a != b);
|
||||
|
||||
EXPECT_TRUE(Compare(a, a, 0.f));
|
||||
EXPECT_TRUE(Compare(c, d, .2f));
|
||||
EXPECT_FALSE(Compare(c, d, .05f));
|
||||
}
|
||||
|
||||
TEST(VectorComparison3, ozz_math) {
|
||||
const Float3 a(.5f, -1.f, 2.f);
|
||||
const Float3 b(4.f, 5.f, -6.f);
|
||||
const Float3 c(4.f, 5.f, 6.f);
|
||||
const Float3 d(4.f, 5.f, 6.1f);
|
||||
|
||||
const Float3 min = Min(a, b);
|
||||
EXPECT_FLOAT3_EQ(min, .5f, -1.f, -6.f);
|
||||
|
||||
const Float3 max = Max(a, b);
|
||||
EXPECT_FLOAT3_EQ(max, 4.f, 5.f, 2.f);
|
||||
|
||||
EXPECT_FLOAT3_EQ(Clamp(a, Float3(-12.f, 2.f, 9.f), c), .5f, 2.f, 6.f);
|
||||
|
||||
EXPECT_TRUE(a < c);
|
||||
EXPECT_TRUE(a <= c);
|
||||
EXPECT_TRUE(c <= c);
|
||||
|
||||
EXPECT_TRUE(c > a);
|
||||
EXPECT_TRUE(c >= a);
|
||||
EXPECT_TRUE(a >= a);
|
||||
|
||||
EXPECT_TRUE(a == a);
|
||||
EXPECT_TRUE(a != b);
|
||||
|
||||
EXPECT_TRUE(Compare(a, a, 1e-3f));
|
||||
EXPECT_TRUE(Compare(c, d, .2f));
|
||||
EXPECT_FALSE(Compare(c, d, .05f));
|
||||
}
|
||||
|
||||
TEST(VectorComparison2, ozz_math) {
|
||||
const Float2 a(.5f, 1.f);
|
||||
const Float2 b(4.f, -5.f);
|
||||
const Float2 c(4.f, 5.f);
|
||||
const Float2 d(4.f, 5.1f);
|
||||
|
||||
const Float2 min = Min(a, b);
|
||||
EXPECT_FLOAT2_EQ(min, .5f, -5.f);
|
||||
|
||||
const Float2 max = Max(a, b);
|
||||
EXPECT_FLOAT2_EQ(max, 4.f, 1.f);
|
||||
|
||||
EXPECT_FLOAT2_EQ(Clamp(a, Float2(-12.f, 2.f), c), .5f, 2.f);
|
||||
|
||||
EXPECT_TRUE(a < c);
|
||||
EXPECT_TRUE(a <= c);
|
||||
EXPECT_TRUE(c <= c);
|
||||
|
||||
EXPECT_TRUE(c > a);
|
||||
EXPECT_TRUE(c >= a);
|
||||
EXPECT_TRUE(a >= a);
|
||||
|
||||
EXPECT_TRUE(a == a);
|
||||
EXPECT_TRUE(a != b);
|
||||
|
||||
EXPECT_TRUE(Compare(a, a, 1e-3f));
|
||||
EXPECT_TRUE(Compare(c, d, .2f));
|
||||
EXPECT_FALSE(Compare(c, d, .05f));
|
||||
}
|
||||
Reference in New Issue
Block a user