Huge refactoring v3

master
Vectozavr 2021-10-30 15:18:31 +07:00
parent 88d57b5af6
commit e1c66d8617
8 changed files with 33 additions and 44 deletions

View File

@ -10,7 +10,7 @@ Player::Player(ObjectNameTag name) : RigidBody(name) {
loadObj(ShooterConsts::CUBE_OBJ, Vec3D{0.5, 1.9, 0.5}); loadObj(ShooterConsts::CUBE_OBJ, Vec3D{0.5, 1.9, 0.5});
setAcceleration(Vec3D{0, -ShooterConsts::GRAVITY, 0}); setAcceleration(Vec3D{0, -ShooterConsts::GRAVITY, 0});
setCollision(true); setCollision(true);
//setVisible(false); setVisible(false);
Vec3D randColor = Vec3D::Random(); Vec3D randColor = Vec3D::Random();
setColor({static_cast<sf::Uint8>(randColor.x()*255), static_cast<sf::Uint8>(randColor.y()*255), static_cast<sf::Uint8>(randColor.z()*255)}); setColor({static_cast<sf::Uint8>(randColor.x()*255), static_cast<sf::Uint8>(randColor.y()*255), static_cast<sf::Uint8>(randColor.z()*255)});

View File

@ -19,27 +19,31 @@ std::vector<std::shared_ptr<Triangle>> Camera::project(std::shared_ptr<Mesh> mes
} }
// Model transform matrix: translate _tris in the origin of body. // Model transform matrix: translate _tris in the origin of body.
Matrix4x4 M = Matrix4x4::Translation(mesh->position()); Matrix4x4 M = mesh->model();
Matrix4x4 VM = _V * M; Matrix4x4 V = Matrix4x4::View(left(), up(), lookAt(), position());
// We don't want to waste time re-allocating memory every time // We don't want to waste time re-allocating memory every time
std::vector<Triangle> clippedTriangles, tempBuffer; std::vector<Triangle> clippedTriangles, tempBuffer;
for(auto& t : mesh->triangles()) { 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) { if(dot > 0) {
continue; continue;
} }
Triangle VMTriangle = MTriangle * V;
// It needs to be cleared because it's reused through iterations. Usually it doesn't free memory. // It needs to be cleared because it's reused through iterations. Usually it doesn't free memory.
clippedTriangles.clear(); clippedTriangles.clear();
tempBuffer.clear(); tempBuffer.clear();
// In the beginning we need to to translate triangle from world coordinate to our camera system: // 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 // After that we apply clipping for all planes from _clipPlanes
clippedTriangles.emplace_back(t * VM); clippedTriangles.emplace_back(VMTriangle);
for(auto& plane : _clipPlanes) { for(auto& plane : _clipPlanes) {
while(!clippedTriangles.empty()) { while(!clippedTriangles.empty()) {
std::vector<Triangle> clipResult = plane.clip(clippedTriangles.back()); std::vector<Triangle> 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. // 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 // Because here we calculate matrix that does not change during the motion of _objects or camera
_aspect = (double)width / (double)height; _aspect = (double)width / (double)height;
_P = Matrix4x4::Projection(fov, _aspect, ZNear, ZFar); Matrix4x4 P = Matrix4x4::Projection(fov, _aspect, ZNear, ZFar);
_S = Matrix4x4::ScreenSpace(width, height); 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. // This is planes for clipping _tris.
// Motivation: we are not interest in _tris that we cannot see. // Motivation: we are not interest in _tris that we cannot see.
@ -121,8 +125,5 @@ std::vector<std::shared_ptr<Triangle>> Camera::sorted() {
void Camera::clear() { void Camera::clear() {
// Cleaning all _tris and recalculation of View matrix // 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(); _triangles.clear();
_V = Matrix4x4::View(left(), up(), lookAt(), position());
} }

View File

@ -12,19 +12,13 @@
class Camera final : public Object{ class Camera final : public Object{
private: 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<std::shared_ptr<Triangle>> _triangles{}; std::vector<std::shared_ptr<Triangle>> _triangles{};
std::vector<Plane> _clipPlanes{}; std::vector<Plane> _clipPlanes{};
bool _ready = false; bool _ready = false;
double _aspect = 0; double _aspect = 0;
Matrix4x4 _SP;
public: public:
Camera() : Object(ObjectNameTag("Camera")) {}; Camera() : Object(ObjectNameTag("Camera")) {};
Camera(const Camera& camera) = delete; Camera(const Camera& camera) = delete;

View File

@ -13,7 +13,7 @@ namespace Consts {
const sf::Color BACKGROUND_COLOR = sf::Color(255, 255, 255); const sf::Color BACKGROUND_COLOR = sf::Color(255, 255, 255);
const std::string PROJECT_NAME = "engine"; const std::string PROJECT_NAME = "engine";
const bool USE_LOG_FILE = true; const bool USE_LOG_FILE = true;
const bool USE_OPEN_GL = true; const bool USE_OPEN_GL = false;
const bool SHOW_COORDINATES = true; const bool SHOW_COORDINATES = true;
const double PI = 3.14159265358979323846264338327950288; const double PI = 3.14159265358979323846264338327950288;

View File

@ -85,9 +85,9 @@ Matrix4x4 Matrix4x4::Translation(const Vec3D& v) {
t._arr[2][2] = 1.0; t._arr[2][2] = 1.0;
t._arr[3][3] = 1.0; t._arr[3][3] = 1.0;
t._arr[3][0] = v.x(); t._arr[0][3] = v.x();
t._arr[3][1] = v.y(); t._arr[1][3] = v.y();
t._arr[3][2] = v.z(); t._arr[2][3] = v.z();
return t; return t;
} }
@ -188,16 +188,12 @@ Matrix4x4 Matrix4x4::ScreenSpace(int width, int height) {
return s; return s;
} }
Matrix4x4 Matrix4x4::Model(const Matrix4x4& transformMatrix) { Matrix4x4 Matrix4x4::Model(const Matrix4x4 &transformMatrix, const Vec3D &position) {
Matrix4x4 M(transformMatrix); Matrix4x4 M(transformMatrix);
M._arr[0][3] = M._arr[3][0]; M._arr[0][3] = position.x();
M._arr[1][3] = M._arr[3][1]; M._arr[1][3] = position.y();
M._arr[2][3] = M._arr[3][2]; M._arr[2][3] = position.z();
M._arr[3][0] = 0;
M._arr[3][1] = 0;
M._arr[3][2] = 0;
return M; return M;
} }
@ -236,7 +232,3 @@ 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]);
} }
[[nodiscard]] Vec3D Matrix4x4::w() const {
return Vec3D(_arr[3][0], _arr[3][1],_arr[3][2]);
}

View File

@ -24,8 +24,6 @@ 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();
@ -40,7 +38,7 @@ public:
Matrix4x4 static RotationZ (double rz); Matrix4x4 static RotationZ (double rz);
Matrix4x4 static Rotation (const Vec3D& v, double rv); 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 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 Projection (double fov = 90.0, double aspect = 1.0, double ZNear = 1.0, double ZFar = 10.0);
Matrix4x4 static ScreenSpace (int width, int height); Matrix4x4 static ScreenSpace (int width, int height);

View File

@ -8,7 +8,7 @@
void Object::translate(const Vec3D &dv) { void Object::translate(const Vec3D &dv) {
_transformMatrix = _transformMatrix * Matrix4x4::Translation(dv); _position = _position + dv;
for(auto &[attachedName, attachedObject] : _attachedObjects) { for(auto &[attachedName, attachedObject] : _attachedObjects) {
if(!attachedObject.expired()) { if(!attachedObject.expired()) {
@ -67,8 +67,7 @@ void Object::rotateRelativePoint(const Vec3D &s, const Vec3D &r) {
_transformMatrix = rotationMatrix*_transformMatrix; _transformMatrix = rotationMatrix*_transformMatrix;
// After rotation we translate XYZ by vector -r2 and recalculate position // 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) { for(auto &[attachedName, attachedObject] : _attachedObjects) {
if(!attachedObject.expired()) { if(!attachedObject.expired()) {
@ -87,7 +86,7 @@ void Object::rotateRelativePoint(const Vec3D &s, const Vec3D &v, double r) {
_transformMatrix = rotationMatrix*_transformMatrix; _transformMatrix = rotationMatrix*_transformMatrix;
// After rotation we translate XYZ by vector -r2 and recalculate position // 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) { for(auto &[attachedName, attachedObject] : _attachedObjects) {
if(!attachedObject.expired()) { if(!attachedObject.expired()) {

View File

@ -34,12 +34,17 @@ private:
std::map<ObjectNameTag, std::weak_ptr<Object>> _attachedObjects; std::map<ObjectNameTag, std::weak_ptr<Object>> _attachedObjects;
Vec3D _position {0, 0, 0};
Vec3D _angle {0, 0, 0}; Vec3D _angle {0, 0, 0};
Vec3D _angleLeftUpLookAt{0, 0, 0}; Vec3D _angleLeftUpLookAt{0, 0, 0};
public: public:
explicit Object(ObjectNameTag nameTag) : _nameTag(std::move(nameTag)) {}; explicit Object(ObjectNameTag nameTag) : _nameTag(std::move(nameTag)) {};
explicit Object(const Object& object) : _nameTag(object.name()), _transformMatrix(object.model()) {}; 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 translate(const Vec3D& dv);
void translateToPoint(const Vec3D& point); void translateToPoint(const Vec3D& point);
void scale(const Vec3D& s); void scale(const Vec3D& s);
@ -55,7 +60,7 @@ public:
[[nodiscard]] Vec3D left() const { return _transformMatrix.x(); } [[nodiscard]] Vec3D left() const { return _transformMatrix.x(); }
[[nodiscard]] Vec3D up() const { return _transformMatrix.y(); } [[nodiscard]] Vec3D up() const { return _transformMatrix.y(); }
[[nodiscard]] Vec3D lookAt() const { return _transformMatrix.z(); } [[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 angle() const { return _angle; }
[[nodiscard]] Vec3D angleLeftUpLookAt() const { return _angleLeftUpLookAt; } [[nodiscard]] Vec3D angleLeftUpLookAt() const { return _angleLeftUpLookAt; }
@ -66,7 +71,7 @@ public:
[[nodiscard]] ObjectNameTag name() const { return _nameTag; } [[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 // OpenGL function
[[nodiscard]] GLfloat* glModel() const; [[nodiscard]] GLfloat* glModel() const;