diff --git a/engine/Engine.cpp b/engine/Engine.cpp index 6deada2..5104483 100644 --- a/engine/Engine.cpp +++ b/engine/Engine.cpp @@ -63,11 +63,11 @@ void Engine::create(int screenWidth, int screenHeight, const std::string &name, GLfloat *model = it.second->glModel(); GLfloat *geometry = Screen::glMeshToGLfloatArray(it.second, camera->position()); screen->glDrawMesh(geometry, view, model, 3 * it.second->triangles().size()); - free(geometry); - free(model); + delete[] geometry; + delete[] model; } } - free(view); + delete[] view; } else { // clear triangles from previous frame camera->clear(); diff --git a/engine/Matrix4x4.cpp b/engine/Matrix4x4.cpp index 2f02ed9..541a668 100644 --- a/engine/Matrix4x4.cpp +++ b/engine/Matrix4x4.cpp @@ -37,15 +37,10 @@ Vec3D Matrix4x4::operator*(const Vec3D &vec) const { Matrix4x4 Matrix4x4::Identity() { Matrix4x4 result; - for (int i = 0; i < 4; i++) { - for (int j = 0; j < 4; j++) { - if (i == j) { - result._arr[j][i] = 1.0; - } else { - result._arr[j][i] = 0.0; - } - } - } + result._arr[0][0] = 1.0; + result._arr[1][1] = 1.0; + result._arr[2][2] = 1.0; + result._arr[3][3] = 1.0; return result; } @@ -93,12 +88,15 @@ Matrix4x4 Matrix4x4::Translation(const Vec3D &v) { Matrix4x4 Matrix4x4::RotationX(double rx) { Matrix4x4 Rx{}; + + double c = cos(rx), s = sin(rx); + Rx._arr[0][0] = 1.0; - Rx._arr[1][1] = cos(rx); - Rx._arr[1][2] = -sin(rx); - Rx._arr[2][1] = sin(rx); - Rx._arr[2][2] = cos(rx); + Rx._arr[1][1] = c; + Rx._arr[1][2] = -s; + Rx._arr[2][1] = s; + Rx._arr[2][2] = c; Rx._arr[3][3] = 1.0; @@ -108,12 +106,14 @@ Matrix4x4 Matrix4x4::RotationX(double rx) { Matrix4x4 Matrix4x4::RotationY(double ry) { Matrix4x4 Ry{}; + double c = cos(ry), s = sin(ry); + Ry._arr[1][1] = 1.0; - Ry._arr[0][0] = cos(ry); - Ry._arr[0][2] = sin(ry); - Ry._arr[2][0] = -sin(ry); - Ry._arr[2][2] = cos(ry); + Ry._arr[0][0] = c; + Ry._arr[0][2] = s; + Ry._arr[2][0] = -s; + Ry._arr[2][2] = c; Ry._arr[3][3] = 1.0; @@ -123,12 +123,14 @@ Matrix4x4 Matrix4x4::RotationY(double ry) { Matrix4x4 Matrix4x4::RotationZ(double rz) { Matrix4x4 Rz{}; + double c = cos(rz), s = sin(rz); + Rz._arr[2][2] = 1.0; - Rz._arr[0][0] = cos(rz); - Rz._arr[0][1] = -sin(rz); - Rz._arr[1][0] = sin(rz); - Rz._arr[1][1] = cos(rz); + Rz._arr[0][0] = c; + Rz._arr[0][1] = -s; + Rz._arr[1][0] = s; + Rz._arr[1][1] = c; Rz._arr[3][3] = 1.0; @@ -143,17 +145,19 @@ Matrix4x4 Matrix4x4::Rotation(const Vec3D &v, double rv) { Matrix4x4 Rv{}; Vec3D nv(v.normalized()); - Rv._arr[0][0] = cos(rv) + (1.0 - cos(rv)) * nv.x() * nv.x(); - Rv._arr[0][1] = (1.0 - cos(rv)) * nv.x() * nv.y() - sin(rv) * nv.z(); - Rv._arr[0][2] = (1.0 - cos(rv)) * nv.x() * nv.z() + sin(rv) * nv.y(); + double c = cos(rv), s = sin(rv); - Rv._arr[1][0] = (1.0 - cos(rv)) * nv.x() * nv.y() + sin(rv) * nv.z(); - Rv._arr[1][1] = cos(rv) + (1.0 - cos(rv)) * nv.y() * nv.y(); - Rv._arr[1][2] = (1.0 - cos(rv)) * nv.y() * nv.z() - sin(rv) * nv.x(); + Rv._arr[0][0] = c + (1.0 - c) * nv.x() * nv.x(); + Rv._arr[0][1] = (1.0 - c) * nv.x() * nv.y() - s * nv.z(); + Rv._arr[0][2] = (1.0 - c) * nv.x() * nv.z() + s * nv.y(); - Rv._arr[2][0] = (1.0 - cos(rv)) * nv.z() * nv.x() - sin(rv) * nv.y(); - Rv._arr[2][1] = (1.0 - cos(rv)) * nv.z() * nv.y() + sin(rv) * nv.x(); - Rv._arr[2][2] = cos(rv) + (1.0 - cos(rv)) * nv.z() * nv.z(); + Rv._arr[1][0] = (1.0 - c) * nv.x() * nv.y() + s * nv.z(); + Rv._arr[1][1] = c + (1.0 - c) * nv.y() * nv.y(); + Rv._arr[1][2] = (1.0 - c) * nv.y() * nv.z() - s * nv.x(); + + Rv._arr[2][0] = (1.0 - c) * nv.z() * nv.x() - s * nv.y(); + Rv._arr[2][1] = (1.0 - c) * nv.z() * nv.y() + s * nv.x(); + Rv._arr[2][2] = c + (1.0 - c) * nv.z() * nv.z(); Rv._arr[3][3] = 1.0; diff --git a/engine/Mesh.cpp b/engine/Mesh.cpp index b166979..43e8f5e 100644 --- a/engine/Mesh.cpp +++ b/engine/Mesh.cpp @@ -11,10 +11,11 @@ using namespace std; Mesh &Mesh::operator*=(const Matrix4x4 &matrix4X4) { std::vector newTriangles; + newTriangles.reserve(_tris.size()); for (auto &t : _tris) { newTriangles.emplace_back(t * matrix4X4); } - setTriangles(newTriangles); + setTriangles(std::move(newTriangles)); return *this; } @@ -46,10 +47,11 @@ void Mesh::setColor(const sf::Color &c) { // change color of all mesh triangles: std::vector newTriangles; + newTriangles.reserve(_tris.size()); for (auto &t : _tris) { newTriangles.emplace_back(Triangle(t[0], t[1], t[2], c)); } - setTriangles(newTriangles); + setTriangles(std::move(newTriangles)); } Mesh @@ -99,6 +101,10 @@ void Mesh::setTriangles(const vector &t) { } } +void Mesh::setTriangles(vector&& t) { + _tris = std::move(t); +} + Mesh::~Mesh() { _tris.clear(); } diff --git a/engine/Mesh.h b/engine/Mesh.h index 1f37bea..e0d3c89 100644 --- a/engine/Mesh.h +++ b/engine/Mesh.h @@ -38,6 +38,8 @@ public: void setTriangles(const std::vector &t); + void setTriangles(std::vector&& t); + [[nodiscard]] size_t size() const { return _tris.size() * 3; } [[nodiscard]] sf::Color color() const { return _color; } diff --git a/engine/Object.cpp b/engine/Object.cpp index 3594170..0e86a6c 100644 --- a/engine/Object.cpp +++ b/engine/Object.cpp @@ -140,7 +140,7 @@ void Object::unattach(const ObjectNameTag &tag) { // OpenGL function GLfloat *Object::glView() const { - auto *v = (GLfloat *) malloc(4 * 4 * sizeof(GLfloat)); + auto *v = new GLfloat[4 * 4]; v[0] = -static_cast(left().x()); v[4] = -static_cast(left().y()); @@ -166,7 +166,7 @@ GLfloat *Object::glView() const { } GLfloat *Object::glModel() const { - auto *m = (GLfloat *) malloc(4 * 4 * sizeof(GLfloat)); + auto *m = new GLfloat[4 * 4]; m[0] = static_cast(left().x()); m[4] = static_cast(up().x()); diff --git a/engine/Screen.cpp b/engine/Screen.cpp index 9b8a308..c865de5 100644 --- a/engine/Screen.cpp +++ b/engine/Screen.cpp @@ -123,9 +123,6 @@ void Screen::drawText(const sf::Text &text) { // OpenGL functions void Screen::glDrawMesh(GLfloat *geometry, GLfloat *view, GLfloat *model, size_t count) { - // OpenGL: - // Make the window the active window for OpenGL calls - _window->setActive(true); glEnable(GL_CULL_FACE); // enable culling face glCullFace(GL_BACK); // cull faces from back @@ -171,43 +168,43 @@ void Screen::glDrawMesh(GLfloat *geometry, GLfloat *view, GLfloat *model, size_t // Draw the mesh glDrawArrays(GL_TRIANGLES, 0, count); - - // Make the window no longer the active window for OpenGL calls - _window->setActive(false); } GLfloat *Screen::glMeshToGLfloatArray(std::shared_ptr mesh, const Vec3D &cameraPosition) { std::vector const &triangles = mesh->triangles(); - auto *geometry = (GLfloat *) malloc(7 * 3 * triangles.size() * sizeof(GLfloat)); + auto *geometry = new GLfloat[7 * 3 * triangles.size()]; + + auto model = mesh->model(); for (size_t i = 0; i < triangles.size(); i++) { int stride = 21 * i; - double dot[3]; - sf::Color ambientColor[3]; - - Triangle MTriangle = triangles[i] * mesh->model(); + Triangle MTriangle = triangles[i] * model; + Vec3D norm = MTriangle.norm(); for (int k = 0; k < 3; k++) { - dot[k] = MTriangle.norm().dot((Vec3D(MTriangle[k]) - cameraPosition).normalized()); + auto& tris = MTriangle[k]; + float dot = norm.dot((Vec3D(tris) - cameraPosition).normalized()); - sf::Color color = triangles[i].color(); - ambientColor[k] = sf::Color(static_cast(color.r * (0.3 * std::abs(dot[k]) + 0.7)), - static_cast(color.g * (0.3 * std::abs(dot[k]) + 0.7)), - static_cast(color.b * (0.3 * std::abs(dot[k]) + 0.7)), - static_cast(color.a)); + sf::Color color = MTriangle.color(); + GLfloat ambientColor[4] = { + color.r * (0.3f * std::fabs(dot) + 0.7f) / 255.0f, + color.g * (0.3f * std::fabs(dot) + 0.7f) / 255.0f, + color.b * (0.3f * std::fabs(dot) + 0.7f) / 255.0f, + color.a / 255.0f + }; - geometry[stride + 7 * k + 0] = static_cast(MTriangle[k].x()); - geometry[stride + 7 * k + 1] = static_cast(MTriangle[k].y()); - geometry[stride + 7 * k + 2] = static_cast(MTriangle[k].z()); + geometry[stride + 7 * k + 0] = static_cast(tris.x()); + geometry[stride + 7 * k + 1] = static_cast(tris.y()); + geometry[stride + 7 * k + 2] = static_cast(tris.z()); - geometry[stride + 7 * k + 3] = static_cast(ambientColor[k].r) / 255.0f; - geometry[stride + 7 * k + 4] = static_cast(ambientColor[k].g) / 255.0f; - geometry[stride + 7 * k + 5] = static_cast(ambientColor[k].b) / 255.0f; - geometry[stride + 7 * k + 6] = static_cast(ambientColor[k].a) / 255.0f; + geometry[stride + 7 * k + 3] = ambientColor[0]; + geometry[stride + 7 * k + 4] = ambientColor[1]; + geometry[stride + 7 * k + 5] = ambientColor[2]; + geometry[stride + 7 * k + 6] = ambientColor[3]; } } return geometry; diff --git a/engine/Triangle.cpp b/engine/Triangle.cpp index 8d25f1a..d488553 100644 --- a/engine/Triangle.cpp +++ b/engine/Triangle.cpp @@ -30,7 +30,7 @@ Vec3D Triangle::norm() const { } } -Vec4D Triangle::operator[](int i) const { +const Vec4D& Triangle::operator[](int i) const { return _points[i]; } diff --git a/engine/Triangle.h b/engine/Triangle.h index 733ba4f..836c1c6 100644 --- a/engine/Triangle.h +++ b/engine/Triangle.h @@ -24,7 +24,7 @@ public: Triangle &operator=(const Triangle &) = default; - [[nodiscard]] Vec4D operator[](int i) const; + [[nodiscard]] const Vec4D& operator[](int i) const; [[nodiscard]] Vec3D norm() const; diff --git a/engine/Vec2D.cpp b/engine/Vec2D.cpp index ef0fd37..4305a8d 100644 --- a/engine/Vec2D.cpp +++ b/engine/Vec2D.cpp @@ -39,7 +39,7 @@ Vec2D Vec2D::operator+(const Vec2D &vec) const { } Vec2D Vec2D::operator-(const Vec2D &vec) const { - return Vec2D(*this) + -vec; + return *this + -vec; } Vec2D Vec2D::operator*(double number) const { @@ -48,7 +48,7 @@ Vec2D Vec2D::operator*(double number) const { Vec2D Vec2D::operator/(double number) const { if (std::abs(number) > Consts::EPS) { - return Vec2D(*this) * (1.0 / number); + return *this * (1.0 / number); } else { throw std::domain_error{"Vec2D::operator/(double number): division by zero"}; } @@ -64,9 +64,9 @@ double Vec2D::abs() const { } Vec2D Vec2D::normalized() const { - double vecAbs = abs(); + double vecAbs = sqrAbs(); if (vecAbs > Consts::EPS) { - return Vec2D(*this) / vecAbs; + return *this / sqrt(vecAbs); } else { return Vec2D(0); } diff --git a/engine/Vec3D.cpp b/engine/Vec3D.cpp index 3a41ca4..349c9a8 100644 --- a/engine/Vec3D.cpp +++ b/engine/Vec3D.cpp @@ -44,7 +44,7 @@ Vec3D Vec3D::operator+(const Vec3D &vec) const { } Vec3D Vec3D::operator-(const Vec3D &vec) const { - return Vec3D(*this) + -vec; + return *this + -vec; } Vec3D Vec3D::operator*(double number) const { @@ -53,7 +53,7 @@ Vec3D Vec3D::operator*(double number) const { Vec3D Vec3D::operator/(double number) const { if (std::abs(number) > Consts::EPS) { - return Vec3D(*this) * (1.0 / number); + return *this * (1.0 / number); } else { throw std::domain_error{"Vec3D::operator/(double number): division by zero"}; } @@ -69,9 +69,9 @@ double Vec3D::abs() const { } Vec3D Vec3D::normalized() const { - double vecAbs = abs(); + double vecAbs = sqrAbs(); if (vecAbs > Consts::EPS) { - return Vec3D(*this) / vecAbs; + return *this / sqrt(vecAbs); } else { return Vec3D(1); } diff --git a/engine/Vec4D.cpp b/engine/Vec4D.cpp index f9a92a6..b11321a 100644 --- a/engine/Vec4D.cpp +++ b/engine/Vec4D.cpp @@ -40,7 +40,7 @@ Vec4D Vec4D::operator+(const Vec4D &point4D) const { } Vec4D Vec4D::operator-(const Vec4D &point4D) const { - return Vec4D(*this) + -point4D; + return *this + -point4D; } Vec4D Vec4D::operator*(double number) const { @@ -49,7 +49,7 @@ Vec4D Vec4D::operator*(double number) const { Vec4D Vec4D::operator/(double number) const { if (std::abs(number) > Consts::EPS) { - return Vec4D(*this) * (1.0 / number); + return *this * (1.0 / number); } else { throw std::domain_error{"Vec4D::operator/(double number): division by zero"}; } @@ -65,9 +65,9 @@ double Vec4D::abs() const { } Vec4D Vec4D::normalized() const { - double vecAbs = abs(); + double vecAbs = sqrAbs(); if (vecAbs > Consts::EPS) { - return Vec4D(*this) / vecAbs; + return *this / sqrt(vecAbs); } else { return Vec4D(1); } diff --git a/engine/animation/AScale.h b/engine/animation/AScale.h index c559d8d..7fc24e5 100644 --- a/engine/animation/AScale.h +++ b/engine/animation/AScale.h @@ -21,12 +21,14 @@ private: return; } + auto object = _object.lock(); std::vector newTriangles; - for (auto &t : _object->triangles()) { + newTriangles.reserve(object->triangles().size()); + for (auto &t : object->triangles()) { newTriangles.emplace_back( t * Matrix4x4::Scale(Vec3D{1, 1, 1} + (_scalingValue - Vec3D{1, 1, 1}) * progress())); } - _object.lock()->setTriangles(newTriangles); + object.lock()->setTriangles(std::move(newTriangles)); } public: diff --git a/engine/physics/HitBox.cpp b/engine/physics/HitBox.cpp index 7fa21dd..9e490be 100644 --- a/engine/physics/HitBox.cpp +++ b/engine/physics/HitBox.cpp @@ -2,26 +2,28 @@ // Created by Иван Ильин on 04.11.2021. // +#include +#include + #include "HitBox.h" #include "../Consts.h" HitBox::HitBox(const Mesh &mesh) { + _hitBox.reserve(mesh.triangles().size() * 3); for(const auto& t : mesh.triangles()) { for(int i = 0; i < 3; i++) { // we dont need to add the same points in hit box _addIfUnique(Vec3D(t[i])); } } + _hitBox.shrink_to_fit(); } -void HitBox::_addIfUnique(const Vec3D &point) { - bool addPoint = true; - for(const auto& p : _hitBox) { - if(p == point) { - addPoint = false; - } - } - if(addPoint) { +void HitBox::_addIfUnique(Vec3D &&point) { + + auto check = [&point](const auto& p) { return p == point; }; + + if (std::find_if(std::execution::par, _hitBox.rbegin(), _hitBox.rend(), check) == _hitBox.rend()) { _hitBox.push_back(point); } } diff --git a/engine/physics/HitBox.h b/engine/physics/HitBox.h index 3afe05e..5af2725 100644 --- a/engine/physics/HitBox.h +++ b/engine/physics/HitBox.h @@ -11,7 +11,7 @@ class HitBox final { private: std::vector _hitBox; - void _addIfUnique(const Vec3D &point); + void _addIfUnique(Vec3D &&point); public: HitBox() = default; diff --git a/engine/physics/RigidBody.cpp b/engine/physics/RigidBody.cpp index 2150016..070f8b4 100644 --- a/engine/physics/RigidBody.cpp +++ b/engine/physics/RigidBody.cpp @@ -37,12 +37,11 @@ Vec3D RigidBody::_findFurthestPoint(const Vec3D &direction) { */ for(auto & it : _hitBox) { - auto point = Vec3D(it); - double distance = point.dot(transformedDirection); + double distance = it.dot(transformedDirection); if (distance > maxDistance) { maxDistance = distance; - maxPoint = point; + maxPoint = it; } } @@ -253,6 +252,7 @@ CollisionPoint RigidBody::EPA(const Simplex &simplex, std::shared_ptr } std::vector newFaces; + newFaces.reserve(uniqueEdges.size() * 3); for (auto[edgeIndex1, edgeIndex2] : uniqueEdges) { newFaces.push_back(edgeIndex1); newFaces.push_back(edgeIndex2); @@ -280,6 +280,7 @@ CollisionPoint RigidBody::EPA(const Simplex &simplex, std::shared_ptr std::pair, size_t> RigidBody::_getFaceNormals(const std::vector &polytope, const std::vector &faces) { std::vector normals; + normals.reserve(faces.size() / 3); size_t nearestFaceIndex = 0; double minDistance = std::numeric_limits::max();