Made Triangle immutable
Correct inheritance (Objects -> Mesh & Camera -> RigidBody) Small code refactormaster
parent
17a307c45e
commit
be42d4d9bc
2
Bonus.h
2
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:
|
||||
|
|
70
Client.cpp
70
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<Player>() });
|
||||
(*_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>(Mesh::LineTo(p1, p2, 0.05)), tmp);
|
||||
(*_world)[tmp]->setCollider(false);
|
||||
_world->addBody(std::make_shared<RigidBody>(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<Bonus>(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<Bonus>(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<Bonus>(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<Bonus>(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> world, const std::string &traceName) {
|
||||
world->removeMesh(traceName);
|
||||
world->removeBody(traceName);
|
||||
}
|
||||
|
||||
void Client::takeBonus(const std::string& bonusName) {
|
||||
|
|
2
Client.h
2
Client.h
|
@ -21,7 +21,7 @@ private:
|
|||
|
||||
void spawnPlayer(sf::Uint16 id);
|
||||
public:
|
||||
Client(std::shared_ptr<Player> player, std::shared_ptr<World> world) : _player(std::move(player)), _world(std::move(world)) {};
|
||||
Client(std::shared_ptr<Player> player, std::shared_ptr<World> world) : _player(player), _world(world) {};
|
||||
|
||||
void updatePacket() override;
|
||||
|
||||
|
|
98
Player.cpp
98
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<Mesh> obj) {
|
||||
void Player::collisionWithObject(const std::string &objName, std::shared_ptr<RigidBody> obj) {
|
||||
if(objName.find("Bonus_gun") != std::string::npos)
|
||||
addWeapon(std::make_shared<Gun>());
|
||||
|
||||
|
@ -299,13 +299,13 @@ void Player::collisionWithObject(const std::string &objName, std::shared_ptr<Mes
|
|||
setFullAbility();
|
||||
|
||||
if(objName.find("Bonus") != std::string::npos) {
|
||||
_world->removeMesh(objName);
|
||||
takeBonusCallBack(objName);
|
||||
_world->removeBody(objName);
|
||||
_takeBonusCallBack(objName);
|
||||
}
|
||||
}
|
||||
|
||||
void Player::addWeapon(std::shared_ptr<Weapon> weapon) {
|
||||
changeWeaponSound.play();
|
||||
_changeWeaponSound.play();
|
||||
|
||||
if(!_weapons.empty()) {
|
||||
for(auto& w : _weapons) {
|
||||
|
@ -320,11 +320,11 @@ void Player::addWeapon(std::shared_ptr<Weapon> 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() {
|
||||
|
|
77
Player.h
77
Player.h
|
@ -8,7 +8,6 @@
|
|||
#include <SFML/Audio/Sound.hpp>
|
||||
#include <utility>
|
||||
#include <ResourceManager.h>
|
||||
#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> _camera;
|
||||
std::shared_ptr<Screen> _screen;
|
||||
|
||||
std::shared_ptr<World> _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<std::shared_ptr<Weapon>> _weapons;
|
||||
uint8_t _selectedWeapon = 0;
|
||||
|
||||
std::function<void(sf::Uint16 targetId, double)> damagePlayerCallBack;
|
||||
std::function<void(const Point4D&, const Point4D&)> addTraceCallBack;
|
||||
std::function<void(const std::string&)> takeBonusCallBack;
|
||||
std::function<void(sf::Uint16 targetId, double)> _damagePlayerCallBack;
|
||||
std::function<void(const Point4D&, const Point4D&)> _addTraceCallBack;
|
||||
std::function<void(const std::string&)> _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<RigidBody> obj) {collisionWithObject(objName, obj);});
|
||||
};
|
||||
|
||||
void update();
|
||||
|
||||
void attachCamera(std::shared_ptr<Camera> camera, std::shared_ptr<Screen> 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> 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<Mesh> 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<void(sf::Uint16 targetId, double)> hit) {
|
||||
damagePlayerCallBack = std::move(hit);
|
||||
_damagePlayerCallBack = std::move(hit);
|
||||
}
|
||||
|
||||
void setAddTraceCallBack(std::function<void(const Point4D&, const Point4D&)> add) {
|
||||
addTraceCallBack = std::move(add);
|
||||
_addTraceCallBack = std::move(add);
|
||||
}
|
||||
|
||||
void setTakeBonusCallBack(std::function<void(const std::string&)> 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<Mesh> obj);
|
||||
void collisionWithObject(const std::string& objName, std::shared_ptr<RigidBody> obj);
|
||||
|
||||
void addWeapon(std::shared_ptr<Weapon> weapon);
|
||||
|
||||
|
|
|
@ -5,25 +5,25 @@
|
|||
#include "Camera.h"
|
||||
#include "utils/Log.h"
|
||||
|
||||
std::vector<Triangle> &Camera::project(Mesh& mesh, Screen::ViewMode mode) {
|
||||
std::vector<Triangle> &Camera::project(std::shared_ptr<Mesh> 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<Triangle> 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<Triangle> &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<Triangle> &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<Triangle> &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<double> v_z1({t1[0].z(), t1[1].z(), t1[2].z()});
|
||||
std::vector<double> v_z2({t2[0].z(), t2[1].z(), t2[2].z()});
|
||||
|
@ -118,44 +117,44 @@ std::vector<Triangle> &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);
|
||||
}
|
||||
|
|
|
@ -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<Triangle> triangles;
|
||||
std::vector<Plane> clipPlanes;
|
||||
std::vector<Triangle> _triangles;
|
||||
std::vector<Plane> _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<Triangle>& project(Mesh& mesh, Screen::ViewMode mode);
|
||||
std::vector<Triangle>& project(std::shared_ptr<Mesh> mesh);
|
||||
|
||||
void record();
|
||||
void clear();
|
||||
|
||||
[[nodiscard]] int buffSize() const { return triangles.size(); }
|
||||
[[nodiscard]] int buffSize() const { return _triangles.size(); }
|
||||
std::vector<Triangle>& 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;
|
||||
};
|
||||
|
||||
|
|
|
@ -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<bool, Simplex> 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();
|
||||
}
|
||||
|
||||
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");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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> screen;
|
||||
std::shared_ptr<World> world;
|
||||
std::shared_ptr<Camera> 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(){}
|
||||
};
|
||||
|
|
|
@ -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<Triangle> &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<std::shared_ptr<Mesh>>
|
||||
Mesh::LoadObjects(const string &filename, const string &materials, const Point4D &scale) {
|
||||
std::vector<std::shared_ptr<Mesh>> Mesh::LoadObjects(const string &filename, const string &materials, const Point4D &scale) {
|
||||
std::vector<std::shared_ptr<Mesh>> objects;
|
||||
map<string, sf::Color> 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;
|
||||
}
|
||||
|
|
|
@ -8,24 +8,16 @@
|
|||
#include <vector>
|
||||
#include "Triangle.h"
|
||||
#include "animation/Animatable.h"
|
||||
#include "physics/RigidBody.h"
|
||||
#include <SFML/Graphics.hpp>
|
||||
#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<Triangle> tris;
|
||||
|
||||
std::vector<Triangle> _tris;
|
||||
sf::Color _color = sf::Color(255, 245, 194);
|
||||
bool _visible = true;
|
||||
|
||||
sf::Color c_color = sf::Color(255, 245, 194);
|
||||
|
||||
std::function<void(const std::string&, std::shared_ptr<Mesh>)> _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::vector<Triangle>const &triangles() const { return tris; }
|
||||
[[nodiscard]] std::vector<Triangle>& triangles() override { return tris; }
|
||||
void setTriangles(const std::vector<Triangle>& t) override { tris = t; }
|
||||
[[nodiscard]] std::vector<Triangle>const &triangles() const { return _tris; }
|
||||
[[nodiscard]] std::vector<Triangle>& triangles() override { return _tris; }
|
||||
void setTriangles(const std::vector<Triangle>& 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<std::shared_ptr<Mesh>> static LoadObjects(const std::string& filename, const std::string &materials = "", const Point4D& scale = Point4D{1, 1, 1});
|
||||
|
||||
[[nodiscard]] const std::function<void(const std::string&, std::shared_ptr<Mesh>)>& collisionCallBack() const { return _collisionCallBack; }
|
||||
void setCollisionCallBack(const std::function<void(const std::string&, std::shared_ptr<Mesh>)>& f) { _collisionCallBack = f; }
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -11,10 +11,10 @@
|
|||
|
||||
class Object {
|
||||
protected:
|
||||
std::vector<std::shared_ptr<Object>> v_attached;
|
||||
std::vector<std::shared_ptr<Object>> _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> object) {
|
||||
v_attached.push_back(std::move(object));
|
||||
_attachedObjects.push_back(object);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -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<Point4D, double> 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<Point4D, double> 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<Point4D, double> intersect1 = intersection(insidePoints[0], outsidePoints[0]);
|
||||
std::pair<Point4D, double> 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<Point4D, double> intersect1 = intersection(insidePoints[0], outsidePoints[0]);
|
||||
std::pair<Point4D, double> 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;
|
||||
}
|
||||
|
|
|
@ -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<Point4D, double> 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<Point4D, double> 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; }
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
#include "ResourceManager.h"
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <iostream>
|
||||
|
||||
namespace ResourceManager
|
||||
{
|
||||
namespace
|
||||
|
@ -13,7 +13,6 @@ namespace ResourceManager
|
|||
std::map<std::string, std::shared_ptr<sf::Texture>> _textures;
|
||||
std::map<std::string, std::shared_ptr<sf::Font>> _fonts;
|
||||
std::map<std::string, std::shared_ptr<sf::SoundBuffer>> _soundBuffers;
|
||||
std::map<std::string, std::shared_ptr<sf::Shader>> _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<sf::Texture> loadTexture(const std::string& filename)
|
||||
|
@ -103,21 +95,4 @@ namespace ResourceManager
|
|||
|
||||
return font;
|
||||
}
|
||||
|
||||
std::shared_ptr<sf::Shader> 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<sf::Shader> shader(new sf::Shader);
|
||||
if (!shader->loadFromFile(filename, type))
|
||||
return nullptr;
|
||||
|
||||
// If success - remember and return texture pointer
|
||||
_shaders.emplace(filename, shader);
|
||||
|
||||
return shader;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,7 +25,6 @@ namespace ResourceManager
|
|||
std::shared_ptr<sf::Texture> loadTexture(const std::string& filename);
|
||||
std::shared_ptr<sf::Font> loadFont(const std::string& filename);
|
||||
std::shared_ptr<sf::SoundBuffer> loadSoundBuffer(const std::string& filename);
|
||||
std::shared_ptr<sf::Shader> loadShader(const std::string& filename, sf::Shader::Type type);
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -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<int> disp = sf::Mouse::getPosition(window) - sf::Vector2<int>(w/2, h/2);
|
||||
sf::Vector2<int> disp = sf::Mouse::getPosition(window) - sf::Vector2<int>(_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);
|
||||
|
|
|
@ -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<sf::Keyboard::Key, double> _tappedKeys;
|
||||
std::map<sf::Mouse::Button, double> _tappedButtons;
|
||||
|
||||
std::map<sf::Keyboard::Key, double> tappedKeys;
|
||||
std::map<sf::Mouse::Button, double> 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);
|
||||
};
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -10,34 +10,25 @@
|
|||
#include <SFML/Graphics.hpp>
|
||||
|
||||
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; }
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -2,35 +2,27 @@
|
|||
// Created by Иван Ильин on 13.01.2021.
|
||||
//
|
||||
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include "World.h"
|
||||
#include "utils/Log.h"
|
||||
#include "Plane.h"
|
||||
#include "physics/Solver.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
void World::addMesh(std::shared_ptr<Mesh> 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<RigidBody> 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<Mesh>(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<RigidBody>(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<Mesh> 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<Point4D, string> World::rayCast(const Point4D& from, const Point4D& to) {
|
||||
|
||||
std::pair<Point4D, string> result{Point4D{0, 0,0, -1}, ""};
|
||||
|
@ -41,7 +33,7 @@ std::pair<Point4D, string> 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<RigidBody>(*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<bool, Simplex> 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> camera) {
|
||||
for (auto &m : _objects)
|
||||
camera->project(m.second);
|
||||
}
|
||||
|
||||
std::shared_ptr<RigidBody> World::body(const string &name) {
|
||||
if(_objects.count(name) == 0)
|
||||
Log::log("World::body: mesh '" + name + "' does not exist.");
|
||||
return _objects.find(name)->second;
|
||||
}
|
||||
|
|
|
@ -6,25 +6,26 @@
|
|||
#define ENGINE_WORLD_H
|
||||
|
||||
#include <map>
|
||||
#include "Mesh.h"
|
||||
#include "Camera.h"
|
||||
#include "physics/RigidBody.h"
|
||||
|
||||
class World {
|
||||
private:
|
||||
std::map<std::string, std::shared_ptr<Mesh>> _objects;
|
||||
|
||||
std::map<std::string, std::shared_ptr<RigidBody>> _objects;
|
||||
std::vector<std::string> _objToRemove;
|
||||
public:
|
||||
World() = default;
|
||||
|
||||
[[nodiscard]] std::shared_ptr<Mesh> operator[] (const std::string& name);
|
||||
void checkCollision(const std::string& body);
|
||||
void update();
|
||||
void projectObjectsInCamera(std::shared_ptr<Camera> camera);
|
||||
|
||||
[[nodiscard]] std::map<std::string, std::shared_ptr<Mesh>>& objects() { return _objects; }
|
||||
|
||||
void addMesh(std::shared_ptr<Mesh> mesh, const std::string& name = "");
|
||||
void removeMesh(const std::string& name);
|
||||
void removeMeshInstantly(const std::string& name);
|
||||
void addBody(std::shared_ptr<RigidBody> mesh, const std::string& name = "");
|
||||
std::shared_ptr<RigidBody> 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)
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@ void Window::addButton(int x, int y, int w, int h, std::function<void()> click,
|
|||
|
||||
void Window::update(std::shared_ptr<Screen> screen) {
|
||||
|
||||
screen->title(s_name);
|
||||
screen->setName(s_name);
|
||||
screen->window.draw(back);
|
||||
|
||||
Point4D mousePos = screen->getMousePosition();
|
||||
|
|
|
@ -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<std::pair<size_t, size_t>>& 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) {
|
||||
|
||||
}
|
||||
|
|
|
@ -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<RigidBody> obj, const Point4D& direction);
|
||||
|
||||
std::function<void(const std::string&, std::shared_ptr<RigidBody>)> _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<std::vector<Point4D>, size_t> GetFaceNormals(const std::vector<Point4D>& polytope, const std::vector<size_t>& faces);
|
||||
static void AddIfUniqueEdge(std::vector<std::pair<size_t, size_t>>& edges, const std::vector<size_t>& 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<bool, Simplex> checkGJKCollision(std::shared_ptr<RigidBody> obj);
|
||||
CollisionPoint EPA(const Simplex& simplex, std::shared_ptr<RigidBody> obj);
|
||||
|
@ -56,19 +60,16 @@ public:
|
|||
void setCollision(bool c) { _collision= c; }
|
||||
void setCollider(bool c) { _isCollider = c; }
|
||||
|
||||
[[nodiscard]] virtual std::vector<Triangle>& 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<void(const std::string&, std::shared_ptr<RigidBody>)>& collisionCallBack() const { return _collisionCallBack; }
|
||||
void setCollisionCallBack(const std::function<void(const std::string&, std::shared_ptr<RigidBody>)>& f) { _collisionCallBack = f; }
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -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(),
|
||||
|
|
13
main.cpp
13
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,8 +166,6 @@ 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));
|
||||
|
@ -179,7 +177,6 @@ void Shooter::gui() {
|
|||
// health player stats
|
||||
player->drawStats();
|
||||
}
|
||||
}
|
||||
|
||||
void Shooter::play() {
|
||||
inGame = true;
|
||||
|
|
|
@ -41,12 +41,12 @@ Shotgun::processFire(std::shared_ptr<World> world, std::shared_ptr<Camera> 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>(Mesh::LineTo(from, to, 0.05)), traceName);
|
||||
(*world)[traceName]->setCollider(false);
|
||||
world->addBody(make_shared<RigidBody>(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); },
|
||||
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);
|
||||
}
|
||||
|
|
|
@ -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<RigidBody>(obj)});
|
||||
}
|
||||
noAmmoSound.setBuffer(*ResourceManager::loadSoundBuffer("../sound/weapons/no_ammo.ogg"));
|
||||
}
|
||||
|
@ -62,13 +65,13 @@ void Weapon::reload() {
|
|||
|
||||
void Weapon::addToWorld(shared_ptr<World> world) {
|
||||
for(auto& obj : _objects) {
|
||||
world->addMesh(obj.second, obj.first);
|
||||
world->addBody(obj.second, obj.first);
|
||||
}
|
||||
}
|
||||
|
||||
void Weapon::removeFromWorld(shared_ptr<World> 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> 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<std::string, double> Weapon::processFire(shared_ptr<World> 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>(Mesh::LineTo(from, to, 0.05)), traceName);
|
||||
(*world)[traceName]->setCollider(false);
|
||||
world->addBody(make_shared<RigidBody>(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);
|
||||
|
||||
|
|
|
@ -28,7 +28,7 @@ protected:
|
|||
double _spreading = 2.0;
|
||||
|
||||
std::string _name = "Weapon_name";
|
||||
std::map<std::string, std::shared_ptr<Mesh>> _objects;
|
||||
std::map<std::string, std::shared_ptr<RigidBody>> _objects;
|
||||
|
||||
double _lastFireTime = -INFINITY;
|
||||
double _lastReloadTime = -INFINITY;
|
||||
|
|
Loading…
Reference in New Issue