diff --git a/engine/Matrix4x4.cpp b/engine/Matrix4x4.cpp index 529e626..2ca08d1 100644 --- a/engine/Matrix4x4.cpp +++ b/engine/Matrix4x4.cpp @@ -85,10 +85,6 @@ Matrix4x4 Matrix4x4::Translation(const Vec3D& v) { t._arr[2][2] = 1.0; t._arr[3][3] = 1.0; - //t._arr[0][3] = v.x(); - //t._arr[1][3] = v.y(); - //t._arr[2][3] = v.z(); - t._arr[3][0] = v.x(); t._arr[3][1] = v.y(); t._arr[3][2] = v.z(); @@ -192,6 +188,20 @@ Matrix4x4 Matrix4x4::ScreenSpace(int width, int height) { return s; } +Matrix4x4 Matrix4x4::Model(const Matrix4x4& transformMatrix) { + Matrix4x4 M(transformMatrix); + + M._arr[0][3] = M._arr[3][0]; + M._arr[1][3] = M._arr[3][1]; + M._arr[2][3] = M._arr[3][2]; + + M._arr[3][0] = 0; + M._arr[3][1] = 0; + M._arr[3][2] = 0; + + return M; +} + Matrix4x4 Matrix4x4::View(const Vec3D &left, const Vec3D &up, const Vec3D &lookAt, const Vec3D &eye) { Matrix4x4 V = Zero(); @@ -226,3 +236,7 @@ Vec3D Matrix4x4::y() const { Vec3D Matrix4x4::z() const { return Vec3D(_arr[0][2], _arr[1][2],_arr[2][2]); } + +[[nodiscard]] Vec3D Matrix4x4::w() const { + return Vec3D(_arr[3][0], _arr[3][1],_arr[3][2]); +} diff --git a/engine/Matrix4x4.h b/engine/Matrix4x4.h index 43563fd..92ae7e0 100644 --- a/engine/Matrix4x4.h +++ b/engine/Matrix4x4.h @@ -24,6 +24,8 @@ public: [[nodiscard]] Vec3D x() const; [[nodiscard]] Vec3D y() const; [[nodiscard]] Vec3D z() const; + [[nodiscard]] Vec3D w() const; + // Any useful matrix (static methods) Matrix4x4 static Identity(); @@ -38,6 +40,7 @@ public: Matrix4x4 static RotationZ (double rz); Matrix4x4 static Rotation (const Vec3D& v, double rv); + Matrix4x4 static Model(const Matrix4x4& transformMatrix); Matrix4x4 static View(const Vec3D &left, const Vec3D &up, const Vec3D &lookAt, const Vec3D &eye); Matrix4x4 static Projection (double fov = 90.0, double aspect = 1.0, double ZNear = 1.0, double ZFar = 10.0); Matrix4x4 static ScreenSpace (int width, int height); diff --git a/engine/Object.cpp b/engine/Object.cpp index 8abbf52..1351584 100644 --- a/engine/Object.cpp +++ b/engine/Object.cpp @@ -8,7 +8,7 @@ void Object::translate(const Vec3D &dv) { - _position = _position + dv; + _transformMatrix = _transformMatrix * Matrix4x4::Translation(dv); for(auto &[attachedName, attachedObject] : _attachedObjects) { if(!attachedObject.expired()) { @@ -67,7 +67,8 @@ void Object::rotateRelativePoint(const Vec3D &s, const Vec3D &r) { _transformMatrix = rotationMatrix*_transformMatrix; // After rotation we translate XYZ by vector -r2 and recalculate position - _position = s + r2; + _transformMatrix = _transformMatrix * Matrix4x4::Translation(s + r2 - position()); + for(auto &[attachedName, attachedObject] : _attachedObjects) { if(!attachedObject.expired()) { @@ -86,7 +87,7 @@ void Object::rotateRelativePoint(const Vec3D &s, const Vec3D &v, double r) { _transformMatrix = rotationMatrix*_transformMatrix; // After rotation we translate XYZ by vector -r2 and recalculate position - _position = s + r2; + _transformMatrix = _transformMatrix * Matrix4x4::Translation(s + r2 - position()); for(auto &[attachedName, attachedObject] : _attachedObjects) { if(!attachedObject.expired()) { diff --git a/engine/Object.h b/engine/Object.h index 976d06e..b4a611e 100644 --- a/engine/Object.h +++ b/engine/Object.h @@ -34,7 +34,6 @@ private: std::map> _attachedObjects; - Vec3D _position {0, 0, 0}; Vec3D _angle {0, 0, 0}; Vec3D _angleLeftUpLookAt{0, 0, 0}; public: @@ -56,7 +55,7 @@ public: [[nodiscard]] Vec3D left() const { return _transformMatrix.x(); } [[nodiscard]] Vec3D up() const { return _transformMatrix.y(); } [[nodiscard]] Vec3D lookAt() const { return _transformMatrix.z(); } - [[nodiscard]] Vec3D position() const { return _position; } + [[nodiscard]] Vec3D position() const { return _transformMatrix.w(); } [[nodiscard]] Vec3D angle() const { return _angle; } [[nodiscard]] Vec3D angleLeftUpLookAt() const { return _angleLeftUpLookAt; } @@ -67,7 +66,7 @@ public: [[nodiscard]] ObjectNameTag name() const { return _nameTag; } - [[nodiscard]] Matrix4x4 model() const { return _transformMatrix; } + [[nodiscard]] Matrix4x4 model() const { return Matrix4x4::Model(_transformMatrix); } // OpenGL function [[nodiscard]] GLfloat* glModel() const; diff --git a/engine/Screen.cpp b/engine/Screen.cpp index bc3b76a..b330583 100644 --- a/engine/Screen.cpp +++ b/engine/Screen.cpp @@ -190,7 +190,6 @@ void Screen::glDrawMesh(GLfloat* geometry, GLfloat* view, GLfloat* model, size_t } GLfloat* Screen::glMeshToGLfloatArray(std::shared_ptr mesh, const Vec3D& cameraPosition) { - Vec3D pos = mesh->position(); std::vector& triangles = mesh->triangles(); auto* geometry = (GLfloat*)malloc(7*3*triangles.size()*sizeof(GLfloat)); @@ -199,7 +198,7 @@ GLfloat* Screen::glMeshToGLfloatArray(std::shared_ptr mesh, const Vec3D& c int stride = 21*i; - double dot = triangles[i].norm().dot((pos + mesh->model()*Vec3D(triangles[i][0]) - cameraPosition).normalized()); + double dot = triangles[i].norm().dot((mesh->model()*Vec3D(triangles[i][0]) - cameraPosition).normalized()); sf::Color color = triangles[i].color(); sf::Color ambientColor = sf::Color((sf::Uint8)(color.r * (0.3 * std::abs(dot) + 0.7)), (sf::Uint8)(color.g * (0.3 * std::abs(dot) + 0.7)), diff --git a/engine/World.cpp b/engine/World.cpp index ecab937..b04c667 100644 --- a/engine/World.cpp +++ b/engine/World.cpp @@ -52,7 +52,8 @@ IntersectionInformation World::rayCast(const Vec3D& from, const Vec3D& to, const } for(auto& tri : body->triangles()) { - Triangle tri_translated(body->model()*tri[0] + body->position().makePoint4D(), body->model()*tri[1] + body->position().makePoint4D(), body->model()*tri[2] + body->position().makePoint4D()); + Matrix4x4 model = body->model(); + Triangle tri_translated(model*tri[0], model*tri[1], model*tri[2]); Plane plane(tri_translated); auto intersection = plane.intersection(from, to); diff --git a/engine/physics/RigidBody.cpp b/engine/physics/RigidBody.cpp index fd6f166..68cf415 100644 --- a/engine/physics/RigidBody.cpp +++ b/engine/physics/RigidBody.cpp @@ -20,7 +20,7 @@ Vec3D RigidBody::_findFurthestPoint(const Vec3D& direction) { for(auto& tri : triangles()){ for(int i = 0; i < 3; i++){ - Vec3D point = model()*Vec3D(tri[i]) + position(); + Vec3D point(model()*tri[i]); double distance = point.dot(direction.normalized()); if(distance > maxDistance) {