diff --git a/Bonus.h b/Bonus.h index 27aafc0..bccc4e1 100755 --- a/Bonus.h +++ b/Bonus.h @@ -8,7 +8,7 @@ #include "World.h" #include "Player.h" -class Bonus : public Mesh { +class Bonus : public RigidBody { protected: std::string _name; public: diff --git a/Client.cpp b/Client.cpp index e15e47e..fb50a9a 100755 --- a/Client.cpp +++ b/Client.cpp @@ -15,27 +15,27 @@ void Client::updatePacket() { void Client::spawnPlayer(sf::Uint16 id) { std::string name = "Player_" + std::to_string(id); _players.insert({ id, std::make_shared() }); - (*_world).addMesh(_players[id], name); + (*_world).addBody(_players[id], name); _players[id]->setVisible(true); _players[id]->setAcceleration(Point4D{0, 0, 0}); // add head and other stuff: - _world->loadObj(name + "_head", "../obj/cube.obj", "",Point4D{0.7, 0.7, 0.7}); - (*_world)[name + "_head"]->translate(Point4D{0, 2, 0}); - (*_world)[name + "_head"]->setCollider(false); - _players[id]->attach((*_world)[name + "_head"]); + _world->loadBody(name + "_head", "../obj/cube.obj", "", Point4D{0.7, 0.7, 0.7}); + _world->body(name + "_head")->translate(Point4D{0, 2, 0}); + _world->body(name + "_head")->setCollider(false); + _players[id]->attach(_world->body(name + "_head")); - _world->loadObj(name + "_eye1", "../obj/cube.obj", "",Point4D{0.2, 0.2, 0.05}); - (*_world)[name + "_eye1"]->translate(Point4D{0.3, 2.1, 0.7}); - (*_world)[name + "_eye1"]->setCollider(false); - (*_world)[name + "_eye1"]->setColor({147, 159, 255}); - (*_world)[name + "_head"]->attach((*_world)[name + "_eye1"]); + _world->loadBody(name + "_eye1", "../obj/cube.obj", "", Point4D{0.2, 0.2, 0.05}); + _world->body(name + "_eye1")->translate(Point4D{0.3, 2.1, 0.7}); + _world->body(name + "_eye1")->setCollider(false); + _world->body(name + "_eye1")->setColor({147, 159, 255}); + _world->body(name + "_head")->attach(_world->body(name + "_eye1")); - _world->loadObj(name + "_eye2", "../obj/cube.obj", "",Point4D{0.2, 0.2, 0.05}); - (*_world)[name + "_eye2"]->translate(Point4D{-0.3, 2.1, 0.7}); - (*_world)[name + "_eye2"]->setCollider(false); - (*_world)[name + "_eye2"]->setColor({147, 159, 255}); - (*_world)[name + "_head"]->attach((*_world)[name + "_eye2"]); + _world->loadBody(name + "_eye2", "../obj/cube.obj", "", Point4D{0.2, 0.2, 0.05}); + _world->body(name + "_eye2")->translate(Point4D{-0.3, 2.1, 0.7}); + _world->body(name + "_eye2")->setCollider(false); + _world->body(name + "_eye2")->setColor({147, 159, 255}); + _world->body(name + "_head")->attach(_world->body(name + "_eye2")); } void Client::processInit(sf::Packet& packet) { @@ -64,7 +64,7 @@ void Client::processUpdate(sf::Packet& packet) { _players[targetId]->setHealth(buf[3]); _players[targetId]->rotateToAngle(Point4D{0, buf[4], 0}); - (*_world)[name + "_head"]->rotate(Matrix4x4::RotationY(buf[4]) * Point4D{1, 0, 0}, + _world->body(name + "_head")->rotate(Matrix4x4::RotationY(buf[4]) * Point4D{1, 0, 0}, buf[5] - _players[targetId]->headAngle()); _players[targetId]->setHeadAngle(buf[5]); } else if (targetId == _socket.ownId()) { @@ -84,10 +84,10 @@ void Client::processNewClient(sf::Packet& packet) { void Client::processDisconnect(sf::Uint16 targetId) { if (targetId != _socket.ownId() && _players.count(targetId)) { std::string name = "Player_" + std::to_string(targetId); - _world->removeMesh(name); - _world->removeMesh(name + "_head"); - _world->removeMesh(name + "_eye1"); - _world->removeMesh(name + "_eye2"); + _world->removeBody(name); + _world->removeBody(name + "_head"); + _world->removeBody(name + "_eye1"); + _world->removeBody(name + "_eye2"); _players.erase(targetId); } @@ -128,18 +128,19 @@ void Client::processCustomPacket(MsgType type, sf::Packet& packet) { p2 = Point4D(dbuff[3], dbuff[4], dbuff[5]); tmp = "Client_fireTraces_" + std::to_string(fireTraces++); - _world->addMesh(std::make_shared(Mesh::LineTo(p1, p2, 0.05)), tmp); - (*_world)[tmp]->setCollider(false); + _world->addBody(std::make_shared(RigidBody(Mesh::LineTo(p1, p2, 0.05))), tmp); + _world->body(tmp)->setCollider(false); - (*_world)[tmp]->a_color(tmp + "_fadeOut", {255, 255, 255, 0}, 1, Animation::None, Animation::linear); - (*_world)["Player_im"]->a_function(tmp + "delete", [this, tmp](){ deleteTrace(_world, tmp); }, 1, 2); + _world->body(tmp)->a_color(tmp + "_fadeOut", {255, 255, 255, 0}, 1, Animation::None, Animation::linear); + _world->body("Player_im")->a_function(tmp + "delete", [this, tmp](){ deleteTrace(_world, tmp); }, 1, 2); break; case MsgType::InitBonuses: while (packet >> tmp >> dbuff[0] >> dbuff[1] >> dbuff[2]) { tmp2 = tmp.substr(6, tmp.size()-3-5); - _world->addMesh(std::make_shared(tmp, "../obj/" + tmp2 + ".obj", "../obj/" + tmp2 + "_mat.txt", Point4D{3, 3, 3}), tmp); - (*_world)[tmp]->translateToPoint(Point4D(dbuff[0], dbuff[1], dbuff[2])); + _world->addBody(std::make_shared(tmp, "../obj/" + tmp2 + ".obj", "../obj/" + tmp2 + "_mat.txt", + Point4D{3, 3, 3}), tmp); + _world->body(tmp)->translateToPoint(Point4D(dbuff[0], dbuff[1], dbuff[2])); } break; @@ -147,13 +148,14 @@ void Client::processCustomPacket(MsgType type, sf::Packet& packet) { packet >> tmp >> dbuff[0] >> dbuff[1] >> dbuff[2]; tmp2 = tmp.substr(6, tmp.size()-3-5); - _world->addMesh(std::make_shared(tmp, "../obj/" + tmp2 + ".obj", "../obj/" + tmp2 + "_mat.txt", Point4D{3, 3, 3}), tmp); - (*_world)[tmp]->translateToPoint(Point4D(dbuff[0], dbuff[1], dbuff[2])); + _world->addBody(std::make_shared(tmp, "../obj/" + tmp2 + ".obj", "../obj/" + tmp2 + "_mat.txt", + Point4D{3, 3, 3}), tmp); + _world->body(tmp)->translateToPoint(Point4D(dbuff[0], dbuff[1], dbuff[2])); break; case MsgType::RemoveBonus: packet >> tmp; - _world->removeMesh(tmp); + _world->removeBody(tmp); break; } } @@ -162,10 +164,10 @@ void Client::processDisconnected() { for (auto it = _players.begin(); it != _players.end();) { std::string name = "Player_" + std::to_string(it->first); - _world->removeMesh(name); - _world->removeMesh(name + "_head"); - _world->removeMesh(name + "_eye1"); - _world->removeMesh(name + "_eye2"); + _world->removeBody(name); + _world->removeBody(name + "_head"); + _world->removeBody(name + "_eye1"); + _world->removeBody(name + "_eye2"); _players.erase(it++); } } @@ -187,7 +189,7 @@ void Client::addTrace(const Point4D& from, const Point4D& to) { } void Client::deleteTrace(std::shared_ptr world, const std::string &traceName) { - world->removeMesh(traceName); + world->removeBody(traceName); } void Client::takeBonus(const std::string& bonusName) { diff --git a/Client.h b/Client.h index 9350cb6..ee517c8 100755 --- a/Client.h +++ b/Client.h @@ -21,7 +21,7 @@ private: void spawnPlayer(sf::Uint16 id); public: - Client(std::shared_ptr player, std::shared_ptr world) : _player(std::move(player)), _world(std::move(world)) {}; + Client(std::shared_ptr player, std::shared_ptr world) : _player(player), _world(world) {}; void updatePacket() override; diff --git a/Player.cpp b/Player.cpp index 2254028..8427d90 100755 --- a/Player.cpp +++ b/Player.cpp @@ -11,28 +11,28 @@ void Player::update() { // friction if(inCollision()) - p_velocity = p_velocity - p_velocity*Time::deltaTime()*2; + _velocity = _velocity - _velocity * Time::deltaTime() * 2; - if(isInSlowMo) { + if(_isInSlowMo) { if(_ability > 0) _ability -= Time::deltaTime(); else { _ability = 0; - isInSlowMo = false; - setVelocity(velocity()*slowMoCoefficient); - setAcceleration(p_acceleration*slowMoCoefficient*slowMoCoefficient); - slowMoSound.stop(); - unSlowMoSound.play(); + _isInSlowMo = false; + setVelocity(velocity() * _slowMoCoefficient); + setAcceleration(_acceleration * _slowMoCoefficient * _slowMoCoefficient); + _slowMoSound.stop(); + _unSlowMoSound.play(); } } - double coeff = isInSlowMo ? 1.0/slowMoCoefficient : 1.0; + double coeff = _isInSlowMo ? 1.0 / _slowMoCoefficient : 1.0; - bool inRunning_old = inRunning; - inRunning = _screen != nullptr && (Screen::isKeyPressed(sf::Keyboard::A) || Screen::isKeyPressed(sf::Keyboard::D) ||Screen::isKeyPressed(sf::Keyboard::W) || Screen::isKeyPressed(sf::Keyboard::S)); + bool inRunning_old = _inRunning; + _inRunning = _screen != nullptr && (Screen::isKeyPressed(sf::Keyboard::A) || Screen::isKeyPressed(sf::Keyboard::D) || Screen::isKeyPressed(sf::Keyboard::W) || Screen::isKeyPressed(sf::Keyboard::S)); // in case when the camera is attached we make some animation during running - if(_camera != nullptr && inRunning && !_camera->isInAnim()) { + if(_camera != nullptr && _inRunning && !_camera->isInAnim()) { _camera->a_translate("hor_oscil", -_camera->left()/12, 0.3/coeff, Animation::LoopOut::None, Animation::cos); _camera->a_wait("hor_oscil", 0); _camera->a_translate("hor_oscil", _camera->left()/12, 0.3/coeff, Animation::LoopOut::None, Animation::cos); @@ -47,7 +47,7 @@ void Player::update() { _camera->a_translateToPoint("init", position() + Point4D{0, 1.8, 0}, 0.3/coeff, Animation::None, Animation::cos); - } else if(_camera != nullptr && inRunning_old && !inRunning) { + } else if(_camera != nullptr && inRunning_old && !_inRunning) { _camera->a_stopAllAnimations(); _camera->a_translateToPoint("init", position() + Point4D{0, 1.8, 0}, 0.15/coeff, Animation::None, Animation::cos); @@ -58,55 +58,55 @@ void Player::update() { if(_world != nullptr && _screen != nullptr && _camera != nullptr) { // Left and right if (Screen::isKeyPressed(sf::Keyboard::A)) { - translate(_camera->left() * Time::deltaTime() * walkSpeed * coeff); + translate(_camera->left() * Time::deltaTime() * _walkSpeed * coeff); if(inCollision()) setVelocity(Point4D{0,0,0}); } if (Screen::isKeyPressed(sf::Keyboard::D)) { - translate(-_camera->left() * Time::deltaTime() * walkSpeed * coeff); + translate(-_camera->left() * Time::deltaTime() * _walkSpeed * coeff); if(inCollision()) setVelocity(Point4D{0,0,0}); } // Forward and backward if (Screen::isKeyPressed(sf::Keyboard::W)) { - translate(_camera->left().cross3D(Point4D{0, 1, 0}) * Time::deltaTime() * walkSpeed * coeff); + translate(_camera->left().cross3D(Point4D{0, 1, 0}) * Time::deltaTime() * _walkSpeed * coeff); if(inCollision()) setVelocity(Point4D{0,0,0}); } if (Screen::isKeyPressed(sf::Keyboard::S)) { - translate(-_camera->left().cross3D(Point4D{0, 1, 0}) * Time::deltaTime() * walkSpeed * coeff); + translate(-_camera->left().cross3D(Point4D{0, 1, 0}) * Time::deltaTime() * _walkSpeed * coeff); if(inCollision()) setVelocity(Point4D{0,0,0}); } - if (_ability > 0 && !isInSlowMo && Screen::isKeyPressed(sf::Keyboard::LShift)) { + if (_ability > 0 && !_isInSlowMo && Screen::isKeyPressed(sf::Keyboard::LShift)) { // slow mo - isInSlowMo = true; - setVelocity(velocity()/slowMoCoefficient); - setAcceleration(p_acceleration/(slowMoCoefficient*slowMoCoefficient)); - unSlowMoSound.stop(); - slowMoSound.play(); - } else if (isInSlowMo && !Screen::isKeyPressed(sf::Keyboard::LShift)) { - isInSlowMo = false; - setVelocity(velocity()*slowMoCoefficient); - setAcceleration(p_acceleration*slowMoCoefficient*slowMoCoefficient); - slowMoSound.stop(); - unSlowMoSound.play(); + _isInSlowMo = true; + setVelocity(velocity() / _slowMoCoefficient); + setAcceleration(_acceleration / (_slowMoCoefficient * _slowMoCoefficient)); + _unSlowMoSound.stop(); + _slowMoSound.play(); + } else if (_isInSlowMo && !Screen::isKeyPressed(sf::Keyboard::LShift)) { + _isInSlowMo = false; + setVelocity(velocity() * _slowMoCoefficient); + setAcceleration(_acceleration * _slowMoCoefficient * _slowMoCoefficient); + _slowMoSound.stop(); + _unSlowMoSound.play(); } if (Screen::isKeyPressed(sf::Keyboard::Space) && inCollision()) { - addVelocity(Point4D{0, std::abs(_collisionNormal.y())*sqrt(2 * g * jumpHeight)*coeff, 0}); - translate(Point4D{0, Time::deltaTime() * walkSpeed * 2 * coeff, 0}); + addVelocity(Point4D{0, std::abs(_collisionNormal.y()) * sqrt(2 * _g * _jumpHeight) * coeff, 0}); + translate(Point4D{0, Time::deltaTime() * _walkSpeed * 2 * coeff, 0}); } // Mouse movement Point4D disp = _screen->getMouseDisplacement(); rotate(Point4D{0, -disp.x() / 1000.0, 0}); - p_velocity = Matrix4x4::RotationY(-disp.x() / 1000.0)*p_velocity; + _velocity = Matrix4x4::RotationY(-disp.x() / 1000.0) * _velocity; double rotationLeft = disp.y() / 1000.0; @@ -126,7 +126,7 @@ void Player::update() { _selectedWeapon = (_selectedWeapon + 1) % _weapons.size(); _weapons[_selectedWeapon]->addToWorld(_world); Log::log("selected _selectedWeapon " + std::to_string(_selectedWeapon)); - changeWeaponSound.play(); + _changeWeaponSound.play(); } } @@ -140,7 +140,7 @@ void Player::update() { _selectedWeapon = _weapons.size() - 1; _weapons[_selectedWeapon]->addToWorld(_world); Log::log("selected _selectedWeapon " + std::to_string(_selectedWeapon)); - changeWeaponSound.play(); + _changeWeaponSound.play(); } } @@ -148,7 +148,7 @@ void Player::update() { auto damagedPlayers = _weapons[_selectedWeapon]->fire(_world, _camera); for(auto& damagedPlayer : damagedPlayers) { sf::Uint16 targetId = std::stoi(damagedPlayer.first.substr(7)); - damagePlayerCallBack(targetId, damagedPlayer.second); + _damagePlayerCallBack(targetId, damagedPlayer.second); } } @@ -156,11 +156,11 @@ void Player::update() { _weapons[_selectedWeapon]->reload(); } - if (inRunning && inCollision() && walkSound.getStatus() != sf::Sound::Status::Playing) { + if (_inRunning && inCollision() && _walkSound.getStatus() != sf::Sound::Status::Playing) { if ((position() - rayToFloor.first).abs() < 2) { int soundNum = round((double) rand() / RAND_MAX * 5) + 1; - walkSound.setBuffer(*ResourceManager::loadSoundBuffer("../sound/stonestep" + std::to_string(soundNum) + ".ogg")); - walkSound.play(); + _walkSound.setBuffer(*ResourceManager::loadSoundBuffer("../sound/stonestep" + std::to_string(soundNum) + ".ogg")); + _walkSound.play(); } } } @@ -248,7 +248,7 @@ void Player::drawStats() { text_ammo2.setFillColor(sf::Color(0, 0, 0, 70)); _screen->window.draw(text_ammo2); - // text killSound/deathSound stats + // text _killSound/_deathSound stats sf::Text text_kills(text_health); text_kills.setStyle(sf::Text::Bold); text_kills.setString("KILLS: " + std::to_string((int)_kills) + " | " + "DEATHS: " + std::to_string((int)_deaths)); @@ -267,16 +267,16 @@ void Player::drawStats() { } void Player::playDeath() { - deathSound.setBuffer(*ResourceManager::loadSoundBuffer("../sound/classic_hurt.ogg")); - deathSound.play(); + _deathSound.setBuffer(*ResourceManager::loadSoundBuffer("../sound/classic_hurt.ogg")); + _deathSound.play(); } void Player::playKill() { - killSound.setBuffer(*ResourceManager::loadSoundBuffer("../sound/kill.ogg")); - killSound.play(); + _killSound.setBuffer(*ResourceManager::loadSoundBuffer("../sound/kill.ogg")); + _killSound.play(); } -void Player::collisionWithObject(const std::string &objName, std::shared_ptr obj) { +void Player::collisionWithObject(const std::string &objName, std::shared_ptr obj) { if(objName.find("Bonus_gun") != std::string::npos) addWeapon(std::make_shared()); @@ -299,13 +299,13 @@ void Player::collisionWithObject(const std::string &objName, std::shared_ptrremoveMesh(objName); - takeBonusCallBack(objName); + _world->removeBody(objName); + _takeBonusCallBack(objName); } } void Player::addWeapon(std::shared_ptr weapon) { - changeWeaponSound.play(); + _changeWeaponSound.play(); if(!_weapons.empty()) { for(auto& w : _weapons) { @@ -320,11 +320,11 @@ void Player::addWeapon(std::shared_ptr weapon) { _weapons.back()->attachToPlayer(*this); _weapons.back()->translate(position()); - _weapons.back()->rotateRelativePoint(position() + Point4D{0, 1.8, 0}, Point4D{0, 1, 0}, p_angle.y()); + _weapons.back()->rotateRelativePoint(position() + Point4D{0, 1.8, 0}, Point4D{0, 1, 0}, _angle.y()); _weapons.back()->rotateRelativePoint(position() + Point4D{0, 1.8, 0}, _camera->left(), _camera->angleLeftUpLookAt().x()); - _weapons.back()->setAddTraceCallBack(addTraceCallBack); - changeWeaponSound.play(); + _weapons.back()->setAddTraceCallBack(_addTraceCallBack); + _changeWeaponSound.play(); } void Player::initWeapons() { diff --git a/Player.h b/Player.h index 03c2c88..d2e7bab 100755 --- a/Player.h +++ b/Player.h @@ -8,7 +8,6 @@ #include #include #include -#include "Mesh.h" #include "Camera.h" #include "World.h" #include "weapon/Ak47.h" @@ -17,7 +16,7 @@ #include "weapon/Gold_Ak47.h" #include "weapon/Rifle.h" -class Player : public Mesh{ +class Player : public RigidBody{ private: double _healthMax = 100; double _health = _healthMax; @@ -25,80 +24,80 @@ private: double _abilityMax = 10; double _ability = _abilityMax; - double jumpHeight = 3; - double walkSpeed = 10; + double _jumpHeight = 3; + double _walkSpeed = 10; double _headAngle = 0; unsigned _kills = 0; unsigned _deaths = 0; - double g = 35; + double _g = 35; - double slowMoCoefficient = 5; - bool isInSlowMo = false; + double _slowMoCoefficient = 5; + bool _isInSlowMo = false; std::shared_ptr _camera; std::shared_ptr _screen; std::shared_ptr _world; - bool inRunning = false; + bool _inRunning = false; // sounds - sf::Sound killSound; - sf::Sound deathSound; - sf::Sound walkSound; - sf::Sound changeWeaponSound; - sf::Sound slowMoSound; - sf::Sound unSlowMoSound; - sf::Sound fullHealthSound; - sf::Sound fullAbilitySound; + sf::Sound _killSound; + sf::Sound _deathSound; + sf::Sound _walkSound; + sf::Sound _changeWeaponSound; + sf::Sound _slowMoSound; + sf::Sound _unSlowMoSound; + sf::Sound _fullHealthSound; + sf::Sound _fullAbilitySound; std::string _name = "im"; std::vector> _weapons; uint8_t _selectedWeapon = 0; - std::function damagePlayerCallBack; - std::function addTraceCallBack; - std::function takeBonusCallBack; + std::function _damagePlayerCallBack; + std::function _addTraceCallBack; + std::function _takeBonusCallBack; public: Player() { loadObj("../obj/cube.obj", "", Point4D{0.5, 1.9, 0.5}); - setAcceleration(Point4D{0, -g, 0}); + setAcceleration(Point4D{0, -_g, 0}); setCollision(true); setVisible(false); setColor({240, 168, 168}); + + _changeWeaponSound.setBuffer(*ResourceManager::loadSoundBuffer("../sound/weapons/change_weapon.ogg")); + + _slowMoSound.setBuffer(*ResourceManager::loadSoundBuffer("../sound/slow_mo.ogg")); + _unSlowMoSound.setBuffer(*ResourceManager::loadSoundBuffer("../sound/unslow_mo.ogg")); + + _fullHealthSound.setBuffer(*ResourceManager::loadSoundBuffer("../sound/fullHealth.ogg")); + _fullAbilitySound.setBuffer(*ResourceManager::loadSoundBuffer("../sound/fullAbility.ogg")); + + setCollisionCallBack([this](const std::string& objName, std::shared_ptr obj) {collisionWithObject(objName, obj);}); }; void update(); void attachCamera(std::shared_ptr camera, std::shared_ptr screen) { - _camera = std::move(camera); - _screen = std::move(screen); + _camera = camera; + _screen = screen; _camera->translateToPoint(position() + Point4D{0, 1.8, 0}); this->attach(_camera); } void attachWorld(std::shared_ptr world, const Point4D& pos = Point4D{0, 30, 0}) { - _world = std::move(world); + _world = world; translate(pos); initWeapons(); - - changeWeaponSound.setBuffer(*ResourceManager::loadSoundBuffer("../sound/weapons/change_weapon.ogg")); - - slowMoSound.setBuffer(*ResourceManager::loadSoundBuffer("../sound/slow_mo.ogg")); - unSlowMoSound.setBuffer(*ResourceManager::loadSoundBuffer("../sound/unslow_mo.ogg")); - - fullHealthSound.setBuffer(*ResourceManager::loadSoundBuffer("../sound/fullHealth.ogg")); - fullAbilitySound.setBuffer(*ResourceManager::loadSoundBuffer("../sound/fullAbility.ogg")); - - setCollisionCallBack([this](const std::string& objName, std::shared_ptr obj) {collisionWithObject(objName, std::move(obj));}); } void setHealth(double h) { @@ -110,24 +109,24 @@ public: void setFullHealth() { _health = _healthMax; - fullHealthSound.play(); + _fullHealthSound.play(); } void setFullAbility() { _ability = _abilityMax; - fullAbilitySound.play(); + _fullAbilitySound.play(); } void setDamagePlayerCallBack(std::function hit) { - damagePlayerCallBack = std::move(hit); + _damagePlayerCallBack = std::move(hit); } void setAddTraceCallBack(std::function add) { - addTraceCallBack = std::move(add); + _addTraceCallBack = std::move(add); } void setTakeBonusCallBack(std::function take) { - takeBonusCallBack = std::move(take); + _takeBonusCallBack = std::move(take); } [[nodiscard]] double health() const { return _health; } @@ -151,7 +150,7 @@ public: void playDeath(); void playKill(); - void collisionWithObject(const std::string& objName, std::shared_ptr obj); + void collisionWithObject(const std::string& objName, std::shared_ptr obj); void addWeapon(std::shared_ptr weapon); diff --git a/engine/Camera.cpp b/engine/Camera.cpp index 5aa0978..ff65b70 100755 --- a/engine/Camera.cpp +++ b/engine/Camera.cpp @@ -5,25 +5,25 @@ #include "Camera.h" #include "utils/Log.h" -std::vector &Camera::project(Mesh& mesh, Screen::ViewMode mode) { +std::vector &Camera::project(std::shared_ptr mesh) { - if(!ready) { - Log::log("Camera::project(): cannot project tris without camera initialization ( Camera::init() ) "); - return this->triangles; + if(!_ready) { + Log::log("Camera::project(): cannot project _tris without camera initialization ( Camera::init() ) "); + return this->_triangles; } - if(!mesh.isVisible()) - return this->triangles; + if(!mesh->isVisible()) + return this->_triangles; - // Model transform matrix: translate tris in the origin of mesh. - Matrix4x4 M = Matrix4x4::Translation(mesh.position()); - VM = V * M; + // Model transform matrix: translate _tris in the origin of body. + Matrix4x4 M = Matrix4x4::Translation(mesh->position()); + Matrix4x4 VM = _V * M; // We don't want to waste time re-allocating memory every time std::vector clippedTriangles, tempBuffer; - for(auto& t : mesh.triangles()) { + for(auto& t : mesh->triangles()) { - double dot = t.norm().dot((mesh.position() + t[0] - p_position).normalized()); + double dot = t.norm().dot((mesh->position() + t[0] - _position).normalized()); if(dot > 0) continue; @@ -32,10 +32,10 @@ std::vector &Camera::project(Mesh& mesh, Screen::ViewMode mode) { // It needs to be cleared because it's reused through iterations. Usually it doesn't free memory. clippedTriangles.clear(); - // 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 + // In the beginning we need to to translate drawTriangle from world coordinate to our camera system: + // After that we apply clipping for all planes from _clipPlanes clippedTriangles.emplace_back(t * VM); - for(auto& plane : clipPlanes) + for(auto& plane : _clipPlanes) { while(!clippedTriangles.empty()) { @@ -51,60 +51,59 @@ std::vector &Camera::project(Mesh& mesh, Screen::ViewMode mode) { } for(auto& clippedTriangle : clippedTriangles) { - if(mode != Screen::ViewMode::Clipped) { - clippedTriangle.color = sf::Color(clippedTriangle.color.r * (0.3 * std::abs(dot) + 0.7), - clippedTriangle.color.g * (0.3 * std::abs(dot) + 0.7), - clippedTriangle.color.b * (0.3 * std::abs(dot) + 0.7), - (mode == Screen::ViewMode::Transparency || - mode == Screen::ViewMode::Normals) ? 100 : clippedTriangle.color.a); - } + sf::Color color = clippedTriangle.color(); + sf::Color ambientColor = sf::Color(color.r * (0.3 * std::abs(dot) + 0.7), + color.g * (0.3 * std::abs(dot) + 0.7), + color.b * (0.3 * std::abs(dot) + 0.7), + color.a); - // Finally its time to project our clipped colored triangle from 3D -> 2D + // Finally its time to project our clipped colored drawTriangle from 3D -> 2D // and transform it's coordinate to screen space (in pixels): - clippedTriangle *= SP; + clippedTriangle = clippedTriangle * _SP; - clippedTriangle[0] = clippedTriangle[0] / clippedTriangle[0].w(); - clippedTriangle[1] = clippedTriangle[1] / clippedTriangle[1].w(); - clippedTriangle[2] = clippedTriangle[2] / clippedTriangle[2].w(); + clippedTriangle = Triangle(clippedTriangle[0] / clippedTriangle[0].w(), + clippedTriangle[1] / clippedTriangle[1].w(), + clippedTriangle[2] / clippedTriangle[2].w(), + ambientColor); - triangles.emplace_back(clippedTriangle); + _triangles.emplace_back(clippedTriangle); } } - return this->triangles; + return this->_triangles; } 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. // Because here we calculate matrix that does not change during the motion of _objects or camera - w = width; h = height; - aspect = (double)width / (double)height; - P = Matrix4x4::Projection(fov, aspect, ZNear, ZFar); - S = Matrix4x4::ScreenSpace(width, height); + _w = width; _h = height; + _aspect = (double)width / (double)height; + _P = Matrix4x4::Projection(fov, _aspect, ZNear, ZFar); + _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. - // Motivation: we are not interest in tris that we cannot see. - clipPlanes.emplace_back(Plane(Point4D{0, 0, 1}, Point4D{0, 0, ZNear})); // near plane - clipPlanes.emplace_back(Plane(Point4D{0, 0, -1}, Point4D{0, 0, ZFar})); // far plane + // This is planes for clipping _tris. + // Motivation: we are not interest in _tris that we cannot see. + _clipPlanes.emplace_back(Plane(Point4D{0, 0, 1}, Point4D{0, 0, ZNear})); // near plane + _clipPlanes.emplace_back(Plane(Point4D{0, 0, -1}, Point4D{0, 0, ZFar})); // far plane double thetta1 = M_PI*fov*0.5/180.0; - double thetta2 = atan(aspect*tan(thetta1)); - clipPlanes.emplace_back(Plane(Point4D{-cos(thetta2), 0, sin(thetta2)}, Point4D{0, 0, 0})); // left plane - clipPlanes.emplace_back(Plane(Point4D{cos(thetta2), 0, sin(thetta2)}, Point4D{0, 0, 0})); // right plane - clipPlanes.emplace_back(Plane(Point4D{0, cos(thetta1), sin(thetta1)}, Point4D{0, 0, 0})); // down plane - clipPlanes.emplace_back(Plane(Point4D{0, -cos(thetta1), sin(thetta1)},Point4D{0, 0, 0})); // up plane + double thetta2 = atan(_aspect * tan(thetta1)); + _clipPlanes.emplace_back(Plane(Point4D{-cos(thetta2), 0, sin(thetta2)}, Point4D{0, 0, 0})); // left plane + _clipPlanes.emplace_back(Plane(Point4D{cos(thetta2), 0, sin(thetta2)}, Point4D{0, 0, 0})); // right plane + _clipPlanes.emplace_back(Plane(Point4D{0, cos(thetta1), sin(thetta1)}, Point4D{0, 0, 0})); // down plane + _clipPlanes.emplace_back(Plane(Point4D{0, -cos(thetta1), sin(thetta1)}, Point4D{0, 0, 0})); // up plane - ready = true; + _ready = true; Log::log("Camera::init(): camera successfully initialized."); } std::vector &Camera::sorted() { - // Sort tris from back to front + // Sort _tris from back to front // This is some replacement for Z-buffer - std::sort(triangles.begin(), triangles.end(), [](Triangle &t1, Triangle &t2) + std::sort(_triangles.begin(), _triangles.end(), [](Triangle &t1, Triangle &t2) { std::vector v_z1({t1[0].z(), t1[1].z(), t1[2].z()}); std::vector v_z2({t2[0].z(), t2[1].z(), t2[2].z()}); @@ -118,44 +117,44 @@ std::vector &Camera::sorted() { return z1 > z2; }); - return triangles; + return _triangles; } -void Camera::record() { - // Cleaning all tris and recalculation of View matrix +void Camera::clear() { + // 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(); - V = Matrix4x4::View(p_left, p_up, p_lookAt, p_position); + _triangles.clear(); + _V = Matrix4x4::View(_left, _up, _lookAt, _position); } void Camera::rotateX(double rx) { - p_angle = Point4D{p_angle.x() + rx, p_angle.y(), p_angle.z()}; - p_left = Matrix4x4::RotationX(rx) * p_left; - p_up = Matrix4x4::RotationX(rx) * p_up; - p_lookAt = Matrix4x4::RotationX(rx) * p_lookAt; + _angle = Point4D{_angle.x() + rx, _angle.y(), _angle.z()}; + _left = Matrix4x4::RotationX(rx) * _left; + _up = Matrix4x4::RotationX(rx) * _up; + _lookAt = Matrix4x4::RotationX(rx) * _lookAt; - for(auto attached : v_attached) + for(auto attached : _attachedObjects) attached->rotateRelativePoint(position(), Point4D{rx, 0, 0}); } void Camera::rotateY(double ry) { - p_angle = Point4D{p_angle.x(), p_angle.y() + ry, p_angle.z()}; - p_left = Matrix4x4::RotationY(ry) * p_left; - p_up = Matrix4x4::RotationY(ry) * p_up; - p_lookAt = Matrix4x4::RotationY(ry) * p_lookAt; + _angle = Point4D{_angle.x(), _angle.y() + ry, _angle.z()}; + _left = Matrix4x4::RotationY(ry) * _left; + _up = Matrix4x4::RotationY(ry) * _up; + _lookAt = Matrix4x4::RotationY(ry) * _lookAt; - for(auto attached : v_attached) + for(auto attached : _attachedObjects) attached->rotateRelativePoint(position(), Point4D{0, ry, 0}); } void Camera::rotateZ(double rz) { - p_angle = Point4D{p_angle.x(), p_angle.y(), p_angle.z() + rz}; - p_left = Matrix4x4::RotationZ(rz) * p_left; - p_up = Matrix4x4::RotationZ(rz) * p_up; - p_lookAt = Matrix4x4::RotationZ(rz) * p_lookAt; + _angle = Point4D{_angle.x(), _angle.y(), _angle.z() + rz}; + _left = Matrix4x4::RotationZ(rz) * _left; + _up = Matrix4x4::RotationZ(rz) * _up; + _lookAt = Matrix4x4::RotationZ(rz) * _lookAt; - for(auto attached : v_attached) + for(auto attached : _attachedObjects) attached->rotateRelativePoint(position(), Point4D{0, 0, rz}); } @@ -167,69 +166,69 @@ void Camera::rotate(const Point4D& r) { void Camera::rotate(const Point4D& v, double rv) { - p_left = Matrix4x4::Rotation(v, rv) * p_left; - p_up = Matrix4x4::Rotation(v, rv) * p_up; - p_lookAt = Matrix4x4::Rotation(v, rv) * p_lookAt; + _left = Matrix4x4::Rotation(v, rv) * _left; + _up = Matrix4x4::Rotation(v, rv) * _up; + _lookAt = Matrix4x4::Rotation(v, rv) * _lookAt; - for(auto attached : v_attached) + for(auto attached : _attachedObjects) attached->rotateRelativePoint(position(), v, rv); } void Camera::rotateLeft(double rl) { - p_angleLeftUpLookAt = Point4D{p_angleLeftUpLookAt.x() + rl, p_angleLeftUpLookAt.y(), p_angleLeftUpLookAt.z()}; + _angleLeftUpLookAt = Point4D{_angleLeftUpLookAt.x() + rl, _angleLeftUpLookAt.y(), _angleLeftUpLookAt.z()}; - rotate(p_left, rl); + rotate(_left, rl); - for(auto attached : v_attached) - attached->rotateRelativePoint(position(), p_left, rl); + for(auto attached : _attachedObjects) + attached->rotateRelativePoint(position(), _left, rl); } void Camera::rotateUp(double ru) { - p_angleLeftUpLookAt = Point4D{p_angleLeftUpLookAt.x(), p_angleLeftUpLookAt.y() + ru, p_angleLeftUpLookAt.z()}; - rotate(p_up, ru); + _angleLeftUpLookAt = Point4D{_angleLeftUpLookAt.x(), _angleLeftUpLookAt.y() + ru, _angleLeftUpLookAt.z()}; + rotate(_up, ru); - for(auto attached : v_attached) - attached->rotateRelativePoint(position(), p_up, ru); + for(auto attached : _attachedObjects) + attached->rotateRelativePoint(position(), _up, ru); } void Camera::rotateLookAt(double rlAt) { - p_angleLeftUpLookAt = Point4D{p_angleLeftUpLookAt.x(), p_angleLeftUpLookAt.y(), p_angleLeftUpLookAt.z() + rlAt}; - rotate(p_lookAt, rlAt); + _angleLeftUpLookAt = Point4D{_angleLeftUpLookAt.x(), _angleLeftUpLookAt.y(), _angleLeftUpLookAt.z() + rlAt}; + rotate(_lookAt, rlAt); - for(auto attached : v_attached) - attached->rotateRelativePoint(position(), p_lookAt, rlAt); + for(auto attached : _attachedObjects) + attached->rotateRelativePoint(position(), _lookAt, rlAt); } void Camera::rotateRelativePoint(const Point4D &s, const Point4D &r) { - p_angle = p_angle + r; + _angle = _angle + r; // Translate XYZ by vector r1 - Point4D r1 = p_position - s; + Point4D r1 = _position - s; // In translated coordinate system we rotate camera and position Point4D r2 = Matrix4x4::Rotation(r)*r1; rotate(r); // After rotation we translate XYZ by vector -r2 and recalculate position - p_position = s + r2; + _position = s + r2; - for(auto attached : v_attached) + for(auto attached : _attachedObjects) attached->rotateRelativePoint(s, r); } void Camera::rotateRelativePoint(const Point4D &s, const Point4D &v, double r) { // Translate XYZ by vector r1 - Point4D r1 = p_position - s; + Point4D r1 = _position - s; // In translated coordinate system we rotate camera and position Point4D r2 = Matrix4x4::Rotation(v, r)*r1; rotate(v, r); // After rotation we translate XYZ by vector -r2 and recalculate position - p_position = s + r2; + _position = s + r2; - for(auto attached : v_attached) + for(auto attached : _attachedObjects) attached->rotateRelativePoint(s, v, r); } void Camera::translateToPoint(const Point4D &point) { - translate(point - p_position); + translate(point - _position); } diff --git a/engine/Camera.h b/engine/Camera.h index 5162557..9f3ccee 100755 --- a/engine/Camera.h +++ b/engine/Camera.h @@ -12,29 +12,28 @@ class Camera : public Object, public Animatable{ private: - Point4D p_angleLeftUpLookAt; + Point4D _angleLeftUpLookAt; - Point4D p_left = Point4D{1, 0, 0, 0}; // internal X - Point4D p_up = Point4D{0, 1, 0, 0}; // internal Y - Point4D p_lookAt = Point4D{0, 0, 1, 0}; // internal Z + Point4D _left = Point4D{1, 0, 0, 0}; // internal X + Point4D _up = Point4D{0, 1, 0, 0}; // internal Y + Point4D _lookAt = Point4D{0, 0, 1, 0}; // internal Z - Matrix4x4 S; // screen space matrix - Matrix4x4 P; // projections matrix - Matrix4x4 V; // camera matrix + Matrix4x4 _S; // screen space matrix + Matrix4x4 _P; // projections matrix + Matrix4x4 _V; // camera matrix - double aspect = 0; + double _aspect = 0; // To accelerate calculations we can use precalculated matrix that does not chance - Matrix4x4 SP; // screen-space-projections matrix - Matrix4x4 VM; // camera-model-animation matrix + Matrix4x4 _SP; // screen-space-projections matrix - std::vector triangles; - std::vector clipPlanes; + std::vector _triangles; + std::vector _clipPlanes; - bool ready = false; + bool _ready = false; - double w = 0; - double h = 0; + double _w = 0; + double _h = 0; public: Camera() = default; Camera(const Camera& camera) = delete; @@ -42,28 +41,28 @@ public: void init(int width, int height, double fov = 110.0, double ZNear = 0.1, double ZFar = 5000.0); - std::vector& project(Mesh& mesh, Screen::ViewMode mode); + std::vector& project(std::shared_ptr mesh); - void record(); + void clear(); - [[nodiscard]] int buffSize() const { return triangles.size(); } + [[nodiscard]] int buffSize() const { return _triangles.size(); } std::vector& sorted(); - [[nodiscard]] Point4D position() const override { return p_position; } - [[nodiscard]] Point4D angle() const override { return p_angle; } - [[nodiscard]] Point4D angleLeftUpLookAt() const { return p_angleLeftUpLookAt; } + [[nodiscard]] Point4D position() const override { return _position; } + [[nodiscard]] Point4D angle() const override { return _angle; } + [[nodiscard]] Point4D angleLeftUpLookAt() const { return _angleLeftUpLookAt; } - [[nodiscard]] Point4D eye() const { return p_position; } - [[nodiscard]] Point4D left() const { return p_left; } - [[nodiscard]] Point4D right() const { return -p_left; } - [[nodiscard]] Point4D up() const { return p_up; } - [[nodiscard]] Point4D down() const { return -p_up; } - [[nodiscard]] Point4D lookAt() const { return p_lookAt; } + [[nodiscard]] Point4D eye() const { return _position; } + [[nodiscard]] Point4D left() const { return _left; } + [[nodiscard]] Point4D right() const { return -_left; } + [[nodiscard]] Point4D up() const { return _up; } + [[nodiscard]] Point4D down() const { return -_up; } + [[nodiscard]] Point4D lookAt() const { return _lookAt; } void translate(const Point4D& dv) override { - p_position = p_position + dv; + _position = _position + dv; - for(auto attached : v_attached) + for(auto attached : _attachedObjects) attached->translate(dv); } @@ -80,9 +79,9 @@ public: void rotateUp(double ru); void rotateLookAt(double rlAt); - // Rotate mesh around XYZ by (r.x, r.y, r.z) radians relative val 'point4D' + // Rotate body around XYZ by (r.x, r.y, r.z) radians relative val 'point4D' void rotateRelativePoint(const Point4D& s, const Point4D& r) override; - // Rotate mesh around normalised vector 'v' by 'r' radians relative val 'point4D' + // Rotate body around normalised vector 'v' by 'r' radians relative val 'point4D' void rotateRelativePoint(const Point4D& s, const Point4D& v, double r) override; }; diff --git a/engine/Engine.cpp b/engine/Engine.cpp index 196b772..6ab3048 100755 --- a/engine/Engine.cpp +++ b/engine/Engine.cpp @@ -15,6 +15,8 @@ Engine::Engine() { } void Engine::create(int screenWidth, int screenHeight, const std::string &name, bool verticalSync, sf::Color background, sf::Uint32 style) { + _name = name; + screen->open(screenWidth, screenHeight, name, verticalSync, background, style); Log::log("Engine::create(): started engine (" + std::to_string(screenWidth) + " x " + std::to_string(screenHeight) + ") with name '" + name + "'."); @@ -28,67 +30,35 @@ void Engine::create(int screenWidth, int screenHeight, const std::string &name, screen->clear(); Time::update(); - screen->keyboardControl(); - update(Time::deltaTime()); + update(); world->garbageCollector(); /* Project all mesh - * Here we project all tris for each mesh from world._objects. + * Here we project all _tris for each body from world._objects. * When we call camera.project(m.second), */ // sometimes we dont need to update physics world // (for example in menu or while pause) - // hence we can set 'b_updateWorld' equal to false in setUpdateWorld(bool): - if(b_updateWorld) { - camera->record(); - for (auto &m : world->objects()) { - m.second->a_update(); - camera->project(*m.second, screen->mode()); - - m.second->updatePhysicsState(); - // isCollision detection: - if (m.second->isCollision()) { - m.second->setInCollision(false); - m.second->setCollisionNormal(Point4D{0, 0, 0}); - for (auto &obj : world->objects()) { - if(obj.first != m.first) { - std::pair gjk = m.second->checkGJKCollision(obj.second); - if (gjk.first) { - if (obj.second->isCollider()) { - CollisionPoint epa = m.second->EPA(gjk.second, obj.second); - Solver::solveCollision(m.second, obj.second, epa); - } - if (m.second->collisionCallBack() != nullptr) - m.second->collisionCallBack()(obj.first, obj.second); - } - } - } - } - - } - - // draw projected mesh - for (auto &t : camera->sorted()) - screen->triangle(t); + // hence we can set '_updateWorld' equal to false in setUpdateWorld(bool): + if(_updateWorld) { camera->a_update(); + camera->clear(); - triPerSec = camera->buffSize() * Time::fps(); + world->update(); + world->projectObjectsInCamera(camera); - if (b_debugText) { - screen->debugText(name + "\n\n X: " + - std::to_string((camera->eye().x())) + "\n Y: " + - std::to_string((camera->eye().y())) + "\n Z: " + - std::to_string((camera->eye().z())) + "\n\n" + - std::to_string(screen->width()) + "x" + - std::to_string(screen->height()) + "\n" + - std::to_string(Time::fps()) + - " fps \n" + std::to_string((int) triPerSec) + " tris/s"); - } + // draw projected body + for (auto &t : camera->sorted()) + screen->drawTriangle(t); + + _triPerSec = camera->buffSize() * Time::fps(); + + printDebugText(); + gui(); } - gui(); screen->display(); } exit(); @@ -99,5 +69,18 @@ void Engine::exit() { screen->close(); } ResourceManager::unloadAllResources(); - Log::log("Engine::exit(): exit engine (" + std::to_string(screen->width()) + " x " + std::to_string(screen->height()) + ") with name '" + screen->title() + "'."); + Log::log("Engine::exit(): exit engine (" + std::to_string(screen->width()) + " x " + std::to_string(screen->height()) + ") with name '" + screen->name() + "'."); +} + +void Engine::printDebugText() const { + if (_debugText) { + screen->debugText(_name + "\n\n X: " + + std::to_string((camera->eye().x())) + "\n Y: " + + std::to_string((camera->eye().y())) + "\n Z: " + + std::to_string((camera->eye().z())) + "\n\n" + + std::to_string(screen->width()) + "x" + + std::to_string(screen->height()) + "\n" + + std::to_string(Time::fps()) + + " fps \n" + std::to_string((int) _triPerSec) + " _tris/s"); + } } diff --git a/engine/Engine.h b/engine/Engine.h index a8814cc..8d14a26 100755 --- a/engine/Engine.h +++ b/engine/Engine.h @@ -11,15 +11,19 @@ #include "utils/Log.h" class Engine { +private: + std::string _name; + double _triPerSec = 0; + bool _debugText = true; + bool _updateWorld = true; + + void printDebugText() const; + protected: std::shared_ptr screen; std::shared_ptr world; std::shared_ptr camera; - double triPerSec = 0; - - bool b_debugText = true; - bool b_updateWorld = true; public: Engine(); @@ -28,10 +32,11 @@ public: void create(int screenWidth = 1920, int screenHeight = 1080, const std::string& name = "engine", bool verticalSync = true, sf::Color background = sf::Color(255, 255, 255), sf::Uint32 style = sf::Style::Default); virtual void start() {}; - virtual void update(double elapsedTime) {}; + virtual void update() {}; void exit(); - void debugText(bool value) { b_debugText = value; } - void setUpdateWorld(bool value) { b_updateWorld = value; } + + void setDebugText(bool value) { _debugText = value; } + void setUpdateWorld(bool value) { _updateWorld = value; } virtual void gui(){} }; diff --git a/engine/Mesh.cpp b/engine/Mesh.cpp index cdb58a3..96c3f38 100755 --- a/engine/Mesh.cpp +++ b/engine/Mesh.cpp @@ -11,13 +11,9 @@ using namespace std; -Mesh Mesh::operator*(const Matrix4x4 &matrix4X4) const { - return Mesh(*this) *= matrix4X4; -} - Mesh &Mesh::operator*=(const Matrix4x4 &matrix4X4) { - for (auto& t : tris) - t *= matrix4X4; + for (auto& t : _tris) + t = t * matrix4X4; return *this; } @@ -27,7 +23,7 @@ Mesh &Mesh::loadObj(const std::string& filename, const std::string &materials, c auto objects = Mesh::LoadObjects(filename, materials, scale); for(auto& obj : objects) { for (auto &tri : obj->triangles()) { - tris.push_back(tri); + _tris.push_back(tri); } } return *this; @@ -38,10 +34,10 @@ Mesh::Mesh(const std::string& filename, const std::string &materials, const Poin } Mesh::Mesh(const vector &tries){ - tris = tries; + _tris = tries; } -Mesh::Mesh(const Mesh& mesh) : Animatable(mesh) { +Mesh::Mesh(const Mesh& mesh) { *this = mesh; } @@ -50,17 +46,17 @@ Mesh Mesh::Obj(const std::string& filename) { } void Mesh::rotate(const Point4D &r) { - p_angle = p_angle + r; + _angle = _angle + r; *this *= Matrix4x4::Rotation(r); - for(auto attached : v_attached) + for(auto attached : _attachedObjects) attached->rotateRelativePoint(position(), r); } void Mesh::rotate(const Point4D &v, double r) { *this *= Matrix4x4::Rotation(v, r); - for(auto attached : v_attached) + for(auto attached : _attachedObjects) attached->rotateRelativePoint(position(), v, r); } @@ -71,72 +67,71 @@ void Mesh::scale(const Point4D &s) { } void Mesh::translate(const Point4D &t) { - p_position = p_position + t; + _position = _position + t; - for(auto attached : v_attached) + for(auto attached : _attachedObjects) attached->translate(t); } Mesh &Mesh::operator=(const Mesh &mesh) { - tris = mesh.tris; - p_position = mesh.p_position; - c_color = mesh.c_color; + _tris = mesh._tris; + _position = mesh._position; + _color = mesh._color; return *this; } void Mesh::rotateRelativePoint(const Point4D &s, const Point4D &r) { - p_angle = p_angle + r; + _angle = _angle + r; // Translate XYZ by vector r1 - Point4D r1 = p_position - s; + Point4D r1 = _position - s; *this *= Matrix4x4::Translation(r1); - // In translated coordinate system we rotate mesh and position + // In translated coordinate system we rotate body and position Matrix4x4 rotationMatrix = Matrix4x4::Rotation(r); Point4D r2 = rotationMatrix*r1; *this *= rotationMatrix; // After rotation we translate XYZ by vector -r2 and recalculate position *this *= Matrix4x4::Translation(-r2); - p_position = s + r2; + _position = s + r2; - if(v_attached.empty()) + if(_attachedObjects.empty()) return; - for(auto attached : v_attached) + for(auto attached : _attachedObjects) attached->rotateRelativePoint(s, r); } void Mesh::rotateRelativePoint(const Point4D &s, const Point4D &v, double r) { // Translate XYZ by vector r1 - Point4D r1 = p_position - s; + Point4D r1 = _position - s; *this *= Matrix4x4::Translation(r1); - // In translated coordinate system we rotate mesh and position + // In translated coordinate system we rotate body and position Matrix4x4 rotationMatrix = Matrix4x4::Rotation(v, r); Point4D r2 = rotationMatrix*r1; *this *= rotationMatrix; // After rotation we translate XYZ by vector -r2 and recalculate position *this *= Matrix4x4::Translation(-r2); - p_position = s + r2; + _position = s + r2; - for(auto attached : v_attached) + for(auto attached : _attachedObjects) attached->rotateRelativePoint(s, v, r); } void Mesh::translateToPoint(const Point4D &point) { - translate(point - p_position); + translate(point - _position); } void Mesh::setColor(sf::Color c) { - c_color = c; - for (auto& t : tris) - t.color = c_color; + _color = c; + for (auto& t : _tris) + t = Triangle(t[0], t[1], t[2], _color); } -std::vector> -Mesh::LoadObjects(const string &filename, const string &materials, const Point4D &scale) { +std::vector> Mesh::LoadObjects(const string &filename, const string &materials, const Point4D &scale) { std::vector> objects; map maters; @@ -209,8 +204,7 @@ Mesh::LoadObjects(const string &filename, const string &materials, const Point4D { int f[3]; s >> junk >> f[0] >> f[1] >> f[2]; - tris.emplace_back(verts[f[0] - 1], verts[f[1] - 1], verts[f[2] - 1] ); - tris.back().color = currentColor; + tris.emplace_back(verts[f[0] - 1], verts[f[1] - 1], verts[f[2] - 1], currentColor); } } @@ -225,6 +219,7 @@ Mesh::LoadObjects(const string &filename, const string &materials, const Point4D } Mesh Mesh::LineTo(const Point4D& from, const Point4D& to, double line_width, sf::Color color) { + Mesh line; Point4D v1 = (to - from).normalized(); @@ -242,7 +237,7 @@ Mesh Mesh::LineTo(const Point4D& from, const Point4D& to, double line_width, sf: Point4D p7 = to + v2 * line_width/2.0 + v3 * line_width/2.0; Point4D p8 = to + v2 * line_width/2.0 - v3 * line_width/2.0; - line.tris = { + line._tris = { { p2, p4, p1 }, { p2, p3, p4 }, { p1, p6, p2 }, @@ -259,5 +254,10 @@ Mesh Mesh::LineTo(const Point4D& from, const Point4D& to, double line_width, sf: line.setColor(color); + for(auto& triangle : line._tris) + triangle = Triangle(Point4D{triangle[0].x(), triangle[0].y(), triangle[0].z(), 1}, + Point4D{triangle[1].x(), triangle[1].y(), triangle[1].z(), 1}, + Point4D{triangle[2].x(), triangle[2].y(), triangle[2].z(), 1}, line.color()); + return line; } diff --git a/engine/Mesh.h b/engine/Mesh.h index 9b76ee7..2dfcdd2 100755 --- a/engine/Mesh.h +++ b/engine/Mesh.h @@ -8,24 +8,16 @@ #include #include "Triangle.h" #include "animation/Animatable.h" -#include "physics/RigidBody.h" #include #include "Object.h" -class Mesh : public Object, public Animatable, public RigidBody { +class Mesh : public Object, public Animatable { private: - // Operations with Matrix4x4 - [[nodiscard]] Mesh operator*(const Matrix4x4& matrix4X4) const; - Mesh& operator*=(const Matrix4x4& matrix4X4); - -protected: - std::vector tris; - + std::vector _tris; + sf::Color _color = sf::Color(255, 245, 194); bool _visible = true; - sf::Color c_color = sf::Color(255, 245, 194); - - std::function)> _collisionCallBack; + Mesh& operator*=(const Matrix4x4& matrix4X4); public: Mesh() = default; @@ -37,29 +29,29 @@ public: Mesh& loadObj(const std::string& filename, const std::string &materials = "", const Point4D& scale = Point4D{1, 1, 1}); - [[nodiscard]] std::vectorconst &triangles() const { return tris; } - [[nodiscard]] std::vector& triangles() override { return tris; } - void setTriangles(const std::vector& t) override { tris = t; } + [[nodiscard]] std::vectorconst &triangles() const { return _tris; } + [[nodiscard]] std::vector& triangles() override { return _tris; } + void setTriangles(const std::vector& t) override { _tris = t; } - // Translate mesh + // Translate body void translate(const Point4D& t) override; void translateToPoint(const Point4D& point); - // Rotate mesh around XYZ axes + // Rotate body around XYZ axes void rotate(const Point4D& r) override; - // Rotate mesh around normalised vector 'v' by 'r' radians + // Rotate body around normalised vector 'v' by 'r' radians void rotate(const Point4D& v, double r) override; - // Rotate mesh around XYZ by (r.x, r.y, r.z) radians relative val 'point4D' + // Rotate body around XYZ by (r.x, r.y, r.z) radians relative val 'point4D' void rotateRelativePoint(const Point4D& point4D, const Point4D& r) override; - // Rotate mesh around normalised vector 'v' by 'r' radians relative val 'point4D' + // Rotate body around normalised vector 'v' by 'r' radians relative val 'point4D' void rotateRelativePoint(const Point4D& point4D, const Point4D& v, double r) override; void scale(const Point4D& s); - void rotateToAngle(const Point4D& v) { rotate(v - p_angle); } + void rotateToAngle(const Point4D& v) { rotate(v - _angle); } - [[nodiscard]] Point4D position() const override { return p_position; } - [[nodiscard]] Point4D angle() const override { return p_angle; } + [[nodiscard]] Point4D position() const override { return _position; } + [[nodiscard]] Point4D angle() const override { return _angle; } - [[nodiscard]] sf::Color color() const override { return c_color; } + [[nodiscard]] sf::Color color() const override { return _color; } void setColor(sf::Color c) override; Mesh static Obj(const std::string& filename); @@ -69,9 +61,6 @@ public: [[nodiscard]] bool isVisible() const { return _visible; } std::vector> static LoadObjects(const std::string& filename, const std::string &materials = "", const Point4D& scale = Point4D{1, 1, 1}); - - [[nodiscard]] const std::function)>& collisionCallBack() const { return _collisionCallBack; } - void setCollisionCallBack(const std::function)>& f) { _collisionCallBack = f; } }; diff --git a/engine/Object.h b/engine/Object.h index 0bdc98f..04350da 100755 --- a/engine/Object.h +++ b/engine/Object.h @@ -11,10 +11,10 @@ class Object { protected: - std::vector> v_attached; + std::vector> _attachedObjects; - Point4D p_position; - Point4D p_angle; + Point4D _position; + Point4D _angle; public: Object() = default; @@ -24,11 +24,11 @@ public: virtual void rotate(const Point4D& v, double rv) {} virtual void rotateRelativePoint(const Point4D& s, const Point4D& v, double r) {} - [[nodiscard]] Point4D position() const { return p_position; } - [[nodiscard]] Point4D angle() const { return p_angle; } + [[nodiscard]] Point4D position() const { return _position; } + [[nodiscard]] Point4D angle() const { return _angle; } void attach(std::shared_ptr object) { - v_attached.push_back(std::move(object)); + _attachedObjects.push_back(object); } }; diff --git a/engine/Plane.cpp b/engine/Plane.cpp index 1cb9ce3..22f91fe 100755 --- a/engine/Plane.cpp +++ b/engine/Plane.cpp @@ -5,35 +5,34 @@ #include "Plane.h" Plane::Plane(const Triangle& tri) { - triangle = tri; - n = tri.norm(); - p = tri[0]; + _triangle = tri; + _n = tri.norm(); + _p = tri[0]; } Plane::Plane(const Point4D &N, const Point4D &P) { - n = N; - p = P; + _n = N.normalized(); + _p = P; } Plane::Plane(const Plane &plane) { - triangle = plane.triangle; - n = plane.n; - p = plane.p; + _triangle = plane._triangle; + _n = plane._n; + _p = plane._p; } double Plane::distance(const Point4D &point4D) const { - return point4D.dot(n) - p.dot(n); + return point4D.dot(_n) - _p.dot(_n); } -std::pair Plane::intersection(const Point4D &start, const Point4D &end) { - double s_dot_n = start.dot(n); - double k = (s_dot_n - p.dot(n))/(s_dot_n - end.dot(n)); +std::pair Plane::intersection(const Point4D &start, const Point4D &end) const { + double s_dot_n = start.dot(_n); + double k = (s_dot_n - _p.dot(_n)) / (s_dot_n - end.dot(_n)); Point4D res = start + (end - start)*k; return std::make_pair(res, k); } -int Plane::clip(Triangle &tri, Triangle &additional_tri) { - n = n.normalized(); +int Plane::clip(Triangle &tri, Triangle &additional_tri) const { Point4D insidePoints[3]; int inside = 0; Point4D outsidePoints[3]; int outside = 0; @@ -49,20 +48,14 @@ int Plane::clip(Triangle &tri, Triangle &additional_tri) { } if(inside == 0) { - tri.clip = Triangle::Skipped; return 0; } if(inside == 1) { std::pair intersect1 = intersection(insidePoints[0], outsidePoints[0]); std::pair intersect2 = intersection(insidePoints[0], outsidePoints[1]); - tri[0] = insidePoints[0]; - tri[1] = intersect1.first; - - tri[2] = intersect2.first; - - tri.clip = Triangle::Cropped; + tri = Triangle(insidePoints[0], intersect1.first, intersect2.first, tri.color()); return 1; } @@ -71,20 +64,8 @@ int Plane::clip(Triangle &tri, Triangle &additional_tri) { std::pair intersect1 = intersection(insidePoints[0], outsidePoints[0]); std::pair intersect2 = intersection(insidePoints[1], outsidePoints[0]); - tri[0] = insidePoints[0]; - - tri[1] = intersect1.first; - - tri[2] = insidePoints[1]; - - additional_tri[0] = intersect1.first; - - additional_tri[1] = intersect2.first; - - additional_tri[2] = insidePoints[1]; - - tri.clip = Triangle::Doubled; - additional_tri.clip = Triangle::Doubled; + tri = Triangle(insidePoints[0], intersect1.first, insidePoints[1], tri.color()); + additional_tri = Triangle(intersect1.first, intersect2.first, insidePoints[1], tri.color()); return 2; } diff --git a/engine/Plane.h b/engine/Plane.h index f2fe955..1ae7c1a 100755 --- a/engine/Plane.h +++ b/engine/Plane.h @@ -11,24 +11,24 @@ class Plane { private: // You can define plane by defining the points in 3D space - Triangle triangle; + Triangle _triangle; // Or by defining normal vector and one val laying on the plane - Point4D n = Point4D{0, 0, 1, 0}; - Point4D p{}; + Point4D _n = Point4D{0, 0, 1, 0}; + Point4D _p{}; public: - // A plain with normal vector 'n' and val 'p' lays on the plane + // A plain with normal vector '_n' and val '_p' lays on the plane Plane() = default; Plane(const Point4D& N, const Point4D& P); Plane(const Plane& plane); explicit Plane(const Triangle& tri); [[nodiscard]] double distance(const Point4D& point4D) const; - // Point4D in space where line ('start' to 'end') intersects plain with normal vector 'n' and val 'p' lays on the plane - std::pair intersection(const Point4D& start, const Point4D& end); - int clip(Triangle& tri, Triangle& additional_tri); + // Point4D in space where line ('start' to 'end') intersects plain with normal vector '_n' and val '_p' lays on the plane + [[nodiscard]] std::pair intersection(const Point4D& start, const Point4D& end) const; + int clip(Triangle& tri, Triangle& additional_tri) const; - [[nodiscard]] Point4D N() const { return n; } - [[nodiscard]] Point4D P() const { return p; } + [[nodiscard]] Point4D N() const { return _n; } + [[nodiscard]] Point4D P() const { return _p; } }; diff --git a/engine/ResourceManager.cpp b/engine/ResourceManager.cpp index 3eb15e2..38556d5 100755 --- a/engine/ResourceManager.cpp +++ b/engine/ResourceManager.cpp @@ -5,7 +5,7 @@ #include "ResourceManager.h" #include #include -#include + namespace ResourceManager { namespace @@ -13,7 +13,6 @@ namespace ResourceManager std::map> _textures; std::map> _fonts; std::map> _soundBuffers; - std::map> _shaders; } void unloadTextures() @@ -36,18 +35,11 @@ namespace ResourceManager _fonts.clear(); } - void unloadShaders() { - for (auto& shader : _shaders) - shader.second.reset(); - _shaders.clear(); - } - void unloadAllResources() { unloadTextures(); unloadSoundBuffers(); unloadFonts(); - unloadShaders(); } std::shared_ptr loadTexture(const std::string& filename) @@ -103,21 +95,4 @@ namespace ResourceManager return font; } - - std::shared_ptr loadShader(const std::string& filename, sf::Shader::Type type) { - // If Shader is already loaded - return pointer to it - auto it = _shaders.find(filename); - if (it != _shaders.end()) - return it->second; - - // Otherwise - try to load it. If failure - return zero - std::shared_ptr shader(new sf::Shader); - if (!shader->loadFromFile(filename, type)) - return nullptr; - - // If success - remember and return texture pointer - _shaders.emplace(filename, shader); - - return shader; - } } diff --git a/engine/ResourceManager.h b/engine/ResourceManager.h index 0d57216..101a6bf 100755 --- a/engine/ResourceManager.h +++ b/engine/ResourceManager.h @@ -25,7 +25,6 @@ namespace ResourceManager std::shared_ptr loadTexture(const std::string& filename); std::shared_ptr loadFont(const std::string& filename); std::shared_ptr loadSoundBuffer(const std::string& filename); - std::shared_ptr loadShader(const std::string& filename, sf::Shader::Type type); }; diff --git a/engine/Screen.cpp b/engine/Screen.cpp index fe03007..7831701 100755 --- a/engine/Screen.cpp +++ b/engine/Screen.cpp @@ -11,15 +11,15 @@ void Screen::open(int screenWidth, int screenHeight, const std::string &name, bool verticalSync, sf::Color background, sf::Uint32 style) { - this->name = name; - w = screenWidth; - h = screenHeight; - this->background = background; + _name = name; + _w = screenWidth; + _h = screenHeight; + _background = background; sf::ContextSettings settings; settings.antialiasingLevel = 8; - window.create(sf::VideoMode(w, h), name, style, settings); + window.create(sf::VideoMode(_w, _h), name, style, settings); window.setVerticalSyncEnabled(verticalSync); } @@ -31,44 +31,29 @@ void Screen::display() { } } - std::string title = name + " (" + std::to_string(Time::fps()) + " fps)"; + std::string title = _name + " (" + std::to_string(Time::fps()) + " fps)"; window.setTitle(title); window.display(); } void Screen::clear() { - window.clear(background); + window.clear(_background); } -void Screen::triangle(const Triangle& triangle) +void Screen::drawTriangle(const Triangle& triangle) { - if(vm == Frame || vm == Borders || vm == Xray || vm == Clipped || vm == Transparency || vm == Normals) { - sf::Vertex lines[4] = - { - sf::Vertex(sf::Vector2f(triangle[0].x(), triangle[0].y()), sf::Color(0, 0, 0, 255)), - sf::Vertex(sf::Vector2f(triangle[1].x(), triangle[1].y()), sf::Color(0, 0, 0, 255)), - sf::Vertex(sf::Vector2f(triangle[2].x(), triangle[2].y()), sf::Color(0, 0, 0, 255)), - sf::Vertex(sf::Vector2f(triangle[0].x(), triangle[0].y()), sf::Color(0, 0, 0, 255)) - }; - - window.draw(lines, 4, sf::LineStrip); - } - if(vm == Frame || vm == Xray) - return; // no texture when we turn on Frame or Xray mode - sf::Vertex tris[3] = { - sf::Vertex(sf::Vector2f(triangle[0].x(), triangle[0].y()), triangle.color), - sf::Vertex(sf::Vector2f(triangle[1].x(), triangle[1].y()), triangle.color), - sf::Vertex(sf::Vector2f(triangle[2].x(), triangle[2].y()), triangle.color) + sf::Vertex(sf::Vector2f(triangle[0].x(), triangle[0].y()), triangle.color()), + sf::Vertex(sf::Vector2f(triangle[1].x(), triangle[1].y()), triangle.color()), + sf::Vertex(sf::Vector2f(triangle[2].x(), triangle[2].y()), triangle.color()) }; window.draw(tris, 3, sf::Triangles); } -void Screen::title(const std::string& title) -{ - name = title; +void Screen::setName(const std::string& title) { + _name = title; } bool Screen::isOpen() { @@ -89,49 +74,28 @@ Point4D Screen::getMousePosition() const { } Point4D Screen::getMouseDisplacement() const { - sf::Vector2 disp = sf::Mouse::getPosition(window) - sf::Vector2(w/2, h/2); + sf::Vector2 disp = sf::Mouse::getPosition(window) - sf::Vector2(_w/2, _h/2); setMouseInCenter(); return Point4D(disp.x, disp.y, 0, 0); } void Screen::setMouseInCenter() const { - sf::Mouse::setPosition({ w / 2, h / 2 }, window); + sf::Mouse::setPosition({ _w / 2, _h / 2 }, window); } void Screen::setMouseCursorVisible(bool visible) { window.setMouseCursorVisible(visible); } -void Screen::keyboardControl() { - // Check all input after this condition please - if (!window.hasFocus()) - return; - - if(isKeyTapped(sf::Keyboard::Num1)) - setMode(ViewMode::Default); - if(isKeyTapped(sf::Keyboard::Num2)) - setMode(ViewMode::Borders); - if(isKeyTapped(sf::Keyboard::Num3)) - setMode(ViewMode::Transparency); - if(isKeyTapped(sf::Keyboard::Num4)) - setMode(ViewMode::Frame); - if(isKeyTapped(sf::Keyboard::Num5)) - setMode(ViewMode::Xray); - if(isKeyTapped(sf::Keyboard::Num6)) - setMode(ViewMode::Clipped); - if(isKeyTapped(sf::Keyboard::Num7)) - setMode(ViewMode::Normals); -} - bool Screen::isKeyTapped(sf::Keyboard::Key key) { if (!Screen::isKeyPressed(key)) return false; - if(tappedKeys.count(key) == 0) { - tappedKeys.emplace(key, Time::time()); + if(_tappedKeys.count(key) == 0) { + _tappedKeys.emplace(key, Time::time()); return true; - } else if((Time::time() - tappedKeys[key]) > 0.2) { - tappedKeys[key] = Time::time(); + } else if((Time::time() - _tappedKeys[key]) > 0.2) { + _tappedKeys[key] = Time::time(); return true; } return false; @@ -145,11 +109,11 @@ bool Screen::isButtonTapped(sf::Mouse::Button button) { if (!Screen::isButtonPressed(button)) return false; - if(tappedButtons.count(button) == 0) { - tappedButtons.emplace(button, Time::time()); + if(_tappedButtons.count(button) == 0) { + _tappedButtons.emplace(button, Time::time()); return true; - } else if((Time::time() - tappedButtons[button]) > 0.2) { - tappedButtons[button] = Time::time(); + } else if((Time::time() - _tappedButtons[button]) > 0.2) { + _tappedButtons[button] = Time::time(); return true; } return false; @@ -159,7 +123,7 @@ bool Screen::isButtonTapped(sf::Mouse::Button button) { void Screen::debugText(const std::string& text) { sf::Text t; - t.setFont(*ResourceManager::loadFont(font)); + t.setFont(*ResourceManager::loadFont(_font)); t.setString(text); t.setCharacterSize(30); t.setFillColor(sf::Color::Black); diff --git a/engine/Screen.h b/engine/Screen.h index d728ebc..e47c8ef 100755 --- a/engine/Screen.h +++ b/engine/Screen.h @@ -13,33 +13,18 @@ #include "utils/Time.h" class Screen { -public: - enum ViewMode { - Default = 0, - Frame, - Borders, - Xray, - Clipped, - Transparency, - Normals - }; private: - int w = 1920; - int h = 1080; + int _w = 1920; + int _h = 1080; - std::string name; + std::string _name; - sf::Color background; + sf::Color _background; - Screen::ViewMode vm = Screen::ViewMode::Default; + std::map _tappedKeys; + std::map _tappedButtons; - std::map tappedKeys; - std::map tappedButtons; - - std::string font = "../engine/fonts/Roboto-Thin.ttf"; - - int frame = 0; - int scene = 0; // the number of scene + std::string _font = "../engine/fonts/Roboto-Thin.ttf"; public: sf::RenderWindow window; @@ -49,10 +34,10 @@ public: void display(); void clear(); - void triangle(const Triangle& triangle ); + void drawTriangle(const Triangle& triangle); - void title(const std::string& title); - std::string title() const { return name; }; + void setName(const std::string& title); + std::string name() const { return _name; }; bool isOpen(); @@ -72,11 +57,6 @@ public: void setMouseInCenter() const; void setMouseCursorVisible(bool visible); - void setMode(ViewMode mode) { vm = mode; } - [[nodiscard]] ViewMode mode() const { return vm; } - - void keyboardControl(); - void debugText(const std::string& text); }; diff --git a/engine/Triangle.cpp b/engine/Triangle.cpp index bb589ef..5cad1ba 100755 --- a/engine/Triangle.cpp +++ b/engine/Triangle.cpp @@ -5,76 +5,55 @@ #include "Triangle.h" Triangle::Triangle () { - p[0] = Point4D{0,0,0,1}; - p[1] = Point4D{0,0,0,1}; - p[2] = Point4D{0,0,0,1}; + _p[0] = Point4D{0, 0, 0, 1}; + _p[1] = Point4D{0, 0, 0, 1}; + _p[2] = Point4D{0, 0, 0, 1}; } -Triangle::Triangle(const Point4D& p1, const Point4D& p2, const Point4D& p3, double w) { - p[0] = Point4D{p1.x(), p1.y(), p1.z(), w}; - p[1] = Point4D{p2.x(), p2.y(), p2.z(), w}; - p[2] = Point4D{p3.x(), p3.y(), p3.z(), w}; +Triangle::Triangle(const Point4D& p1, const Point4D& p2, const Point4D& p3, sf::Color color) { + _p[0] = p1; + _p[1] = p2; + _p[2] = p3; + _color = color; } Triangle Triangle::operator*(const Matrix4x4 &matrix4X4) const { - return Triangle(*this) *= matrix4X4; -} + Triangle res(*this); -Triangle &Triangle::operator*=(const Matrix4x4 &matrix4X4) { - p[0] = matrix4X4 * p[0]; - p[1] = matrix4X4 * p[1]; - p[2] = matrix4X4 * p[2]; + res._p[0] = matrix4X4 * _p[0]; + res._p[1] = matrix4X4 * _p[1]; + res._p[2] = matrix4X4 * _p[2]; - return *this; + return res; } Point4D Triangle::norm() const { - Point4D v1 = p[1] - p[0]; - Point4D v2 = p[2] - p[0]; + Point4D v1 = _p[1] - _p[0]; + Point4D v2 = _p[2] - _p[0]; return v1.cross3D(v2).normalized(); } Point4D Triangle::operator[](int i) const { - return p[i]; -} - -Point4D &Triangle::operator[](int i) { - return p[i]; -} - -Point4D Triangle::pos() const { - return (p[0] + p[1] + p[2])/3.0; + return _p[i]; } Triangle::Triangle(const Triangle &triangle) { - clip = triangle.clip; - color = triangle.color; - p[0] = triangle[0]; - p[1] = triangle[1]; - p[2] = triangle[2]; + _color = triangle._color; + _p[0] = triangle[0]; + _p[1] = triangle[1]; + _p[2] = triangle[2]; } bool Triangle::isPointInside(const Point4D &point) const { Point4D triangleNorm = norm(); - double dot1 = (point - p[0]).cross3D(p[1] - p[0]).dot(triangleNorm); - double dot2 = (point - p[1]).cross3D(p[2] - p[1]).dot(triangleNorm); - double dot3 = (point - p[2]).cross3D(p[0] - p[2]).dot(triangleNorm); + double dot1 = (point - _p[0]).cross3D(_p[1] - _p[0]).dot(triangleNorm); + double dot2 = (point - _p[1]).cross3D(_p[2] - _p[1]).dot(triangleNorm); + double dot3 = (point - _p[2]).cross3D(_p[0] - _p[2]).dot(triangleNorm); if((dot1 >= 0 && dot2 >= 0 && dot3 >= 0) || (dot1 <= 0 && dot2 <= 0 && dot3 <= 0)) return true; return false; } - -Triangle &Triangle::operator=(const Triangle &triangle) { - if(&triangle != this) { - clip = triangle.clip; - color = triangle.color; - p[0] = triangle[0]; - p[1] = triangle[1]; - p[2] = triangle[2]; - } - return *this; -} diff --git a/engine/Triangle.h b/engine/Triangle.h index 3efc35c..a5580dd 100755 --- a/engine/Triangle.h +++ b/engine/Triangle.h @@ -10,34 +10,25 @@ #include class Triangle { +private: + sf::Color _color; + Point4D _p[3]; + public: - // This is for clipping debug: you can distinguish how this triangle was clipped - enum ClipMode { - None = 0, - Cropped, - Doubled, - Skipped - }; - ClipMode clip = None; - sf::Color color; - Point4D p[3]; Triangle (); Triangle (const Triangle& triangle); - Triangle (const Point4D& p1, const Point4D& p2, const Point4D& p3, double w = 1); - Triangle& operator=(const Triangle& triangle); + Triangle (const Point4D& p1, const Point4D& p2, const Point4D& p3, sf::Color color = {0, 0, 0}); [[nodiscard]] Point4D operator[] (int i) const; - [[nodiscard]] Point4D& operator[] (int i); - [[nodiscard]] Point4D norm() const; // Operations with Matrix4x4 [[nodiscard]] Triangle operator*(const Matrix4x4& matrix4X4) const; - Triangle& operator*=(const Matrix4x4& matrix4X4); - [[nodiscard]] Point4D pos() const; [[nodiscard]] bool isPointInside(const Point4D& point) const; + + [[nodiscard]] sf::Color color() const { return _color; } }; diff --git a/engine/World.cpp b/engine/World.cpp index f52df29..20f7baa 100755 --- a/engine/World.cpp +++ b/engine/World.cpp @@ -2,35 +2,27 @@ // Created by Иван Ильин on 13.01.2021. // -#include -#include #include "World.h" #include "utils/Log.h" #include "Plane.h" +#include "physics/Solver.h" using namespace std; -void World::addMesh(std::shared_ptr mesh, const string &name) { - _objects.emplace(name, mesh); - Log::log("World::addMesh(): inserted mesh '" + name + "' with " + std::to_string(_objects[name]->triangles().size()) + " tris."); - +void World::addBody(std::shared_ptr body, const string &name) { + _objects.emplace(name, body); + Log::log("World::addBody(): inserted body '" + name + "' with " + std::to_string(_objects[name]->triangles().size()) + " _tris."); } -void World::loadObj(const string &name, const string &filename,const std::string &materials, const Point4D& scale) { - _objects.emplace(name, std::make_shared(filename, materials, scale)); - Log::log("World::loadObj(): inserted mesh from " + filename + " with name '" + name + "' with " + std::to_string(_objects[name]->triangles().size()) + " tris."); +void World::loadBody(const string &name, const string &filename, const std::string &materials, const Point4D& scale) { + _objects.emplace(name, std::make_shared(Mesh(filename, materials, scale))); + Log::log("World::loadBody(): inserted body from " + filename + " with name '" + name + "' with " + std::to_string(_objects[name]->triangles().size()) + " _tris."); } -void World::removeMesh(const string &name) { +void World::removeBody(const string &name) { _objToRemove.push_back(name); } -std::shared_ptr World::operator[](const string &name) { - if(_objects.count(name) == 0) - Log::log("World::operator[]: mesh '" + name + "' does not exist."); - return _objects.find(name)->second; -} - std::pair World::rayCast(const Point4D& from, const Point4D& to) { std::pair result{Point4D{0, 0,0, -1}, ""}; @@ -41,7 +33,7 @@ std::pair World::rayCast(const Point4D& from, const Point4D& to continue; for(auto& tri : object.second->triangles()) { - Triangle tri_translated(tri[0] + object.second->position(), tri[1] + object.second->position(), tri[2] + object.second->position(), 0); + Triangle tri_translated(tri[0] + object.second->position(), tri[1] + object.second->position(), tri[2] + object.second->position()); Plane plane(tri_translated); auto intersection = plane.intersection(from, to); @@ -59,23 +51,63 @@ void World::loadMap(const string &filename, const string &name, const Point4D &s auto objs = Mesh::LoadObjects(filename, materials, scale); for(int i = 0; i < objs.size(); i++) { string meshName = name + "_" + to_string(i); - addMesh(objs[i], meshName); + addBody(std::make_shared(*objs[i]), meshName); } } void World::garbageCollector() { for(auto& obj : _objToRemove) { if(_objects.erase(obj) > 0) - Log::log("World::garbageCollector(): removed mesh '" + obj + "'"); + Log::log("World::garbageCollector(): removed body '" + obj + "'"); else - Log::log("World::garbageCollector(): cannot remove mesh '" + obj + "': mesh does not exist."); + Log::log("World::garbageCollector(): cannot remove body '" + obj + "': body does not exist."); } _objToRemove.clear(); } -void World::removeMeshInstantly(const string &name) { +void World::removeBodyInstantly(const string &name) { if(_objects.erase(name) > 0) - Log::log("World::removeMeshInstantly(): removed mesh '" + name + "'"); + Log::log("World::removeBodyInstantly(): removed body '" + name + "'"); else - Log::log("World::removeMeshInstantly(): cannot remove mesh '" + name + "': mesh does not exist."); + Log::log("World::removeBodyInstantly(): cannot remove body '" + name + "': body does not exist."); +} + +void World::checkCollision(const std::string& body) { + if (_objects[body]->isCollision()) { + + _objects[body]->setInCollision(false); + + for (auto &obj : _objects) { + if(obj.first != body) { + std::pair gjk = _objects[body]->checkGJKCollision(obj.second); + if (gjk.first) { + if (obj.second->isCollider()) { + CollisionPoint epa = _objects[body]->EPA(gjk.second, obj.second); + Solver::solveCollision(_objects[body], obj.second, epa); + } + if (_objects[body]->collisionCallBack() != nullptr) + _objects[body]->collisionCallBack()(obj.first, obj.second); + } + } + } + } +} + +void World::update() { + for (auto &m : _objects) { + m.second->a_update(); + m.second->updatePhysicsState(); + checkCollision(m.first); + } +} + +void World::projectObjectsInCamera(std::shared_ptr camera) { + for (auto &m : _objects) + camera->project(m.second); +} + +std::shared_ptr World::body(const string &name) { + if(_objects.count(name) == 0) + Log::log("World::body: mesh '" + name + "' does not exist."); + return _objects.find(name)->second; } diff --git a/engine/World.h b/engine/World.h index 392fe82..93855a3 100755 --- a/engine/World.h +++ b/engine/World.h @@ -6,25 +6,26 @@ #define ENGINE_WORLD_H #include -#include "Mesh.h" +#include "Camera.h" +#include "physics/RigidBody.h" class World { private: - std::map> _objects; - + std::map> _objects; std::vector _objToRemove; public: World() = default; - [[nodiscard]] std::shared_ptr operator[] (const std::string& name); + void checkCollision(const std::string& body); + void update(); + void projectObjectsInCamera(std::shared_ptr camera); - [[nodiscard]] std::map>& objects() { return _objects; } - - void addMesh(std::shared_ptr mesh, const std::string& name = ""); - void removeMesh(const std::string& name); - void removeMeshInstantly(const std::string& name); + void addBody(std::shared_ptr mesh, const std::string& name = ""); + std::shared_ptr body(const std::string& name); + void removeBody(const std::string& name); + void removeBodyInstantly(const std::string& name); void garbageCollector(); - void loadObj(const std::string &name, const std::string &filename,const std::string &materials = "", const Point4D& scale = Point4D{1, 1, 1}); + void loadBody(const std::string &name, const std::string &filename, const std::string &materials = "", const Point4D& scale = Point4D{1, 1, 1}); // rayCast returns pair of Point4D and std::string: // 1) Point4D is point of collision (the last coordinate is -1 if there are no collisions) diff --git a/engine/animation/Animation.h b/engine/animation/Animation.h index 0ec26fa..d22f0dc 100755 --- a/engine/animation/Animation.h +++ b/engine/animation/Animation.h @@ -34,7 +34,7 @@ protected: double _duration = 0; bool _started = false; LoopOut _looped = None; - // p - animation progress + // _p - animation progress double _p = 0; double _dp = 0; diff --git a/engine/gui/Window.cpp b/engine/gui/Window.cpp index 63b611a..ac31507 100755 --- a/engine/gui/Window.cpp +++ b/engine/gui/Window.cpp @@ -16,7 +16,7 @@ void Window::addButton(int x, int y, int w, int h, std::function click, void Window::update(std::shared_ptr screen) { - screen->title(s_name); + screen->setName(s_name); screen->window.draw(back); Point4D mousePos = screen->getMousePosition(); diff --git a/engine/gui/Window.h b/engine/gui/Window.h index d0957c9..975851e 100755 --- a/engine/gui/Window.h +++ b/engine/gui/Window.h @@ -21,7 +21,7 @@ private: Point4D prevMousePosition; public: - explicit Window(std::string name = "Menu", std::string backTexture = "") : s_name(std::move(name)), s_backTexture(std::move(backTexture)){} + explicit Window(std::string name = "Menu", std::string backTexture = "") : s_name(std::move(name)), s_backTexture(std::move(backTexture)){} void addButton(int x, int y, int w, int h, std::function click, diff --git a/engine/physics/RigidBody.cpp b/engine/physics/RigidBody.cpp index 5290e64..33677b1 100755 --- a/engine/physics/RigidBody.cpp +++ b/engine/physics/RigidBody.cpp @@ -13,7 +13,8 @@ Point4D RigidBody::_findFurthestPoint(const Point4D& direction) { Point4D maxPoint = {}; auto maxDistance = (double)-INFINITY; for(auto& tri : triangles()){ - for(auto point : tri.p){ + for(int i = 0; i < 3; i++){ + Point4D point = tri[i]; point = point + position(); @@ -302,18 +303,22 @@ void RigidBody::AddIfUniqueEdge(std::vector>& edges, c } void RigidBody::updatePhysicsState() { - translate(p_velocity * Time::deltaTime()); - p_velocity = p_velocity + p_acceleration * Time::deltaTime(); + translate(_velocity * Time::deltaTime()); + _velocity = _velocity + _acceleration * Time::deltaTime(); } void RigidBody::setVelocity(const Point4D& velocity) { - p_velocity = velocity; + _velocity = velocity; } void RigidBody::addVelocity(const Point4D &velocity) { - p_velocity = p_velocity + velocity; + _velocity = _velocity + velocity; } void RigidBody::setAcceleration(const Point4D& acceleration) { - p_acceleration = acceleration; + _acceleration = acceleration; +} + +RigidBody::RigidBody(const Mesh &mesh) : Mesh(mesh) { + } diff --git a/engine/physics/RigidBody.h b/engine/physics/RigidBody.h index 96ca227..52c8379 100755 --- a/engine/physics/RigidBody.h +++ b/engine/physics/RigidBody.h @@ -10,6 +10,7 @@ #include "../utils/Point4D.h" #include "../Triangle.h" #include "Simplex.h" +#include "Mesh.h" struct CollisionPoint { Point4D a; // Furthest point of a into b @@ -19,20 +20,13 @@ struct CollisionPoint { bool hasCollision; }; -class RigidBody { -protected: - Point4D p_velocity; - Point4D p_acceleration; - - bool _collision = false; - bool _isCollider = true; - - bool _inCollision = false; - Point4D _collisionNormal; - +class RigidBody : public Mesh { +private: Point4D _findFurthestPoint(const Point4D& direction); Point4D _support(std::shared_ptr obj, const Point4D& direction); + std::function)> _collisionCallBack; + static bool _nextSimplex(Simplex& points, Point4D& direction); static bool _line(Simplex& points, Point4D& direction); static bool _triangle(Simplex& points, Point4D& direction); @@ -41,9 +35,19 @@ protected: static std::pair, size_t> GetFaceNormals(const std::vector& polytope, const std::vector& faces); static void AddIfUniqueEdge(std::vector>& edges, const std::vector& faces, size_t a, size_t b); +protected: + Point4D _velocity; + Point4D _acceleration; + + bool _collision = false; + bool _isCollider = true; + + bool _inCollision = false; + Point4D _collisionNormal; + public: RigidBody() = default; - virtual ~RigidBody() = default; + explicit RigidBody(const Mesh& mesh); std::pair checkGJKCollision(std::shared_ptr obj); CollisionPoint EPA(const Simplex& simplex, std::shared_ptr obj); @@ -56,19 +60,16 @@ public: void setCollision(bool c) { _collision= c; } void setCollider(bool c) { _isCollider = c; } - [[nodiscard]] virtual std::vector& triangles() = 0; - - [[nodiscard]] virtual Point4D position() const = 0; - virtual void translate(const Point4D& dv) = 0; - virtual void rotate(const Point4D& r) = 0; - void updatePhysicsState(); void setVelocity(const Point4D& velocity); void addVelocity(const Point4D& velocity); void setAcceleration(const Point4D& acceleration); - [[nodiscard]] Point4D velocity() const { return p_velocity; } + [[nodiscard]] Point4D velocity() const { return _velocity; } + + [[nodiscard]] const std::function)>& collisionCallBack() const { return _collisionCallBack; } + void setCollisionCallBack(const std::function)>& f) { _collisionCallBack = f; } }; diff --git a/engine/utils/Point4D.cpp b/engine/utils/Point4D.cpp index 69980d5..fea6de0 100755 --- a/engine/utils/Point4D.cpp +++ b/engine/utils/Point4D.cpp @@ -46,7 +46,7 @@ Point4D Point4D::operator-(const Point4D& point4D) const { double Point4D::dot(const Point4D& point4D) const { - return point4D.x() * x() + point4D.y() * y() + point4D.z() * z() + point4D.w() * w(); + return point4D.x() * x() + point4D.y() * y() + point4D.z() * z(); } [[nodiscard]] Point4D Point4D::cross3D(const Point4D& point4D) const { return Point4D {y() * point4D.z() - point4D.y() * z(), diff --git a/main.cpp b/main.cpp index 0865751..8c9cc2a 100755 --- a/main.cpp +++ b/main.cpp @@ -75,7 +75,7 @@ public: Shooter() = default; void start() override; - void update(double elapsedTime) override; + void update() override; void gui() override; @@ -84,7 +84,7 @@ public: void Shooter::start() { // This code executed once in the beginning: - debugText(false); + setDebugText(false); screen->setMouseCursorVisible(true); @@ -100,7 +100,7 @@ void Shooter::start() { setUpdateWorld(false); - world->addMesh(player, player->name()); + world->addBody(player, player->name()); player->setDamagePlayerCallBack([this] (sf::Uint16 targetId, double damage) { client->damagePlayer(targetId, damage); }); player->setTakeBonusCallBack([this] (const string& bonusName) { client->takeBonus(bonusName); }); @@ -132,7 +132,7 @@ void Shooter::start() { } } -void Shooter::update(double elapsedTime) { +void Shooter::update() { // This code executed every time step: server->update(); @@ -148,7 +148,7 @@ void Shooter::update(double elapsedTime) { } if(inGame) { - screen->title("Shooter"); + screen->setName("Shooter"); player->update(); } else { mainMenu.update(screen); @@ -166,19 +166,16 @@ void Shooter::update(double elapsedTime) { void Shooter::gui() { - if(inGame) { - // aim - sf::Sprite sprite; - sprite.setTexture(*ResourceManager::loadTexture("../textures/gui.png")); - sprite.setTextureRect(sf::IntRect(243, 3, 9, 9)); - sprite.scale(3, 3); - sprite.setPosition(screen->width() / 2.0 - 27.0/2.0, screen->height() / 2 - 27.0/2.0); - sprite.setColor(sf::Color(0,0,0, 200)); - screen->window.draw(sprite); + sf::Sprite sprite; + sprite.setTexture(*ResourceManager::loadTexture("../textures/gui.png")); + sprite.setTextureRect(sf::IntRect(243, 3, 9, 9)); + sprite.scale(3, 3); + sprite.setPosition(screen->width() / 2.0 - 27.0/2.0, screen->height() / 2 - 27.0/2.0); + sprite.setColor(sf::Color(0,0,0, 200)); + screen->window.draw(sprite); - // health player stats - player->drawStats(); - } + // health player stats + player->drawStats(); } void Shooter::play() { diff --git a/weapon/Shotgun.cpp b/weapon/Shotgun.cpp index 5be64ae..25617a1 100755 --- a/weapon/Shotgun.cpp +++ b/weapon/Shotgun.cpp @@ -41,13 +41,13 @@ Shotgun::processFire(std::shared_ptr world, std::shared_ptr camer string traceName = _name + "_trace_nr_" + std::to_string(fireTraces++); Point4D from = _objects[_name + "_" + to_string(9)]->position() + _objects[_name + "_" + to_string(9)]->triangles()[0][0]; - world->addMesh(make_shared(Mesh::LineTo(from, to, 0.05)), traceName); - (*world)[traceName]->setCollider(false); + world->addBody(make_shared(Mesh::LineTo(from, to, 0.05)), traceName); + world->body(traceName)->setCollider(false); // remove trace line after some time - (*world)[traceName]->a_color("color_trace", {255, 255, 255, 0}, 1, Animation::None, Animation::linear); - (*world)["map_0"]->a_function(traceName + "delete", [world, traceName]() { deleteTrace(world, traceName); }, - 1, 2); + world->body(traceName)->a_color("color_trace", {255, 255, 255, 0}, 1, Animation::None, Animation::linear); + world->body("map_0")->a_function(traceName + "delete", [world, traceName]() { deleteTrace(world, traceName); }, + 1, 2); addTraceCallBack(from, to); } diff --git a/weapon/Weapon.cpp b/weapon/Weapon.cpp index 13dca7c..478724a 100755 --- a/weapon/Weapon.cpp +++ b/weapon/Weapon.cpp @@ -14,13 +14,16 @@ Weapon::Weapon(const std::string& weaponName, const std::string& objFileName, co auto objs = Mesh::LoadObjects(objFileName, matFileName, scale); for(int i = 0; i < objs.size(); i++) { string meshName = _name + "_" + to_string(i); - objs[i]->setCollider(false); + + RigidBody obj(*objs[i]); + + obj.setCollider(false); //transforms - objs[i]->rotate(rotate); - objs[i]->translate(translate); + obj.rotate(rotate); + obj.translate(translate); - _objects.insert({meshName, objs[i]}); + _objects.insert({meshName, std::make_shared(obj)}); } noAmmoSound.setBuffer(*ResourceManager::loadSoundBuffer("../sound/weapons/no_ammo.ogg")); } @@ -62,13 +65,13 @@ void Weapon::reload() { void Weapon::addToWorld(shared_ptr world) { for(auto& obj : _objects) { - world->addMesh(obj.second, obj.first); + world->addBody(obj.second, obj.first); } } void Weapon::removeFromWorld(shared_ptr world) { for(auto& obj : _objects) { - world->removeMeshInstantly(obj.first); + world->removeBodyInstantly(obj.first); } } @@ -90,7 +93,7 @@ void Weapon::translate(const Point4D &point4D) { } void Weapon::deleteTrace(shared_ptr world, const std::string& traceName) { - world->removeMesh(traceName); + world->removeBody(traceName); } void Weapon::rotateRelativePoint(const Point4D &point4D, const Point4D &v, double val) { @@ -114,12 +117,12 @@ std::map Weapon::processFire(shared_ptr world, share Point4D to = rayCast.first.w() == -1 ? camera->position() + camera->lookAt() * 1000 + randV: rayCast.first; string traceName = _name + "_trace_nr_" + std::to_string(fireTraces++); Point4D from = _objects[_name + "_" + to_string(_objects.size()-1)]->position() + _objects[_name + "_" + to_string(_objects.size()-1)]->triangles()[0][0]; - world->addMesh(make_shared(Mesh::LineTo(from, to, 0.05)), traceName); - (*world)[traceName]->setCollider(false); + world->addBody(make_shared(Mesh::LineTo(from, to, 0.05)), traceName); + world->body(traceName)->setCollider(false); // remove trace line after some time - (*world)[traceName]->a_color("color_trace", {255, 255, 255, 0}, 1, Animation::None, Animation::linear); - (*world)["Player_im"]->a_function(traceName + "delete", [world, traceName](){deleteTrace(world, traceName); }, 1, 2); + world->body(traceName)->a_color("color_trace", {255, 255, 255, 0}, 1, Animation::None, Animation::linear); + world->body("Player_im")->a_function(traceName + "delete", [world, traceName](){deleteTrace(world, traceName); }, 1, 2); addTraceCallBack(from, to); diff --git a/weapon/Weapon.h b/weapon/Weapon.h index cdfb345..0e33506 100755 --- a/weapon/Weapon.h +++ b/weapon/Weapon.h @@ -28,7 +28,7 @@ protected: double _spreading = 2.0; std::string _name = "Weapon_name"; - std::map> _objects; + std::map> _objects; double _lastFireTime = -INFINITY; double _lastReloadTime = -INFINITY;