From 1e6539e8e0f2bee49c9e8b3e659cc91324075a70 Mon Sep 17 00:00:00 2001 From: Vectozavr <60608292+vectozavr@users.noreply.github.com> Date: Sat, 30 Oct 2021 20:54:56 +0700 Subject: [PATCH] add transform(const Matrix4x4& t) add transformRelativePoint(const Vec3D &point, const Matrix4x4& transform) implement every transform method using transform() & transformRelativePoint() --- engine/Matrix4x4.cpp | 4 ++ engine/Matrix4x4.h | 2 + engine/Object.cpp | 92 +++++++++++++++----------------------------- engine/Object.h | 7 ++-- 4 files changed, 40 insertions(+), 65 deletions(-) diff --git a/engine/Matrix4x4.cpp b/engine/Matrix4x4.cpp index 0b1e8ee..c4f8d49 100644 --- a/engine/Matrix4x4.cpp +++ b/engine/Matrix4x4.cpp @@ -222,3 +222,7 @@ Vec3D Matrix4x4::y() const { Vec3D Matrix4x4::z() const { return Vec3D(_arr[0][2], _arr[1][2],_arr[2][2]); } + +Vec3D Matrix4x4::w() const { + return Vec3D(_arr[0][3], _arr[1][3],_arr[2][3]); +} diff --git a/engine/Matrix4x4.h b/engine/Matrix4x4.h index 43563fd..9f06ba7 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(); diff --git a/engine/Object.cpp b/engine/Object.cpp index 8abbf52..fdfdcf7 100644 --- a/engine/Object.cpp +++ b/engine/Object.cpp @@ -4,7 +4,32 @@ #include "Object.h" #include "Matrix4x4.h" -#include "utils/Log.h" + +void Object::transform(const Matrix4x4& t) { + _transformMatrix = t * _transformMatrix; + + for(auto &[attachedName, attachedObject] : _attachedObjects) { + if(!attachedObject.expired()) { + attachedObject.lock()->transformRelativePoint(position(), t); + } + } +} +void Object::transformRelativePoint(const Vec3D &point, const Matrix4x4& transform) { + + // translate object in new coordinate system (connected with point) + _transformMatrix = Matrix4x4::Translation(position() - point) * _transformMatrix; + // transform object in the new coordinate system + _transformMatrix = transform*_transformMatrix; + // translate object back in self connected coordinate system + _position = _transformMatrix.w() + point; + _transformMatrix = Matrix4x4::Translation(-_transformMatrix.w()) * _transformMatrix; + + for(auto &[attachedName, attachedObject] : _attachedObjects) { + if(!attachedObject.expired()) { + attachedObject.lock()->transformRelativePoint(point, transform); + } + } +} void Object::translate(const Vec3D &dv) { @@ -18,81 +43,26 @@ void Object::translate(const Vec3D &dv) { } void Object::scale(const Vec3D &s) { - - _transformMatrix = Matrix4x4::Scale(s)*_transformMatrix; - - for(auto &[attachedName, attachedObject] : _attachedObjects) { - if(!attachedObject.expired()) { - attachedObject.lock()->scale(s); - } - } + transform(Matrix4x4::Scale(s)); } void Object::rotate(const Vec3D &r) { _angle = _angle + r; Matrix4x4 rotationMatrix = Matrix4x4::RotationZ(r.z())*Matrix4x4::RotationY(r.y())*Matrix4x4::RotationX(r.z()); - - _transformMatrix = rotationMatrix*_transformMatrix; - - for(auto &[attachedName, attachedObject] : _attachedObjects) { - if(!attachedObject.expired()) { - attachedObject.lock()->rotateRelativePoint(position(), r); - } - } + transform(rotationMatrix); } void Object::rotate(const Vec3D &v, double rv) { - Matrix4x4 rotationMatrix = Matrix4x4::Rotation(v, rv); - - _transformMatrix = rotationMatrix*_transformMatrix; - - for(auto &[attachedName, attachedObject] : _attachedObjects) { - if(!attachedObject.expired()) { - attachedObject.lock()->rotateRelativePoint(position(), v, rv); - } - } + transform(Matrix4x4::Rotation(v, rv)); } void Object::rotateRelativePoint(const Vec3D &s, const Vec3D &r) { - _angle = _angle + r; - - // Translate XYZ by vector r1 - Vec3D r1(position() - s); - - // In translated coordinate system we rotate body and position - Matrix4x4 rotationMatrix = Matrix4x4::Rotation(r); - Vec3D r2(rotationMatrix*r1); - - _transformMatrix = rotationMatrix*_transformMatrix; - - // After rotation we translate XYZ by vector -r2 and recalculate position - _position = s + r2; - - for(auto &[attachedName, attachedObject] : _attachedObjects) { - if(!attachedObject.expired()) { - attachedObject.lock()->rotateRelativePoint(s, r); - } - } + transformRelativePoint(s, Matrix4x4::Rotation(r)); } void Object::rotateRelativePoint(const Vec3D &s, const Vec3D &v, double r) { - // Translate XYZ by vector r1 - Vec3D r1(position() - s); - // In translated coordinate system we rotate body and position - Matrix4x4 rotationMatrix = Matrix4x4::Rotation(v, r); - Vec3D r2 = rotationMatrix*r1; - - _transformMatrix = rotationMatrix*_transformMatrix; - - // After rotation we translate XYZ by vector -r2 and recalculate position - _position = s + r2; - - for(auto &[attachedName, attachedObject] : _attachedObjects) { - if(!attachedObject.expired()) { - attachedObject.lock()->rotateRelativePoint(s, v, r); - } - } + transformRelativePoint(s, Matrix4x4::Rotation(v, r)); } void Object::rotateLeft(double rl) { diff --git a/engine/Object.h b/engine/Object.h index f3380aa..929ec5a 100644 --- a/engine/Object.h +++ b/engine/Object.h @@ -40,11 +40,10 @@ private: public: explicit Object(ObjectNameTag nameTag) : _nameTag(std::move(nameTag)) {}; 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 transform(const Matrix4x4& t); + void transformRelativePoint(const Vec3D &point, const Matrix4x4& transform); void translate(const Vec3D& dv); void translateToPoint(const Vec3D& point); void scale(const Vec3D& s);