replace math_graphics with glm version 1.0.3

This commit is contained in:
Sven Balzer
2026-04-15 10:50:41 +02:00
parent 07af9deb6a
commit 4ec664c8db
1676 changed files with 289261 additions and 1477 deletions
+62
View File
@@ -0,0 +1,62 @@
glmCreateTestGTC(gtx)
glmCreateTestGTC(gtx_associated_min_max)
glmCreateTestGTC(gtx_closest_point)
glmCreateTestGTC(gtx_color_encoding)
glmCreateTestGTC(gtx_color_space_YCoCg)
glmCreateTestGTC(gtx_color_space)
glmCreateTestGTC(gtx_common)
glmCreateTestGTC(gtx_compatibility)
glmCreateTestGTC(gtx_component_wise)
glmCreateTestGTC(gtx_easing)
glmCreateTestGTC(gtx_euler_angle)
glmCreateTestGTC(gtx_extend)
glmCreateTestGTC(gtx_extended_min_max)
glmCreateTestGTC(gtx_exterior_product)
glmCreateTestGTC(gtx_fast_exponential)
glmCreateTestGTC(gtx_fast_square_root)
glmCreateTestGTC(gtx_fast_trigonometry)
glmCreateTestGTC(gtx_functions)
glmCreateTestGTC(gtx_gradient_paint)
glmCreateTestGTC(gtx_handed_coordinate_space)
glmCreateTestGTC(gtx_hash)
glmCreateTestGTC(gtx_integer)
glmCreateTestGTC(gtx_intersect)
glmCreateTestGTC(gtx_io)
glmCreateTestGTC(gtx_iteration)
glmCreateTestGTC(gtx_load)
glmCreateTestGTC(gtx_log_base)
glmCreateTestGTC(gtx_matrix_cross_product)
glmCreateTestGTC(gtx_matrix_decompose)
glmCreateTestGTC(gtx_matrix_factorisation)
glmCreateTestGTC(gtx_matrix_interpolation)
glmCreateTestGTC(gtx_matrix_major_storage)
glmCreateTestGTC(gtx_matrix_operation)
glmCreateTestGTC(gtx_matrix_query)
glmCreateTestGTC(gtx_matrix_transform_2d)
glmCreateTestGTC(gtx_norm)
glmCreateTestGTC(gtx_normal)
glmCreateTestGTC(gtx_normalize_dot)
glmCreateTestGTC(gtx_orthonormalize)
glmCreateTestGTC(gtx_optimum_pow)
glmCreateTestGTC(gtx_pca)
glmCreateTestGTC(gtx_perpendicular)
glmCreateTestGTC(gtx_polar_coordinates)
glmCreateTestGTC(gtx_projection)
glmCreateTestGTC(gtx_quaternion)
glmCreateTestGTC(gtx_dual_quaternion)
glmCreateTestGTC(gtx_range)
glmCreateTestGTC(gtx_rotate_normalized_axis)
glmCreateTestGTC(gtx_rotate_vector)
glmCreateTestGTC(gtx_scalar_multiplication)
glmCreateTestGTC(gtx_scalar_relational)
glmCreateTestGTC(gtx_spline)
glmCreateTestGTC(gtx_string_cast)
glmCreateTestGTC(gtx_structured_bindings)
glmCreateTestGTC(gtx_texture)
glmCreateTestGTC(gtx_transform2)
glmCreateTestGTC(gtx_type_aligned)
glmCreateTestGTC(gtx_type_trait)
glmCreateTestGTC(gtx_vec_swizzle)
glmCreateTestGTC(gtx_vector_angle)
glmCreateTestGTC(gtx_vector_query)
glmCreateTestGTC(gtx_wrap)
+8
View File
@@ -0,0 +1,8 @@
#include <glm/ext.hpp>
int main()
{
int Error = 0;
return Error;
}
@@ -0,0 +1,10 @@
#define GLM_ENABLE_EXPERIMENTAL
#include <glm/gtc/type_precision.hpp>
#include <glm/gtx/associated_min_max.hpp>
int main()
{
int Error(0);
return Error;
}
+9
View File
@@ -0,0 +1,9 @@
#define GLM_ENABLE_EXPERIMENTAL
#include <glm/gtx/closest_point.hpp>
int main()
{
int Error(0);
return Error;
}
+52
View File
@@ -0,0 +1,52 @@
#define GLM_ENABLE_EXPERIMENTAL
#include <glm/gtx/color_encoding.hpp>
#include <glm/gtc/color_space.hpp>
#include <glm/gtc/epsilon.hpp>
#include <glm/gtc/constants.hpp>
namespace srgb
{
static int test()
{
int Error(0);
glm::vec3 const ColorSourceRGB(1.0, 0.5, 0.0);
/*
{
glm::vec3 const ColorSRGB = glm::convertLinearSRGBToD65XYZ(ColorSourceRGB);
glm::vec3 const ColorRGB = glm::convertD65XYZToLinearSRGB(ColorSRGB);
Error += glm::all(glm::epsilonEqual(ColorSourceRGB, ColorRGB, 0.00001f)) ? 0 : 1;
}
*/
{
glm::vec3 const ColorSRGB = glm::convertLinearToSRGB(ColorSourceRGB, 2.8f);
glm::vec3 const ColorRGB = glm::convertSRGBToLinear(ColorSRGB, 2.8f);
Error += glm::all(glm::epsilonEqual(ColorSourceRGB, ColorRGB, 0.00001f)) ? 0 : 1;
}
glm::vec4 const ColorSourceRGBA(1.0, 0.5, 0.0, 1.0);
{
glm::vec4 const ColorSRGB = glm::convertLinearToSRGB(ColorSourceRGBA);
glm::vec4 const ColorRGB = glm::convertSRGBToLinear(ColorSRGB);
Error += glm::all(glm::epsilonEqual(ColorSourceRGBA, ColorRGB, 0.00001f)) ? 0 : 1;
}
{
glm::vec4 const ColorSRGB = glm::convertLinearToSRGB(ColorSourceRGBA, 2.8f);
glm::vec4 const ColorRGB = glm::convertSRGBToLinear(ColorSRGB, 2.8f);
Error += glm::all(glm::epsilonEqual(ColorSourceRGBA, ColorRGB, 0.00001f)) ? 0 : 1;
}
return Error;
}
}//namespace srgb
int main()
{
int Error(0);
Error += srgb::test();
return Error;
}
+36
View File
@@ -0,0 +1,36 @@
#include <glm/ext/vector_relational.hpp>
#define GLM_ENABLE_EXPERIMENTAL
#include <glm/gtx/color_space.hpp>
static int test_hsv()
{
int Error = 0;
glm::vec3 colorHSV = glm::hsvColor(glm::vec3(1.0f, 0.5f, 0.0f));
glm::vec3 colorRGB = glm::rgbColor(colorHSV);
Error += glm::all(glm::equal(colorRGB, glm::vec3(1.0f, 0.5f, 0.0f), glm::epsilon<float>())) ? 0 : 1;
return Error;
}
static int test_saturation()
{
int Error = 0;
glm::vec4 Color = glm::saturation(1.0f, glm::vec4(1.0, 0.5, 0.0, 1.0));
Error += glm::all(glm::equal(Color, glm::vec4(1.0, 0.5, 0.0, 1.0), glm::epsilon<float>())) ? 0 : 1;
return Error;
}
int main()
{
int Error(0);
Error += test_hsv();
Error += test_saturation();
return Error;
}
@@ -0,0 +1,17 @@
#include <glm/ext/vector_relational.hpp>
#include <glm/ext/scalar_constants.hpp>
#define GLM_ENABLE_EXPERIMENTAL
#include <glm/gtx/color_space_YCoCg.hpp>
int main()
{
int Error = 0;
glm::vec3 colorYCoCg = glm::rgb2YCoCg(glm::vec3(1.0f, 0.5f, 0.0f));
glm::vec3 colorRGB1 = glm::YCoCg2rgb(colorYCoCg);
Error += glm::all(glm::equal(colorRGB1, glm::vec3(1.0f, 0.5f, 0.0f), glm::epsilon<float>())) ? 0 : 1;
return Error;
}
+161
View File
@@ -0,0 +1,161 @@
#define GLM_ENABLE_EXPERIMENTAL
#include <glm/gtx/common.hpp>
#include <glm/gtc/integer.hpp>
#include <glm/gtc/epsilon.hpp>
#include <glm/vector_relational.hpp>
#include <glm/common.hpp>
namespace fmod_
{
template<typename genType>
GLM_FUNC_QUALIFIER genType modTrunc(genType a, genType b)
{
return a - b * glm::trunc(a / b);
}
static int test()
{
int Error(0);
{
float A0(3.0);
float B0(2.0f);
float C0 = glm::fmod(A0, B0);
Error += glm::abs(C0 - 1.0f) < 0.00001f ? 0 : 1;
glm::vec4 A1(3.0);
float B1(2.0f);
glm::vec4 C1 = glm::fmod(A1, B1);
Error += glm::all(glm::epsilonEqual(C1, glm::vec4(1.0f), 0.00001f)) ? 0 : 1;
glm::vec4 A2(3.0);
glm::vec4 B2(2.0f);
glm::vec4 C2 = glm::fmod(A2, B2);
Error += glm::all(glm::epsilonEqual(C2, glm::vec4(1.0f), 0.00001f)) ? 0 : 1;
glm::ivec4 A3(3);
int B3(2);
glm::ivec4 C3 = glm::fmod(A3, B3);
Error += glm::all(glm::equal(C3, glm::ivec4(1))) ? 0 : 1;
glm::ivec4 A4(3);
glm::ivec4 B4(2);
glm::ivec4 C4 = glm::fmod(A4, B4);
Error += glm::all(glm::equal(C4, glm::ivec4(1))) ? 0 : 1;
}
{
float A0(22.0);
float B0(-10.0f);
float C0 = glm::fmod(A0, B0);
Error += glm::abs(C0 - 2.0f) < 0.00001f ? 0 : 1;
glm::vec4 A1(22.0);
float B1(-10.0f);
glm::vec4 C1 = glm::fmod(A1, B1);
Error += glm::all(glm::epsilonEqual(C1, glm::vec4(2.0f), 0.00001f)) ? 0 : 1;
glm::vec4 A2(22.0);
glm::vec4 B2(-10.0f);
glm::vec4 C2 = glm::fmod(A2, B2);
Error += glm::all(glm::epsilonEqual(C2, glm::vec4(2.0f), 0.00001f)) ? 0 : 1;
glm::ivec4 A3(22);
int B3(-10);
glm::ivec4 C3 = glm::fmod(A3, B3);
Error += glm::all(glm::equal(C3, glm::ivec4(2))) ? 0 : 1;
glm::ivec4 A4(22);
glm::ivec4 B4(-10);
glm::ivec4 C4 = glm::fmod(A4, B4);
Error += glm::all(glm::equal(C4, glm::ivec4(2))) ? 0 : 1;
}
// http://stackoverflow.com/questions/7610631/glsl-mod-vs-hlsl-fmod
{
for (float y = -10.0f; y < 10.0f; y += 0.1f)
for (float x = -10.0f; x < 10.0f; x += 0.1f)
{
float const A(std::fmod(x, y));
//float const B(std::remainder(x, y));
float const C(glm::fmod(x, y));
float const D(modTrunc(x, y));
//Error += glm::epsilonEqual(A, B, 0.0001f) ? 0 : 1;
//assert(!Error);
Error += glm::epsilonEqual(A, C, 0.0001f) ? 0 : 1;
assert(!Error);
Error += glm::epsilonEqual(A, D, 0.00001f) ? 0 : 1;
assert(!Error);
}
}
return Error;
}
}//namespace fmod_
static int test_isdenormal()
{
int Error = 0;
bool A = glm::isdenormal(1.0f);
Error += !A ? 0 : 1;
glm::bvec1 B = glm::isdenormal(glm::vec1(1.0f));
Error += !glm::any(B) ? 0 : 1;
glm::bvec2 C = glm::isdenormal(glm::vec2(1.0f));
Error += !glm::any(C) ? 0 : 1;
glm::bvec3 D = glm::isdenormal(glm::vec3(1.0f));
Error += !glm::any(D) ? 0 : 1;
glm::bvec4 E = glm::isdenormal(glm::vec4(1.0f));
Error += !glm::any(E) ? 0 : 1;
return Error;
}
static int test_openBounded()
{
int Error = 0;
Error += glm::all(glm::openBounded(glm::ivec2(2), glm::ivec2(1), glm::ivec2(3))) ? 0 : 1;
Error += !glm::all(glm::openBounded(glm::ivec2(1), glm::ivec2(1), glm::ivec2(3))) ? 0 : 1;
Error += !glm::all(glm::openBounded(glm::ivec2(3), glm::ivec2(1), glm::ivec2(3))) ? 0 : 1;
return Error;
}
static int test_closeBounded()
{
int Error = 0;
Error += glm::all(glm::closeBounded(glm::ivec2(2), glm::ivec2(1), glm::ivec2(3))) ? 0 : 1;
Error += glm::all(glm::closeBounded(glm::ivec2(1), glm::ivec2(1), glm::ivec2(3))) ? 0 : 1;
Error += glm::all(glm::closeBounded(glm::ivec2(3), glm::ivec2(1), glm::ivec2(3))) ? 0 : 1;
return Error;
}
int main()
{
int Error = 0;
Error += test_isdenormal();
Error += ::fmod_::test();
Error += test_openBounded();
Error += test_closeBounded();
return Error;
}
+58
View File
@@ -0,0 +1,58 @@
#define GLM_ENABLE_EXPERIMENTAL
#include <glm/gtx/compatibility.hpp>
// This file has divisions by zero to test isnan
#if GLM_COMPILER & GLM_COMPILER_VC
# pragma warning(push)
# pragma warning(disable : 4723)
#endif
int main()
{
int Error(0);
float Zero_f = 0.0;
double Zero_d = 0.0;
Error += glm::isfinite(1.0f) ? 0 : 1;
Error += glm::isfinite(1.0) ? 0 : 1;
Error += glm::isfinite(-1.0f) ? 0 : 1;
Error += glm::isfinite(-1.0) ? 0 : 1;
Error += glm::all(glm::isfinite(glm::vec4(1.0f))) ? 0 : 1;
Error += glm::all(glm::isfinite(glm::dvec4(1.0))) ? 0 : 1;
Error += glm::all(glm::isfinite(glm::vec4(-1.0f))) ? 0 : 1;
Error += glm::all(glm::isfinite(glm::dvec4(-1.0))) ? 0 : 1;
Error += glm::all(glm::isfinite(glm::quat(1.0f, 1.0f, 1.0f, 1.0f))) ? 0 : 1;
Error += glm::all(glm::isfinite(glm::dquat(1.0, 1.0, 1.0, 1.0))) ? 0 : 1;
Error += glm::all(glm::isfinite(glm::quat(-1.0f, -1.0f, -1.0f, -1.0f))) ? 0 : 1;
Error += glm::all(glm::isfinite(glm::dquat(-1.0, -1.0, -1.0, -1.0))) ? 0 : 1;
Error += glm::isfinite(0.0f/Zero_f) ? 1 : 0;
Error += glm::isfinite(0.0/Zero_d) ? 1 : 0;
Error += glm::isfinite(1.0f/Zero_f) ? 1 : 0;
Error += glm::isfinite(1.0/Zero_d) ? 1 : 0;
Error += glm::isfinite(-1.0f/Zero_f) ? 1 : 0;
Error += glm::isfinite(-1.0/Zero_d) ? 1 : 0;
Error += glm::any(glm::isfinite(glm::vec4(0.0f/Zero_f))) ? 1 : 0;
Error += glm::any(glm::isfinite(glm::dvec4(0.0/Zero_d))) ? 1 : 0;
Error += glm::any(glm::isfinite(glm::vec4(1.0f/Zero_f))) ? 1 : 0;
Error += glm::any(glm::isfinite(glm::dvec4(1.0/Zero_d))) ? 1 : 0;
Error += glm::any(glm::isfinite(glm::vec4(-1.0f/Zero_f))) ? 1 : 0;
Error += glm::any(glm::isfinite(glm::dvec4(-1.0/Zero_d))) ? 1 : 0;
Error += glm::any(glm::isfinite(glm::quat(0.0f/Zero_f, 0.0f/Zero_f, 0.0f/Zero_f, 0.0f/Zero_f))) ? 1 : 0;
Error += glm::any(glm::isfinite(glm::dquat(0.0/Zero_d, 0.0/Zero_d, 0.0/Zero_d, 0.0/Zero_d))) ? 1 : 0;
Error += glm::any(glm::isfinite(glm::quat(1.0f/Zero_f, 1.0f/Zero_f, 1.0f/Zero_f, 1.0f/Zero_f))) ? 1 : 0;
Error += glm::any(glm::isfinite(glm::dquat(1.0/Zero_d, 1.0/Zero_d, 1.0/Zero_d, 1.0/Zero_d))) ? 1 : 0;
Error += glm::any(glm::isfinite(glm::quat(-1.0f/Zero_f, -1.0f/Zero_f, -1.0f/Zero_f, -1.0f/Zero_f))) ? 1 : 0;
Error += glm::any(glm::isfinite(glm::dquat(-1.0/Zero_d, -1.0/Zero_d, -1.0/Zero_d, -1.0/Zero_d))) ? 1 : 0;
return Error;
}
#if(GLM_COMPILER & GLM_COMPILER_VC)
# pragma warning(pop)
#endif
+182
View File
@@ -0,0 +1,182 @@
#define GLM_ENABLE_EXPERIMENTAL
#include <glm/gtx/component_wise.hpp>
#include <glm/gtc/type_precision.hpp>
#include <glm/gtc/epsilon.hpp>
#include <glm/gtc/constants.hpp>
#include <glm/ext/scalar_relational.hpp>
#include <glm/ext/scalar_constants.hpp>
#include <limits>
namespace compNormalize
{
static int run()
{
int Error(0);
{
glm::vec4 const A = glm::compNormalize<float>(glm::u8vec4(0, 127, 128, 255));
Error += glm::epsilonEqual(A.x, 0.0f, glm::epsilon<float>()) ? 0 : 1;
Error += A.y < 0.5f ? 0 : 1;
Error += A.z > 0.5f ? 0 : 1;
Error += glm::epsilonEqual(A.w, 1.0f, glm::epsilon<float>()) ? 0 : 1;
}
{
glm::vec4 const A = glm::compNormalize<float>(glm::i8vec4(-128, -1, 0, 127));
Error += glm::epsilonEqual(A.x,-1.0f, glm::epsilon<float>()) ? 0 : 1;
Error += A.y < 0.0f ? 0 : 1;
Error += A.z > 0.0f ? 0 : 1;
Error += glm::epsilonEqual(A.w, 1.0f, glm::epsilon<float>()) ? 0 : 1;
}
{
glm::vec4 const A = glm::compNormalize<float>(glm::u16vec4(
std::numeric_limits<glm::u16>::min(),
(std::numeric_limits<glm::u16>::max() >> 1) + 0,
(std::numeric_limits<glm::u16>::max() >> 1) + 1,
std::numeric_limits<glm::u16>::max()));
Error += glm::epsilonEqual(A.x, 0.0f, glm::epsilon<float>()) ? 0 : 1;
Error += A.y < 0.5f ? 0 : 1;
Error += A.z > 0.5f ? 0 : 1;
Error += glm::epsilonEqual(A.w, 1.0f, glm::epsilon<float>()) ? 0 : 1;
}
{
glm::vec4 const A = glm::compNormalize<float>(glm::i16vec4(
std::numeric_limits<glm::i16>::min(),
static_cast<glm::i16>(-1),
static_cast<glm::i16>(0),
std::numeric_limits<glm::i16>::max()));
Error += glm::epsilonEqual(A.x,-1.0f, glm::epsilon<float>()) ? 0 : 1;
Error += A.y < 0.0f ? 0 : 1;
Error += A.z > 0.0f ? 0 : 1;
Error += glm::epsilonEqual(A.w, 1.0f, glm::epsilon<float>()) ? 0 : 1;
}
return Error;
}
}//namespace compNormalize
namespace compScale
{
static int run()
{
int Error(0);
{
glm::u8vec4 const A = glm::compScale<glm::u8>(glm::vec4(0.0f, 0.2f, 0.5f, 1.0f));
Error += A.x == std::numeric_limits<glm::u8>::min() ? 0 : 1;
Error += A.y < (std::numeric_limits<glm::u8>::max() >> 2) ? 0 : 1;
Error += A.z == 127 ? 0 : 1;
Error += A.w == 255 ? 0 : 1;
}
{
glm::i8vec4 const A = glm::compScale<glm::i8>(glm::vec4(0.0f,-1.0f, 0.5f, 1.0f));
Error += A.x == 0 ? 0 : 1;
Error += A.y == -128 ? 0 : 1;
Error += A.z == 63 ? 0 : 1;
Error += A.w == 127 ? 0 : 1;
}
{
glm::u16vec4 const A = glm::compScale<glm::u16>(glm::vec4(0.0f, 0.2f, 0.5f, 1.0f));
Error += A.x == std::numeric_limits<glm::u16>::min() ? 0 : 1;
Error += A.y < (std::numeric_limits<glm::u16>::max() >> 2) ? 0 : 1;
Error += A.z == 32767 ? 0 : 1;
Error += A.w == 65535 ? 0 : 1;
}
{
glm::i16vec4 const A = glm::compScale<glm::i16>(glm::vec4(0.0f,-1.0f, 0.5f, 1.0f));
Error += A.x == 0 ? 0 : 1;
Error += A.y == -32768 ? 0 : 1;
Error += A.z == 16383 ? 0 : 1;
Error += A.w == 32767 ? 0 : 1;
}
return Error;
}
}// compScale
#if ((GLM_LANG & GLM_LANG_CXX11_FLAG) || (GLM_COMPILER & GLM_COMPILER_VC))
namespace fcompMax
{
static int run()
{
int Error(0);
{
float const A = glm::fcompMax(glm::vec4(NAN, 0.2f, 0.5f, 1.0f));
Error += glm::equal(A, 1.0f, glm::epsilon<float>()) ? 0 : 1;
}
{
float const A = glm::fcompMax(glm::vec4(2.0f, NAN, 0.3f, 0.7f));
Error += glm::equal(A, 2.0f, glm::epsilon<float>()) ? 0 : 1;
}
{
float const A = glm::fcompMax(glm::vec4(NAN, NAN, NAN, NAN));
Error += std::isnan(A) ? 0 : 1;
}
return Error;
}
}// fcompMax
namespace fcompMin
{
static int run()
{
int Error(0);
{
float const A = glm::fcompMin(glm::vec4(NAN, 0.2f, 0.5f, 1.0f));
Error += glm::equal(A, 0.2f, glm::epsilon<float>()) ? 0 : 1;
}
{
float const A = glm::fcompMin(glm::vec4(2.0f, NAN, 0.3f, 0.7f));
Error += glm::equal(A, 0.3f, glm::epsilon<float>()) ? 0 : 1;
}
{
float const A = glm::fcompMin(glm::vec4(NAN, NAN, NAN, NAN));
Error += std::isnan(A) ? 0 : 1;
}
return Error;
}
}// fcompMin
#endif//((GLM_LANG & GLM_LANG_CXX11_FLAG) || (GLM_COMPILER & GLM_COMPILER_VC))
int main()
{
int Error(0);
Error += compNormalize::run();
Error += compScale::run();
#if ((GLM_LANG & GLM_LANG_CXX11_FLAG) || (GLM_COMPILER & GLM_COMPILER_VC))
Error += fcompMax::run();
Error += fcompMin::run();
#endif//((GLM_LANG & GLM_LANG_CXX11_FLAG) || (GLM_COMPILER & GLM_COMPILER_VC))
return Error;
}
+205
View File
@@ -0,0 +1,205 @@
#define GLM_ENABLE_EXPERIMENTAL
#define GLM_FORCE_CTOR_INIT
#include <glm/gtx/dual_quaternion.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/epsilon.hpp>
#include <glm/gtx/euler_angles.hpp>
#include <glm/vector_relational.hpp>
#if GLM_HAS_TRIVIAL_QUERIES
# include <type_traits>
#endif
static int myrand()
{
static int holdrand = 1;
return (((holdrand = holdrand * 214013L + 2531011L) >> 16) & 0x7fff);
}
static float myfrand() // returns values from -1 to 1 inclusive
{
return float(double(myrand()) / double( 0x7ffff )) * 2.0f - 1.0f;
}
static int test_dquat_type()
{
glm::dvec3 vA;
glm::dquat dqA, dqB;
glm::ddualquat C(dqA, dqB);
glm::ddualquat B(dqA);
glm::ddualquat D(dqA, vA);
return 0;
}
static int test_scalars()
{
float const Epsilon = 0.0001f;
int Error(0);
glm::quat src_q1 = glm::quat(1.0f,2.0f,3.0f,4.0f);
glm::quat src_q2 = glm::quat(5.0f,6.0f,7.0f,8.0f);
glm::dualquat src1(src_q1,src_q2);
{
glm::dualquat dst1 = src1 * 2.0f;
glm::dualquat dst2 = 2.0f * src1;
glm::dualquat dst3 = src1;
dst3 *= 2.0f;
glm::dualquat dstCmp(src_q1 * 2.0f,src_q2 * 2.0f);
Error += glm::all(glm::epsilonEqual(dst1.real,dstCmp.real, Epsilon)) && glm::all(glm::epsilonEqual(dst1.dual,dstCmp.dual, Epsilon)) ? 0 : 1;
Error += glm::all(glm::epsilonEqual(dst2.real,dstCmp.real, Epsilon)) && glm::all(glm::epsilonEqual(dst2.dual,dstCmp.dual, Epsilon)) ? 0 : 1;
Error += glm::all(glm::epsilonEqual(dst3.real,dstCmp.real, Epsilon)) && glm::all(glm::epsilonEqual(dst3.dual,dstCmp.dual, Epsilon)) ? 0 : 1;
}
{
glm::dualquat dst1 = src1 / 2.0f;
glm::dualquat dst2 = src1;
dst2 /= 2.0f;
glm::dualquat dstCmp(src_q1 / 2.0f,src_q2 / 2.0f);
Error += glm::all(glm::epsilonEqual(dst1.real,dstCmp.real, Epsilon)) && glm::all(glm::epsilonEqual(dst1.dual,dstCmp.dual, Epsilon)) ? 0 : 1;
Error += glm::all(glm::epsilonEqual(dst2.real,dstCmp.real, Epsilon)) && glm::all(glm::epsilonEqual(dst2.dual,dstCmp.dual, Epsilon)) ? 0 : 1;
}
return Error;
}
static int test_inverse()
{
int Error(0);
float const Epsilon = 0.0001f;
glm::dualquat dqid = glm::dual_quat_identity<float, glm::defaultp>();
glm::mat4x4 mid(1.0f);
for (int j = 0; j < 100; ++j)
{
glm::mat4x4 rot = glm::yawPitchRoll(myfrand() * 360.0f, myfrand() * 360.0f, myfrand() * 360.0f);
glm::vec3 vt = glm::vec3(myfrand() * 10.0f, myfrand() * 10.0f, myfrand() * 10.0f);
glm::mat4x4 m = glm::translate(mid, vt) * rot;
glm::quat qr = glm::quat_cast(m);
glm::dualquat dq(qr);
glm::dualquat invdq = glm::inverse(dq);
glm::dualquat r1 = invdq * dq;
glm::dualquat r2 = dq * invdq;
Error += glm::all(glm::epsilonEqual(r1.real, dqid.real, Epsilon)) && glm::all(glm::epsilonEqual(r1.dual, dqid.dual, Epsilon)) ? 0 : 1;
Error += glm::all(glm::epsilonEqual(r2.real, dqid.real, Epsilon)) && glm::all(glm::epsilonEqual(r2.dual, dqid.dual, Epsilon)) ? 0 : 1;
// testing commutative property
glm::dualquat r ( glm::quat( myfrand() * glm::pi<float>() * 2.0f, myfrand(), myfrand(), myfrand() ),
glm::vec3(myfrand() * 10.0f, myfrand() * 10.0f, myfrand() * 10.0f) );
glm::dualquat riq = (r * invdq) * dq;
glm::dualquat rqi = (r * dq) * invdq;
Error += glm::all(glm::epsilonEqual(riq.real, rqi.real, Epsilon)) && glm::all(glm::epsilonEqual(riq.dual, rqi.dual, Epsilon)) ? 0 : 1;
}
return Error;
}
static int test_mul()
{
int Error(0);
float const Epsilon = 0.0001f;
glm::mat4x4 mid(1.0f);
for (int j = 0; j < 100; ++j)
{
// generate random rotations and translations and compare transformed by matrix and dualquats random points
glm::vec3 vt1 = glm::vec3(myfrand() * 10.0f, myfrand() * 10.0f, myfrand() * 10.0f);
glm::vec3 vt2 = glm::vec3(myfrand() * 10.0f, myfrand() * 10.0f, myfrand() * 10.0f);
glm::mat4x4 rot1 = glm::yawPitchRoll(myfrand() * 360.0f, myfrand() * 360.0f, myfrand() * 360.0f);
glm::mat4x4 rot2 = glm::yawPitchRoll(myfrand() * 360.0f, myfrand() * 360.0f, myfrand() * 360.0f);
glm::mat4x4 m1 = glm::translate(mid, vt1) * rot1;
glm::mat4x4 m2 = glm::translate(mid, vt2) * rot2;
glm::mat4x4 m3 = m2 * m1;
glm::mat4x4 m4 = m1 * m2;
glm::quat qrot1 = glm::quat_cast(rot1);
glm::quat qrot2 = glm::quat_cast(rot2);
glm::dualquat dq1 = glm::dualquat(qrot1,vt1);
glm::dualquat dq2 = glm::dualquat(qrot2,vt2);
glm::dualquat dq3 = dq2 * dq1;
glm::dualquat dq4 = dq1 * dq2;
for (int i = 0; i < 100; ++i)
{
glm::vec4 src_pt = glm::vec4(myfrand() * 4.0f, myfrand() * 5.0f, myfrand() * 3.0f,1.0f);
// test both multiplication orders
glm::vec4 dst_pt_m3 = m3 * src_pt;
glm::vec4 dst_pt_dq3 = dq3 * src_pt;
glm::vec4 dst_pt_m3_i = glm::inverse(m3) * src_pt;
glm::vec4 dst_pt_dq3_i = src_pt * dq3;
glm::vec4 dst_pt_m4 = m4 * src_pt;
glm::vec4 dst_pt_dq4 = dq4 * src_pt;
glm::vec4 dst_pt_m4_i = glm::inverse(m4) * src_pt;
glm::vec4 dst_pt_dq4_i = src_pt * dq4;
Error += glm::all(glm::epsilonEqual(dst_pt_m3, dst_pt_dq3, Epsilon)) ? 0 : 1;
Error += glm::all(glm::epsilonEqual(dst_pt_m4, dst_pt_dq4, Epsilon)) ? 0 : 1;
Error += glm::all(glm::epsilonEqual(dst_pt_m3_i, dst_pt_dq3_i, Epsilon)) ? 0 : 1;
Error += glm::all(glm::epsilonEqual(dst_pt_m4_i, dst_pt_dq4_i, Epsilon)) ? 0 : 1;
}
}
return Error;
}
static int test_dual_quat_ctr()
{
int Error(0);
# if GLM_HAS_TRIVIAL_QUERIES
// Error += std::is_trivially_default_constructible<glm::dualquat>::value ? 0 : 1;
// Error += std::is_trivially_default_constructible<glm::ddualquat>::value ? 0 : 1;
// Error += std::is_trivially_copy_assignable<glm::dualquat>::value ? 0 : 1;
// Error += std::is_trivially_copy_assignable<glm::ddualquat>::value ? 0 : 1;
Error += std::is_trivially_copyable<glm::dualquat>::value ? 0 : 1;
Error += std::is_trivially_copyable<glm::ddualquat>::value ? 0 : 1;
Error += std::is_copy_constructible<glm::dualquat>::value ? 0 : 1;
Error += std::is_copy_constructible<glm::ddualquat>::value ? 0 : 1;
# endif
return Error;
}
static int test_size()
{
int Error = 0;
Error += 32 == sizeof(glm::dualquat) ? 0 : 1;
Error += 64 == sizeof(glm::ddualquat) ? 0 : 1;
Error += glm::dualquat().length() == 2 ? 0 : 1;
Error += glm::ddualquat().length() == 2 ? 0 : 1;
Error += glm::dualquat::length() == 2 ? 0 : 1;
Error += glm::ddualquat::length() == 2 ? 0 : 1;
return Error;
}
int main()
{
int Error = 0;
Error += test_dual_quat_ctr();
Error += test_dquat_type();
Error += test_scalars();
Error += test_inverse();
Error += test_mul();
Error += test_size();
return Error;
}
+91
View File
@@ -0,0 +1,91 @@
#define GLM_ENABLE_EXPERIMENTAL
#include <glm/glm.hpp>
#include <glm/gtx/quaternion.hpp>
#include <glm/gtx/easing.hpp>
namespace
{
template<typename T>
static void _test_easing()
{
T a = static_cast<T>(0.5);
T r;
r = glm::linearInterpolation(a);
(void)r;
r = glm::quadraticEaseIn(a);
(void)r;
r = glm::quadraticEaseOut(a);
(void)r;
r = glm::quadraticEaseInOut(a);
(void)r;
r = glm::cubicEaseIn(a);
(void)r;
r = glm::cubicEaseOut(a);
(void)r;
r = glm::cubicEaseInOut(a);
(void)r;
r = glm::quarticEaseIn(a);
(void)r;
r = glm::quarticEaseOut(a);
(void)r;
r = glm::quinticEaseInOut(a);
(void)r;
r = glm::sineEaseIn(a);
(void)r;
r = glm::sineEaseOut(a);
(void)r;
r = glm::sineEaseInOut(a);
(void)r;
r = glm::circularEaseIn(a);
(void)r;
r = glm::circularEaseOut(a);
(void)r;
r = glm::circularEaseInOut(a);
(void)r;
r = glm::exponentialEaseIn(a);
(void)r;
r = glm::exponentialEaseOut(a);
(void)r;
r = glm::exponentialEaseInOut(a);
(void)r;
r = glm::elasticEaseIn(a);
(void)r;
r = glm::elasticEaseOut(a);
(void)r;
r = glm::elasticEaseInOut(a);
(void)r;
r = glm::backEaseIn(a);
(void)r;
r = glm::backEaseOut(a);
(void)r;
r = glm::backEaseInOut(a);
(void)r;
r = glm::bounceEaseIn(a);
(void)r;
r = glm::bounceEaseOut(a);
(void)r;
r = glm::bounceEaseInOut(a);
(void)r;
}
}
int main()
{
int Error = 0;
_test_easing<float>();
_test_easing<double>();
return Error;
}
+537
View File
@@ -0,0 +1,537 @@
// Code sample from Filippo Ramaciotti
#define GLM_ENABLE_EXPERIMENTAL
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtx/matrix_cross_product.hpp>
#include <glm/gtx/matrix_operation.hpp>
#include <glm/gtc/epsilon.hpp>
#include <glm/gtx/string_cast.hpp>
#include <glm/gtx/euler_angles.hpp>
#include <cstdio>
#include <vector>
#include <utility>
namespace test_eulerAngleX
{
static int test()
{
int Error = 0;
float const Angle(glm::pi<float>() * 0.5f);
glm::vec3 const X(1.0f, 0.0f, 0.0f);
glm::vec4 const Y(0.0f, 1.0f, 0.0f, 1.0f);
glm::vec4 const Y1 = glm::rotate(glm::mat4(1.0f), Angle, X) * Y;
glm::vec4 const Y2 = glm::eulerAngleX(Angle) * Y;
glm::vec4 const Y3 = glm::eulerAngleXY(Angle, 0.0f) * Y;
glm::vec4 const Y4 = glm::eulerAngleYX(0.0f, Angle) * Y;
glm::vec4 const Y5 = glm::eulerAngleXZ(Angle, 0.0f) * Y;
glm::vec4 const Y6 = glm::eulerAngleZX(0.0f, Angle) * Y;
glm::vec4 const Y7 = glm::eulerAngleYXZ(0.0f, Angle, 0.0f) * Y;
Error += glm::all(glm::epsilonEqual(Y1, Y2, 0.00001f)) ? 0 : 1;
Error += glm::all(glm::epsilonEqual(Y1, Y3, 0.00001f)) ? 0 : 1;
Error += glm::all(glm::epsilonEqual(Y1, Y4, 0.00001f)) ? 0 : 1;
Error += glm::all(glm::epsilonEqual(Y1, Y5, 0.00001f)) ? 0 : 1;
Error += glm::all(glm::epsilonEqual(Y1, Y6, 0.00001f)) ? 0 : 1;
Error += glm::all(glm::epsilonEqual(Y1, Y7, 0.00001f)) ? 0 : 1;
glm::vec4 const Z(0.0f, 0.0f, 1.0f, 1.0f);
glm::vec4 const Z1 = glm::rotate(glm::mat4(1.0f), Angle, X) * Z;
glm::vec4 const Z2 = glm::eulerAngleX(Angle) * Z;
glm::vec4 const Z3 = glm::eulerAngleXY(Angle, 0.0f) * Z;
glm::vec4 const Z4 = glm::eulerAngleYX(0.0f, Angle) * Z;
glm::vec4 const Z5 = glm::eulerAngleXZ(Angle, 0.0f) * Z;
glm::vec4 const Z6 = glm::eulerAngleZX(0.0f, Angle) * Z;
glm::vec4 const Z7 = glm::eulerAngleYXZ(0.0f, Angle, 0.0f) * Z;
Error += glm::all(glm::epsilonEqual(Z1, Z2, 0.00001f)) ? 0 : 1;
Error += glm::all(glm::epsilonEqual(Z1, Z3, 0.00001f)) ? 0 : 1;
Error += glm::all(glm::epsilonEqual(Z1, Z4, 0.00001f)) ? 0 : 1;
Error += glm::all(glm::epsilonEqual(Z1, Z5, 0.00001f)) ? 0 : 1;
Error += glm::all(glm::epsilonEqual(Z1, Z6, 0.00001f)) ? 0 : 1;
Error += glm::all(glm::epsilonEqual(Z1, Z7, 0.00001f)) ? 0 : 1;
return Error;
}
}//namespace test_eulerAngleX
namespace test_eulerAngleY
{
static int test()
{
int Error = 0;
float const Angle(glm::pi<float>() * 0.5f);
glm::vec3 const Y(0.0f, 1.0f, 0.0f);
glm::vec4 const X(1.0f, 0.0f, 0.0f, 1.0f);
glm::vec4 const X1 = glm::rotate(glm::mat4(1.0f), Angle, Y) * X;
glm::vec4 const X2 = glm::eulerAngleY(Angle) * X;
glm::vec4 const X3 = glm::eulerAngleYX(Angle, 0.0f) * X;
glm::vec4 const X4 = glm::eulerAngleXY(0.0f, Angle) * X;
glm::vec4 const X5 = glm::eulerAngleYZ(Angle, 0.0f) * X;
glm::vec4 const X6 = glm::eulerAngleZY(0.0f, Angle) * X;
glm::vec4 const X7 = glm::eulerAngleYXZ(Angle, 0.0f, 0.0f) * X;
Error += glm::all(glm::epsilonEqual(X1, X2, 0.00001f)) ? 0 : 1;
Error += glm::all(glm::epsilonEqual(X1, X3, 0.00001f)) ? 0 : 1;
Error += glm::all(glm::epsilonEqual(X1, X4, 0.00001f)) ? 0 : 1;
Error += glm::all(glm::epsilonEqual(X1, X5, 0.00001f)) ? 0 : 1;
Error += glm::all(glm::epsilonEqual(X1, X6, 0.00001f)) ? 0 : 1;
Error += glm::all(glm::epsilonEqual(X1, X7, 0.00001f)) ? 0 : 1;
glm::vec4 const Z(0.0f, 0.0f, 1.0f, 1.0f);
glm::vec4 const Z1 = glm::eulerAngleY(Angle) * Z;
glm::vec4 const Z2 = glm::rotate(glm::mat4(1.0f), Angle, Y) * Z;
glm::vec4 const Z3 = glm::eulerAngleYX(Angle, 0.0f) * Z;
glm::vec4 const Z4 = glm::eulerAngleXY(0.0f, Angle) * Z;
glm::vec4 const Z5 = glm::eulerAngleYZ(Angle, 0.0f) * Z;
glm::vec4 const Z6 = glm::eulerAngleZY(0.0f, Angle) * Z;
glm::vec4 const Z7 = glm::eulerAngleYXZ(Angle, 0.0f, 0.0f) * Z;
Error += glm::all(glm::epsilonEqual(Z1, Z2, 0.00001f)) ? 0 : 1;
Error += glm::all(glm::epsilonEqual(Z1, Z3, 0.00001f)) ? 0 : 1;
Error += glm::all(glm::epsilonEqual(Z1, Z4, 0.00001f)) ? 0 : 1;
Error += glm::all(glm::epsilonEqual(Z1, Z5, 0.00001f)) ? 0 : 1;
Error += glm::all(glm::epsilonEqual(Z1, Z6, 0.00001f)) ? 0 : 1;
Error += glm::all(glm::epsilonEqual(Z1, Z7, 0.00001f)) ? 0 : 1;
return Error;
}
}//namespace test_eulerAngleY
namespace test_eulerAngleZ
{
static int test()
{
int Error = 0;
float const Angle(glm::pi<float>() * 0.5f);
glm::vec3 const Z(0.0f, 0.0f, 1.0f);
glm::vec4 const X(1.0f, 0.0f, 0.0f, 1.0f);
glm::vec4 const X1 = glm::rotate(glm::mat4(1.0f), Angle, Z) * X;
glm::vec4 const X2 = glm::eulerAngleZ(Angle) * X;
glm::vec4 const X3 = glm::eulerAngleZX(Angle, 0.0f) * X;
glm::vec4 const X4 = glm::eulerAngleXZ(0.0f, Angle) * X;
glm::vec4 const X5 = glm::eulerAngleZY(Angle, 0.0f) * X;
glm::vec4 const X6 = glm::eulerAngleYZ(0.0f, Angle) * X;
glm::vec4 const X7 = glm::eulerAngleYXZ(0.0f, 0.0f, Angle) * X;
Error += glm::all(glm::epsilonEqual(X1, X2, 0.00001f)) ? 0 : 1;
Error += glm::all(glm::epsilonEqual(X1, X3, 0.00001f)) ? 0 : 1;
Error += glm::all(glm::epsilonEqual(X1, X4, 0.00001f)) ? 0 : 1;
Error += glm::all(glm::epsilonEqual(X1, X5, 0.00001f)) ? 0 : 1;
Error += glm::all(glm::epsilonEqual(X1, X6, 0.00001f)) ? 0 : 1;
Error += glm::all(glm::epsilonEqual(X1, X7, 0.00001f)) ? 0 : 1;
glm::vec4 const Y(1.0f, 0.0f, 0.0f, 1.0f);
glm::vec4 const Z1 = glm::rotate(glm::mat4(1.0f), Angle, Z) * Y;
glm::vec4 const Z2 = glm::eulerAngleZ(Angle) * Y;
glm::vec4 const Z3 = glm::eulerAngleZX(Angle, 0.0f) * Y;
glm::vec4 const Z4 = glm::eulerAngleXZ(0.0f, Angle) * Y;
glm::vec4 const Z5 = glm::eulerAngleZY(Angle, 0.0f) * Y;
glm::vec4 const Z6 = glm::eulerAngleYZ(0.0f, Angle) * Y;
glm::vec4 const Z7 = glm::eulerAngleYXZ(0.0f, 0.0f, Angle) * Y;
Error += glm::all(glm::epsilonEqual(Z1, Z2, 0.00001f)) ? 0 : 1;
Error += glm::all(glm::epsilonEqual(Z1, Z3, 0.00001f)) ? 0 : 1;
Error += glm::all(glm::epsilonEqual(Z1, Z4, 0.00001f)) ? 0 : 1;
Error += glm::all(glm::epsilonEqual(Z1, Z5, 0.00001f)) ? 0 : 1;
Error += glm::all(glm::epsilonEqual(Z1, Z6, 0.00001f)) ? 0 : 1;
Error += glm::all(glm::epsilonEqual(Z1, Z7, 0.00001f)) ? 0 : 1;
return Error;
}
}//namespace test_eulerAngleZ
namespace test_derivedEulerAngles
{
static bool epsilonEqual(glm::mat4 const& mat1, glm::mat4 const& mat2, glm::mat4::value_type const& epsilon)
{
return glm::all(glm::epsilonEqual(mat1[0], mat2[0], epsilon)) ?
(
glm::all(glm::epsilonEqual(mat1[1], mat2[1], epsilon)) ?
(
glm::all(glm::epsilonEqual(mat1[2], mat2[2], epsilon)) ?
(
glm::all(glm::epsilonEqual(mat1[3], mat2[3], epsilon)) ? true : false
) : false
) : false
) : false;
}
template<typename RotationFunc, typename TestDerivedFunc>
static int test(RotationFunc rotationFunc, TestDerivedFunc testDerivedFunc, const glm::vec3& basis)
{
int Error = 0;
typedef glm::vec3::value_type value;
value const zeroAngle(0.0f);
value const Angle(glm::pi<float>() * 0.75f);
value const negativeAngle(-Angle);
value const zeroAngleVelocity(0.0f);
value const AngleVelocity(glm::pi<float>() * 0.27f);
value const negativeAngleVelocity(-AngleVelocity);
typedef std::pair<value,value> AngleAndAngleVelocity;
std::vector<AngleAndAngleVelocity> testPairs;
testPairs.push_back(AngleAndAngleVelocity(zeroAngle, zeroAngleVelocity));
testPairs.push_back(AngleAndAngleVelocity(zeroAngle, AngleVelocity));
testPairs.push_back(AngleAndAngleVelocity(zeroAngle, negativeAngleVelocity));
testPairs.push_back(AngleAndAngleVelocity(Angle, zeroAngleVelocity));
testPairs.push_back(AngleAndAngleVelocity(Angle, AngleVelocity));
testPairs.push_back(AngleAndAngleVelocity(Angle, negativeAngleVelocity));
testPairs.push_back(AngleAndAngleVelocity(negativeAngle, zeroAngleVelocity));
testPairs.push_back(AngleAndAngleVelocity(negativeAngle, AngleVelocity));
testPairs.push_back(AngleAndAngleVelocity(negativeAngle, negativeAngleVelocity));
for (size_t i = 0, size = testPairs.size(); i < size; ++i)
{
AngleAndAngleVelocity const& pair = testPairs.at(i);
glm::mat4 const W = glm::matrixCross4(basis * pair.second);
glm::mat4 const rotMt = glm::transpose(rotationFunc(pair.first));
glm::mat4 const derivedRotM = testDerivedFunc(pair.first, pair.second);
Error += epsilonEqual(W, derivedRotM * rotMt, 0.00001f) ? 0 : 1;
}
return Error;
}
}//namespace test_derivedEulerAngles
namespace test_eulerAngleXY
{
static int test()
{
int Error = 0;
glm::vec4 const V(1.0f);
float const AngleX(glm::pi<float>() * 0.5f);
float const AngleY(glm::pi<float>() * 0.25f);
glm::vec3 const axisX(1.0f, 0.0f, 0.0f);
glm::vec3 const axisY(0.0f, 1.0f, 0.0f);
glm::vec4 const V1 = (glm::rotate(glm::mat4(1.0f), AngleX, axisX) * glm::rotate(glm::mat4(1.0f), AngleY, axisY)) * V;
glm::vec4 const V2 = glm::eulerAngleXY(AngleX, AngleY) * V;
glm::vec4 const V3 = glm::eulerAngleX(AngleX) * glm::eulerAngleY(AngleY) * V;
Error += glm::all(glm::epsilonEqual(V1, V2, 0.00001f)) ? 0 : 1;
Error += glm::all(glm::epsilonEqual(V1, V3, 0.00001f)) ? 0 : 1;
return Error;
}
}//namespace test_eulerAngleXY
namespace test_eulerAngleYX
{
static int test()
{
int Error = 0;
glm::vec4 const V(1.0f);
float const AngleX(glm::pi<float>() * 0.5f);
float const AngleY(glm::pi<float>() * 0.25f);
glm::vec3 const axisX(1.0f, 0.0f, 0.0f);
glm::vec3 const axisY(0.0f, 1.0f, 0.0f);
glm::vec4 const V1 = (glm::rotate(glm::mat4(1.0f), AngleY, axisY) * glm::rotate(glm::mat4(1.0f), AngleX, axisX)) * V;
glm::vec4 const V2 = glm::eulerAngleYX(AngleY, AngleX) * V;
glm::vec4 const V3 = glm::eulerAngleY(AngleY) * glm::eulerAngleX(AngleX) * V;
Error += glm::all(glm::epsilonEqual(V1, V2, 0.00001f)) ? 0 : 1;
Error += glm::all(glm::epsilonEqual(V1, V3, 0.00001f)) ? 0 : 1;
return Error;
}
}//namespace test_eulerAngleYX
namespace test_eulerAngleXZ
{
static int test()
{
int Error = 0;
glm::vec4 const V(1.0f);
float const AngleX(glm::pi<float>() * 0.5f);
float const AngleZ(glm::pi<float>() * 0.25f);
glm::vec3 const axisX(1.0f, 0.0f, 0.0f);
glm::vec3 const axisZ(0.0f, 0.0f, 1.0f);
glm::vec4 const V1 = (glm::rotate(glm::mat4(1.0f), AngleX, axisX) * glm::rotate(glm::mat4(1.0f), AngleZ, axisZ)) * V;
glm::vec4 const V2 = glm::eulerAngleXZ(AngleX, AngleZ) * V;
glm::vec4 const V3 = glm::eulerAngleX(AngleX) * glm::eulerAngleZ(AngleZ) * V;
Error += glm::all(glm::epsilonEqual(V1, V2, 0.00001f)) ? 0 : 1;
Error += glm::all(glm::epsilonEqual(V1, V3, 0.00001f)) ? 0 : 1;
return Error;
}
}//namespace test_eulerAngleXZ
namespace test_eulerAngleZX
{
static int test()
{
int Error = 0;
glm::vec4 const V(1.0f);
float const AngleX(glm::pi<float>() * 0.5f);
float const AngleZ(glm::pi<float>() * 0.25f);
glm::vec3 const axisX(1.0f, 0.0f, 0.0f);
glm::vec3 const axisZ(0.0f, 0.0f, 1.0f);
glm::vec4 const V1 = (glm::rotate(glm::mat4(1.0f), AngleZ, axisZ) * glm::rotate(glm::mat4(1.0f), AngleX, axisX)) * V;
glm::vec4 const V2 = glm::eulerAngleZX(AngleZ, AngleX) * V;
glm::vec4 const V3 = glm::eulerAngleZ(AngleZ) * glm::eulerAngleX(AngleX) * V;
Error += glm::all(glm::epsilonEqual(V1, V2, 0.00001f)) ? 0 : 1;
Error += glm::all(glm::epsilonEqual(V1, V3, 0.00001f)) ? 0 : 1;
return Error;
}
}//namespace test_eulerAngleZX
namespace test_eulerAngleYZ
{
static int test()
{
int Error = 0;
glm::vec4 const V(1.0f);
float const AngleY(glm::pi<float>() * 0.5f);
float const AngleZ(glm::pi<float>() * 0.25f);
glm::vec3 const axisY(0.0f, 1.0f, 0.0f);
glm::vec3 const axisZ(0.0f, 0.0f, 1.0f);
glm::vec4 const V1 = (glm::rotate(glm::mat4(1.0f), AngleY, axisY) * glm::rotate(glm::mat4(1.0f), AngleZ, axisZ)) * V;
glm::vec4 const V2 = glm::eulerAngleYZ(AngleY, AngleZ) * V;
glm::vec4 const V3 = glm::eulerAngleY(AngleY) * glm::eulerAngleZ(AngleZ) * V;
Error += glm::all(glm::epsilonEqual(V1, V2, 0.00001f)) ? 0 : 1;
Error += glm::all(glm::epsilonEqual(V1, V3, 0.00001f)) ? 0 : 1;
return Error;
}
}//namespace test_eulerAngleYZ
namespace test_eulerAngleZY
{
static int test()
{
int Error = 0;
glm::vec4 const V(1.0f);
float const AngleY(glm::pi<float>() * 0.5f);
float const AngleZ(glm::pi<float>() * 0.25f);
glm::vec3 const axisY(0.0f, 1.0f, 0.0f);
glm::vec3 const axisZ(0.0f, 0.0f, 1.0f);
glm::vec4 const V1 = (glm::rotate(glm::mat4(1.0f), AngleZ, axisZ) * glm::rotate(glm::mat4(1.0f), AngleY, axisY)) * V;
glm::vec4 const V2 = glm::eulerAngleZY(AngleZ, AngleY) * V;
glm::vec4 const V3 = glm::eulerAngleZ(AngleZ) * glm::eulerAngleY(AngleY) * V;
Error += glm::all(glm::epsilonEqual(V1, V2, 0.00001f)) ? 0 : 1;
Error += glm::all(glm::epsilonEqual(V1, V3, 0.00001f)) ? 0 : 1;
return Error;
}
}//namespace test_eulerAngleZY
namespace test_eulerAngleYXZ
{
static int test()
{
glm::f32 first = 1.046f;
glm::f32 second = 0.52f;
glm::f32 third = -0.785f;
glm::fmat4 rotationEuler = glm::eulerAngleYXZ(first, second, third);
glm::fmat4 rotationInvertedY = glm::eulerAngleY(-1.f*first) * glm::eulerAngleX(second) * glm::eulerAngleZ(third);
glm::fmat4 rotationDumb = glm::fmat4();
rotationDumb = glm::rotate(rotationDumb, first, glm::fvec3(0,1,0));
rotationDumb = glm::rotate(rotationDumb, second, glm::fvec3(1,0,0));
rotationDumb = glm::rotate(rotationDumb, third, glm::fvec3(0,0,1));
std::printf("%s\n", glm::to_string(glm::fmat3(rotationEuler)).c_str());
std::printf("%s\n", glm::to_string(glm::fmat3(rotationDumb)).c_str());
std::printf("%s\n", glm::to_string(glm::fmat3(rotationInvertedY)).c_str());
std::printf("\nRESIDUAL\n");
std::printf("%s\n", glm::to_string(glm::fmat3(rotationEuler-(rotationDumb))).c_str());
std::printf("%s\n", glm::to_string(glm::fmat3(rotationEuler-(rotationInvertedY))).c_str());
return 0;
}
}//namespace eulerAngleYXZ
namespace test_eulerAngles
{
template<typename TestRotationFunc>
static int test(TestRotationFunc testRotationFunc, glm::vec3 const& I, glm::vec3 const& J, glm::vec3 const& K)
{
int Error = 0;
typedef glm::mat4::value_type value;
value const minAngle(-glm::pi<value>());
value const maxAngle(glm::pi<value>());
value const maxAngleWithDelta(maxAngle - 0.0000001f);
value const minMidAngle(-glm::pi<value>() * 0.5f);
value const maxMidAngle(glm::pi<value>() * 0.5f);
std::vector<glm::vec3> testEulerAngles;
testEulerAngles.push_back(glm::vec3(1.046f, 0.52f, -0.785f));
testEulerAngles.push_back(glm::vec3(minAngle, minMidAngle, minAngle));
testEulerAngles.push_back(glm::vec3(minAngle, minMidAngle, maxAngle));
testEulerAngles.push_back(glm::vec3(minAngle, minMidAngle, maxAngleWithDelta));
testEulerAngles.push_back(glm::vec3(minAngle, maxMidAngle, minAngle));
testEulerAngles.push_back(glm::vec3(minAngle, maxMidAngle, maxAngle));
testEulerAngles.push_back(glm::vec3(minAngle, maxMidAngle, maxAngleWithDelta));
testEulerAngles.push_back(glm::vec3(maxAngle, minMidAngle, minAngle));
testEulerAngles.push_back(glm::vec3(maxAngle, minMidAngle, maxAngle));
testEulerAngles.push_back(glm::vec3(maxAngle, minMidAngle, maxAngleWithDelta));
testEulerAngles.push_back(glm::vec3(maxAngleWithDelta, minMidAngle, maxAngle));
testEulerAngles.push_back(glm::vec3(maxAngleWithDelta, minMidAngle, maxAngleWithDelta));
testEulerAngles.push_back(glm::vec3(maxAngle, maxMidAngle, minAngle));
testEulerAngles.push_back(glm::vec3(maxAngleWithDelta, maxMidAngle, minAngle));
testEulerAngles.push_back(glm::vec3(maxAngle, maxMidAngle, maxAngle));
testEulerAngles.push_back(glm::vec3(maxAngle, maxMidAngle, maxAngleWithDelta));
testEulerAngles.push_back(glm::vec3(maxAngleWithDelta, maxMidAngle, maxAngle));
testEulerAngles.push_back(glm::vec3(maxAngleWithDelta, maxMidAngle, maxAngleWithDelta));
testEulerAngles.push_back(glm::vec3(minAngle, 0.0f, minAngle));
testEulerAngles.push_back(glm::vec3(minAngle, 0.0f, maxAngle));
testEulerAngles.push_back(glm::vec3(maxAngle, maxAngle, minAngle));
testEulerAngles.push_back(glm::vec3(maxAngle, maxAngle, maxAngle));
for (size_t i = 0, size = testEulerAngles.size(); i < size; ++i)
{
glm::vec3 const& angles = testEulerAngles.at(i);
glm::mat4 const rotationEuler = testRotationFunc(angles.x, angles.y, angles.z);
glm::mat4 rotationDumb = glm::diagonal4x4(glm::mat4::col_type(1.0f));
rotationDumb = glm::rotate(rotationDumb, angles.x, I);
rotationDumb = glm::rotate(rotationDumb, angles.y, J);
rotationDumb = glm::rotate(rotationDumb, angles.z, K);
glm::vec4 const V(1.0f,1.0f,1.0f,1.0f);
glm::vec4 const V1 = rotationEuler * V;
glm::vec4 const V2 = rotationDumb * V;
Error += glm::all(glm::epsilonEqual(V1, V2, 0.00001f)) ? 0 : 1;
}
return Error;
}
}//namespace test_extractsEulerAngles
namespace test_extractsEulerAngles
{
template<typename RotationFunc, typename TestExtractionFunc>
static int test(RotationFunc rotationFunc, TestExtractionFunc testExtractionFunc)
{
int Error = 0;
typedef glm::mat4::value_type value;
value const minAngle(-glm::pi<value>());
value const maxAngle(glm::pi<value>());
value const maxAngleWithDelta(maxAngle - 0.0000001f);
value const minMidAngle(-glm::pi<value>() * 0.5f);
value const maxMidAngle(glm::pi<value>() * 0.5f);
std::vector<glm::vec3> testEulerAngles;
testEulerAngles.push_back(glm::vec3(1.046f, 0.52f, -0.785f));
testEulerAngles.push_back(glm::vec3(minAngle, minMidAngle, minAngle));
testEulerAngles.push_back(glm::vec3(minAngle, minMidAngle, maxAngle));
testEulerAngles.push_back(glm::vec3(minAngle, minMidAngle, maxAngleWithDelta));
testEulerAngles.push_back(glm::vec3(minAngle, maxMidAngle, minAngle));
testEulerAngles.push_back(glm::vec3(minAngle, maxMidAngle, maxAngle));
testEulerAngles.push_back(glm::vec3(minAngle, maxMidAngle, maxAngleWithDelta));
testEulerAngles.push_back(glm::vec3(maxAngle, minMidAngle, minAngle));
testEulerAngles.push_back(glm::vec3(maxAngle, minMidAngle, maxAngle));
testEulerAngles.push_back(glm::vec3(maxAngle, minMidAngle, maxAngleWithDelta));
testEulerAngles.push_back(glm::vec3(maxAngleWithDelta, minMidAngle, maxAngle));
testEulerAngles.push_back(glm::vec3(maxAngleWithDelta, minMidAngle, maxAngleWithDelta));
testEulerAngles.push_back(glm::vec3(maxAngle, maxMidAngle, minAngle));
testEulerAngles.push_back(glm::vec3(maxAngleWithDelta, maxMidAngle, minAngle));
testEulerAngles.push_back(glm::vec3(maxAngle, maxMidAngle, maxAngle));
testEulerAngles.push_back(glm::vec3(maxAngle, maxMidAngle, maxAngleWithDelta));
testEulerAngles.push_back(glm::vec3(maxAngleWithDelta, maxMidAngle, maxAngle));
testEulerAngles.push_back(glm::vec3(maxAngleWithDelta, maxMidAngle, maxAngleWithDelta));
testEulerAngles.push_back(glm::vec3(minAngle, 0.0f, minAngle));
testEulerAngles.push_back(glm::vec3(minAngle, 0.0f, maxAngle));
testEulerAngles.push_back(glm::vec3(maxAngle, maxAngle, minAngle));
testEulerAngles.push_back(glm::vec3(maxAngle, maxAngle, maxAngle));
for (size_t i = 0, size = testEulerAngles.size(); i < size; ++i)
{
glm::vec3 const& angles = testEulerAngles.at(i);
glm::mat4 const rotation = rotationFunc(angles.x, angles.y, angles.z);
glm::vec3 extractedEulerAngles(0.0f);
testExtractionFunc(rotation, extractedEulerAngles.x, extractedEulerAngles.y, extractedEulerAngles.z);
glm::mat4 const extractedRotation = rotationFunc(extractedEulerAngles.x, extractedEulerAngles.y, extractedEulerAngles.z);
glm::vec4 const V(1.0f,1.0f,1.0f,1.0f);
glm::vec4 const V1 = rotation * V;
glm::vec4 const V2 = extractedRotation * V;
Error += glm::all(glm::epsilonEqual(V1, V2, 0.00001f)) ? 0 : 1;
}
return Error;
}
}//namespace test_extractsEulerAngles
int main()
{
int Error = 0;
typedef glm::mat4::value_type value;
glm::vec3 const X(1.0f, 0.0f, 0.0f);
glm::vec3 const Y(0.0f, 1.0f, 0.0f);
glm::vec3 const Z(0.0f, 0.0f, 1.0f);
Error += test_eulerAngleX::test();
Error += test_eulerAngleY::test();
Error += test_eulerAngleZ::test();
Error += test_derivedEulerAngles::test(glm::eulerAngleX<value>, glm::derivedEulerAngleX<value>, X);
Error += test_derivedEulerAngles::test(glm::eulerAngleY<value>, glm::derivedEulerAngleY<value>, Y);
Error += test_derivedEulerAngles::test(glm::eulerAngleZ<value>, glm::derivedEulerAngleZ<value>, Z);
Error += test_eulerAngleXY::test();
Error += test_eulerAngleYX::test();
Error += test_eulerAngleXZ::test();
Error += test_eulerAngleZX::test();
Error += test_eulerAngleYZ::test();
Error += test_eulerAngleZY::test();
Error += test_eulerAngleYXZ::test();
Error += test_eulerAngles::test(glm::eulerAngleXZX<value>, X, Z, X);
Error += test_eulerAngles::test(glm::eulerAngleXYX<value>, X, Y, X);
Error += test_eulerAngles::test(glm::eulerAngleYXY<value>, Y, X, Y);
Error += test_eulerAngles::test(glm::eulerAngleYZY<value>, Y, Z, Y);
Error += test_eulerAngles::test(glm::eulerAngleZYZ<value>, Z, Y, Z);
Error += test_eulerAngles::test(glm::eulerAngleZXZ<value>, Z, X, Z);
Error += test_eulerAngles::test(glm::eulerAngleXZY<value>, X, Z, Y);
Error += test_eulerAngles::test(glm::eulerAngleYZX<value>, Y, Z, X);
Error += test_eulerAngles::test(glm::eulerAngleZYX<value>, Z, Y, X);
Error += test_eulerAngles::test(glm::eulerAngleZXY<value>, Z, X, Y);
Error += test_extractsEulerAngles::test(glm::eulerAngleYXZ<value>, glm::extractEulerAngleYXZ<value>);
Error += test_extractsEulerAngles::test(glm::eulerAngleXZX<value>, glm::extractEulerAngleXZX<value>);
Error += test_extractsEulerAngles::test(glm::eulerAngleXYX<value>, glm::extractEulerAngleXYX<value>);
Error += test_extractsEulerAngles::test(glm::eulerAngleYXY<value>, glm::extractEulerAngleYXY<value>);
Error += test_extractsEulerAngles::test(glm::eulerAngleYZY<value>, glm::extractEulerAngleYZY<value>);
Error += test_extractsEulerAngles::test(glm::eulerAngleZYZ<value>, glm::extractEulerAngleZYZ<value>);
Error += test_extractsEulerAngles::test(glm::eulerAngleZXZ<value>, glm::extractEulerAngleZXZ<value>);
Error += test_extractsEulerAngles::test(glm::eulerAngleXZY<value>, glm::extractEulerAngleXZY<value>);
Error += test_extractsEulerAngles::test(glm::eulerAngleYZX<value>, glm::extractEulerAngleYZX<value>);
Error += test_extractsEulerAngles::test(glm::eulerAngleZYX<value>, glm::extractEulerAngleZYX<value>);
Error += test_extractsEulerAngles::test(glm::eulerAngleZXY<value>, glm::extractEulerAngleZXY<value>);
return Error;
}
+9
View File
@@ -0,0 +1,9 @@
#define GLM_ENABLE_EXPERIMENTAL
#include <glm/gtx/extend.hpp>
int main()
{
int Error(0);
return Error;
}
+101
View File
@@ -0,0 +1,101 @@
#define GLM_ENABLE_EXPERIMENTAL
#include <glm/gtx/extended_min_max.hpp>
#include <glm/gtc/vec1.hpp>
#include <glm/gtc/constants.hpp>
#include <glm/ext/scalar_relational.hpp>
#include <glm/ext/vector_relational.hpp>
// This file has divisions by zero to test isnan
#if GLM_COMPILER & GLM_COMPILER_VC
# pragma warning(disable : 4723)
#endif
namespace fmin_
{
static int test()
{
int Error = 0;
float Zero_f = 0.0f;
glm::vec1 A0 = glm::fmin(glm::vec1(1), glm::vec1(Zero_f / 0.0f));
Error += glm::equal(A0.x, 1.0f, glm::epsilon<float>()) ? 0 : 1;
glm::vec1 A1 = glm::fmin(glm::vec1(Zero_f / 0.0f), glm::vec1(1));
Error += glm::equal(A1.x, 1.0f, glm::epsilon<float>()) ? 0 : 1;
glm::vec2 B0 = glm::fmin(glm::vec2(1), glm::vec2(1));
glm::vec2 B1 = glm::fmin(glm::vec2(1), 1.0f);
bool B2 = glm::all(glm::equal(B0, B1, glm::epsilon<float>()));
Error += B2 ? 0 : 1;
glm::vec3 C0 = glm::fmin(glm::vec3(1), glm::vec3(1));
glm::vec3 C1 = glm::fmin(glm::vec3(1), 1.0f);
bool C2 = glm::all(glm::equal(C0, C1, glm::epsilon<float>()));
Error += C2 ? 0 : 1;
glm::vec4 D0 = glm::fmin(glm::vec4(1), glm::vec4(1));
glm::vec4 D1 = glm::fmin(glm::vec4(1), 1.0f);
bool D2 = glm::all(glm::equal(D0, D1, glm::epsilon<float>()));
Error += D2 ? 0 : 1;
return Error;
}
}//namespace fmin_
namespace fmax_
{
static int test()
{
int Error = 0;
float Zero_f = 0.0f;
glm::vec1 A0 = glm::fmax(glm::vec1(1), glm::vec1(Zero_f / 0.0f));
Error += glm::equal(A0.x, 1.0f, glm::epsilon<float>()) ? 0 : 1;
glm::vec1 A1 = glm::fmax(glm::vec1(Zero_f / 0.0f), glm::vec1(1));
Error += glm::equal(A1.x, 1.0f, glm::epsilon<float>()) ? 0 : 1;
glm::vec2 B0 = glm::fmax(glm::vec2(1), glm::vec2(1));
glm::vec2 B1 = glm::fmax(glm::vec2(1), 1.0f);
bool B2 = glm::all(glm::equal(B0, B1, glm::epsilon<float>()));
Error += B2 ? 0 : 1;
glm::vec3 C0 = glm::fmax(glm::vec3(1), glm::vec3(1));
glm::vec3 C1 = glm::fmax(glm::vec3(1), 1.0f);
bool C2 = glm::all(glm::equal(C0, C1, glm::epsilon<float>()));
Error += C2 ? 0 : 1;
glm::vec4 D0 = glm::fmax(glm::vec4(1), glm::vec4(1));
glm::vec4 D1 = glm::fmax(glm::vec4(1), 1.0f);
bool D2 = glm::all(glm::equal(D0, D1, glm::epsilon<float>()));
Error += D2 ? 0 : 1;
return Error;
}
}//namespace fmax_
namespace fclamp_
{
static int test()
{
int Error = 0;
float Zero_f = 0.0f;
glm::vec1 A0 = glm::fclamp(glm::vec1(1), glm::vec1(Zero_f / 0.0f), glm::vec1(2.0f));
Error += glm::equal(A0.x, 1.0f, glm::epsilon<float>()) ? 0 : 1;
return Error;
}
}//namespace fclamp_
int main()
{
int Error = 0;
Error += fmin_::test();
Error += fmax_::test();
Error += fclamp_::test();
return Error;
}
@@ -0,0 +1,39 @@
///////////////////////////////////////////////////////////////////////////////////
/// OpenGL Mathematics (glm.g-truc.net)
///
/// Copyright (c) 2005 - 2015 G-Truc Creation (www.g-truc.net)
/// 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.
///
/// Restrictions:
/// By making use of the Software for military purposes, you choose to make
/// a Bunny unhappy.
///
/// 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.
///
/// @file test/gtx/gtx_extented_min_max.cpp
/// @date 2013-10-25 / 2014-11-25
/// @author Christophe Riccio
///////////////////////////////////////////////////////////////////////////////////
#include <glm/gtx/extended_min_max.hpp>
int main()
{
int Error(0);
return Error;
}
@@ -0,0 +1,15 @@
#define GLM_ENABLE_EXPERIMENTAL
#include <glm/gtx/exterior_product.hpp>
#include <glm/gtc/epsilon.hpp>
#include <glm/vec2.hpp>
int main()
{
int Error = 0;
float const f = glm::cross(glm::vec2(1.0f, 1.0f), glm::vec2(1.0f, 1.0f));
Error += glm::epsilonEqual(f, 0.0f, 0.001f) ? 0 : 1;
return Error;
}
@@ -0,0 +1,9 @@
#define GLM_ENABLE_EXPERIMENTAL
#include <glm/gtx/fast_exponential.hpp>
int main()
{
int Error(0);
return Error;
}
@@ -0,0 +1,45 @@
#define GLM_ENABLE_EXPERIMENTAL
#include <glm/gtx/fast_square_root.hpp>
#include <glm/gtc/type_precision.hpp>
#include <glm/gtc/epsilon.hpp>
#include <glm/vector_relational.hpp>
static int test_fastInverseSqrt()
{
int Error = 0;
Error += glm::epsilonEqual(glm::fastInverseSqrt(1.0f), 1.0f, 0.01f) ? 0 : 1;
Error += glm::epsilonEqual(glm::fastInverseSqrt(1.0), 1.0, 0.01) ? 0 : 1;
Error += glm::all(glm::epsilonEqual(glm::fastInverseSqrt(glm::vec2(1.0f)), glm::vec2(1.0f), 0.01f)) ? 0 : 1;
Error += glm::all(glm::epsilonEqual(glm::fastInverseSqrt(glm::dvec3(1.0)), glm::dvec3(1.0), 0.01)) ? 0 : 1;
Error += glm::all(glm::epsilonEqual(glm::fastInverseSqrt(glm::dvec4(1.0)), glm::dvec4(1.0), 0.01)) ? 0 : 1;
return Error;
}
static int test_fastDistance()
{
int Error = 0;
float const A = glm::fastDistance(0.0f, 1.0f);
float const B = glm::fastDistance(glm::vec2(0.0f), glm::vec2(1.0f, 0.0f));
float const C = glm::fastDistance(glm::vec3(0.0f), glm::vec3(1.0f, 0.0f, 0.0f));
float const D = glm::fastDistance(glm::vec4(0.0f), glm::vec4(1.0f, 0.0f, 0.0f, 0.0f));
Error += glm::epsilonEqual(A, 1.0f, 0.01f) ? 0 : 1;
Error += glm::epsilonEqual(B, 1.0f, 0.01f) ? 0 : 1;
Error += glm::epsilonEqual(C, 1.0f, 0.01f) ? 0 : 1;
Error += glm::epsilonEqual(D, 1.0f, 0.01f) ? 0 : 1;
return Error;
}
int main()
{
int Error = 0;
Error += test_fastInverseSqrt();
Error += test_fastDistance();
return Error;
}
+592
View File
@@ -0,0 +1,592 @@
#include <glm/ext/scalar_ulp.hpp>
#define GLM_ENABLE_EXPERIMENTAL
#include <glm/gtc/type_precision.hpp>
#include <glm/gtx/fast_trigonometry.hpp>
#include <glm/gtx/integer.hpp>
#include <glm/gtx/common.hpp>
#include <glm/gtc/constants.hpp>
#include <glm/gtc/vec1.hpp>
#include <glm/trigonometric.hpp>
#include <cmath>
#include <ctime>
#include <cstdio>
#include <vector>
namespace fastCos
{
static int perf(bool NextFloat)
{
const float begin = -glm::pi<float>();
const float end = glm::pi<float>();
float result = 0.f;
const std::clock_t timestamp1 = std::clock();
for(float i = begin; i < end; i = NextFloat ? glm::nextFloat(i) : i + 0.1f)
result = glm::fastCos(i);
const std::clock_t timestamp2 = std::clock();
for(float i = begin; i < end; i = NextFloat ? glm::nextFloat(i) : i + 0.1f)
result = glm::cos(i);
const std::clock_t timestamp3 = std::clock();
const std::clock_t time_fast = timestamp2 - timestamp1;
const std::clock_t time_default = timestamp3 - timestamp2;
std::printf("fastCos Time %d clocks\n", static_cast<int>(time_fast));
std::printf("cos Time %d clocks\n", static_cast<int>(time_default));
(void) result; // Silence set but not used warning
return time_fast <= time_default ? 0 : 1;
}
}//namespace fastCos
namespace fastSin
{
/*
float sin(float x) {
float temp;
temp = (x + M_PI) / ((2 * M_PI) - M_PI);
return limited_sin((x + M_PI) - ((2 * M_PI) - M_PI) * temp));
}
*/
static int perf(bool NextFloat)
{
const float begin = -glm::pi<float>();
const float end = glm::pi<float>();
float result = 0.f;
const std::clock_t timestamp1 = std::clock();
for(float i = begin; i < end; i = NextFloat ? glm::nextFloat(i) : i + 0.1f)
result = glm::fastSin(i);
const std::clock_t timestamp2 = std::clock();
for(float i = begin; i < end; i = NextFloat ? glm::nextFloat(i) : i + 0.1f)
result = glm::sin(i);
const std::clock_t timestamp3 = std::clock();
const std::clock_t time_fast = timestamp2 - timestamp1;
const std::clock_t time_default = timestamp3 - timestamp2;
std::printf("fastSin Time %d clocks\n", static_cast<int>(time_fast));
std::printf("sin Time %d clocks\n", static_cast<int>(time_default));
(void) result; // Silence set but not used warning
return time_fast <= time_default ? 0 : 1;
}
}//namespace fastSin
namespace fastTan
{
static int perf(bool NextFloat)
{
const float begin = -glm::pi<float>();
const float end = glm::pi<float>();
float result = 0.f;
const std::clock_t timestamp1 = std::clock();
for(float i = begin; i < end; i = NextFloat ? glm::nextFloat(i) : i + 0.1f)
result = glm::fastTan(i);
const std::clock_t timestamp2 = std::clock();
for (float i = begin; i < end; i = NextFloat ? glm::nextFloat(i) : i + 0.1f)
result = glm::tan(i);
const std::clock_t timestamp3 = std::clock();
const std::clock_t time_fast = timestamp2 - timestamp1;
const std::clock_t time_default = timestamp3 - timestamp2;
std::printf("fastTan Time %d clocks\n", static_cast<int>(time_fast));
std::printf("tan Time %d clocks\n", static_cast<int>(time_default));
(void) result; // Silence set but not used warning
return time_fast <= time_default ? 0 : 1;
}
}//namespace fastTan
namespace fastAcos
{
static int perf(bool NextFloat)
{
const float begin = -glm::pi<float>();
const float end = glm::pi<float>();
float result = 0.f;
const std::clock_t timestamp1 = std::clock();
for(float i = begin; i < end; i = NextFloat ? glm::nextFloat(i) : i + 0.1f)
result = glm::fastAcos(i);
const std::clock_t timestamp2 = std::clock();
for(float i = begin; i < end; i = NextFloat ? glm::nextFloat(i) : i + 0.1f)
result = glm::acos(i);
const std::clock_t timestamp3 = std::clock();
const std::clock_t time_fast = timestamp2 - timestamp1;
const std::clock_t time_default = timestamp3 - timestamp2;
std::printf("fastAcos Time %d clocks\n", static_cast<int>(time_fast));
std::printf("acos Time %d clocks\n", static_cast<int>(time_default));
(void) result; // Silence set but not used warning
return time_fast <= time_default ? 0 : 1;
}
}//namespace fastAcos
namespace fastAsin
{
static int perf(bool NextFloat)
{
const float begin = -glm::pi<float>();
const float end = glm::pi<float>();
float result = 0.f;
const std::clock_t timestamp1 = std::clock();
for(float i = begin; i < end; i = NextFloat ? glm::nextFloat(i) : i + 0.1f)
result = glm::fastAsin(i);
const std::clock_t timestamp2 = std::clock();
for(float i = begin; i < end; i = NextFloat ? glm::nextFloat(i) : i + 0.1f)
result = glm::asin(i);
const std::clock_t timestamp3 = std::clock();
const std::clock_t time_fast = timestamp2 - timestamp1;
const std::clock_t time_default = timestamp3 - timestamp2;
std::printf("fastAsin Time %d clocks\n", static_cast<int>(time_fast));
std::printf("asin Time %d clocks\n", static_cast<int>(time_default));
(void) result; // Silence set but not used warning
return time_fast <= time_default ? 0 : 1;
}
}//namespace fastAsin
namespace fastAtan
{
static int perf(bool NextFloat)
{
const float begin = -glm::pi<float>();
const float end = glm::pi<float>();
float result = 0.f;
const std::clock_t timestamp1 = std::clock();
for(float i = begin; i < end; i = NextFloat ? glm::nextFloat(i) : i + 0.1f)
result = glm::fastAtan(i);
const std::clock_t timestamp2 = std::clock();
for(float i = begin; i < end; i = NextFloat ? glm::nextFloat(i) : i + 0.1f)
result = glm::atan(i);
const std::clock_t timestamp3 = std::clock();
const std::clock_t time_fast = timestamp2 - timestamp1;
const std::clock_t time_default = timestamp3 - timestamp2;
std::printf("fastAtan Time %d clocks\n", static_cast<int>(time_fast));
std::printf("atan Time %d clocks\n", static_cast<int>(time_default));
(void) result; // Silence set but not used warning
return time_fast <= time_default ? 0 : 1;
}
}//namespace fastAtan
namespace taylorCos
{
using glm::qualifier;
using glm::length_t;
# if (GLM_COMPILER & GLM_COMPILER_CLANG)
# pragma clang diagnostic push
# pragma clang diagnostic ignored "-Wglobal-constructors"
# endif
glm::vec4 const AngleShift(0.0f, glm::half_pi<float>(), glm::pi<float>(), glm::three_over_two_pi<float>());
# if (GLM_COMPILER & GLM_COMPILER_CLANG)
# pragma clang diagnostic pop
# endif
template<length_t L, typename T, qualifier Q>
static GLM_FUNC_QUALIFIER glm::vec<L, T, Q> taylorSeriesNewCos(glm::vec<L, T, Q> const& x)
{
glm::vec<L, T, Q> const Powed2(x * x);
glm::vec<L, T, Q> const Powed4(Powed2 * Powed2);
glm::vec<L, T, Q> const Powed6(Powed4 * Powed2);
glm::vec<L, T, Q> const Powed8(Powed4 * Powed4);
return static_cast<T>(1)
- Powed2 * static_cast<T>(0.5)
+ Powed4 * static_cast<T>(0.04166666666666666666666666666667)
- Powed6 * static_cast<T>(0.00138888888888888888888888888889)
+ Powed8 * static_cast<T>(2.4801587301587301587301587301587e-5);
}
/*
template<length_t L, typename T, qualifier Q>
static GLM_FUNC_QUALIFIER glm::vec<L, T, Q> taylorSeriesNewCos6(glm::vec<L, T, Q> const& x)
{
glm::vec<L, T, Q> const Powed2(x * x);
glm::vec<L, T, Q> const Powed4(Powed2 * Powed2);
glm::vec<L, T, Q> const Powed6(Powed4 * Powed2);
return static_cast<T>(1)
- Powed2 * static_cast<T>(0.5)
+ Powed4 * static_cast<T>(0.04166666666666666666666666666667)
- Powed6 * static_cast<T>(0.00138888888888888888888888888889);
}
*/
/*
template<glm::length_t L, qualifier Q>
static GLM_FUNC_QUALIFIER glm::vec<L, float, Q> fastAbs(glm::vec<L, float, Q> x)
{
int* Pointer = reinterpret_cast<int*>(&x[0]);
Pointer[0] &= 0x7fffffff;
Pointer[1] &= 0x7fffffff;
Pointer[2] &= 0x7fffffff;
Pointer[3] &= 0x7fffffff;
return x;
}
template<glm::length_t L, typename T, qualifier Q>
static GLM_FUNC_QUALIFIER glm::vec<L, T, Q> fastCosNew(glm::vec<L, T, Q> const& x)
{
glm::vec<L, T, Q> const Angle0_PI(fastAbs(fmod(x + glm::pi<T>(), glm::two_pi<T>()) - glm::pi<T>()));
return taylorSeriesNewCos6(x);
// vec<L, bool, Q> const FirstQuarterPi(lessThanEqual(Angle0_PI, vec<L, T, Q>(glm::half_pi<T>())));
// vec<L, T, Q> const RevertAngle(mix(vec<L, T, Q>(glm::pi<T>()), vec<L, T, Q>(0), FirstQuarterPi));
// vec<L, T, Q> const ReturnSign(mix(vec<L, T, Q>(-1), vec<L, T, Q>(1), FirstQuarterPi));
// vec<L, T, Q> const SectionAngle(RevertAngle - Angle0_PI);
// return ReturnSign * taylorSeriesNewCos(SectionAngle);
}
*/
/*
static int perf_fastCosNew(float Begin, float End, std::size_t Samples)
{
std::vector<glm::vec4> Results;
Results.resize(Samples);
float const Steps = (End - Begin) / static_cast<float>(Samples);
std::clock_t const TimeStampBegin = std::clock();
for(std::size_t i = 0; i < Samples; ++i)
Results[i] = fastCosNew(AngleShift + glm::vec4(Begin + Steps * static_cast<float>(i)));
std::clock_t const TimeStampEnd = std::clock();
std::printf("fastCosNew %d clocks\n", static_cast<int>(TimeStampEnd - TimeStampBegin));
int Error = 0;
for(std::size_t i = 0; i < Samples; ++i)
Error += Results[i].x >= -1.0f && Results[i].x <= 1.0f ? 0 : 1;
return Error;
}
*/
template<length_t L, typename T, qualifier Q>
static GLM_FUNC_QUALIFIER glm::vec<L, T, Q> deterministic_fmod(glm::vec<L, T, Q> const& x, T y)
{
return x - y * trunc(x / y);
}
template<length_t L, typename T, qualifier Q>
static GLM_FUNC_QUALIFIER glm::vec<L, T, Q> fastCosDeterminisctic(glm::vec<L, T, Q> const& x)
{
glm::vec<L, T, Q> const Angle0_PI(abs(deterministic_fmod(x + glm::pi<T>(), glm::two_pi<T>()) - glm::pi<T>()));
glm::vec<L, bool, Q> const FirstQuarterPi(lessThanEqual(Angle0_PI, glm::vec<L, T, Q>(glm::half_pi<T>())));
glm::vec<L, T, Q> const RevertAngle(mix(glm::vec<L, T, Q>(glm::pi<T>()), glm::vec<L, T, Q>(0), FirstQuarterPi));
glm::vec<L, T, Q> const ReturnSign(mix(glm::vec<L, T, Q>(-1), glm::vec<L, T, Q>(1), FirstQuarterPi));
glm::vec<L, T, Q> const SectionAngle(RevertAngle - Angle0_PI);
return ReturnSign * taylorSeriesNewCos(SectionAngle);
}
static int perf_fastCosDeterminisctic(float Begin, float End, std::size_t Samples)
{
std::vector<glm::vec4> Results;
Results.resize(Samples);
float const Steps = (End - Begin) / static_cast<float>(Samples);
std::clock_t const TimeStampBegin = std::clock();
for(std::size_t i = 0; i < Samples; ++i)
Results[i] = taylorCos::fastCosDeterminisctic(AngleShift + glm::vec4(Begin + Steps * static_cast<float>(i)));
std::clock_t const TimeStampEnd = std::clock();
std::printf("fastCosDeterminisctic %d clocks\n", static_cast<int>(TimeStampEnd - TimeStampBegin));
int Error = 0;
for(std::size_t i = 0; i < Samples; ++i)
Error += Results[i].x >= -1.0f && Results[i].x <= 1.0f ? 0 : 1;
return Error;
}
template<length_t L, typename T, qualifier Q>
static GLM_FUNC_QUALIFIER glm::vec<L, T, Q> taylorSeriesRefCos(glm::vec<L, T, Q> const& x)
{
return static_cast<T>(1)
- (x * x) / glm::factorial(static_cast<T>(2))
+ (x * x * x * x) / glm::factorial(static_cast<T>(4))
- (x * x * x * x * x * x) / glm::factorial(static_cast<T>(6))
+ (x * x * x * x * x * x * x * x) / glm::factorial(static_cast<T>(8));
}
template<length_t L, typename T, qualifier Q>
static GLM_FUNC_QUALIFIER glm::vec<L, T, Q> fastRefCos(glm::vec<L, T, Q> const& x)
{
glm::vec<L, T, Q> const Angle0_PI(glm::abs(fmod(x + glm::pi<T>(), glm::two_pi<T>()) - glm::pi<T>()));
// return taylorSeriesRefCos(Angle0_PI);
glm::vec<L, bool, Q> const FirstQuarterPi(lessThanEqual(Angle0_PI, glm::vec<L, T, Q>(glm::half_pi<T>())));
glm::vec<L, T, Q> const RevertAngle(mix(glm::vec<L, T, Q>(glm::pi<T>()), glm::vec<L, T, Q>(0), FirstQuarterPi));
glm::vec<L, T, Q> const ReturnSign(mix(glm::vec<L, T, Q>(-1), glm::vec<L, T, Q>(1), FirstQuarterPi));
glm::vec<L, T, Q> const SectionAngle(RevertAngle - Angle0_PI);
return ReturnSign * taylorSeriesRefCos(SectionAngle);
}
static int perf_fastCosRef(float Begin, float End, std::size_t Samples)
{
std::vector<glm::vec4> Results;
Results.resize(Samples);
float const Steps = (End - Begin) / static_cast<float>(Samples);
std::clock_t const TimeStampBegin = std::clock();
for(std::size_t i = 0; i < Samples; ++i)
Results[i] = taylorCos::fastRefCos(AngleShift + glm::vec4(Begin + Steps * static_cast<float>(i)));
std::clock_t const TimeStampEnd = std::clock();
std::printf("fastCosRef %d clocks\n", static_cast<int>(TimeStampEnd - TimeStampBegin));
int Error = 0;
for(std::size_t i = 0; i < Samples; ++i)
Error += Results[i].x >= -1.0f && Results[i].x <= 1.0f ? 0 : 1;
return Error;
}
static int perf_fastCosOld(float Begin, float End, std::size_t Samples)
{
std::vector<glm::vec4> Results;
Results.resize(Samples);
float const Steps = (End - Begin) / static_cast<float>(Samples);
std::clock_t const TimeStampBegin = std::clock();
for(std::size_t i = 0; i < Samples; ++i)
Results[i] = glm::fastCos(AngleShift + glm::vec4(Begin + Steps * static_cast<float>(i)));
std::clock_t const TimeStampEnd = std::clock();
std::printf("fastCosOld %d clocks\n", static_cast<int>(TimeStampEnd - TimeStampBegin));
int Error = 0;
for(std::size_t i = 0; i < Samples; ++i)
Error += Results[i].x >= -1.0f && Results[i].x <= 1.0f ? 0 : 1;
return Error;
}
static int perf_cos(float Begin, float End, std::size_t Samples)
{
std::vector<glm::vec4> Results;
Results.resize(Samples);
float const Steps = (End - Begin) / static_cast<float>(Samples);
std::clock_t const TimeStampBegin = std::clock();
for(std::size_t i = 0; i < Samples; ++i)
Results[i] = glm::cos(AngleShift + glm::vec4(Begin + Steps * static_cast<float>(i)));
std::clock_t const TimeStampEnd = std::clock();
std::printf("cos %d clocks\n", static_cast<int>(TimeStampEnd - TimeStampBegin));
int Error = 0;
for(std::size_t i = 0; i < Samples; ++i)
Error += Results[i].x >= -1.0f && Results[i].x <= 1.0f ? 0 : 1;
return Error;
}
static int perf(std::size_t const Samples)
{
int Error = 0;
float const Begin = -glm::pi<float>();
float const End = glm::pi<float>();
Error += perf_cos(Begin, End, Samples);
Error += perf_fastCosOld(Begin, End, Samples);
Error += perf_fastCosRef(Begin, End, Samples);
//Error += perf_fastCosNew(Begin, End, Samples);
Error += perf_fastCosDeterminisctic(Begin, End, Samples);
return Error;
}
static int test()
{
int Error = 0;
//for(float Angle = -4.0f * glm::pi<float>(); Angle < 4.0f * glm::pi<float>(); Angle += 0.1f)
//for(float Angle = -720.0f; Angle < 720.0f; Angle += 0.1f)
for(float Angle = 0.0f; Angle < 180.0f; Angle += 0.1f)
{
float const modAngle = std::fmod(glm::abs(Angle), 360.f);
assert(modAngle >= 0.0f && modAngle <= 360.f);
float const radAngle = glm::radians(modAngle);
float const Cos0 = std::cos(radAngle);
float const Cos1 = taylorCos::fastRefCos(glm::fvec1(radAngle)).x;
Error += glm::abs(Cos1 - Cos0) < 0.1f ? 0 : 1;
//float const Cos2 = taylorCos::fastCosNew(glm::fvec1(radAngle)).x;
//Error += glm::abs(Cos2 - Cos0) < 0.1f ? 0 : 1;
assert(!Error);
}
return Error;
}
}//namespace taylorCos
namespace taylor2
{
# if (GLM_COMPILER & GLM_COMPILER_CLANG)
# pragma clang diagnostic push
# pragma clang diagnostic ignored "-Wglobal-constructors"
# endif
glm::vec4 const AngleShift(0.0f, glm::pi<float>() * 0.5f, glm::pi<float>() * 1.0f, glm::pi<float>() * 1.5f);
# if (GLM_COMPILER & GLM_COMPILER_CLANG)
# pragma clang diagnostic pop
# endif
static float taylorCosA(float x)
{
return 1.f
- (x * x) * (1.f / 2.f)
+ (x * x * x * x) * (1.f / 24.f)
- (x * x * x * x * x * x) * (1.f / 720.f)
+ (x * x * x * x * x * x * x * x) * (1.f / 40320.f);
}
static float taylorCosB(float x)
{
return 1.f
- (x * x) * (1.f / 2.f)
+ (x * x * x * x) * (1.f / 24.f)
- (x * x * x * x * x * x) * (1.f / 720.f)
+ (x * x * x * x * x * x * x * x) * (1.f / 40320.f);
}
static float taylorCosC(float x)
{
return 1.f
- (x * x) * (1.f / 2.f)
+ ((x * x) * (x * x)) * (1.f / 24.f)
- (((x * x) * (x * x)) * (x * x)) * (1.f / 720.f)
+ (((x * x) * (x * x)) * ((x * x) * (x * x))) * (1.f / 40320.f);
}
static int perf_taylorCosA(float Begin, float End, std::size_t Samples)
{
std::vector<float> Results;
Results.resize(Samples);
float const Steps = (End - Begin) / static_cast<float>(Samples);
std::clock_t const TimeStampBegin = std::clock();
for(std::size_t i = 0; i < Samples; ++i)
Results[i] = taylorCosA(AngleShift.x + Begin + Steps * static_cast<float>(i));
std::clock_t const TimeStampEnd = std::clock();
std::printf("taylorCosA %d clocks\n", static_cast<int>(TimeStampEnd - TimeStampBegin));
int Error = 0;
for(std::size_t i = 0; i < Samples; ++i)
Error += Results[i] >= -1.0f && Results[i] <= 1.0f ? 0 : 1;
return Error;
}
static int perf_taylorCosB(float Begin, float End, std::size_t Samples)
{
std::vector<float> Results;
Results.resize(Samples);
float const Steps = (End - Begin) / static_cast<float>(Samples);
std::clock_t const TimeStampBegin = std::clock();
for(std::size_t i = 0; i < Samples; ++i)
Results[i] = taylorCosB(AngleShift.x + Begin + Steps * static_cast<float>(i));
std::clock_t const TimeStampEnd = std::clock();
std::printf("taylorCosB %d clocks\n", static_cast<int>(TimeStampEnd - TimeStampBegin));
int Error = 0;
for(std::size_t i = 0; i < Samples; ++i)
Error += Results[i] >= -1.0f && Results[i] <= 1.0f ? 0 : 1;
return Error;
}
static int perf_taylorCosC(float Begin, float End, std::size_t Samples)
{
std::vector<float> Results;
Results.resize(Samples);
float const Steps = (End - Begin) / static_cast<float>(Samples);
std::clock_t const TimeStampBegin = std::clock();
for(std::size_t i = 0; i < Samples; ++i)
Results[i] = taylorCosC(AngleShift.x + Begin + Steps * static_cast<float>(i));
std::clock_t const TimeStampEnd = std::clock();
std::printf("taylorCosC %d clocks\n", static_cast<int>(TimeStampEnd - TimeStampBegin));
int Error = 0;
for(std::size_t i = 0; i < Samples; ++i)
Error += Results[i] >= -1.0f && Results[i] <= 1.0f ? 0 : 1;
return Error;
}
static int perf(std::size_t Samples)
{
int Error = 0;
float const Begin = -glm::pi<float>();
float const End = glm::pi<float>();
Error += perf_taylorCosA(Begin, End, Samples);
Error += perf_taylorCosB(Begin, End, Samples);
Error += perf_taylorCosC(Begin, End, Samples);
return Error;
}
}//namespace taylor2
int main()
{
int Error(0);
Error += ::taylor2::perf(1000);
Error += ::taylorCos::test();
Error += ::taylorCos::perf(1000);
::fastCos::perf(false);
::fastSin::perf(false);
::fastTan::perf(false);
::fastAcos::perf(false);
::fastAsin::perf(false);
::fastAtan::perf(false);
return Error;
}
+37
View File
@@ -0,0 +1,37 @@
#define GLM_ENABLE_EXPERIMENTAL
#include <glm/gtx/functions.hpp>
#include <glm/ext/vector_float2.hpp>
#include <vector>
static int test_gauss_1d()
{
int Error = 0;
std::vector<float> Result(20);
for(std::size_t i = 0, n = Result.size(); i < n; ++i)
Result[i] = glm::gauss(static_cast<float>(i) * 0.1f, 0.0f, 1.0f);
return Error;
}
static int test_gauss_2d()
{
int Error = 0;
std::vector<float> Result(20);
for(std::size_t i = 0, n = Result.size(); i < n; ++i)
Result[i] = glm::gauss(glm::vec2(static_cast<float>(i)) * 0.1f, glm::vec2(0.0f), glm::vec2(1.0f));
return Error;
}
int main()
{
int Error = 0;
Error += test_gauss_1d();
Error += test_gauss_2d();
return Error;
}
+34
View File
@@ -0,0 +1,34 @@
#define GLM_ENABLE_EXPERIMENTAL
#include <glm/gtx/gradient_paint.hpp>
static int test_radialGradient()
{
int Error = 0;
float Gradient = glm::radialGradient(glm::vec2(0), 1.0f, glm::vec2(1), glm::vec2(0.5));
Error += Gradient != 0.0f ? 0 : 1;
return Error;
}
static int test_linearGradient()
{
int Error = 0;
float Gradient = glm::linearGradient(glm::vec2(0), glm::vec2(1), glm::vec2(0.5));
Error += Gradient != 0.0f ? 0 : 1;
return Error;
}
int main()
{
int Error = 0;
Error += test_radialGradient();
Error += test_linearGradient();
return Error;
}
@@ -0,0 +1,9 @@
#define GLM_ENABLE_EXPERIMENTAL
#include <glm/gtx/handed_coordinate_space.hpp>
int main()
{
int Error(0);
return Error;
}
+80
View File
@@ -0,0 +1,80 @@
#if __cplusplus >= 201103L
#include <glm/detail/setup.hpp>
#if GLM_COMPILER & GLM_COMPILER_CLANG
# pragma clang diagnostic push
# pragma clang diagnostic ignored "-Wfloat-equal"
#endif
#define GLM_ENABLE_EXPERIMENTAL
#include <glm/gtx/hash.hpp>
#include <unordered_map>
static int test_compile()
{
int Error = 0;
// Vector types
std::unordered_map<glm::ivec1, int> map_vec1;
Error += ++map_vec1[glm::ivec1(0)];
std::unordered_map<glm::ivec2, int> map_vec2;
Error += ++map_vec2[glm::ivec2(0)];
std::unordered_map<glm::ivec3, int> map_vec3;
Error += ++map_vec3[glm::ivec3(0)];
std::unordered_map<glm::ivec4, int> map_vec4;
Error += ++map_vec4[glm::ivec4(0)];
// Quaternion types
std::unordered_map<glm::quat, int> map_quat;
Error += ++map_quat[glm::quat(0.0f, glm::vec3(0.0f))];
std::unordered_map<glm::dualquat, int> map_dualquat;
Error += ++map_dualquat[glm::dualquat(glm::vec3(0.0f))];
// Matrix types
std::unordered_map<glm::mat2x2, int> map_mat2x2;
Error += ++map_mat2x2[glm::mat2x2(0.0f)];
std::unordered_map<glm::mat2x3, int> map_mat2x3;
Error += ++map_mat2x3[glm::mat2x3(0.0f)];
std::unordered_map<glm::mat2x4, int> map_mat2x4;
Error += ++map_mat2x4[glm::mat2x4(0.0f)];
std::unordered_map<glm::mat3x2, int> map_mat3x2;
Error += ++map_mat3x2[glm::mat3x2(0.0f)];
std::unordered_map<glm::mat3x3, int> map_mat3x3;
Error += ++map_mat3x3[glm::mat3x3(0.0f)];
std::unordered_map<glm::mat3x4, int> map_mat3x4;
Error += ++map_mat3x4[glm::mat3x4(0.0f)];
std::unordered_map<glm::mat4x2, int> map_mat4x2;
Error += ++map_mat4x2[glm::mat4x2(0.0f)];
std::unordered_map<glm::mat4x3, int> map_mat4x3;
Error += ++map_mat4x3[glm::mat4x3(0.0f)];
std::unordered_map<glm::mat4x4, int> map_mat4x4;
Error += ++map_mat4x4[glm::mat4x4(0.0f)];
return Error > 0 ? 0 : 1;
}
int main()
{
int Error = 0;
Error += test_compile();
return Error;
}
#if GLM_COMPILER & GLM_COMPILER_CLANG
# pragma clang diagnostic pop
#endif
#else
int main()
{
return 0;
}
#endif// __cplusplus >= 201103L
+18
View File
@@ -0,0 +1,18 @@
///////////////////////////////////////////////////////////////////////////////////////////////////
// OpenGL Mathematics Copyright (c) 2005 - 2013 G-Truc Creation (www.g-truc.net)
///////////////////////////////////////////////////////////////////////////////////////////////////
// Created : 2013-10-25
// Updated : 2013-10-25
// Licence : This source is under MIT licence
// File : test/gtx/associated_min_max.cpp
///////////////////////////////////////////////////////////////////////////////////////////////////
#include <glm/gtc/type_precision.hpp>
#include <glm/gtx/associated_min_max.hpp>
int main()
{
int Error(0);
return Error;
}
+108
View File
@@ -0,0 +1,108 @@
#define GLM_ENABLE_EXPERIMENTAL
#include <glm/exponential.hpp>
#include <glm/gtc/epsilon.hpp>
#include <glm/gtx/integer.hpp>
#include <cstdio>
/*
static int test_floor_log2()
{
int Error = 0;
for(std::size_t i = 1; i < 1000000; ++i)
{
glm::uint A = glm::floor_log2(glm::uint(i));
glm::uint B = glm::uint(glm::floor(glm::log2(double(i)))); // Will fail with float, lack of accuracy
Error += A == B ? 0 : 1;
assert(!Error);
}
return Error;
}
*/
static int test_log2()
{
int Error = 0;
for(std::size_t i = 1; i < 24; ++i)
{
glm::uint A = glm::log2(glm::uint(1 << i));
glm::uint B = glm::uint(glm::log2(double(1 << i)));
//Error += glm::equalEpsilon(double(A), B, 1.0) ? 0 : 1;
Error += glm::abs(double(A) - B) <= 24 ? 0 : 1;
assert(!Error);
std::printf("Log2(%d) error A=%u, B=%u\n", 1 << i, A, B);
}
std::printf("log2 error=%d\n", Error);
return Error;
}
static int test_nlz()
{
int Error = 0;
for(glm::uint i = 1; i < glm::uint(33); ++i)
Error += glm::nlz(i) == 31u - static_cast<glm::uint>(glm::findMSB(i)) ? 0 : 1;
//printf("%d, %d\n", glm::nlz(i), 31u - glm::findMSB(i));
return Error;
}
static int test_pow_uint()
{
int Error = 0;
glm::uint const p0 = glm::pow(2u, 0u);
Error += p0 == 1u ? 0 : 1;
glm::uint const p1 = glm::pow(2u, 1u);
Error += p1 == 2u ? 0 : 1;
glm::uint const p2 = glm::pow(2u, 2u);
Error += p2 == 4u ? 0 : 1;
return Error;
}
static int test_pow_int()
{
int Error = 0;
int const p0 = glm::pow(2, 0u);
Error += p0 == 1 ? 0 : 1;
int const p1 = glm::pow(2, 1u);
Error += p1 == 2 ? 0 : 1;
int const p2 = glm::pow(2, 2u);
Error += p2 == 4 ? 0 : 1;
int const p0n = glm::pow(-2, 0u);
Error += p0n == -1 ? 0 : 1;
int const p1n = glm::pow(-2, 1u);
Error += p1n == -2 ? 0 : 1;
int const p2n = glm::pow(-2, 2u);
Error += p2n == 4 ? 0 : 1;
return Error;
}
int main()
{
int Error = 0;
Error += test_nlz();
// Error += test_floor_log2();
Error += test_log2();
Error += test_pow_uint();
Error += test_pow_int();
return Error;
}
+92
View File
@@ -0,0 +1,92 @@
#define GLM_ENABLE_EXPERIMENTAL
#include <glm/glm.hpp>
#include <glm/gtc/epsilon.hpp>
#include <glm/gtx/intersect.hpp>
static int test_intersectRayPlane()
{
int Error = 0;
glm::vec3 const PlaneOrigin(0, 0, 1);
glm::vec3 const PlaneNormal(0, 0, -1);
glm::vec3 const RayOrigin(0, 0, 0);
glm::vec3 const RayDir(0, 0, 1);
// check that inversion of the plane normal has no effect
{
float Distance = 0;
bool const Result = glm::intersectRayPlane(RayOrigin, RayDir, PlaneOrigin, PlaneNormal, Distance);
Error += glm::abs(Distance - 1.f) <= std::numeric_limits<float>::epsilon() ? 0 : 1;
Error += Result ? 0 : 1;
}
{
float Distance = 0;
bool const Result = glm::intersectRayPlane(RayOrigin, RayDir, PlaneOrigin, -1.f * PlaneNormal, Distance);
Error += glm::abs(Distance - 1.f) <= std::numeric_limits<float>::epsilon() ? 0 : 1;
Error += Result ? 0 : 1;
}
// check if plane is before of behind the ray origin
{
float Distance = 9.9999f; // value should not be changed
bool const Result = glm::intersectRayPlane(RayOrigin, RayDir, -1.f * PlaneOrigin, PlaneNormal, Distance);
Error += glm::abs(Distance - 9.9999f) <= std::numeric_limits<float>::epsilon() ? 0 : 1;
Error += Result ? 1 : 0; // there is no intersection in front of the ray origin, only behind
}
return Error;
}
static int test_intersectRayTriangle()
{
int Error = 0;
glm::vec3 const Orig(0, 0, 2);
glm::vec3 const Dir(0, 0, -1);
glm::vec3 const Vert0(0, 0, 0);
glm::vec3 const Vert1(-1, -1, 0);
glm::vec3 const Vert2(1, -1, 0);
glm::vec2 BaryPosition(0);
float Distance = 0;
bool const Result = glm::intersectRayTriangle(Orig, Dir, Vert0, Vert1, Vert2, BaryPosition, Distance);
Error += glm::all(glm::epsilonEqual(BaryPosition, glm::vec2(0), std::numeric_limits<float>::epsilon())) ? 0 : 1;
Error += glm::abs(Distance - 2.f) <= std::numeric_limits<float>::epsilon() ? 0 : 1;
Error += Result ? 0 : 1;
return Error;
}
#if GLM_PLATFORM != GLM_PLATFORM_LINUX
static int test_intersectLineTriangle()
{
int Error = 0;
glm::vec3 const Orig(0, 0, 2);
glm::vec3 const Dir(0, 0, -1);
glm::vec3 const Vert0(0, 0, 0);
glm::vec3 const Vert1(-1, -1, 0);
glm::vec3 const Vert2(1, -1, 0);
glm::vec3 Position(2.0f, 0.0f, 0.0f);
bool const Result = glm::intersectLineTriangle(Orig, Dir, Vert0, Vert1, Vert2, Position);
Error += glm::all(glm::epsilonEqual(Position, glm::vec3(2.0f, 0.0f, 0.0f), std::numeric_limits<float>::epsilon())) ? 0 : 1;
Error += Result ? 0 : 1;
return Error;
}
#endif//GLM_PLATFORM != GLM_PLATFORM_LINUX
int main()
{
int Error = 0;
#if GLM_PLATFORM != GLM_PLATFORM_LINUX
Error += test_intersectRayPlane();
Error += test_intersectRayTriangle();
Error += test_intersectLineTriangle(); // Disabled on 2025/01/16, C.I. failing on Ubuntu latest, GCC 13.3.0
#endif//GLM_PLATFORM != GLM_PLATFORM_LINUX
return Error;
}
+186
View File
@@ -0,0 +1,186 @@
#include <glm/glm.hpp>
#if GLM_LANG & GLM_LANG_CXXMS_FLAG
#include <glm/gtc/type_precision.hpp>
#define GLM_ENABLE_EXPERIMENTAL
#include <glm/gtx/io.hpp>
#include <iostream>
#include <sstream>
#include <typeinfo>
namespace
{
template<typename CTy, typename CTr>
static std::basic_ostream<CTy,CTr>& operator<<(std::basic_ostream<CTy,CTr>& os, glm::qualifier const& a)
{
typename std::basic_ostream<CTy,CTr>::sentry const cerberus(os);
if (cerberus)
{
switch (a) {
case glm::highp: os << "uhi"; break;
case glm::mediump: os << "umd"; break;
case glm::lowp: os << "ulo"; break;
# if GLM_CONFIG_ALIGNED_GENTYPES == GLM_ENABLE
case glm::aligned_highp: os << "ahi"; break;
case glm::aligned_mediump: os << "amd"; break;
case glm::aligned_lowp: os << "alo"; break;
# endif
}
}
return os;
}
template<typename U, glm::qualifier P, typename T, typename CTy, typename CTr>
static std::basic_string<CTy> type_name(std::basic_ostream<CTy,CTr>&, T const&)
{
std::basic_ostringstream<CTy,CTr> ostr;
if (typeid(T) == typeid(glm::qua<U,P>)) { ostr << "quat"; }
else if (typeid(T) == typeid(glm::vec<2, U,P>)) { ostr << "vec2"; }
else if (typeid(T) == typeid(glm::vec<3, U,P>)) { ostr << "vec3"; }
else if (typeid(T) == typeid(glm::vec<4, U,P>)) { ostr << "vec4"; }
else if (typeid(T) == typeid(glm::mat<2, 2, U,P>)) { ostr << "mat2x2"; }
else if (typeid(T) == typeid(glm::mat<2, 3, U,P>)) { ostr << "mat2x3"; }
else if (typeid(T) == typeid(glm::mat<2, 4, U,P>)) { ostr << "mat2x4"; }
else if (typeid(T) == typeid(glm::mat<3, 2, U,P>)) { ostr << "mat3x2"; }
else if (typeid(T) == typeid(glm::mat<3, 3, U,P>)) { ostr << "mat3x3"; }
else if (typeid(T) == typeid(glm::mat<3, 4, U,P>)) { ostr << "mat3x4"; }
else if (typeid(T) == typeid(glm::mat<4, 2, U,P>)) { ostr << "mat4x2"; }
else if (typeid(T) == typeid(glm::mat<4, 3, U,P>)) { ostr << "mat4x3"; }
else if (typeid(T) == typeid(glm::mat<4, 4, U,P>)) { ostr << "mat4x4"; }
else { ostr << "unknown"; }
ostr << "<" << typeid(U).name() << "," << P << ">";
return ostr.str();
}
} // namespace {
template<typename T, glm::qualifier P, typename OS>
static int test_io_quat(OS& os)
{
os << "\n" << typeid(OS).name() << "\n";
glm::qua<T, P> const q(1, 0, 0, 0);
{
glm::io::basic_format_saver<typename OS::char_type> const iofs(os);
os << glm::io::precision(2) << glm::io::width(1 + 2 + 1 + 2)
<< type_name<T, P>(os, q) << ": " << q << "\n";
}
{
glm::io::basic_format_saver<typename OS::char_type> const iofs(os);
os << glm::io::unformatted
<< type_name<T, P>(os, q) << ": " << q << "\n";
}
return 0;
}
template<typename T, glm::qualifier P, typename OS>
static int test_io_vec(OS& os)
{
os << "\n" << typeid(OS).name() << "\n";
glm::vec<2, T,P> const v2(0, 1);
glm::vec<3, T,P> const v3(2, 3, 4);
glm::vec<4, T,P> const v4(5, 6, 7, 8);
os << type_name<T,P>(os, v2) << ": " << v2 << "\n"
<< type_name<T,P>(os, v3) << ": " << v3 << "\n"
<< type_name<T,P>(os, v4) << ": " << v4 << "\n";
glm::io::basic_format_saver<typename OS::char_type> const iofs(os);
os << glm::io::precision(2) << glm::io::width(1 + 2 + 1 + 2)
<< type_name<T,P>(os, v2) << ": " << v2 << "\n"
<< type_name<T,P>(os, v3) << ": " << v3 << "\n"
<< type_name<T,P>(os, v4) << ": " << v4 << "\n";
return 0;
}
template<typename T, glm::qualifier P, typename OS>
static int test_io_mat(OS& os, glm::io::order_type otype)
{
os << "\n" << typeid(OS).name() << "\n";
glm::vec<2, T,P> const v2_1( 0, 1);
glm::vec<2, T,P> const v2_2( 2, 3);
glm::vec<2, T,P> const v2_3( 4, 5);
glm::vec<2, T,P> const v2_4( 6, 7);
glm::vec<3, T,P> const v3_1( 8, 9, 10);
glm::vec<3, T,P> const v3_2(11, 12, 13);
glm::vec<3, T,P> const v3_3(14, 15, 16);
glm::vec<3, T,P> const v3_4(17, 18, 19);
glm::vec<4, T,P> const v4_1(20, 21, 22, 23);
glm::vec<4, T,P> const v4_2(24, 25, 26, 27);
glm::vec<4, T,P> const v4_3(28, 29, 30, 31);
glm::vec<4, T,P> const v4_4(32, 33, 34, 35);
glm::io::basic_format_saver<typename OS::char_type> const iofs(os);
os << glm::io::precision(2) << glm::io::width(1 + 2 + 1 + 2)
<< glm::io::order(otype)
<< "mat2x2<" << typeid(T).name() << "," << P << ">: " << glm::mat<2, 2, T,P>(v2_1, v2_2) << "\n"
<< "mat2x3<" << typeid(T).name() << "," << P << ">: " << glm::mat<2, 3, T,P>(v3_1, v3_2) << "\n"
<< "mat2x4<" << typeid(T).name() << "," << P << ">: " << glm::mat<2, 4, T,P>(v4_1, v4_2) << "\n"
<< "mat3x2<" << typeid(T).name() << "," << P << ">: " << glm::mat<3, 2, T,P>(v2_1, v2_2, v2_3) << "\n"
<< "mat3x3<" << typeid(T).name() << "," << P << ">: " << glm::mat<3, 3, T,P>(v3_1, v3_2, v3_3) << "\n"
<< "mat3x4<" << typeid(T).name() << "," << P << ">: " << glm::mat<3, 4, T,P>(v4_1, v4_2, v4_3) << "\n"
<< "mat4x2<" << typeid(T).name() << "," << P << ">: " << glm::mat<4, 2, T,P>(v2_1, v2_2, v2_3, v2_4) << "\n"
<< "mat4x3<" << typeid(T).name() << "," << P << ">: " << glm::mat<4, 3, T,P>(v3_1, v3_2, v3_3, v3_4) << "\n"
<< "mat4x4<" << typeid(T).name() << "," << P << ">: " << glm::mat<4, 4, T,P>(v4_1, v4_2, v4_3, v4_4) << "\n";
os << glm::io::unformatted
<< glm::io::order(otype)
<< "mat2x2<" << typeid(T).name() << "," << P << ">: " << glm::mat<2, 2, T,P>(v2_1, v2_2) << "\n"
<< "mat2x3<" << typeid(T).name() << "," << P << ">: " << glm::mat<2, 3, T,P>(v3_1, v3_2) << "\n"
<< "mat2x4<" << typeid(T).name() << "," << P << ">: " << glm::mat<2, 4, T,P>(v4_1, v4_2) << "\n"
<< "mat3x2<" << typeid(T).name() << "," << P << ">: " << glm::mat<3, 2, T,P>(v2_1, v2_2, v2_3) << "\n"
<< "mat3x3<" << typeid(T).name() << "," << P << ">: " << glm::mat<3, 3, T,P>(v3_1, v3_2, v3_3) << "\n"
<< "mat3x4<" << typeid(T).name() << "," << P << ">: " << glm::mat<3, 4, T,P>(v4_1, v4_2, v4_3) << "\n"
<< "mat4x2<" << typeid(T).name() << "," << P << ">: " << glm::mat<4, 2, T,P>(v2_1, v2_2, v2_3, v2_4) << "\n"
<< "mat4x3<" << typeid(T).name() << "," << P << ">: " << glm::mat<4, 3, T,P>(v3_1, v3_2, v3_3, v3_4) << "\n"
<< "mat4x4<" << typeid(T).name() << "," << P << ">: " << glm::mat<4, 4, T,P>(v4_1, v4_2, v4_3, v4_4) << "\n";
return 0;
}
int main()
{
int Error(0);
Error += test_io_quat<float, glm::highp>(std::cout);
Error += test_io_quat<float, glm::highp>(std::wcout);
Error += test_io_quat<int, glm::mediump>(std::cout);
Error += test_io_quat<int, glm::mediump>(std::wcout);
Error += test_io_quat<glm::uint, glm::lowp>(std::cout);
Error += test_io_quat<glm::uint, glm::lowp>(std::wcout);
Error += test_io_vec<float, glm::highp>(std::cout);
Error += test_io_vec<float, glm::highp>(std::wcout);
Error += test_io_vec<int, glm::mediump>(std::cout);
Error += test_io_vec<int, glm::mediump>(std::wcout);
Error += test_io_vec<glm::uint, glm::lowp>(std::cout);
Error += test_io_vec<glm::uint, glm::lowp>(std::wcout);
Error += test_io_mat<float, glm::highp>(std::cout, glm::io::column_major);
Error += test_io_mat<float, glm::lowp>(std::wcout, glm::io::column_major);
Error += test_io_mat<float, glm::highp>(std::cout, glm::io::row_major);
Error += test_io_mat<float, glm::lowp>(std::wcout, glm::io::row_major);
return Error;
}
#else
int main()
{
return 0;
}
#endif// GLM_LANG & GLM_LANG_CXXMS_FLAG
+215
View File
@@ -0,0 +1,215 @@
#define GLM_ENABLE_EXPERIMENTAL
#include <glm/gtx/iteration.hpp>
#include <iterator>
#include <algorithm>
#include <numeric>
#include <glm/glm.hpp>
#include <glm/gtx/quaternion.hpp>
// Testing if adl works if it doesn't a compiler error is generated
// Note all usages of glm::begin,glm::end,glm::rbegin,glm::rend
// in this file is via adl
template<typename T>
void begin(T) {}
template<typename T>
void rbegin(T) {}
template<typename T>
void end(T) {}
template<typename T>
void rend(T) {}
template<typename T>
std::ptrdiff_t get_iter_distance() {
T t = T(); // needed for const initializing
return std::distance(begin(t), end(t));
}
template<typename T>
std::ptrdiff_t get_rev_iter_distance() {
T t = T(); // needed for const initializing
return std::distance(rbegin(t), rend(t));
}
template<typename GenTypc>
int rangedSumComp(GenTypc& genType, int compsum) {
int Error = 0;
#if defined(__cpp_range_based_for)
#if __cpp_range_based_for >= 200907L
{
int sum = 0;
for (const int& elem : genType)
sum += elem;
Error += sum != compsum;
}
#endif
#endif
{
int sum = 0;
for (const int* it = begin(genType); it != end(genType); ++it)
sum += *it;
Error += sum != compsum;
}
{
int sum = 0;
for (std::reverse_iterator<const int*> it = rbegin(genType); it != rend(genType); ++it)
sum += *it;
Error += sum != compsum;
}
return Error;
}
template<glm::length_t L>
int sumVec() {
glm::vec<L, int> v;
int sumManual = 0;
for (int i = 0; i < L; ++i) {
v[i] = i;
sumManual += i;
}
glm::vec<L, int> const cv = v;
return (sumManual != std::accumulate(begin(v), end(v), 0))
+ (sumManual != std::accumulate(begin(cv), end(cv), 0))
+ (sumManual != std::accumulate(rbegin(v), rend(v), 0))
+ (sumManual != std::accumulate(rbegin(cv), rend(cv), 0))
+ rangedSumComp(v, sumManual)
+ rangedSumComp(cv, sumManual);
}
template<glm::length_t C, glm::length_t R>
int sumMat() {
glm::mat<C, R, int> m;
int sumManual = 0;
for (int i = 0; i < C; ++i) {
for (int j = 0; j < R; ++j) {
m[i][j] = i * j;
sumManual += i * j;
}
}
glm::mat<C, R, int> const cm = m;
return (sumManual != std::accumulate(begin(m), end(m), 0))
+ (sumManual != std::accumulate(begin(cm), end(cm), 0))
+ (sumManual != std::accumulate(rbegin(m), rend(m), 0))
+ (sumManual != std::accumulate(rbegin(cm), rend(cm), 0))
+ rangedSumComp(m, sumManual)
+ rangedSumComp(cm, sumManual);
}
static int sumQuat() {
glm::qua<int> q(0, 1, 2, 3);
glm::qua<int> const cq(0, 1, 2, 3);
const int sumManual = (0 + 1 + 2 + 3);
return (sumManual != std::accumulate(begin(q), end(q), 0))
+ (sumManual != std::accumulate(begin(cq), end(cq), 0))
+ (sumManual != std::accumulate(rbegin(q), rend(q), 0))
+ (sumManual != std::accumulate(rbegin(cq), rend(cq), 0))
+ rangedSumComp(q, sumManual)
+ rangedSumComp(cq, sumManual);
}
int main()
{
int Error = 0;
Error += (1 != get_iter_distance<glm::vec1>());
Error += (2 != get_iter_distance<glm::vec2>());
Error += (3 != get_iter_distance<glm::vec3>());
Error += (4 != get_iter_distance<glm::vec4>());
Error += (1 != get_iter_distance<const glm::vec1>());
Error += (2 != get_iter_distance<const glm::vec2>());
Error += (3 != get_iter_distance<const glm::vec3>());
Error += (4 != get_iter_distance<const glm::vec4>());
Error += (4 != get_iter_distance<glm::quat>());
Error += (4 != get_iter_distance<const glm::quat>());
Error += (2 * 2 != get_iter_distance<glm::mat2x2>());
Error += (2 * 3 != get_iter_distance<glm::mat2x3>());
Error += (2 * 4 != get_iter_distance<glm::mat2x4>());
Error += (2 * 2 != get_iter_distance<const glm::mat2x2>());
Error += (2 * 3 != get_iter_distance<const glm::mat2x3>());
Error += (2 * 4 != get_iter_distance<const glm::mat2x4>());
Error += (3 * 2 != get_iter_distance<glm::mat3x2>());
Error += (3 * 3 != get_iter_distance<glm::mat3x3>());
Error += (3 * 4 != get_iter_distance<glm::mat3x4>());
Error += (3 * 2 != get_iter_distance<const glm::mat3x2>());
Error += (3 * 3 != get_iter_distance<const glm::mat3x3>());
Error += (3 * 4 != get_iter_distance<const glm::mat3x4>());
Error += (4 * 2 != get_iter_distance<glm::mat4x2>());
Error += (4 * 3 != get_iter_distance<glm::mat4x3>());
Error += (4 * 4 != get_iter_distance<glm::mat4x4>());
Error += (4 * 2 != get_iter_distance<const glm::mat4x2>());
Error += (4 * 3 != get_iter_distance<const glm::mat4x3>());
Error += (4 * 4 != get_iter_distance<const glm::mat4x4>());
Error += (1 != get_rev_iter_distance<glm::vec1>());
Error += (2 != get_rev_iter_distance<glm::vec2>());
Error += (3 != get_rev_iter_distance<glm::vec3>());
Error += (4 != get_rev_iter_distance<glm::vec4>());
Error += (1 != get_rev_iter_distance<const glm::vec1>());
Error += (2 != get_rev_iter_distance<const glm::vec2>());
Error += (3 != get_rev_iter_distance<const glm::vec3>());
Error += (4 != get_rev_iter_distance<const glm::vec4>());
Error += (4 != get_rev_iter_distance<glm::quat>());
Error += (4 != get_rev_iter_distance<const glm::quat>());
Error += (2 * 2 != get_rev_iter_distance<glm::mat2x2>());
Error += (2 * 3 != get_rev_iter_distance<glm::mat2x3>());
Error += (2 * 4 != get_rev_iter_distance<glm::mat2x4>());
Error += (2 * 2 != get_rev_iter_distance<const glm::mat2x2>());
Error += (2 * 3 != get_rev_iter_distance<const glm::mat2x3>());
Error += (2 * 4 != get_rev_iter_distance<const glm::mat2x4>());
Error += (3 * 2 != get_rev_iter_distance<glm::mat3x2>());
Error += (3 * 3 != get_rev_iter_distance<glm::mat3x3>());
Error += (3 * 4 != get_rev_iter_distance<glm::mat3x4>());
Error += (3 * 2 != get_rev_iter_distance<const glm::mat3x2>());
Error += (3 * 3 != get_rev_iter_distance<const glm::mat3x3>());
Error += (3 * 4 != get_rev_iter_distance<const glm::mat3x4>());
Error += (4 * 2 != get_rev_iter_distance<glm::mat4x2>());
Error += (4 * 3 != get_rev_iter_distance<glm::mat4x3>());
Error += (4 * 4 != get_rev_iter_distance<glm::mat4x4>());
Error += (4 * 2 != get_rev_iter_distance<const glm::mat4x2>());
Error += (4 * 3 != get_rev_iter_distance<const glm::mat4x3>());
Error += (4 * 4 != get_rev_iter_distance<const glm::mat4x4>());
Error += sumVec<1>();
Error += sumVec<2>();
Error += sumVec<3>();
Error += sumVec<4>();
Error += sumMat<2, 2>();
Error += sumMat<2, 3>();
Error += sumMat<2, 4>();
Error += sumMat<3, 2>();
Error += sumMat<3, 3>();
Error += sumMat<3, 4>();
Error += sumMat<4, 2>();
Error += sumMat<4, 3>();
Error += sumMat<4, 4>();
Error += sumQuat();
return Error;
}
+124
View File
@@ -0,0 +1,124 @@
#include <glm/glm.hpp>
/*
#if GLM_CONFIG_SIMD == GLM_ENABLE
#define GLM_ENABLE_EXPERIMENTAL
#include <glm/gtx/common.hpp>
#include <glm/gtc/integer.hpp>
#include <glm/gtc/epsilon.hpp>
#include <glm/gtc/type_aligned.hpp>
#include <glm/ext/vector_relational.hpp>
namespace glm
{
enum genTypeEnum
{
QUALIFIER_HIGHP,
QUALIFIER_MEDIUMP,
QUALIFIER_LOWP
};
template <typename genType>
struct genTypeTrait
{};
template <length_t L, typename T>
struct genTypeTrait<vec<L, T, aligned_highp> >
{
static const genTypeEnum GENTYPE = QUALIFIER_HIGHP;
};
template <length_t L, typename T>
struct genTypeTrait<vec<L, T, aligned_mediump> >
{
static const genTypeEnum GENTYPE = QUALIFIER_MEDIUMP;
};
template <length_t L, typename T>
struct genTypeTrait<vec<L, T, aligned_lowp> >
{
static const genTypeEnum GENTYPE = QUALIFIER_LOWP;
};
template<length_t L, typename T, qualifier Q, bool isAligned>
struct load_gentype
{
};
# if GLM_ARCH & GLM_ARCH_SSE_BIT
template<qualifier Q>
struct load_gentype<4, float, Q, true>
{
GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<4, float, Q> load(float const* Mem)
{
vec<4, float, Q> Result;
Result.data = _mm_loadu_ps(Mem);
return Result;
}
};
# endif//GLM_ARCH & GLM_ARCH_SSE_BIT
template<typename genType>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR genType example_identity()
{
return detail::init_gentype<genType, detail::genTypeTrait<genType>::GENTYPE>::identity();
}
template <typename genType, typename valType>
genType load(valType const* Mem)
{
}
aligned_vec4 loadu(float const* Mem)
{
aligned_vec4 Result;
# if GLM_ARCH & GLM_ARCH_SSE_BIT
Result.data = _mm_loadu_ps(Mem);
# else
Result[0] = *(Mem + 0);
Result[1] = *(Mem + 1);
Result[2] = *(Mem + 2);
Result[3] = *(Mem + 3);
# endif//GLM_ARCH & GLM_ARCH_SSE_BIT
return Result;
}
aligned_vec4 loada(float const* Mem)
{
aligned_vec4 Result;
# if GLM_ARCH & GLM_ARCH_SSE_BIT
Result.data = _mm_load_ps(Mem);
# else
Result[0] = *(Mem + 0);
Result[1] = *(Mem + 1);
Result[2] = *(Mem + 2);
Result[3] = *(Mem + 3);
# endif//GLM_ARCH & GLM_ARCH_SSE_BIT
return Result;
}
}//namespace glm
int test_vec4_load()
{
int Error = 0;
float Data[] = {1.f, 2.f, 3.f, 4.f};
glm::aligned_vec4 const V = glm::loadu(Data);
Error += glm::all(glm::equal(V, glm::aligned_vec4(1.f, 2.f, 3.f, 4.f), glm::epsilon<float>())) ? 0 : 1;
return Error;
}
#endif
*/
int main()
{
int Error = 0;
/*
# if GLM_CONFIG_SIMD == GLM_ENABLE
Error += test_vec4_load();
# endif
*/
return Error;
}
+54
View File
@@ -0,0 +1,54 @@
#define GLM_ENABLE_EXPERIMENTAL
#include <glm/gtx/log_base.hpp>
#include <glm/gtc/vec1.hpp>
#include <glm/gtc/epsilon.hpp>
#include <glm/exponential.hpp>
namespace test_log
{
static int run()
{
int Error = 0;
{
float A = glm::log(10.f, 2.0f);
float B = glm::log2(10.f);
Error += glm::epsilonEqual(A, B, 0.00001f) ? 0 : 1;
}
{
glm::vec1 A = glm::log(glm::vec1(10.f), glm::vec1(2.0f));
glm::vec1 B = glm::log2(glm::vec1(10.f));
Error += glm::all(glm::epsilonEqual(A, B, glm::vec1(0.00001f))) ? 0 : 1;
}
{
glm::vec2 A = glm::log(glm::vec2(10.f), glm::vec2(2.0f));
glm::vec2 B = glm::log2(glm::vec2(10.f));
Error += glm::all(glm::epsilonEqual(A, B, glm::vec2(0.00001f))) ? 0 : 1;
}
{
glm::vec3 A = glm::log(glm::vec3(10.f), glm::vec3(2.0f));
glm::vec3 B = glm::log2(glm::vec3(10.f));
Error += glm::all(glm::epsilonEqual(A, B, glm::vec3(0.00001f))) ? 0 : 1;
}
{
glm::vec4 A = glm::log(glm::vec4(10.f), glm::vec4(2.0f));
glm::vec4 B = glm::log2(glm::vec4(10.f));
Error += glm::all(glm::epsilonEqual(A, B, glm::vec4(0.00001f))) ? 0 : 1;
}
return Error;
}
}//namespace test_log
int main()
{
int Error(0);
Error += test_log::run();
return Error;
}
@@ -0,0 +1,9 @@
#define GLM_ENABLE_EXPERIMENTAL
#include <glm/gtx/matrix_cross_product.hpp>
int main()
{
int Error(0);
return Error;
}
@@ -0,0 +1,59 @@
#define GLM_ENABLE_EXPERIMENTAL
#include <glm/gtx/matrix_decompose.hpp>
#include <glm/ext/matrix_relational.hpp>
#include <glm/ext/matrix_transform.hpp>
#include <glm/ext/scalar_constants.hpp>
static int test_identity() {
int Error = 0;
glm::mat4 Matrix(1);
glm::vec3 Scale;
glm::quat Orientation;
glm::vec3 Translation;
glm::vec3 Skew(1);
glm::vec4 Perspective(1);
glm::decompose(Matrix, Scale, Orientation, Translation, Skew, Perspective);
glm::mat4 Out = glm::recompose(Scale, Orientation, Translation, Skew, Perspective);
Error += glm::all(glm::equal(Matrix, Out, glm::epsilon<float>())) ? 0 : 1;
return Error;
}
static int test_scale_translate() {
int Error = 0;
glm::vec3 const T(2.0f);
glm::vec3 const S(2.0f);
glm::mat4 Matrix = glm::translate(glm::scale(glm::mat4(1), S), T);
glm::vec3 Scale(2);
glm::quat Orientation;
glm::vec3 Translation(2);
glm::vec3 Skew(1);
glm::vec4 Perspective(1);
glm::decompose(Matrix, Scale, Orientation, Translation, Skew, Perspective);
glm::mat4 Out = glm::recompose(Scale, Orientation, Translation, Skew, Perspective);
Error += glm::all(glm::equal(Matrix, Out, glm::epsilon<float>())) ? 0 : 1;
return Error;
}
int main()
{
int Error = 0;
Error += test_identity();
Error += test_scale_translate();
return Error;
}
@@ -0,0 +1,105 @@
#define GLM_ENABLE_EXPERIMENTAL
#include <glm/gtx/matrix_factorisation.hpp>
#include <glm/gtc/constants.hpp>
#include <glm/gtc/epsilon.hpp>
template <glm::length_t C, glm::length_t R, typename T, glm::qualifier Q>
static int test_qr(glm::mat<C, R, T, Q> m)
{
int Error = 0;
T const epsilon = static_cast<T>(1e-10);
glm::mat<(C < R ? C : R), R, T, Q> q(-999);
glm::mat<C, (C < R ? C : R), T, Q> r(-999);
glm::qr_decompose(m, q, r);
//Test if q*r really equals the input matrix
glm::mat<C, R, T, Q> tm = q*r;
glm::mat<C, R, T, Q> err = tm - m;
for (glm::length_t i = 0; i < C; i++)
for (glm::length_t j = 0; j < R; j++)
Error += glm::abs(err[i][j]) > epsilon ? 1 : 0;
//Test if the columns of q are orthonormal
for (glm::length_t i = 0; i < (C < R ? C : R); i++)
{
Error += (length(q[i]) - 1) > epsilon ? 1 : 0;
for (glm::length_t j = 0; j<i; j++)
Error += glm::abs(dot(q[i], q[j])) > epsilon ? 1 : 0;
}
//Test if the matrix r is upper triangular
for (glm::length_t i = 0; i < C; i++)
for (glm::length_t j = i + 1; j < (C < R ? C : R); j++)
Error += glm::epsilonEqual(r[i][j], static_cast<T>(0), glm::epsilon<T>()) ? 0 : 1;
return Error;
}
template <glm::length_t C, glm::length_t R, typename T, glm::qualifier Q>
static int test_rq(glm::mat<C, R, T, Q> m)
{
int Error = 0;
T const epsilon = static_cast<T>(1e-10);
glm::mat<C, (C < R ? C : R), T, Q> q(-999);
glm::mat<(C < R ? C : R), R, T, Q> r(-999);
glm::rq_decompose(m, r, q);
//Test if q*r really equals the input matrix
glm::mat<C, R, T, Q> tm = r*q;
glm::mat<C, R, T, Q> err = tm - m;
for (glm::length_t i = 0; i < C; i++)
for (glm::length_t j = 0; j < R; j++)
Error += glm::abs(err[i][j]) > epsilon ? 1 : 0;
//Test if the rows of q are orthonormal
glm::mat<(C < R ? C : R), C, T, Q> tq = transpose(q);
for (glm::length_t i = 0; i < (C < R ? C : R); i++)
{
Error += (length(tq[i]) - 1) > epsilon ? 1 : 0;
for (glm::length_t j = 0; j<i; j++)
Error += glm::abs(dot(tq[i], tq[j])) > epsilon ? 1 : 0;
}
//Test if the matrix r is upper triangular
for (glm::length_t i = 0; i < (C < R ? C : R); i++)
for (glm::length_t j = R - (C < R ? C : R) + i + 1; j < R; j++)
Error += glm::epsilonEqual(r[i][j], static_cast<T>(0), glm::epsilon<T>()) ? 0 : 1;
return Error;
}
int main()
{
int Error = 0;
//Test QR square
Error += test_qr(glm::dmat3(12.0, 6.0, -4.0, -51.0, 167.0, 24.0, 4.0, -68.0, -41.0)) ? 1 : 0;
//Test RQ square
Error += test_rq(glm::dmat3(12.0, 6.0, -4.0, -51.0, 167.0, 24.0, 4.0, -68.0, -41.0)) ? 1 : 0;
//Test QR triangular 1
Error += test_qr(glm::dmat3x4(12.0, 6.0, -4.0, -51.0, 167.0, 24.0, 4.0, -68.0, -41.0, 7.0, 2.0, 15.0)) ? 1 : 0;
//Test QR triangular 2
Error += test_qr(glm::dmat4x3(12.0, 6.0, -4.0, -51.0, 167.0, 24.0, 4.0, -68.0, -41.0, 7.0, 2.0, 15.0)) ? 1 : 0;
//Test RQ triangular 1 : Fails at the triangular test
Error += test_rq(glm::dmat3x4(12.0, 6.0, -4.0, -51.0, 167.0, 24.0, 4.0, -68.0, -41.0, 7.0, 2.0, 15.0)) ? 1 : 0;
//Test QR triangular 2
Error += test_rq(glm::dmat4x3(12.0, 6.0, -4.0, -51.0, 167.0, 24.0, 4.0, -68.0, -41.0, 7.0, 2.0, 15.0)) ? 1 : 0;
return Error;
}
@@ -0,0 +1,122 @@
#define GLM_ENABLE_EXPERIMENTAL
#include <glm/gtc/quaternion.hpp>
#include <glm/gtx/component_wise.hpp>
#include <glm/gtx/matrix_interpolation.hpp>
#include <iostream>
#include <limits>
#include <math.h>
static int test_axisAngle()
{
int Error = 0;
glm::mat4 m1(-0.9946f, 0.0f, -0.104531f, 0.0f,
0.0f, 1.0f, 0.0f, 0.0f,
0.104531f, 0.0f, -0.9946f, 0.0f,
0.0f, 0.0f, 0.0f, 1.0f);
glm::mat4 m2(-0.992624f, 0.0f, -0.121874f, 0.0f,
0.0f, 1.0f, 0.0f, 0.0f,
0.121874f, 0.0f, -0.992624f, 0.0f,
0.0f, 0.0f, 0.0f, 1.0f);
glm::mat4 const m1rot = glm::extractMatrixRotation(m1);
glm::mat4 const dltRotation = m2 * glm::transpose(m1rot);
glm::vec3 dltAxis(0.0f);
float dltAngle = 0.0f;
glm::axisAngle(dltRotation, dltAxis, dltAngle);
std::cout << "dltAxis: (" << dltAxis.x << ", " << dltAxis.y << ", " << dltAxis.z << "), dltAngle: " << dltAngle << std::endl;
glm::quat q = glm::quat_cast(dltRotation);
std::cout << "q: (" << q.x << ", " << q.y << ", " << q.z << ", " << q.w << ")" << std::endl;
float yaw = glm::yaw(q);
std::cout << "Yaw: " << yaw << std::endl;
return Error;
}
template <class T>
static int testForAxisAngle(glm::vec<3, T, glm::defaultp> const axisTrue, T const angleTrue)
{
T const eps = std::sqrt(std::numeric_limits<T>::epsilon());
glm::mat<4, 4, T, glm::defaultp> const matTrue = glm::axisAngleMatrix(axisTrue, angleTrue);
glm::vec<3, T, glm::defaultp> axis;
T angle;
glm::axisAngle(matTrue, axis, angle);
glm::mat<4, 4, T, glm::defaultp> const matRebuilt = glm::axisAngleMatrix(axis, angle);
glm::mat<4, 4, T, glm::defaultp> const errMat = matTrue - matRebuilt;
T const maxErr = glm::compMax(glm::vec<4, T, glm::defaultp>(
glm::compMax(glm::abs(errMat[0])),
glm::compMax(glm::abs(errMat[1])),
glm::compMax(glm::abs(errMat[2])),
glm::compMax(glm::abs(errMat[3]))
));
return maxErr < eps ? 0 : 1;
}
static int test_axisAngle2()
{
int Error = 0;
Error += testForAxisAngle(glm::vec3(0.0f, 1.0f, 0.0f), 0.0f);
Error += testForAxisAngle(glm::vec3(0.358f, 0.0716f, 0.9309f), 0.00001f);
Error += testForAxisAngle(glm::vec3(1.0f, 0.0f, 0.0f), 0.0001f);
Error += testForAxisAngle(glm::vec3(0.0f, 0.0f, 1.0f), 0.001f);
Error += testForAxisAngle(glm::vec3(0.0f, 0.0f, 1.0f), 0.001f);
Error += testForAxisAngle(glm::vec3(0.0f, 1.0f, 0.0f), 0.005f);
Error += testForAxisAngle(glm::vec3(0.0f, 0.0f, 1.0f), 0.005f);
Error += testForAxisAngle(glm::vec3(0.358f, 0.0716f, 0.9309f), 0.03f);
Error += testForAxisAngle(glm::vec3(0.358f, 0.0716f, 0.9309f), 0.0003f);
Error += testForAxisAngle(glm::vec3(0.0f, 0.0f, 1.0f), 0.01f);
Error += testForAxisAngle(glm::dvec3(0.0f, 1.0f, 0.0f), 0.00005);
Error += testForAxisAngle(glm::dvec3(-1.0f, 0.0f, 0.0f), 0.000001);
Error += testForAxisAngle(glm::dvec3(0.7071f, 0.7071f, 0.0f), 0.5);
Error += testForAxisAngle(glm::dvec3(0.7071f, 0.0f, 0.7071f), 0.0002);
Error += testForAxisAngle(glm::dvec3(0.7071f, 0.0f, 0.7071f), 0.00002);
Error += testForAxisAngle(glm::dvec3(0.7071f, 0.0f, 0.7071f), 0.000002);
Error += testForAxisAngle(glm::dvec3(0.7071f, 0.0f, 0.7071f), 0.0000002);
Error += testForAxisAngle(glm::vec3(0.0f, 0.7071f, 0.7071f), 1.3f);
Error += testForAxisAngle(glm::vec3(0.0f, 0.7071f, 0.7071f), 6.3f);
Error += testForAxisAngle(glm::vec3(1.0f, 0.0f, 0.0f), -0.23456f);
Error += testForAxisAngle(glm::vec3(1.0f, 0.0f, 0.0f), glm::pi<float>());
Error += testForAxisAngle(glm::vec3(0.0f, 1.0f, 0.0f), -glm::pi<float>());
Error += testForAxisAngle(glm::vec3(0.358f, 0.0716f, 0.9309f), -glm::pi<float>());
Error += testForAxisAngle(glm::vec3(1.0f, 0.0f, 0.0f), glm::pi<float>() + 2e-6f);
Error += testForAxisAngle(glm::vec3(1.0f, 0.0f, 0.0f), glm::pi<float>() + 1e-4f);
Error += testForAxisAngle(glm::vec3(0.0f, 1.0f, 0.0f), -glm::pi<float>() + 1e-3f);
Error += testForAxisAngle(glm::vec3(0.358f, 0.0716f, 0.9309f), -glm::pi<float>() + 5e-3f);
return Error;
}
static int test_rotate()
{
glm::mat4 m2(1.0);
float myAngle = 1.0f;
m2 = glm::rotate(m2, myAngle, glm::vec3(1.0f, 0.0f, 0.0f));
glm::vec3 m2Axis;
float m2Angle;
glm::axisAngle(m2, m2Axis, m2Angle);
return 0;
}
int main()
{
int Error = 0;
Error += test_axisAngle();
Error += test_axisAngle2();
Error += test_rotate();
return Error;
}
@@ -0,0 +1,9 @@
#define GLM_ENABLE_EXPERIMENTAL
#include <glm/gtx/matrix_major_storage.hpp>
int main()
{
int Error(0);
return Error;
}
@@ -0,0 +1,86 @@
#define GLM_ENABLE_EXPERIMENTAL
#include <glm/glm.hpp>
#include <glm/gtc/epsilon.hpp>
#include <glm/gtx/matrix_operation.hpp>
#include <limits>
static int test_adjugate()
{
int Error = 0;
const float epsilon = std::numeric_limits<float>::epsilon();
// mat2
const glm::mat2 m2(
2, 3,
1, 5
);
const glm::mat2 eam2(
5, -3,
-1, 2
);
const glm::mat2 am2 = glm::adjugate(m2);
Error += glm::all(glm::bvec2(
glm::all(glm::epsilonEqual(am2[0], eam2[0], epsilon)),
glm::all(glm::epsilonEqual(am2[1], eam2[1], epsilon))
)) ? 0 : 1;
// mat3
const glm::mat3 m3(
2, 3, 3,
1, 5, 4,
4, 6, 8
);
const glm::mat3 eam3(
16, -6, -3,
8, 4, -5,
-14, 0, 7
);
const glm::mat3 am3 = glm::adjugate(m3);
Error += glm::all(glm::bvec3(
glm::all(glm::epsilonEqual(am3[0], eam3[0], epsilon)),
glm::all(glm::epsilonEqual(am3[1], eam3[1], epsilon)),
glm::all(glm::epsilonEqual(am3[2], eam3[2], epsilon))
)) ? 0 : 1;
// mat4
const glm::mat4 m4(
2, 3, 3, 1,
1, 5, 4, 3,
4, 6, 8, 5,
-2, -3, -3, 4
);
const glm::mat4 eam4(
97, -30, -15, 17,
45, 20, -25, 5,
-91, 0, 35, -21,
14, 0, 0, 14
);
const glm::mat4 am4 = glm::adjugate(m4);
Error += glm::all(glm::bvec4(
glm::all(glm::epsilonEqual(am4[0], eam4[0], epsilon)),
glm::all(glm::epsilonEqual(am4[1], eam4[1], epsilon)),
glm::all(glm::epsilonEqual(am4[2], eam4[2], epsilon)),
glm::all(glm::epsilonEqual(am4[3], eam4[3], epsilon))
)) ? 0 : 1;
return Error;
}
int main()
{
int Error = 0;
Error += test_adjugate();
return Error;
}
+72
View File
@@ -0,0 +1,72 @@
#define GLM_ENABLE_EXPERIMENTAL
#include <glm/gtx/matrix_query.hpp>
static int test_isNull()
{
int Error(0);
bool TestA = glm::isNull(glm::mat4(0), 0.00001f);
Error += TestA ? 0 : 1;
return Error;
}
static int test_isIdentity()
{
int Error(0);
{
bool TestA = glm::isIdentity(glm::mat2(1), 0.00001f);
Error += TestA ? 0 : 1;
}
{
bool TestA = glm::isIdentity(glm::mat3(1), 0.00001f);
Error += TestA ? 0 : 1;
}
{
bool TestA = glm::isIdentity(glm::mat4(1), 0.00001f);
Error += TestA ? 0 : 1;
}
return Error;
}
static int test_isNormalized()
{
int Error(0);
bool TestA = glm::isNormalized(glm::mat4(1), 0.00001f);
Error += TestA ? 0 : 1;
return Error;
}
static int test_isOrthogonal()
{
int Error(0);
{
bool TestA = glm::isOrthogonal(glm::mat4(1), 0.00001f);
Error += TestA ? 0 : 1;
}
{
bool TestA = glm::isOrthogonal(glm::mat4(0), 0.00001f);
Error += TestA ? 1 : 0;
}
return Error;
}
int main()
{
int Error(0);
Error += test_isNull();
Error += test_isIdentity();
Error += test_isNormalized();
Error += test_isOrthogonal();
return Error;
}
@@ -0,0 +1,9 @@
#define GLM_ENABLE_EXPERIMENTAL
#include <glm/gtx/matrix_transform_2d.hpp>
int main()
{
int Error(0);
return Error;
}
+18
View File
@@ -0,0 +1,18 @@
///////////////////////////////////////////////////////////////////////////////////////////////////
// OpenGL Mathematics Copyright (c) 2005 - 2013 G-Truc Creation (www.g-truc.net)
///////////////////////////////////////////////////////////////////////////////////////////////////
// Created : 2013-10-25
// Updated : 2013-10-25
// Licence : This source is under MIT licence
// File : test/gtx/associated_min_max.cpp
///////////////////////////////////////////////////////////////////////////////////////////////////
#include <glm/gtc/type_precision.hpp>
#include <glm/gtx/associated_min_max.hpp>
int main()
{
int Error(0);
return Error;
}
+84
View File
@@ -0,0 +1,84 @@
#define GLM_ENABLE_EXPERIMENTAL
#include <glm/gtx/norm.hpp>
#include <glm/ext/scalar_relational.hpp>
#include <glm/vec2.hpp>
#include <glm/vec3.hpp>
#include <glm/vec4.hpp>
static int test_lMaxNorm()
{
int Error(0);
{
float norm = glm::lMaxNorm(glm::vec3(-1, -2, -3));
Error += glm::equal(norm, 3.f, 0.00001f) ? 0 : 1;
}
{
float norm = glm::lMaxNorm(glm::vec3(2, 3, 1));
Error += glm::equal(norm, 3.f, 0.00001f) ? 0 : 1;
}
return Error;
}
static int test_lxNorm()
{
int Error(0);
{
unsigned int depth_1 = 1;
float normA = glm::lxNorm(glm::vec3(2, 3, 1), depth_1);
float normB = glm::l1Norm(glm::vec3(2, 3, 1));
Error += glm::equal(normA, normB, 0.00001f) ? 0 : 1;
Error += glm::equal(normA, 6.f, 0.00001f) ? 0 : 1;
}
{
unsigned int depth_1 = 1;
float normA = glm::lxNorm(glm::vec3(-1, -2, -3), depth_1);
float normB = glm::l1Norm(glm::vec3(-1, -2, -3));
Error += glm::equal(normA, normB, 0.00001f) ? 0 : 1;
Error += glm::equal(normA, 6.f, 0.00001f) ? 0 : 1;
}
{
unsigned int depth_2 = 2;
float normA = glm::lxNorm(glm::vec3(2, 3, 1), depth_2);
float normB = glm::l2Norm(glm::vec3(2, 3, 1));
Error += glm::equal(normA, normB, 0.00001f) ? 0 : 1;
Error += glm::equal(normA, 3.741657387f, 0.00001f) ? 0 : 1;
}
{
unsigned int depth_2 = 2;
float normA = glm::lxNorm(glm::vec3(-1, -2, -3), depth_2);
float normB = glm::l2Norm(glm::vec3(-1, -2, -3));
Error += glm::equal(normA, normB, 0.00001f) ? 0 : 1;
Error += glm::equal(normA, 3.741657387f, 0.00001f) ? 0 : 1;
}
{
unsigned int oddDepth = 3;
float norm = glm::lxNorm(glm::vec3(2, 3, 1), oddDepth);
Error += glm::equal(norm, 3.301927249f, 0.00001f) ? 0 : 1;
}
{
unsigned int oddDepth = 3;
float norm = glm::lxNorm(glm::vec3(-1, -2, -3), oddDepth);
Error += glm::equal(norm, 3.301927249f, 0.00001f) ? 0 : 1;
}
return Error;
}
int main()
{
int Error(0);
Error += test_lMaxNorm();
Error += test_lxNorm();
return Error;
}
+9
View File
@@ -0,0 +1,9 @@
#define GLM_ENABLE_EXPERIMENTAL
#include <glm/gtx/normal.hpp>
int main()
{
int Error(0);
return Error;
}
+9
View File
@@ -0,0 +1,9 @@
#define GLM_ENABLE_EXPERIMENTAL
#include <glm/gtx/normalize_dot.hpp>
int main()
{
int Error(0);
return Error;
}
+9
View File
@@ -0,0 +1,9 @@
#define GLM_ENABLE_EXPERIMENTAL
#include <glm/gtx/optimum_pow.hpp>
int main()
{
int Error(0);
return Error;
}
+9
View File
@@ -0,0 +1,9 @@
#define GLM_ENABLE_EXPERIMENTAL
#include <glm/gtx/orthonormalize.hpp>
int main()
{
int Error(0);
return Error;
}
+733
View File
@@ -0,0 +1,733 @@
#define GLM_ENABLE_EXPERIMENTAL
#include <glm/glm.hpp>
#include <glm/gtx/pca.hpp>
#include <glm/gtc/epsilon.hpp>
#include <glm/gtx/string_cast.hpp>
#include <cstdio>
#include <vector>
#if GLM_HAS_CXX11_STL == 1
#include <random>
#endif
#if GLM_COMPILER & GLM_COMPILER_CLANG
# pragma clang diagnostic push
# pragma clang diagnostic ignored "-Wsign-conversion"
#endif
template<typename T>
T myEpsilon();
template<>
GLM_INLINE GLM_CONSTEXPR float myEpsilon<float>() { return 0.00001f; }
template<>
GLM_INLINE GLM_CONSTEXPR double myEpsilon<double>() { return 0.000001; }
template<glm::length_t D, typename T, glm::qualifier Q>
static bool vectorEpsilonEqual(glm::vec<D, T, Q> const& a, glm::vec<D, T, Q> const& b, T epsilon)
{
for (int c = 0; c < D; ++c)
if (!glm::epsilonEqual(a[c], b[c], epsilon))
{
fprintf(stderr, "failing vectorEpsilonEqual: [%d] %lf != %lf (~%lf)\n",
c,
static_cast<double>(a[c]),
static_cast<double>(b[c]),
static_cast<double>(epsilon)
);
return false;
}
return true;
}
template<glm::length_t D, typename T, glm::qualifier Q>
static bool matrixEpsilonEqual(glm::mat<D, D, T, Q> const& a, glm::mat<D, D, T, Q> const& b, T epsilon)
{
for (int c = 0; c < D; ++c)
for (int r = 0; r < D; ++r)
if (!glm::epsilonEqual(a[c][r], b[c][r], epsilon))
{
fprintf(stderr, "failing vectorEpsilonEqual: [%d][%d] %lf != %lf (~%lf)\n",
c, r,
static_cast<double>(a[c][r]),
static_cast<double>(b[c][r]),
static_cast<double>(epsilon)
);
return false;
}
return true;
}
template<typename T>
GLM_INLINE bool sameSign(T const& a, T const& b)
{
return ((a >= 0) && (b >= 0)) || ((a < 0) && (b < 0));
}
template<typename T>
static T failReport(T line)
{
fprintf(stderr, "Failed in line %d\n", static_cast<int>(line));
return line;
}
// Test data: 1AGA 'agarose double helix'
// https://www.rcsb.org/structure/1aga
// The fourth coordinate is randomized
namespace agarose
{
// Fills `outTestData` with hard-coded atom positions from 1AGA
// The fourth coordinate is randomized
template<typename vec>
static void fillTestData(std::vector<vec>& outTestData)
{
// x,y,z coordinates copied from RCSB PDB file of 1AGA
// w coordinate randomized with standard normal distribution
static const double _1aga[] = {
3.219, -0.637, 19.462, 2.286,
4.519, 0.024, 18.980, -0.828,
4.163, 1.425, 18.481, -0.810,
3.190, 1.341, 17.330, -0.170,
1.962, 0.991, 18.165, 0.816,
2.093, 1.952, 19.331, 0.276,
5.119, -0.701, 17.908, -0.490,
3.517, 2.147, 19.514, -0.207,
2.970, 2.609, 16.719, 0.552,
2.107, -0.398, 18.564, 0.403,
2.847, 2.618, 15.335, 0.315,
1.457, 3.124, 14.979, 0.683,
1.316, 3.291, 13.473, 0.446,
2.447, 4.155, 12.931, 1.324,
3.795, 3.614, 13.394, 0.112,
4.956, 4.494, 12.982, 0.253,
0.483, 2.217, 15.479, 1.316,
0.021, 3.962, 13.166, 1.522,
2.311, 5.497, 13.395, 0.248,
3.830, 3.522, 14.827, 0.591,
5.150, 4.461, 11.576, 0.635,
-1.057, 3.106, 13.132, 0.191,
-2.280, 3.902, 12.650, 1.135,
-3.316, 2.893, 12.151, 0.794,
-2.756, 2.092, 11.000, 0.720,
-1.839, 1.204, 11.835, -1.172,
-2.737, 0.837, 13.001, -0.313,
-1.952, 4.784, 11.578, 2.082,
-3.617, 1.972, 13.184, 0.653,
-3.744, 1.267, 10.389, -0.413,
-0.709, 2.024, 12.234, -1.747,
-3.690, 1.156, 9.005, -1.275,
-3.434, -0.300, 8.649, 0.441,
-3.508, -0.506, 7.143, 0.237,
-4.822, 0.042, 6.601, -2.856,
-5.027, 1.480, 7.064, 0.985,
-6.370, 2.045, 6.652, 0.915,
-2.162, -0.690, 9.149, 1.100,
-3.442, -1.963, 6.836, -0.081,
-5.916, -0.747, 7.065, -2.345,
-4.965, 1.556, 8.497, 0.504,
-6.439, 2.230, 5.246, 1.451,
-2.161, -2.469, 6.802, -1.171,
-2.239, -3.925, 6.320, -1.434,
-0.847, -4.318, 5.821, 0.098,
-0.434, -3.433, 4.670, -1.446,
-0.123, -2.195, 5.505, 0.182,
0.644, -2.789, 6.671, 0.865,
-3.167, -4.083, 5.248, -0.098,
0.101, -4.119, 6.854, -0.001,
0.775, -3.876, 4.059, 1.061,
-1.398, -1.625, 5.904, 0.230,
0.844, -3.774, 2.675, 1.313,
1.977, -2.824, 2.319, -0.112,
2.192, -2.785, 0.813, -0.981,
2.375, -4.197, 0.271, -0.355,
1.232, -5.093, 0.734, 0.632,
1.414, -6.539, 0.322, 0.576,
1.678, -1.527, 2.819, -1.187,
3.421, -1.999, 0.496, -1.770,
3.605, -4.750, 0.735, 1.099,
1.135, -5.078, 2.167, 0.854,
1.289, -6.691, -1.084, -0.487,
-1.057, 3.106, 22.602, -1.297,
-2.280, 3.902, 22.120, 0.376,
-3.316, 2.893, 21.621, 0.932,
-2.756, 2.092, 20.470, 1.680,
-1.839, 1.204, 21.305, 0.615,
-2.737, 0.837, 22.471, 0.899,
-1.952, 4.784, 21.048, -0.521,
-3.617, 1.972, 22.654, 0.133,
-3.744, 1.267, 19.859, 0.081,
-0.709, 2.024, 21.704, 1.420,
-3.690, 1.156, 18.475, -0.850,
-3.434, -0.300, 18.119, -0.249,
-3.508, -0.506, 16.613, 1.434,
-4.822, 0.042, 16.071, -2.466,
-5.027, 1.480, 16.534, -1.045,
-6.370, 2.045, 16.122, 1.707,
-2.162, -0.690, 18.619, -2.023,
-3.442, -1.963, 16.336, -0.304,
-5.916, -0.747, 16.535, 0.979,
-4.965, 1.556, 17.967, -1.165,
-6.439, 2.230, 14.716, 0.929,
-2.161, -2.469, 16.302, -0.234,
-2.239, -3.925, 15.820, -0.228,
-0.847, -4.318, 15.321, 1.844,
-0.434, -3.433, 14.170, 1.132,
-0.123, -2.195, 15.005, 0.211,
0.644, -2.789, 16.171, -0.632,
-3.167, -4.083, 14.748, -0.519,
0.101, -4.119, 16.354, 0.173,
0.775, -3.876, 13.559, 1.243,
-1.398, -1.625, 15.404, -0.187,
0.844, -3.774, 12.175, -1.332,
1.977, -2.824, 11.819, -1.616,
2.192, -2.785, 10.313, 1.320,
2.375, -4.197, 9.771, 0.237,
1.232, -5.093, 10.234, 0.851,
1.414, -6.539, 9.822, 1.816,
1.678, -1.527, 12.319, -1.657,
3.421, -1.999, 10.036, 1.559,
3.605, -4.750, 10.235, 0.831,
1.135, -5.078, 11.667, 0.060,
1.289, -6.691, 8.416, 1.066,
3.219, -0.637, 10.002, 2.111,
4.519, 0.024, 9.520, -0.874,
4.163, 1.425, 9.021, -1.012,
3.190, 1.341, 7.870, -0.250,
1.962, 0.991, 8.705, -1.359,
2.093, 1.952, 9.871, -0.126,
5.119, -0.701, 8.448, 0.995,
3.517, 2.147, 10.054, 0.941,
2.970, 2.609, 7.259, -0.562,
2.107, -0.398, 9.104, -0.038,
2.847, 2.618, 5.875, 0.398,
1.457, 3.124, 5.519, 0.481,
1.316, 3.291, 4.013, -0.187,
2.447, 4.155, 3.471, -0.429,
3.795, 3.614, 3.934, -0.432,
4.956, 4.494, 3.522, -0.788,
0.483, 2.217, 6.019, -0.923,
0.021, 3.962, 3.636, -0.316,
2.311, 5.497, 3.935, -1.917,
3.830, 3.522, 5.367, -0.302,
5.150, 4.461, 2.116, -1.615
};
static const glm::length_t _1agaSize = sizeof(_1aga) / (4 * sizeof(double));
outTestData.resize(_1agaSize);
for(glm::length_t i = 0; i < _1agaSize; ++i)
for(glm::length_t d = 0; d < static_cast<glm::length_t>(vec::length()); ++d)
outTestData[i][d] = static_cast<typename vec::value_type>(_1aga[i * 4 + d]);
}
// All reference values computed separately using symbolic precision
// https://github.com/sgrottel/exp-pca-precision
// This applies to all functions named: `agarose::expected*()`
GLM_INLINE glm::dmat4 const& expectedCovarData()
{
static const glm::dmat4 covar4x4d(
9.62434068027210898322, -0.00006657369614512471, -4.29321376568405099761, 0.01879374187452758846,
-0.00006657369614512471, 9.62443937868480681175, 5.35113872637944076871, -0.11569259145880574080,
-4.29321376568405099761, 5.35113872637944076871, 35.62848549634668415820, 0.90874239254220201545,
0.01879374187452758846, -0.11569259145880574080, 0.90874239254220201545, 1.09705971856890904803
);
return covar4x4d;
}
template<glm::length_t D>
GLM_INLINE glm::vec<D, double, glm::defaultp> const& expectedEigenvalues();
template<>
GLM_INLINE glm::dvec2 const& expectedEigenvalues<2>()
{
static const glm::dvec2 evals2(
9.62447289926297399961763301774251330057894539467032275382255,
9.62430715969394210015560961264297422776572580714373620309355
);
return evals2;
}
template<>
GLM_INLINE glm::dvec3 const& expectedEigenvalues<3>()
{
static const glm::dvec3 evals3(
37.3274494274683425233695502581182052836449738530676689472257,
9.62431434161498823505729817436585077939509766554969096873168,
7.92550178622027216422369326567668971675332732240052872097887
);
return evals3;
}
template<>
GLM_INLINE glm::dvec4 const& expectedEigenvalues<4>()
{
static const glm::dvec4 evals4(
37.3477389918792213596879452204499702406947817221901007885630,
9.62470688921105696017807313860277172063600080413412567999700,
7.94017075281634999342344275928070533134615133171969063657713,
1.06170863996588365446060186982477896078741484440002343404155
);
return evals4;
}
template<glm::length_t D>
GLM_INLINE glm::mat<D, D, double, glm::defaultp> const& expectedEigenvectors();
template<>
GLM_INLINE glm::dmat2 const& expectedEigenvectors<2>()
{
static const glm::dmat2 evecs2(
glm::dvec2(
-0.503510847492551904906870957742619139443409162857537237123308,
1
),
glm::dvec2(
1.98605453086051402895741763848787613048533838388005162794043,
1
)
);
return evecs2;
}
template<>
GLM_INLINE glm::dmat3 const& expectedEigenvectors<3>()
{
static const glm::dmat3 evecs3(
glm::dvec3(
-0.154972738414395866005286433008304444294405085038689821864654,
0.193161285869815165989799191097521722568079378840201629578695,
1
),
glm::dvec3(
-158565.112775416943154745839952575022429933119522746586149868,
-127221.506282351944358932458687410410814983610301927832439675,
1
),
glm::dvec3(
2.52702248596556806145700361724323960543858113426446460406536,
-3.14959802931313870497377546974185300816008580801457419079412,
1
)
);
return evecs3;
}
template<>
GLM_INLINE glm::dmat4 const& expectedEigenvectors<4>()
{
static const glm::dmat4 evecs4(
glm::dvec4(
-6.35322390281037045217295803597357821705371650876122113027264,
7.91546394153385394517767054617789939529794642646629201212056,
41.0301543819240679808549819457450130787045236815736490549663,
1
),
glm::dvec4(
-114.622418941087829756565311692197154422302604224781253861297,
-92.2070185807065289900871215218752013659402949497379896153118,
0.0155846091025912430932734548933329458404665760587569100867246,
1
),
glm::dvec4(
13.1771887761559019483954743159026938257325190511642952175789,
-16.3688257459634877666638419310116970616615816436949741766895,
5.17386502341472097227408249233288958059579189051394773143190,
1
),
glm::dvec4(
-0.0192777078948229800494895064532553117703859768210647632969276,
0.0348034950916108873629241563077465542944938906271231198634442,
-0.0340715609308469289267379681032545422644143611273049912226126,
1
)
);
return evecs4;
}
} // namespace agarose
// Compute center of gravity
template<typename vec>
static vec computeCenter(const std::vector<vec>& testData)
{
double c[4];
std::fill(c, c + vec::length(), 0.0);
typename std::vector<vec>::const_iterator e = testData.end();
for(typename std::vector<vec>::const_iterator i = testData.begin(); i != e; ++i)
for(glm::length_t d = 0; d < static_cast<glm::length_t>(vec::length()); ++d)
c[d] += static_cast<double>((*i)[d]);
vec cVec(0);
for(glm::length_t d = 0; d < static_cast<glm::length_t>(vec::length()); ++d)
cVec[d] = static_cast<typename vec::value_type>(c[d] / static_cast<double>(testData.size()));
return cVec;
}
// Test sorting of Eigenvalue&Eigenvector lists. Use exhaustive search.
template<glm::length_t D, typename T, glm::qualifier Q>
static int testEigenvalueSort()
{
// Test input data: four arbitrary values
static const glm::vec<D, T, Q> refVal(
glm::vec<4, T, Q>(
10, 8, 6, 4
)
);
// Test input data: four arbitrary vectors, which can be matched to the above values
static const glm::mat<D, D, T, Q> refVec(
glm::mat<4, 4, T, Q>(
10, 20, 5, 40,
8, 16, 4, 32,
6, 12, 3, 24,
4, 8, 2, 16
)
);
// Permutations of test input data for exhaustive check, based on `D` (1 <= D <= 4)
static const int permutationCount[] = {
0,
1,
2,
6,
24
};
// The permutations t perform, based on `D` (1 <= D <= 4)
static const glm::ivec4 permutation[] = {
glm::ivec4(0, 1, 2, 3),
glm::ivec4(1, 0, 2, 3), // last for D = 2
glm::ivec4(0, 2, 1, 3),
glm::ivec4(1, 2, 0, 3),
glm::ivec4(2, 0, 1, 3),
glm::ivec4(2, 1, 0, 3), // last for D = 3
glm::ivec4(0, 1, 3, 2),
glm::ivec4(1, 0, 3, 2),
glm::ivec4(0, 2, 3, 1),
glm::ivec4(1, 2, 3, 0),
glm::ivec4(2, 0, 3, 1),
glm::ivec4(2, 1, 3, 0),
glm::ivec4(0, 3, 1, 2),
glm::ivec4(1, 3, 0, 2),
glm::ivec4(0, 3, 2, 1),
glm::ivec4(1, 3, 2, 0),
glm::ivec4(2, 3, 0, 1),
glm::ivec4(2, 3, 1, 0),
glm::ivec4(3, 0, 1, 2),
glm::ivec4(3, 1, 0, 2),
glm::ivec4(3, 0, 2, 1),
glm::ivec4(3, 1, 2, 0),
glm::ivec4(3, 2, 0, 1),
glm::ivec4(3, 2, 1, 0) // last for D = 4
};
// initial sanity check
if(!vectorEpsilonEqual(refVal, refVal, myEpsilon<T>()))
return failReport(__LINE__);
if(!matrixEpsilonEqual(refVec, refVec, myEpsilon<T>()))
return failReport(__LINE__);
// Exhaustive search through all permutations
for(int p = 0; p < permutationCount[D]; ++p)
{
glm::vec<D, T, Q> testVal;
glm::mat<D, D, T, Q> testVec;
for(int i = 0; i < D; ++i)
{
testVal[i] = refVal[permutation[p][i]];
testVec[i] = refVec[permutation[p][i]];
}
glm::sortEigenvalues(testVal, testVec);
if (!vectorEpsilonEqual(testVal, refVal, myEpsilon<T>()))
return failReport(__LINE__);
if (!matrixEpsilonEqual(testVec, refVec, myEpsilon<T>()))
return failReport(__LINE__);
}
return 0;
}
// Test covariance matrix creation functions
template<glm::length_t D, typename T, glm::qualifier Q>
static int testCovar(
#if GLM_HAS_CXX11_STL == 1
glm::length_t dataSize, unsigned int randomEngineSeed
#else // GLM_HAS_CXX11_STL == 1
glm::length_t, unsigned int
#endif // GLM_HAS_CXX11_STL == 1
)
{
typedef glm::vec<D, T, Q> vec;
typedef glm::mat<D, D, T, Q> mat;
// #1: test expected result with fixed data set
std::vector<vec> testData;
agarose::fillTestData(testData);
// compute center of gravity
vec center = computeCenter(testData);
mat covarMat = glm::computeCovarianceMatrix(testData.data(), testData.size(), center);
if(!matrixEpsilonEqual(covarMat, mat(agarose::expectedCovarData()), myEpsilon<T>()))
{
fprintf(stderr, "Reconstructed covarMat:\n%s\n", glm::to_string(covarMat).c_str());
return failReport(__LINE__);
}
// #2: test function variant consistency with random data
#if GLM_HAS_CXX11_STL == 1
std::default_random_engine rndEng(randomEngineSeed);
std::normal_distribution<T> normalDist;
testData.resize(dataSize);
// some common offset of all data
T offset[D];
for(glm::length_t d = 0; d < D; ++d)
offset[d] = normalDist(rndEng);
// init data
for(glm::length_t i = 0; i < dataSize; ++i)
for(glm::length_t d = 0; d < D; ++d)
testData[i][d] = offset[d] + normalDist(rndEng);
center = computeCenter(testData);
std::vector<vec> centeredTestData;
centeredTestData.reserve(testData.size());
typename std::vector<vec>::const_iterator e = testData.end();
for(typename std::vector<vec>::const_iterator i = testData.begin(); i != e; ++i)
centeredTestData.push_back((*i) - center);
mat c1 = glm::computeCovarianceMatrix(centeredTestData.data(), centeredTestData.size());
mat c2 = glm::computeCovarianceMatrix<D, T, Q>(centeredTestData.begin(), centeredTestData.end());
mat c3 = glm::computeCovarianceMatrix(testData.data(), testData.size(), center);
mat c4 = glm::computeCovarianceMatrix<D, T, Q>(testData.rbegin(), testData.rend(), center);
if(!matrixEpsilonEqual(c1, c2, myEpsilon<T>()))
return failReport(__LINE__);
if(!matrixEpsilonEqual(c1, c3, myEpsilon<T>()))
return failReport(__LINE__);
if(!matrixEpsilonEqual(c1, c4, myEpsilon<T>()))
return failReport(__LINE__);
#endif // GLM_HAS_CXX11_STL == 1
return 0;
}
// Computes eigenvalues and eigenvectors from well-known covariance matrix
template<glm::length_t D, typename T, glm::qualifier Q>
static int testEigenvectors(T epsilon)
{
typedef glm::vec<D, T, Q> vec;
typedef glm::mat<D, D, T, Q> mat;
// test expected result with fixed data set
std::vector<vec> testData;
mat covarMat(agarose::expectedCovarData());
vec eigenvalues;
mat eigenvectors;
unsigned int c = glm::findEigenvaluesSymReal(covarMat, eigenvalues, eigenvectors);
if(c != D)
return failReport(__LINE__);
glm::sortEigenvalues(eigenvalues, eigenvectors);
if (!vectorEpsilonEqual(eigenvalues, vec(agarose::expectedEigenvalues<D>()), epsilon))
return failReport(__LINE__);
for (int i = 0; i < D; ++i)
{
vec act = glm::normalize(eigenvectors[i]);
vec exp = glm::normalize(agarose::expectedEigenvectors<D>()[i]);
if (!sameSign(act[0], exp[0])) exp = -exp;
if (!vectorEpsilonEqual(act, exp, epsilon))
return failReport(__LINE__);
}
return 0;
}
// A simple small smoke test:
// - a uniformly sampled block
// - reconstruct main axes
// - check order of eigenvalues equals order of extends of block in direction of main axes
static int smokeTest()
{
using glm::vec3;
using glm::mat3;
std::vector<vec3> pts;
pts.reserve(11 * 15 * 7);
for(int x = -5; x <= 5; ++x)
for(int y = -7; y <= 7; ++y)
for(int z = -3; z <= 3; ++z)
pts.push_back(vec3(x, y, z));
mat3 covar = glm::computeCovarianceMatrix(pts.data(), pts.size());
mat3 eVec;
vec3 eVal;
unsigned int eCnt = glm::findEigenvaluesSymReal(covar, eVal, eVec);
if(eCnt != 3u)
return failReport(__LINE__);
// sort eVec by descending eVal
if(eVal[0] < eVal[1])
{
std::swap(eVal[0], eVal[1]);
std::swap(eVec[0], eVec[1]);
}
if(eVal[0] < eVal[2])
{
std::swap(eVal[0], eVal[2]);
std::swap(eVec[0], eVec[2]);
}
if(eVal[1] < eVal[2])
{
std::swap(eVal[1], eVal[2]);
std::swap(eVec[1], eVec[2]);
}
if(!vectorEpsilonEqual(glm::abs(eVec[0]), vec3(0, 1, 0), myEpsilon<float>()))
return failReport(__LINE__);
if(!vectorEpsilonEqual(glm::abs(eVec[1]), vec3(1, 0, 0), myEpsilon<float>()))
return failReport(__LINE__);
if(!vectorEpsilonEqual(glm::abs(eVec[2]), vec3(0, 0, 1), myEpsilon<float>()))
return failReport(__LINE__);
return 0;
}
#if GLM_HAS_CXX11_STL == 1
static int rndTest(unsigned int randomEngineSeed)
{
std::default_random_engine rndEng(randomEngineSeed);
std::normal_distribution<double> normalDist;
// construct orthonormal system
glm::dvec3 x(normalDist(rndEng), normalDist(rndEng), normalDist(rndEng));
double l = glm::length(x);
while(l < myEpsilon<double>())
x = glm::dvec3(normalDist(rndEng), normalDist(rndEng), normalDist(rndEng));
x = glm::normalize(x);
glm::dvec3 y(normalDist(rndEng), normalDist(rndEng), normalDist(rndEng));
l = glm::length(y);
while(l < myEpsilon<double>())
y = glm::dvec3(normalDist(rndEng), normalDist(rndEng), normalDist(rndEng));
while(glm::abs(glm::dot(x, y)) < myEpsilon<double>())
{
y = glm::dvec3(normalDist(rndEng), normalDist(rndEng), normalDist(rndEng));
while(l < myEpsilon<double>())
y = glm::dvec3(normalDist(rndEng), normalDist(rndEng), normalDist(rndEng));
}
y = glm::normalize(y);
glm::dvec3 z = glm::normalize(glm::cross(x, y));
y = glm::normalize(glm::cross(z, x));
// generate input point data
std::vector<glm::dvec3> ptData;
static const int pattern[] = {
8, 0, 0,
4, 1, 2,
0, 2, 0,
0, 0, 4
};
glm::dvec3 offset(normalDist(rndEng), normalDist(rndEng), normalDist(rndEng));
for(int p = 0; p < 4; ++p)
for(int xs = 1; xs >= -1; xs -= 2)
for(int ys = 1; ys >= -1; ys -= 2)
for(int zs = 1; zs >= -1; zs -= 2)
ptData.push_back(
offset
+ x * static_cast<double>(pattern[p * 3 + 0] * xs)
+ y * static_cast<double>(pattern[p * 3 + 1] * ys)
+ z * static_cast<double>(pattern[p * 3 + 2] * zs));
// perform PCA:
glm::dvec3 center = computeCenter(ptData);
glm::dmat3 covarMat = glm::computeCovarianceMatrix(ptData.data(), ptData.size(), center);
glm::dvec3 evals;
glm::dmat3 evecs;
unsigned int evcnt = glm::findEigenvaluesSymReal(covarMat, evals, evecs);
if(evcnt != 3u)
return failReport(__LINE__);
glm::sortEigenvalues(evals, evecs);
if (!sameSign(evecs[0][0], x[0])) evecs[0] = -evecs[0];
if(!vectorEpsilonEqual(x, evecs[0], myEpsilon<double>()))
return failReport(__LINE__);
if (!sameSign(evecs[2][0], y[0])) evecs[2] = -evecs[2];
if (!vectorEpsilonEqual(y, evecs[2], myEpsilon<double>()))
return failReport(__LINE__);
if (!sameSign(evecs[1][0], z[0])) evecs[1] = -evecs[1];
if (!vectorEpsilonEqual(z, evecs[1], myEpsilon<double>()))
return failReport(__LINE__);
return 0;
}
#endif // GLM_HAS_CXX11_STL == 1
int main()
{
int error(0);
// A small smoke test to fail early with most problems
if(smokeTest())
return failReport(__LINE__);
// test sorting utility.
if(testEigenvalueSort<2, float, glm::defaultp>() != 0)
error = failReport(__LINE__);
if(testEigenvalueSort<2, double, glm::defaultp>() != 0)
error = failReport(__LINE__);
if(testEigenvalueSort<3, float, glm::defaultp>() != 0)
error = failReport(__LINE__);
if(testEigenvalueSort<3, double, glm::defaultp>() != 0)
error = failReport(__LINE__);
if(testEigenvalueSort<4, float, glm::defaultp>() != 0)
error = failReport(__LINE__);
if(testEigenvalueSort<4, double, glm::defaultp>() != 0)
error = failReport(__LINE__);
if (error != 0)
return error;
// Note: the random engine uses a fixed seed to create consistent and reproducible test data
// test covariance matrix computation from different data sources
if(testCovar<2, float, glm::defaultp>(100, 12345) != 0)
error = failReport(__LINE__);
if(testCovar<2, double, glm::defaultp>(100, 42) != 0)
error = failReport(__LINE__);
if(testCovar<3, float, glm::defaultp>(100, 2021) != 0)
error = failReport(__LINE__);
if(testCovar<3, double, glm::defaultp>(100, 815) != 0)
error = failReport(__LINE__);
if(testCovar<4, float, glm::defaultp>(100, 3141) != 0)
error = failReport(__LINE__);
if(testCovar<4, double, glm::defaultp>(100, 174) != 0)
error = failReport(__LINE__);
if (error != 0)
return error;
// test PCA eigen vector reconstruction
// Expected epsilon precision evaluated separately:
// https://github.com/sgrottel/exp-pca-precision
if(testEigenvectors<2, float, glm::defaultp>(0.002f) != 0)
error = failReport(__LINE__);
if(testEigenvectors<2, double, glm::defaultp>(0.00000000001) != 0)
error = failReport(__LINE__);
if(testEigenvectors<3, float, glm::defaultp>(0.00001f) != 0)
error = failReport(__LINE__);
if(testEigenvectors<3, double, glm::defaultp>(0.0000000001) != 0)
error = failReport(__LINE__);
if(testEigenvectors<4, float, glm::defaultp>(0.0001f) != 0)
error = failReport(__LINE__);
if(testEigenvectors<4, double, glm::defaultp>(0.0000001) != 0)
error = failReport(__LINE__);
if(error != 0)
return error;
// Final tests with randomized data
#if GLM_HAS_CXX11_STL == 1
if(rndTest(12345) != 0)
error = failReport(__LINE__);
if(rndTest(42) != 0)
error = failReport(__LINE__);
if (error != 0)
return error;
#endif // GLM_HAS_CXX11_STL == 1
return error;
}
#if GLM_COMPILER & GLM_COMPILER_CLANG
# pragma clang diagnostic pop
#endif
+9
View File
@@ -0,0 +1,9 @@
#define GLM_ENABLE_EXPERIMENTAL
#include <glm/gtx/perpendicular.hpp>
int main()
{
int Error(0);
return Error;
}
@@ -0,0 +1,9 @@
#define GLM_ENABLE_EXPERIMENTAL
#include <glm/gtx/polar_coordinates.hpp>
int main()
{
int Error(0);
return Error;
}
+9
View File
@@ -0,0 +1,9 @@
#define GLM_ENABLE_EXPERIMENTAL
#include <glm/gtx/projection.hpp>
int main()
{
int Error(0);
return Error;
}
+112
View File
@@ -0,0 +1,112 @@
#define GLM_ENABLE_EXPERIMENTAL
#include <glm/ext/quaternion_relational.hpp>
#include <glm/gtc/epsilon.hpp>
#include <glm/gtc/type_ptr.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtx/transform.hpp>
#include <glm/gtx/quaternion.hpp>
#include <glm/gtx/compatibility.hpp>
static int test_quat_fastMix()
{
int Error = 0;
glm::quat A = glm::angleAxis(0.0f, glm::vec3(0, 0, 1));
glm::quat B = glm::angleAxis(glm::pi<float>() * 0.5f, glm::vec3(0, 0, 1));
glm::quat C = glm::fastMix(A, B, 0.5f);
glm::quat D = glm::angleAxis(glm::pi<float>() * 0.25f, glm::vec3(0, 0, 1));
Error += glm::epsilonEqual(C.x, D.x, 0.01f) ? 0 : 1;
Error += glm::epsilonEqual(C.y, D.y, 0.01f) ? 0 : 1;
Error += glm::epsilonEqual(C.z, D.z, 0.01f) ? 0 : 1;
Error += glm::epsilonEqual(C.w, D.w, 0.01f) ? 0 : 1;
return Error;
}
static int test_quat_shortMix()
{
int Error = 0;
glm::quat A = glm::angleAxis(0.0f, glm::vec3(0, 0, 1));
glm::quat B = glm::angleAxis(glm::pi<float>() * 0.5f, glm::vec3(0, 0, 1));
glm::quat C = glm::shortMix(A, B, 0.5f);
glm::quat D = glm::angleAxis(glm::pi<float>() * 0.25f, glm::vec3(0, 0, 1));
Error += glm::epsilonEqual(C.x, D.x, 0.01f) ? 0 : 1;
Error += glm::epsilonEqual(C.y, D.y, 0.01f) ? 0 : 1;
Error += glm::epsilonEqual(C.z, D.z, 0.01f) ? 0 : 1;
Error += glm::epsilonEqual(C.w, D.w, 0.01f) ? 0 : 1;
return Error;
}
static int test_orientation()
{
int Error = 0;
{
glm::quat q(1.0f, 0.0f, 0.0f, 1.0f);
float p = glm::roll(q);
Error += glm::epsilonEqual(p, glm::pi<float>() * 0.5f, 0.0001f) ? 0 : 1;
}
{
glm::quat q(1.0f, 0.0f, 0.0f, 1.0f);
float p = glm::pitch(q);
Error += glm::epsilonEqual(p, 0.f, 0.0001f) ? 0 : 1;
}
{
glm::quat q(1.0f, 0.0f, 0.0f, 1.0f);
float p = glm::yaw(q);
Error += glm::epsilonEqual(p, 0.f, 0.0001f) ? 0 : 1;
}
return Error;
}
static int test_rotation()
{
int Error = 0;
glm::vec3 v(1, 0, 0);
glm::vec3 u(0, 1, 0);
glm::quat Rotation = glm::rotation(v, u);
float Angle = glm::angle(Rotation);
Error += glm::abs(Angle - glm::pi<float>() * 0.5f) < glm::epsilon<float>() ? 0 : 1;
return Error;
}
static int test_log()
{
int Error = 0;
glm::vec3 v(1, 0, 0);
glm::vec3 u(0, 1, 0);
glm::quat q = glm::rotation(v, u);
glm::quat p = glm::log(q);
glm::quat r = glm::exp(p);
Error += glm::all(glm::equal(q, r, 0.0001f)) ? 0 : 1;
return Error;
}
int main()
{
int Error = 0;
Error += test_log();
Error += test_rotation();
Error += test_orientation();
Error += test_quat_fastMix();
Error += test_quat_shortMix();
return Error;
}
+99
View File
@@ -0,0 +1,99 @@
///////////////////////////////////////////////////////////////////////////////////////////////////
// OpenGL Mathematics Copyright (c) 2005 - 2012 G-Truc Creation (www.g-truc.net)
///////////////////////////////////////////////////////////////////////////////////////////////////
// Created : 2011-05-31
// Updated : 2011-05-31
// Licence : This source is under MIT licence
// File : test/gtx/random.cpp
///////////////////////////////////////////////////////////////////////////////////////////////////
#include <glm/glm.hpp>
#include <glm/gtx/random.hpp>
#include <glm/gtx/epsilon.hpp>
#include <iostream>
int test_signedRand1()
{
int Error = 0;
{
float ResultFloat = 0.0f;
double ResultDouble = 0.0f;
for(std::size_t i = 0; i < 100000; ++i)
{
ResultFloat += glm::signedRand1<float>();
ResultDouble += glm::signedRand1<double>();
}
Error += glm::equalEpsilon(ResultFloat, 0.0f, 0.0001f);
Error += glm::equalEpsilon(ResultDouble, 0.0, 0.0001);
}
return Error;
}
int test_normalizedRand2()
{
int Error = 0;
{
std::size_t Max = 100000;
float ResultFloat = 0.0f;
double ResultDouble = 0.0f;
for(std::size_t i = 0; i < Max; ++i)
{
ResultFloat += glm::length(glm::normalizedRand2<float>());
ResultDouble += glm::length(glm::normalizedRand2<double>());
}
Error += glm::equalEpsilon(ResultFloat, float(Max), 0.000001f) ? 0 : 1;
Error += glm::equalEpsilon(ResultDouble, double(Max), 0.000001) ? 0 : 1;
assert(!Error);
}
return Error;
}
int test_normalizedRand3()
{
int Error = 0;
{
std::size_t Max = 100000;
float ResultFloatA = 0.0f;
float ResultFloatB = 0.0f;
float ResultFloatC = 0.0f;
double ResultDoubleA = 0.0f;
double ResultDoubleB = 0.0f;
double ResultDoubleC = 0.0f;
for(std::size_t i = 0; i < Max; ++i)
{
ResultFloatA += glm::length(glm::normalizedRand3<float>());
ResultDoubleA += glm::length(glm::normalizedRand3<double>());
ResultFloatB += glm::length(glm::normalizedRand3(2.0f, 2.0f));
ResultDoubleB += glm::length(glm::normalizedRand3(2.0, 2.0));
ResultFloatC += glm::length(glm::normalizedRand3(1.0f, 3.0f));
ResultDoubleC += glm::length(glm::normalizedRand3(1.0, 3.0));
}
Error += glm::equalEpsilon(ResultFloatA, float(Max), 0.0001f) ? 0 : 1;
Error += glm::equalEpsilon(ResultDoubleA, double(Max), 0.0001) ? 0 : 1;
Error += glm::equalEpsilon(ResultFloatB, float(Max * 2), 0.0001f) ? 0 : 1;
Error += glm::equalEpsilon(ResultDoubleB, double(Max * 2), 0.0001) ? 0 : 1;
Error += (ResultFloatC >= float(Max) && ResultFloatC <= float(Max * 3)) ? 0 : 1;
Error += (ResultDoubleC >= double(Max) && ResultDoubleC <= double(Max * 3)) ? 0 : 1;
}
return Error;
}
int main()
{
int Error = 0;
Error += test_signedRand1();
Error += test_normalizedRand2();
Error += test_normalizedRand3();
return Error;
}
+83
View File
@@ -0,0 +1,83 @@
#include <glm/gtc/constants.hpp>
#include <glm/ext/scalar_relational.hpp>
#include <glm/ext/vector_relational.hpp>
#include <glm/glm.hpp>
#if GLM_HAS_RANGE_FOR
#define GLM_ENABLE_EXPERIMENTAL
#include <glm/gtx/range.hpp>
static int test_vec()
{
int Error = 0;
{
glm::ivec3 const v(1, 2, 3);
int count = 0;
glm::ivec3 Result(0);
for(int x : v)
{
Result[count] = x;
count++;
}
Error += count == 3 ? 0 : 1;
Error += v == Result ? 0 : 1;
}
{
glm::ivec3 v(1, 2, 3);
for(int& x : v)
x = 0;
Error += glm::all(glm::equal(v, glm::ivec3(0))) ? 0 : 1;
}
return Error;
}
static int test_mat()
{
int Error = 0;
{
glm::mat4x3 m(1.0f);
int count = 0;
float Sum = 0.0f;
for(float x : m)
{
count++;
Sum += x;
}
Error += count == 12 ? 0 : 1;
Error += glm::equal(Sum, 3.0f, 0.001f) ? 0 : 1;
}
{
glm::mat4x3 m(1.0f);
for (float& x : m) { x = 0; }
glm::vec4 v(1, 1, 1, 1);
Error += glm::all(glm::equal(m*v, glm::vec3(0, 0, 0), glm::epsilon<float>())) ? 0 : 1;
}
return Error;
}
int main()
{
int Error = 0;
Error += test_vec();
Error += test_mat();
return Error;
}
#else
int main()
{
return 0;
}
#endif//GLM_HAS_RANGE_FOR
@@ -0,0 +1,9 @@
#define GLM_ENABLE_EXPERIMENTAL
#include <glm/gtx/rotate_normalized_axis.hpp>
int main()
{
int Error(0);
return Error;
}
+88
View File
@@ -0,0 +1,88 @@
#define GLM_ENABLE_EXPERIMENTAL
#include <glm/gtx/rotate_vector.hpp>
#include <glm/gtc/constants.hpp>
#include <glm/ext/vector_relational.hpp>
static int test_rotate()
{
int Error = 0;
glm::vec2 A = glm::rotate(glm::vec2(1, 0), glm::pi<float>() * 0.5f);
Error += glm::all(glm::equal(A, glm::vec2(0.0f, 1.0f), glm::epsilon<float>())) ? 0 : 1;
glm::vec3 B = glm::rotate(glm::vec3(1, 0, 0), glm::pi<float>() * 0.5f, glm::vec3(0, 0, 1));
Error += glm::all(glm::equal(B, glm::vec3(0.0f, 1.0f, 0.0f), glm::epsilon<float>())) ? 0 : 1;
glm::vec4 C = glm::rotate(glm::vec4(1, 0, 0, 1), glm::pi<float>() * 0.5f, glm::vec3(0, 0, 1));
Error += glm::all(glm::equal(C, glm::vec4(0.0f, 1.0f, 0.0f, 1.0f), glm::epsilon<float>())) ? 0 : 1;
return Error;
}
static int test_rotateX()
{
int Error = 0;
glm::vec3 D = glm::rotateX(glm::vec3(1, 0, 0), glm::pi<float>() * 0.5f);
Error += glm::all(glm::equal(D, glm::vec3(1.0f, 0.0f, 0.0f), glm::epsilon<float>())) ? 0 : 1;
glm::vec4 E = glm::rotateX(glm::vec4(1, 0, 0, 1), glm::pi<float>() * 0.5f);
Error += glm::all(glm::equal(E, glm::vec4(1.0f, 0.0f, 0.0f, 1.0f), glm::epsilon<float>())) ? 0 : 1;
return Error;
}
static int test_rotateY()
{
int Error = 0;
glm::vec3 F = glm::rotateY(glm::vec3(1, 0, 0), glm::pi<float>() * 0.5f);
Error += glm::all(glm::equal(F, glm::vec3(0.0f, 0.0f, -1.0f), glm::epsilon<float>())) ? 0 : 1;
glm::vec4 G = glm::rotateY(glm::vec4(1, 0, 0, 1), glm::pi<float>() * 0.5f);
Error += glm::all(glm::equal(G, glm::vec4(0.0f, 0.0f, -1.0f, 1.0f), glm::epsilon<float>())) ? 0 : 1;
return Error;
}
static int test_rotateZ()
{
int Error = 0;
glm::vec3 H = glm::rotateZ(glm::vec3(1, 0, 0), glm::pi<float>() * 0.5f);
Error += glm::all(glm::equal(H, glm::vec3(0.0f, 1.0f, 0.0f), glm::epsilon<float>())) ? 0 : 1;
glm::vec4 I = glm::rotateZ(glm::vec4(1, 0, 0, 1), glm::pi<float>() * 0.5f);
Error += glm::all(glm::equal(I, glm::vec4(0.0f, 1.0f, 0.0f, 1.0f), glm::epsilon<float>())) ? 0 : 1;
return Error;
}
static int test_orientation()
{
int Error = 0;
glm::mat4 O = glm::orientation(glm::normalize(glm::vec3(1)), glm::vec3(0, 0, 1));
Error += glm::all(glm::equal(O[0], glm::vec4(0.79f, -0.21f,-0.58f, 0.0f), 0.1f)) ? 0 : 1;
Error += glm::all(glm::equal(O[1], glm::vec4(-0.21f, 0.79f,-0.58f, 0.0f), 0.1f)) ? 0 : 1;
Error += glm::all(glm::equal(O[2], glm::vec4(0.58f, 0.58f, 0.58f, 0.0f), 0.1f)) ? 0 : 1;
Error += glm::all(glm::equal(O[3], glm::vec4(0.0f, 0.0f, 0.0f, 1.0f), 0.1f)) ? 0 : 1;
return Error;
}
int main()
{
int Error = 0;
Error += test_rotate();
Error += test_rotateX();
Error += test_rotateY();
Error += test_rotateZ();
Error += test_orientation();
return Error;
}
@@ -0,0 +1,38 @@
#include <glm/gtc/constants.hpp>
#include <glm/ext/vector_relational.hpp>
#include <glm/glm.hpp>
#if GLM_HAS_TEMPLATE_ALIASES && !(GLM_COMPILER & GLM_COMPILER_GCC)
#define GLM_ENABLE_EXPERIMENTAL
#include <glm/gtx/scalar_multiplication.hpp>
int main()
{
int Error(0);
glm::vec3 v(0.5, 3.1, -9.1);
Error += glm::all(glm::equal(v, 1.0 * v, glm::epsilon<float>())) ? 0 : 1;
Error += glm::all(glm::equal(v, 1 * v, glm::epsilon<float>())) ? 0 : 1;
Error += glm::all(glm::equal(v, 1u * v, glm::epsilon<float>())) ? 0 : 1;
glm::mat3 m(1, 2, 3, 4, 5, 6, 7, 8, 9);
glm::vec3 w = 0.5f * m * v;
Error += glm::all(glm::equal((m*v)/2, w, glm::epsilon<float>())) ? 0 : 1;
Error += glm::all(glm::equal(m*(v/2), w, glm::epsilon<float>())) ? 0 : 1;
Error += glm::all(glm::equal((m/2)*v, w, glm::epsilon<float>())) ? 0 : 1;
Error += glm::all(glm::equal((0.5*m)*v, w, glm::epsilon<float>())) ? 0 : 1;
Error += glm::all(glm::equal(0.5*(m*v), w, glm::epsilon<float>())) ? 0 : 1;
return Error;
}
#else
int main()
{
return 0;
}
#endif
+174
View File
@@ -0,0 +1,174 @@
#define GLM_ENABLE_EXPERIMENTAL
#include <glm/gtx/scalar_relational.hpp>
#include <glm/gtc/constants.hpp>
#include <glm/ext/scalar_relational.hpp>
#include <glm/ext/vector_relational.hpp>
#include <glm/ext/matrix_relational.hpp>
#include <glm/glm.hpp>
static int test_lessThan()
{
int Error = 0;
Error += glm::lessThan(0, 1) ? 0 : 1;
Error += glm::lessThan(1, 0) ? 1 : 0;
Error += glm::lessThan(0, 0) ? 1 : 0;
Error += glm::lessThan(1, 1) ? 1 : 0;
Error += glm::lessThan(0.0f, 1.0f) ? 0 : 1;
Error += glm::lessThan(1.0f, 0.0f) ? 1 : 0;
Error += glm::lessThan(0.0f, 0.0f) ? 1 : 0;
Error += glm::lessThan(1.0f, 1.0f) ? 1 : 0;
Error += glm::lessThan(0.0, 1.0) ? 0 : 1;
Error += glm::lessThan(1.0, 0.0) ? 1 : 0;
Error += glm::lessThan(0.0, 0.0) ? 1 : 0;
Error += glm::lessThan(1.0, 1.0) ? 1 : 0;
return Error;
}
static int test_lessThanEqual()
{
int Error = 0;
Error += glm::lessThanEqual(0, 1) ? 0 : 1;
Error += glm::lessThanEqual(1, 0) ? 1 : 0;
Error += glm::lessThanEqual(0, 0) ? 0 : 1;
Error += glm::lessThanEqual(1, 1) ? 0 : 1;
Error += glm::lessThanEqual(0.0f, 1.0f) ? 0 : 1;
Error += glm::lessThanEqual(1.0f, 0.0f) ? 1 : 0;
Error += glm::lessThanEqual(0.0f, 0.0f) ? 0 : 1;
Error += glm::lessThanEqual(1.0f, 1.0f) ? 0 : 1;
Error += glm::lessThanEqual(0.0, 1.0) ? 0 : 1;
Error += glm::lessThanEqual(1.0, 0.0) ? 1 : 0;
Error += glm::lessThanEqual(0.0, 0.0) ? 0 : 1;
Error += glm::lessThanEqual(1.0, 1.0) ? 0 : 1;
return Error;
}
static int test_greaterThan()
{
int Error = 0;
Error += glm::greaterThan(0, 1) ? 1 : 0;
Error += glm::greaterThan(1, 0) ? 0 : 1;
Error += glm::greaterThan(0, 0) ? 1 : 0;
Error += glm::greaterThan(1, 1) ? 1 : 0;
Error += glm::greaterThan(0.0f, 1.0f) ? 1 : 0;
Error += glm::greaterThan(1.0f, 0.0f) ? 0 : 1;
Error += glm::greaterThan(0.0f, 0.0f) ? 1 : 0;
Error += glm::greaterThan(1.0f, 1.0f) ? 1 : 0;
Error += glm::greaterThan(0.0, 1.0) ? 1 : 0;
Error += glm::greaterThan(1.0, 0.0) ? 0 : 1;
Error += glm::greaterThan(0.0, 0.0) ? 1 : 0;
Error += glm::greaterThan(1.0, 1.0) ? 1 : 0;
return Error;
}
static int test_greaterThanEqual()
{
int Error = 0;
Error += glm::greaterThanEqual(0, 1) ? 1 : 0;
Error += glm::greaterThanEqual(1, 0) ? 0 : 1;
Error += glm::greaterThanEqual(0, 0) ? 0 : 1;
Error += glm::greaterThanEqual(1, 1) ? 0 : 1;
Error += glm::greaterThanEqual(0.0f, 1.0f) ? 1 : 0;
Error += glm::greaterThanEqual(1.0f, 0.0f) ? 0 : 1;
Error += glm::greaterThanEqual(0.0f, 0.0f) ? 0 : 1;
Error += glm::greaterThanEqual(1.0f, 1.0f) ? 0 : 1;
Error += glm::greaterThanEqual(0.0, 1.0) ? 1 : 0;
Error += glm::greaterThanEqual(1.0, 0.0) ? 0 : 1;
Error += glm::greaterThanEqual(0.0, 0.0) ? 0 : 1;
Error += glm::greaterThanEqual(1.0, 1.0) ? 0 : 1;
return Error;
}
static int test_equal()
{
int Error = 0;
Error += glm::equal(0, 1) ? 1 : 0;
Error += glm::equal(1, 0) ? 1 : 0;
Error += glm::equal(0, 0) ? 0 : 1;
Error += glm::equal(1, 1) ? 0 : 1;
Error += glm::equal(0.0f, 1.0f, glm::epsilon<float>()) ? 1 : 0;
Error += glm::equal(1.0f, 0.0f, glm::epsilon<float>()) ? 1 : 0;
Error += glm::equal(0.0f, 0.0f, glm::epsilon<float>()) ? 0 : 1;
Error += glm::equal(1.0f, 1.0f, glm::epsilon<float>()) ? 0 : 1;
Error += glm::equal(0.0, 1.0, glm::epsilon<double>()) ? 1 : 0;
Error += glm::equal(1.0, 0.0, glm::epsilon<double>()) ? 1 : 0;
Error += glm::equal(0.0, 0.0, glm::epsilon<double>()) ? 0 : 1;
Error += glm::equal(1.0, 1.0, glm::epsilon<double>()) ? 0 : 1;
return Error;
}
static int test_notEqual()
{
int Error = 0;
Error += glm::notEqual(0, 1) ? 0 : 1;
Error += glm::notEqual(1, 0) ? 0 : 1;
Error += glm::notEqual(0, 0) ? 1 : 0;
Error += glm::notEqual(1, 1) ? 1 : 0;
Error += glm::notEqual(0.0f, 1.0f, glm::epsilon<float>()) ? 0 : 1;
Error += glm::notEqual(1.0f, 0.0f, glm::epsilon<float>()) ? 0 : 1;
Error += glm::notEqual(0.0f, 0.0f, glm::epsilon<float>()) ? 1 : 0;
Error += glm::notEqual(1.0f, 1.0f, glm::epsilon<float>()) ? 1 : 0;
Error += glm::notEqual(0.0, 1.0, glm::epsilon<double>()) ? 0 : 1;
Error += glm::notEqual(1.0, 0.0, glm::epsilon<double>()) ? 0 : 1;
Error += glm::notEqual(0.0, 0.0, glm::epsilon<double>()) ? 1 : 0;
Error += glm::notEqual(1.0, 1.0, glm::epsilon<double>()) ? 1 : 0;
return Error;
}
static int test_any()
{
int Error = 0;
Error += glm::any(true) ? 0 : 1;
Error += glm::any(false) ? 1 : 0;
return Error;
}
static int test_all()
{
int Error = 0;
Error += glm::all(true) ? 0 : 1;
Error += glm::all(false) ? 1 : 0;
return Error;
}
static int test_not()
{
int Error = 0;
Error += glm::not_(true) ? 1 : 0;
Error += glm::not_(false) ? 0 : 1;
return Error;
}
int main()
{
int Error = 0;
Error += test_lessThan();
Error += test_lessThanEqual();
Error += test_greaterThan();
Error += test_greaterThanEqual();
Error += test_equal();
Error += test_notEqual();
Error += test_any();
Error += test_all();
Error += test_not();
return Error;
}
+324
View File
@@ -0,0 +1,324 @@
///////////////////////////////////////////////////////////////////////////////////
/// OpenGL Mathematics (glm.g-truc.net)
///
/// Copyright (c) 2005 - 2012 G-Truc Creation (www.g-truc.net)
/// 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.
///
/// Restrictions:
/// By making use of the Software for military purposes, you choose to make
/// a Bunny unhappy.
///
/// 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.
///
/// @file test/gtx/gtx_simd_mat4.cpp
/// @date 2010-09-16 / 2014-11-25
/// @author Christophe Riccio
///////////////////////////////////////////////////////////////////////////////////
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/quaternion.hpp>
#include <glm/gtc/random.hpp>
#include <glm/gtx/simd_vec4.hpp>
#include <glm/gtx/simd_mat4.hpp>
#include <cstdio>
#include <ctime>
#include <vector>
#if(GLM_ARCH != GLM_ARCH_PURE)
std::vector<float> test_detA(std::vector<glm::mat4> const & Data)
{
std::vector<float> Test(Data.size());
std::clock_t TimeStart = clock();
for(std::size_t i = 0; i < Test.size() - 1; ++i)
Test[i] = glm::determinant(Data[i]);
std::clock_t TimeEnd = clock();
printf("Det A: %ld\n", TimeEnd - TimeStart);
return Test;
}
std::vector<float> test_detB(std::vector<glm::mat4> const & Data)
{
std::vector<float> Test(Data.size());
std::clock_t TimeStart = clock();
for(std::size_t i = 0; i < Test.size() - 1; ++i)
{
_mm_prefetch((char*)&Data[i + 1], _MM_HINT_T0);
glm::simdMat4 m(Data[i]);
glm::simdVec4 d(glm::detail::sse_slow_det_ps((__m128 const * const)&m));
glm::vec4 v;//(d);
Test[i] = v.x;
}
std::clock_t TimeEnd = clock();
printf("Det B: %ld\n", TimeEnd - TimeStart);
return Test;
}
std::vector<float> test_detC(std::vector<glm::mat4> const & Data)
{
std::vector<float> Test(Data.size());
std::clock_t TimeStart = clock();
for(std::size_t i = 0; i < Test.size() - 1; ++i)
{
_mm_prefetch((char*)&Data[i + 1], _MM_HINT_T0);
glm::simdMat4 m(Data[i]);
glm::simdVec4 d(glm::detail::sse_det_ps((__m128 const * const)&m));
glm::vec4 v;//(d);
Test[i] = v.x;
}
std::clock_t TimeEnd = clock();
printf("Det C: %ld\n", TimeEnd - TimeStart);
return Test;
}
std::vector<float> test_detD(std::vector<glm::mat4> const & Data)
{
std::vector<float> Test(Data.size());
std::clock_t TimeStart = clock();
for(std::size_t i = 0; i < Test.size() - 1; ++i)
{
_mm_prefetch((char*)&Data[i + 1], _MM_HINT_T0);
glm::simdMat4 m(Data[i]);
glm::simdVec4 d(glm::detail::sse_detd_ps((__m128 const * const)&m));
glm::vec4 v;//(d);
Test[i] = v.x;
}
std::clock_t TimeEnd = clock();
printf("Det D: %ld\n", TimeEnd - TimeStart);
return Test;
}
void test_invA(std::vector<glm::mat4> const & Data, std::vector<glm::mat4> & Out)
{
//std::vector<float> Test(Data.size());
Out.resize(Data.size());
std::clock_t TimeStart = clock();
for(std::size_t i = 0; i < Out.size() - 1; ++i)
{
Out[i] = glm::inverse(Data[i]);
}
std::clock_t TimeEnd = clock();
printf("Inv A: %ld\n", TimeEnd - TimeStart);
}
void test_invC(std::vector<glm::mat4> const & Data, std::vector<glm::mat4> & Out)
{
//std::vector<float> Test(Data.size());
Out.resize(Data.size());
std::clock_t TimeStart = clock();
for(std::size_t i = 0; i < Out.size() - 1; ++i)
{
_mm_prefetch((char*)&Data[i + 1], _MM_HINT_T0);
glm::simdMat4 m(Data[i]);
glm::simdMat4 o;
glm::detail::sse_inverse_fast_ps((__m128 const * const)&m, (__m128 *)&o);
Out[i] = *(glm::mat4*)&o;
}
std::clock_t TimeEnd = clock();
printf("Inv C: %ld\n", TimeEnd - TimeStart);
}
void test_invD(std::vector<glm::mat4> const & Data, std::vector<glm::mat4> & Out)
{
//std::vector<float> Test(Data.size());
Out.resize(Data.size());
std::clock_t TimeStart = clock();
for(std::size_t i = 0; i < Out.size() - 1; ++i)
{
_mm_prefetch((char*)&Data[i + 1], _MM_HINT_T0);
glm::simdMat4 m(Data[i]);
glm::simdMat4 o;
glm::detail::sse_inverse_ps((__m128 const * const)&m, (__m128 *)&o);
Out[i] = *(glm::mat4*)&o;
}
std::clock_t TimeEnd = clock();
printf("Inv D: %ld\n", TimeEnd - TimeStart);
}
void test_mulA(std::vector<glm::mat4> const & Data, std::vector<glm::mat4> & Out)
{
//std::vector<float> Test(Data.size());
Out.resize(Data.size());
std::clock_t TimeStart = clock();
for(std::size_t i = 0; i < Out.size() - 1; ++i)
{
Out[i] = Data[i] * Data[i];
}
std::clock_t TimeEnd = clock();
printf("Mul A: %ld\n", TimeEnd - TimeStart);
}
void test_mulD(std::vector<glm::mat4> const & Data, std::vector<glm::mat4> & Out)
{
//std::vector<float> Test(Data.size());
Out.resize(Data.size());
std::clock_t TimeStart = clock();
for(std::size_t i = 0; i < Out.size() - 1; ++i)
{
_mm_prefetch((char*)&Data[i + 1], _MM_HINT_T0);
glm::simdMat4 m(Data[i]);
glm::simdMat4 o;
glm::detail::sse_mul_ps((__m128 const * const)&m, (__m128 const * const)&m, (__m128*)&o);
Out[i] = *(glm::mat4*)&o;
}
std::clock_t TimeEnd = clock();
printf("Mul D: %ld\n", TimeEnd - TimeStart);
}
int test_compute_glm()
{
return 0;
}
int test_compute_gtx()
{
std::vector<glm::vec4> Output(1000000);
std::clock_t TimeStart = clock();
for(std::size_t k = 0; k < Output.size(); ++k)
{
float i = float(k) / 1000.f + 0.001f;
glm::vec3 A = glm::normalize(glm::vec3(i));
glm::vec3 B = glm::cross(A, glm::normalize(glm::vec3(1, 1, 2)));
glm::mat4 C = glm::rotate(glm::mat4(1.0f), i, B);
glm::mat4 D = glm::scale(C, glm::vec3(0.8f, 1.0f, 1.2f));
glm::mat4 E = glm::translate(D, glm::vec3(1.4f, 1.2f, 1.1f));
glm::mat4 F = glm::perspective(i, 1.5f, 0.1f, 1000.f);
glm::mat4 G = glm::inverse(F * E);
glm::vec3 H = glm::unProject(glm::vec3(i), G, F, E[3]);
glm::vec3 I = glm::any(glm::isnan(glm::project(H, G, F, E[3]))) ? glm::vec3(2) : glm::vec3(1);
glm::mat4 J = glm::lookAt(glm::normalize(glm::max(B, glm::vec3(0.001f))), H, I);
glm::mat4 K = glm::transpose(J);
glm::quat L = glm::normalize(glm::quat_cast(K));
glm::vec4 M = L * glm::smoothstep(K[3], J[3], glm::vec4(i));
glm::mat4 N = glm::mat4(glm::normalize(glm::max(M, glm::vec4(0.001f))), K[3], J[3], glm::vec4(i));
glm::mat4 O = N * glm::inverse(N);
glm::vec4 P = O * glm::reflect(N[3], glm::vec4(A, 1.0f));
glm::vec4 Q = glm::vec4(glm::dot(M, P));
glm::vec4 R = glm::quat(Q.w, glm::vec3(Q)) * P;
Output[k] = R;
}
std::clock_t TimeEnd = clock();
printf("test_compute_gtx: %ld\n", TimeEnd - TimeStart);
return 0;
}
int main()
{
int Error = 0;
std::vector<glm::mat4> Data(64 * 64 * 1);
for(std::size_t i = 0; i < Data.size(); ++i)
Data[i] = glm::mat4(
glm::vec4(glm::linearRand(glm::vec4(-2.0f), glm::vec4(2.0f))),
glm::vec4(glm::linearRand(glm::vec4(-2.0f), glm::vec4(2.0f))),
glm::vec4(glm::linearRand(glm::vec4(-2.0f), glm::vec4(2.0f))),
glm::vec4(glm::linearRand(glm::vec4(-2.0f), glm::vec4(2.0f))));
{
std::vector<glm::mat4> TestInvA;
test_invA(Data, TestInvA);
}
{
std::vector<glm::mat4> TestInvC;
test_invC(Data, TestInvC);
}
{
std::vector<glm::mat4> TestInvD;
test_invD(Data, TestInvD);
}
{
std::vector<glm::mat4> TestA;
test_mulA(Data, TestA);
}
{
std::vector<glm::mat4> TestD;
test_mulD(Data, TestD);
}
{
std::vector<float> TestDetA = test_detA(Data);
std::vector<float> TestDetB = test_detB(Data);
std::vector<float> TestDetD = test_detD(Data);
std::vector<float> TestDetC = test_detC(Data);
for(std::size_t i = 0; i < TestDetA.size(); ++i)
if(TestDetA[i] != TestDetB[i] && TestDetC[i] != TestDetB[i] && TestDetC[i] != TestDetD[i])
return 1;
}
// shuffle test
glm::simdVec4 A(1.0f, 2.0f, 3.0f, 4.0f);
glm::simdVec4 B(5.0f, 6.0f, 7.0f, 8.0f);
//__m128 C = _mm_shuffle_ps(A.Data, B.Data, _MM_SHUFFLE(1, 0, 1, 0));
Error += test_compute_glm();
Error += test_compute_gtx();
float Det = glm::determinant(glm::simdMat4(1.0));
Error += Det == 1.0f ? 0 : 1;
glm::simdMat4 D = glm::matrixCompMult(glm::simdMat4(1.0), glm::simdMat4(1.0));
return Error;
}
#else
int main()
{
int Error = 0;
return Error;
}
#endif//(GLM_ARCH != GLM_ARCH_PURE)
+71
View File
@@ -0,0 +1,71 @@
///////////////////////////////////////////////////////////////////////////////////
/// OpenGL Mathematics (glm.g-truc.net)
///
/// Copyright (c) 2005 - 2012 G-Truc Creation (www.g-truc.net)
/// 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.
///
/// Restrictions:
/// By making use of the Software for military purposes, you choose to make
/// a Bunny unhappy.
///
/// 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.
///
/// @file test/gtx/gtx_simd_vec4.cpp
/// @date 2010-09-16 / 2014-11-25
/// @author Christophe Riccio
///////////////////////////////////////////////////////////////////////////////////
#include <glm/glm.hpp>
#include <glm/gtx/simd_vec4.hpp>
#include <cstdio>
#if(GLM_ARCH != GLM_ARCH_PURE)
int main()
{
glm::simdVec4 A1(0.0f, 0.1f, 0.2f, 0.3f);
glm::simdVec4 B1(0.4f, 0.5f, 0.6f, 0.7f);
glm::simdVec4 C1 = A1 + B1;
glm::simdVec4 D1 = A1.swizzle<glm::X, glm::Z, glm::Y, glm::W>();
glm::simdVec4 E1(glm::vec4(1.0f));
glm::vec4 F1 = glm::vec4_cast(E1);
//glm::vec4 G1(E1);
//printf("A1(%2.3f, %2.3f, %2.3f, %2.3f)\n", A1.x, A1.y, A1.z, A1.w);
//printf("B1(%2.3f, %2.3f, %2.3f, %2.3f)\n", B1.x, B1.y, B1.z, B1.w);
//printf("C1(%2.3f, %2.3f, %2.3f, %2.3f)\n", C1.x, C1.y, C1.z, C1.w);
//printf("D1(%2.3f, %2.3f, %2.3f, %2.3f)\n", D1.x, D1.y, D1.z, D1.w);
__m128 value = _mm_set1_ps(0.0f);
__m128 data = _mm_cmpeq_ps(value, value);
__m128 add0 = _mm_add_ps(data, data);
glm::simdVec4 GNI(add0);
return 0;
}
#else
int main()
{
int Error = 0;
return Error;
}
#endif//(GLM_ARCH != GLM_ARCH_PURE)
+121
View File
@@ -0,0 +1,121 @@
#include <glm/vec2.hpp>
#include <glm/vec3.hpp>
#include <glm/vec4.hpp>
#include <glm/ext/vector_relational.hpp>
#include <glm/ext/scalar_constants.hpp>
#define GLM_ENABLE_EXPERIMENTAL
#include <glm/gtx/spline.hpp>
namespace catmullRom
{
static int test()
{
int Error = 0;
glm::vec2 Result2 = glm::catmullRom(
glm::vec2(0.0f, 0.0f),
glm::vec2(1.0f, 0.0f),
glm::vec2(1.0f, 1.0f),
glm::vec2(0.0f, 1.0f), 0.5f);
Error += glm::all(glm::equal(Result2, glm::vec2(1.125f, 0.5f), glm::epsilon<float>())) ? 0 : 1;
glm::vec3 Result3 = glm::catmullRom(
glm::vec3(0.0f, 0.0f, 0.0f),
glm::vec3(1.0f, 0.0f, 0.0f),
glm::vec3(1.0f, 1.0f, 0.0f),
glm::vec3(0.0f, 1.0f, 0.0f), 0.5f);
Error += glm::all(glm::equal(Result3, glm::vec3(1.125f, 0.5f, 0.0f), glm::epsilon<float>())) ? 0 : 1;
glm::vec4 Result4 = glm::catmullRom(
glm::vec4(0.0f, 0.0f, 0.0f, 1.0f),
glm::vec4(1.0f, 0.0f, 0.0f, 1.0f),
glm::vec4(1.0f, 1.0f, 0.0f, 1.0f),
glm::vec4(0.0f, 1.0f, 0.0f, 1.0f), 0.5f);
Error += glm::all(glm::equal(Result4, glm::vec4(1.125f, 0.5f, 0.0f, 1.0f), glm::epsilon<float>())) ? 0 : 1;
return Error;
}
}//catmullRom
namespace hermite
{
static int test()
{
int Error = 0;
glm::vec2 Result2 = glm::hermite(
glm::vec2(0.0f, 0.0f),
glm::vec2(1.0f, 0.0f),
glm::vec2(1.0f, 1.0f),
glm::vec2(0.0f, 1.0f), 0.5f);
Error += glm::all(glm::equal(Result2, glm::vec2(0.625f, 0.375f), glm::epsilon<float>())) ? 0 : 1;
glm::vec3 Result3 = glm::hermite(
glm::vec3(0.0f, 0.0f, 0.0f),
glm::vec3(1.0f, 0.0f, 0.0f),
glm::vec3(1.0f, 1.0f, 0.0f),
glm::vec3(0.0f, 1.0f, 0.0f), 0.5f);
Error += glm::all(glm::equal(Result3, glm::vec3(0.625f, 0.375f, 0.0f), glm::epsilon<float>())) ? 0 : 1;
glm::vec4 Result4 = glm::hermite(
glm::vec4(0.0f, 0.0f, 0.0f, 1.0f),
glm::vec4(1.0f, 0.0f, 0.0f, 1.0f),
glm::vec4(1.0f, 1.0f, 0.0f, 1.0f),
glm::vec4(0.0f, 1.0f, 0.0f, 1.0f), 0.5f);
Error += glm::all(glm::equal(Result4, glm::vec4(0.625f, 0.375f, 0.0f, 1.0f), glm::epsilon<float>())) ? 0 : 1;
return Error;
}
}//catmullRom
namespace cubic
{
static int test()
{
int Error = 0;
glm::vec2 Result2 = glm::cubic(
glm::vec2(0.0f, 0.0f),
glm::vec2(1.0f, 0.0f),
glm::vec2(1.0f, 1.0f),
glm::vec2(0.0f, 1.0f), 0.5f);
Error += glm::all(glm::equal(Result2, glm::vec2(0.75f, 1.5f), glm::epsilon<float>())) ? 0 : 1;
glm::vec3 Result3 = glm::cubic(
glm::vec3(0.0f, 0.0f, 0.0f),
glm::vec3(1.0f, 0.0f, 0.0f),
glm::vec3(1.0f, 1.0f, 0.0f),
glm::vec3(0.0f, 1.0f, 0.0f), 0.5f);
Error += glm::all(glm::equal(Result3, glm::vec3(0.75f, 1.5f, 0.0f), glm::epsilon<float>())) ? 0 : 1;
glm::vec4 Result4 = glm::cubic(
glm::vec4(0.0f, 0.0f, 0.0f, 1.0f),
glm::vec4(1.0f, 0.0f, 0.0f, 1.0f),
glm::vec4(1.0f, 1.0f, 0.0f, 1.0f),
glm::vec4(0.0f, 1.0f, 0.0f, 1.0f), 0.5f);
Error += glm::all(glm::equal(Result4, glm::vec4(0.75f, 1.5f, 0.0f, 1.875f), glm::epsilon<float>())) ? 0 : 1;
return Error;
}
}//catmullRom
int main()
{
int Error(0);
Error += catmullRom::test();
Error += hermite::test();
Error += cubic::test();
return Error;
}
+156
View File
@@ -0,0 +1,156 @@
#include <glm/glm.hpp>
#define GLM_ENABLE_EXPERIMENTAL
#include <glm/gtx/string_cast.hpp>
#include <limits>
static int test_string_cast_vector()
{
int Error = 0;
{
glm::vec2 A1(1, 2);
std::string A2 = glm::to_string(A1);
Error += A2 != std::string("vec2(1.000000, 2.000000)") ? 1 : 0;
glm::vec3 B1(1, 2, 3);
std::string B2 = glm::to_string(B1);
Error += B2 != std::string("vec3(1.000000, 2.000000, 3.000000)") ? 1 : 0;
glm::vec4 C1(1, 2, 3, 4);
std::string C2 = glm::to_string(C1);
Error += C2 != std::string("vec4(1.000000, 2.000000, 3.000000, 4.000000)") ? 1 : 0;
glm::dvec2 J1(1, 2);
std::string J2 = glm::to_string(J1);
Error += J2 != std::string("dvec2(1.000000, 2.000000)") ? 1 : 0;
glm::dvec3 K1(1, 2, 3);
std::string K2 = glm::to_string(K1);
Error += K2 != std::string("dvec3(1.000000, 2.000000, 3.000000)") ? 1 : 0;
glm::dvec4 L1(1, 2, 3, 4);
std::string L2 = glm::to_string(L1);
Error += L2 != std::string("dvec4(1.000000, 2.000000, 3.000000, 4.000000)") ? 1 : 0;
}
{
glm::bvec2 M1(false, true);
std::string M2 = glm::to_string(M1);
Error += M2 != std::string("bvec2(false, true)") ? 1 : 0;
glm::bvec3 O1(false, true, false);
std::string O2 = glm::to_string(O1);
Error += O2 != std::string("bvec3(false, true, false)") ? 1 : 0;
glm::bvec4 P1(false, true, false, true);
std::string P2 = glm::to_string(P1);
Error += P2 != std::string("bvec4(false, true, false, true)") ? 1 : 0;
}
{
glm::ivec2 D1(1, 2);
std::string D2 = glm::to_string(D1);
Error += D2 != std::string("ivec2(1, 2)") ? 1 : 0;
glm::ivec3 E1(1, 2, 3);
std::string E2 = glm::to_string(E1);
Error += E2 != std::string("ivec3(1, 2, 3)") ? 1 : 0;
glm::ivec4 F1(1, 2, 3, 4);
std::string F2 = glm::to_string(F1);
Error += F2 != std::string("ivec4(1, 2, 3, 4)") ? 1 : 0;
}
{
glm::i8vec2 D1(1, 2);
std::string D2 = glm::to_string(D1);
Error += D2 != std::string("i8vec2(1, 2)") ? 1 : 0;
glm::i8vec3 E1(1, 2, 3);
std::string E2 = glm::to_string(E1);
Error += E2 != std::string("i8vec3(1, 2, 3)") ? 1 : 0;
glm::i8vec4 F1(1, 2, 3, 4);
std::string F2 = glm::to_string(F1);
Error += F2 != std::string("i8vec4(1, 2, 3, 4)") ? 1 : 0;
}
{
glm::i16vec2 D1(1, 2);
std::string D2 = glm::to_string(D1);
Error += D2 != std::string("i16vec2(1, 2)") ? 1 : 0;
glm::i16vec3 E1(1, 2, 3);
std::string E2 = glm::to_string(E1);
Error += E2 != std::string("i16vec3(1, 2, 3)") ? 1 : 0;
glm::i16vec4 F1(1, 2, 3, 4);
std::string F2 = glm::to_string(F1);
Error += F2 != std::string("i16vec4(1, 2, 3, 4)") ? 1 : 0;
}
{
glm::i64vec2 D1(1, 2);
std::string D2 = glm::to_string(D1);
Error += D2 != std::string("i64vec2(1, 2)") ? 1 : 0;
glm::i64vec3 E1(1, 2, 3);
std::string E2 = glm::to_string(E1);
Error += E2 != std::string("i64vec3(1, 2, 3)") ? 1 : 0;
glm::i64vec4 F1(1, 2, 3, 4);
std::string F2 = glm::to_string(F1);
Error += F2 != std::string("i64vec4(1, 2, 3, 4)") ? 1 : 0;
}
return Error;
}
static int test_string_cast_matrix()
{
int Error = 0;
glm::mat2x2 A1(1.000000, 2.000000, 3.000000, 4.000000);
std::string A2 = glm::to_string(A1);
Error += A2 != std::string("mat2x2((1.000000, 2.000000), (3.000000, 4.000000))") ? 1 : 0;
return Error;
}
static int test_string_cast_quaternion()
{
int Error = 0;
glm::quat Q0 = glm::quat(1.0f, 2.0f, 3.0f, 4.0f);
std::string S0 = glm::to_string(Q0);
Error += S0 != std::string("quat(1.000000, {2.000000, 3.000000, 4.000000})") ? 1 : 0;
return Error;
}
static int test_string_cast_dual_quaternion()
{
int Error = 0;
glm::dualquat Q0 = glm::dualquat(glm::quat(1.0f, 2.0f, 3.0f, 4.0f), glm::quat(5.0f, 6.0f, 7.0f, 8.0f));
std::string S0 = glm::to_string(Q0);
Error += S0 != std::string("dualquat((1.000000, {2.000000, 3.000000, 4.000000}), (5.000000, {6.000000, 7.000000, 8.000000}))") ? 1 : 0;
return Error;
}
int main()
{
int Error = 0;
Error += test_string_cast_vector();
Error += test_string_cast_matrix();
Error += test_string_cast_quaternion();
Error += test_string_cast_dual_quaternion();
return Error;
}
@@ -0,0 +1,366 @@
#define GLM_ENABLE_EXPERIMENTAL
#include <glm/gtx/structured_bindings.hpp>
#include <glm/glm.hpp>
#include <glm/gtc/vec1.hpp>
static int test_vec1() {
glm::vec1 v(0);
float& x = glm::get<0>(v);
return (&x != &v.x);
}
static int test_vec2() {
glm::vec2 v(0);
float& x = glm::get<0>(v);
float& y = glm::get<1>(v);
return (&x != &v.x) + (&y != &v.y);
}
static int test_vec3() {
glm::vec3 v(0);
float& x = glm::get<0>(v);
float& y = glm::get<1>(v);
float& z = glm::get<2>(v);
return (&x != &v.x) + (&y != &v.y) + (&z != &v.z);
}
static int test_vec4() {
glm::vec4 v(0);
float& x = glm::get<0>(v);
float& y = glm::get<1>(v);
float& z = glm::get<2>(v);
float& w = glm::get<3>(v);
return (&x != &v.x) + (&y != &v.y) + (&z != &v.z) + (&w != &v.w);
}
static int test_const_vec1() {
glm::vec1 const v(0);
float const& x = glm::get<0>(v);
return (&x != &v.x);
}
static int test_const_vec2() {
glm::vec2 const v(0);
float const& x = glm::get<0>(v);
float const& y = glm::get<1>(v);
return (&x != &v.x) + (&y != &v.y);
}
static int test_const_vec3() {
glm::vec3 const v(0);
float const& x = glm::get<0>(v);
float const& y = glm::get<1>(v);
float const& z = glm::get<2>(v);
return (&x != &v.x) + (&y != &v.y) + (&z != &v.z);
}
static int test_const_vec4() {
glm::vec4 const v(0);
float const& x = glm::get<0>(v);
float const& y = glm::get<1>(v);
float const& z = glm::get<2>(v);
float const& w = glm::get<3>(v);
return (&x != &v.x) + (&y != &v.y) + (&z != &v.z) + (&w != &v.w);
}
static int test_quat() {
glm::quat q(0.0f, 0.0f, 0.0f, 0.0f);
#ifdef GLM_FORCE_QUAT_DATA_WXYZ
float& w = glm::get<0>(q);
float& x = glm::get<1>(q);
float& y = glm::get<2>(q);
float& z = glm::get<3>(q);
#else
float& x = glm::get<0>(q);
float& y = glm::get<1>(q);
float& z = glm::get<2>(q);
float& w = glm::get<3>(q);
#endif
return (&x != &q.x) + (&y != &q.y) + (&z != &q.z) + (&w != &q.w);
}
static int test_const_quat() {
glm::quat const q(0.0f, 0.0f, 0.0f, 0.0f);
#ifdef GLM_FORCE_QUAT_DATA_WXYZ
float const& w = glm::get<0>(q);
float const& x = glm::get<1>(q);
float const& y = glm::get<2>(q);
float const& z = glm::get<3>(q);
#else
float const& x = glm::get<0>(q);
float const& y = glm::get<1>(q);
float const& z = glm::get<2>(q);
float const& w = glm::get<3>(q);
#endif
return (&x != &q.x) + (&y != &q.y) + (&z != &q.z) + (&w != &q.w);
}
template<glm::length_t R>
static int test_mat2xR() {
typedef glm::mat<2, R, float> Mat;
Mat m(0);
typename Mat::col_type& c1 = glm::get<0>(m);
typename Mat::col_type& c2 = glm::get<1>(m);
return (&c1 != &m[0]) + (&c2 != &m[1]);
}
template<glm::length_t R>
static int test_const_mat2xR() {
typedef glm::mat<2,R,float> Mat;
Mat const m(0);
typename Mat::col_type const& c1 = glm::get<0>(m);
typename Mat::col_type const& c2 = glm::get<1>(m);
return (&c1 != &m[0]) + (&c2 != &m[1]);
}
template<glm::length_t R>
static int test_mat3xR() {
typedef glm::mat<3, R, float> Mat;
Mat m(0);
typename Mat::col_type& c1 = glm::get<0>(m);
typename Mat::col_type& c2 = glm::get<1>(m);
typename Mat::col_type& c3 = glm::get<2>(m);
return (&c1 != &m[0]) + (&c2 != &m[1]) + (&c3 != &m[2]);
}
template<glm::length_t R>
static int test_const_mat3xR() {
typedef glm::mat< 3, R, float> Mat;
Mat const m(0);
typename Mat::col_type const& c1 = glm::get<0>(m);
typename Mat::col_type const& c2 = glm::get<1>(m);
typename Mat::col_type const& c3 = glm::get<2>(m);
return (&c1 != &m[0]) + (&c2 != &m[1]) + (&c3 != &m[2]);
}
template<glm::length_t R>
static int test_mat4xR() {
typedef glm::mat<4,R,float> Mat;
Mat m(0);
typename Mat::col_type& c1 = glm::get<0>(m);
typename Mat::col_type& c2 = glm::get<1>(m);
typename Mat::col_type& c3 = glm::get<2>(m);
typename Mat::col_type& c4 = glm::get<3>(m);
return (&c1 != &m[0]) + (&c2 != &m[1]) + (&c3 != &m[2]) + (&c4 != &m[3]);
}
template<glm::length_t R>
static int test_const_mat4xR() {
typedef glm::mat<4,R,float> Mat;
Mat const m(0);
typename Mat::col_type const& c1 = glm::get<0>(m);
typename Mat::col_type const& c2 = glm::get<1>(m);
typename Mat::col_type const& c3 = glm::get<2>(m);
typename Mat::col_type const& c4 = glm::get<3>(m);
return (&c1 != &m[0]) + (&c2 != &m[1]) + (&c3 != &m[2]) + (&c4 != &m[3]);
}
#if defined(__cpp_structured_bindings)
#if __cpp_structured_bindings >= 201606L
static int test_structured_vec1() {
glm::vec1 v(0);
auto& [x] = v;
return (&x != &v.x);
}
static int test_structured_vec2() {
glm::vec2 v(0);
auto& [x, y] = v;
return (&x != &v.x) + (&y != &v.y);
}
static int test_structured_vec3() {
glm::vec3 v(0);
auto& [x, y, z] = v;
return (&x != &v.x) + (&y != &v.y) + (&z != &v.z);
}
static int test_structured_vec4() {
glm::vec4 v(0);
auto& [x, y, z, w] = v;
return (&x != &v.x) + (&y != &v.y) + (&z != &v.z) + (&w != &v.w);
}
static int test_const_structured_vec1() {
glm::vec1 const v(0);
auto const& [x] = v;
return (&x != &v.x);
}
static int test_const_structured_vec2() {
glm::vec2 const v(0);
auto const& [x, y] = v;
return (&x != &v.x) + (&y != &v.y);
}
static int test_const_structured_vec3() {
glm::vec3 const v(0);
auto const& [x, y, z] = v;
return (&x != &v.x) + (&y != &v.y) + (&z != &v.z);
}
static int test_const_structured_vec4() {
glm::vec4 const v(0);
auto const& [x, y, z, w] = v;
return (&x != &v.x) + (&y != &v.y) + (&z != &v.z) + (&w != &v.w);
}
template<glm::length_t R>
static int test_structured_mat2xR() {
glm::mat<2,R,float,glm::defaultp> m(0);
auto& [c1, c2] = m;
return (&c1 != &m[0]) + (&c2 != &m[1]);
}
template<glm::length_t R>
static int test_const_structured_mat2xR() {
glm::mat<2, R, float, glm::defaultp> const m(0);
auto const& [c1, c2] = m;
return (&c1 != &m[0]) + (&c2 != &m[1]);
}
template<glm::length_t R>
static int test_structured_mat3xR() {
glm::mat<3, R, float, glm::defaultp> m(0);
auto& [c1, c2,c3] = m;
return (&c1 != &m[0]) + (&c2 != &m[1]) + (&c3 != &m[2]);
}
template<glm::length_t R>
static int test_const_structured_mat3xR() {
glm::mat<3, R, float, glm::defaultp> const m(0);
auto const& [c1, c2, c3] = m;
return (&c1 != &m[0]) + (&c2 != &m[1]) + (&c3 != &m[2]);
}
template<glm::length_t R>
static int test_structured_mat4xR() {
glm::mat<4, R, float, glm::defaultp> m(0);
auto& [c1, c2, c3,c4] = m;
return (&c1 != &m[0]) + (&c2 != &m[1]) + (&c3 != &m[2]) + (&c4 != &m[3]);
}
template<glm::length_t R>
static int test_const_structured_mat4xR() {
glm::mat<4, R, float, glm::defaultp> const m(0);
auto const& [c1, c2, c3, c4] = m;
return (&c1 != &m[0]) + (&c2 != &m[1]) + (&c3 != &m[2]) + (&c4 != &m[3]);
}
static int test_structured_quat() {
glm::quat q(0.0f, 0.0f, 0.0f, 0.0f);
#ifdef GLM_FORCE_QUAT_DATA_WXYZ
auto& [w, x, y, z] = q;
#else
auto& [x, y, z, w] = q;
#endif
return (&x != &q.x) + (&y != &q.y) + (&z != &q.z) + (&w != &q.w);
}
static int test_const_structured_quat() {
glm::quat const q(0.0f, 0.0f, 0.0f, 0.0f);
#ifdef GLM_FORCE_QUAT_DATA_WXYZ
auto const& [w, x, y, z] = q;
#else
auto const& [x, y, z, w] = q;
#endif
return (&x != &q.x) + (&y != &q.y) + (&z != &q.z) + (&w != &q.w);
}
#endif
#endif
int main()
{
int Error = 0;
Error += test_vec1();
Error += test_vec2();
Error += test_vec3();
Error += test_vec4();
Error += test_const_vec1();
Error += test_const_vec2();
Error += test_const_vec3();
Error += test_const_vec4();
Error += test_quat();
Error += test_const_quat();
Error += test_mat2xR<2>();
Error += test_const_mat2xR<2>();
Error += test_mat2xR<3>();
Error += test_const_mat2xR<3>();
Error += test_mat2xR<4>();
Error += test_const_mat2xR<4>();
Error += test_mat3xR<2>();
Error += test_const_mat3xR<2>();
Error += test_mat3xR<3>();
Error += test_const_mat3xR<3>();
Error += test_mat3xR<4>();
Error += test_const_mat3xR<4>();
Error += test_mat4xR<2>();
Error += test_const_mat4xR<2>();
Error += test_mat4xR<3>();
Error += test_const_mat4xR<3>();
Error += test_mat4xR<4>();
Error += test_const_mat4xR<4>();
#ifdef __cpp_structured_bindings
#if __cpp_structured_bindings >= 201606L
Error += test_structured_vec1();
Error += test_structured_vec2();
Error += test_structured_vec3();
Error += test_structured_vec4();
Error += test_const_structured_vec1();
Error += test_const_structured_vec2();
Error += test_const_structured_vec3();
Error += test_const_structured_vec4();
Error += test_structured_quat();
Error += test_const_structured_quat();
Error += test_structured_mat2xR<2>();
Error += test_const_structured_mat2xR<2>();
Error += test_structured_mat2xR<3>();
Error += test_const_structured_mat2xR<3>();
Error += test_structured_mat2xR<4>();
Error += test_const_structured_mat2xR<4>();
Error += test_structured_mat3xR<2>();
Error += test_const_structured_mat3xR<2>();
Error += test_structured_mat3xR<3>();
Error += test_const_structured_mat3xR<3>();
Error += test_structured_mat3xR<4>();
Error += test_const_structured_mat3xR<4>();
Error += test_structured_mat4xR<2>();
Error += test_const_structured_mat4xR<2>();
Error += test_structured_mat4xR<3>();
Error += test_const_structured_mat4xR<3>();
Error += test_structured_mat4xR<4>();
Error += test_const_structured_mat4xR<4>();
#endif
#endif
return Error;
}
+23
View File
@@ -0,0 +1,23 @@
#include <glm/vec2.hpp>
#define GLM_ENABLE_EXPERIMENTAL
#include <glm/gtx/texture.hpp>
static int test_levels()
{
int Error = 0;
int const Levels = glm::levels(glm::ivec2(3, 2));
Error += Levels == 2 ? 0 : 1;
return Error;
}
int main()
{
int Error = 0;
Error += test_levels();
return Error;
}
+135
View File
@@ -0,0 +1,135 @@
#include <glm/glm.hpp>
#include <glm/gtc/epsilon.hpp>
#define GLM_ENABLE_EXPERIMENTAL
#include <glm/gtx/transform2.hpp>
static int test_reflect2D()
{
int Error = 0;
{
const glm::mat3 m3(
1, 0, 0,
0, 1, 0,
1, 2, 1
);
const glm::mat3 eam3(
1, 0, 0,
0, -1, 0,
1, 2, 1
);
const glm::mat3 am3 = glm::reflect2D(
m3,
glm::vec2(0, 1),
static_cast<glm::mat3::row_type::value_type>(0)
);
Error += glm::all(glm::bvec3(
glm::all(glm::epsilonEqual(eam3[0], am3[0], glm::epsilon<float>())),
glm::all(glm::epsilonEqual(eam3[1], am3[1], glm::epsilon<float>())),
glm::all(glm::epsilonEqual(eam3[2], am3[2], glm::epsilon<float>())))) ? 0 : 1;
}
{
const glm::mat3 m3(
1, 0, 0,
0, 1, 0,
1, 2, 1
);
const glm::mat3 eam3(
0, 1, 0,
1, 0, 0,
1, 2, 1
);
const glm::mat3 am3 = glm::reflect2D(
m3,
glm::vec2(-0.70710678, 0.70710678),
static_cast<glm::mat3::row_type::value_type>(0)
);
Error += glm::all(glm::bvec3(
glm::all(glm::epsilonEqual(eam3[0], am3[0], glm::epsilon<float>())),
glm::all(glm::epsilonEqual(eam3[1], am3[1], glm::epsilon<float>())),
glm::all(glm::epsilonEqual(eam3[2], am3[2], glm::epsilon<float>())))) ? 0 : 1;
}
return Error;
}
static int test_reflect3D()
{
int Error = 0;
{
const glm::mat4 m4(
1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1
);
const glm::mat4 eam4(
1, 0, 0, 0,
0, -1, 0, 0,
0, 0, 1, 0,
0, -2, 0, 1
);
const glm::mat4 am4 = glm::reflect3D(
m4,
glm::vec3(0, 1, 0),
static_cast<glm::mat4::row_type::value_type>(1)
);
Error += glm::all(glm::bvec4(
glm::all(glm::epsilonEqual(eam4[0], am4[0], glm::epsilon<float>())),
glm::all(glm::epsilonEqual(eam4[1], am4[1], glm::epsilon<float>())),
glm::all(glm::epsilonEqual(eam4[2], am4[2], glm::epsilon<float>())),
glm::all(glm::epsilonEqual(eam4[3], am4[3], glm::epsilon<float>())))) ? 0 : 1;
}
{
const glm::mat4 m4(
1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1
);
const glm::mat4 eam4(
0, 1, 0, 0,
1, 0, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1
);
const glm::mat4 am4 = glm::reflect3D(
m4,
glm::vec3(-0.70710678, 0.70710678, 0.0),
static_cast<glm::mat4::row_type::value_type>(0)
);
Error += glm::all(glm::bvec4(
glm::all(glm::epsilonEqual(eam4[0], am4[0], glm::epsilon<float>())),
glm::all(glm::epsilonEqual(eam4[1], am4[1], glm::epsilon<float>())),
glm::all(glm::epsilonEqual(eam4[2], am4[2], glm::epsilon<float>())),
glm::all(glm::epsilonEqual(eam4[3], am4[3], glm::epsilon<float>())))) ? 0 : 1;
}
return Error;
}
int main()
{
int Error = 0;
Error += test_reflect2D();
Error += test_reflect3D();
return Error;
}
+150
View File
@@ -0,0 +1,150 @@
#define GLM_ENABLE_EXPERIMENTAL
#include <glm/gtx/type_aligned.hpp>
#include <cstdio>
#if GLM_COMPILER & GLM_COMPILER_CLANG
# pragma clang diagnostic push
# pragma clang diagnostic ignored "-Wpadded"
#endif
static int test_decl()
{
int Error(0);
{
struct S1
{
glm::aligned_vec4 B;
};
struct S2
{
glm::vec4 B;
};
std::printf("vec4 - Aligned: %d, unaligned: %d\n", static_cast<int>(sizeof(S1)), static_cast<int>(sizeof(S2)));
Error += sizeof(S1) >= sizeof(S2) ? 0 : 1;
}
{
struct S1
{
bool A;
glm::vec3 B;
};
# if GLM_COMPILER & GLM_COMPILER_VC
# pragma warning(push)
# pragma warning(disable : 4324)
# endif
struct S2
{
bool A;
glm::aligned_vec3 B;
};
# if GLM_COMPILER & GLM_COMPILER_VC
# pragma warning(pop)
# endif
std::printf("vec3 - Aligned: %d, unaligned: %d\n", static_cast<int>(sizeof(S1)), static_cast<int>(sizeof(S2)));
Error += sizeof(S1) <= sizeof(S2) ? 0 : 1;
}
{
# if GLM_COMPILER & GLM_COMPILER_VC
# pragma warning(push)
# pragma warning(disable : 4324)
# endif
struct S1
{
bool A;
glm::aligned_vec4 B;
};
# if GLM_COMPILER & GLM_COMPILER_VC
# pragma warning(pop)
# endif
struct S2
{
bool A;
glm::vec4 B;
};
std::printf("vec4 - Aligned: %d, unaligned: %d\n", static_cast<int>(sizeof(S1)), static_cast<int>(sizeof(S2)));
Error += sizeof(S1) >= sizeof(S2) ? 0 : 1;
}
{
# if GLM_COMPILER & GLM_COMPILER_VC
# pragma warning(push)
# pragma warning(disable : 4324)
# endif
struct S1
{
bool A;
glm::aligned_dvec4 B;
};
# if GLM_COMPILER & GLM_COMPILER_VC
# pragma warning(pop)
# endif
struct S2
{
bool A;
glm::dvec4 B;
};
std::printf("dvec4 - Aligned: %d, unaligned: %d\n", static_cast<int>(sizeof(S1)), static_cast<int>(sizeof(S2)));
Error += sizeof(S1) >= sizeof(S2) ? 0 : 1;
}
return Error;
}
template<typename genType>
static void print(genType const& Mat0)
{
std::printf("mat4(\n");
std::printf("\tvec4(%2.9f, %2.9f, %2.9f, %2.9f)\n", static_cast<double>(Mat0[0][0]), static_cast<double>(Mat0[0][1]), static_cast<double>(Mat0[0][2]), static_cast<double>(Mat0[0][3]));
std::printf("\tvec4(%2.9f, %2.9f, %2.9f, %2.9f)\n", static_cast<double>(Mat0[1][0]), static_cast<double>(Mat0[1][1]), static_cast<double>(Mat0[1][2]), static_cast<double>(Mat0[1][3]));
std::printf("\tvec4(%2.9f, %2.9f, %2.9f, %2.9f)\n", static_cast<double>(Mat0[2][0]), static_cast<double>(Mat0[2][1]), static_cast<double>(Mat0[2][2]), static_cast<double>(Mat0[2][3]));
std::printf("\tvec4(%2.9f, %2.9f, %2.9f, %2.9f))\n\n", static_cast<double>(Mat0[3][0]), static_cast<double>(Mat0[3][1]), static_cast<double>(Mat0[3][2]), static_cast<double>(Mat0[3][3]));
}
static int perf_mul()
{
int Error = 0;
glm::mat4 A(1.0f);
glm::mat4 B(1.0f);
glm::mat4 C = A * B;
print(C);
return Error;
}
#if GLM_COMPILER & GLM_COMPILER_CLANG
# pragma clang diagnostic pop
#endif
int main()
{
int Error(0);
Error += test_decl();
Error += perf_mul();
return Error;
}
+11
View File
@@ -0,0 +1,11 @@
#define GLM_ENABLE_EXPERIMENTAL
#include <glm/vec4.hpp>
#include <glm/gtx/type_trait.hpp>
int main()
{
int Error = 0;
return Error;
}
+11
View File
@@ -0,0 +1,11 @@
#define GLM_ENABLE_EXPERIMENTAL
#include <glm/gtx/vec_swizzle.hpp>
int main()
{
int Error = 0;
return Error;
}
+59
View File
@@ -0,0 +1,59 @@
#define GLM_ENABLE_EXPERIMENTAL
#include <glm/gtc/constants.hpp>
#include <glm/gtx/vector_angle.hpp>
#include <limits>
static int test_angle()
{
int Error = 0;
float AngleA = glm::angle(glm::vec2(1, 0), glm::normalize(glm::vec2(1, 1)));
Error += glm::epsilonEqual(AngleA, glm::pi<float>() * 0.25f, 0.01f) ? 0 : 1;
float AngleB = glm::angle(glm::vec3(1, 0, 0), glm::normalize(glm::vec3(1, 1, 0)));
Error += glm::epsilonEqual(AngleB, glm::pi<float>() * 0.25f, 0.01f) ? 0 : 1;
float AngleC = glm::angle(glm::vec4(1, 0, 0, 0), glm::normalize(glm::vec4(1, 1, 0, 0)));
Error += glm::epsilonEqual(AngleC, glm::pi<float>() * 0.25f, 0.01f) ? 0 : 1;
return Error;
}
static int test_orientedAngle_vec2()
{
int Error = 0;
float AngleA = glm::orientedAngle(glm::vec2(1, 0), glm::normalize(glm::vec2(1, 1)));
Error += glm::epsilonEqual(AngleA, glm::pi<float>() * 0.25f, 0.01f) ? 0 : 1;
float AngleB = glm::orientedAngle(glm::vec2(0, 1), glm::normalize(glm::vec2(1, 1)));
Error += glm::epsilonEqual(AngleB, -glm::pi<float>() * 0.25f, 0.01f) ? 0 : 1;
float AngleC = glm::orientedAngle(glm::normalize(glm::vec2(1, 1)), glm::vec2(0, 1));
Error += glm::epsilonEqual(AngleC, glm::pi<float>() * 0.25f, 0.01f) ? 0 : 1;
return Error;
}
static int test_orientedAngle_vec3()
{
int Error = 0;
float AngleA = glm::orientedAngle(glm::vec3(1, 0, 0), glm::normalize(glm::vec3(1, 1, 0)), glm::vec3(0, 0, 1));
Error += glm::epsilonEqual(AngleA, glm::pi<float>() * 0.25f, 0.01f) ? 0 : 1;
float AngleB = glm::orientedAngle(glm::vec3(0, 1, 0), glm::normalize(glm::vec3(1, 1, 0)), glm::vec3(0, 0, 1));
Error += glm::epsilonEqual(AngleB, -glm::pi<float>() * 0.25f, 0.01f) ? 0 : 1;
float AngleC = glm::orientedAngle(glm::normalize(glm::vec3(1, 1, 0)), glm::vec3(0, 1, 0), glm::vec3(0, 0, 1));
Error += glm::epsilonEqual(AngleC, glm::pi<float>() * 0.25f, 0.01f) ? 0 : 1;
return Error;
}
int main()
{
int Error(0);
Error += test_angle();
Error += test_orientedAngle_vec2();
Error += test_orientedAngle_vec3();
return Error;
}
+82
View File
@@ -0,0 +1,82 @@
#define GLM_ENABLE_EXPERIMENTAL
#include <glm/vec2.hpp>
#include <glm/vec3.hpp>
#include <glm/vec4.hpp>
#include <glm/gtx/vector_query.hpp>
static int test_areCollinear()
{
int Error(0);
{
bool TestA = glm::areCollinear(glm::vec2(-1), glm::vec2(1), 0.00001f);
Error += TestA ? 0 : 1;
}
{
bool TestA = glm::areCollinear(glm::vec3(-1), glm::vec3(1), 0.00001f);
Error += TestA ? 0 : 1;
}
{
bool TestA = glm::areCollinear(glm::vec4(-1), glm::vec4(1), 0.00001f);
Error += TestA ? 0 : 1;
}
return Error;
}
static int test_areOrthogonal()
{
int Error(0);
bool TestA = glm::areOrthogonal(glm::vec2(1, 0), glm::vec2(0, 1), 0.00001f);
Error += TestA ? 0 : 1;
return Error;
}
static int test_isNormalized()
{
int Error(0);
bool TestA = glm::isNormalized(glm::vec4(1, 0, 0, 0), 0.00001f);
Error += TestA ? 0 : 1;
return Error;
}
static int test_isNull()
{
int Error(0);
bool TestA = glm::isNull(glm::vec4(0), 0.00001f);
Error += TestA ? 0 : 1;
return Error;
}
static int test_areOrthonormal()
{
int Error(0);
bool TestA = glm::areOrthonormal(glm::vec2(1, 0), glm::vec2(0, 1), 0.00001f);
Error += TestA ? 0 : 1;
return Error;
}
int main()
{
int Error(0);
Error += test_areCollinear();
Error += test_areOrthogonal();
Error += test_isNormalized();
Error += test_isNull();
Error += test_areOrthonormal();
return Error;
}
+191
View File
@@ -0,0 +1,191 @@
#define GLM_ENABLE_EXPERIMENTAL
#include <glm/gtx/wrap.hpp>
#include <glm/ext/scalar_relational.hpp>
#include <glm/ext/vector_relational.hpp>
namespace clamp
{
static int test()
{
int Error(0);
float A = glm::clamp(0.5f);
Error += glm::equal(A, 0.5f, 0.00001f) ? 0 : 1;
float B = glm::clamp(0.0f);
Error += glm::equal(B, 0.0f, 0.00001f) ? 0 : 1;
float C = glm::clamp(1.0f);
Error += glm::equal(C, 1.0f, 0.00001f) ? 0 : 1;
float D = glm::clamp(-0.5f);
Error += glm::equal(D, 0.0f, 0.00001f) ? 0 : 1;
float E = glm::clamp(1.5f);
Error += glm::equal(E, 1.0f, 0.00001f) ? 0 : 1;
glm::vec2 K = glm::clamp(glm::vec2(0.5f));
Error += glm::all(glm::equal(K, glm::vec2(0.5f), glm::vec2(0.00001f))) ? 0 : 1;
glm::vec3 L = glm::clamp(glm::vec3(0.5f));
Error += glm::all(glm::equal(L, glm::vec3(0.5f), glm::vec3(0.00001f))) ? 0 : 1;
glm::vec4 M = glm::clamp(glm::vec4(0.5f));
Error += glm::all(glm::equal(M, glm::vec4(0.5f), glm::vec4(0.00001f))) ? 0 : 1;
glm::vec1 N = glm::clamp(glm::vec1(0.5f));
Error += glm::all(glm::equal(N, glm::vec1(0.5f), glm::vec1(0.00001f))) ? 0 : 1;
return Error;
}
}//namespace clamp
namespace repeat
{
static int test()
{
int Error(0);
float A = glm::repeat(0.5f);
Error += glm::equal(A, 0.5f, 0.00001f) ? 0 : 1;
float B = glm::repeat(0.0f);
Error += glm::equal(B, 0.0f, 0.00001f) ? 0 : 1;
float C = glm::repeat(1.0f);
Error += glm::equal(C, 0.0f, 0.00001f) ? 0 : 1;
float D = glm::repeat(-0.5f);
Error += glm::equal(D, 0.5f, 0.00001f) ? 0 : 1;
float E = glm::repeat(1.5f);
Error += glm::equal(E, 0.5f, 0.00001f) ? 0 : 1;
float F = glm::repeat(0.9f);
Error += glm::equal(F, 0.9f, 0.00001f) ? 0 : 1;
glm::vec2 K = glm::repeat(glm::vec2(0.5f));
Error += glm::all(glm::equal(K, glm::vec2(0.5f), glm::vec2(0.00001f))) ? 0 : 1;
glm::vec3 L = glm::repeat(glm::vec3(0.5f));
Error += glm::all(glm::equal(L, glm::vec3(0.5f), glm::vec3(0.00001f))) ? 0 : 1;
glm::vec4 M = glm::repeat(glm::vec4(0.5f));
Error += glm::all(glm::equal(M, glm::vec4(0.5f), glm::vec4(0.00001f))) ? 0 : 1;
glm::vec1 N = glm::repeat(glm::vec1(0.5f));
Error += glm::all(glm::equal(N, glm::vec1(0.5f), glm::vec1(0.00001f))) ? 0 : 1;
return Error;
}
}//namespace repeat
namespace mirrorClamp
{
static int test()
{
int Error(0);
float A = glm::mirrorClamp(0.5f);
Error += glm::equal(A, 0.5f, 0.00001f) ? 0 : 1;
float B = glm::mirrorClamp(0.0f);
Error += glm::equal(B, 0.0f, 0.00001f) ? 0 : 1;
float C = glm::mirrorClamp(1.1f);
Error += glm::equal(C, 0.1f, 0.00001f) ? 0 : 1;
float D = glm::mirrorClamp(-0.5f);
Error += glm::equal(D, 0.5f, 0.00001f) ? 0 : 1;
float E = glm::mirrorClamp(1.5f);
Error += glm::equal(E, 0.5f, 0.00001f) ? 0 : 1;
float F = glm::mirrorClamp(0.9f);
Error += glm::equal(F, 0.9f, 0.00001f) ? 0 : 1;
float G = glm::mirrorClamp(3.1f);
Error += glm::equal(G, 0.1f, 0.00001f) ? 0 : 1;
float H = glm::mirrorClamp(-3.1f);
Error += glm::equal(H, 0.1f, 0.00001f) ? 0 : 1;
float I = glm::mirrorClamp(-0.9f);
Error += glm::equal(I, 0.9f, 0.00001f) ? 0 : 1;
glm::vec2 K = glm::mirrorClamp(glm::vec2(0.5f));
Error += glm::all(glm::equal(K, glm::vec2(0.5f), glm::vec2(0.00001f))) ? 0 : 1;
glm::vec3 L = glm::mirrorClamp(glm::vec3(0.5f));
Error += glm::all(glm::equal(L, glm::vec3(0.5f), glm::vec3(0.00001f))) ? 0 : 1;
glm::vec4 M = glm::mirrorClamp(glm::vec4(0.5f));
Error += glm::all(glm::equal(M, glm::vec4(0.5f), glm::vec4(0.00001f))) ? 0 : 1;
glm::vec1 N = glm::mirrorClamp(glm::vec1(0.5f));
Error += glm::all(glm::equal(N, glm::vec1(0.5f), glm::vec1(0.00001f))) ? 0 : 1;
return Error;
}
}//namespace mirrorClamp
namespace mirrorRepeat
{
static int test()
{
int Error(0);
float A = glm::mirrorRepeat(0.5f);
Error += glm::equal(A, 0.5f, 0.00001f) ? 0 : 1;
float B = glm::mirrorRepeat(0.0f);
Error += glm::equal(B, 0.0f, 0.00001f) ? 0 : 1;
float C = glm::mirrorRepeat(1.0f);
Error += glm::equal(C, 1.0f, 0.00001f) ? 0 : 1;
float D = glm::mirrorRepeat(-0.5f);
Error += glm::equal(D, 0.5f, 0.00001f) ? 0 : 1;
float E = glm::mirrorRepeat(1.5f);
Error += glm::equal(E, 0.5f, 0.00001f) ? 0 : 1;
float F = glm::mirrorRepeat(0.9f);
Error += glm::equal(F, 0.9f, 0.00001f) ? 0 : 1;
float G = glm::mirrorRepeat(3.0f);
Error += glm::equal(G, 1.0f, 0.00001f) ? 0 : 1;
float H = glm::mirrorRepeat(-3.0f);
Error += glm::equal(H, 1.0f, 0.00001f) ? 0 : 1;
float I = glm::mirrorRepeat(-1.0f);
Error += glm::equal(I, 1.0f, 0.00001f) ? 0 : 1;
glm::vec2 K = glm::mirrorRepeat(glm::vec2(0.5f));
Error += glm::all(glm::equal(K, glm::vec2(0.5f), glm::vec2(0.00001f))) ? 0 : 1;
glm::vec3 L = glm::mirrorRepeat(glm::vec3(0.5f));
Error += glm::all(glm::equal(L, glm::vec3(0.5f), glm::vec3(0.00001f))) ? 0 : 1;
glm::vec4 M = glm::mirrorRepeat(glm::vec4(0.5f));
Error += glm::all(glm::equal(M, glm::vec4(0.5f), glm::vec4(0.00001f))) ? 0 : 1;
glm::vec1 N = glm::mirrorRepeat(glm::vec1(0.5f));
Error += glm::all(glm::equal(N, glm::vec1(0.5f), glm::vec1(0.00001f))) ? 0 : 1;
return Error;
}
}//namespace mirrorRepeat
int main()
{
int Error(0);
Error += clamp::test();
Error += repeat::test();
Error += mirrorClamp::test();
Error += mirrorRepeat::test();
return Error;
}