From 280abd4a3807386adb1d7bbda1128a9ee48de890 Mon Sep 17 00:00:00 2001 From: Andrew Golovashevich Date: Thu, 20 Mar 2025 17:49:04 +0300 Subject: [PATCH] Projection matrix fix --- programs/lab5/src/main.cpp | 15 ++++-- programs/lab5/src/sprite_data.hpp | 6 ++- programs/lab5/src/triangle.hpp | 19 ++++--- .../utilities/matrix.hpp | 50 ++++++++++++++++--- 4 files changed, 73 insertions(+), 17 deletions(-) diff --git a/programs/lab5/src/main.cpp b/programs/lab5/src/main.cpp index 0af8606..34f7a34 100644 --- a/programs/lab5/src/main.cpp +++ b/programs/lab5/src/main.cpp @@ -64,10 +64,19 @@ namespace BGTU::ComputerGraphicsLabWork::Impl { return 0; #else - auto x = Utilities::Matrix4d::projection_orto(-2, 2, -1, 1, 0, 2); + auto x = Utilities::Matrix4d::projection_central(-1, 1, -1, 1, 1, 2); + + Utilities::Vec4 a[]{ + {1, 1, -1, 1}, + {1, 1, -2, 1}, + {2, 2, -2, 1}, + }; + Utilities::Vec4 b[]{ + x * a[0], + x * a[1], + x * a[2], + }; - RendererApi::PointF<3> a{1, 1, 6}; - RendererApi::PointF<3> b = x * a; return 0; diff --git a/programs/lab5/src/sprite_data.hpp b/programs/lab5/src/sprite_data.hpp index ff133f8..2a8523a 100644 --- a/programs/lab5/src/sprite_data.hpp +++ b/programs/lab5/src/sprite_data.hpp @@ -56,9 +56,11 @@ namespace BGTU::ComputerGraphicsLabWork::Impl { SpriteData get_sprite_data() override { this->sync.lock(); double radius = (((this->w < this->h) ? this->w : this->h) * 7 / 16.0); - auto projection = this->is_projection_enabled ? Utilities::Matrix4d::projection_central(-2, 2, -2, 2, this->scale - 2, this->scale + 2) * Utilities::Matrix4d::shift(0, 0, this->scale) : Utilities::Matrix4d::projection_orto(-2, 2, -2, 2, -2, 2); + auto projection = this->is_projection_enabled + ? Utilities::Matrix4d::projection_central(-2, 2, -2, 2, 1, 9) * Utilities::Matrix4d::scale(1, 1, -1) * Utilities::Matrix4d::shift(0, 0, 7) + : Utilities::Matrix4d::projection_orto(-2, 2, -2, 2, -6, 2); SpriteData cached{ - Utilities::Matrix4d::shift(this->w / 2, this->h / 2, 2) * Utilities::Matrix4d::scale(radius) * projection * Utilities::Matrix4d::rotate_x(this->x_angle) * Utilities::Matrix4d::rotate_y(this->y_angle), + Utilities::Matrix4d::shift(this->w / 2, this->h / 2, 0) * Utilities::Matrix4d::scale(radius) * projection * Utilities::Matrix4d::rotate_x(this->x_angle) * Utilities::Matrix4d::rotate_y(this->y_angle), }; this->sync.unlock(); return cached; diff --git a/programs/lab5/src/triangle.hpp b/programs/lab5/src/triangle.hpp index 7b05cf5..b9140db 100644 --- a/programs/lab5/src/triangle.hpp +++ b/programs/lab5/src/triangle.hpp @@ -35,14 +35,21 @@ namespace BGTU::ComputerGraphicsLabWork::Impl { shader_p0{shader_p0}, shader_p1{shader_p1}, shader_p2{shader_p2}, shader{shader} {} void draw(BGTU::ComputerGraphicsLabWork::RendererApi::VirtualVoxelPainter *frame, SpriteData const *data) const override { - auto ta = data->transform * this->triangle_p0; - auto tb = data->transform * this->triangle_p1; - auto tc = data->transform * this->triangle_p2; + auto ta4 = data->transform * Utilities::Vec4{this->triangle_p0.x, this->triangle_p0.y, -this->triangle_p0.z, 1.0}; + auto tb4 = data->transform * Utilities::Vec4{this->triangle_p1.x, this->triangle_p1.y, -this->triangle_p1.z, 1.0}; + auto tc4 = data->transform * Utilities::Vec4{this->triangle_p2.x, this->triangle_p2.y, -this->triangle_p2.z, 1.0}; + + RendererApi::PointF<3> ta{ta4[0] / ta4[3], ta4[1] / ta4[3], ta4[2] / ta4[3]}; + RendererApi::PointF<3> tb{tb4[0] / tb4[3], tb4[1] / tb4[3], tb4[2] / tb4[3]}; + RendererApi::PointF<3> tc{tc4[0] / tc4[3], tc4[1] / tc4[3], tc4[2] / tc4[3]}; Utilities::Shapes::triangle_barycentric_interpolator> interpolator{ - {ta.x, ta.y}, {this->shader_p0.x, this->shader_p0.y, ta.z}, - {tb.x, tb.y}, {this->shader_p1.x, this->shader_p1.y, tb.z}, - {tc.x, tc.y}, {this->shader_p2.x, this->shader_p2.y, tc.z}, + {ta.x, ta.y}, + {this->shader_p0.x, this->shader_p0.y, ta.z}, + {tb.x, tb.y}, + {this->shader_p1.x, this->shader_p1.y, tb.z}, + {tc.x, tc.y}, + {this->shader_p2.x, this->shader_p2.y, tc.z}, }; Utilities::Shapes::iterate_triangle_fill( diff --git a/utilities/include/bgtu/computer_graphics_lab_work/utilities/matrix.hpp b/utilities/include/bgtu/computer_graphics_lab_work/utilities/matrix.hpp index b13a9b4..fb7d034 100644 --- a/utilities/include/bgtu/computer_graphics_lab_work/utilities/matrix.hpp +++ b/utilities/include/bgtu/computer_graphics_lab_work/utilities/matrix.hpp @@ -159,6 +159,27 @@ namespace BGTU::ComputerGraphicsLabWork::Utilities { using Matrix3f = Matrix3; using Matrix3d = Matrix3; + template + class Matrix4; + + template + class Vec4 { + private: + elem_t data[4]; + + + template + friend + class Matrix4; + + public: + Vec4(elem_t a, elem_t b, elem_t c, elem_t d) : data{a, b, c, d} {} + + elem_t operator[](std::size_t i) const { + return this->data[i]; + }; + }; + template class Matrix4 { private: @@ -309,18 +330,35 @@ namespace BGTU::ComputerGraphicsLabWork::Utilities { }; } + Vec4 operator*(Vec4 other) const { + return Vec4{ + this->data[0][0] * other.data[0] + this->data[0][1] * other.data[1] + this->data[0][2] * other.data[2] + this->data[0][3] * other.data[3], + this->data[1][0] * other.data[0] + this->data[1][1] * other.data[1] + this->data[1][2] * other.data[2] + this->data[1][3] * other.data[3], + this->data[2][0] * other.data[0] + this->data[2][1] * other.data[1] + this->data[2][2] * other.data[2] + this->data[2][3] * other.data[3], + this->data[3][0] * other.data[0] + this->data[3][1] * other.data[1] + this->data[3][2] * other.data[2] + this->data[3][3] * other.data[3] + }; + } + + Matrix4 transposed() const { + return Matrix4{ + this->data[0][0], this->data[1][0], this->data[2][0], this->data[3][0], + this->data[0][1], this->data[1][1], this->data[2][1], this->data[3][1], + this->data[0][2], this->data[1][2], this->data[2][2], this->data[3][2], + this->data[0][3], this->data[1][3], this->data[2][3], this->data[3][3], + }; + } static Matrix4 projection_orto(elem_t l, elem_t r, elem_t b, elem_t t, elem_t n, elem_t f) { - return Matrix4{static_cast(2.0 / (r - l)), 0, 0, static_cast(-(r + l) * (r - l)), - 0, static_cast(2.0 / (t - b)), 0, static_cast(-(t + b) * (t - b)), - 0, 0, static_cast(2.0 / (f - n)), static_cast(-(f + n) * (f - n)), + return Matrix4{static_cast(2.0 / (r - l)), 0, 0, static_cast(-(r + l) / (r - l)), + 0, static_cast(2.0 / (t - b)), 0, static_cast(-(t + b) / (t - b)), + 0, 0, static_cast(2.0 / (f - n)), static_cast(-(f + n) / (f - n)), 0, 0, 0, 1}; } static Matrix4 projection_central(elem_t l, elem_t r, elem_t b, elem_t t, elem_t n, elem_t f) { - return Matrix4{static_cast(2.0 * n / (r - l)), 0, static_cast((r + l) * (r - l)), 0, - 0, static_cast(2.0 * n / (t - b)), static_cast((t + b) * (t - b)), 0, - 0, 0, static_cast(-(f + n) * (f - n)), static_cast(-2.0 * n * f * (f - n)), + return Matrix4{static_cast(2.0 * n / (r - l)), 0, static_cast((r + l) / (r - l)), 0, + 0, static_cast(2.0 * n / (t - b)), static_cast((t + b) / (t - b)), 0, + 0, 0, static_cast(-(f + n) / (f - n)), static_cast(-2.0 * n * f / (f - n)), 0, 0, -1, 0}; } };