mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-07-18 00:49:19 +02:00
Remove dumb3d
This commit is contained in:
@@ -104,7 +104,6 @@ set(SOURCES
|
|||||||
"vehicle/Camera.cpp"
|
"vehicle/Camera.cpp"
|
||||||
"vehicle/Driver.cpp"
|
"vehicle/Driver.cpp"
|
||||||
"application/driverhints.cpp"
|
"application/driverhints.cpp"
|
||||||
"utilities/dumb3d.cpp"
|
|
||||||
"vehicle/DynObj.cpp"
|
"vehicle/DynObj.cpp"
|
||||||
"EU07.cpp"
|
"EU07.cpp"
|
||||||
"export_e3d_standalone.cpp"
|
"export_e3d_standalone.cpp"
|
||||||
|
|||||||
@@ -78,7 +78,6 @@ zwiekszenie nacisku przy duzych predkosciach w hamulcach Oerlikona
|
|||||||
...
|
...
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "utilities/dumb3d.h"
|
|
||||||
#include "utilities/utilities.h"
|
#include "utilities/utilities.h"
|
||||||
|
|
||||||
extern int ConversionError;
|
extern int ConversionError;
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ http://mozilla.org/MPL/2.0/.
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "utilities/Float3d.h"
|
#include "utilities/Float3d.h"
|
||||||
#include "utilities/dumb3d.h"
|
|
||||||
|
|
||||||
inline std::vector<glm::vec4> const ndcfrustumshapepoints //
|
inline std::vector<glm::vec4> const ndcfrustumshapepoints //
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,430 +0,0 @@
|
|||||||
/*
|
|
||||||
This Source Code Form is subject to the
|
|
||||||
terms of the Mozilla Public License, v.
|
|
||||||
2.0. If a copy of the MPL was not
|
|
||||||
distributed with this file, You can
|
|
||||||
obtain one at
|
|
||||||
http://mozilla.org/MPL/2.0/.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "stdafx.h"
|
|
||||||
#include "utilities/dumb3d.h"
|
|
||||||
#include <cassert>
|
|
||||||
|
|
||||||
namespace Math3D
|
|
||||||
{
|
|
||||||
|
|
||||||
void vector3::RotateX(double angle)
|
|
||||||
{
|
|
||||||
double ty = y;
|
|
||||||
y = (cos(angle) * y - z * sin(angle));
|
|
||||||
z = (z * cos(angle) + sin(angle) * ty);
|
|
||||||
};
|
|
||||||
void vector3::RotateY(double angle)
|
|
||||||
{
|
|
||||||
double tx = x;
|
|
||||||
x = (cos(angle) * x + z * sin(angle));
|
|
||||||
z = (z * cos(angle) - sin(angle) * tx);
|
|
||||||
};
|
|
||||||
|
|
||||||
glm::vec3 RotateY(glm::vec3 v, float angle)
|
|
||||||
{
|
|
||||||
float s = sin(angle);
|
|
||||||
float c = cos(angle);
|
|
||||||
|
|
||||||
return glm::vec3(c * v.x + s * v.z, v.y, c * v.z - s * v.x);
|
|
||||||
}
|
|
||||||
glm::dvec3 RotateY(glm::dvec3 v, double angle)
|
|
||||||
{
|
|
||||||
double s = sin(angle);
|
|
||||||
double c = cos(angle);
|
|
||||||
|
|
||||||
return glm::vec3(c * v.x + s * v.z, v.y, c * v.z - s * v.x);
|
|
||||||
}
|
|
||||||
|
|
||||||
void vector3::RotateZ(double angle)
|
|
||||||
{
|
|
||||||
double ty = y;
|
|
||||||
y = (cos(angle) * y + x * sin(angle));
|
|
||||||
x = (x * cos(angle) - sin(angle) * ty);
|
|
||||||
};
|
|
||||||
|
|
||||||
void inline vector3::SafeNormalize()
|
|
||||||
{
|
|
||||||
double l = Length();
|
|
||||||
if (l == 0)
|
|
||||||
{
|
|
||||||
x = y = z = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
x /= l;
|
|
||||||
y /= l;
|
|
||||||
z /= l;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// From code in Graphics Gems; p. 766
|
|
||||||
inline scalar_t det2x2(scalar_t a, scalar_t b, scalar_t c, scalar_t d)
|
|
||||||
{
|
|
||||||
return a * d - b * c;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline scalar_t det3x3(scalar_t a1, scalar_t a2, scalar_t a3, scalar_t b1, scalar_t b2, scalar_t b3,
|
|
||||||
scalar_t c1, scalar_t c2, scalar_t c3)
|
|
||||||
{
|
|
||||||
return a1 * det2x2(b2, b3, c2, c3) - b1 * det2x2(a2, a3, c2, c3) + c1 * det2x2(a2, a3, b2, b3);
|
|
||||||
}
|
|
||||||
|
|
||||||
scalar_t Determinant(const matrix4x4 &m)
|
|
||||||
{
|
|
||||||
scalar_t a1 = m[0][0];
|
|
||||||
scalar_t a2 = m[1][0];
|
|
||||||
scalar_t a3 = m[2][0];
|
|
||||||
scalar_t a4 = m[3][0];
|
|
||||||
scalar_t b1 = m[0][1];
|
|
||||||
scalar_t b2 = m[1][1];
|
|
||||||
scalar_t b3 = m[2][1];
|
|
||||||
scalar_t b4 = m[3][1];
|
|
||||||
scalar_t c1 = m[0][2];
|
|
||||||
scalar_t c2 = m[1][2];
|
|
||||||
scalar_t c3 = m[2][2];
|
|
||||||
scalar_t c4 = m[3][2];
|
|
||||||
scalar_t d1 = m[0][3];
|
|
||||||
scalar_t d2 = m[1][3];
|
|
||||||
scalar_t d3 = m[2][3];
|
|
||||||
scalar_t d4 = m[3][3];
|
|
||||||
|
|
||||||
return a1 * det3x3(b2, b3, b4, c2, c3, c4, d2, d3, d4) -
|
|
||||||
b1 * det3x3(a2, a3, a4, c2, c3, c4, d2, d3, d4) +
|
|
||||||
c1 * det3x3(a2, a3, a4, b2, b3, b4, d2, d3, d4) -
|
|
||||||
d1 * det3x3(a2, a3, a4, b2, b3, b4, c2, c3, c4);
|
|
||||||
}
|
|
||||||
|
|
||||||
matrix4x4 Adjoint(const matrix4x4 &m)
|
|
||||||
{
|
|
||||||
scalar_t a1 = m[0][0];
|
|
||||||
scalar_t a2 = m[0][1];
|
|
||||||
scalar_t a3 = m[0][2];
|
|
||||||
scalar_t a4 = m[0][3];
|
|
||||||
scalar_t b1 = m[1][0];
|
|
||||||
scalar_t b2 = m[1][1];
|
|
||||||
scalar_t b3 = m[1][2];
|
|
||||||
scalar_t b4 = m[1][3];
|
|
||||||
scalar_t c1 = m[2][0];
|
|
||||||
scalar_t c2 = m[2][1];
|
|
||||||
scalar_t c3 = m[2][2];
|
|
||||||
scalar_t c4 = m[2][3];
|
|
||||||
scalar_t d1 = m[3][0];
|
|
||||||
scalar_t d2 = m[3][1];
|
|
||||||
scalar_t d3 = m[3][2];
|
|
||||||
scalar_t d4 = m[3][3];
|
|
||||||
|
|
||||||
// Adjoint(x,y) = -1^(x+y) * a(y,x)
|
|
||||||
// Where a(i,j) is the 3x3 determinant of m with row i and col j removed
|
|
||||||
matrix4x4 retVal;
|
|
||||||
retVal(0)[0] = det3x3(b2, b3, b4, c2, c3, c4, d2, d3, d4);
|
|
||||||
retVal(0)[1] = -det3x3(a2, a3, a4, c2, c3, c4, d2, d3, d4);
|
|
||||||
retVal(0)[2] = det3x3(a2, a3, a4, b2, b3, b4, d2, d3, d4);
|
|
||||||
retVal(0)[3] = -det3x3(a2, a3, a4, b2, b3, b4, c2, c3, c4);
|
|
||||||
|
|
||||||
retVal(1)[0] = -det3x3(b1, b3, b4, c1, c3, c4, d1, d3, d4);
|
|
||||||
retVal(1)[1] = det3x3(a1, a3, a4, c1, c3, c4, d1, d3, d4);
|
|
||||||
retVal(1)[2] = -det3x3(a1, a3, a4, b1, b3, b4, d1, d3, d4);
|
|
||||||
retVal(1)[3] = det3x3(a1, a3, a4, b1, b3, b4, c1, c3, c4);
|
|
||||||
|
|
||||||
retVal(2)[0] = det3x3(b1, b2, b4, c1, c2, c4, d1, d2, d4);
|
|
||||||
retVal(2)[1] = -det3x3(a1, a2, a4, c1, c2, c4, d1, d2, d4);
|
|
||||||
retVal(2)[2] = det3x3(a1, a2, a4, b1, b2, b4, d1, d2, d4);
|
|
||||||
retVal(2)[3] = -det3x3(a1, a2, a4, b1, b2, b4, c1, c2, c4);
|
|
||||||
|
|
||||||
retVal(3)[0] = -det3x3(b1, b2, b3, c1, c2, c3, d1, d2, d3);
|
|
||||||
retVal(3)[1] = det3x3(a1, a2, a3, c1, c2, c3, d1, d2, d3);
|
|
||||||
retVal(3)[2] = -det3x3(a1, a2, a3, b1, b2, b3, d1, d2, d3);
|
|
||||||
retVal(3)[3] = det3x3(a1, a2, a3, b1, b2, b3, c1, c2, c3);
|
|
||||||
|
|
||||||
return retVal;
|
|
||||||
}
|
|
||||||
|
|
||||||
matrix4x4 Inverse(const matrix4x4 &m)
|
|
||||||
{
|
|
||||||
matrix4x4 retVal = Adjoint(m);
|
|
||||||
scalar_t det = Determinant(m);
|
|
||||||
assert(det);
|
|
||||||
|
|
||||||
for (int i = 0; i < 4; ++i)
|
|
||||||
{
|
|
||||||
for (int j = 0; j < 4; ++j)
|
|
||||||
{
|
|
||||||
retVal(i)[j] /= det;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return retVal;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//**************************************
|
|
||||||
// Testing from here on.
|
|
||||||
//**************************************
|
|
||||||
#ifdef TEST_MATH3D
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
using namespace Math3D;
|
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
static int failures = 0;
|
|
||||||
|
|
||||||
void ReportFailure(const char *className, const char *testName, bool passed)
|
|
||||||
{
|
|
||||||
cout << className;
|
|
||||||
if (passed)
|
|
||||||
cout << " passed test ";
|
|
||||||
else
|
|
||||||
{
|
|
||||||
cout << " FAILED test ";
|
|
||||||
++failures;
|
|
||||||
}
|
|
||||||
cout << testName << "." << endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char *vector3Name = "vector3";
|
|
||||||
const char *matrix4x4Name = "matrix4x4";
|
|
||||||
|
|
||||||
void Testvector3Constructors(void)
|
|
||||||
{
|
|
||||||
// Default ctor... just make sure it compiles
|
|
||||||
vector3 defaultCtorTest;
|
|
||||||
|
|
||||||
// Initializer ctor test (3 param)
|
|
||||||
vector3 initCtorTest(1, 2, 3);
|
|
||||||
ReportFailure(vector3Name, "initialized ctor (3 parameter version)",
|
|
||||||
(initCtorTest[0] == 1 && initCtorTest[1] == 2 && initCtorTest[2] == 3 &&
|
|
||||||
initCtorTest[3] == 1));
|
|
||||||
|
|
||||||
// Initializer ctor test (4 param)
|
|
||||||
vector3 initCtorTest2(1, 2, 3, 4);
|
|
||||||
ReportFailure(vector3Name, "initialized ctor (4 parameter version)",
|
|
||||||
(initCtorTest2[0] == 1 && initCtorTest2[1] == 2 && initCtorTest2[2] == 3 &&
|
|
||||||
initCtorTest2[3] == 4));
|
|
||||||
|
|
||||||
scalar_t initArray[] = {1, 2, 3, 4};
|
|
||||||
vector3 initCtorArrayTest3(initArray);
|
|
||||||
ReportFailure(vector3Name, "array initialized ctor (3 parameter version)",
|
|
||||||
(initCtorArrayTest3[0] == 1 && initCtorArrayTest3[1] == 2 &&
|
|
||||||
initCtorArrayTest3[2] == 3 && initCtorArrayTest3[3] == 1));
|
|
||||||
|
|
||||||
vector3 initCtorArrayTest4(initArray, 4);
|
|
||||||
ReportFailure(vector3Name, "array initialized ctor (4 parameter version)",
|
|
||||||
(initCtorArrayTest4[0] == 1 && initCtorArrayTest4[1] == 2 &&
|
|
||||||
initCtorArrayTest4[2] == 3 && initCtorArrayTest4[3] == 4));
|
|
||||||
|
|
||||||
// Copy ctor test
|
|
||||||
vector3 copyCtorTest(initCtorTest2);
|
|
||||||
ReportFailure(vector3Name, "copy ctor", (copyCtorTest[0] == 1 && copyCtorTest[1] == 2 &&
|
|
||||||
copyCtorTest[2] == 3 && copyCtorTest[3] == 4));
|
|
||||||
}
|
|
||||||
|
|
||||||
void Testvector3Comparison(void)
|
|
||||||
{
|
|
||||||
vector3 alpha(1, 1, 1);
|
|
||||||
vector3 beta(alpha);
|
|
||||||
vector3 gamma(2, 3, 4);
|
|
||||||
|
|
||||||
ReportFailure(vector3Name, "equivalence operator test 1", (alpha == beta));
|
|
||||||
ReportFailure(vector3Name, "equivalence operator test 2", (!(alpha == gamma)));
|
|
||||||
ReportFailure(vector3Name, "comparison operator test 1", !(alpha < beta));
|
|
||||||
ReportFailure(vector3Name, "comparison operator test 2", (alpha < gamma));
|
|
||||||
ReportFailure(vector3Name, "comparison operator test 3", !(gamma < beta));
|
|
||||||
}
|
|
||||||
|
|
||||||
void Testvector3Assignment(void)
|
|
||||||
{
|
|
||||||
vector3 alpha(1, 1, 1, 1);
|
|
||||||
vector3 beta(10, 10, 10, 10);
|
|
||||||
alpha = beta;
|
|
||||||
ReportFailure(vector3Name, "assignment operator", (alpha == beta));
|
|
||||||
}
|
|
||||||
|
|
||||||
void Testvector3UnaryOps(void)
|
|
||||||
{
|
|
||||||
vector3 alpha(10, 10, 10, 10);
|
|
||||||
vector3 beta(-10, -10, -10, -10);
|
|
||||||
alpha = -alpha;
|
|
||||||
ReportFailure(vector3Name, "negation operator", (alpha == beta));
|
|
||||||
|
|
||||||
ReportFailure(vector3Name, "length squared 3 element version", LengthSquared3(alpha) == 300);
|
|
||||||
ReportFailure(vector3Name, "length 3 element version", Length3(alpha) == SQRT_FUNCTION(300));
|
|
||||||
ReportFailure(vector3Name, "length squared 4 element version", LengthSquared4(alpha) == 400);
|
|
||||||
ReportFailure(vector3Name, "length 4 element version", Length4(alpha) == SQRT_FUNCTION(400));
|
|
||||||
|
|
||||||
// Manually normalize beta
|
|
||||||
// Done without /= on vector3, as we want to be independant of failure of /=
|
|
||||||
// Earlier failures should be resolved before later ones (just like C++)
|
|
||||||
beta = alpha;
|
|
||||||
for (int i = 0; i < 3; ++i)
|
|
||||||
beta(i) /= SQRT_FUNCTION(300);
|
|
||||||
beta(3) = 1;
|
|
||||||
ReportFailure(vector3Name, "normalize 3 element version", Normalize3(alpha) == beta);
|
|
||||||
|
|
||||||
beta = alpha;
|
|
||||||
for (int i = 0; i < 4; ++i)
|
|
||||||
beta(i) /= SQRT_FUNCTION(400);
|
|
||||||
ReportFailure(vector3Name, "normalize 4 element version", Normalize4(alpha) == beta);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Testvector3BinaryOps(void)
|
|
||||||
{
|
|
||||||
// Vector * Matrix is tested in Testmatrix4x4BinaryOps
|
|
||||||
vector3 testVec(1, 1, 1, 1);
|
|
||||||
vector3 deltaVec(1, 2, 3, 4);
|
|
||||||
vector3 crossVec(1, -2, 1, 1); // testVec x deltaVec
|
|
||||||
|
|
||||||
vector3 factorVec(10, 10, 10, 10);
|
|
||||||
vector3 sumVec(2, 3, 4, 5);
|
|
||||||
vector3 difVec(0, -1, -2, -3);
|
|
||||||
vector3 testVec2;
|
|
||||||
|
|
||||||
ReportFailure(vector3Name, "scalar multiply 1", (testVec * 10) == factorVec);
|
|
||||||
ReportFailure(vector3Name, "scalar multiply 2", (10 * testVec) == factorVec);
|
|
||||||
testVec2 = testVec;
|
|
||||||
ReportFailure(vector3Name, "scalar multiply and store", (testVec2 *= 10) == factorVec);
|
|
||||||
|
|
||||||
ReportFailure(vector3Name, "scalar divide", (factorVec / 10) == testVec);
|
|
||||||
testVec2 = factorVec;
|
|
||||||
ReportFailure(vector3Name, "scalar divide and store", (testVec2 /= 10) == testVec);
|
|
||||||
|
|
||||||
ReportFailure(vector3Name, "vector addition", (testVec + deltaVec) == sumVec);
|
|
||||||
testVec2 = testVec;
|
|
||||||
ReportFailure(vector3Name, "vector addition and store", (testVec2 += deltaVec) == sumVec);
|
|
||||||
|
|
||||||
ReportFailure(vector3Name, "vector subtraction", (testVec - deltaVec) == difVec);
|
|
||||||
testVec2 = testVec;
|
|
||||||
ReportFailure(vector3Name, "vector subtraction and store", (testVec2 -= deltaVec) == difVec);
|
|
||||||
|
|
||||||
ReportFailure(vector3Name, "3 element dot product", 6 == DotProduct3(testVec, deltaVec));
|
|
||||||
ReportFailure(vector3Name, "4 element dot product", 10 == DotProduct4(testVec, deltaVec));
|
|
||||||
|
|
||||||
ReportFailure(vector3Name, "cross product", crossVec == CrossProduct(testVec, deltaVec));
|
|
||||||
}
|
|
||||||
|
|
||||||
void Testvector3(void)
|
|
||||||
{
|
|
||||||
// Accessors cannot be tested effectively...
|
|
||||||
// They are really trivial, and so don't really need testing,
|
|
||||||
// but more importantly, how do you test the ctors without assuming
|
|
||||||
// the accessors work? Conversely, how do you test the acccessors
|
|
||||||
// without assuming the ctors work? Chicken and egg problem, and I
|
|
||||||
// decided on testing the ctors, not the accessors.
|
|
||||||
Testvector3Constructors();
|
|
||||||
Testvector3Comparison();
|
|
||||||
Testvector3Assignment();
|
|
||||||
Testvector3UnaryOps();
|
|
||||||
Testvector3BinaryOps();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Testmatrix4x4Constructors(void)
|
|
||||||
{
|
|
||||||
// Check if default ctor compiles
|
|
||||||
matrix4x4 defaultTest;
|
|
||||||
|
|
||||||
scalar_t initArray[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
|
|
||||||
matrix4x4 arrayTest;
|
|
||||||
arrayTest.C_Matrix(initArray);
|
|
||||||
bool passedTest = true;
|
|
||||||
for (int x = 0; x < 4; ++x)
|
|
||||||
for (int y = 0; y < 4; ++y)
|
|
||||||
if (arrayTest[x][y] != initArray[(y << 2) + x])
|
|
||||||
passedTest = false;
|
|
||||||
ReportFailure(matrix4x4Name, "array constructor", passedTest);
|
|
||||||
|
|
||||||
matrix4x4 copyTest(arrayTest);
|
|
||||||
passedTest = true;
|
|
||||||
for (int x = 0; x < 4; ++x)
|
|
||||||
for (int y = 0; y < 4; ++y)
|
|
||||||
if (arrayTest[x][y] != copyTest[x][y])
|
|
||||||
passedTest = false;
|
|
||||||
ReportFailure(matrix4x4Name, "copy constructor", passedTest);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Testmatrix4x4Comparison(void)
|
|
||||||
{
|
|
||||||
scalar_t initArray[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
|
|
||||||
scalar_t initArray2[] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1};
|
|
||||||
matrix4x4 alpha, beta, gamma;
|
|
||||||
alpha.C_Matrix(initArray);
|
|
||||||
beta.C_Matrix(initArray);
|
|
||||||
gamma.C_Matrix(initArray2);
|
|
||||||
|
|
||||||
ReportFailure(matrix4x4Name, "equality test 1", alpha == beta);
|
|
||||||
ReportFailure(matrix4x4Name, "equality test 2", !(alpha == gamma));
|
|
||||||
ReportFailure(matrix4x4Name, "comparison test 1", alpha < gamma);
|
|
||||||
ReportFailure(matrix4x4Name, "comparison test 2", !(gamma < alpha));
|
|
||||||
ReportFailure(matrix4x4Name, "comparison test 3", !(alpha < beta));
|
|
||||||
}
|
|
||||||
|
|
||||||
void Testmatrix4x4BinaryOps(void)
|
|
||||||
{
|
|
||||||
scalar_t initVector[] = {0, 1, 2, 3};
|
|
||||||
scalar_t initMatrix[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
|
|
||||||
scalar_t resultVector[] = {0 * 0 + 1 * 1 + 2 * 2 + 3 * 3, 0 * 4 + 1 * 5 + 2 * 6 + 3 * 7,
|
|
||||||
0 * 8 + 1 * 9 + 2 * 10 + 3 * 11, 0 * 12 + 1 * 13 + 2 * 14 + 3 * 15};
|
|
||||||
|
|
||||||
vector3 vector1(initVector, 4);
|
|
||||||
matrix4x4 matrix1;
|
|
||||||
matrix1.C_Matrix(initMatrix);
|
|
||||||
vector3 vectorTest(resultVector, 4);
|
|
||||||
ReportFailure(matrix4x4Name, "matrix * vector", vectorTest == matrix1 * vector1);
|
|
||||||
|
|
||||||
scalar_t initMatrix2[] = {15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0};
|
|
||||||
|
|
||||||
matrix4x4 matrix2;
|
|
||||||
matrix2.C_Matrix(initMatrix2);
|
|
||||||
matrix4x4 resultMatrix;
|
|
||||||
for (int x = 0; x < 4; ++x)
|
|
||||||
for (int y = 0; y < 4; ++y)
|
|
||||||
{
|
|
||||||
resultMatrix(x)[y] = 0;
|
|
||||||
for (int i = 0; i < 4; ++i)
|
|
||||||
resultMatrix(x)[y] += matrix1[i][y] * matrix2[x][i];
|
|
||||||
}
|
|
||||||
ReportFailure(matrix4x4Name, "matrix * matrix", resultMatrix == matrix1 * matrix2);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Testmatrix4x4(void)
|
|
||||||
{
|
|
||||||
Testmatrix4x4Constructors();
|
|
||||||
Testmatrix4x4Comparison();
|
|
||||||
Testmatrix4x4BinaryOps();
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int, char *[])
|
|
||||||
{
|
|
||||||
int vectorFailures = 0;
|
|
||||||
int matrixFailures = 0;
|
|
||||||
Testvector3();
|
|
||||||
vectorFailures = failures;
|
|
||||||
failures = 0;
|
|
||||||
|
|
||||||
Testmatrix4x4();
|
|
||||||
matrixFailures = failures;
|
|
||||||
|
|
||||||
cout << endl
|
|
||||||
<< "****************************************" << endl;
|
|
||||||
cout << "* *" << endl;
|
|
||||||
if (vectorFailures + matrixFailures == 0)
|
|
||||||
cout << "* No failures detected in Math3D *" << endl;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
cout << "* FAILURES DETECTED IN MATH3D! *" << endl;
|
|
||||||
cout << "* Total vector3 failures: " << vectorFailures << " *" << endl;
|
|
||||||
cout << "* Total matrix4x4 failures: " << matrixFailures << " *" << endl;
|
|
||||||
cout << "* Total Failures in Math3D: " << vectorFailures + matrixFailures << " *"
|
|
||||||
<< endl;
|
|
||||||
}
|
|
||||||
cout << "* *" << endl;
|
|
||||||
cout << "****************************************" << endl;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
@@ -1,671 +0,0 @@
|
|||||||
/*
|
|
||||||
This Source Code Form is subject to the
|
|
||||||
terms of the Mozilla Public License, v.
|
|
||||||
2.0. If a copy of the MPL was not
|
|
||||||
distributed with this file, You can
|
|
||||||
obtain one at
|
|
||||||
http://mozilla.org/MPL/2.0/.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <cmath>
|
|
||||||
|
|
||||||
namespace Math3D
|
|
||||||
{
|
|
||||||
|
|
||||||
glm::vec3 RotateY(glm::vec3 v, float angle);
|
|
||||||
glm::dvec3 RotateY(glm::dvec3 v, double angle);
|
|
||||||
|
|
||||||
inline glm::dmat4 BasisChange(glm::dvec3 u, glm::dvec3 v, glm::dvec3 n)
|
|
||||||
{
|
|
||||||
return glm::dmat4{glm::dvec4(u.x, v.x, n.x, 0.0), glm::dvec4(u.y, v.y, n.y, 0.0), glm::dvec4(u.z, v.z, n.z, 0.0), glm::dvec4(0.0, 0.0, 0.0, 1.0)}; // 4 columns; first rows: u, v, n
|
|
||||||
}
|
|
||||||
|
|
||||||
inline glm::dmat4 BasisChange(glm::dvec3 v, glm::dvec3 n)
|
|
||||||
{
|
|
||||||
glm::dvec3 u = glm::cross(v, n);
|
|
||||||
return BasisChange(u, v, n);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Define this to have Math3D.cp generate a main which tests these classes
|
|
||||||
//#define TEST_MATH3D
|
|
||||||
|
|
||||||
// Define this to allow streaming output of vectors and matrices
|
|
||||||
// Automatically enabled by TEST_MATH3D
|
|
||||||
//#define OSTREAM_MATH3D
|
|
||||||
|
|
||||||
// definition of the scalar type
|
|
||||||
typedef double scalar_t;
|
|
||||||
// inline pass-throughs to various basic math functions
|
|
||||||
// written in this style to allow for easy substitution with more efficient versions
|
|
||||||
inline scalar_t SINE_FUNCTION(scalar_t x)
|
|
||||||
{
|
|
||||||
return std::sin(x);
|
|
||||||
}
|
|
||||||
inline scalar_t COSINE_FUNCTION(scalar_t x)
|
|
||||||
{
|
|
||||||
return std::cos(x);
|
|
||||||
}
|
|
||||||
inline scalar_t SQRT_FUNCTION(scalar_t x)
|
|
||||||
{
|
|
||||||
return std::sqrt(x);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 2 element vector
|
|
||||||
class vector2
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
vector2(void) :
|
|
||||||
x(0.0), y(0.0)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
vector2(scalar_t a, scalar_t b)
|
|
||||||
{
|
|
||||||
x = a;
|
|
||||||
y = b;
|
|
||||||
}
|
|
||||||
double x;
|
|
||||||
union
|
|
||||||
{
|
|
||||||
double y;
|
|
||||||
double z;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
// 3 element vector
|
|
||||||
class vector3
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
vector3(void) :
|
|
||||||
x(0.0), y(0.0), z(0.0)
|
|
||||||
{}
|
|
||||||
vector3( scalar_t X, scalar_t Y, scalar_t Z ) :
|
|
||||||
x( X ), y( Y ), z( Z )
|
|
||||||
{}
|
|
||||||
template <typename Type_, glm::precision Precision_>
|
|
||||||
vector3( glm::tvec3<Type_, Precision_> const &Vector ) :
|
|
||||||
x( Vector.x ), y( Vector.y ), z( Vector.z )
|
|
||||||
{}
|
|
||||||
template <typename Type_, glm::precision Precision_>
|
|
||||||
operator glm::tvec3<Type_, Precision_>() const {
|
|
||||||
return glm::tvec3<Type_, Precision_>{ x, y, z }; }
|
|
||||||
// The int parameter is the number of elements to copy from initArray (3 or 4)
|
|
||||||
// explicit vector3(scalar_t* initArray, int arraySize = 3)
|
|
||||||
// { for (int i = 0;i<arraySize;++i) e[i] = initArray[i]; }
|
|
||||||
|
|
||||||
void RotateX(double angle);
|
|
||||||
void RotateY(double angle);
|
|
||||||
void RotateZ(double angle);
|
|
||||||
|
|
||||||
void inline Normalize();
|
|
||||||
void inline SafeNormalize();
|
|
||||||
double inline Length() const;
|
|
||||||
double inline LengthSquared() const;
|
|
||||||
void inline Zero()
|
|
||||||
{
|
|
||||||
x = y = z = 0.0;
|
|
||||||
};
|
|
||||||
|
|
||||||
// [] is to read, () is to write (const correctness)
|
|
||||||
// const scalar_t& operator[] (int i) const { return e[i]; }
|
|
||||||
// scalar_t& operator() (int i) { return e[i]; }
|
|
||||||
|
|
||||||
// Provides access to the underlying array; useful for passing this class off to C APIs
|
|
||||||
const scalar_t *readArray(void)
|
|
||||||
{
|
|
||||||
return &x;
|
|
||||||
}
|
|
||||||
scalar_t *getArray(void)
|
|
||||||
{
|
|
||||||
return &x;
|
|
||||||
}
|
|
||||||
|
|
||||||
double x, y, z;
|
|
||||||
|
|
||||||
bool inline Equal(vector3 *v)
|
|
||||||
{ // sprawdzenie odległości punktów
|
|
||||||
if (std::fabs(x - v->x) > 0.02)
|
|
||||||
return false; // sześcian zamiast kuli
|
|
||||||
if (std::fabs(z - v->z) > 0.02)
|
|
||||||
return false;
|
|
||||||
if (std::fabs(y - v->y) > 0.02)
|
|
||||||
return false;
|
|
||||||
return true;
|
|
||||||
};
|
|
||||||
|
|
||||||
operator glm::dvec3() const
|
|
||||||
{
|
|
||||||
return glm::dvec3(x, y, z);
|
|
||||||
}
|
|
||||||
private:
|
|
||||||
};
|
|
||||||
|
|
||||||
// 4 element matrix
|
|
||||||
class matrix4x4
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
matrix4x4(void)
|
|
||||||
{
|
|
||||||
memset( e, 0, sizeof( e ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
// When defining matrices in C arrays, it is easiest to define them with
|
|
||||||
// the column increasing fastest. However, some APIs (OpenGL in particular) do this
|
|
||||||
// backwards, hence the "constructor" from C matrices, or from OpenGL matrices.
|
|
||||||
// Note that matrices are stored internally in OpenGL format.
|
|
||||||
void C_Matrix(scalar_t const *initArray)
|
|
||||||
{
|
|
||||||
int i = 0;
|
|
||||||
for (int y = 0; y < 4; ++y)
|
|
||||||
for (int x = 0; x < 4; ++x)
|
|
||||||
(*this)(x)[y] = initArray[i++];
|
|
||||||
}
|
|
||||||
template <typename Type_>
|
|
||||||
void OpenGL_Matrix(Type_ const *initArray)
|
|
||||||
{
|
|
||||||
int i = 0;
|
|
||||||
for (int x = 0; x < 4; ++x)
|
|
||||||
for (int y = 0; y < 4; ++y)
|
|
||||||
(*this)(x)[y] = initArray[i++];
|
|
||||||
}
|
|
||||||
|
|
||||||
// [] is to read, () is to write (const correctness)
|
|
||||||
// m[x][y] or m(x)[y] is the correct form
|
|
||||||
const scalar_t *operator[](int i) const
|
|
||||||
{
|
|
||||||
return &e[i << 2];
|
|
||||||
}
|
|
||||||
scalar_t *operator()(int i)
|
|
||||||
{
|
|
||||||
return &e[i << 2];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Low-level access to the array.
|
|
||||||
const scalar_t *readArray(void) const
|
|
||||||
{
|
|
||||||
return e;
|
|
||||||
}
|
|
||||||
scalar_t *getArray(void)
|
|
||||||
{
|
|
||||||
return e;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Construct various matrices; REPLACES CURRENT CONTENTS OF THE MATRIX!
|
|
||||||
// Written this way to work in-place and hence be somewhat more efficient
|
|
||||||
void Identity(void)
|
|
||||||
{
|
|
||||||
for (int i = 0; i < 16; ++i)
|
|
||||||
e[i] = 0;
|
|
||||||
e[0] = 1;
|
|
||||||
e[5] = 1;
|
|
||||||
e[10] = 1;
|
|
||||||
e[15] = 1;
|
|
||||||
}
|
|
||||||
inline matrix4x4 &Rotation(scalar_t angle, vector3 axis);
|
|
||||||
inline matrix4x4 &Translation(const vector3 &translation);
|
|
||||||
inline matrix4x4 &Scale(scalar_t x, scalar_t y, scalar_t z);
|
|
||||||
inline matrix4x4 &BasisChange(const vector3 &v, const vector3 &n);
|
|
||||||
inline matrix4x4 &BasisChange(const vector3 &u, const vector3 &v, const vector3 &n);
|
|
||||||
inline matrix4x4 &ProjectionMatrix(bool perspective, scalar_t l, scalar_t r, scalar_t t,
|
|
||||||
scalar_t b, scalar_t n, scalar_t f);
|
|
||||||
void InitialRotate()
|
|
||||||
{ // taka specjalna rotacja, nie ma co ciągać trygonometrii
|
|
||||||
double f;
|
|
||||||
for (int i = 0; i < 16; i += 4)
|
|
||||||
{
|
|
||||||
e[i] = -e[i]; // zmiana znaku X
|
|
||||||
f = e[i + 1];
|
|
||||||
e[i + 1] = e[i + 2];
|
|
||||||
e[i + 2] = f; // zamiana Y i Z
|
|
||||||
}
|
|
||||||
};
|
|
||||||
inline bool IdentityIs()
|
|
||||||
{ // sprawdzenie jednostkowości
|
|
||||||
for (int i = 0; i < 16; ++i)
|
|
||||||
if (e[i] != ((i % 5) ? 0.0 : 1.0)) // jedynki tylko na 0, 5, 10 i 15
|
|
||||||
return false;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
operator glm::dmat4() const
|
|
||||||
{
|
|
||||||
return glm::make_mat4(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
scalar_t e[16];
|
|
||||||
};
|
|
||||||
|
|
||||||
// Scalar operations
|
|
||||||
|
|
||||||
// Returns false if there are 0 solutions
|
|
||||||
inline bool SolveQuadratic(scalar_t a, scalar_t b, scalar_t c, scalar_t *x1, scalar_t *x2);
|
|
||||||
|
|
||||||
// Vector operations
|
|
||||||
inline bool operator==(const vector3 &, const vector3 &);
|
|
||||||
inline bool operator<(const vector3 &, const vector3 &);
|
|
||||||
|
|
||||||
inline vector3 operator-(const vector3 &);
|
|
||||||
inline vector3 operator*(const vector3 &, scalar_t);
|
|
||||||
inline vector3 operator*(scalar_t, const vector3 &);
|
|
||||||
inline vector3 &operator*=(vector3 &, scalar_t);
|
|
||||||
inline vector3 operator/(const vector3 &, scalar_t);
|
|
||||||
inline vector3 &operator/=(vector3 &, scalar_t);
|
|
||||||
|
|
||||||
inline vector3 operator+(const vector3 &, const vector3 &);
|
|
||||||
inline vector3 &operator+=(vector3 &, const vector3 &);
|
|
||||||
inline vector3 operator-(const vector3 &, const vector3 &);
|
|
||||||
inline vector3 &operator-=(vector3 &, const vector3 &);
|
|
||||||
|
|
||||||
// X3 is the 3 element version of a function, X4 is four element
|
|
||||||
inline scalar_t LengthSquared3(const vector3 &);
|
|
||||||
inline scalar_t LengthSquared4(const vector3 &);
|
|
||||||
inline scalar_t Length3(const vector3 &);
|
|
||||||
inline scalar_t Length4(const vector3 &);
|
|
||||||
inline vector3 Normalize(const vector3 &);
|
|
||||||
inline vector3 Normalize4(const vector3 &);
|
|
||||||
inline scalar_t DotProduct(const vector3 &, const vector3 &);
|
|
||||||
inline scalar_t DotProduct4(const vector3 &, const vector3 &);
|
|
||||||
// Cross product is only defined for 3 elements
|
|
||||||
inline vector3 CrossProduct(const vector3 &, const vector3 &);
|
|
||||||
|
|
||||||
inline vector3 operator*(const matrix4x4 &, const vector3 &);
|
|
||||||
|
|
||||||
// Matrix operations
|
|
||||||
inline bool operator==(const matrix4x4 &, const matrix4x4 &);
|
|
||||||
inline bool operator<(const matrix4x4 &, const matrix4x4 &);
|
|
||||||
|
|
||||||
inline matrix4x4 operator*(const matrix4x4 &, const matrix4x4 &);
|
|
||||||
|
|
||||||
inline matrix4x4 Transpose(const matrix4x4 &);
|
|
||||||
scalar_t Determinant(const matrix4x4 &);
|
|
||||||
matrix4x4 Adjoint(const matrix4x4 &);
|
|
||||||
matrix4x4 Inverse(const matrix4x4 &);
|
|
||||||
|
|
||||||
// Inline implementations follow
|
|
||||||
inline bool SolveQuadratic(scalar_t a, scalar_t b, scalar_t c, scalar_t *x1, scalar_t *x2)
|
|
||||||
{
|
|
||||||
// If a == 0, solve a linear equation
|
|
||||||
if (a == 0)
|
|
||||||
{
|
|
||||||
if (b == 0)
|
|
||||||
return false;
|
|
||||||
*x1 = c / b;
|
|
||||||
*x2 = *x1;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
scalar_t det = b * b - 4 * a * c;
|
|
||||||
if (det < 0)
|
|
||||||
return false;
|
|
||||||
det = SQRT_FUNCTION(det) / (2 * a);
|
|
||||||
scalar_t prefix = -b / (2 * a);
|
|
||||||
*x1 = prefix + det;
|
|
||||||
*x2 = prefix - det;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool operator==(const vector3 &v1, const vector3 &v2)
|
|
||||||
{
|
|
||||||
return (v1.x == v2.x && v1.y == v2.y && v1.z == v2.z);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool operator<(const vector3 &v1, const vector3 &v2)
|
|
||||||
{
|
|
||||||
// for (int i=0;i<4;++i)
|
|
||||||
// if (v1[i] < v2[i]) return true;
|
|
||||||
// else if (v1[i] > v2[i]) return false;
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline vector3 operator-(const vector3 &v)
|
|
||||||
{
|
|
||||||
return vector3(-v.x, -v.y, -v.z);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline vector3 operator*(const vector3 &v, scalar_t k)
|
|
||||||
{
|
|
||||||
return vector3(k * v.x, k * v.y, k * v.z);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline vector3 operator*(scalar_t k, const vector3 &v)
|
|
||||||
{
|
|
||||||
return v * k;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline vector3 &operator*=(vector3 &v, scalar_t k)
|
|
||||||
{
|
|
||||||
v.x *= k;
|
|
||||||
v.y *= k;
|
|
||||||
v.z *= k;
|
|
||||||
return v;
|
|
||||||
};
|
|
||||||
|
|
||||||
inline vector3 operator/(const vector3 &v, scalar_t k)
|
|
||||||
{
|
|
||||||
return vector3(v.x / k, v.y / k, v.z / k);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline vector3 &operator/=(vector3 &v, scalar_t k)
|
|
||||||
{
|
|
||||||
v.x /= k;
|
|
||||||
v.y /= k;
|
|
||||||
v.z /= k;
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline scalar_t LengthSquared3(const vector3 &v)
|
|
||||||
{
|
|
||||||
return DotProduct(v, v);
|
|
||||||
}
|
|
||||||
inline scalar_t LengthSquared4(const vector3 &v)
|
|
||||||
{
|
|
||||||
return DotProduct4(v, v);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline scalar_t Length3(const vector3 &v)
|
|
||||||
{
|
|
||||||
return SQRT_FUNCTION(LengthSquared3(v));
|
|
||||||
}
|
|
||||||
inline scalar_t Length4(const vector3 &v)
|
|
||||||
{
|
|
||||||
return SQRT_FUNCTION(LengthSquared4(v));
|
|
||||||
}
|
|
||||||
|
|
||||||
inline vector3 Normalize(const vector3 &v)
|
|
||||||
{
|
|
||||||
vector3 retVal = v / Length3(v);
|
|
||||||
return retVal;
|
|
||||||
}
|
|
||||||
inline vector3 SafeNormalize(const vector3 &v)
|
|
||||||
{
|
|
||||||
double l = Length3(v);
|
|
||||||
vector3 retVal;
|
|
||||||
if (l == 0)
|
|
||||||
retVal.x = retVal.y = retVal.z = 0;
|
|
||||||
else
|
|
||||||
retVal = v / l;
|
|
||||||
return retVal;
|
|
||||||
}
|
|
||||||
inline vector3 Normalize4(const vector3 &v)
|
|
||||||
{
|
|
||||||
return v / Length4(v);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline vector3 operator+(const vector3 &v1, const vector3 &v2)
|
|
||||||
{
|
|
||||||
return vector3(v1.x + v2.x, v1.y + v2.y, v1.z + v2.z);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline vector3 &operator+=(vector3 &v1, const vector3 &v2)
|
|
||||||
{
|
|
||||||
v1.x += v2.x;
|
|
||||||
v1.y += v2.y;
|
|
||||||
v1.z += v2.z;
|
|
||||||
return v1;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline vector3 operator-(const vector3 &v1, const vector3 &v2)
|
|
||||||
{
|
|
||||||
return vector3(v1.x - v2.x, v1.y - v2.y, v1.z - v2.z);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline vector3 &operator-=(vector3 &v1, const vector3 &v2)
|
|
||||||
{
|
|
||||||
v1.x -= v2.x;
|
|
||||||
v1.y -= v2.y;
|
|
||||||
v1.z -= v2.z;
|
|
||||||
return v1;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline scalar_t DotProduct(const vector3 &v1, const vector3 &v2)
|
|
||||||
{
|
|
||||||
return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline scalar_t DotProduct4(const vector3 &v1, const vector3 &v2)
|
|
||||||
{
|
|
||||||
return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline vector3 CrossProduct(const vector3 &v1, const vector3 &v2)
|
|
||||||
{
|
|
||||||
return vector3(v1.y * v2.z - v1.z * v2.y, v2.x * v1.z - v2.z * v1.x, v1.x * v2.y - v1.y * v2.x);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline vector3 Interpolate( vector3 const &First, vector3 const &Second, float const Factor ) {
|
|
||||||
|
|
||||||
return ( First * ( 1.0f - Factor ) ) + ( Second * Factor );
|
|
||||||
}
|
|
||||||
|
|
||||||
inline vector3 operator*(const matrix4x4 &m, const vector3 &v)
|
|
||||||
{
|
|
||||||
return vector3(v.x * m[0][0] + v.y * m[1][0] + v.z * m[2][0] + m[3][0],
|
|
||||||
v.x * m[0][1] + v.y * m[1][1] + v.z * m[2][1] + m[3][1],
|
|
||||||
v.x * m[0][2] + v.y * m[1][2] + v.z * m[2][2] + m[3][2]);
|
|
||||||
}
|
|
||||||
|
|
||||||
void inline vector3::Normalize()
|
|
||||||
{
|
|
||||||
double il = 1 / Length();
|
|
||||||
x *= il;
|
|
||||||
y *= il;
|
|
||||||
z *= il;
|
|
||||||
}
|
|
||||||
|
|
||||||
double inline vector3::Length() const
|
|
||||||
{
|
|
||||||
return SQRT_FUNCTION(x * x + y * y + z * z);
|
|
||||||
}
|
|
||||||
|
|
||||||
double inline vector3::LengthSquared() const {
|
|
||||||
|
|
||||||
return ( x * x + y * y + z * z );
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool operator==(const matrix4x4 &m1, const matrix4x4 &m2)
|
|
||||||
{
|
|
||||||
for (int x = 0; x < 4; ++x)
|
|
||||||
for (int y = 0; y < 4; ++y)
|
|
||||||
if (m1[x][y] != m2[x][y])
|
|
||||||
return false;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool operator<(const matrix4x4 &m1, const matrix4x4 &m2)
|
|
||||||
{
|
|
||||||
for (int x = 0; x < 4; ++x)
|
|
||||||
for (int y = 0; y < 4; ++y)
|
|
||||||
if (m1[x][y] < m2[x][y])
|
|
||||||
return true;
|
|
||||||
else if (m1[x][y] > m2[x][y])
|
|
||||||
return false;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline matrix4x4 operator*(const matrix4x4 &m1, const matrix4x4 &m2)
|
|
||||||
{
|
|
||||||
matrix4x4 retVal;
|
|
||||||
for (int x = 0; x < 4; ++x)
|
|
||||||
for (int y = 0; y < 4; ++y)
|
|
||||||
{
|
|
||||||
retVal(x)[y] = 0;
|
|
||||||
for (int i = 0; i < 4; ++i)
|
|
||||||
retVal(x)[y] += m1[i][y] * m2[x][i];
|
|
||||||
}
|
|
||||||
return retVal;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline matrix4x4 Transpose(const matrix4x4 &m)
|
|
||||||
{
|
|
||||||
matrix4x4 retVal;
|
|
||||||
for (int x = 0; x < 4; ++x)
|
|
||||||
for (int y = 0; y < 4; ++y)
|
|
||||||
retVal(x)[y] = m[y][x];
|
|
||||||
return retVal;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline matrix4x4 &matrix4x4::Rotation(scalar_t angle, vector3 axis)
|
|
||||||
{
|
|
||||||
scalar_t c = COSINE_FUNCTION(angle);
|
|
||||||
scalar_t s = SINE_FUNCTION(angle);
|
|
||||||
// One minus c (short name for legibility of formulai)
|
|
||||||
scalar_t omc = (1 - c);
|
|
||||||
|
|
||||||
if (LengthSquared3(axis) != 1)
|
|
||||||
axis = Normalize(axis);
|
|
||||||
|
|
||||||
scalar_t x = axis.x;
|
|
||||||
scalar_t y = axis.y;
|
|
||||||
scalar_t z = axis.z;
|
|
||||||
scalar_t xs = x * s;
|
|
||||||
scalar_t ys = y * s;
|
|
||||||
scalar_t zs = z * s;
|
|
||||||
scalar_t xyomc = x * y * omc;
|
|
||||||
scalar_t xzomc = x * z * omc;
|
|
||||||
scalar_t yzomc = y * z * omc;
|
|
||||||
|
|
||||||
e[0] = x * x * omc + c;
|
|
||||||
e[1] = xyomc + zs;
|
|
||||||
e[2] = xzomc - ys;
|
|
||||||
e[3] = 0;
|
|
||||||
|
|
||||||
e[4] = xyomc - zs;
|
|
||||||
e[5] = y * y * omc + c;
|
|
||||||
e[6] = yzomc + xs;
|
|
||||||
e[7] = 0;
|
|
||||||
|
|
||||||
e[8] = xzomc + ys;
|
|
||||||
e[9] = yzomc - xs;
|
|
||||||
e[10] = z * z * omc + c;
|
|
||||||
e[11] = 0;
|
|
||||||
|
|
||||||
e[12] = 0;
|
|
||||||
e[13] = 0;
|
|
||||||
e[14] = 0;
|
|
||||||
e[15] = 1;
|
|
||||||
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline matrix4x4 &matrix4x4::Translation(const vector3 &translation)
|
|
||||||
{
|
|
||||||
Identity();
|
|
||||||
e[12] = translation.x;
|
|
||||||
e[13] = translation.y;
|
|
||||||
e[14] = translation.z;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline matrix4x4 &matrix4x4::Scale(scalar_t x, scalar_t y, scalar_t z)
|
|
||||||
{
|
|
||||||
Identity();
|
|
||||||
e[0] = x;
|
|
||||||
e[5] = y;
|
|
||||||
e[10] = z;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline matrix4x4 &matrix4x4::BasisChange(const vector3 &u, const vector3 &v, const vector3 &n)
|
|
||||||
{
|
|
||||||
e[0] = u.x;
|
|
||||||
e[1] = v.x;
|
|
||||||
e[2] = n.x;
|
|
||||||
e[3] = 0;
|
|
||||||
|
|
||||||
e[4] = u.y;
|
|
||||||
e[5] = v.y;
|
|
||||||
e[6] = n.y;
|
|
||||||
e[7] = 0;
|
|
||||||
|
|
||||||
e[8] = u.z;
|
|
||||||
e[9] = v.z;
|
|
||||||
e[10] = n.z;
|
|
||||||
e[11] = 0;
|
|
||||||
|
|
||||||
e[12] = 0;
|
|
||||||
e[13] = 0;
|
|
||||||
e[14] = 0;
|
|
||||||
e[15] = 1;
|
|
||||||
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline matrix4x4 &matrix4x4::BasisChange(const vector3 &v, const vector3 &n)
|
|
||||||
{
|
|
||||||
vector3 u = CrossProduct(v, n);
|
|
||||||
return BasisChange(u, v, n);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline matrix4x4 &matrix4x4::ProjectionMatrix(bool perspective, scalar_t left_plane,
|
|
||||||
scalar_t right_plane, scalar_t top_plane,
|
|
||||||
scalar_t bottom_plane, scalar_t near_plane,
|
|
||||||
scalar_t far_plane)
|
|
||||||
{
|
|
||||||
scalar_t A = (right_plane + left_plane) / (right_plane - left_plane);
|
|
||||||
scalar_t B = (top_plane + bottom_plane) / (top_plane - bottom_plane);
|
|
||||||
scalar_t C = (far_plane + near_plane) / (far_plane - near_plane);
|
|
||||||
|
|
||||||
Identity();
|
|
||||||
if (perspective)
|
|
||||||
{
|
|
||||||
e[0] = 2 * near_plane / (right_plane - left_plane);
|
|
||||||
e[5] = 2 * near_plane / (top_plane - bottom_plane);
|
|
||||||
e[8] = A;
|
|
||||||
e[9] = B;
|
|
||||||
e[10] = C;
|
|
||||||
e[11] = -1;
|
|
||||||
e[14] = 2 * far_plane * near_plane / (far_plane - near_plane);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
e[0] = 2 / (right_plane - left_plane);
|
|
||||||
e[5] = 2 / (top_plane - bottom_plane);
|
|
||||||
e[10] = -2 / (far_plane - near_plane);
|
|
||||||
e[12] = A;
|
|
||||||
e[13] = B;
|
|
||||||
e[14] = C;
|
|
||||||
}
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
double inline SquareMagnitude(const vector3 &v)
|
|
||||||
{
|
|
||||||
return v.x * v.x + v.y * v.y + v.z * v.z;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // close namespace
|
|
||||||
|
|
||||||
// If we're testing, then we need OSTREAM support
|
|
||||||
#ifdef TEST_MATH3D
|
|
||||||
#define OSTREAM_MATH3D
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef OSTREAM_MATH3D
|
|
||||||
#include <ostream>
|
|
||||||
// Streaming support
|
|
||||||
std::ostream &operator<<(std::ostream &os, const Math3D::vector3 &v)
|
|
||||||
{
|
|
||||||
os << '[';
|
|
||||||
for (int i = 0; i < 4; ++i)
|
|
||||||
os << ' ' << v[i];
|
|
||||||
return os << ']';
|
|
||||||
}
|
|
||||||
|
|
||||||
std::ostream &operator<<(std::ostream &os, const Math3D::matrix4x4 &m)
|
|
||||||
{
|
|
||||||
for (int y = 0; y < 4; ++y)
|
|
||||||
{
|
|
||||||
os << '[';
|
|
||||||
for (int x = 0; x < 4; ++x)
|
|
||||||
os << ' ' << m[x][y];
|
|
||||||
os << " ]" << std::endl;
|
|
||||||
}
|
|
||||||
return os;
|
|
||||||
}
|
|
||||||
#endif // OSTREAM_MATH3D
|
|
||||||
21
utilities/glmHelpers.h
Normal file
21
utilities/glmHelpers.h
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <glm/glm.hpp>
|
||||||
|
|
||||||
|
inline glm::dmat4 BasisChange(glm::dvec3 u, glm::dvec3 v, glm::dvec3 n)
|
||||||
|
{
|
||||||
|
return glm::dmat4{glm::dvec4(u.x, v.x, n.x, 0.0), glm::dvec4(u.y, v.y, n.y, 0.0), glm::dvec4(u.z, v.z, n.z, 0.0), glm::dvec4(0.0, 0.0, 0.0, 1.0)}; // 4 columns; first rows: u, v, n
|
||||||
|
}
|
||||||
|
|
||||||
|
inline glm::dmat4 BasisChange(glm::dvec3 v, glm::dvec3 n)
|
||||||
|
{
|
||||||
|
glm::dvec3 u = glm::cross(v, n);
|
||||||
|
return BasisChange(u, v, n);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T> inline glm::vec<3, T> RotateY(const glm::vec<3, T> &v, T angle)
|
||||||
|
{
|
||||||
|
T s = std::sin(angle);
|
||||||
|
T c = std::cos(angle);
|
||||||
|
|
||||||
|
return glm::vec<3, T>(c * v.x + s * v.z, v.y, c * v.z - s * v.x);
|
||||||
|
}
|
||||||
@@ -12,6 +12,7 @@ http://mozilla.org/MPL/2.0/.
|
|||||||
|
|
||||||
#include "utilities/Globals.h"
|
#include "utilities/Globals.h"
|
||||||
#include "utilities/utilities.h"
|
#include "utilities/utilities.h"
|
||||||
|
#include "utilities/glmHelpers.h"
|
||||||
#include "Console.h"
|
#include "Console.h"
|
||||||
#include "utilities/Timer.h"
|
#include "utilities/Timer.h"
|
||||||
#include "vehicle/Driver.h"
|
#include "vehicle/Driver.h"
|
||||||
@@ -171,7 +172,7 @@ void TCamera::Update()
|
|||||||
|| ( true == DebugCameraFlag ) ) {
|
|| ( true == DebugCameraFlag ) ) {
|
||||||
// free movement position update
|
// free movement position update
|
||||||
auto movement { Velocity };
|
auto movement { Velocity };
|
||||||
movement = Math3D::RotateY(movement, Angle.y);
|
movement = RotateY(movement, Angle.y);
|
||||||
Pos += movement * 5.0 * deltatime;
|
Pos += movement * 5.0 * deltatime;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -194,7 +195,7 @@ void TCamera::Update()
|
|||||||
movement.y = -movement.y;
|
movement.y = -movement.y;
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
movement = Math3D::RotateY(movement, Angle.y);
|
movement = RotateY(movement, Angle.y);
|
||||||
|
|
||||||
m_owneroffset += movement * deltatime;
|
m_owneroffset += movement * deltatime;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ http://mozilla.org/MPL/2.0/.
|
|||||||
#include "utilities/Globals.h"
|
#include "utilities/Globals.h"
|
||||||
#include "utilities/Timer.h"
|
#include "utilities/Timer.h"
|
||||||
#include "utilities/Logs.h"
|
#include "utilities/Logs.h"
|
||||||
|
#include "utilities/glmHelpers.h"
|
||||||
#include "Console.h"
|
#include "Console.h"
|
||||||
#include "world/Traction.h"
|
#include "world/Traction.h"
|
||||||
#include "audio/sound.h"
|
#include "audio/sound.h"
|
||||||
@@ -2695,7 +2696,7 @@ void TDynamicObject::Move(double fDistance)
|
|||||||
vLeft = glm::normalize(glm::cross(vUp, vFront)); // wektor w lewo
|
vLeft = glm::normalize(glm::cross(vUp, vFront)); // wektor w lewo
|
||||||
// vUp=CrossProduct(vFront,vLeft); //wektor w górę
|
// vUp=CrossProduct(vFront,vLeft); //wektor w górę
|
||||||
}
|
}
|
||||||
mMatrix = Math3D::BasisChange(vLeft, vUp, vFront); // to też można by od razu policzyć, ale potrzebne jest do wyświetlania // przesuwanie jest jednak rzadziej niż renderowanie
|
mMatrix = BasisChange(vLeft, vUp, vFront); // to też można by od razu policzyć, ale potrzebne jest do wyświetlania // przesuwanie jest jednak rzadziej niż renderowanie
|
||||||
mMatrix = glm::inverse(mMatrix); // wyliczenie macierzy dla pojazdu (potrzebna tylko do wyświetlania?)
|
mMatrix = glm::inverse(mMatrix); // wyliczenie macierzy dla pojazdu (potrzebna tylko do wyświetlania?)
|
||||||
// if (MoverParameters->CategoryFlag&2)
|
// if (MoverParameters->CategoryFlag&2)
|
||||||
{ // przesunięcia są używane po wyrzuceniu pociągu z toru
|
{ // przesunięcia są używane po wyrzuceniu pociągu z toru
|
||||||
|
|||||||
@@ -23,7 +23,6 @@ http://mozilla.org/MPL/2.0/.
|
|||||||
#include "utilities/Logs.h"
|
#include "utilities/Logs.h"
|
||||||
#include "model/MdlMngr.h"
|
#include "model/MdlMngr.h"
|
||||||
#include "model/Model3d.h"
|
#include "model/Model3d.h"
|
||||||
#include "utilities/dumb3d.h"
|
|
||||||
#include "utilities/Timer.h"
|
#include "utilities/Timer.h"
|
||||||
#include "vehicle/Driver.h"
|
#include "vehicle/Driver.h"
|
||||||
#include "vehicle/DynObj.h"
|
#include "vehicle/DynObj.h"
|
||||||
|
|||||||
Reference in New Issue
Block a user