add transform(const Matrix4x4& t)

add transformRelativePoint(const Vec3D &point, const Matrix4x4& transform)
implement every transform method using transform() & transformRelativePoint()
master
Vectozavr 2021-10-30 20:54:56 +07:00
parent 54b1ffa94f
commit 1e6539e8e0
4 changed files with 40 additions and 65 deletions

View File

@ -222,3 +222,7 @@ Vec3D Matrix4x4::y() const {
Vec3D Matrix4x4::z() const { Vec3D Matrix4x4::z() const {
return Vec3D(_arr[0][2], _arr[1][2],_arr[2][2]); 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]);
}

View File

@ -24,6 +24,8 @@ public:
[[nodiscard]] Vec3D x() const; [[nodiscard]] Vec3D x() const;
[[nodiscard]] Vec3D y() const; [[nodiscard]] Vec3D y() const;
[[nodiscard]] Vec3D z() const; [[nodiscard]] Vec3D z() const;
[[nodiscard]] Vec3D w() const;
// Any useful matrix (static methods) // Any useful matrix (static methods)
Matrix4x4 static Identity(); Matrix4x4 static Identity();

View File

@ -4,7 +4,32 @@
#include "Object.h" #include "Object.h"
#include "Matrix4x4.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) { void Object::translate(const Vec3D &dv) {
@ -18,81 +43,26 @@ void Object::translate(const Vec3D &dv) {
} }
void Object::scale(const Vec3D &s) { void Object::scale(const Vec3D &s) {
transform(Matrix4x4::Scale(s));
_transformMatrix = Matrix4x4::Scale(s)*_transformMatrix;
for(auto &[attachedName, attachedObject] : _attachedObjects) {
if(!attachedObject.expired()) {
attachedObject.lock()->scale(s);
}
}
} }
void Object::rotate(const Vec3D &r) { void Object::rotate(const Vec3D &r) {
_angle = _angle + r; _angle = _angle + r;
Matrix4x4 rotationMatrix = Matrix4x4::RotationZ(r.z())*Matrix4x4::RotationY(r.y())*Matrix4x4::RotationX(r.z()); Matrix4x4 rotationMatrix = Matrix4x4::RotationZ(r.z())*Matrix4x4::RotationY(r.y())*Matrix4x4::RotationX(r.z());
transform(rotationMatrix);
_transformMatrix = rotationMatrix*_transformMatrix;
for(auto &[attachedName, attachedObject] : _attachedObjects) {
if(!attachedObject.expired()) {
attachedObject.lock()->rotateRelativePoint(position(), r);
}
}
} }
void Object::rotate(const Vec3D &v, double rv) { void Object::rotate(const Vec3D &v, double rv) {
Matrix4x4 rotationMatrix = Matrix4x4::Rotation(v, rv); transform(Matrix4x4::Rotation(v, rv));
_transformMatrix = rotationMatrix*_transformMatrix;
for(auto &[attachedName, attachedObject] : _attachedObjects) {
if(!attachedObject.expired()) {
attachedObject.lock()->rotateRelativePoint(position(), v, rv);
}
}
} }
void Object::rotateRelativePoint(const Vec3D &s, const Vec3D &r) { void Object::rotateRelativePoint(const Vec3D &s, const Vec3D &r) {
_angle = _angle + r; transformRelativePoint(s, Matrix4x4::Rotation(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);
}
}
} }
void Object::rotateRelativePoint(const Vec3D &s, const Vec3D &v, double r) { void Object::rotateRelativePoint(const Vec3D &s, const Vec3D &v, double r) {
// Translate XYZ by vector r1 transformRelativePoint(s, Matrix4x4::Rotation(v, r));
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);
}
}
} }
void Object::rotateLeft(double rl) { void Object::rotateLeft(double rl) {

View File

@ -40,11 +40,10 @@ private:
public: public:
explicit Object(ObjectNameTag nameTag) : _nameTag(std::move(nameTag)) {}; explicit Object(ObjectNameTag nameTag) : _nameTag(std::move(nameTag)) {};
Object(const Object& object) : _nameTag(object.name()), _transformMatrix(object.model()) {}; 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 // TODO: implement rotations using quaternions
void transform(const Matrix4x4& t);
void transformRelativePoint(const Vec3D &point, const Matrix4x4& transform);
void translate(const Vec3D& dv); void translate(const Vec3D& dv);
void translateToPoint(const Vec3D& point); void translateToPoint(const Vec3D& point);
void scale(const Vec3D& s); void scale(const Vec3D& s);