more tests
This commit is contained in:
parent
e0f992aada
commit
cc2c13f7a5
3 changed files with 393 additions and 307 deletions
196
tests/Vector.cpp
196
tests/Vector.cpp
|
|
@ -36,6 +36,15 @@ consteval std::array<bool, Len> AlternateTrueFalse() {
|
|||
return result;
|
||||
}
|
||||
|
||||
template <std::uint8_t Len>
|
||||
consteval std::array<std::uint8_t, Len> GetCountReverse() {
|
||||
std::array<std::uint8_t, Len> result = {};
|
||||
for (std::uint8_t i = 0; i < Len; ++i) {
|
||||
result[Len - 1 - i] = i;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename T, template<std::uint32_t, std::uint32_t> class VectorType, std::uint32_t MaxSize, std::uint32_t Len = 1, std::uint32_t Packing = 1>
|
||||
std::string* TestAllCombinations() {
|
||||
if constexpr (Len > MaxSize) {
|
||||
|
|
@ -59,6 +68,13 @@ std::string* TestAllCombinations() {
|
|||
floats1[i] = 0;
|
||||
floats2[i] = 0;
|
||||
}
|
||||
T expectedLength[Packing] = {0};
|
||||
for (std::uint32_t i2 = 0; i2 < Packing; i2++) {
|
||||
for (std::uint32_t i = 0; i < Len; i++) {
|
||||
expectedLength[i2] += floats[i2*Len+i] * floats[i2*Len+i];
|
||||
}
|
||||
expectedLength[i2] = T(std::sqrt(float(expectedLength[i2])));
|
||||
}
|
||||
|
||||
std::string* result = nullptr;
|
||||
constexpr auto total = Len * Packing;
|
||||
|
|
@ -304,113 +320,97 @@ std::string* TestAllCombinations() {
|
|||
return new std::string(std::format("Normalize mismatch at Len={} Packing={}, Expected: {}, Got: {}", Len, Packing, 1, (float)length));
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
VectorType<Len, Packing> vec(floats);
|
||||
VectorType<Len, Packing> result = vec.template Shuffle<GetCountReverse<Len>()>();
|
||||
Vector<T, Len*Packing, VectorType<Len, Packing>::Alignment> stored = result.Store();
|
||||
for (std::uint32_t i = 0; i < Len; i++) {
|
||||
T expected = floats[Len - 1 - i];
|
||||
if (!FloatEquals(stored.v[i], expected)) {
|
||||
return new std::string(std::format("Shuffle mismatch at Len={} Packing={}, Index={}, Expected: {}, Got: {}", Len, Packing, i, (float)expected, (float)stored.v[i]));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// if constexpr(Len == 3) {
|
||||
// {
|
||||
// VectorType<Len, Packing> vec1(floats1);
|
||||
// VectorType<Len, Packing> vec2(floats2);
|
||||
// VectorType<Len, Packing> result = VectorType<Len, Packing>::Cross(vec1, vec2);
|
||||
// Vector<T, Len*Packing, VectorType<Len, Packing>::Alignment> stored = result.Store();
|
||||
// if (!FloatEquals(stored.v[0], T(-3)) || !FloatEquals(stored.v[1], T(6)) || !FloatEquals(stored.v[2], T(-3))) {
|
||||
// return new std::string(std::format("Cross mismatch at Len={} Packing={}, Expected: -3,6,-3, Got: {},{},{}", Len, Packing, (float)stored.v[0], (float)stored.v[1], (float)stored.v[2]));
|
||||
// }
|
||||
// }
|
||||
// // if constexpr(4 * Packing < VectorType<1, 1>::MaxSize) {
|
||||
// // T qData[VectorType<4, Packing>::Alignment];
|
||||
// // qData[0] = T(1);
|
||||
// // qData[1] = T(0);
|
||||
// // qData[2] = T(0);
|
||||
// // qData[3] = T(0);
|
||||
if constexpr(Len == 3) {
|
||||
{
|
||||
VectorType<Len, Packing> vec1(floats1);
|
||||
VectorType<Len, Packing> vec2(floats2);
|
||||
VectorType<Len, Packing> result = VectorType<Len, Packing>::Cross(vec1, vec2);
|
||||
Vector<T, Len*Packing, VectorType<Len, Packing>::Alignment> stored = result.Store();
|
||||
if (!FloatEquals(stored.v[0], T(-3)) || !FloatEquals(stored.v[1], T(6)) || !FloatEquals(stored.v[2], T(-3))) {
|
||||
return new std::string(std::format("Cross mismatch at Len={} Packing={}, Expected: -3,6,-3, Got: {},{},{}", Len, Packing, (float)stored.v[0], (float)stored.v[1], (float)stored.v[2]));
|
||||
}
|
||||
}
|
||||
if constexpr(4 * Packing < VectorType<1, 1>::MaxSize) {
|
||||
T qData[VectorType<4, Packing>::Alignment];
|
||||
qData[0] = T(0);
|
||||
qData[1] = T(0);
|
||||
qData[2] = T(0);
|
||||
qData[3] = T(1);
|
||||
|
||||
// // VectorType<3, Packing> vecV(floats);
|
||||
// // VectorType<4, Packing> vecQ(qData);
|
||||
// // VectorType<3, Packing> result = VectorType<3, Packing>::Rotate(vecV, vecQ);
|
||||
// // Vector<T, 3*Packing, VectorType<3, Packing>::Alignment> stored = result.Store();
|
||||
VectorType<3, Packing> vecV(floats);
|
||||
VectorType<4, Packing> vecQ(qData);
|
||||
VectorType<3, Packing> result = VectorType<3, Packing>::Rotate(vecV, vecQ);
|
||||
Vector<T, 3*Packing, VectorType<3, Packing>::Alignment> stored = result.Store();
|
||||
|
||||
// // for (std::uint32_t i = 0; i < 3; i++) {
|
||||
// // if (!FloatEquals(stored.v[i], floats[i])) {
|
||||
// // return new std::string(std::format("Rotate mismatch at Len={} Packing={}, Index={}, Expected: {}, Got: {}", Len, Packing, i, (float)floats[i], (float)stored.v[i]));
|
||||
// // }
|
||||
// // }
|
||||
// // }
|
||||
// }
|
||||
for (std::uint32_t i = 0; i < 3; i++) {
|
||||
if (!FloatEquals(stored.v[i], floats[i])) {
|
||||
return new std::string(std::format("Rotate mismatch at Len={} Packing={}, Index={}, Expected: {}, Got: {}", Len, Packing, i, (float)floats[i], (float)stored.v[i]));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if constexpr(Len == 4) {
|
||||
T eulerData[VectorType<3, Packing>::Alignment];
|
||||
for(std::uint8_t i = 0; i < Packing; i++) {
|
||||
eulerData[i*3] = T(0.7853981);
|
||||
eulerData[i*3+1] = T(0.1243412);
|
||||
eulerData[i*3+2] = T(0.3245312);
|
||||
}
|
||||
VectorType<3, Packing> eulerVec(eulerData);
|
||||
VectorType<4, Packing> result = VectorType<4, Packing>::QuanternionFromEuler(eulerVec);
|
||||
Vector<T, 4*Packing, VectorType<4, Packing>::Alignment> stored = result.Store();
|
||||
|
||||
// // Test QuanternionFromEuler() static method (Len == 4 only)
|
||||
// if constexpr(Len == 4) {
|
||||
// T eulerData[3] = {T(0), T(0), T(0)}; // Zero rotation
|
||||
// VectorType<3, 1> eulerVec(eulerData);
|
||||
// VectorType<4, 1> result = VectorType<4, 1>::QuanternionFromEuler(eulerVec);
|
||||
// Vector<T, 4, 8> stored = result.Store();
|
||||
|
||||
// // Identity quaternion should be (1, 0, 0, 0)
|
||||
// if (!FloatEquals(stored.v[0], T(1)) || !FloatEquals(stored.v[1], T(0)) ||
|
||||
// !FloatEquals(stored.v[2], T(0)) || !FloatEquals(stored.v[3], T(0))) {
|
||||
// return new std::string(std::format("QuanternionFromEuler mismatch at Len={} Packing={}, Expected: 1,0,0,0, Got: {},{},{},{}", Len, Packing, (float)stored.v[0], (float)stored.v[1], (float)stored.v[2], (float)stored.v[3]));
|
||||
// }
|
||||
// }
|
||||
if (!FloatEquals(stored.v[0], T(0.63720703)) || !FloatEquals(stored.v[1], T(0.30688477)) ||
|
||||
!FloatEquals(stored.v[2], T(0.14074707)) || !FloatEquals(stored.v[3], T(0.6933594))) {
|
||||
return new std::string(std::format("QuanternionFromEuler mismatch at Len={} Packing={}, Expected: 0.63720703,0.30688477,0.14074707,0.6933594, Got: {},{},{},{}", Len, Packing, (float)stored.v[0], (float)stored.v[1], (float)stored.v[2], (float)stored.v[3]));
|
||||
}
|
||||
}
|
||||
|
||||
// // Test batch Normalize() for 2 vectors (Len == 2)
|
||||
// if constexpr(Len == 2) {
|
||||
// T aData[2] = {T(3), T(4)};
|
||||
// T eData[2] = {T(6), T(8)};
|
||||
// VectorType<2, 1> vecA(aData);
|
||||
// VectorType<2, 1> vecE(eData);
|
||||
// auto result = VectorType<2, 1>::Normalize(vecA, vecE);
|
||||
// Vector<T, 2, 8> storedA = std::get<0>(result).Store();
|
||||
// Vector<T, 2, 8> storedE = std::get<1>(result).Store();
|
||||
|
||||
// // Normalize (3,4) -> (0.6, 0.8)
|
||||
// for (std::uint32_t i = 0; i < 2; i++) {
|
||||
// if (!FloatEquals(storedA.v[i], static_cast<T>(0.6f + i * 0.2f))) {
|
||||
// return new std::string(std::format("Normalize 2 vec test failed (A) at index {}, Expected: {}, Got: {}", i, (float)(0.6f + i * 0.2f), (float)storedA.v[i]));
|
||||
// }
|
||||
// }
|
||||
|
||||
// // Normalize (6,8) -> (0.6, 0.8)
|
||||
// for (std::uint32_t i = 0; i < 2; i++) {
|
||||
// if (!FloatEquals(storedE.v[i], static_cast<T>(0.6f + i * 0.2f))) {
|
||||
// return new std::string(std::format("Normalize 2 vec test failed (E) at index {}, Expected: {}, Got: {}", i, (float)(0.6f + i * 0.2f), (float)storedE.v[i]));
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
if constexpr(Len == 2 && Packing*Len == VectorType<Len, Packing>::Alignment) {
|
||||
{
|
||||
VectorType<Len, Packing> vecA(floats);
|
||||
VectorType<Len, Packing> vecE = vecA *2;
|
||||
VectorType<1, Packing*2> result = VectorType<Len, Packing>::Length(vecA, vecE);
|
||||
Vector<T, Packing*2, VectorType<Len, Packing>::Alignment> stored = result.Store();
|
||||
|
||||
// // Test batch LengthSq() for 2 vectors (Len == 2)
|
||||
// if constexpr(Len == 2) {
|
||||
// T aData[2] = {T(3), T(4)};
|
||||
// T eData[2] = {T(5), T(12)};
|
||||
// VectorType<2, 1> vecA(aData);
|
||||
// VectorType<2, 1> vecE(eData);
|
||||
// VectorType<2, 1> result = VectorType<2, 1>::LengthSq(vecA, vecE);
|
||||
// Vector<T, 2, 8> stored = result.Store();
|
||||
|
||||
// // LengthSq of (3,4) = 9+16 = 25
|
||||
// // LengthSq of (5,12) = 25+144 = 169
|
||||
// if (!FloatEquals(stored.v[0], T(25)) || !FloatEquals(stored.v[1], T(169))) {
|
||||
// return new std::string(std::format("LengthSq 2 vec test failed at Len={} Packing={}, Expected: 25,169, Got: {},{}", Len, Packing, (float)stored.v[0], (float)stored.v[1]));
|
||||
// }
|
||||
// }
|
||||
if (!FloatEquals(stored.v[0], expectedLength[0])) {
|
||||
return new std::string(std::format("Length 2 vecA test failed at Len={} Packing={} Expected: {}, Got: {}", Len, Packing, (float)expectedLength[0], (float)stored.v[0]));
|
||||
}
|
||||
|
||||
if (!FloatEquals(stored.v[(Len*Packing)/2], expectedLength[0] * 2)) {
|
||||
return new std::string(std::format("Length 2 vecE test failed at Len={} Packing={} Expected: {}, Got: {}", Len, Packing, (float)expectedLength[0] * 2, (float)stored.v[(Len*Packing)/2]));
|
||||
}
|
||||
}
|
||||
|
||||
// // Test batch Dot() for 2 vectors (Len == 2)
|
||||
// if constexpr(Len == 2) {
|
||||
// T a0Data[2] = {T(1), T(2)};
|
||||
// T a1Data[2] = {T(3), T(4)};
|
||||
// T e0Data[2] = {T(5), T(6)};
|
||||
// T e1Data[2] = {T(7), T(8)};
|
||||
// VectorType<2, 1> vecA0(a0Data);
|
||||
// VectorType<2, 1> vecA1(a1Data);
|
||||
// VectorType<2, 1> vecE0(e0Data);
|
||||
// VectorType<2, 1> vecE1(e1Data);
|
||||
// VectorType<2, 1> result = VectorType<2, 1>::Dot(vecA0, vecA1, vecE0, vecE1);
|
||||
// Vector<T, 2, 8> stored = result.Store();
|
||||
|
||||
// // Dot (1,2) with (3,4) = 3+8=11
|
||||
// // Dot (5,6) with (7,8) = 35+48=83
|
||||
// if (!FloatEquals(stored.v[0], T(11)) || !FloatEquals(stored.v[1], T(83))) {
|
||||
// return new std::string(std::format("Dot 2 vec test failed at Len={} Packing={}, Expected: 11,83, Got: {},{}", Len, Packing, (float)stored.v[0], (float)stored.v[1]));
|
||||
// }
|
||||
// }
|
||||
{
|
||||
VectorType<Len, Packing> vecA(floats);
|
||||
VectorType<Len, Packing> vecE = vecA * 2;
|
||||
auto result = VectorType<Len, Packing>::Normalize(vecA, vecE);
|
||||
VectorType<1, Packing*2> result2 = VectorType<Len, Packing>::Length(std::get<0>(result), std::get<1>(result));
|
||||
Vector<T, Packing*2, VectorType<Len, Packing>::Alignment> stored = result2.Store();
|
||||
|
||||
for(std::uint8_t i = 0; i < Len*Packing; i++) {
|
||||
if (!FloatEquals(stored.v[i], T(1))) {
|
||||
return new std::string(std::format("Normalize {} test failed at Len={} Packing={} Expected: {}, Got: {}", i, Len, Packing, 1, (float)stored.v[i]));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return TestAllCombinations<T, VectorType, MaxSize, Len, Packing + 1>();
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue