diff --git a/CMakeLists.txt b/CMakeLists.txt index 593f2238..8806a7dc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -104,7 +104,6 @@ set(SOURCES "vehicle/Camera.cpp" "vehicle/Driver.cpp" "application/driverhints.cpp" -"utilities/dumb3d.cpp" "vehicle/DynObj.cpp" "EU07.cpp" "export_e3d_standalone.cpp" diff --git a/McZapkie/MOVER.h b/McZapkie/MOVER.h index 78062821..939a5e50 100644 --- a/McZapkie/MOVER.h +++ b/McZapkie/MOVER.h @@ -78,7 +78,6 @@ zwiekszenie nacisku przy duzych predkosciach w hamulcach Oerlikona ... */ -#include "utilities/dumb3d.h" #include "utilities/utilities.h" extern int ConversionError; diff --git a/rendering/frustum.h b/rendering/frustum.h index 111a2d9b..4afe02f0 100644 --- a/rendering/frustum.h +++ b/rendering/frustum.h @@ -10,7 +10,6 @@ http://mozilla.org/MPL/2.0/. #pragma once #include "utilities/Float3d.h" -#include "utilities/dumb3d.h" inline std::vector const ndcfrustumshapepoints // { diff --git a/utilities/dumb3d.cpp b/utilities/dumb3d.cpp deleted file mode 100644 index 0693d1a3..00000000 --- a/utilities/dumb3d.cpp +++ /dev/null @@ -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 - -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 - -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 diff --git a/utilities/dumb3d.h b/utilities/dumb3d.h deleted file mode 100644 index 33ea4bde..00000000 --- a/utilities/dumb3d.h +++ /dev/null @@ -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 - -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 - vector3( glm::tvec3 const &Vector ) : - x( Vector.x ), y( Vector.y ), z( Vector.z ) - {} - template - operator glm::tvec3() const { - return glm::tvec3{ 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;ix) > 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 - 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 -// 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 diff --git a/utilities/glmHelpers.h b/utilities/glmHelpers.h new file mode 100644 index 00000000..b784f2d3 --- /dev/null +++ b/utilities/glmHelpers.h @@ -0,0 +1,21 @@ +#pragma once +#include + +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 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); +} diff --git a/vehicle/Camera.cpp b/vehicle/Camera.cpp index 51f1ca46..4d2d630f 100644 --- a/vehicle/Camera.cpp +++ b/vehicle/Camera.cpp @@ -12,6 +12,7 @@ http://mozilla.org/MPL/2.0/. #include "utilities/Globals.h" #include "utilities/utilities.h" +#include "utilities/glmHelpers.h" #include "Console.h" #include "utilities/Timer.h" #include "vehicle/Driver.h" @@ -171,7 +172,7 @@ void TCamera::Update() || ( true == DebugCameraFlag ) ) { // free movement position update auto movement { Velocity }; - movement = Math3D::RotateY(movement, Angle.y); + movement = RotateY(movement, Angle.y); Pos += movement * 5.0 * deltatime; } else { @@ -194,7 +195,7 @@ void TCamera::Update() movement.y = -movement.y; } */ - movement = Math3D::RotateY(movement, Angle.y); + movement = RotateY(movement, Angle.y); m_owneroffset += movement * deltatime; } diff --git a/vehicle/DynObj.cpp b/vehicle/DynObj.cpp index 24a87629..d8b764cb 100644 --- a/vehicle/DynObj.cpp +++ b/vehicle/DynObj.cpp @@ -23,6 +23,7 @@ http://mozilla.org/MPL/2.0/. #include "utilities/Globals.h" #include "utilities/Timer.h" #include "utilities/Logs.h" +#include "utilities/glmHelpers.h" #include "Console.h" #include "world/Traction.h" #include "audio/sound.h" @@ -2695,7 +2696,7 @@ void TDynamicObject::Move(double fDistance) vLeft = glm::normalize(glm::cross(vUp, vFront)); // wektor w lewo // 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?) // if (MoverParameters->CategoryFlag&2) { // przesunięcia są używane po wyrzuceniu pociągu z toru diff --git a/vehicle/Train.cpp b/vehicle/Train.cpp index 9e062133..d79e1023 100644 --- a/vehicle/Train.cpp +++ b/vehicle/Train.cpp @@ -23,7 +23,6 @@ http://mozilla.org/MPL/2.0/. #include "utilities/Logs.h" #include "model/MdlMngr.h" #include "model/Model3d.h" -#include "utilities/dumb3d.h" #include "utilities/Timer.h" #include "vehicle/Driver.h" #include "vehicle/DynObj.h"