From e1c66d86177935a84a358001d902ef5b8f5555d4 Mon Sep 17 00:00:00 2001 From: Vectozavr <60608292+vectozavr@users.noreply.github.com> Date: Sat, 30 Oct 2021 15:18:31 +0700 Subject: [PATCH] Huge refactoring v3 --- Player.cpp | 2 +- engine/Camera.cpp | 21 +++++++++++---------- engine/Camera.h | 10 ++-------- engine/Consts.h | 2 +- engine/Matrix4x4.cpp | 22 +++++++--------------- engine/Matrix4x4.h | 4 +--- engine/Object.cpp | 7 +++---- engine/Object.h | 9 +++++++-- 8 files changed, 33 insertions(+), 44 deletions(-) diff --git a/Player.cpp b/Player.cpp index 4ac86f1..db90776 100644 --- a/Player.cpp +++ b/Player.cpp @@ -10,7 +10,7 @@ Player::Player(ObjectNameTag name) : RigidBody(name) { loadObj(ShooterConsts::CUBE_OBJ, Vec3D{0.5, 1.9, 0.5}); setAcceleration(Vec3D{0, -ShooterConsts::GRAVITY, 0}); setCollision(true); - //setVisible(false); + setVisible(false); Vec3D randColor = Vec3D::Random(); setColor({static_cast(randColor.x()*255), static_cast(randColor.y()*255), static_cast(randColor.z()*255)}); diff --git a/engine/Camera.cpp b/engine/Camera.cpp index 838791f..de00794 100644 --- a/engine/Camera.cpp +++ b/engine/Camera.cpp @@ -19,27 +19,31 @@ std::vector> Camera::project(std::shared_ptr mes } // Model transform matrix: translate _tris in the origin of body. - Matrix4x4 M = Matrix4x4::Translation(mesh->position()); - Matrix4x4 VM = _V * M; + Matrix4x4 M = mesh->model(); + Matrix4x4 V = Matrix4x4::View(left(), up(), lookAt(), position()); // We don't want to waste time re-allocating memory every time std::vector clippedTriangles, tempBuffer; for(auto& t : mesh->triangles()) { - double dot = t.norm().dot((mesh->position() + Vec3D(t[0]) - position()).normalized()); + Triangle MTriangle = t * M; + + double dot = MTriangle.norm().dot((Vec3D(MTriangle[0]) - position()).normalized()); if(dot > 0) { continue; } + Triangle VMTriangle = MTriangle * V; + // It needs to be cleared because it's reused through iterations. Usually it doesn't free memory. clippedTriangles.clear(); tempBuffer.clear(); // In the beginning we need to to translate triangle from world coordinate to our camera system: // After that we apply clipping for all planes from _clipPlanes - clippedTriangles.emplace_back(t * VM); + clippedTriangles.emplace_back(VMTriangle); for(auto& plane : _clipPlanes) { while(!clippedTriangles.empty()) { std::vector clipResult = plane.clip(clippedTriangles.back()); @@ -78,10 +82,10 @@ void Camera::init(int width, int height, double fov, double ZNear, double ZFar) // We need to init camera only after creation or changing width, height, fov, ZNear or ZFar. // Because here we calculate matrix that does not change during the motion of _objects or camera _aspect = (double)width / (double)height; - _P = Matrix4x4::Projection(fov, _aspect, ZNear, ZFar); - _S = Matrix4x4::ScreenSpace(width, height); + Matrix4x4 P = Matrix4x4::Projection(fov, _aspect, ZNear, ZFar); + Matrix4x4 S = Matrix4x4::ScreenSpace(width, height); - _SP = _S * _P; // screen-space-projections matrix + _SP = S * P; // screen-space-projections matrix // This is planes for clipping _tris. // Motivation: we are not interest in _tris that we cannot see. @@ -121,8 +125,5 @@ std::vector> Camera::sorted() { void Camera::clear() { // Cleaning all _tris and recalculation of View matrix - // That is like preparation for new camera shot: we need to set - // the position of camera and insert new cartridge for photo. _triangles.clear(); - _V = Matrix4x4::View(left(), up(), lookAt(), position()); } diff --git a/engine/Camera.h b/engine/Camera.h index eba6498..db164b6 100644 --- a/engine/Camera.h +++ b/engine/Camera.h @@ -12,19 +12,13 @@ class Camera final : public Object{ private: - Matrix4x4 _S; // screen space matrix - Matrix4x4 _P; // projections matrix - Matrix4x4 _V; // camera matrix - - // To accelerate calculations we can use precalculated matrix that does not chance - Matrix4x4 _SP; // screen-space-projections matrix - std::vector> _triangles{}; std::vector _clipPlanes{}; - bool _ready = false; double _aspect = 0; + Matrix4x4 _SP; + public: Camera() : Object(ObjectNameTag("Camera")) {}; Camera(const Camera& camera) = delete; diff --git a/engine/Consts.h b/engine/Consts.h index b46af7c..5b17d4f 100644 --- a/engine/Consts.h +++ b/engine/Consts.h @@ -13,7 +13,7 @@ namespace Consts { const sf::Color BACKGROUND_COLOR = sf::Color(255, 255, 255); const std::string PROJECT_NAME = "engine"; const bool USE_LOG_FILE = true; - const bool USE_OPEN_GL = true; + const bool USE_OPEN_GL = false; const bool SHOW_COORDINATES = true; const double PI = 3.14159265358979323846264338327950288; diff --git a/engine/Matrix4x4.cpp b/engine/Matrix4x4.cpp index 2ca08d1..7ded573 100644 --- a/engine/Matrix4x4.cpp +++ b/engine/Matrix4x4.cpp @@ -85,9 +85,9 @@ Matrix4x4 Matrix4x4::Translation(const Vec3D& v) { t._arr[2][2] = 1.0; t._arr[3][3] = 1.0; - t._arr[3][0] = v.x(); - t._arr[3][1] = v.y(); - t._arr[3][2] = v.z(); + t._arr[0][3] = v.x(); + t._arr[1][3] = v.y(); + t._arr[2][3] = v.z(); return t; } @@ -188,16 +188,12 @@ Matrix4x4 Matrix4x4::ScreenSpace(int width, int height) { return s; } -Matrix4x4 Matrix4x4::Model(const Matrix4x4& transformMatrix) { +Matrix4x4 Matrix4x4::Model(const Matrix4x4 &transformMatrix, const Vec3D &position) { 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; + M._arr[0][3] = position.x(); + M._arr[1][3] = position.y(); + M._arr[2][3] = position.z(); return M; } @@ -236,7 +232,3 @@ 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 92ae7e0..263b70d 100644 --- a/engine/Matrix4x4.h +++ b/engine/Matrix4x4.h @@ -24,8 +24,6 @@ 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(); @@ -40,7 +38,7 @@ public: Matrix4x4 static RotationZ (double rz); Matrix4x4 static Rotation (const Vec3D& v, double rv); - Matrix4x4 static Model(const Matrix4x4& transformMatrix); + Matrix4x4 static Model(const Matrix4x4& transformMatrix, const Vec3D &position); 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 1351584..8abbf52 100644 --- a/engine/Object.cpp +++ b/engine/Object.cpp @@ -8,7 +8,7 @@ void Object::translate(const Vec3D &dv) { - _transformMatrix = _transformMatrix * Matrix4x4::Translation(dv); + _position = _position + dv; for(auto &[attachedName, attachedObject] : _attachedObjects) { if(!attachedObject.expired()) { @@ -67,8 +67,7 @@ void Object::rotateRelativePoint(const Vec3D &s, const Vec3D &r) { _transformMatrix = rotationMatrix*_transformMatrix; // After rotation we translate XYZ by vector -r2 and recalculate position - _transformMatrix = _transformMatrix * Matrix4x4::Translation(s + r2 - position()); - + _position = s + r2; for(auto &[attachedName, attachedObject] : _attachedObjects) { if(!attachedObject.expired()) { @@ -87,7 +86,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 - _transformMatrix = _transformMatrix * Matrix4x4::Translation(s + r2 - position()); + _position = s + r2; for(auto &[attachedName, attachedObject] : _attachedObjects) { if(!attachedObject.expired()) { diff --git a/engine/Object.h b/engine/Object.h index b4a611e..07c3b95 100644 --- a/engine/Object.h +++ b/engine/Object.h @@ -34,12 +34,17 @@ private: std::map> _attachedObjects; + Vec3D _position {0, 0, 0}; Vec3D _angle {0, 0, 0}; Vec3D _angleLeftUpLookAt{0, 0, 0}; public: explicit Object(ObjectNameTag nameTag) : _nameTag(std::move(nameTag)) {}; explicit Object(const Object& object) : _nameTag(object.name()), _transformMatrix(object.model()) {}; + // TODO: add transform(const Matrix4x4& t) + // TODO: add transformRelativePoint(const Vec3D &point, const Matrix4x4& transform) + // TODO: implement every transform method using transform() & transformRelativePoint() + // TODO: implement rotations using quaternions void translate(const Vec3D& dv); void translateToPoint(const Vec3D& point); void scale(const Vec3D& s); @@ -55,7 +60,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 _transformMatrix.w(); } + [[nodiscard]] Vec3D position() const { return _position; } [[nodiscard]] Vec3D angle() const { return _angle; } [[nodiscard]] Vec3D angleLeftUpLookAt() const { return _angleLeftUpLookAt; } @@ -66,7 +71,7 @@ public: [[nodiscard]] ObjectNameTag name() const { return _nameTag; } - [[nodiscard]] Matrix4x4 model() const { return Matrix4x4::Model(_transformMatrix); } + [[nodiscard]] Matrix4x4 model() const { return Matrix4x4::Model(_transformMatrix, _position); } // OpenGL function [[nodiscard]] GLfloat* glModel() const;