code refactoring
parent
c2620aa8a5
commit
785850ec43
42
Player.cpp
42
Player.cpp
|
@ -13,47 +13,49 @@ Player::Player(ObjectNameTag name) : RigidBody(name) {
|
||||||
setVisible(false);
|
setVisible(false);
|
||||||
|
|
||||||
Vec3D randColor = Vec3D::Random();
|
Vec3D randColor = Vec3D::Random();
|
||||||
setColor({static_cast<sf::Uint8>(randColor.x()*255), static_cast<sf::Uint8>(randColor.y()*255), static_cast<sf::Uint8>(randColor.z()*255)});
|
setColor({static_cast<sf::Uint8>(randColor.x() * 255), static_cast<sf::Uint8>(randColor.y() * 255),
|
||||||
|
static_cast<sf::Uint8>(randColor.z() * 255)});
|
||||||
|
|
||||||
setCollisionCallBack([this](const ObjectNameTag& tag, std::shared_ptr<RigidBody> obj) {collisionWithObject(tag, obj);});
|
setCollisionCallBack(
|
||||||
|
[this](const ObjectNameTag &tag, std::shared_ptr<RigidBody> obj) { collisionWithObject(tag, obj); });
|
||||||
}
|
}
|
||||||
|
|
||||||
void Player::rotateWeaponsRelativePoint(const Vec3D& point4D, const Vec3D& v, double val) {
|
void Player::rotateWeaponsRelativePoint(const Vec3D &point4D, const Vec3D &v, double val) {
|
||||||
for(auto& weapon : _weapons) {
|
for (auto &weapon : _weapons) {
|
||||||
weapon->rotateRelativePoint(point4D, v, val);
|
weapon->rotateRelativePoint(point4D, v, val);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Player::collisionWithObject(const ObjectNameTag& tag, std::shared_ptr<RigidBody> obj) {
|
void Player::collisionWithObject(const ObjectNameTag &tag, std::shared_ptr<RigidBody> obj) {
|
||||||
if(tag.str().find("Bonus_gun") != std::string::npos) {
|
if (tag.str().find("Bonus_gun") != std::string::npos) {
|
||||||
addWeapon(std::make_shared<Gun>());
|
addWeapon(std::make_shared<Gun>());
|
||||||
}
|
}
|
||||||
|
|
||||||
if(tag.str().find("Bonus_shotgun") != std::string::npos) {
|
if (tag.str().find("Bonus_shotgun") != std::string::npos) {
|
||||||
addWeapon(std::make_shared<Shotgun>());
|
addWeapon(std::make_shared<Shotgun>());
|
||||||
}
|
}
|
||||||
|
|
||||||
if(tag.str().find("Bonus_ak47") != std::string::npos) {
|
if (tag.str().find("Bonus_ak47") != std::string::npos) {
|
||||||
addWeapon(std::make_shared<Ak47>());
|
addWeapon(std::make_shared<Ak47>());
|
||||||
}
|
}
|
||||||
|
|
||||||
if(tag.str().find("Bonus_gold_ak47") != std::string::npos) {
|
if (tag.str().find("Bonus_gold_ak47") != std::string::npos) {
|
||||||
addWeapon(std::make_shared<Gold_Ak47>());
|
addWeapon(std::make_shared<Gold_Ak47>());
|
||||||
}
|
}
|
||||||
|
|
||||||
if(tag.str().find("Bonus_rifle") != std::string::npos) {
|
if (tag.str().find("Bonus_rifle") != std::string::npos) {
|
||||||
addWeapon(std::make_shared<Rifle>());
|
addWeapon(std::make_shared<Rifle>());
|
||||||
}
|
}
|
||||||
|
|
||||||
if(tag.str().find("Bonus_hill") != std::string::npos) {
|
if (tag.str().find("Bonus_hill") != std::string::npos) {
|
||||||
setFullHealth();
|
setFullHealth();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(tag.str().find("Bonus_ability") != std::string::npos) {
|
if (tag.str().find("Bonus_ability") != std::string::npos) {
|
||||||
setFullAbility();
|
setFullAbility();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(tag.str().find("Bonus") != std::string::npos) {
|
if (tag.str().find("Bonus") != std::string::npos) {
|
||||||
_takeBonusCallBack(tag.str());
|
_takeBonusCallBack(tag.str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -61,7 +63,7 @@ void Player::collisionWithObject(const ObjectNameTag& tag, std::shared_ptr<Rigid
|
||||||
void Player::addWeapon(std::shared_ptr<Weapon> weapon) {
|
void Player::addWeapon(std::shared_ptr<Weapon> weapon) {
|
||||||
SoundController::playSound(SoundTag("changeWeapon"), ShooterConsts::CHANGE_WEAPON_SOUND);
|
SoundController::playSound(SoundTag("changeWeapon"), ShooterConsts::CHANGE_WEAPON_SOUND);
|
||||||
|
|
||||||
for(auto& w : _weapons) {
|
for (auto &w : _weapons) {
|
||||||
if (w->name() == weapon->name()) {
|
if (w->name() == weapon->name()) {
|
||||||
w->addAmmo(w->initialPack());
|
w->addAmmo(w->initialPack());
|
||||||
return;
|
return;
|
||||||
|
@ -80,8 +82,8 @@ void Player::addWeapon(std::shared_ptr<Weapon> weapon) {
|
||||||
|
|
||||||
void Player::initWeapons() {
|
void Player::initWeapons() {
|
||||||
|
|
||||||
if(!_weapons.empty()) {
|
if (!_weapons.empty()) {
|
||||||
for(auto weapon : _weapons) {
|
for (auto weapon : _weapons) {
|
||||||
unattach(ObjectNameTag(weapon->name()));
|
unattach(ObjectNameTag(weapon->name()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -95,7 +97,7 @@ void Player::initWeapons() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Player::nextWeapon() {
|
void Player::nextWeapon() {
|
||||||
if(_weapons.size() > 1) {
|
if (_weapons.size() > 1) {
|
||||||
// change '_selectedWeapon'
|
// change '_selectedWeapon'
|
||||||
_removeWeaponCallBack(_weapons[_selectedWeapon]);
|
_removeWeaponCallBack(_weapons[_selectedWeapon]);
|
||||||
_selectedWeapon = (_selectedWeapon + 1) % _weapons.size();
|
_selectedWeapon = (_selectedWeapon + 1) % _weapons.size();
|
||||||
|
@ -106,7 +108,7 @@ void Player::nextWeapon() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Player::previousWeapon() {
|
void Player::previousWeapon() {
|
||||||
if(_weapons.size() > 1) {
|
if (_weapons.size() > 1) {
|
||||||
// change '_selectedWeapon'
|
// change '_selectedWeapon'
|
||||||
_removeWeaponCallBack(_weapons[_selectedWeapon]);
|
_removeWeaponCallBack(_weapons[_selectedWeapon]);
|
||||||
if (_selectedWeapon > 0) {
|
if (_selectedWeapon > 0) {
|
||||||
|
@ -122,9 +124,9 @@ void Player::previousWeapon() {
|
||||||
|
|
||||||
bool Player::fire() {
|
bool Player::fire() {
|
||||||
auto camera = attached(ObjectNameTag("Camera"));
|
auto camera = attached(ObjectNameTag("Camera"));
|
||||||
if(camera != nullptr) {
|
if (camera != nullptr) {
|
||||||
auto fireInfo = _weapons[_selectedWeapon]->fire(_rayCastFunction, camera->position(), camera->lookAt());
|
auto fireInfo = _weapons[_selectedWeapon]->fire(_rayCastFunction, camera->position(), camera->lookAt());
|
||||||
for(auto& [damagedPlayerName, damage] : fireInfo.damagedPlayers) {
|
for (auto&[damagedPlayerName, damage] : fireInfo.damagedPlayers) {
|
||||||
sf::Uint16 targetId = std::stoi(damagedPlayerName.str().substr(6));
|
sf::Uint16 targetId = std::stoi(damagedPlayerName.str().substr(6));
|
||||||
_damagePlayerCallBack(targetId, damage);
|
_damagePlayerCallBack(targetId, damage);
|
||||||
}
|
}
|
||||||
|
|
42
Player.h
42
Player.h
|
@ -17,7 +17,7 @@
|
||||||
#include "weapon/Rifle.h"
|
#include "weapon/Rifle.h"
|
||||||
#include "ShooterConsts.h"
|
#include "ShooterConsts.h"
|
||||||
|
|
||||||
class Player final : public RigidBody{
|
class Player final : public RigidBody {
|
||||||
private:
|
private:
|
||||||
double _health = ShooterConsts::HEALTH_MAX;
|
double _health = ShooterConsts::HEALTH_MAX;
|
||||||
double _ability = ShooterConsts::ABILITY_MAX;
|
double _ability = ShooterConsts::ABILITY_MAX;
|
||||||
|
@ -33,75 +33,95 @@ private:
|
||||||
std::string _nickName = ShooterConsts::PLAYER_NAME;
|
std::string _nickName = ShooterConsts::PLAYER_NAME;
|
||||||
|
|
||||||
std::function<void(sf::Uint16 targetId, double)> _damagePlayerCallBack;
|
std::function<void(sf::Uint16 targetId, double)> _damagePlayerCallBack;
|
||||||
std::function<void(const Vec3D&, const Vec3D&)> _addTraceCallBack;
|
std::function<void(const Vec3D &, const Vec3D &)> _addTraceCallBack;
|
||||||
std::function<void(const std::string&)> _takeBonusCallBack;
|
std::function<void(const std::string &)> _takeBonusCallBack;
|
||||||
|
|
||||||
std::function<void(std::shared_ptr<Weapon>)> _addWeaponCallBack;
|
std::function<void(std::shared_ptr<Weapon>)> _addWeaponCallBack;
|
||||||
std::function<void(std::shared_ptr<Weapon>)> _removeWeaponCallBack;
|
std::function<void(std::shared_ptr<Weapon>)> _removeWeaponCallBack;
|
||||||
|
|
||||||
std::function<IntersectionInformation(const Vec3D&, const Vec3D&)> _rayCastFunction;
|
std::function<IntersectionInformation(const Vec3D &, const Vec3D &)> _rayCastFunction;
|
||||||
public:
|
public:
|
||||||
explicit Player(ObjectNameTag name);
|
explicit Player(ObjectNameTag name);
|
||||||
|
|
||||||
void setHealth(double h) { _health = h; }
|
void setHealth(double h) { _health = h; }
|
||||||
|
|
||||||
void setAbility(double a) { _ability = a; }
|
void setAbility(double a) { _ability = a; }
|
||||||
|
|
||||||
[[nodiscard]] double health() const { return _health; }
|
[[nodiscard]] double health() const { return _health; }
|
||||||
|
|
||||||
[[nodiscard]] double ability() const { return _ability; }
|
[[nodiscard]] double ability() const { return _ability; }
|
||||||
|
|
||||||
|
|
||||||
void setFullHealth();
|
void setFullHealth();
|
||||||
|
|
||||||
void setFullAbility();
|
void setFullAbility();
|
||||||
|
|
||||||
void initWeapons();
|
void initWeapons();
|
||||||
|
|
||||||
void addWeapon(std::shared_ptr<Weapon> weapon);
|
void addWeapon(std::shared_ptr<Weapon> weapon);
|
||||||
[[nodiscard]] std::pair<double, double> balance() const{ return _weapons[_selectedWeapon]->balance();}
|
|
||||||
|
[[nodiscard]] std::pair<double, double> balance() const { return _weapons[_selectedWeapon]->balance(); }
|
||||||
|
|
||||||
void nextWeapon();
|
void nextWeapon();
|
||||||
|
|
||||||
void previousWeapon();
|
void previousWeapon();
|
||||||
|
|
||||||
bool fire();
|
bool fire();
|
||||||
|
|
||||||
void reload();
|
void reload();
|
||||||
|
|
||||||
[[nodiscard]] ObjectNameTag weaponName() const { return _weapons[_selectedWeapon]->name(); }
|
[[nodiscard]] ObjectNameTag weaponName() const { return _weapons[_selectedWeapon]->name(); }
|
||||||
|
|
||||||
std::shared_ptr<Weapon> weapon() { return _weapons[_selectedWeapon]; }
|
std::shared_ptr<Weapon> weapon() { return _weapons[_selectedWeapon]; }
|
||||||
|
|
||||||
void rotateWeaponsRelativePoint(const Vec3D& point, const Vec3D& v, double val);
|
void rotateWeaponsRelativePoint(const Vec3D &point, const Vec3D &v, double val);
|
||||||
|
|
||||||
[[nodiscard]] int kills() const { return _kills; }
|
[[nodiscard]] int kills() const { return _kills; }
|
||||||
|
|
||||||
[[nodiscard]] int deaths() const { return _deaths; }
|
[[nodiscard]] int deaths() const { return _deaths; }
|
||||||
|
|
||||||
void addKill() { _kills++; }
|
void addKill() { _kills++; }
|
||||||
|
|
||||||
void addDeath() { _deaths++; }
|
void addDeath() { _deaths++; }
|
||||||
|
|
||||||
void setKills(int kills) { _kills = kills; }
|
void setKills(int kills) { _kills = kills; }
|
||||||
|
|
||||||
void setDeaths(int deaths) { _deaths = deaths; }
|
void setDeaths(int deaths) { _deaths = deaths; }
|
||||||
|
|
||||||
void setDamagePlayerCallBack(std::function<void(sf::Uint16 targetId, double)> hit) {
|
void setDamagePlayerCallBack(std::function<void(sf::Uint16 targetId, double)> hit) {
|
||||||
_damagePlayerCallBack = std::move(hit);
|
_damagePlayerCallBack = std::move(hit);
|
||||||
}
|
}
|
||||||
void setAddTraceCallBack(std::function<void(const Vec3D&, const Vec3D&)> add) {
|
|
||||||
|
void setAddTraceCallBack(std::function<void(const Vec3D &, const Vec3D &)> add) {
|
||||||
_addTraceCallBack = std::move(add);
|
_addTraceCallBack = std::move(add);
|
||||||
}
|
}
|
||||||
void setTakeBonusCallBack(std::function<void(const std::string&)> take) {
|
|
||||||
|
void setTakeBonusCallBack(std::function<void(const std::string &)> take) {
|
||||||
_takeBonusCallBack = std::move(take);
|
_takeBonusCallBack = std::move(take);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setAddWeaponCallBack(std::function<void(std::shared_ptr<Weapon>)> addWeapon) {
|
void setAddWeaponCallBack(std::function<void(std::shared_ptr<Weapon>)> addWeapon) {
|
||||||
_addWeaponCallBack = std::move(addWeapon);
|
_addWeaponCallBack = std::move(addWeapon);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setRemoveWeaponCallBack(std::function<void(std::shared_ptr<Weapon>)> removeWeapon) {
|
void setRemoveWeaponCallBack(std::function<void(std::shared_ptr<Weapon>)> removeWeapon) {
|
||||||
_removeWeaponCallBack = std::move(removeWeapon);
|
_removeWeaponCallBack = std::move(removeWeapon);
|
||||||
}
|
}
|
||||||
void setRayCastFunction(std::function<IntersectionInformation(const Vec3D&, const Vec3D&)> rayCastFunction) {
|
|
||||||
|
void setRayCastFunction(std::function<IntersectionInformation(const Vec3D &, const Vec3D &)> rayCastFunction) {
|
||||||
_rayCastFunction = std::move(rayCastFunction);
|
_rayCastFunction = std::move(rayCastFunction);
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is for situation when you want to store the position of the head but you dont have attached camera
|
// This is for situation when you want to store the position of the head but you dont have attached camera
|
||||||
void setHeadAngle(double a) { _headAngle = a; }
|
void setHeadAngle(double a) { _headAngle = a; }
|
||||||
|
|
||||||
[[nodiscard]] double headAngle() const { return _headAngle; };
|
[[nodiscard]] double headAngle() const { return _headAngle; };
|
||||||
|
|
||||||
void collisionWithObject(const ObjectNameTag& tag, std::shared_ptr<RigidBody> obj);
|
void collisionWithObject(const ObjectNameTag &tag, std::shared_ptr<RigidBody> obj);
|
||||||
|
|
||||||
[[nodiscard]] std::string playerNickName() const { return _nickName; }
|
[[nodiscard]] std::string playerNickName() const { return _nickName; }
|
||||||
void setPlayerNickName(const std::string& name) { _nickName = name; }
|
|
||||||
|
void setPlayerNickName(const std::string &name) { _nickName = name; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -12,22 +12,24 @@
|
||||||
|
|
||||||
PlayerController::PlayerController(std::shared_ptr<Player> player,
|
PlayerController::PlayerController(std::shared_ptr<Player> player,
|
||||||
std::shared_ptr<Keyboard> keyboard,
|
std::shared_ptr<Keyboard> keyboard,
|
||||||
std::shared_ptr<Mouse> mouse) : _player(player), _keyboard(keyboard), _mouse(mouse) {}
|
std::shared_ptr<Mouse> mouse) : _player(player), _keyboard(keyboard),
|
||||||
|
_mouse(mouse) {}
|
||||||
|
|
||||||
void PlayerController::update() {
|
void PlayerController::update() {
|
||||||
// friction
|
// friction
|
||||||
if(_player->inCollision()) {
|
if (_player->inCollision()) {
|
||||||
_player->setVelocity(_player->velocity() * (1.0 - Time::deltaTime() * 2));
|
_player->setVelocity(_player->velocity() * (1.0 - Time::deltaTime() * 2));
|
||||||
}
|
}
|
||||||
|
|
||||||
if(_isInSlowMo) {
|
if (_isInSlowMo) {
|
||||||
if(_player->ability() > 0) {
|
if (_player->ability() > 0) {
|
||||||
_player->setAbility(_player->ability() - Time::deltaTime());
|
_player->setAbility(_player->ability() - Time::deltaTime());
|
||||||
} else {
|
} else {
|
||||||
_player->setAbility(0);
|
_player->setAbility(0);
|
||||||
_isInSlowMo = false;
|
_isInSlowMo = false;
|
||||||
_player->setVelocity(_player->velocity() * ShooterConsts::SLOW_MO_COEFFICIENT);
|
_player->setVelocity(_player->velocity() * ShooterConsts::SLOW_MO_COEFFICIENT);
|
||||||
_player->setAcceleration(_player->acceleration() * ShooterConsts::SLOW_MO_COEFFICIENT * ShooterConsts::SLOW_MO_COEFFICIENT);
|
_player->setAcceleration(
|
||||||
|
_player->acceleration() * ShooterConsts::SLOW_MO_COEFFICIENT * ShooterConsts::SLOW_MO_COEFFICIENT);
|
||||||
SoundController::stopSound(SoundTag("slowMo"));
|
SoundController::stopSound(SoundTag("slowMo"));
|
||||||
SoundController::playSound(SoundTag("unSlowMo"), ShooterConsts::UN_SLOW_MO_SOUND);
|
SoundController::playSound(SoundTag("unSlowMo"), ShooterConsts::UN_SLOW_MO_SOUND);
|
||||||
}
|
}
|
||||||
|
@ -36,46 +38,64 @@ void PlayerController::update() {
|
||||||
double coeff = _isInSlowMo ? 1.0 / ShooterConsts::SLOW_MO_COEFFICIENT : 1.0;
|
double coeff = _isInSlowMo ? 1.0 / ShooterConsts::SLOW_MO_COEFFICIENT : 1.0;
|
||||||
|
|
||||||
bool inRunning_old = _inRunning;
|
bool inRunning_old = _inRunning;
|
||||||
_inRunning = ( Keyboard::isKeyPressed(sf::Keyboard::A) ||
|
_inRunning = (Keyboard::isKeyPressed(sf::Keyboard::A) ||
|
||||||
Keyboard::isKeyPressed(sf::Keyboard::D) ||
|
Keyboard::isKeyPressed(sf::Keyboard::D) ||
|
||||||
Keyboard::isKeyPressed(sf::Keyboard::W) ||
|
Keyboard::isKeyPressed(sf::Keyboard::W) ||
|
||||||
Keyboard::isKeyPressed(sf::Keyboard::S));
|
Keyboard::isKeyPressed(sf::Keyboard::S));
|
||||||
|
|
||||||
std::shared_ptr<Object> camera = _player->attached(ObjectNameTag("Camera"));
|
std::shared_ptr<Object> camera = _player->attached(ObjectNameTag("Camera"));
|
||||||
if(camera != nullptr && _inRunning && _player->inCollision()) {
|
if (camera != nullptr && _inRunning && _player->inCollision()) {
|
||||||
if (!Timeline::isInAnimList(AnimationListTag("camera_hor_oscil"))) {
|
if (!Timeline::isInAnimList(AnimationListTag("camera_hor_oscil"))) {
|
||||||
Timeline::animate(AnimationListTag("camera_hor_oscil"), std::make_shared<ATranslate>(camera, -camera->left() / 6, 0.3,Animation::LoopOut::None, Animation::InterpolationType::Cos));
|
Timeline::animate(AnimationListTag("camera_hor_oscil"),
|
||||||
|
std::make_shared<ATranslate>(camera, -camera->left() / 6, 0.3, Animation::LoopOut::None,
|
||||||
|
Animation::InterpolationType::Cos));
|
||||||
Timeline::animate(AnimationListTag("camera_hor_oscil"), std::make_shared<AWait>(0));
|
Timeline::animate(AnimationListTag("camera_hor_oscil"), std::make_shared<AWait>(0));
|
||||||
Timeline::animate(AnimationListTag("camera_hor_oscil"), std::make_shared<ATranslate>(camera, camera->left() / 6, 0.3, Animation::LoopOut::None, Animation::InterpolationType::Cos));
|
Timeline::animate(AnimationListTag("camera_hor_oscil"),
|
||||||
|
std::make_shared<ATranslate>(camera, camera->left() / 6, 0.3, Animation::LoopOut::None,
|
||||||
|
Animation::InterpolationType::Cos));
|
||||||
|
|
||||||
Timeline::animate(AnimationListTag("camera_vert_oscil"), std::make_shared<ATranslate>(camera, -Vec3D{0, 1, 0} / 12, 0.15, Animation::LoopOut::None, Animation::InterpolationType::Cos));
|
Timeline::animate(AnimationListTag("camera_vert_oscil"),
|
||||||
|
std::make_shared<ATranslate>(camera, -Vec3D{0, 1, 0} / 12, 0.15, Animation::LoopOut::None,
|
||||||
|
Animation::InterpolationType::Cos));
|
||||||
Timeline::animate(AnimationListTag("camera_vert_oscil"), std::make_shared<AWait>(0));
|
Timeline::animate(AnimationListTag("camera_vert_oscil"), std::make_shared<AWait>(0));
|
||||||
Timeline::animate(AnimationListTag("camera_vert_oscil"), std::make_shared<ATranslate>(camera, Vec3D{0, 1, 0} / 12, 0.15, Animation::LoopOut::None, Animation::InterpolationType::Cos));
|
Timeline::animate(AnimationListTag("camera_vert_oscil"),
|
||||||
|
std::make_shared<ATranslate>(camera, Vec3D{0, 1, 0} / 12, 0.15, Animation::LoopOut::None,
|
||||||
|
Animation::InterpolationType::Cos));
|
||||||
Timeline::animate(AnimationListTag("camera_vert_oscil"), std::make_shared<AWait>(0));
|
Timeline::animate(AnimationListTag("camera_vert_oscil"), std::make_shared<AWait>(0));
|
||||||
Timeline::animate(AnimationListTag("camera_vert_oscil"), std::make_shared<ATranslate>(camera, -Vec3D{0, 1, 0} / 12, 0.15, Animation::LoopOut::None, Animation::InterpolationType::Cos));
|
Timeline::animate(AnimationListTag("camera_vert_oscil"),
|
||||||
|
std::make_shared<ATranslate>(camera, -Vec3D{0, 1, 0} / 12, 0.15, Animation::LoopOut::None,
|
||||||
|
Animation::InterpolationType::Cos));
|
||||||
Timeline::animate(AnimationListTag("camera_vert_oscil"), std::make_shared<AWait>(0));
|
Timeline::animate(AnimationListTag("camera_vert_oscil"), std::make_shared<AWait>(0));
|
||||||
Timeline::animate(AnimationListTag("camera_vert_oscil"), std::make_shared<ATranslate>(camera, Vec3D{0, 1, 0} / 12, 0.15, Animation::LoopOut::None, Animation::InterpolationType::Cos));
|
Timeline::animate(AnimationListTag("camera_vert_oscil"),
|
||||||
|
std::make_shared<ATranslate>(camera, Vec3D{0, 1, 0} / 12, 0.15, Animation::LoopOut::None,
|
||||||
|
Animation::InterpolationType::Cos));
|
||||||
|
|
||||||
Timeline::animate(AnimationListTag("camera_init"), std::make_shared<ATranslateToPoint>( camera, _player->position() + Vec3D{0, 1.8, 0}, 0.3, Animation::LoopOut::None, Animation::InterpolationType::Cos));
|
Timeline::animate(AnimationListTag("camera_init"),
|
||||||
|
std::make_shared<ATranslateToPoint>(camera, _player->position() + Vec3D{0, 1.8, 0}, 0.3,
|
||||||
|
Animation::LoopOut::None,
|
||||||
|
Animation::InterpolationType::Cos));
|
||||||
}
|
}
|
||||||
} else if(camera != nullptr && inRunning_old && !_inRunning) {
|
} else if (camera != nullptr && inRunning_old && !_inRunning) {
|
||||||
Timeline::deleteAnimationList(AnimationListTag("camera_hor_oscil"));
|
Timeline::deleteAnimationList(AnimationListTag("camera_hor_oscil"));
|
||||||
Timeline::deleteAnimationList(AnimationListTag("camera_vert_oscil"));
|
Timeline::deleteAnimationList(AnimationListTag("camera_vert_oscil"));
|
||||||
Timeline::deleteAnimationList(AnimationListTag("camera_init"));
|
Timeline::deleteAnimationList(AnimationListTag("camera_init"));
|
||||||
Timeline::animate(AnimationListTag("camera_init"), std::make_shared<ATranslateToPoint>( camera, _player->position() + Vec3D{0, 1.8, 0}, 0.15, Animation::LoopOut::None, Animation::InterpolationType::Cos));
|
Timeline::animate(AnimationListTag("camera_init"),
|
||||||
|
std::make_shared<ATranslateToPoint>(camera, _player->position() + Vec3D{0, 1.8, 0}, 0.15,
|
||||||
|
Animation::LoopOut::None,
|
||||||
|
Animation::InterpolationType::Cos));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Left and right
|
// Left and right
|
||||||
|
|
||||||
if (Keyboard::isKeyPressed(sf::Keyboard::A)) {
|
if (Keyboard::isKeyPressed(sf::Keyboard::A)) {
|
||||||
_player->translate(_player->left() * Time::deltaTime() * ShooterConsts::WALK_SPEED * coeff);
|
_player->translate(_player->left() * Time::deltaTime() * ShooterConsts::WALK_SPEED * coeff);
|
||||||
if(_player->inCollision()) {
|
if (_player->inCollision()) {
|
||||||
_player->setVelocity(Vec3D{0, 0, 0});
|
_player->setVelocity(Vec3D{0, 0, 0});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (Keyboard::isKeyPressed(sf::Keyboard::D)) {
|
if (Keyboard::isKeyPressed(sf::Keyboard::D)) {
|
||||||
_player->translate(-_player->left() * Time::deltaTime() * ShooterConsts::WALK_SPEED * coeff);
|
_player->translate(-_player->left() * Time::deltaTime() * ShooterConsts::WALK_SPEED * coeff);
|
||||||
if(_player->inCollision()) {
|
if (_player->inCollision()) {
|
||||||
_player->setVelocity(Vec3D{0, 0, 0});
|
_player->setVelocity(Vec3D{0, 0, 0});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -83,7 +103,7 @@ void PlayerController::update() {
|
||||||
// Forward and backward
|
// Forward and backward
|
||||||
if (Keyboard::isKeyPressed(sf::Keyboard::W)) {
|
if (Keyboard::isKeyPressed(sf::Keyboard::W)) {
|
||||||
_player->translate(_player->lookAt() * Time::deltaTime() * ShooterConsts::WALK_SPEED * coeff);
|
_player->translate(_player->lookAt() * Time::deltaTime() * ShooterConsts::WALK_SPEED * coeff);
|
||||||
if(_player->inCollision()) {
|
if (_player->inCollision()) {
|
||||||
_player->setVelocity(Vec3D{0, 0, 0});
|
_player->setVelocity(Vec3D{0, 0, 0});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -91,7 +111,7 @@ void PlayerController::update() {
|
||||||
if (Keyboard::isKeyPressed(sf::Keyboard::S)) {
|
if (Keyboard::isKeyPressed(sf::Keyboard::S)) {
|
||||||
_player->translate(-_player->lookAt() * Time::deltaTime() * ShooterConsts::WALK_SPEED * coeff);
|
_player->translate(-_player->lookAt() * Time::deltaTime() * ShooterConsts::WALK_SPEED * coeff);
|
||||||
|
|
||||||
if(_player->inCollision()) {
|
if (_player->inCollision()) {
|
||||||
_player->setVelocity(Vec3D{0, 0, 0});
|
_player->setVelocity(Vec3D{0, 0, 0});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -100,7 +120,9 @@ void PlayerController::update() {
|
||||||
// slow mo
|
// slow mo
|
||||||
_isInSlowMo = true;
|
_isInSlowMo = true;
|
||||||
_player->setVelocity(_player->velocity() / ShooterConsts::SLOW_MO_COEFFICIENT);
|
_player->setVelocity(_player->velocity() / ShooterConsts::SLOW_MO_COEFFICIENT);
|
||||||
_player->setAcceleration(Vec3D(0, -ShooterConsts::GRAVITY / (ShooterConsts::SLOW_MO_COEFFICIENT * ShooterConsts::SLOW_MO_COEFFICIENT), 0));
|
_player->setAcceleration(Vec3D(0, -ShooterConsts::GRAVITY /
|
||||||
|
(ShooterConsts::SLOW_MO_COEFFICIENT * ShooterConsts::SLOW_MO_COEFFICIENT),
|
||||||
|
0));
|
||||||
SoundController::stopSound(SoundTag("unSlowMo"));
|
SoundController::stopSound(SoundTag("unSlowMo"));
|
||||||
SoundController::playSound(SoundTag("slowMo"), ShooterConsts::SLOW_MO_SOUND);
|
SoundController::playSound(SoundTag("slowMo"), ShooterConsts::SLOW_MO_SOUND);
|
||||||
} else if (_isInSlowMo && !Keyboard::isKeyPressed(sf::Keyboard::LShift)) {
|
} else if (_isInSlowMo && !Keyboard::isKeyPressed(sf::Keyboard::LShift)) {
|
||||||
|
@ -114,8 +136,8 @@ void PlayerController::update() {
|
||||||
if (Mouse::isButtonPressed(sf::Mouse::Button::Left)) {
|
if (Mouse::isButtonPressed(sf::Mouse::Button::Left)) {
|
||||||
bool shot = _player->fire();
|
bool shot = _player->fire();
|
||||||
|
|
||||||
if(shot) {
|
if (shot) {
|
||||||
if(_player->weaponName() == ObjectNameTag("shotgun")) {
|
if (_player->weaponName() == ObjectNameTag("shotgun")) {
|
||||||
_player->addVelocity(-camera->lookAt() * 30 * coeff);
|
_player->addVelocity(-camera->lookAt() * 30 * coeff);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -133,7 +155,7 @@ void PlayerController::update() {
|
||||||
sqrt(2 * -_player->acceleration().y() * ShooterConsts::JUMP_HEIGHT) * coeff *
|
sqrt(2 * -_player->acceleration().y() * ShooterConsts::JUMP_HEIGHT) * coeff *
|
||||||
Time::deltaTime() * 60, 0});
|
Time::deltaTime() * 60, 0});
|
||||||
}
|
}
|
||||||
_player->translate(Vec3D{ 0, Time::deltaTime() * ShooterConsts::WALK_SPEED * 2 * coeff, 0 });
|
_player->translate(Vec3D{0, Time::deltaTime() * ShooterConsts::WALK_SPEED * 2 * coeff, 0});
|
||||||
_isSliding = true;
|
_isSliding = true;
|
||||||
} else {
|
} else {
|
||||||
_isSliding = false;
|
_isSliding = false;
|
||||||
|
@ -143,7 +165,8 @@ void PlayerController::update() {
|
||||||
Vec2D displacement = _mouse->getMouseDisplacement();
|
Vec2D displacement = _mouse->getMouseDisplacement();
|
||||||
|
|
||||||
_player->rotate(Vec3D{0, -displacement.x() * ShooterConsts::MOUSE_SENSITIVITY, 0});
|
_player->rotate(Vec3D{0, -displacement.x() * ShooterConsts::MOUSE_SENSITIVITY, 0});
|
||||||
_player->setVelocity(Matrix4x4::RotationY(-displacement.x() * ShooterConsts::MOUSE_SENSITIVITY) * _player->velocity());
|
_player->setVelocity(
|
||||||
|
Matrix4x4::RotationY(-displacement.x() * ShooterConsts::MOUSE_SENSITIVITY) * _player->velocity());
|
||||||
|
|
||||||
double rotationLeft = displacement.y() * ShooterConsts::MOUSE_SENSITIVITY;
|
double rotationLeft = displacement.y() * ShooterConsts::MOUSE_SENSITIVITY;
|
||||||
|
|
||||||
|
@ -158,7 +181,7 @@ void PlayerController::update() {
|
||||||
_player->setHeadAngle(_player->headAngle() + rotationLeft);
|
_player->setHeadAngle(_player->headAngle() + rotationLeft);
|
||||||
_player->rotateWeaponsRelativePoint(_player->position() + Vec3D{0, 1.8, 0}, _player->left(), rotationLeft);
|
_player->rotateWeaponsRelativePoint(_player->position() + Vec3D{0, 1.8, 0}, _player->left(), rotationLeft);
|
||||||
|
|
||||||
if(camera != nullptr) {
|
if (camera != nullptr) {
|
||||||
camera->rotateLeft(_player->headAngle() - camera->angleLeftUpLookAt().x());
|
camera->rotateLeft(_player->headAngle() - camera->angleLeftUpLookAt().x());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -170,18 +193,19 @@ void PlayerController::update() {
|
||||||
_player->previousWeapon();
|
_player->previousWeapon();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(Keyboard::isKeyPressed(sf::Keyboard::R)) {
|
if (Keyboard::isKeyPressed(sf::Keyboard::R)) {
|
||||||
_player->reload();
|
_player->reload();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool walkSoundPlayed = false;
|
bool walkSoundPlayed = false;
|
||||||
for(int k = 1; k < 7; k++) {
|
for (int k = 1; k < 7; k++) {
|
||||||
if(SoundController::getStatus(SoundTag("walkSound_" + std::to_string(k))) == sf::Sound::Status::Playing) {
|
if (SoundController::getStatus(SoundTag("walkSound_" + std::to_string(k))) == sf::Sound::Status::Playing) {
|
||||||
walkSoundPlayed = true;
|
walkSoundPlayed = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ((_inRunning || _player->velocity().sqrAbs() > 3) && _player->inCollision() && !walkSoundPlayed) {
|
if ((_inRunning || _player->velocity().sqrAbs() > 3) && _player->inCollision() && !walkSoundPlayed) {
|
||||||
int soundNum = (int)((double) rand() / RAND_MAX * 6) + 1;
|
int soundNum = (int) ((double) rand() / RAND_MAX * 6) + 1;
|
||||||
SoundController::playSound(SoundTag("walkSound_" + std::to_string(soundNum)), "sound/stonestep" + std::to_string(soundNum) + ".ogg");
|
SoundController::playSound(SoundTag("walkSound_" + std::to_string(soundNum)),
|
||||||
|
"sound/stonestep" + std::to_string(soundNum) + ".ogg");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,7 @@ private:
|
||||||
|
|
||||||
public:
|
public:
|
||||||
PlayerController(std::shared_ptr<Player> player, std::shared_ptr<Keyboard> keyboard, std::shared_ptr<Mouse> mouse);
|
PlayerController(std::shared_ptr<Player> player, std::shared_ptr<Keyboard> keyboard, std::shared_ptr<Mouse> mouse);
|
||||||
|
|
||||||
void update();
|
void update();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
120
Shooter.cpp
120
Shooter.cpp
|
@ -24,8 +24,8 @@ void Shooter::InitNetwork() {
|
||||||
std::ifstream connectFile("connect.txt", std::ifstream::in);
|
std::ifstream connectFile("connect.txt", std::ifstream::in);
|
||||||
|
|
||||||
// If failed to read client settings
|
// If failed to read client settings
|
||||||
if (!connectFile.is_open() || !(connectFile >> clientIp >> clientPort >> playerName) || sf::IpAddress(clientIp) == sf::IpAddress::None)
|
if (!connectFile.is_open() || !(connectFile >> clientIp >> clientPort >> playerName) ||
|
||||||
{
|
sf::IpAddress(clientIp) == sf::IpAddress::None) {
|
||||||
connectFile.close();
|
connectFile.close();
|
||||||
// Create file and write default settings
|
// Create file and write default settings
|
||||||
clientIp = "127.0.0.1";
|
clientIp = "127.0.0.1";
|
||||||
|
@ -39,8 +39,7 @@ void Shooter::InitNetwork() {
|
||||||
|
|
||||||
// If failed to read server settings
|
// If failed to read server settings
|
||||||
connectFile.open("server.txt", std::ifstream::in);
|
connectFile.open("server.txt", std::ifstream::in);
|
||||||
if (!connectFile.is_open() || !(connectFile >> serverPort))
|
if (!connectFile.is_open() || !(connectFile >> serverPort)) {
|
||||||
{
|
|
||||||
connectFile.close();
|
connectFile.close();
|
||||||
// Create file and write default settings
|
// Create file and write default settings
|
||||||
serverPort = 54000;
|
serverPort = 54000;
|
||||||
|
@ -52,7 +51,7 @@ void Shooter::InitNetwork() {
|
||||||
|
|
||||||
if (clientIp == sf::IpAddress::LocalHost) {
|
if (clientIp == sf::IpAddress::LocalHost) {
|
||||||
server->start(serverPort);
|
server->start(serverPort);
|
||||||
if(server->isWorking())
|
if (server->isWorking())
|
||||||
server->generateBonuses();
|
server->generateBonuses();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,12 +59,14 @@ void Shooter::InitNetwork() {
|
||||||
player->setPlayerNickName(playerName);
|
player->setPlayerNickName(playerName);
|
||||||
|
|
||||||
// TODO: encapsulate call backs inside ShooterClient
|
// TODO: encapsulate call backs inside ShooterClient
|
||||||
client->setSpawnPlayerCallBack([this](sf::Uint16 id){ spawnPlayer(id); });
|
client->setSpawnPlayerCallBack([this](sf::Uint16 id) { spawnPlayer(id); });
|
||||||
client->setRemovePlayerCallBack([this](sf::Uint16 id){ removePlayer(id); });
|
client->setRemovePlayerCallBack([this](sf::Uint16 id) { removePlayer(id); });
|
||||||
client->setAddFireTraceCallBack([this](const Vec3D& from, const Vec3D& to){ addFireTrace(from, to); });
|
client->setAddFireTraceCallBack([this](const Vec3D &from, const Vec3D &to) { addFireTrace(from, to); });
|
||||||
client->setAddBonusCallBack([this](const std::string& bonusName, const Vec3D& position){ addBonus(bonusName, position); });
|
client->setAddBonusCallBack(
|
||||||
client->setRemoveBonusCallBack([this](const ObjectNameTag& bonusName){ removeBonus(bonusName); });
|
[this](const std::string &bonusName, const Vec3D &position) { addBonus(bonusName, position); });
|
||||||
client->setChangeEnemyWeaponCallBack([this](const std::string& weaponName, sf::Uint16 id){ changeEnemyWeapon(weaponName, id); });
|
client->setRemoveBonusCallBack([this](const ObjectNameTag &bonusName) { removeBonus(bonusName); });
|
||||||
|
client->setChangeEnemyWeaponCallBack(
|
||||||
|
[this](const std::string &weaponName, sf::Uint16 id) { changeEnemyWeapon(weaponName, id); });
|
||||||
}
|
}
|
||||||
|
|
||||||
void Shooter::start() {
|
void Shooter::start() {
|
||||||
|
@ -79,12 +80,17 @@ void Shooter::start() {
|
||||||
player->scale(Vec3D(3, 1, 3));
|
player->scale(Vec3D(3, 1, 3));
|
||||||
|
|
||||||
// TODO: encapsulate call backs inside Player
|
// TODO: encapsulate call backs inside Player
|
||||||
player->setAddTraceCallBack([this](const Vec3D& from, const Vec3D& to){ client->addTrace(from, to); addFireTrace(from, to); });
|
player->setAddTraceCallBack([this](const Vec3D &from, const Vec3D &to) {
|
||||||
player->setDamagePlayerCallBack([this] (sf::Uint16 targetId, double damage) { client->damagePlayer(targetId, damage); });
|
client->addTrace(from, to);
|
||||||
player->setRayCastFunction([this](const Vec3D& from, const Vec3D& to) { return world->rayCast(from, to, "Player Weapon"); });
|
addFireTrace(from, to);
|
||||||
player->setTakeBonusCallBack([this] (const string& bonusName) { client->takeBonus(bonusName); });
|
});
|
||||||
player->setAddWeaponCallBack([this](std::shared_ptr<Weapon> weapon){ addWeapon(std::move(weapon)); });
|
player->setDamagePlayerCallBack(
|
||||||
player->setRemoveWeaponCallBack([this](std::shared_ptr<Weapon> weapon){ removeWeapon(std::move(weapon)); });
|
[this](sf::Uint16 targetId, double damage) { client->damagePlayer(targetId, damage); });
|
||||||
|
player->setRayCastFunction(
|
||||||
|
[this](const Vec3D &from, const Vec3D &to) { return world->rayCast(from, to, "Player Weapon"); });
|
||||||
|
player->setTakeBonusCallBack([this](const string &bonusName) { client->takeBonus(bonusName); });
|
||||||
|
player->setAddWeaponCallBack([this](std::shared_ptr<Weapon> weapon) { addWeapon(std::move(weapon)); });
|
||||||
|
player->setRemoveWeaponCallBack([this](std::shared_ptr<Weapon> weapon) { removeWeapon(std::move(weapon)); });
|
||||||
|
|
||||||
player->initWeapons();
|
player->initWeapons();
|
||||||
|
|
||||||
|
@ -112,10 +118,23 @@ void Shooter::start() {
|
||||||
mainMenu.setTitle("Main menu");
|
mainMenu.setTitle("Main menu");
|
||||||
mainMenu.setBackgroundTexture(ShooterConsts::MAIN_MENU_BACK, 1.1, 1.1, screen->width(), screen->height());
|
mainMenu.setBackgroundTexture(ShooterConsts::MAIN_MENU_BACK, 1.1, 1.1, screen->width(), screen->height());
|
||||||
|
|
||||||
mainMenu.addButton(screen->width()/2, 200, 200, 20, [this] () { this->play(); SoundController::playSound(SoundTag("click"), ShooterConsts::CLICK_SOUND);}, "Server: " + client->serverIp().toString(), 5, 5, ShooterConsts::MAIN_MENU_GUI, {0, 66}, {0, 86}, {0, 46}, Consts::MEDIUM_FONT, {255, 255, 255});
|
mainMenu.addButton(screen->width() / 2, 200, 200, 20, [this]() {
|
||||||
mainMenu.addButton(screen->width()/2, 350, 200, 20, [this] () { this->player->translateToPoint(Vec3D{0, 0, 0}); this->player->setVelocity({}); this->play(); SoundController::playSound(SoundTag("click"), ShooterConsts::CLICK_SOUND);}, "Respawn", 5, 5, ShooterConsts::MAIN_MENU_GUI, {0, 66}, {0, 86}, {0, 46}, Consts::MEDIUM_FONT, {255, 255, 255});
|
this->play();
|
||||||
|
SoundController::playSound(SoundTag("click"), ShooterConsts::CLICK_SOUND);
|
||||||
|
}, "Server: " + client->serverIp().toString(), 5, 5, ShooterConsts::MAIN_MENU_GUI, {0, 66}, {0, 86}, {0, 46},
|
||||||
|
Consts::MEDIUM_FONT, {255, 255, 255});
|
||||||
|
mainMenu.addButton(screen->width() / 2, 350, 200, 20, [this]() {
|
||||||
|
this->player->translateToPoint(Vec3D{0, 0, 0});
|
||||||
|
this->player->setVelocity({});
|
||||||
|
this->play();
|
||||||
|
SoundController::playSound(SoundTag("click"), ShooterConsts::CLICK_SOUND);
|
||||||
|
}, "Respawn", 5, 5, ShooterConsts::MAIN_MENU_GUI, {0, 66}, {0, 86}, {0, 46}, Consts::MEDIUM_FONT, {255, 255, 255});
|
||||||
|
|
||||||
mainMenu.addButton(screen->width()/2, 500, 200, 20, [this] () { client->disconnect(); server->stop(); this->exit();}, "Exit", 5, 5, ShooterConsts::MAIN_MENU_GUI, {0, 66}, {0, 86}, {0, 46}, Consts::MEDIUM_FONT, {255, 255, 255});
|
mainMenu.addButton(screen->width() / 2, 500, 200, 20, [this]() {
|
||||||
|
client->disconnect();
|
||||||
|
server->stop();
|
||||||
|
this->exit();
|
||||||
|
}, "Exit", 5, 5, ShooterConsts::MAIN_MENU_GUI, {0, 66}, {0, 86}, {0, 46}, Consts::MEDIUM_FONT, {255, 255, 255});
|
||||||
}
|
}
|
||||||
|
|
||||||
void Shooter::update() {
|
void Shooter::update() {
|
||||||
|
@ -129,12 +148,12 @@ void Shooter::update() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(keyboard->isKeyTapped(sf::Keyboard::Escape)) {
|
if (keyboard->isKeyTapped(sf::Keyboard::Escape)) {
|
||||||
inGame = !inGame;
|
inGame = !inGame;
|
||||||
screen->setMouseCursorVisible(!inGame);
|
screen->setMouseCursorVisible(!inGame);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(inGame) {
|
if (inGame) {
|
||||||
screen->setTitle(ShooterConsts::PROJECT_NAME);
|
screen->setTitle(ShooterConsts::PROJECT_NAME);
|
||||||
playerController->update();
|
playerController->update();
|
||||||
mouse->setMouseInCenter();
|
mouse->setMouseInCenter();
|
||||||
|
@ -145,7 +164,7 @@ void Shooter::update() {
|
||||||
setUpdateWorld(inGame);
|
setUpdateWorld(inGame);
|
||||||
|
|
||||||
// background sounds and music control
|
// background sounds and music control
|
||||||
if(SoundController::getStatus(SoundTag("background")) != sf::Sound::Status::Playing) {
|
if (SoundController::getStatus(SoundTag("background")) != sf::Sound::Status::Playing) {
|
||||||
SoundController::playSound(SoundTag("background"), ShooterConsts::BACK_NOISE);
|
SoundController::playSound(SoundTag("background"), ShooterConsts::BACK_NOISE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -156,7 +175,8 @@ void Shooter::gui() {
|
||||||
sprite.setTexture(*ResourceManager::loadTexture(ShooterConsts::MAIN_MENU_GUI));
|
sprite.setTexture(*ResourceManager::loadTexture(ShooterConsts::MAIN_MENU_GUI));
|
||||||
sprite.setTextureRect(sf::IntRect(243, 3, 9, 9));
|
sprite.setTextureRect(sf::IntRect(243, 3, 9, 9));
|
||||||
sprite.scale(3, 3);
|
sprite.scale(3, 3);
|
||||||
sprite.setPosition(static_cast<float>(screen->width()) / 2.0f - 27.0f/2.0f, static_cast<float>(screen->height()) / 2.0f - 27.0f/2.0f);
|
sprite.setPosition(static_cast<float>(screen->width()) / 2.0f - 27.0f / 2.0f,
|
||||||
|
static_cast<float>(screen->height()) / 2.0f - 27.0f / 2.0f);
|
||||||
sprite.setColor(sf::Color(0, 0, 0, 250));
|
sprite.setColor(sf::Color(0, 0, 0, 250));
|
||||||
screen->drawSprite(sprite);
|
screen->drawSprite(sprite);
|
||||||
|
|
||||||
|
@ -168,20 +188,21 @@ void Shooter::gui() {
|
||||||
void Shooter::drawStatsTable() {
|
void Shooter::drawStatsTable() {
|
||||||
int i = 1;
|
int i = 1;
|
||||||
|
|
||||||
screen->drawText(client->lastEvent(),Vec2D{10, 10},25, sf::Color(0, 0, 0, 100));
|
screen->drawText(client->lastEvent(), Vec2D{10, 10}, 25, sf::Color(0, 0, 0, 100));
|
||||||
|
|
||||||
vector<shared_ptr<Player>> allPlayers;
|
vector<shared_ptr<Player>> allPlayers;
|
||||||
allPlayers.push_back(player);
|
allPlayers.push_back(player);
|
||||||
for(auto& [playerId, player] : client->players())
|
for (auto&[playerId, player] : client->players())
|
||||||
allPlayers.push_back(player);
|
allPlayers.push_back(player);
|
||||||
|
|
||||||
std::sort(allPlayers.begin(), allPlayers.end(), [](std::shared_ptr<Player> p1, std::shared_ptr<Player> p2){
|
std::sort(allPlayers.begin(), allPlayers.end(), [](std::shared_ptr<Player> p1, std::shared_ptr<Player> p2) {
|
||||||
return p1->kills() - p1->deaths() > p2->kills() - p2->deaths();
|
return p1->kills() - p1->deaths() > p2->kills() - p2->deaths();
|
||||||
} );
|
});
|
||||||
|
|
||||||
for(auto& p : allPlayers) {
|
for (auto &p : allPlayers) {
|
||||||
screen->drawText(std::to_string(i) + "\t" + p->playerNickName() + "\t" + std::to_string(p->kills()) + " / " + std::to_string(p->deaths()),
|
screen->drawText(std::to_string(i) + "\t" + p->playerNickName() + "\t" + std::to_string(p->kills()) + " / " +
|
||||||
Vec2D{10, 15 + 35.0*i}, 25, sf::Color(0, 0, 0, 150));
|
std::to_string(p->deaths()),
|
||||||
|
Vec2D{10, 15 + 35.0 * i}, 25, sf::Color(0, 0, 0, 150));
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -191,25 +212,29 @@ void Shooter::drawPlayerStats() {
|
||||||
double xPos = 10;
|
double xPos = 10;
|
||||||
double yPos = screen->height() - 20;
|
double yPos = screen->height() - 20;
|
||||||
|
|
||||||
int width = screen->width()/2 - 20;
|
int width = screen->width() / 2 - 20;
|
||||||
int height = 10;
|
int height = 10;
|
||||||
|
|
||||||
screen->drawTetragon(Vec2D{xPos, yPos},
|
screen->drawTetragon(Vec2D{xPos, yPos},
|
||||||
Vec2D{xPos + width * player->health() / ShooterConsts::HEALTH_MAX, yPos},
|
Vec2D{xPos + width * player->health() / ShooterConsts::HEALTH_MAX, yPos},
|
||||||
Vec2D{xPos + width * player->health() / ShooterConsts::HEALTH_MAX, yPos + height},
|
Vec2D{xPos + width * player->health() / ShooterConsts::HEALTH_MAX, yPos + height},
|
||||||
Vec2D{xPos, yPos + height},
|
Vec2D{xPos, yPos + height},
|
||||||
{ static_cast<sf::Uint8>((ShooterConsts::HEALTH_MAX - player->health())/ShooterConsts::HEALTH_MAX * 255), static_cast<sf::Uint8>(player->health() * 255 / ShooterConsts::HEALTH_MAX), 0, 100 });
|
{static_cast<sf::Uint8>((ShooterConsts::HEALTH_MAX - player->health()) /
|
||||||
|
ShooterConsts::HEALTH_MAX * 255),
|
||||||
|
static_cast<sf::Uint8>(player->health() * 255 / ShooterConsts::HEALTH_MAX), 0, 100});
|
||||||
|
|
||||||
screen->drawTetragon(Vec2D{xPos, yPos - 15},
|
screen->drawTetragon(Vec2D{xPos, yPos - 15},
|
||||||
Vec2D{xPos + width * player->ability() / ShooterConsts::ABILITY_MAX, yPos - 15},
|
Vec2D{xPos + width * player->ability() / ShooterConsts::ABILITY_MAX, yPos - 15},
|
||||||
Vec2D{xPos + width * player->ability() / ShooterConsts::ABILITY_MAX, yPos - 15 + height},
|
Vec2D{xPos + width * player->ability() / ShooterConsts::ABILITY_MAX, yPos - 15 + height},
|
||||||
Vec2D{xPos, yPos - 15 + height},
|
Vec2D{xPos, yPos - 15 + height},
|
||||||
{ 255, 168, 168, 100 });
|
{255, 168, 168, 100});
|
||||||
|
|
||||||
auto balance = player->balance();
|
auto balance = player->balance();
|
||||||
|
|
||||||
screen->drawText(std::to_string((int)balance.first), Vec2D{150, static_cast<double>(screen->height() - 150)}, 100, sf::Color(0, 0, 0, 100));
|
screen->drawText(std::to_string((int) balance.first), Vec2D{150, static_cast<double>(screen->height() - 150)}, 100,
|
||||||
screen->drawText(std::to_string((int)balance.second), Vec2D{50, static_cast<double>(screen->height() - 100)}, 50, sf::Color(0, 0, 0, 70));
|
sf::Color(0, 0, 0, 100));
|
||||||
|
screen->drawText(std::to_string((int) balance.second), Vec2D{50, static_cast<double>(screen->height() - 100)}, 50,
|
||||||
|
sf::Color(0, 0, 0, 70));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Shooter::play() {
|
void Shooter::play() {
|
||||||
|
@ -263,23 +288,28 @@ void Shooter::addFireTrace(const Vec3D &from, const Vec3D &to) {
|
||||||
world->addBody(std::make_shared<RigidBody>(Mesh::LineTo(ObjectNameTag(traceName), from, to, 0.05)));
|
world->addBody(std::make_shared<RigidBody>(Mesh::LineTo(ObjectNameTag(traceName), from, to, 0.05)));
|
||||||
world->body(ObjectNameTag(traceName))->setCollider(false);
|
world->body(ObjectNameTag(traceName))->setCollider(false);
|
||||||
|
|
||||||
Timeline::animate(AnimationListTag(traceName + "_fadeOut"), std::make_shared<AColor>(world->body(ObjectNameTag(traceName)), sf::Color{150, 150, 150, 0}));
|
Timeline::animate(AnimationListTag(traceName + "_fadeOut"),
|
||||||
Timeline::animate(AnimationListTag(traceName + "_delete"), std::make_shared<AFunction>([this, traceName](){ removeFireTrace(ObjectNameTag(traceName)); }, 1, 2));
|
std::make_shared<AColor>(world->body(ObjectNameTag(traceName)), sf::Color{150, 150, 150, 0}));
|
||||||
|
Timeline::animate(AnimationListTag(traceName + "_delete"),
|
||||||
|
std::make_shared<AFunction>([this, traceName]() { removeFireTrace(ObjectNameTag(traceName)); }, 1,
|
||||||
|
2));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Shooter::removeFireTrace(const ObjectNameTag& traceName) {
|
void Shooter::removeFireTrace(const ObjectNameTag &traceName) {
|
||||||
world->removeBody(traceName);
|
world->removeBody(traceName);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Shooter::addBonus(const string &bonusName, const Vec3D &position) {
|
void Shooter::addBonus(const string &bonusName, const Vec3D &position) {
|
||||||
std::string name = bonusName.substr(6, bonusName.size()-3-5);
|
std::string name = bonusName.substr(6, bonusName.size() - 3 - 5);
|
||||||
|
|
||||||
ObjectNameTag nameTag(bonusName);
|
ObjectNameTag nameTag(bonusName);
|
||||||
|
|
||||||
world->addBody(std::make_shared<RigidBody>(ObjectNameTag(bonusName), "obj/" + name + ".obj", Vec3D{3, 3, 3}));
|
world->addBody(std::make_shared<RigidBody>(ObjectNameTag(bonusName), "obj/" + name + ".obj", Vec3D{3, 3, 3}));
|
||||||
world->body(ObjectNameTag(bonusName))->translateToPoint(position);
|
world->body(ObjectNameTag(bonusName))->translateToPoint(position);
|
||||||
world->body(ObjectNameTag(bonusName))->setCollider(false);
|
world->body(ObjectNameTag(bonusName))->setCollider(false);
|
||||||
Timeline::animate(AnimationListTag(bonusName + "_rotation"), std::make_shared<ARotate>(world->body(ObjectNameTag(bonusName)), Vec3D{0, 2*Consts::PI, 0}, 4, Animation::LoopOut::Continue, Animation::InterpolationType::Linear));
|
Timeline::animate(AnimationListTag(bonusName + "_rotation"),
|
||||||
|
std::make_shared<ARotate>(world->body(ObjectNameTag(bonusName)), Vec3D{0, 2 * Consts::PI, 0}, 4,
|
||||||
|
Animation::LoopOut::Continue, Animation::InterpolationType::Linear));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Shooter::removeBonus(const ObjectNameTag &bonusName) {
|
void Shooter::removeBonus(const ObjectNameTag &bonusName) {
|
||||||
|
@ -290,12 +320,12 @@ void Shooter::removeBonus(const ObjectNameTag &bonusName) {
|
||||||
void Shooter::addWeapon(std::shared_ptr<Weapon> weapon) {
|
void Shooter::addWeapon(std::shared_ptr<Weapon> weapon) {
|
||||||
world->addBody(weapon);
|
world->addBody(weapon);
|
||||||
|
|
||||||
if(client != nullptr) {
|
if (client != nullptr) {
|
||||||
client->changeWeapon(weapon->name().str());
|
client->changeWeapon(weapon->name().str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Shooter::changeEnemyWeapon(const std::string& weaponName, sf::Uint16 enemyId) {
|
void Shooter::changeEnemyWeapon(const std::string &weaponName, sf::Uint16 enemyId) {
|
||||||
ObjectNameTag weaponTag("Enemy_" + std::to_string(enemyId) + "_weapon");
|
ObjectNameTag weaponTag("Enemy_" + std::to_string(enemyId) + "_weapon");
|
||||||
auto head = world->body(ObjectNameTag("Enemy_" + std::to_string(enemyId) + "_head"));
|
auto head = world->body(ObjectNameTag("Enemy_" + std::to_string(enemyId) + "_head"));
|
||||||
auto enemy = world->body(ObjectNameTag("Enemy_" + std::to_string(enemyId)));
|
auto enemy = world->body(ObjectNameTag("Enemy_" + std::to_string(enemyId)));
|
||||||
|
@ -308,9 +338,9 @@ void Shooter::changeEnemyWeapon(const std::string& weaponName, sf::Uint16 enemyI
|
||||||
world->body(weaponTag)->setCollider(false);
|
world->body(weaponTag)->setCollider(false);
|
||||||
world->body(weaponTag)->scale(Vec3D(3, 3, 3));
|
world->body(weaponTag)->scale(Vec3D(3, 3, 3));
|
||||||
|
|
||||||
world->body(weaponTag)->translateToPoint(head->position() - enemy->left() - enemy->up());
|
world->body(weaponTag)->translateToPoint(head->position() - enemy->left()*2 - enemy->up()*0.5);
|
||||||
|
|
||||||
world->body(weaponTag)->rotate(Vec3D(0, Consts::PI + head->angle().y(), 0));
|
world->body(weaponTag)->rotate(Vec3D(0, Consts::PI + enemy->angle().y(), 0));
|
||||||
world->body(weaponTag)->rotateLeft(-head->angleLeftUpLookAt().x());
|
world->body(weaponTag)->rotateLeft(-head->angleLeftUpLookAt().x());
|
||||||
enemy->attach(world->body(weaponTag));
|
enemy->attach(world->body(weaponTag));
|
||||||
}
|
}
|
||||||
|
|
22
Shooter.h
22
Shooter.h
|
@ -30,6 +30,7 @@ private:
|
||||||
int fireTraces = 0;
|
int fireTraces = 0;
|
||||||
|
|
||||||
void start() override;
|
void start() override;
|
||||||
|
|
||||||
void update() override;
|
void update() override;
|
||||||
|
|
||||||
void gui() override;
|
void gui() override;
|
||||||
|
@ -37,18 +38,29 @@ private:
|
||||||
void play();
|
void play();
|
||||||
|
|
||||||
void drawPlayerStats();
|
void drawPlayerStats();
|
||||||
|
|
||||||
void drawStatsTable();
|
void drawStatsTable();
|
||||||
|
|
||||||
void InitNetwork();
|
void InitNetwork();
|
||||||
|
|
||||||
void spawnPlayer(sf::Uint16 id);
|
void spawnPlayer(sf::Uint16 id);
|
||||||
|
|
||||||
void removePlayer(sf::Uint16 id);
|
void removePlayer(sf::Uint16 id);
|
||||||
void addFireTrace(const Vec3D& from, const Vec3D& to);
|
|
||||||
void removeFireTrace(const ObjectNameTag& traceName);
|
void addFireTrace(const Vec3D &from, const Vec3D &to);
|
||||||
void addBonus(const std::string& bonusName, const Vec3D& position);
|
|
||||||
void removeBonus(const ObjectNameTag& bonusName);
|
void removeFireTrace(const ObjectNameTag &traceName);
|
||||||
|
|
||||||
|
void addBonus(const std::string &bonusName, const Vec3D &position);
|
||||||
|
|
||||||
|
void removeBonus(const ObjectNameTag &bonusName);
|
||||||
|
|
||||||
void addWeapon(std::shared_ptr<Weapon> weapon);
|
void addWeapon(std::shared_ptr<Weapon> weapon);
|
||||||
|
|
||||||
void removeWeapon(std::shared_ptr<Weapon> weapon);
|
void removeWeapon(std::shared_ptr<Weapon> weapon);
|
||||||
void changeEnemyWeapon(const std::string& weaponName, sf::Uint16 enemyId);
|
|
||||||
|
void changeEnemyWeapon(const std::string &weaponName, sf::Uint16 enemyId);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Shooter() : mainMenu(screen, mouse) {};
|
Shooter() : mainMenu(screen, mouse) {};
|
||||||
};
|
};
|
||||||
|
|
|
@ -7,28 +7,27 @@
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include "engine/utils/Log.h"
|
#include "engine/utils/Log.h"
|
||||||
#include "engine/animation/Timeline.h"
|
#include "engine/animation/Timeline.h"
|
||||||
#include "engine/animation/ATranslateToPoint.h"
|
|
||||||
#include "ShooterMsgType.h"
|
#include "ShooterMsgType.h"
|
||||||
|
|
||||||
void ShooterClient::updatePacket() {
|
void ShooterClient::updatePacket() {
|
||||||
sf::Packet packet;
|
sf::Packet packet;
|
||||||
packet << MsgType::ClientUpdate << _player->position().x() << _player->position().y() << _player->position().z() << _player->angle().y() << _player->headAngle() << _player->playerNickName();
|
packet << MsgType::ClientUpdate << _player->position().x() << _player->position().y() << _player->position().z()
|
||||||
|
<< _player->angle().y() << _player->headAngle() << _player->playerNickName();
|
||||||
_socket.send(packet, _socket.serverId());
|
_socket.send(packet, _socket.serverId());
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShooterClient::processInit(sf::Packet& packet) {
|
void ShooterClient::processInit(sf::Packet &packet) {
|
||||||
sf::Uint16 targetId;
|
sf::Uint16 targetId;
|
||||||
double buf[4];
|
double buf[4];
|
||||||
int kills, deaths;
|
int kills, deaths;
|
||||||
|
|
||||||
while (packet >> targetId >> buf[0] >> buf[1] >> buf[2] >> buf[3] >> kills >> deaths)
|
while (packet >> targetId >> buf[0] >> buf[1] >> buf[2] >> buf[3] >> kills >> deaths) {
|
||||||
{
|
if (targetId != _socket.ownId()) {
|
||||||
if(targetId != _socket.ownId()) {
|
if (_spawnPlayerCallBack != nullptr) {
|
||||||
if(_spawnPlayerCallBack != nullptr) {
|
|
||||||
_spawnPlayerCallBack(targetId);
|
_spawnPlayerCallBack(targetId);
|
||||||
}
|
}
|
||||||
|
|
||||||
_players[targetId]->translateToPoint(Vec3D{ buf[0], buf[1], buf[2]});
|
_players[targetId]->translateToPoint(Vec3D{buf[0], buf[1], buf[2]});
|
||||||
_players[targetId]->setHealth(buf[3]);
|
_players[targetId]->setHealth(buf[3]);
|
||||||
_players[targetId]->setKills(kills);
|
_players[targetId]->setKills(kills);
|
||||||
_players[targetId]->setDeaths(deaths);
|
_players[targetId]->setDeaths(deaths);
|
||||||
|
@ -36,7 +35,7 @@ void ShooterClient::processInit(sf::Packet& packet) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShooterClient::processUpdate(sf::Packet& packet) {
|
void ShooterClient::processUpdate(sf::Packet &packet) {
|
||||||
sf::Uint16 targetId;
|
sf::Uint16 targetId;
|
||||||
double buf[6];
|
double buf[6];
|
||||||
std::string playerName;
|
std::string playerName;
|
||||||
|
@ -51,13 +50,13 @@ void ShooterClient::processUpdate(sf::Packet& packet) {
|
||||||
_players[targetId]->rotateToAngle(Vec3D{0, buf[4], 0});
|
_players[targetId]->rotateToAngle(Vec3D{0, buf[4], 0});
|
||||||
_players[targetId]->setPlayerNickName(playerName);
|
_players[targetId]->setPlayerNickName(playerName);
|
||||||
|
|
||||||
auto head = _players[targetId]->attached(ObjectNameTag(name + "_head"));
|
auto head = _players[targetId]->attached(ObjectNameTag(name + "_head"));
|
||||||
auto weapon = _players[targetId]->attached(ObjectNameTag("Enemy_" + std::to_string(targetId) + "_weapon"));
|
auto weapon = _players[targetId]->attached(ObjectNameTag("Enemy_" + std::to_string(targetId) + "_weapon"));
|
||||||
|
|
||||||
if(head != nullptr) {
|
if (head != nullptr) {
|
||||||
head->rotateLeft(buf[5] - _players[targetId]->headAngle());
|
head->rotateLeft(buf[5] - _players[targetId]->headAngle());
|
||||||
}
|
}
|
||||||
if(weapon != nullptr) {
|
if (weapon != nullptr) {
|
||||||
weapon->rotateLeft(-(buf[5] - _players[targetId]->headAngle()));
|
weapon->rotateLeft(-(buf[5] - _players[targetId]->headAngle()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -68,12 +67,12 @@ void ShooterClient::processUpdate(sf::Packet& packet) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShooterClient::processNewClient(sf::Packet& packet) {
|
void ShooterClient::processNewClient(sf::Packet &packet) {
|
||||||
sf::Uint16 targetId;
|
sf::Uint16 targetId;
|
||||||
|
|
||||||
packet >> targetId;
|
packet >> targetId;
|
||||||
|
|
||||||
if(_spawnPlayerCallBack != nullptr) {
|
if (_spawnPlayerCallBack != nullptr) {
|
||||||
_spawnPlayerCallBack(targetId);
|
_spawnPlayerCallBack(targetId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -86,7 +85,7 @@ void ShooterClient::processDisconnect(sf::Uint16 targetId) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void ShooterClient::processCustomPacket(sf::Packet& packet) {
|
void ShooterClient::processCustomPacket(sf::Packet &packet) {
|
||||||
sf::Uint16 buffId[2];
|
sf::Uint16 buffId[2];
|
||||||
double dbuff[10];
|
double dbuff[10];
|
||||||
std::string tmp, tmp2;
|
std::string tmp, tmp2;
|
||||||
|
@ -98,27 +97,27 @@ void ShooterClient::processCustomPacket(sf::Packet& packet) {
|
||||||
case ShooterMsgType::Kill:
|
case ShooterMsgType::Kill:
|
||||||
packet >> buffId[0] >> buffId[1];
|
packet >> buffId[0] >> buffId[1];
|
||||||
_lastEvent = "";
|
_lastEvent = "";
|
||||||
if(buffId[1] == _socket.ownId()) {
|
if (buffId[1] == _socket.ownId()) {
|
||||||
_player->addKill();
|
_player->addKill();
|
||||||
SoundController::playSound(SoundTag("kill"), ShooterConsts::KILL_SOUND);
|
SoundController::playSound(SoundTag("kill"), ShooterConsts::KILL_SOUND);
|
||||||
_lastEvent += _player->playerNickName();
|
_lastEvent += _player->playerNickName();
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
_players[buffId[1]]->addKill();
|
_players[buffId[1]]->addKill();
|
||||||
_lastEvent += _players[buffId[1]]->playerNickName();
|
_lastEvent += _players[buffId[1]]->playerNickName();
|
||||||
}
|
}
|
||||||
_lastEvent += " ~> ";
|
_lastEvent += " ~> ";
|
||||||
|
|
||||||
if(buffId[0] == _socket.ownId()) {
|
if (buffId[0] == _socket.ownId()) {
|
||||||
_player->addDeath();
|
_player->addDeath();
|
||||||
// respawn
|
// respawn
|
||||||
_player->translateToPoint(Vec3D{50.0*(-1 + 2.0*(double)rand()/RAND_MAX),30.0*(double)rand()/RAND_MAX,50.0*(-1 + 2.0*(double)rand()/RAND_MAX)});
|
_player->translateToPoint(
|
||||||
|
Vec3D{50.0 * (-1 + 2.0 * (double) rand() / RAND_MAX), 30.0 * (double) rand() / RAND_MAX,
|
||||||
|
50.0 * (-1 + 2.0 * (double) rand() / RAND_MAX)});
|
||||||
_player->initWeapons();
|
_player->initWeapons();
|
||||||
_player->setFullAbility();
|
_player->setFullAbility();
|
||||||
SoundController::playSound(SoundTag("death"), ShooterConsts::DEATH_SOUND);
|
SoundController::playSound(SoundTag("death"), ShooterConsts::DEATH_SOUND);
|
||||||
_lastEvent += _player->playerNickName();
|
_lastEvent += _player->playerNickName();
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
_players[buffId[0]]->addDeath();
|
_players[buffId[0]]->addDeath();
|
||||||
_lastEvent += _players[buffId[0]]->playerNickName();
|
_lastEvent += _players[buffId[0]]->playerNickName();
|
||||||
}
|
}
|
||||||
|
@ -126,14 +125,14 @@ void ShooterClient::processCustomPacket(sf::Packet& packet) {
|
||||||
case ShooterMsgType::FireTrace:
|
case ShooterMsgType::FireTrace:
|
||||||
packet >> dbuff[0] >> dbuff[1] >> dbuff[2] >> dbuff[3] >> dbuff[4] >> dbuff[5];
|
packet >> dbuff[0] >> dbuff[1] >> dbuff[2] >> dbuff[3] >> dbuff[4] >> dbuff[5];
|
||||||
|
|
||||||
if(_addFireTraceCallBack != nullptr) {
|
if (_addFireTraceCallBack != nullptr) {
|
||||||
_addFireTraceCallBack(Vec3D(dbuff[0], dbuff[1], dbuff[2]), Vec3D(dbuff[3], dbuff[4], dbuff[5]));
|
_addFireTraceCallBack(Vec3D(dbuff[0], dbuff[1], dbuff[2]), Vec3D(dbuff[3], dbuff[4], dbuff[5]));
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case ShooterMsgType::InitBonuses:
|
case ShooterMsgType::InitBonuses:
|
||||||
while (packet >> tmp >> dbuff[0] >> dbuff[1] >> dbuff[2]) {
|
while (packet >> tmp >> dbuff[0] >> dbuff[1] >> dbuff[2]) {
|
||||||
if(_addBonusCallBack != nullptr) {
|
if (_addBonusCallBack != nullptr) {
|
||||||
_addBonusCallBack(tmp, Vec3D(dbuff[0], dbuff[1], dbuff[2]));
|
_addBonusCallBack(tmp, Vec3D(dbuff[0], dbuff[1], dbuff[2]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -141,26 +140,27 @@ void ShooterClient::processCustomPacket(sf::Packet& packet) {
|
||||||
|
|
||||||
case ShooterMsgType::AddBonus:
|
case ShooterMsgType::AddBonus:
|
||||||
packet >> tmp >> dbuff[0] >> dbuff[1] >> dbuff[2];
|
packet >> tmp >> dbuff[0] >> dbuff[1] >> dbuff[2];
|
||||||
if(_addBonusCallBack != nullptr) {
|
if (_addBonusCallBack != nullptr) {
|
||||||
_addBonusCallBack(tmp, Vec3D(dbuff[0], dbuff[1], dbuff[2]));
|
_addBonusCallBack(tmp, Vec3D(dbuff[0], dbuff[1], dbuff[2]));
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case ShooterMsgType::RemoveBonus:
|
case ShooterMsgType::RemoveBonus:
|
||||||
packet >> tmp;
|
packet >> tmp;
|
||||||
if(_removeBonusCallBack != nullptr) {
|
if (_removeBonusCallBack != nullptr) {
|
||||||
_removeBonusCallBack(ObjectNameTag(tmp));
|
_removeBonusCallBack(ObjectNameTag(tmp));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ShooterMsgType::ChangeWeapon:
|
case ShooterMsgType::ChangeWeapon:
|
||||||
packet >> buffId[0] >> tmp;
|
packet >> buffId[0] >> tmp;
|
||||||
|
|
||||||
if(_changeEnemyWeaponCallBack != nullptr) {
|
if (_changeEnemyWeaponCallBack != nullptr) {
|
||||||
_changeEnemyWeaponCallBack(tmp, buffId[0]);
|
_changeEnemyWeaponCallBack(tmp, buffId[0]);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
Log::log("ShooterClient::processCustomPacket: unknown message type " + std::to_string(static_cast<int>(type)));
|
Log::log("ShooterClient::processCustomPacket: unknown message type " +
|
||||||
|
std::to_string(static_cast<int>(type)));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -180,20 +180,21 @@ void ShooterClient::damagePlayer(sf::Uint16 targetId, double damage) {
|
||||||
Log::log("ShooterClient: damagePlayer " + std::to_string(targetId) + " ( -" + std::to_string(damage) + "hp )");
|
Log::log("ShooterClient: damagePlayer " + std::to_string(targetId) + " ( -" + std::to_string(damage) + "hp )");
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShooterClient::addTrace(const Vec3D& from, const Vec3D& to) {
|
void ShooterClient::addTrace(const Vec3D &from, const Vec3D &to) {
|
||||||
sf::Packet packet;
|
sf::Packet packet;
|
||||||
|
|
||||||
packet << MsgType::Custom << ShooterMsgType::FireTrace << from.x() << from.y() << from.z() << to.x() << to.y() << to.z();
|
packet << MsgType::Custom << ShooterMsgType::FireTrace << from.x() << from.y() << from.z() << to.x() << to.y()
|
||||||
|
<< to.z();
|
||||||
_socket.send(packet, _socket.serverId());
|
_socket.send(packet, _socket.serverId());
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShooterClient::takeBonus(const std::string& bonusName) {
|
void ShooterClient::takeBonus(const std::string &bonusName) {
|
||||||
sf::Packet packet;
|
sf::Packet packet;
|
||||||
|
|
||||||
packet << MsgType::Custom << ShooterMsgType::RemoveBonus << bonusName;
|
packet << MsgType::Custom << ShooterMsgType::RemoveBonus << bonusName;
|
||||||
_socket.sendRely(packet, _socket.serverId());
|
_socket.sendRely(packet, _socket.serverId());
|
||||||
|
|
||||||
if(_removeBonusCallBack != nullptr) {
|
if (_removeBonusCallBack != nullptr) {
|
||||||
_removeBonusCallBack(ObjectNameTag(bonusName));
|
_removeBonusCallBack(ObjectNameTag(bonusName));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -206,7 +207,7 @@ void ShooterClient::changeWeapon(const std::string &weaponName) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShooterClient::addPlayer(sf::Uint16 id, std::shared_ptr<Player> player) {
|
void ShooterClient::addPlayer(sf::Uint16 id, std::shared_ptr<Player> player) {
|
||||||
_players.insert({ id, player });
|
_players.insert({id, player});
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShooterClient::setSpawnPlayerCallBack(std::function<void(sf::Uint16)> spawn) {
|
void ShooterClient::setSpawnPlayerCallBack(std::function<void(sf::Uint16)> spawn) {
|
||||||
|
@ -229,6 +230,7 @@ void ShooterClient::setRemoveBonusCallBack(std::function<void(const ObjectNameTa
|
||||||
_removeBonusCallBack = std::move(removeBonus);
|
_removeBonusCallBack = std::move(removeBonus);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShooterClient::setChangeEnemyWeaponCallBack(std::function<void(const std::string&, sf::Uint16)> changeEnemyWeapon) {
|
void
|
||||||
|
ShooterClient::setChangeEnemyWeaponCallBack(std::function<void(const std::string &, sf::Uint16)> changeEnemyWeapon) {
|
||||||
_changeEnemyWeaponCallBack = std::move(changeEnemyWeapon);
|
_changeEnemyWeaponCallBack = std::move(changeEnemyWeapon);
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,42 +17,50 @@ private:
|
||||||
|
|
||||||
std::function<void(sf::Uint16)> _spawnPlayerCallBack;
|
std::function<void(sf::Uint16)> _spawnPlayerCallBack;
|
||||||
std::function<void(sf::Uint16)> _removePlayerCallBack;
|
std::function<void(sf::Uint16)> _removePlayerCallBack;
|
||||||
std::function<void(const Vec3D&, const Vec3D&)> _addFireTraceCallBack;
|
std::function<void(const Vec3D &, const Vec3D &)> _addFireTraceCallBack;
|
||||||
std::function<void(const std::string&, const Vec3D&)> _addBonusCallBack;
|
std::function<void(const std::string &, const Vec3D &)> _addBonusCallBack;
|
||||||
std::function<void(const ObjectNameTag&)> _removeBonusCallBack;
|
std::function<void(const ObjectNameTag &)> _removeBonusCallBack;
|
||||||
std::function<void(const std::string&, sf::Uint16)> _changeEnemyWeaponCallBack;
|
std::function<void(const std::string &, sf::Uint16)> _changeEnemyWeaponCallBack;
|
||||||
public:
|
public:
|
||||||
explicit ShooterClient(std::shared_ptr<Player> player) : _player(player){};
|
explicit ShooterClient(std::shared_ptr<Player> player) : _player(player) {};
|
||||||
|
|
||||||
void updatePacket() override;
|
void updatePacket() override;
|
||||||
|
|
||||||
void setSpawnPlayerCallBack(std::function<void(sf::Uint16)> spawn);
|
void setSpawnPlayerCallBack(std::function<void(sf::Uint16)> spawn);
|
||||||
|
|
||||||
void setRemovePlayerCallBack(std::function<void(sf::Uint16)> remove);
|
void setRemovePlayerCallBack(std::function<void(sf::Uint16)> remove);
|
||||||
void setAddFireTraceCallBack(std::function<void(const Vec3D&, const Vec3D&)> addTrace);
|
|
||||||
void setAddBonusCallBack(std::function<void(const std::string&, const Vec3D&)> addBonus);
|
|
||||||
void setRemoveBonusCallBack(std::function<void(const ObjectNameTag&)> removeBonus);
|
|
||||||
|
|
||||||
void setChangeEnemyWeaponCallBack(std::function<void(const std::string&, sf::Uint16)> changeEnemyWeapon);
|
void setAddFireTraceCallBack(std::function<void(const Vec3D &, const Vec3D &)> addTrace);
|
||||||
|
|
||||||
|
void setAddBonusCallBack(std::function<void(const std::string &, const Vec3D &)> addBonus);
|
||||||
|
|
||||||
|
void setRemoveBonusCallBack(std::function<void(const ObjectNameTag &)> removeBonus);
|
||||||
|
|
||||||
|
void setChangeEnemyWeaponCallBack(std::function<void(const std::string &, sf::Uint16)> changeEnemyWeapon);
|
||||||
|
|
||||||
|
void processInit(sf::Packet &packet) override;
|
||||||
|
|
||||||
|
void processUpdate(sf::Packet &packet) override;
|
||||||
|
|
||||||
|
void processNewClient(sf::Packet &packet) override;
|
||||||
|
|
||||||
void processInit(sf::Packet& packet) override;
|
|
||||||
void processUpdate(sf::Packet& packet) override;
|
|
||||||
void processNewClient(sf::Packet& packet) override;
|
|
||||||
void processDisconnect(sf::Uint16 targetId) override;
|
void processDisconnect(sf::Uint16 targetId) override;
|
||||||
|
|
||||||
void processCustomPacket(sf::Packet& packet) override;
|
void processCustomPacket(sf::Packet &packet) override;
|
||||||
|
|
||||||
void processDisconnected() override;
|
void processDisconnected() override;
|
||||||
|
|
||||||
void damagePlayer(sf::Uint16 targetId, double damage);
|
void damagePlayer(sf::Uint16 targetId, double damage);
|
||||||
|
|
||||||
void takeBonus(const std::string& bonusName);
|
void takeBonus(const std::string &bonusName);
|
||||||
|
|
||||||
void addTrace(const Vec3D& from, const Vec3D& to);
|
void addTrace(const Vec3D &from, const Vec3D &to);
|
||||||
|
|
||||||
void changeWeapon(const std::string& weaponName);
|
void changeWeapon(const std::string &weaponName);
|
||||||
|
|
||||||
void addPlayer(sf::Uint16 id, std::shared_ptr<Player> player);
|
void addPlayer(sf::Uint16 id, std::shared_ptr<Player> player);
|
||||||
[[nodiscard]] std::map<sf::Uint16, std::shared_ptr<Player>>const & players() const { return _players; }
|
|
||||||
|
[[nodiscard]] std::map<sf::Uint16, std::shared_ptr<Player>> const &players() const { return _players; }
|
||||||
|
|
||||||
[[nodiscard]] std::string lastEvent() const { return _lastEvent; }
|
[[nodiscard]] std::string lastEvent() const { return _lastEvent; }
|
||||||
};
|
};
|
||||||
|
|
|
@ -4,15 +4,13 @@
|
||||||
|
|
||||||
#include "ShooterMsgType.h"
|
#include "ShooterMsgType.h"
|
||||||
|
|
||||||
sf::Packet& operator<<(sf::Packet& packet, ShooterMsgType type)
|
sf::Packet &operator<<(sf::Packet &packet, ShooterMsgType type) {
|
||||||
{
|
return packet << (sf::Uint16) type;
|
||||||
return packet << (sf::Uint16)type;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sf::Packet& operator>>(sf::Packet& packet, ShooterMsgType& type)
|
sf::Packet &operator>>(sf::Packet &packet, ShooterMsgType &type) {
|
||||||
{
|
|
||||||
sf::Uint16 temp;
|
sf::Uint16 temp;
|
||||||
packet >> temp;
|
packet >> temp;
|
||||||
type = (ShooterMsgType)temp;
|
type = (ShooterMsgType) temp;
|
||||||
return packet;
|
return packet;
|
||||||
}
|
}
|
|
@ -7,8 +7,7 @@
|
||||||
|
|
||||||
#include <SFML/Network.hpp>
|
#include <SFML/Network.hpp>
|
||||||
|
|
||||||
enum class ShooterMsgType
|
enum class ShooterMsgType {
|
||||||
{
|
|
||||||
Damage,
|
Damage,
|
||||||
Kill,
|
Kill,
|
||||||
FireTrace,
|
FireTrace,
|
||||||
|
@ -18,7 +17,8 @@ enum class ShooterMsgType
|
||||||
ChangeWeapon
|
ChangeWeapon
|
||||||
};
|
};
|
||||||
|
|
||||||
sf::Packet& operator<<(sf::Packet& packet, ShooterMsgType type);
|
sf::Packet &operator<<(sf::Packet &packet, ShooterMsgType type);
|
||||||
sf::Packet& operator>>(sf::Packet& packet, ShooterMsgType& type);
|
|
||||||
|
sf::Packet &operator>>(sf::Packet &packet, ShooterMsgType &type);
|
||||||
|
|
||||||
#endif //SHOOTER_SHOOTERMSGTYPE_H
|
#endif //SHOOTER_SHOOTERMSGTYPE_H
|
||||||
|
|
|
@ -10,11 +10,12 @@ void ShooterServer::broadcast() {
|
||||||
sf::Packet updatePacket;
|
sf::Packet updatePacket;
|
||||||
updatePacket << MsgType::ServerUpdate;
|
updatePacket << MsgType::ServerUpdate;
|
||||||
|
|
||||||
for (auto& [playerId, player] : _players) {
|
for (auto&[playerId, player] : _players) {
|
||||||
updatePacket << playerId << player->position().x() << player->position().y() << player->position().z() << player->health() << player->angle().y() << player->headAngle() << player->playerNickName();
|
updatePacket << playerId << player->position().x() << player->position().y() << player->position().z()
|
||||||
|
<< player->health() << player->angle().y() << player->headAngle() << player->playerNickName();
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto& player : _players) {
|
for (auto &player : _players) {
|
||||||
_socket.send(updatePacket, player.first);
|
_socket.send(updatePacket, player.first);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -27,9 +28,10 @@ void ShooterServer::processConnect(sf::Uint16 targetId) {
|
||||||
// players init
|
// players init
|
||||||
extraPacket << MsgType::NewClient << targetId;
|
extraPacket << MsgType::NewClient << targetId;
|
||||||
sendPacket1 << MsgType::Init << targetId;
|
sendPacket1 << MsgType::Init << targetId;
|
||||||
_players.insert({ targetId, std::make_shared<Player>(ObjectNameTag("Player_" + std::to_string(targetId))) });
|
_players.insert({targetId, std::make_shared<Player>(ObjectNameTag("Player_" + std::to_string(targetId)))});
|
||||||
for (const auto& [playerId, player] : _players) {
|
for (const auto&[playerId, player] : _players) {
|
||||||
sendPacket1 << playerId << player->position().x() << player->position().y() << player->position().z() << player->health() << player->kills() << player->deaths();
|
sendPacket1 << playerId << player->position().x() << player->position().y() << player->position().z()
|
||||||
|
<< player->health() << player->kills() << player->deaths();
|
||||||
if (playerId != targetId)
|
if (playerId != targetId)
|
||||||
_socket.sendRely(extraPacket, playerId);
|
_socket.sendRely(extraPacket, playerId);
|
||||||
}
|
}
|
||||||
|
@ -37,8 +39,8 @@ void ShooterServer::processConnect(sf::Uint16 targetId) {
|
||||||
|
|
||||||
// bonuses init
|
// bonuses init
|
||||||
sendPacket2 << MsgType::Custom << ShooterMsgType::InitBonuses;
|
sendPacket2 << MsgType::Custom << ShooterMsgType::InitBonuses;
|
||||||
for(auto& [bonusName, bonusInfo] : _bonuses) {
|
for (auto&[bonusName, bonusInfo] : _bonuses) {
|
||||||
if(bonusInfo->onTheMap) {
|
if (bonusInfo->onTheMap) {
|
||||||
sendPacket2 << bonusName << bonusInfo->position.x() << bonusInfo->position.y() << bonusInfo->position.z();
|
sendPacket2 << bonusName << bonusInfo->position.x() << bonusInfo->position.y() << bonusInfo->position.z();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -46,12 +48,12 @@ void ShooterServer::processConnect(sf::Uint16 targetId) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShooterServer::processClientUpdate(sf::Uint16 senderId, sf::Packet& packet) {
|
void ShooterServer::processClientUpdate(sf::Uint16 senderId, sf::Packet &packet) {
|
||||||
double buf[5];
|
double buf[5];
|
||||||
std::string playerName;
|
std::string playerName;
|
||||||
|
|
||||||
packet >> buf[0] >> buf[1] >> buf[2] >> buf[3] >> buf[4] >> playerName;
|
packet >> buf[0] >> buf[1] >> buf[2] >> buf[3] >> buf[4] >> playerName;
|
||||||
_players.at(senderId)->translateToPoint(Vec3D{ buf[0], buf[1], buf[2] });
|
_players.at(senderId)->translateToPoint(Vec3D{buf[0], buf[1], buf[2]});
|
||||||
_players.at(senderId)->rotateToAngle(Vec3D{0, buf[3], 0});
|
_players.at(senderId)->rotateToAngle(Vec3D{0, buf[3], 0});
|
||||||
_players.at(senderId)->setHeadAngle(buf[4]);
|
_players.at(senderId)->setHeadAngle(buf[4]);
|
||||||
_players.at(senderId)->setPlayerNickName(playerName);
|
_players.at(senderId)->setPlayerNickName(playerName);
|
||||||
|
@ -62,13 +64,13 @@ void ShooterServer::processDisconnect(sf::Uint16 senderId) {
|
||||||
|
|
||||||
sendPacket << MsgType::Disconnect << senderId;
|
sendPacket << MsgType::Disconnect << senderId;
|
||||||
_players.erase(senderId);
|
_players.erase(senderId);
|
||||||
for (const auto& player : _players) {
|
for (const auto &player : _players) {
|
||||||
_socket.sendRely(sendPacket, player.first);
|
_socket.sendRely(sendPacket, player.first);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void ShooterServer::processCustomPacket(sf::Packet& packet, sf::Uint16 senderId) {
|
void ShooterServer::processCustomPacket(sf::Packet &packet, sf::Uint16 senderId) {
|
||||||
sf::Packet sendPacket;
|
sf::Packet sendPacket;
|
||||||
double dbuff[10];
|
double dbuff[10];
|
||||||
sf::Uint16 targetId;
|
sf::Uint16 targetId;
|
||||||
|
@ -83,7 +85,7 @@ void ShooterServer::processCustomPacket(sf::Packet& packet, sf::Uint16 senderId)
|
||||||
case ShooterMsgType::Damage:
|
case ShooterMsgType::Damage:
|
||||||
packet >> targetId >> damage;
|
packet >> targetId >> damage;
|
||||||
newHealth = _players[targetId]->health() - damage;
|
newHealth = _players[targetId]->health() - damage;
|
||||||
if(newHealth > 0) {
|
if (newHealth > 0) {
|
||||||
_players[targetId]->setHealth(newHealth);
|
_players[targetId]->setHealth(newHealth);
|
||||||
} else {
|
} else {
|
||||||
_players[targetId]->setFullHealth();
|
_players[targetId]->setFullHealth();
|
||||||
|
@ -92,15 +94,16 @@ void ShooterServer::processCustomPacket(sf::Packet& packet, sf::Uint16 senderId)
|
||||||
_players[senderId]->addKill();
|
_players[senderId]->addKill();
|
||||||
|
|
||||||
sendPacket << MsgType::Custom << ShooterMsgType::Kill << targetId << senderId;
|
sendPacket << MsgType::Custom << ShooterMsgType::Kill << targetId << senderId;
|
||||||
for (auto& player : _players)
|
for (auto &player : _players)
|
||||||
_socket.sendRely(sendPacket, player.first);
|
_socket.sendRely(sendPacket, player.first);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ShooterMsgType::FireTrace:
|
case ShooterMsgType::FireTrace:
|
||||||
packet >> dbuff[0] >> dbuff[1] >> dbuff[2] >> dbuff[3] >> dbuff[4] >> dbuff[5];
|
packet >> dbuff[0] >> dbuff[1] >> dbuff[2] >> dbuff[3] >> dbuff[4] >> dbuff[5];
|
||||||
sendPacket << MsgType::Custom << ShooterMsgType::FireTrace << dbuff[0] << dbuff[1] << dbuff[2] << dbuff[3] << dbuff[4] << dbuff[5];
|
sendPacket << MsgType::Custom << ShooterMsgType::FireTrace << dbuff[0] << dbuff[1] << dbuff[2] << dbuff[3]
|
||||||
for (auto& player : _players) {
|
<< dbuff[4] << dbuff[5];
|
||||||
if(player.first != senderId) {
|
for (auto &player : _players) {
|
||||||
|
if (player.first != senderId) {
|
||||||
_socket.send(sendPacket, player.first);
|
_socket.send(sendPacket, player.first);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -109,18 +112,18 @@ void ShooterServer::processCustomPacket(sf::Packet& packet, sf::Uint16 senderId)
|
||||||
case ShooterMsgType::RemoveBonus:
|
case ShooterMsgType::RemoveBonus:
|
||||||
packet >> tmp;
|
packet >> tmp;
|
||||||
|
|
||||||
if(tmp.find("Bonus_hill") != std::string::npos) {
|
if (tmp.find("Bonus_hill") != std::string::npos) {
|
||||||
_players[senderId]->setFullHealth();
|
_players[senderId]->setFullHealth();
|
||||||
}
|
}
|
||||||
if(tmp.find("Bonus_ability") != std::string::npos) {
|
if (tmp.find("Bonus_ability") != std::string::npos) {
|
||||||
_players[senderId]->setFullAbility();
|
_players[senderId]->setFullAbility();
|
||||||
}
|
}
|
||||||
|
|
||||||
_bonuses[tmp] = std::make_shared<BonusInfo>(BonusInfo{_bonuses[tmp]->position, Time::time(), false});
|
_bonuses[tmp] = std::make_shared<BonusInfo>(BonusInfo{_bonuses[tmp]->position, Time::time(), false});
|
||||||
|
|
||||||
sendPacket << MsgType::Custom << ShooterMsgType::RemoveBonus << tmp;
|
sendPacket << MsgType::Custom << ShooterMsgType::RemoveBonus << tmp;
|
||||||
for (auto& player : _players) {
|
for (auto &player : _players) {
|
||||||
if(player.first != senderId) {
|
if (player.first != senderId) {
|
||||||
_socket.sendRely(sendPacket, player.first);
|
_socket.sendRely(sendPacket, player.first);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -129,15 +132,16 @@ void ShooterServer::processCustomPacket(sf::Packet& packet, sf::Uint16 senderId)
|
||||||
packet >> tmp;
|
packet >> tmp;
|
||||||
sendPacket << MsgType::Custom << ShooterMsgType::ChangeWeapon << senderId << tmp;
|
sendPacket << MsgType::Custom << ShooterMsgType::ChangeWeapon << senderId << tmp;
|
||||||
|
|
||||||
for (auto& player : _players) {
|
for (auto &player : _players) {
|
||||||
if(player.first != senderId) {
|
if (player.first != senderId) {
|
||||||
_socket.sendRely(sendPacket, player.first);
|
_socket.sendRely(sendPacket, player.first);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
Log::log("ShooterServer::processCustomPacket: unknown message type " + std::to_string(static_cast<int>(type)));
|
Log::log("ShooterServer::processCustomPacket: unknown message type " +
|
||||||
|
std::to_string(static_cast<int>(type)));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -148,34 +152,49 @@ void ShooterServer::processStop() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShooterServer::generateBonuses() {
|
void ShooterServer::generateBonuses() {
|
||||||
_bonuses.insert({"Bonus_gun_1", std::make_shared<BonusInfo>(BonusInfo{Vec3D(-10, -2, -15), -2*ShooterConsts::BONUS_RECHARGE_TIME, true})});
|
_bonuses.insert({"Bonus_gun_1", std::make_shared<BonusInfo>(
|
||||||
_bonuses.insert({"Bonus_gun_2", std::make_shared<BonusInfo>(BonusInfo{Vec3D(10, -2, 15), -2*ShooterConsts::BONUS_RECHARGE_TIME, true})});
|
BonusInfo{Vec3D(-10, -2, -15), -2 * ShooterConsts::BONUS_RECHARGE_TIME, true})});
|
||||||
|
_bonuses.insert({"Bonus_gun_2", std::make_shared<BonusInfo>(
|
||||||
|
BonusInfo{Vec3D(10, -2, 15), -2 * ShooterConsts::BONUS_RECHARGE_TIME, true})});
|
||||||
|
|
||||||
_bonuses.insert({"Bonus_shotgun_1", std::make_shared<BonusInfo>(BonusInfo{Vec3D(-10, 13, -24), -2*ShooterConsts::BONUS_RECHARGE_TIME, true})});
|
_bonuses.insert({"Bonus_shotgun_1", std::make_shared<BonusInfo>(
|
||||||
_bonuses.insert({"Bonus_shotgun_2", std::make_shared<BonusInfo>(BonusInfo{Vec3D(10, 13, 24), -2*ShooterConsts::BONUS_RECHARGE_TIME, true})});
|
BonusInfo{Vec3D(-10, 13, -24), -2 * ShooterConsts::BONUS_RECHARGE_TIME, true})});
|
||||||
|
_bonuses.insert({"Bonus_shotgun_2", std::make_shared<BonusInfo>(
|
||||||
|
BonusInfo{Vec3D(10, 13, 24), -2 * ShooterConsts::BONUS_RECHARGE_TIME, true})});
|
||||||
|
|
||||||
_bonuses.insert({"Bonus_ak47_1", std::make_shared<BonusInfo>(BonusInfo{Vec3D(-25, 30, 50), -2*ShooterConsts::BONUS_RECHARGE_TIME, true})});
|
_bonuses.insert({"Bonus_ak47_1", std::make_shared<BonusInfo>(
|
||||||
_bonuses.insert({"Bonus_ak47_2", std::make_shared<BonusInfo>(BonusInfo{Vec3D(25, 30, -50), -2*ShooterConsts::BONUS_RECHARGE_TIME, true})});
|
BonusInfo{Vec3D(-25, 30, 50), -2 * ShooterConsts::BONUS_RECHARGE_TIME, true})});
|
||||||
|
_bonuses.insert({"Bonus_ak47_2", std::make_shared<BonusInfo>(
|
||||||
|
BonusInfo{Vec3D(25, 30, -50), -2 * ShooterConsts::BONUS_RECHARGE_TIME, true})});
|
||||||
|
|
||||||
_bonuses.insert({"Bonus_gold_ak47_1", std::make_shared<BonusInfo>(BonusInfo{Vec3D(-35, 80, 25), -2*ShooterConsts::BONUS_RECHARGE_TIME, true})});
|
_bonuses.insert({"Bonus_gold_ak47_1", std::make_shared<BonusInfo>(
|
||||||
_bonuses.insert({"Bonus_gold_ak47_2", std::make_shared<BonusInfo>(BonusInfo{Vec3D(35, 80, -25), -2*ShooterConsts::BONUS_RECHARGE_TIME, true})});
|
BonusInfo{Vec3D(-35, 80, 25), -2 * ShooterConsts::BONUS_RECHARGE_TIME, true})});
|
||||||
|
_bonuses.insert({"Bonus_gold_ak47_2", std::make_shared<BonusInfo>(
|
||||||
|
BonusInfo{Vec3D(35, 80, -25), -2 * ShooterConsts::BONUS_RECHARGE_TIME, true})});
|
||||||
|
|
||||||
_bonuses.insert({"Bonus_rifle_1", std::make_shared<BonusInfo>(BonusInfo{Vec3D(40, -2, 45), -2*ShooterConsts::BONUS_RECHARGE_TIME, true})});
|
_bonuses.insert({"Bonus_rifle_1", std::make_shared<BonusInfo>(
|
||||||
_bonuses.insert({"Bonus_rifle_2", std::make_shared<BonusInfo>(BonusInfo{Vec3D(-40, -2, -45), -2*ShooterConsts::BONUS_RECHARGE_TIME, true})});
|
BonusInfo{Vec3D(40, -2, 45), -2 * ShooterConsts::BONUS_RECHARGE_TIME, true})});
|
||||||
|
_bonuses.insert({"Bonus_rifle_2", std::make_shared<BonusInfo>(
|
||||||
|
BonusInfo{Vec3D(-40, -2, -45), -2 * ShooterConsts::BONUS_RECHARGE_TIME, true})});
|
||||||
|
|
||||||
_bonuses.insert({"Bonus_hill_1", std::make_shared<BonusInfo>(BonusInfo{Vec3D(-40, -2, 45), -2*ShooterConsts::BONUS_RECHARGE_TIME, true})});
|
_bonuses.insert({"Bonus_hill_1", std::make_shared<BonusInfo>(
|
||||||
_bonuses.insert({"Bonus_hill_2", std::make_shared<BonusInfo>(BonusInfo{Vec3D(40, -2, -45), -2*ShooterConsts::BONUS_RECHARGE_TIME, true})});
|
BonusInfo{Vec3D(-40, -2, 45), -2 * ShooterConsts::BONUS_RECHARGE_TIME, true})});
|
||||||
|
_bonuses.insert({"Bonus_hill_2", std::make_shared<BonusInfo>(
|
||||||
|
BonusInfo{Vec3D(40, -2, -45), -2 * ShooterConsts::BONUS_RECHARGE_TIME, true})});
|
||||||
|
|
||||||
_bonuses.insert({"Bonus_ability_1", std::make_shared<BonusInfo>(BonusInfo{Vec3D(25, 18, -33), -2*ShooterConsts::BONUS_RECHARGE_TIME, true})});
|
_bonuses.insert({"Bonus_ability_1", std::make_shared<BonusInfo>(
|
||||||
_bonuses.insert({"Bonus_ability_2", std::make_shared<BonusInfo>(BonusInfo{Vec3D(-25, 18, 33), -2*ShooterConsts::BONUS_RECHARGE_TIME, true})});
|
BonusInfo{Vec3D(25, 18, -33), -2 * ShooterConsts::BONUS_RECHARGE_TIME, true})});
|
||||||
|
_bonuses.insert({"Bonus_ability_2", std::make_shared<BonusInfo>(
|
||||||
|
BonusInfo{Vec3D(-25, 18, 33), -2 * ShooterConsts::BONUS_RECHARGE_TIME, true})});
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShooterServer::updateInfo() {
|
void ShooterServer::updateInfo() {
|
||||||
for(auto& [bonusName, bonusInfo] : _bonuses) {
|
for (auto&[bonusName, bonusInfo] : _bonuses) {
|
||||||
if(!bonusInfo->onTheMap && std::abs(Time::time() - bonusInfo->lastTake) > ShooterConsts::BONUS_RECHARGE_TIME) {
|
if (!bonusInfo->onTheMap && std::abs(Time::time() - bonusInfo->lastTake) > ShooterConsts::BONUS_RECHARGE_TIME) {
|
||||||
sf::Packet sendPacket;
|
sf::Packet sendPacket;
|
||||||
sendPacket << MsgType::Custom << ShooterMsgType::AddBonus << bonusName << bonusInfo->position.x() << bonusInfo->position.y() << bonusInfo->position.z();
|
sendPacket << MsgType::Custom << ShooterMsgType::AddBonus << bonusName << bonusInfo->position.x()
|
||||||
for (const auto& player : _players) {
|
<< bonusInfo->position.y() << bonusInfo->position.z();
|
||||||
|
for (const auto &player : _players) {
|
||||||
_socket.sendRely(sendPacket, player.first);
|
_socket.sendRely(sendPacket, player.first);
|
||||||
}
|
}
|
||||||
bonusInfo = std::make_shared<BonusInfo>(BonusInfo{bonusInfo->position, bonusInfo->lastTake, true});
|
bonusInfo = std::make_shared<BonusInfo>(BonusInfo{bonusInfo->position, bonusInfo->lastTake, true});
|
||||||
|
|
|
@ -24,10 +24,12 @@ public:
|
||||||
void broadcast() override;
|
void broadcast() override;
|
||||||
|
|
||||||
void processConnect(sf::Uint16 senderId) override;
|
void processConnect(sf::Uint16 senderId) override;
|
||||||
void processClientUpdate(sf::Uint16 senderId, sf::Packet& packet) override;
|
|
||||||
|
void processClientUpdate(sf::Uint16 senderId, sf::Packet &packet) override;
|
||||||
|
|
||||||
void processDisconnect(sf::Uint16 senderId) override;
|
void processDisconnect(sf::Uint16 senderId) override;
|
||||||
|
|
||||||
void processCustomPacket(sf::Packet& packet, sf::Uint16 senderId) override;
|
void processCustomPacket(sf::Packet &packet, sf::Uint16 senderId) override;
|
||||||
|
|
||||||
void processStop() override;
|
void processStop() override;
|
||||||
|
|
||||||
|
|
|
@ -2,19 +2,20 @@
|
||||||
// Created by Иван Ильин on 14.01.2021.
|
// Created by Иван Ильин on 14.01.2021.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
#include <cmath>
|
||||||
|
|
||||||
#include "Camera.h"
|
#include "Camera.h"
|
||||||
#include "utils/Log.h"
|
#include "utils/Log.h"
|
||||||
#include "Consts.h"
|
#include "Consts.h"
|
||||||
#include <cmath>
|
|
||||||
|
|
||||||
std::vector<std::shared_ptr<Triangle>> Camera::project(std::shared_ptr<Mesh> mesh) {
|
std::vector<std::shared_ptr<Triangle>> Camera::project(std::shared_ptr<Mesh> mesh) {
|
||||||
|
|
||||||
if(!_ready) {
|
if (!_ready) {
|
||||||
Log::log("Camera::project(): cannot project _tris without camera initialization ( Camera::init() ) ");
|
Log::log("Camera::project(): cannot project _tris without camera initialization ( Camera::init() ) ");
|
||||||
return _triangles;
|
return _triangles;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!mesh->isVisible()) {
|
if (!mesh->isVisible()) {
|
||||||
return this->_triangles;
|
return this->_triangles;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,13 +26,13 @@ std::vector<std::shared_ptr<Triangle>> Camera::project(std::shared_ptr<Mesh> mes
|
||||||
// We don't want to waste time re-allocating memory every time
|
// We don't want to waste time re-allocating memory every time
|
||||||
std::vector<Triangle> clippedTriangles, tempBuffer;
|
std::vector<Triangle> clippedTriangles, tempBuffer;
|
||||||
|
|
||||||
for(auto& t : mesh->triangles()) {
|
for (auto &t : mesh->triangles()) {
|
||||||
|
|
||||||
Triangle MTriangle = t * M;
|
Triangle MTriangle = t * M;
|
||||||
|
|
||||||
double dot = MTriangle.norm().dot((Vec3D(MTriangle[0]) - position()).normalized());
|
double dot = MTriangle.norm().dot((Vec3D(MTriangle[0]) - position()).normalized());
|
||||||
|
|
||||||
if(dot > 0) {
|
if (dot > 0) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -44,23 +45,23 @@ std::vector<std::shared_ptr<Triangle>> Camera::project(std::shared_ptr<Mesh> mes
|
||||||
// In the beginning we need to to translate triangle from world coordinate to our camera system:
|
// In the beginning we need to to translate triangle from world coordinate to our camera system:
|
||||||
// After that we apply clipping for all planes from _clipPlanes
|
// After that we apply clipping for all planes from _clipPlanes
|
||||||
clippedTriangles.emplace_back(VMTriangle);
|
clippedTriangles.emplace_back(VMTriangle);
|
||||||
for(auto& plane : _clipPlanes) {
|
for (auto &plane : _clipPlanes) {
|
||||||
while(!clippedTriangles.empty()) {
|
while (!clippedTriangles.empty()) {
|
||||||
std::vector<Triangle> clipResult = plane.clip(clippedTriangles.back());
|
std::vector<Triangle> clipResult = plane.clip(clippedTriangles.back());
|
||||||
clippedTriangles.pop_back();
|
clippedTriangles.pop_back();
|
||||||
for(auto & i : clipResult) {
|
for (auto &i : clipResult) {
|
||||||
tempBuffer.emplace_back(i);
|
tempBuffer.emplace_back(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
clippedTriangles.swap(tempBuffer);
|
clippedTriangles.swap(tempBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
for(auto& clipped : clippedTriangles) {
|
for (auto &clipped : clippedTriangles) {
|
||||||
sf::Color color = clipped.color();
|
sf::Color color = clipped.color();
|
||||||
sf::Color ambientColor = sf::Color((sf::Uint8)(color.r * (0.3 * std::abs(dot) + 0.7)),
|
sf::Color ambientColor = sf::Color((sf::Uint8) (color.r * (0.3 * std::abs(dot) + 0.7)),
|
||||||
(sf::Uint8)(color.g * (0.3 * std::abs(dot) + 0.7)),
|
(sf::Uint8) (color.g * (0.3 * std::abs(dot) + 0.7)),
|
||||||
(sf::Uint8)(color.b * (0.3 * std::abs(dot) + 0.7)),
|
(sf::Uint8) (color.b * (0.3 * std::abs(dot) + 0.7)),
|
||||||
(sf::Uint8)color.a);
|
(sf::Uint8) color.a);
|
||||||
|
|
||||||
// Finally its time to project our clipped colored drawTriangle 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):
|
// and transform it's coordinate to screen space (in pixels):
|
||||||
|
@ -81,7 +82,7 @@ std::vector<std::shared_ptr<Triangle>> Camera::project(std::shared_ptr<Mesh> mes
|
||||||
void Camera::init(int width, int height, double fov, double ZNear, double ZFar) {
|
void Camera::init(int width, int height, double fov, double ZNear, double ZFar) {
|
||||||
// We need to init camera only after creation or changing width, height, fov, ZNear or ZFar.
|
// We need to init camera only after creation or changing width, height, fov, ZNear or ZFar.
|
||||||
// Because here we calculate matrix that does not change during the motion of _objects or camera
|
// Because here we calculate matrix that does not change during the motion of _objects or camera
|
||||||
_aspect = (double)width / (double)height;
|
_aspect = (double) width / (double) height;
|
||||||
Matrix4x4 P = Matrix4x4::Projection(fov, _aspect, ZNear, ZFar);
|
Matrix4x4 P = Matrix4x4::Projection(fov, _aspect, ZNear, ZFar);
|
||||||
Matrix4x4 S = Matrix4x4::ScreenSpace(width, height);
|
Matrix4x4 S = Matrix4x4::ScreenSpace(width, height);
|
||||||
|
|
||||||
|
@ -92,7 +93,7 @@ void Camera::init(int width, int height, double fov, double ZNear, double ZFar)
|
||||||
_clipPlanes.emplace_back(Plane(Vec3D{0, 0, 1}, Vec3D{0, 0, ZNear})); // near plane
|
_clipPlanes.emplace_back(Plane(Vec3D{0, 0, 1}, Vec3D{0, 0, ZNear})); // near plane
|
||||||
_clipPlanes.emplace_back(Plane(Vec3D{0, 0, -1}, Vec3D{0, 0, ZFar})); // far plane
|
_clipPlanes.emplace_back(Plane(Vec3D{0, 0, -1}, Vec3D{0, 0, ZFar})); // far plane
|
||||||
|
|
||||||
double thetta1 = Consts::PI*fov*0.5/180.0;
|
double thetta1 = Consts::PI * fov * 0.5 / 180.0;
|
||||||
double thetta2 = atan(_aspect * tan(thetta1));
|
double thetta2 = atan(_aspect * tan(thetta1));
|
||||||
_clipPlanes.emplace_back(Plane(Vec3D{-cos(thetta2), 0, sin(thetta2)}, Vec3D{0, 0, 0})); // left plane
|
_clipPlanes.emplace_back(Plane(Vec3D{-cos(thetta2), 0, sin(thetta2)}, Vec3D{0, 0, 0})); // left plane
|
||||||
_clipPlanes.emplace_back(Plane(Vec3D{cos(thetta2), 0, sin(thetta2)}, Vec3D{0, 0, 0})); // right plane
|
_clipPlanes.emplace_back(Plane(Vec3D{cos(thetta2), 0, sin(thetta2)}, Vec3D{0, 0, 0})); // right plane
|
||||||
|
|
|
@ -6,11 +6,13 @@
|
||||||
#define ENGINE_CAMERA_H
|
#define ENGINE_CAMERA_H
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include "Plane.h"
|
|
||||||
#include "Mesh.h"
|
|
||||||
#include <SFML/OpenGL.hpp>
|
#include <SFML/OpenGL.hpp>
|
||||||
|
|
||||||
class Camera final : public Object{
|
#include "Plane.h"
|
||||||
|
#include "Mesh.h"
|
||||||
|
|
||||||
|
class Camera final : public Object {
|
||||||
private:
|
private:
|
||||||
std::vector<std::shared_ptr<Triangle>> _triangles{};
|
std::vector<std::shared_ptr<Triangle>> _triangles{};
|
||||||
std::vector<Plane> _clipPlanes{};
|
std::vector<Plane> _clipPlanes{};
|
||||||
|
@ -18,10 +20,10 @@ private:
|
||||||
double _aspect = 0;
|
double _aspect = 0;
|
||||||
|
|
||||||
Matrix4x4 _SP;
|
Matrix4x4 _SP;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Camera() : Object(ObjectNameTag("Camera")) {};
|
Camera() : Object(ObjectNameTag("Camera")) {};
|
||||||
Camera(const Camera& camera) = delete;
|
|
||||||
|
Camera(const Camera &camera) = delete;
|
||||||
|
|
||||||
void init(int width, int height, double fov = 110.0, double ZNear = 0.1, double ZFar = 5000.0);
|
void init(int width, int height, double fov = 110.0, double ZNear = 0.1, double ZFar = 5000.0);
|
||||||
|
|
||||||
|
@ -30,6 +32,7 @@ public:
|
||||||
void clear();
|
void clear();
|
||||||
|
|
||||||
[[nodiscard]] int buffSize() const { return _triangles.size(); }
|
[[nodiscard]] int buffSize() const { return _triangles.size(); }
|
||||||
|
|
||||||
std::vector<std::shared_ptr<Triangle>> sorted();
|
std::vector<std::shared_ptr<Triangle>> sorted();
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -4,7 +4,9 @@
|
||||||
|
|
||||||
#ifndef SHOOTER_CONSTS_H
|
#ifndef SHOOTER_CONSTS_H
|
||||||
#define SHOOTER_CONSTS_H
|
#define SHOOTER_CONSTS_H
|
||||||
|
|
||||||
#include <SFML/Graphics.hpp>
|
#include <SFML/Graphics.hpp>
|
||||||
|
|
||||||
#include "Vec2D.h"
|
#include "Vec2D.h"
|
||||||
|
|
||||||
namespace Consts {
|
namespace Consts {
|
||||||
|
@ -27,7 +29,7 @@ namespace Consts {
|
||||||
const std::string THIN_FONT = "engine/fonts/Roboto-Thin.ttf";
|
const std::string THIN_FONT = "engine/fonts/Roboto-Thin.ttf";
|
||||||
const std::string MEDIUM_FONT = "engine/fonts/Roboto-Medium.ttf";
|
const std::string MEDIUM_FONT = "engine/fonts/Roboto-Medium.ttf";
|
||||||
|
|
||||||
const double LARGEST_TIME_STEP = 1.0/15.0;
|
const double LARGEST_TIME_STEP = 1.0 / 15.0;
|
||||||
const double TAP_DELAY = 0.2;
|
const double TAP_DELAY = 0.2;
|
||||||
|
|
||||||
const Vec2D BEZIER[2] = {Vec2D{0.8, 0}, Vec2D{0.2, 1}};
|
const Vec2D BEZIER[2] = {Vec2D{0.8, 0}, Vec2D{0.2, 1}};
|
||||||
|
@ -35,10 +37,8 @@ namespace Consts {
|
||||||
const unsigned NETWORK_VERSION = 3U;
|
const unsigned NETWORK_VERSION = 3U;
|
||||||
const int NETWORK_TIMEOUT = 5U;
|
const int NETWORK_TIMEOUT = 5U;
|
||||||
const int NETWORK_WORLD_UPDATE_RATE = 30;
|
const int NETWORK_WORLD_UPDATE_RATE = 30;
|
||||||
const double NETWORK_RELIABLE_RETRY_TIME = 1.0/20;
|
const double NETWORK_RELIABLE_RETRY_TIME = 1.0 / 20;
|
||||||
const uint16_t NETWORK_MAX_CLIENTS = 64;
|
const uint16_t NETWORK_MAX_CLIENTS = 64;
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif //SHOOTER_CONSTS_H
|
#endif //SHOOTER_CONSTS_H
|
||||||
|
|
|
@ -2,9 +2,10 @@
|
||||||
// Created by Иван Ильин on 14.01.2021.
|
// Created by Иван Ильин on 14.01.2021.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
#include "Engine.h"
|
#include "Engine.h"
|
||||||
#include "utils/Time.h"
|
#include "utils/Time.h"
|
||||||
#include <iostream>
|
|
||||||
#include "ResourceManager.h"
|
#include "ResourceManager.h"
|
||||||
#include "animation/Timeline.h"
|
#include "animation/Timeline.h"
|
||||||
#include "SoundController.h"
|
#include "SoundController.h"
|
||||||
|
@ -16,11 +17,13 @@ Engine::Engine() {
|
||||||
SoundController::init();
|
SoundController::init();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Engine::create(int screenWidth, int screenHeight, const std::string &name, bool verticalSync, sf::Color background, sf::Uint32 style) {
|
void Engine::create(int screenWidth, int screenHeight, const std::string &name, bool verticalSync, sf::Color background,
|
||||||
|
sf::Uint32 style) {
|
||||||
_name = name;
|
_name = name;
|
||||||
screen->open(screenWidth, screenHeight, name, verticalSync, background, style);
|
screen->open(screenWidth, screenHeight, name, verticalSync, background, style);
|
||||||
|
|
||||||
Log::log("Engine::create(): started engine (" + std::to_string(screenWidth) + "x" + std::to_string(screenHeight) + ") with title '" + name + "'.");
|
Log::log("Engine::create(): started engine (" + std::to_string(screenWidth) + "x" + std::to_string(screenHeight) +
|
||||||
|
") with title '" + name + "'.");
|
||||||
Time::update();
|
Time::update();
|
||||||
|
|
||||||
start();
|
start();
|
||||||
|
@ -36,18 +39,18 @@ void Engine::create(int screenWidth, int screenHeight, const std::string &name,
|
||||||
// sometimes we dont need to update physics world
|
// sometimes we dont need to update physics world
|
||||||
// (for example in menu or while pause)
|
// (for example in menu or while pause)
|
||||||
// hence we can set '_updateWorld' equal to false in setUpdateWorld(bool):
|
// hence we can set '_updateWorld' equal to false in setUpdateWorld(bool):
|
||||||
if(_updateWorld) {
|
if (_updateWorld) {
|
||||||
|
|
||||||
Timeline::update();
|
Timeline::update();
|
||||||
|
|
||||||
world->update();
|
world->update();
|
||||||
|
|
||||||
if(_useOpenGL) {
|
if (_useOpenGL) {
|
||||||
GLfloat* view = camera->glView();
|
GLfloat *view = camera->glView();
|
||||||
for(auto & it : *world) {
|
for (auto &it : *world) {
|
||||||
if (it.second->isVisible()) {
|
if (it.second->isVisible()) {
|
||||||
GLfloat* model = it.second->glModel();
|
GLfloat *model = it.second->glModel();
|
||||||
GLfloat* geometry = Screen::glMeshToGLfloatArray(it.second, camera->position());
|
GLfloat *geometry = Screen::glMeshToGLfloatArray(it.second, camera->position());
|
||||||
screen->glDrawMesh(geometry, view, model, 3 * it.second->triangles().size());
|
screen->glDrawMesh(geometry, view, model, 3 * it.second->triangles().size());
|
||||||
free(geometry);
|
free(geometry);
|
||||||
free(model);
|
free(model);
|
||||||
|
@ -58,7 +61,7 @@ void Engine::create(int screenWidth, int screenHeight, const std::string &name,
|
||||||
// clear triangles from previous frame
|
// clear triangles from previous frame
|
||||||
camera->clear();
|
camera->clear();
|
||||||
// project triangles to the camera plane
|
// project triangles to the camera plane
|
||||||
for(auto & it : *world) {
|
for (auto &it : *world) {
|
||||||
camera->project(it.second);
|
camera->project(it.second);
|
||||||
}
|
}
|
||||||
// draw triangles on the screen
|
// draw triangles on the screen
|
||||||
|
@ -70,7 +73,8 @@ void Engine::create(int screenWidth, int screenHeight, const std::string &name,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Consts::SHOW_FPS_COUNTER) {
|
if (Consts::SHOW_FPS_COUNTER) {
|
||||||
screen->drawText(std::to_string(Time::fps()) + " fps", Vec2D(screen->width() - 100, 10), 25, sf::Color(100,100,100));
|
screen->drawText(std::to_string(Time::fps()) + " fps", Vec2D(screen->width() - 100, 10), 25,
|
||||||
|
sf::Color(100, 100, 100));
|
||||||
}
|
}
|
||||||
|
|
||||||
printDebugText();
|
printDebugText();
|
||||||
|
@ -82,7 +86,7 @@ void Engine::create(int screenWidth, int screenHeight, const std::string &name,
|
||||||
}
|
}
|
||||||
|
|
||||||
void Engine::exit() {
|
void Engine::exit() {
|
||||||
if(screen->isOpen()) {
|
if (screen->isOpen()) {
|
||||||
screen->close();
|
screen->close();
|
||||||
}
|
}
|
||||||
SoundController::free();
|
SoundController::free();
|
||||||
|
@ -90,21 +94,21 @@ void Engine::exit() {
|
||||||
Timeline::free();
|
Timeline::free();
|
||||||
Time::free();
|
Time::free();
|
||||||
|
|
||||||
Log::log("Engine::exit(): exit engine (" + std::to_string(screen->width()) + "x" + std::to_string(screen->height()) + ") with title '" +
|
Log::log("Engine::exit(): exit engine (" + std::to_string(screen->width()) + "x" +
|
||||||
screen->title() + "'.");
|
std::to_string(screen->height()) + ") with title '" + screen->title() + "'.");
|
||||||
}
|
}
|
||||||
|
|
||||||
void Engine::printDebugText() const {
|
void Engine::printDebugText() const {
|
||||||
|
|
||||||
if (_debugText) {
|
if (_debugText) {
|
||||||
std::string text = _name + "\n\n X: " +
|
std::string text = _name + "\n\n X: " +
|
||||||
std::to_string((camera->position().x())) + "\n Y: " +
|
std::to_string((camera->position().x())) + "\n Y: " +
|
||||||
std::to_string((camera->position().y())) + "\n Z: " +
|
std::to_string((camera->position().y())) + "\n Z: " +
|
||||||
std::to_string((camera->position().z())) + "\n\n" +
|
std::to_string((camera->position().z())) + "\n\n" +
|
||||||
std::to_string(screen->width()) + "x" +
|
std::to_string(screen->width()) + "x" +
|
||||||
std::to_string(screen->height()) + "\t" +
|
std::to_string(screen->height()) + "\t" +
|
||||||
std::to_string(Time::fps()) + " fps";
|
std::to_string(Time::fps()) + " fps";
|
||||||
if(_useOpenGL) {
|
if (_useOpenGL) {
|
||||||
text += "\n Using OpenGL acceleration";
|
text += "\n Using OpenGL acceleration";
|
||||||
} else {
|
} else {
|
||||||
text += "\n" + std::to_string((int) _triPerSec) + " tris/s";
|
text += "\n" + std::to_string((int) _triPerSec) + " tris/s";
|
||||||
|
|
|
@ -8,7 +8,6 @@
|
||||||
#include "Screen.h"
|
#include "Screen.h"
|
||||||
#include "Keyboard.h"
|
#include "Keyboard.h"
|
||||||
#include "Mouse.h"
|
#include "Mouse.h"
|
||||||
|
|
||||||
#include "World.h"
|
#include "World.h"
|
||||||
#include "Camera.h"
|
#include "Camera.h"
|
||||||
#include "utils/Log.h"
|
#include "utils/Log.h"
|
||||||
|
@ -23,6 +22,7 @@ private:
|
||||||
bool _useOpenGL = Consts::USE_OPEN_GL;
|
bool _useOpenGL = Consts::USE_OPEN_GL;
|
||||||
|
|
||||||
void printDebugText() const;
|
void printDebugText() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
const std::shared_ptr<Screen> screen = std::make_shared<Screen>();
|
const std::shared_ptr<Screen> screen = std::make_shared<Screen>();
|
||||||
const std::shared_ptr<Keyboard> keyboard = std::make_shared<Keyboard>();
|
const std::shared_ptr<Keyboard> keyboard = std::make_shared<Keyboard>();
|
||||||
|
@ -32,19 +32,26 @@ protected:
|
||||||
const std::shared_ptr<Camera> camera = std::make_shared<Camera>();
|
const std::shared_ptr<Camera> camera = std::make_shared<Camera>();
|
||||||
|
|
||||||
virtual void start() {};
|
virtual void start() {};
|
||||||
|
|
||||||
virtual void update() {};
|
virtual void update() {};
|
||||||
|
|
||||||
void setDebugText(bool value) { _debugText = value; }
|
void setDebugText(bool value) { _debugText = value; }
|
||||||
|
|
||||||
void setUpdateWorld(bool value) { _updateWorld = value; }
|
void setUpdateWorld(bool value) { _updateWorld = value; }
|
||||||
|
|
||||||
void setGlEnable(bool value) { _useOpenGL = value; }
|
void setGlEnable(bool value) { _useOpenGL = value; }
|
||||||
|
|
||||||
virtual void gui(){}
|
virtual void gui() {}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Engine();
|
Engine();
|
||||||
|
|
||||||
virtual ~Engine() = default;
|
virtual ~Engine() = default;
|
||||||
|
|
||||||
void create(int screenWidth = Consts::STANDARD_SCREEN_WIDTH, int screenHeight = Consts::STANDARD_SCREEN_HEIGHT, const std::string& name = Consts::PROJECT_NAME, bool verticalSync = true, sf::Color background = Consts::BACKGROUND_COLOR, sf::Uint32 style = sf::Style::Default);
|
void create(int screenWidth = Consts::STANDARD_SCREEN_WIDTH, int screenHeight = Consts::STANDARD_SCREEN_HEIGHT,
|
||||||
|
const std::string &name = Consts::PROJECT_NAME, bool verticalSync = true,
|
||||||
|
sf::Color background = Consts::BACKGROUND_COLOR, sf::Uint32 style = sf::Style::Default);
|
||||||
|
|
||||||
void exit();
|
void exit();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -15,10 +15,10 @@ bool Keyboard::isKeyTapped(sf::Keyboard::Key key) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(_tappedKeys.count(key) == 0) {
|
if (_tappedKeys.count(key) == 0) {
|
||||||
_tappedKeys.emplace(key, Time::time());
|
_tappedKeys.emplace(key, Time::time());
|
||||||
return true;
|
return true;
|
||||||
} else if((Time::time() - _tappedKeys[key]) > Consts::TAP_DELAY) {
|
} else if ((Time::time() - _tappedKeys[key]) > Consts::TAP_DELAY) {
|
||||||
_tappedKeys[key] = Time::time();
|
_tappedKeys[key] = Time::time();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,8 +13,11 @@ private:
|
||||||
public:
|
public:
|
||||||
Keyboard() = default;
|
Keyboard() = default;
|
||||||
|
|
||||||
static bool isKeyPressed(sf::Keyboard::Key key); // returns true if this key is _pressed
|
// returns true if this key is _pressed
|
||||||
bool isKeyTapped(sf::Keyboard::Key key); // returns true if this key is tapped and 1/5 sec passed (_button bouncing problem solved)
|
static bool isKeyPressed(sf::Keyboard::Key key);
|
||||||
|
|
||||||
|
// returns true if this key is tapped and 1/5 sec passed (_button bouncing problem solved)
|
||||||
|
bool isKeyTapped(sf::Keyboard::Key key);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -2,18 +2,17 @@
|
||||||
// Created by Иван Ильин on 12.01.2021.
|
// Created by Иван Ильин on 12.01.2021.
|
||||||
//
|
//
|
||||||
|
|
||||||
#include "Matrix4x4.h"
|
|
||||||
#include <cassert>
|
|
||||||
|
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
|
||||||
|
#include "Matrix4x4.h"
|
||||||
#include "Consts.h"
|
#include "Consts.h"
|
||||||
|
|
||||||
Matrix4x4 Matrix4x4::operator*(const Matrix4x4 &matrix4X4) const {
|
Matrix4x4 Matrix4x4::operator*(const Matrix4x4 &matrix4X4) const {
|
||||||
Matrix4x4 result = Matrix4x4::Zero();
|
Matrix4x4 result = Matrix4x4::Zero();
|
||||||
|
|
||||||
for(int i = 0; i < 4; i++)
|
for (int i = 0; i < 4; i++)
|
||||||
for(int j = 0; j < 4; j++)
|
for (int j = 0; j < 4; j++)
|
||||||
for(int k = 0; k < 4; k++)
|
for (int k = 0; k < 4; k++)
|
||||||
result._arr[i][j] += _arr[i][k] * matrix4X4._arr[k][j];
|
result._arr[i][j] += _arr[i][k] * matrix4X4._arr[k][j];
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -32,13 +31,13 @@ Vec3D Matrix4x4::operator*(const Vec3D &vec) const {
|
||||||
_arr[0][0] * vec.x() + _arr[0][1] * vec.y() + _arr[0][2] * vec.z(),
|
_arr[0][0] * vec.x() + _arr[0][1] * vec.y() + _arr[0][2] * vec.z(),
|
||||||
_arr[1][0] * vec.x() + _arr[1][1] * vec.y() + _arr[1][2] * vec.z(),
|
_arr[1][0] * vec.x() + _arr[1][1] * vec.y() + _arr[1][2] * vec.z(),
|
||||||
_arr[2][0] * vec.x() + _arr[2][1] * vec.y() + _arr[2][2] * vec.z()
|
_arr[2][0] * vec.x() + _arr[2][1] * vec.y() + _arr[2][2] * vec.z()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Matrix4x4 Matrix4x4::Identity() {
|
Matrix4x4 Matrix4x4::Identity() {
|
||||||
Matrix4x4 result;
|
Matrix4x4 result;
|
||||||
|
|
||||||
for(int i = 0; i < 4; i++) {
|
for (int i = 0; i < 4; i++) {
|
||||||
for (int j = 0; j < 4; j++) {
|
for (int j = 0; j < 4; j++) {
|
||||||
if (i == j) {
|
if (i == j) {
|
||||||
result._arr[j][i] = 1.0;
|
result._arr[j][i] = 1.0;
|
||||||
|
@ -54,7 +53,7 @@ Matrix4x4 Matrix4x4::Identity() {
|
||||||
Matrix4x4 Matrix4x4::Constant(double value) {
|
Matrix4x4 Matrix4x4::Constant(double value) {
|
||||||
Matrix4x4 result;
|
Matrix4x4 result;
|
||||||
|
|
||||||
for(int i = 0; i < 4; i++) {
|
for (int i = 0; i < 4; i++) {
|
||||||
for (int j = 0; j < 4; j++) {
|
for (int j = 0; j < 4; j++) {
|
||||||
result._arr[j][i] = value;
|
result._arr[j][i] = value;
|
||||||
}
|
}
|
||||||
|
@ -67,7 +66,7 @@ Matrix4x4 Matrix4x4::Zero() {
|
||||||
return Matrix4x4::Constant(0);
|
return Matrix4x4::Constant(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
Matrix4x4 Matrix4x4::Scale(const Vec3D& factor) {
|
Matrix4x4 Matrix4x4::Scale(const Vec3D &factor) {
|
||||||
Matrix4x4 s{};
|
Matrix4x4 s{};
|
||||||
s._arr[0][0] = factor.x();
|
s._arr[0][0] = factor.x();
|
||||||
s._arr[1][1] = factor.y();
|
s._arr[1][1] = factor.y();
|
||||||
|
@ -77,7 +76,7 @@ Matrix4x4 Matrix4x4::Scale(const Vec3D& factor) {
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
Matrix4x4 Matrix4x4::Translation(const Vec3D& v) {
|
Matrix4x4 Matrix4x4::Translation(const Vec3D &v) {
|
||||||
Matrix4x4 t{};
|
Matrix4x4 t{};
|
||||||
|
|
||||||
t._arr[0][0] = 1.0;
|
t._arr[0][0] = 1.0;
|
||||||
|
@ -136,25 +135,25 @@ Matrix4x4 Matrix4x4::RotationZ(double rz) {
|
||||||
return Rz;
|
return Rz;
|
||||||
}
|
}
|
||||||
|
|
||||||
Matrix4x4 Matrix4x4::Rotation(const Vec3D& r) {
|
Matrix4x4 Matrix4x4::Rotation(const Vec3D &r) {
|
||||||
return RotationX(r.x()) * RotationY(r.y()) * RotationZ(r.z());
|
return RotationX(r.x()) * RotationY(r.y()) * RotationZ(r.z());
|
||||||
}
|
}
|
||||||
|
|
||||||
Matrix4x4 Matrix4x4::Rotation(const Vec3D& v, double rv) {
|
Matrix4x4 Matrix4x4::Rotation(const Vec3D &v, double rv) {
|
||||||
Matrix4x4 Rv{};
|
Matrix4x4 Rv{};
|
||||||
Vec3D nv(v.normalized());
|
Vec3D nv(v.normalized());
|
||||||
|
|
||||||
Rv._arr[0][0] = cos(rv) + (1.0 - cos(rv))*nv.x()*nv.x();
|
Rv._arr[0][0] = cos(rv) + (1.0 - cos(rv)) * nv.x() * nv.x();
|
||||||
Rv._arr[0][1] = (1.0 - cos(rv))*nv.x()*nv.y() - sin(rv)*nv.z();
|
Rv._arr[0][1] = (1.0 - cos(rv)) * nv.x() * nv.y() - sin(rv) * nv.z();
|
||||||
Rv._arr[0][2] = (1.0 - cos(rv))*nv.x()*nv.z() + sin(rv)*nv.y();
|
Rv._arr[0][2] = (1.0 - cos(rv)) * nv.x() * nv.z() + sin(rv) * nv.y();
|
||||||
|
|
||||||
Rv._arr[1][0] = (1.0 - cos(rv))*nv.x()*nv.y() + sin(rv)*nv.z();
|
Rv._arr[1][0] = (1.0 - cos(rv)) * nv.x() * nv.y() + sin(rv) * nv.z();
|
||||||
Rv._arr[1][1] = cos(rv) + (1.0 - cos(rv))*nv.y()*nv.y();
|
Rv._arr[1][1] = cos(rv) + (1.0 - cos(rv)) * nv.y() * nv.y();
|
||||||
Rv._arr[1][2] = (1.0 - cos(rv))*nv.y()*nv.z() - sin(rv)*nv.x();
|
Rv._arr[1][2] = (1.0 - cos(rv)) * nv.y() * nv.z() - sin(rv) * nv.x();
|
||||||
|
|
||||||
Rv._arr[2][0] = (1.0 - cos(rv))*nv.z()*nv.x() - sin(rv)*nv.y();
|
Rv._arr[2][0] = (1.0 - cos(rv)) * nv.z() * nv.x() - sin(rv) * nv.y();
|
||||||
Rv._arr[2][1] = (1.0 - cos(rv))*nv.z()*nv.y() + sin(rv)*nv.x();
|
Rv._arr[2][1] = (1.0 - cos(rv)) * nv.z() * nv.y() + sin(rv) * nv.x();
|
||||||
Rv._arr[2][2] = cos(rv) + (1.0 - cos(rv))*nv.z()*nv.z();
|
Rv._arr[2][2] = cos(rv) + (1.0 - cos(rv)) * nv.z() * nv.z();
|
||||||
|
|
||||||
Rv._arr[3][3] = 1.0;
|
Rv._arr[3][3] = 1.0;
|
||||||
|
|
||||||
|
@ -164,10 +163,10 @@ Matrix4x4 Matrix4x4::Rotation(const Vec3D& v, double rv) {
|
||||||
Matrix4x4 Matrix4x4::Projection(double fov, double aspect, double ZNear, double ZFar) {
|
Matrix4x4 Matrix4x4::Projection(double fov, double aspect, double ZNear, double ZFar) {
|
||||||
Matrix4x4 p{};
|
Matrix4x4 p{};
|
||||||
|
|
||||||
p._arr[0][0] = 1.0/(tan(Consts::PI*fov*0.5/180.0)*aspect);
|
p._arr[0][0] = 1.0 / (tan(Consts::PI * fov * 0.5 / 180.0) * aspect);
|
||||||
p._arr[1][1] = 1.0/tan(Consts::PI*fov*0.5/180.0);
|
p._arr[1][1] = 1.0 / tan(Consts::PI * fov * 0.5 / 180.0);
|
||||||
p._arr[2][2] = ZFar/(ZFar - ZNear);
|
p._arr[2][2] = ZFar / (ZFar - ZNear);
|
||||||
p._arr[2][3] = -ZFar*ZNear/(ZFar - ZNear);
|
p._arr[2][3] = -ZFar * ZNear / (ZFar - ZNear);
|
||||||
p._arr[3][2] = 1.0;
|
p._arr[3][2] = 1.0;
|
||||||
|
|
||||||
return p;
|
return p;
|
||||||
|
@ -176,12 +175,12 @@ Matrix4x4 Matrix4x4::Projection(double fov, double aspect, double ZNear, double
|
||||||
Matrix4x4 Matrix4x4::ScreenSpace(int width, int height) {
|
Matrix4x4 Matrix4x4::ScreenSpace(int width, int height) {
|
||||||
Matrix4x4 s{};
|
Matrix4x4 s{};
|
||||||
|
|
||||||
s._arr[0][0] = -0.5*width;
|
s._arr[0][0] = -0.5 * width;
|
||||||
s._arr[1][1] = -0.5*height;
|
s._arr[1][1] = -0.5 * height;
|
||||||
s._arr[2][2] = 1.0;
|
s._arr[2][2] = 1.0;
|
||||||
|
|
||||||
s._arr[0][3] = 0.5*width;
|
s._arr[0][3] = 0.5 * width;
|
||||||
s._arr[1][3] = 0.5*height;
|
s._arr[1][3] = 0.5 * height;
|
||||||
|
|
||||||
s._arr[3][3] = 1.0;
|
s._arr[3][3] = 1.0;
|
||||||
|
|
||||||
|
@ -212,17 +211,17 @@ Matrix4x4 Matrix4x4::View(const Vec3D &left, const Vec3D &up, const Vec3D &lookA
|
||||||
}
|
}
|
||||||
|
|
||||||
Vec3D Matrix4x4::x() const {
|
Vec3D Matrix4x4::x() const {
|
||||||
return Vec3D(_arr[0][0], _arr[1][0],_arr[2][0]);
|
return Vec3D(_arr[0][0], _arr[1][0], _arr[2][0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
Vec3D Matrix4x4::y() const {
|
Vec3D Matrix4x4::y() const {
|
||||||
return Vec3D(_arr[0][1], _arr[1][1],_arr[2][1]);
|
return Vec3D(_arr[0][1], _arr[1][1], _arr[2][1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
Vec3D Matrix4x4::z() const {
|
Vec3D Matrix4x4::z() const {
|
||||||
return Vec3D(_arr[0][2], _arr[1][2],_arr[2][2]);
|
return Vec3D(_arr[0][2], _arr[1][2], _arr[2][2]);
|
||||||
}
|
}
|
||||||
|
|
||||||
Vec3D Matrix4x4::w() const {
|
Vec3D Matrix4x4::w() const {
|
||||||
return Vec3D(_arr[0][3], _arr[1][3],_arr[2][3]);
|
return Vec3D(_arr[0][3], _arr[1][3], _arr[2][3]);
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#define ENGINE_MATRIX4X4_H
|
#define ENGINE_MATRIX4X4_H
|
||||||
|
|
||||||
#include <array>
|
#include <array>
|
||||||
|
|
||||||
#include "Vec4D.h"
|
#include "Vec4D.h"
|
||||||
#include "Vec3D.h"
|
#include "Vec3D.h"
|
||||||
|
|
||||||
|
@ -14,35 +15,51 @@ private:
|
||||||
std::array<std::array<double, 4>, 4> _arr{};
|
std::array<std::array<double, 4>, 4> _arr{};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Matrix4x4 () = default;
|
Matrix4x4() = default;
|
||||||
Matrix4x4& operator=(const Matrix4x4& matrix4X4) = default;
|
|
||||||
|
|
||||||
[[nodiscard]] Matrix4x4 operator*(const Matrix4x4& matrix4X4) const;
|
Matrix4x4 &operator=(const Matrix4x4 &matrix4X4) = default;
|
||||||
[[nodiscard]] Vec4D operator*(const Vec4D& point4D) const;
|
|
||||||
[[nodiscard]] Vec3D operator*(const Vec3D& vec) const;
|
[[nodiscard]] Matrix4x4 operator*(const Matrix4x4 &matrix4X4) const;
|
||||||
|
|
||||||
|
[[nodiscard]] Vec4D operator*(const Vec4D &point4D) const;
|
||||||
|
|
||||||
|
[[nodiscard]] Vec3D operator*(const Vec3D &vec) const;
|
||||||
|
|
||||||
[[nodiscard]] Vec3D x() const;
|
[[nodiscard]] Vec3D x() const;
|
||||||
|
|
||||||
[[nodiscard]] Vec3D y() const;
|
[[nodiscard]] Vec3D y() const;
|
||||||
|
|
||||||
[[nodiscard]] Vec3D z() const;
|
[[nodiscard]] Vec3D z() const;
|
||||||
|
|
||||||
[[nodiscard]] Vec3D w() const;
|
[[nodiscard]] Vec3D w() const;
|
||||||
|
|
||||||
|
|
||||||
// Any useful matrix (static methods)
|
// Any useful matrix (static methods)
|
||||||
Matrix4x4 static Identity();
|
Matrix4x4 static Identity();
|
||||||
Matrix4x4 static Zero();
|
|
||||||
Matrix4x4 static Constant (double value);
|
|
||||||
|
|
||||||
Matrix4x4 static Scale(const Vec3D& factor);
|
Matrix4x4 static Zero();
|
||||||
Matrix4x4 static Translation(const Vec3D& v);
|
|
||||||
Matrix4x4 static Rotation(const Vec3D& r);
|
Matrix4x4 static Constant(double value);
|
||||||
Matrix4x4 static RotationX (double rx);
|
|
||||||
Matrix4x4 static RotationY (double ry);
|
Matrix4x4 static Scale(const Vec3D &factor);
|
||||||
Matrix4x4 static RotationZ (double rz);
|
|
||||||
Matrix4x4 static Rotation (const Vec3D& v, double rv);
|
Matrix4x4 static Translation(const Vec3D &v);
|
||||||
|
|
||||||
|
Matrix4x4 static Rotation(const Vec3D &r);
|
||||||
|
|
||||||
|
Matrix4x4 static RotationX(double rx);
|
||||||
|
|
||||||
|
Matrix4x4 static RotationY(double ry);
|
||||||
|
|
||||||
|
Matrix4x4 static RotationZ(double rz);
|
||||||
|
|
||||||
|
Matrix4x4 static Rotation(const Vec3D &v, double rv);
|
||||||
|
|
||||||
Matrix4x4 static View(const Vec3D &left, const Vec3D &up, const Vec3D &lookAt, const Vec3D &eye);
|
Matrix4x4 static View(const Vec3D &left, const Vec3D &up, const Vec3D &lookAt, const Vec3D &eye);
|
||||||
Matrix4x4 static Projection (double fov = 90.0, double aspect = 1.0, double ZNear = 1.0, double ZFar = 10.0);
|
|
||||||
Matrix4x4 static ScreenSpace (int width, int height);
|
Matrix4x4 static Projection(double fov = 90.0, double aspect = 1.0, double ZNear = 1.0, double ZFar = 10.0);
|
||||||
|
|
||||||
|
Matrix4x4 static ScreenSpace(int width, int height);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
//
|
//
|
||||||
|
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
#include "Mesh.h"
|
#include "Mesh.h"
|
||||||
#include "ResourceManager.h"
|
#include "ResourceManager.h"
|
||||||
|
|
||||||
|
@ -10,7 +11,7 @@ using namespace std;
|
||||||
|
|
||||||
Mesh &Mesh::operator*=(const Matrix4x4 &matrix4X4) {
|
Mesh &Mesh::operator*=(const Matrix4x4 &matrix4X4) {
|
||||||
std::vector<Triangle> newTriangles;
|
std::vector<Triangle> newTriangles;
|
||||||
for(auto &t : _tris) {
|
for (auto &t : _tris) {
|
||||||
newTriangles.emplace_back(t * matrix4X4);
|
newTriangles.emplace_back(t * matrix4X4);
|
||||||
}
|
}
|
||||||
setTriangles(newTriangles);
|
setTriangles(newTriangles);
|
||||||
|
@ -18,10 +19,10 @@ Mesh &Mesh::operator*=(const Matrix4x4 &matrix4X4) {
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Mesh::loadObj(const std::string& filename, const Vec3D& scale) {
|
void Mesh::loadObj(const std::string &filename, const Vec3D &scale) {
|
||||||
|
|
||||||
auto objects = ResourceManager::loadObjects(filename);
|
auto objects = ResourceManager::loadObjects(filename);
|
||||||
for(auto& obj : objects) {
|
for (auto &obj : objects) {
|
||||||
for (auto &tri : obj->triangles()) {
|
for (auto &tri : obj->triangles()) {
|
||||||
_tris.push_back(tri);
|
_tris.push_back(tri);
|
||||||
}
|
}
|
||||||
|
@ -29,29 +30,30 @@ void Mesh::loadObj(const std::string& filename, const Vec3D& scale) {
|
||||||
this->scale(scale);
|
this->scale(scale);
|
||||||
}
|
}
|
||||||
|
|
||||||
Mesh::Mesh(ObjectNameTag nameTag, const std::string& filename, const Vec3D& scale) : Object(std::move(nameTag)) {
|
Mesh::Mesh(ObjectNameTag nameTag, const std::string &filename, const Vec3D &scale) : Object(std::move(nameTag)) {
|
||||||
loadObj(filename, scale);
|
loadObj(filename, scale);
|
||||||
}
|
}
|
||||||
|
|
||||||
Mesh::Mesh(ObjectNameTag nameTag, const vector<Triangle> &tries) : Object(std::move(nameTag)), _tris(tries) {
|
Mesh::Mesh(ObjectNameTag nameTag, const vector<Triangle> &tries) : Object(std::move(nameTag)), _tris(tries) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Mesh Mesh::Obj(ObjectNameTag nameTag, const std::string& filename) {
|
Mesh Mesh::Obj(ObjectNameTag nameTag, const std::string &filename) {
|
||||||
return Mesh(std::move(nameTag), filename);
|
return Mesh(std::move(nameTag), filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Mesh::setColor(const sf::Color& c) {
|
void Mesh::setColor(const sf::Color &c) {
|
||||||
_color = c;
|
_color = c;
|
||||||
|
|
||||||
// change color of all mesh triangles:
|
// change color of all mesh triangles:
|
||||||
std::vector<Triangle> newTriangles;
|
std::vector<Triangle> newTriangles;
|
||||||
for(auto &t : _tris) {
|
for (auto &t : _tris) {
|
||||||
newTriangles.emplace_back(Triangle(t[0], t[1], t[2], c));
|
newTriangles.emplace_back(Triangle(t[0], t[1], t[2], c));
|
||||||
}
|
}
|
||||||
setTriangles(newTriangles);
|
setTriangles(newTriangles);
|
||||||
}
|
}
|
||||||
|
|
||||||
Mesh Mesh::LineTo(ObjectNameTag nameTag, const Vec3D& from, const Vec3D& to, double line_width, const sf::Color& color) {
|
Mesh
|
||||||
|
Mesh::LineTo(ObjectNameTag nameTag, const Vec3D &from, const Vec3D &to, double line_width, const sf::Color &color) {
|
||||||
|
|
||||||
Mesh line(std::move(nameTag));
|
Mesh line(std::move(nameTag));
|
||||||
|
|
||||||
|
@ -72,18 +74,18 @@ Mesh Mesh::LineTo(ObjectNameTag nameTag, const Vec3D& from, const Vec3D& to, dou
|
||||||
|
|
||||||
|
|
||||||
line._tris = std::move(std::vector<Triangle>{
|
line._tris = std::move(std::vector<Triangle>{
|
||||||
{ p2, p4, p1 },
|
{p2, p4, p1},
|
||||||
{ p2, p3, p4 },
|
{p2, p3, p4},
|
||||||
{ p1, p6, p2 },
|
{p1, p6, p2},
|
||||||
{ p1, p5, p6 },
|
{p1, p5, p6},
|
||||||
{ p2, p6, p7 },
|
{p2, p6, p7},
|
||||||
{ p2, p7, p3 },
|
{p2, p7, p3},
|
||||||
{ p6, p5, p8 },
|
{p6, p5, p8},
|
||||||
{ p6, p8, p7 },
|
{p6, p8, p7},
|
||||||
{ p4, p3, p7 },
|
{p4, p3, p7},
|
||||||
{ p4, p7, p8 },
|
{p4, p7, p8},
|
||||||
{ p1, p8, p5 },
|
{p1, p8, p5},
|
||||||
{ p1, p4, p8 }
|
{p1, p4, p8}
|
||||||
});
|
});
|
||||||
line.setColor(color);
|
line.setColor(color);
|
||||||
|
|
||||||
|
@ -92,7 +94,7 @@ Mesh Mesh::LineTo(ObjectNameTag nameTag, const Vec3D& from, const Vec3D& to, dou
|
||||||
|
|
||||||
void Mesh::setTriangles(const vector<Triangle> &t) {
|
void Mesh::setTriangles(const vector<Triangle> &t) {
|
||||||
_tris.clear();
|
_tris.clear();
|
||||||
for (auto & tri : t) {
|
for (auto &tri : t) {
|
||||||
_tris.push_back(tri);
|
_tris.push_back(tri);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,8 +7,10 @@
|
||||||
|
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include "Triangle.h"
|
|
||||||
#include <SFML/Graphics.hpp>
|
#include <SFML/Graphics.hpp>
|
||||||
|
|
||||||
|
#include "Triangle.h"
|
||||||
#include "Object.h"
|
#include "Object.h"
|
||||||
|
|
||||||
class Mesh : public Object {
|
class Mesh : public Object {
|
||||||
|
@ -17,33 +19,43 @@ private:
|
||||||
sf::Color _color = sf::Color(255, 245, 194);
|
sf::Color _color = sf::Color(255, 245, 194);
|
||||||
bool _visible = true;
|
bool _visible = true;
|
||||||
|
|
||||||
Mesh& operator*=(const Matrix4x4& matrix4X4);
|
Mesh &operator*=(const Matrix4x4 &matrix4X4);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit Mesh(ObjectNameTag nameTag) : Object(std::move(nameTag)) {};
|
explicit Mesh(ObjectNameTag nameTag) : Object(std::move(nameTag)) {};
|
||||||
Mesh& operator=(const Mesh& mesh) = delete;
|
|
||||||
Mesh(const Mesh& mesh) = default;
|
|
||||||
|
|
||||||
explicit Mesh(ObjectNameTag nameTag, const std::vector<Triangle>& tries);
|
Mesh &operator=(const Mesh &mesh) = delete;
|
||||||
explicit Mesh(ObjectNameTag nameTag, const std::string& filename, const Vec3D& scale = Vec3D{1, 1, 1});
|
|
||||||
|
|
||||||
void loadObj(const std::string& filename, const Vec3D& scale = Vec3D{1, 1, 1});
|
Mesh(const Mesh &mesh) = default;
|
||||||
|
|
||||||
[[nodiscard]] std::vector<Triangle>const &triangles() const { return _tris; }
|
explicit Mesh(ObjectNameTag nameTag, const std::vector<Triangle> &tries);
|
||||||
[[nodiscard]] std::vector<Triangle>& triangles() { return _tris; }
|
|
||||||
void setTriangles(const std::vector<Triangle>& t);
|
|
||||||
|
|
||||||
[[nodiscard]] int size() const { return _tris.size()*3; }
|
explicit Mesh(ObjectNameTag nameTag, const std::string &filename, const Vec3D &scale = Vec3D{1, 1, 1});
|
||||||
|
|
||||||
|
void loadObj(const std::string &filename, const Vec3D &scale = Vec3D{1, 1, 1});
|
||||||
|
|
||||||
|
[[nodiscard]] std::vector<Triangle> const &triangles() const { return _tris; }
|
||||||
|
|
||||||
|
[[nodiscard]] std::vector<Triangle> &triangles() { return _tris; }
|
||||||
|
|
||||||
|
void setTriangles(const std::vector<Triangle> &t);
|
||||||
|
|
||||||
|
[[nodiscard]] size_t size() const { return _tris.size() * 3; }
|
||||||
|
|
||||||
[[nodiscard]] sf::Color color() const { return _color; }
|
[[nodiscard]] sf::Color color() const { return _color; }
|
||||||
void setColor(const sf::Color& c);
|
|
||||||
|
void setColor(const sf::Color &c);
|
||||||
|
|
||||||
void setVisible(bool visibility) { _visible = visibility; }
|
void setVisible(bool visibility) { _visible = visibility; }
|
||||||
|
|
||||||
[[nodiscard]] bool isVisible() const { return _visible; }
|
[[nodiscard]] bool isVisible() const { return _visible; }
|
||||||
|
|
||||||
~Mesh() override;
|
~Mesh() override;
|
||||||
|
|
||||||
Mesh static Obj(ObjectNameTag nameTag, const std::string& filename);
|
Mesh static Obj(ObjectNameTag nameTag, const std::string &filename);
|
||||||
Mesh static LineTo(ObjectNameTag nameTag, const Vec3D& from, const Vec3D& to, double line_width = 0.1, const sf::Color& color = {150, 150, 150, 100});
|
|
||||||
|
Mesh static LineTo(ObjectNameTag nameTag, const Vec3D &from, const Vec3D &to, double line_width = 0.1,
|
||||||
|
const sf::Color &color = {150, 150, 150, 100});
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //INC_3DZAVR_MESH_H
|
#endif //INC_3DZAVR_MESH_H
|
||||||
|
|
|
@ -12,16 +12,17 @@ Vec2D Mouse::getMousePosition() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
Vec2D Mouse::getMouseDisplacement() const {
|
Vec2D Mouse::getMouseDisplacement() const {
|
||||||
|
// TODO: getMouseDisplacement() should return displacement from the previous position but not from the center
|
||||||
sf::Vector2<int> mousePos = sf::Mouse::getPosition(*_screen->renderWindow());
|
sf::Vector2<int> mousePos = sf::Mouse::getPosition(*_screen->renderWindow());
|
||||||
sf::Vector2<int> center = sf::Vector2<int>(_screen->width()/2, _screen->height()/2);
|
sf::Vector2<int> center = sf::Vector2<int>(_screen->width() / 2, _screen->height() / 2);
|
||||||
|
|
||||||
sf::Vector2<int> displacement = mousePos - center;
|
sf::Vector2<int> displacement = mousePos - center;
|
||||||
//setMouseInCenter();
|
|
||||||
return Vec2D(displacement.x, displacement.y);
|
return Vec2D(displacement.x, displacement.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Mouse::setMouseInCenter() const {
|
void Mouse::setMouseInCenter() const {
|
||||||
sf::Mouse::setPosition({ static_cast<int>(_screen->width() / 2), static_cast<int>(_screen->height() / 2) }, *_screen->renderWindow());
|
sf::Mouse::setPosition({static_cast<int>(_screen->width() / 2), static_cast<int>(_screen->height() / 2)},
|
||||||
|
*_screen->renderWindow());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Mouse::isButtonPressed(sf::Mouse::Button button) {
|
bool Mouse::isButtonPressed(sf::Mouse::Button button) {
|
||||||
|
@ -33,10 +34,10 @@ bool Mouse::isButtonTapped(sf::Mouse::Button button) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(_tappedButtons.count(button) == 0) {
|
if (_tappedButtons.count(button) == 0) {
|
||||||
_tappedButtons.emplace(button, Time::time());
|
_tappedButtons.emplace(button, Time::time());
|
||||||
return true;
|
return true;
|
||||||
} else if((Time::time() - _tappedButtons[button]) > Consts::TAP_DELAY) {
|
} else if ((Time::time() - _tappedButtons[button]) > Consts::TAP_DELAY) {
|
||||||
_tappedButtons[button] = Time::time();
|
_tappedButtons[button] = Time::time();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
#include "Screen.h"
|
#include "Screen.h"
|
||||||
#include "Vec2D.h"
|
#include "Vec2D.h"
|
||||||
|
|
||||||
|
@ -18,11 +19,16 @@ private:
|
||||||
public:
|
public:
|
||||||
explicit Mouse(std::shared_ptr<Screen> screen) : _screen(std::move(screen)) {};
|
explicit Mouse(std::shared_ptr<Screen> screen) : _screen(std::move(screen)) {};
|
||||||
|
|
||||||
static bool isButtonPressed(sf::Mouse::Button button); // returns true if this _button is _pressed
|
// returns true if this _button is _pressed
|
||||||
bool isButtonTapped(sf::Mouse::Button button); // returns true if this _button is tapped and 1/5 sec passed (_button bouncing problem solved)
|
static bool isButtonPressed(sf::Mouse::Button button);
|
||||||
|
|
||||||
|
// returns true if this _button is tapped and 1/5 sec passed (_button bouncing problem solved)
|
||||||
|
bool isButtonTapped(sf::Mouse::Button button);
|
||||||
|
|
||||||
[[nodiscard]] Vec2D getMousePosition() const;
|
[[nodiscard]] Vec2D getMousePosition() const;
|
||||||
|
|
||||||
[[nodiscard]] Vec2D getMouseDisplacement() const;
|
[[nodiscard]] Vec2D getMouseDisplacement() const;
|
||||||
|
|
||||||
void setMouseInCenter() const;
|
void setMouseInCenter() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -5,27 +5,28 @@
|
||||||
#include "Object.h"
|
#include "Object.h"
|
||||||
#include "Matrix4x4.h"
|
#include "Matrix4x4.h"
|
||||||
|
|
||||||
void Object::transform(const Matrix4x4& t) {
|
void Object::transform(const Matrix4x4 &t) {
|
||||||
_transformMatrix = t * _transformMatrix;
|
_transformMatrix = t * _transformMatrix;
|
||||||
|
|
||||||
for(auto &[attachedName, attachedObject] : _attachedObjects) {
|
for (auto &[attachedName, attachedObject] : _attachedObjects) {
|
||||||
if(!attachedObject.expired()) {
|
if (!attachedObject.expired()) {
|
||||||
attachedObject.lock()->transformRelativePoint(position(), t);
|
attachedObject.lock()->transformRelativePoint(position(), t);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void Object::transformRelativePoint(const Vec3D &point, const Matrix4x4& transform) {
|
|
||||||
|
void Object::transformRelativePoint(const Vec3D &point, const Matrix4x4 &transform) {
|
||||||
|
|
||||||
// translate object in new coordinate system (connected with point)
|
// translate object in new coordinate system (connected with point)
|
||||||
_transformMatrix = Matrix4x4::Translation(position() - point) * _transformMatrix;
|
_transformMatrix = Matrix4x4::Translation(position() - point) * _transformMatrix;
|
||||||
// transform object in the new coordinate system
|
// transform object in the new coordinate system
|
||||||
_transformMatrix = transform*_transformMatrix;
|
_transformMatrix = transform * _transformMatrix;
|
||||||
// translate object back in self connected coordinate system
|
// translate object back in self connected coordinate system
|
||||||
_position = _transformMatrix.w() + point;
|
_position = _transformMatrix.w() + point;
|
||||||
_transformMatrix = Matrix4x4::Translation(-_transformMatrix.w()) * _transformMatrix;
|
_transformMatrix = Matrix4x4::Translation(-_transformMatrix.w()) * _transformMatrix;
|
||||||
|
|
||||||
for(auto &[attachedName, attachedObject] : _attachedObjects) {
|
for (auto &[attachedName, attachedObject] : _attachedObjects) {
|
||||||
if(!attachedObject.expired()) {
|
if (!attachedObject.expired()) {
|
||||||
attachedObject.lock()->transformRelativePoint(point, transform);
|
attachedObject.lock()->transformRelativePoint(point, transform);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -35,8 +36,8 @@ void Object::translate(const Vec3D &dv) {
|
||||||
|
|
||||||
_position = _position + dv;
|
_position = _position + dv;
|
||||||
|
|
||||||
for(auto &[attachedName, attachedObject] : _attachedObjects) {
|
for (auto &[attachedName, attachedObject] : _attachedObjects) {
|
||||||
if(!attachedObject.expired()) {
|
if (!attachedObject.expired()) {
|
||||||
attachedObject.lock()->translate(dv);
|
attachedObject.lock()->translate(dv);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -49,7 +50,8 @@ void Object::scale(const Vec3D &s) {
|
||||||
void Object::rotate(const Vec3D &r) {
|
void Object::rotate(const Vec3D &r) {
|
||||||
_angle = _angle + r;
|
_angle = _angle + r;
|
||||||
|
|
||||||
Matrix4x4 rotationMatrix = Matrix4x4::RotationZ(r.z())*Matrix4x4::RotationY(r.y())*Matrix4x4::RotationX(r.z());
|
// TODO: when you rotate body _angle is changed only for this body but all attached objects have incorrect _angle
|
||||||
|
Matrix4x4 rotationMatrix = Matrix4x4::RotationZ(r.z()) * Matrix4x4::RotationY(r.y()) * Matrix4x4::RotationX(r.z());
|
||||||
transform(rotationMatrix);
|
transform(rotationMatrix);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -96,15 +98,15 @@ void Object::rotateToAngle(const Vec3D &v) {
|
||||||
rotate(v - _angle);
|
rotate(v - _angle);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<Object> Object::attached(const ObjectNameTag& tag) {
|
std::shared_ptr<Object> Object::attached(const ObjectNameTag &tag) {
|
||||||
if(_attachedObjects.count(tag) == 0 || _attachedObjects.find(tag)->second.expired()) {
|
if (_attachedObjects.count(tag) == 0 || _attachedObjects.find(tag)->second.expired()) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
return _attachedObjects.find(tag)->second.lock();
|
return _attachedObjects.find(tag)->second.lock();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Object::checkIfAttached(Object *obj) {
|
bool Object::checkIfAttached(Object *obj) {
|
||||||
for(const auto& [nameTag, attachedObject] : _attachedObjects) {
|
for (const auto&[nameTag, attachedObject] : _attachedObjects) {
|
||||||
if (obj == attachedObject.lock().get() || attachedObject.lock()->checkIfAttached(obj)) {
|
if (obj == attachedObject.lock().get() || attachedObject.lock()->checkIfAttached(obj)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -113,8 +115,8 @@ bool Object::checkIfAttached(Object *obj) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Object::attach(std::shared_ptr<Object> object) {
|
void Object::attach(std::shared_ptr<Object> object) {
|
||||||
if(this != object.get()) {
|
if (this != object.get()) {
|
||||||
if(!object->checkIfAttached(this)) {
|
if (!object->checkIfAttached(this)) {
|
||||||
_attachedObjects.emplace(object->name(), object);
|
_attachedObjects.emplace(object->name(), object);
|
||||||
} else {
|
} else {
|
||||||
throw std::invalid_argument{"Object::attach: You tried to create infinite recursive call chains"};
|
throw std::invalid_argument{"Object::attach: You tried to create infinite recursive call chains"};
|
||||||
|
@ -124,59 +126,59 @@ void Object::attach(std::shared_ptr<Object> object) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Object::unattach(const ObjectNameTag& tag) {
|
void Object::unattach(const ObjectNameTag &tag) {
|
||||||
_attachedObjects.erase(tag);
|
_attachedObjects.erase(tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
// OpenGL function
|
// OpenGL function
|
||||||
GLfloat* Object::glView() const {
|
GLfloat *Object::glView() const {
|
||||||
auto* v = (GLfloat*)malloc(4*4*sizeof(GLfloat));
|
auto *v = (GLfloat *) malloc(4 * 4 * sizeof(GLfloat));
|
||||||
|
|
||||||
v[0] = -(GLfloat)left().x();
|
v[0] = -(GLfloat) left().x();
|
||||||
v[4] = -(GLfloat)left().y();
|
v[4] = -(GLfloat) left().y();
|
||||||
v[8] = -(GLfloat)left().z();
|
v[8] = -(GLfloat) left().z();
|
||||||
v[12] = (GLfloat)position().dot(left());
|
v[12] = (GLfloat) position().dot(left());
|
||||||
|
|
||||||
v[1] = (GLfloat)up().x();
|
v[1] = (GLfloat) up().x();
|
||||||
v[5] = (GLfloat)up().y();
|
v[5] = (GLfloat) up().y();
|
||||||
v[9] = (GLfloat)up().z();
|
v[9] = (GLfloat) up().z();
|
||||||
v[13] = -(GLfloat)position().dot(up());
|
v[13] = -(GLfloat) position().dot(up());
|
||||||
|
|
||||||
v[2] = -(GLfloat)lookAt().x();
|
v[2] = -(GLfloat) lookAt().x();
|
||||||
v[6] = -(GLfloat)lookAt().y();
|
v[6] = -(GLfloat) lookAt().y();
|
||||||
v[10] = -(GLfloat)lookAt().z();
|
v[10] = -(GLfloat) lookAt().z();
|
||||||
v[14] = (GLfloat)position().dot(lookAt());
|
v[14] = (GLfloat) position().dot(lookAt());
|
||||||
|
|
||||||
v[3] = (GLfloat)0.0f;
|
v[3] = (GLfloat) 0.0f;
|
||||||
v[7] = (GLfloat)0.0f;
|
v[7] = (GLfloat) 0.0f;
|
||||||
v[11] = (GLfloat)0.0f;
|
v[11] = (GLfloat) 0.0f;
|
||||||
v[15] = (GLfloat)1.0f;
|
v[15] = (GLfloat) 1.0f;
|
||||||
|
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
GLfloat* Object::glModel() const {
|
GLfloat *Object::glModel() const {
|
||||||
auto* m = (GLfloat*)malloc(4*4*sizeof(GLfloat));
|
auto *m = (GLfloat *) malloc(4 * 4 * sizeof(GLfloat));
|
||||||
|
|
||||||
m[0] = (GLfloat)left().x();
|
m[0] = (GLfloat) left().x();
|
||||||
m[4] = (GLfloat)up().x();
|
m[4] = (GLfloat) up().x();
|
||||||
m[8] = (GLfloat)lookAt().x();
|
m[8] = (GLfloat) lookAt().x();
|
||||||
m[12] = (GLfloat)position().x();
|
m[12] = (GLfloat) position().x();
|
||||||
|
|
||||||
m[1] = (GLfloat)left().y();
|
m[1] = (GLfloat) left().y();
|
||||||
m[5] = (GLfloat)up().y();
|
m[5] = (GLfloat) up().y();
|
||||||
m[9] = (GLfloat)lookAt().y();
|
m[9] = (GLfloat) lookAt().y();
|
||||||
m[13] = (GLfloat)position().y();
|
m[13] = (GLfloat) position().y();
|
||||||
|
|
||||||
m[2] = (GLfloat)left().z();
|
m[2] = (GLfloat) left().z();
|
||||||
m[6] = (GLfloat)up().z();
|
m[6] = (GLfloat) up().z();
|
||||||
m[10] =(GLfloat)lookAt().z();
|
m[10] = (GLfloat) lookAt().z();
|
||||||
m[14] = (GLfloat)position().z();
|
m[14] = (GLfloat) position().z();
|
||||||
|
|
||||||
m[3] = (GLfloat)0.0f;
|
m[3] = (GLfloat) 0.0f;
|
||||||
m[7] = (GLfloat)0.0f;
|
m[7] = (GLfloat) 0.0f;
|
||||||
m[11] = (GLfloat)0.0f;
|
m[11] = (GLfloat) 0.0f;
|
||||||
m[15] = (GLfloat)1.0f;
|
m[15] = (GLfloat) 1.0f;
|
||||||
|
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,10 +6,11 @@
|
||||||
#define ENGINE_OBJECT_H
|
#define ENGINE_OBJECT_H
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
#include "Vec3D.h"
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
|
#include "Vec3D.h"
|
||||||
#include "Matrix4x4.h"
|
#include "Matrix4x4.h"
|
||||||
#include <SFML/OpenGL.hpp>
|
#include <SFML/OpenGL.hpp>
|
||||||
|
|
||||||
|
@ -18,63 +19,87 @@ private:
|
||||||
const std::string _name;
|
const std::string _name;
|
||||||
public:
|
public:
|
||||||
explicit ObjectNameTag(std::string name = "") : _name(std::move(name)) {}
|
explicit ObjectNameTag(std::string name = "") : _name(std::move(name)) {}
|
||||||
|
|
||||||
[[nodiscard]] std::string str() const { return _name; }
|
[[nodiscard]] std::string str() const { return _name; }
|
||||||
|
|
||||||
bool operator==(const ObjectNameTag& tag) const { return _name == tag._name; }
|
bool operator==(const ObjectNameTag &tag) const { return _name == tag._name; }
|
||||||
bool operator!=(const ObjectNameTag& tag) const { return _name != tag._name; }
|
|
||||||
bool operator<(const ObjectNameTag& tag) const { return _name < tag._name; }
|
bool operator!=(const ObjectNameTag &tag) const { return _name != tag._name; }
|
||||||
|
|
||||||
|
bool operator<(const ObjectNameTag &tag) const { return _name < tag._name; }
|
||||||
};
|
};
|
||||||
|
|
||||||
class Object {
|
class Object {
|
||||||
private:
|
private:
|
||||||
bool checkIfAttached(Object* obj);
|
bool checkIfAttached(Object *obj);
|
||||||
|
|
||||||
const ObjectNameTag _nameTag;
|
const ObjectNameTag _nameTag;
|
||||||
|
|
||||||
Matrix4x4 _transformMatrix = Matrix4x4::Identity();
|
Matrix4x4 _transformMatrix = Matrix4x4::Identity();
|
||||||
|
|
||||||
std::map<ObjectNameTag, std::weak_ptr<Object>> _attachedObjects;
|
std::map<ObjectNameTag, std::weak_ptr<Object>> _attachedObjects;
|
||||||
|
|
||||||
Vec3D _position {0, 0, 0};
|
Vec3D _position{0, 0, 0};
|
||||||
Vec3D _angle {0, 0, 0};
|
Vec3D _angle{0, 0, 0};
|
||||||
Vec3D _angleLeftUpLookAt{0, 0, 0};
|
Vec3D _angleLeftUpLookAt{0, 0, 0};
|
||||||
public:
|
public:
|
||||||
explicit Object(ObjectNameTag nameTag) : _nameTag(std::move(nameTag)) {};
|
explicit Object(ObjectNameTag nameTag) : _nameTag(std::move(nameTag)) {};
|
||||||
Object(const Object& object) : _nameTag(object.name()), _transformMatrix(object.model()) {};
|
|
||||||
|
Object(const Object &object) : _nameTag(object.name()), _transformMatrix(object.model()) {};
|
||||||
|
|
||||||
// TODO: implement rotations using quaternions (?)
|
// TODO: implement rotations using quaternions (?)
|
||||||
void transform(const Matrix4x4& t);
|
void transform(const Matrix4x4 &t);
|
||||||
void transformRelativePoint(const Vec3D &point, const Matrix4x4& transform);
|
|
||||||
void translate(const Vec3D& dv);
|
void transformRelativePoint(const Vec3D &point, const Matrix4x4 &transform);
|
||||||
void translateToPoint(const Vec3D& point);
|
|
||||||
void scale(const Vec3D& s);
|
void translate(const Vec3D &dv);
|
||||||
void rotate(const Vec3D& r);
|
|
||||||
void rotate(const Vec3D& v, double rv);
|
void translateToPoint(const Vec3D &point);
|
||||||
void rotateToAngle(const Vec3D& v);
|
|
||||||
void rotateRelativePoint(const Vec3D& s, const Vec3D& r);
|
void scale(const Vec3D &s);
|
||||||
void rotateRelativePoint(const Vec3D& s, const Vec3D& v, double r);
|
|
||||||
|
void rotate(const Vec3D &r);
|
||||||
|
|
||||||
|
void rotate(const Vec3D &v, double rv);
|
||||||
|
|
||||||
|
void rotateToAngle(const Vec3D &v);
|
||||||
|
|
||||||
|
void rotateRelativePoint(const Vec3D &s, const Vec3D &r);
|
||||||
|
|
||||||
|
void rotateRelativePoint(const Vec3D &s, const Vec3D &v, double r);
|
||||||
|
|
||||||
void rotateLeft(double rl);
|
void rotateLeft(double rl);
|
||||||
|
|
||||||
void rotateUp(double ru);
|
void rotateUp(double ru);
|
||||||
|
|
||||||
void rotateLookAt(double rlAt);
|
void rotateLookAt(double rlAt);
|
||||||
|
|
||||||
[[nodiscard]] Vec3D left() const { return _transformMatrix.x(); }
|
[[nodiscard]] Vec3D left() const { return _transformMatrix.x(); }
|
||||||
[[nodiscard]] Vec3D up() const { return _transformMatrix.y(); }
|
|
||||||
[[nodiscard]] Vec3D lookAt() const { return _transformMatrix.z(); }
|
[[nodiscard]] Vec3D up() const { return _transformMatrix.y(); }
|
||||||
[[nodiscard]] Vec3D position() const { return _position; }
|
|
||||||
|
[[nodiscard]] Vec3D lookAt() const { return _transformMatrix.z(); }
|
||||||
|
|
||||||
|
[[nodiscard]] Vec3D position() const { return _position; }
|
||||||
|
|
||||||
[[nodiscard]] Vec3D angle() const { return _angle; }
|
[[nodiscard]] Vec3D angle() const { return _angle; }
|
||||||
|
|
||||||
[[nodiscard]] Vec3D angleLeftUpLookAt() const { return _angleLeftUpLookAt; }
|
[[nodiscard]] Vec3D angleLeftUpLookAt() const { return _angleLeftUpLookAt; }
|
||||||
|
|
||||||
void attach(std::shared_ptr<Object> object);
|
void attach(std::shared_ptr<Object> object);
|
||||||
void unattach(const ObjectNameTag& tag);
|
|
||||||
std::shared_ptr<Object> attached(const ObjectNameTag& tag);
|
void unattach(const ObjectNameTag &tag);
|
||||||
|
|
||||||
|
std::shared_ptr<Object> attached(const ObjectNameTag &tag);
|
||||||
|
|
||||||
[[nodiscard]] ObjectNameTag name() const { return _nameTag; }
|
[[nodiscard]] ObjectNameTag name() const { return _nameTag; }
|
||||||
|
|
||||||
[[nodiscard]] Matrix4x4 model() const { return Matrix4x4::Translation(_position) * _transformMatrix; }
|
[[nodiscard]] Matrix4x4 model() const { return Matrix4x4::Translation(_position) * _transformMatrix; }
|
||||||
|
|
||||||
// OpenGL function
|
// OpenGL function
|
||||||
[[nodiscard]] GLfloat* glModel() const;
|
[[nodiscard]] GLfloat *glModel() const;
|
||||||
[[nodiscard]] GLfloat* glView() const;
|
|
||||||
|
[[nodiscard]] GLfloat *glView() const;
|
||||||
|
|
||||||
virtual ~Object();
|
virtual ~Object();
|
||||||
};
|
};
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
#include "Plane.h"
|
#include "Plane.h"
|
||||||
|
|
||||||
Plane::Plane(const Triangle& tri) : _normal(tri.norm()), _point(tri[0]) {
|
Plane::Plane(const Triangle &tri) : _normal(tri.norm()), _point(tri[0]) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Plane::Plane(const Vec3D &N, const Vec3D &P) : _normal(N.normalized()), _point(P) {
|
Plane::Plane(const Vec3D &N, const Vec3D &P) : _normal(N.normalized()), _point(P) {
|
||||||
|
@ -17,7 +17,7 @@ double Plane::distance(const Vec3D &point) const {
|
||||||
std::pair<Vec3D, double> Plane::intersection(const Vec3D &start, const Vec3D &end) const {
|
std::pair<Vec3D, double> Plane::intersection(const Vec3D &start, const Vec3D &end) const {
|
||||||
double s_dot_n = start.dot(_normal);
|
double s_dot_n = start.dot(_normal);
|
||||||
double k = (s_dot_n - _point.dot(_normal)) / (s_dot_n - end.dot(_normal));
|
double k = (s_dot_n - _point.dot(_normal)) / (s_dot_n - end.dot(_normal));
|
||||||
Vec3D res = start + (end - start)*k;
|
Vec3D res = start + (end - start) * k;
|
||||||
return std::make_pair(res, k);
|
return std::make_pair(res, k);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,7 +32,7 @@ std::vector<Triangle> Plane::clip(const Triangle &tri) const {
|
||||||
distance(Vec3D(tri[1])),
|
distance(Vec3D(tri[1])),
|
||||||
distance(Vec3D(tri[2]))};
|
distance(Vec3D(tri[2]))};
|
||||||
|
|
||||||
for(int i = 0; i < 3; i++) {
|
for (int i = 0; i < 3; i++) {
|
||||||
if (distances[i] >= 0) {
|
if (distances[i] >= 0) {
|
||||||
insidePoints.emplace_back(tri[i]);
|
insidePoints.emplace_back(tri[i]);
|
||||||
} else {
|
} else {
|
||||||
|
@ -40,7 +40,7 @@ std::vector<Triangle> Plane::clip(const Triangle &tri) const {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(insidePoints.size() == 1) {
|
if (insidePoints.size() == 1) {
|
||||||
std::pair<Vec3D, double> intersect1 = intersection(insidePoints[0], outsidePoints[0]);
|
std::pair<Vec3D, double> intersect1 = intersection(insidePoints[0], outsidePoints[0]);
|
||||||
std::pair<Vec3D, double> intersect2 = intersection(insidePoints[0], outsidePoints[1]);
|
std::pair<Vec3D, double> intersect2 = intersection(insidePoints[0], outsidePoints[1]);
|
||||||
|
|
||||||
|
@ -50,7 +50,7 @@ std::vector<Triangle> Plane::clip(const Triangle &tri) const {
|
||||||
tri.color());
|
tri.color());
|
||||||
}
|
}
|
||||||
|
|
||||||
if(insidePoints.size() == 2) {
|
if (insidePoints.size() == 2) {
|
||||||
std::pair<Vec3D, double> intersect1 = intersection(insidePoints[0], outsidePoints[0]);
|
std::pair<Vec3D, double> intersect1 = intersection(insidePoints[0], outsidePoints[0]);
|
||||||
std::pair<Vec3D, double> intersect2 = intersection(insidePoints[1], outsidePoints[0]);
|
std::pair<Vec3D, double> intersect2 = intersection(insidePoints[1], outsidePoints[0]);
|
||||||
|
|
||||||
|
@ -64,7 +64,7 @@ std::vector<Triangle> Plane::clip(const Triangle &tri) const {
|
||||||
tri.color());
|
tri.color());
|
||||||
}
|
}
|
||||||
|
|
||||||
if(insidePoints.size() == 3) {
|
if (insidePoints.size() == 3) {
|
||||||
result.emplace_back(tri);
|
result.emplace_back(tri);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,18 +14,24 @@ private:
|
||||||
const Vec3D _point;
|
const Vec3D _point;
|
||||||
public:
|
public:
|
||||||
Plane() = delete;
|
Plane() = delete;
|
||||||
Plane(const Plane& plane) = default;
|
|
||||||
// You can define plane by defining the points in 3D space
|
|
||||||
explicit Plane(const Triangle& tri);
|
|
||||||
// Or by defining normal vector and one val laying on the plane
|
|
||||||
Plane(const Vec3D& N, const Vec3D& P);
|
|
||||||
|
|
||||||
[[nodiscard]] double distance(const Vec3D& point4D) const;
|
Plane(const Plane &plane) = default;
|
||||||
|
|
||||||
|
// You can define plane by defining the points in 3D space
|
||||||
|
explicit Plane(const Triangle &tri);
|
||||||
|
|
||||||
|
// Or by defining normal vector and one val laying on the plane
|
||||||
|
Plane(const Vec3D &N, const Vec3D &P);
|
||||||
|
|
||||||
|
[[nodiscard]] double distance(const Vec3D &point4D) const;
|
||||||
|
|
||||||
// Vec4D in space where line ('start' to 'end') intersects plain with normal vector '_n' and val '_p' lays on the plane
|
// Vec4D in space where line ('start' to 'end') intersects plain with normal vector '_n' and val '_p' lays on the plane
|
||||||
[[nodiscard]] std::pair<Vec3D, double> intersection(const Vec3D& start, const Vec3D& end) const;
|
[[nodiscard]] std::pair<Vec3D, double> intersection(const Vec3D &start, const Vec3D &end) const;
|
||||||
[[nodiscard]] std::vector<Triangle> clip(const Triangle& tri) const;
|
|
||||||
|
[[nodiscard]] std::vector<Triangle> clip(const Triangle &tri) const;
|
||||||
|
|
||||||
[[nodiscard]] Vec3D N() const { return _normal; }
|
[[nodiscard]] Vec3D N() const { return _normal; }
|
||||||
|
|
||||||
[[nodiscard]] Vec3D P() const { return _point; }
|
[[nodiscard]] Vec3D P() const { return _point; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -2,14 +2,15 @@
|
||||||
// Created by Neirokan on 09.05.2020
|
// Created by Neirokan on 09.05.2020
|
||||||
//
|
//
|
||||||
|
|
||||||
#include "ResourceManager.h"
|
|
||||||
#include "utils/Log.h"
|
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
|
||||||
ResourceManager* ResourceManager::_instance = nullptr;
|
#include "ResourceManager.h"
|
||||||
|
#include "utils/Log.h"
|
||||||
|
|
||||||
|
ResourceManager *ResourceManager::_instance = nullptr;
|
||||||
bool ResourceManager::_validInstance = false;
|
bool ResourceManager::_validInstance = false;
|
||||||
|
|
||||||
|
|
||||||
|
@ -22,7 +23,7 @@ void ResourceManager::init() {
|
||||||
|
|
||||||
void ResourceManager::unloadTextures() {
|
void ResourceManager::unloadTextures() {
|
||||||
int texturesCounter = _instance->_textures.size();
|
int texturesCounter = _instance->_textures.size();
|
||||||
for (auto & _texture : _instance->_textures) {
|
for (auto &_texture : _instance->_textures) {
|
||||||
_texture.second.reset();
|
_texture.second.reset();
|
||||||
}
|
}
|
||||||
_instance->_textures.clear();
|
_instance->_textures.clear();
|
||||||
|
@ -33,17 +34,18 @@ void ResourceManager::unloadTextures() {
|
||||||
|
|
||||||
void ResourceManager::unloadSoundBuffers() {
|
void ResourceManager::unloadSoundBuffers() {
|
||||||
int soundBuffersCounter = _instance->_soundBuffers.size();
|
int soundBuffersCounter = _instance->_soundBuffers.size();
|
||||||
for (auto & _soundBuffer : _instance->_soundBuffers) {
|
for (auto &_soundBuffer : _instance->_soundBuffers) {
|
||||||
_soundBuffer.second.reset();
|
_soundBuffer.second.reset();
|
||||||
}
|
}
|
||||||
_instance->_soundBuffers.clear();
|
_instance->_soundBuffers.clear();
|
||||||
|
|
||||||
Log::log("ResourceManager::unloadSoundBuffers(): all " + std::to_string(soundBuffersCounter) + " soundBuffers was unloaded");
|
Log::log("ResourceManager::unloadSoundBuffers(): all " + std::to_string(soundBuffersCounter) +
|
||||||
|
" soundBuffers was unloaded");
|
||||||
}
|
}
|
||||||
|
|
||||||
void ResourceManager::unloadFonts() {
|
void ResourceManager::unloadFonts() {
|
||||||
int fontsCounter = _instance->_fonts.size();
|
int fontsCounter = _instance->_fonts.size();
|
||||||
for (auto & _font : _instance->_fonts) {
|
for (auto &_font : _instance->_fonts) {
|
||||||
_font.second.reset();
|
_font.second.reset();
|
||||||
}
|
}
|
||||||
_instance->_fonts.clear();
|
_instance->_fonts.clear();
|
||||||
|
@ -59,7 +61,7 @@ void ResourceManager::unloadObjects() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ResourceManager::unloadAllResources() {
|
void ResourceManager::unloadAllResources() {
|
||||||
if(!_validInstance) {
|
if (!_validInstance) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,8 +81,8 @@ void ResourceManager::free() {
|
||||||
Log::log("ResourceManager::free(): pointer to 'ResourceManager' was freed");
|
Log::log("ResourceManager::free(): pointer to 'ResourceManager' was freed");
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<sf::Texture> ResourceManager::loadTexture(const std::string& filename) {
|
std::shared_ptr<sf::Texture> ResourceManager::loadTexture(const std::string &filename) {
|
||||||
if(!_validInstance) {
|
if (!_validInstance) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -106,8 +108,8 @@ std::shared_ptr<sf::Texture> ResourceManager::loadTexture(const std::string& fil
|
||||||
return texture;
|
return texture;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<sf::SoundBuffer> ResourceManager::loadSoundBuffer(const std::string& filename) {
|
std::shared_ptr<sf::SoundBuffer> ResourceManager::loadSoundBuffer(const std::string &filename) {
|
||||||
if(!_validInstance) {
|
if (!_validInstance) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -132,8 +134,8 @@ std::shared_ptr<sf::SoundBuffer> ResourceManager::loadSoundBuffer(const std::str
|
||||||
return soundBuffer;
|
return soundBuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<sf::Font> ResourceManager::loadFont(const std::string& filename) {
|
std::shared_ptr<sf::Font> ResourceManager::loadFont(const std::string &filename) {
|
||||||
if(!_validInstance) {
|
if (!_validInstance) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -163,7 +165,7 @@ std::vector<std::shared_ptr<Mesh>> ResourceManager::loadObjects(const std::strin
|
||||||
std::vector<std::shared_ptr<Mesh>> objects{};
|
std::vector<std::shared_ptr<Mesh>> objects{};
|
||||||
std::map<std::string, sf::Color> maters{};
|
std::map<std::string, sf::Color> maters{};
|
||||||
|
|
||||||
if(!_validInstance) {
|
if (!_validInstance) {
|
||||||
return objects;
|
return objects;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -191,40 +193,39 @@ std::vector<std::shared_ptr<Mesh>> ResourceManager::loadObjects(const std::strin
|
||||||
s << line;
|
s << line;
|
||||||
|
|
||||||
char junk;
|
char junk;
|
||||||
if(line[0] == 'o') {
|
if (line[0] == 'o') {
|
||||||
if(!tris.empty())
|
if (!tris.empty())
|
||||||
objects.push_back(std::make_shared<Mesh>(ObjectNameTag(filename + "_temp_obj_" + std::to_string(objects.size())), tris));
|
objects.push_back(
|
||||||
|
std::make_shared<Mesh>(ObjectNameTag(filename + "_temp_obj_" + std::to_string(objects.size())),
|
||||||
|
tris));
|
||||||
tris.clear();
|
tris.clear();
|
||||||
}
|
}
|
||||||
if (line[0] == 'v')
|
if (line[0] == 'v') {
|
||||||
{
|
|
||||||
double x, y, z;
|
double x, y, z;
|
||||||
s >> junk >> x >> y >> z;
|
s >> junk >> x >> y >> z;
|
||||||
verts.emplace_back(x, y, z, 1.0);
|
verts.emplace_back(x, y, z, 1.0);
|
||||||
}
|
}
|
||||||
if(line[0] == 'g') {
|
if (line[0] == 'g') {
|
||||||
std::string matInfo;
|
std::string matInfo;
|
||||||
s >> junk >> matInfo;
|
s >> junk >> matInfo;
|
||||||
std::string colorName = matInfo.substr(matInfo.size()-3, 3);
|
std::string colorName = matInfo.substr(matInfo.size() - 3, 3);
|
||||||
currentColor = maters[matInfo.substr(matInfo.size()-3, 3)];
|
currentColor = maters[matInfo.substr(matInfo.size() - 3, 3)];
|
||||||
}
|
}
|
||||||
if (line[0] == 'f')
|
if (line[0] == 'f') {
|
||||||
{
|
|
||||||
int f[3];
|
int f[3];
|
||||||
s >> junk >> f[0] >> f[1] >> f[2];
|
s >> junk >> f[0] >> f[1] >> f[2];
|
||||||
tris.emplace_back(verts[f[0] - 1], verts[f[1] - 1], verts[f[2] - 1], currentColor);
|
tris.emplace_back(verts[f[0] - 1], verts[f[1] - 1], verts[f[2] - 1], currentColor);
|
||||||
}
|
}
|
||||||
if(line[0] == 'm')
|
if (line[0] == 'm') {
|
||||||
{
|
|
||||||
int color[4];
|
int color[4];
|
||||||
std::string matName;
|
std::string matName;
|
||||||
|
|
||||||
s >> junk >> matName >> color[0] >> color[1] >> color[2] >> color[3];
|
s >> junk >> matName >> color[0] >> color[1] >> color[2] >> color[3];
|
||||||
maters.insert({matName, sf::Color(color[0],color[1],color[2], color[3])});
|
maters.insert({matName, sf::Color(color[0], color[1], color[2], color[3])});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!tris.empty()) {
|
if (!tris.empty()) {
|
||||||
objects.push_back(
|
objects.push_back(
|
||||||
std::make_shared<Mesh>(ObjectNameTag(filename + "_temp_obj_" + std::to_string(objects.size())), tris));
|
std::make_shared<Mesh>(ObjectNameTag(filename + "_temp_obj_" + std::to_string(objects.size())), tris));
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,9 +5,11 @@
|
||||||
#ifndef ENGINE_RESOURCEMANAGER_H
|
#ifndef ENGINE_RESOURCEMANAGER_H
|
||||||
#define ENGINE_RESOURCEMANAGER_H
|
#define ENGINE_RESOURCEMANAGER_H
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
#include <SFML/Graphics.hpp>
|
#include <SFML/Graphics.hpp>
|
||||||
#include <SFML/Audio.hpp>
|
#include <SFML/Audio.hpp>
|
||||||
#include <memory>
|
|
||||||
#include "Mesh.h"
|
#include "Mesh.h"
|
||||||
|
|
||||||
class ResourceManager final {
|
class ResourceManager final {
|
||||||
|
@ -17,32 +19,41 @@ private:
|
||||||
std::map<std::string, std::shared_ptr<sf::SoundBuffer>> _soundBuffers;
|
std::map<std::string, std::shared_ptr<sf::SoundBuffer>> _soundBuffers;
|
||||||
std::map<std::string, std::vector<std::shared_ptr<Mesh>>> _objects;
|
std::map<std::string, std::vector<std::shared_ptr<Mesh>>> _objects;
|
||||||
|
|
||||||
static ResourceManager* _instance;
|
static ResourceManager *_instance;
|
||||||
static bool _validInstance;
|
static bool _validInstance;
|
||||||
|
|
||||||
ResourceManager() = default;
|
ResourceManager() = default;
|
||||||
|
|
||||||
// Unloads all currently loaded textures.
|
// Unloads all currently loaded textures.
|
||||||
static void unloadObjects();
|
static void unloadObjects();
|
||||||
|
|
||||||
static void unloadTextures();
|
static void unloadTextures();
|
||||||
|
|
||||||
static void unloadSoundBuffers();
|
static void unloadSoundBuffers();
|
||||||
|
|
||||||
static void unloadFonts();
|
static void unloadFonts();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ResourceManager(const ResourceManager&) = delete;
|
ResourceManager(const ResourceManager &) = delete;
|
||||||
ResourceManager& operator=(ResourceManager&) = delete;
|
|
||||||
|
ResourceManager &operator=(ResourceManager &) = delete;
|
||||||
|
|
||||||
static void unloadAllResources();
|
static void unloadAllResources();
|
||||||
|
|
||||||
static void init();
|
static void init();
|
||||||
|
|
||||||
static void free();
|
static void free();
|
||||||
|
|
||||||
// Try to load texture from file.
|
// Try to load texture from file.
|
||||||
// If success returns pointer to texture.
|
// If success returns pointer to texture.
|
||||||
// Otherwise returns nullptr.
|
// Otherwise returns nullptr.
|
||||||
static std::vector<std::shared_ptr<Mesh>> loadObjects(const std::string& filename);
|
static std::vector<std::shared_ptr<Mesh>> loadObjects(const std::string &filename);
|
||||||
static std::shared_ptr<sf::Texture> loadTexture(const std::string& filename);
|
|
||||||
static std::shared_ptr<sf::Font> loadFont(const std::string& filename);
|
static std::shared_ptr<sf::Texture> loadTexture(const std::string &filename);
|
||||||
static std::shared_ptr<sf::SoundBuffer> loadSoundBuffer(const std::string& filename);
|
|
||||||
|
static std::shared_ptr<sf::Font> loadFont(const std::string &filename);
|
||||||
|
|
||||||
|
static std::shared_ptr<sf::SoundBuffer> loadSoundBuffer(const std::string &filename);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //PSEUDO3DENGINE_RESOURCEMANAGER_H
|
#endif //PSEUDO3DENGINE_RESOURCEMANAGER_H
|
||||||
|
|
|
@ -2,16 +2,18 @@
|
||||||
// Created by Иван Ильин on 14.01.2021.
|
// Created by Иван Ильин on 14.01.2021.
|
||||||
//
|
//
|
||||||
|
|
||||||
#include "Screen.h"
|
|
||||||
#include "utils/Time.h"
|
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include "utils/Log.h"
|
|
||||||
#include "ResourceManager.h"
|
|
||||||
#include <SFML/OpenGL.hpp>
|
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
|
||||||
|
#include <SFML/OpenGL.hpp>
|
||||||
|
|
||||||
void Screen::open(int screenWidth, int screenHeight, const std::string &name, bool verticalSync, sf::Color background, sf::Uint32 style) {
|
#include "Screen.h"
|
||||||
|
#include "utils/Time.h"
|
||||||
|
#include "utils/Log.h"
|
||||||
|
#include "ResourceManager.h"
|
||||||
|
|
||||||
|
void Screen::open(int screenWidth, int screenHeight, const std::string &name, bool verticalSync, sf::Color background,
|
||||||
|
sf::Uint32 style) {
|
||||||
_title = name;
|
_title = name;
|
||||||
_w = screenWidth;
|
_w = screenWidth;
|
||||||
_h = screenHeight;
|
_h = screenHeight;
|
||||||
|
@ -46,13 +48,12 @@ void Screen::clear() {
|
||||||
_window->clear(_background);
|
_window->clear(_background);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Screen::drawTriangle(const Triangle& triangle)
|
void Screen::drawTriangle(const Triangle &triangle) {
|
||||||
{
|
|
||||||
sf::Vertex tris[3] =
|
sf::Vertex tris[3] =
|
||||||
{
|
{
|
||||||
sf::Vertex(sf::Vector2f((float)triangle[0].x(), (float)triangle[0].y()), triangle.color()),
|
sf::Vertex(sf::Vector2f((float) triangle[0].x(), (float) triangle[0].y()), triangle.color()),
|
||||||
sf::Vertex(sf::Vector2f((float)triangle[1].x(), (float)triangle[1].y()), triangle.color()),
|
sf::Vertex(sf::Vector2f((float) triangle[1].x(), (float) triangle[1].y()), triangle.color()),
|
||||||
sf::Vertex(sf::Vector2f((float)triangle[2].x(), (float)triangle[2].y()), triangle.color())
|
sf::Vertex(sf::Vector2f((float) triangle[2].x(), (float) triangle[2].y()), triangle.color())
|
||||||
};
|
};
|
||||||
|
|
||||||
_window->pushGLStates();
|
_window->pushGLStates();
|
||||||
|
@ -60,7 +61,7 @@ void Screen::drawTriangle(const Triangle& triangle)
|
||||||
_window->popGLStates();
|
_window->popGLStates();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Screen::setTitle(const std::string& title) {
|
void Screen::setTitle(const std::string &title) {
|
||||||
_title = title;
|
_title = title;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,10 +80,10 @@ void Screen::setMouseCursorVisible(bool visible) {
|
||||||
void Screen::drawTetragon(const Vec2D &p1, const Vec2D &p2, const Vec2D &p3, const Vec2D &p4, sf::Color color) {
|
void Screen::drawTetragon(const Vec2D &p1, const Vec2D &p2, const Vec2D &p3, const Vec2D &p4, sf::Color color) {
|
||||||
sf::ConvexShape polygon;
|
sf::ConvexShape polygon;
|
||||||
polygon.setPointCount(4);
|
polygon.setPointCount(4);
|
||||||
polygon.setPoint(0, sf::Vector2f((float)p1.x(), (float)p1.y()));
|
polygon.setPoint(0, sf::Vector2f((float) p1.x(), (float) p1.y()));
|
||||||
polygon.setPoint(1, sf::Vector2f((float)p2.x(), (float)p2.y()));
|
polygon.setPoint(1, sf::Vector2f((float) p2.x(), (float) p2.y()));
|
||||||
polygon.setPoint(2, sf::Vector2f((float)p3.x(), (float)p3.y()));
|
polygon.setPoint(2, sf::Vector2f((float) p3.x(), (float) p3.y()));
|
||||||
polygon.setPoint(3, sf::Vector2f((float)p4.x(), (float)p4.y()));
|
polygon.setPoint(3, sf::Vector2f((float) p4.x(), (float) p4.y()));
|
||||||
polygon.setFillColor(color);
|
polygon.setFillColor(color);
|
||||||
|
|
||||||
_window->pushGLStates();
|
_window->pushGLStates();
|
||||||
|
@ -90,7 +91,7 @@ void Screen::drawTetragon(const Vec2D &p1, const Vec2D &p2, const Vec2D &p3, con
|
||||||
_window->popGLStates();
|
_window->popGLStates();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Screen::drawText(const std::string& string, const Vec2D &position, int size, sf::Color color) {
|
void Screen::drawText(const std::string &string, const Vec2D &position, int size, sf::Color color) {
|
||||||
sf::Text text;
|
sf::Text text;
|
||||||
|
|
||||||
text.setFont(*ResourceManager::loadFont(Consts::MEDIUM_FONT));
|
text.setFont(*ResourceManager::loadFont(Consts::MEDIUM_FONT));
|
||||||
|
@ -98,7 +99,7 @@ void Screen::drawText(const std::string& string, const Vec2D &position, int size
|
||||||
text.setCharacterSize(size);
|
text.setCharacterSize(size);
|
||||||
text.setFillColor(color);
|
text.setFillColor(color);
|
||||||
text.setStyle(sf::Text::Italic);
|
text.setStyle(sf::Text::Italic);
|
||||||
text.setPosition((float)position.x(), (float)position.y());
|
text.setPosition((float) position.x(), (float) position.y());
|
||||||
|
|
||||||
text.setString(string);
|
text.setString(string);
|
||||||
|
|
||||||
|
@ -120,7 +121,7 @@ void Screen::drawText(const sf::Text &text) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// OpenGL functions
|
// OpenGL functions
|
||||||
void Screen::glDrawMesh(GLfloat* geometry, GLfloat* view, GLfloat* model, size_t count) {
|
void Screen::glDrawMesh(GLfloat *geometry, GLfloat *view, GLfloat *model, size_t count) {
|
||||||
// OpenGL:
|
// OpenGL:
|
||||||
// Make the window the active window for OpenGL calls
|
// Make the window the active window for OpenGL calls
|
||||||
_window->setActive(true);
|
_window->setActive(true);
|
||||||
|
@ -174,38 +175,38 @@ void Screen::glDrawMesh(GLfloat* geometry, GLfloat* view, GLfloat* model, size_t
|
||||||
_window->setActive(false);
|
_window->setActive(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
GLfloat* Screen::glMeshToGLfloatArray(std::shared_ptr<Mesh> mesh, const Vec3D& cameraPosition) {
|
GLfloat *Screen::glMeshToGLfloatArray(std::shared_ptr<Mesh> mesh, const Vec3D &cameraPosition) {
|
||||||
std::vector<Triangle>& triangles = mesh->triangles();
|
std::vector<Triangle> &triangles = mesh->triangles();
|
||||||
|
|
||||||
auto* geometry = (GLfloat*)malloc(7*3*triangles.size()*sizeof(GLfloat));
|
auto *geometry = (GLfloat *) malloc(7 * 3 * triangles.size() * sizeof(GLfloat));
|
||||||
|
|
||||||
for(int i = 0; i < triangles.size(); i++) {
|
for (int i = 0; i < triangles.size(); i++) {
|
||||||
|
|
||||||
int stride = 21*i;
|
int stride = 21 * i;
|
||||||
|
|
||||||
double dot[3];
|
double dot[3];
|
||||||
sf::Color ambientColor[3];
|
sf::Color ambientColor[3];
|
||||||
|
|
||||||
Triangle MTriangle = triangles[i]*mesh->model();
|
Triangle MTriangle = triangles[i] * mesh->model();
|
||||||
|
|
||||||
for(int k = 0; k < 3; k++) {
|
for (int k = 0; k < 3; k++) {
|
||||||
|
|
||||||
dot[k] = MTriangle.norm().dot((Vec3D(MTriangle[k]) - cameraPosition).normalized());
|
dot[k] = MTriangle.norm().dot((Vec3D(MTriangle[k]) - cameraPosition).normalized());
|
||||||
|
|
||||||
sf::Color color = triangles[i].color();
|
sf::Color color = triangles[i].color();
|
||||||
ambientColor[k] = sf::Color((sf::Uint8)(color.r * (0.3 * std::abs(dot[k]) + 0.7)),
|
ambientColor[k] = sf::Color((sf::Uint8) (color.r * (0.3 * std::abs(dot[k]) + 0.7)),
|
||||||
(sf::Uint8)(color.g * (0.3 * std::abs(dot[k]) + 0.7)),
|
(sf::Uint8) (color.g * (0.3 * std::abs(dot[k]) + 0.7)),
|
||||||
(sf::Uint8)(color.b * (0.3 * std::abs(dot[k]) + 0.7)),
|
(sf::Uint8) (color.b * (0.3 * std::abs(dot[k]) + 0.7)),
|
||||||
(sf::Uint8)color.a);
|
(sf::Uint8) color.a);
|
||||||
|
|
||||||
geometry[stride + 7*k + 0] = (GLfloat)MTriangle[k].x();
|
geometry[stride + 7 * k + 0] = (GLfloat) MTriangle[k].x();
|
||||||
geometry[stride + 7*k + 1] = (GLfloat)MTriangle[k].y();
|
geometry[stride + 7 * k + 1] = (GLfloat) MTriangle[k].y();
|
||||||
geometry[stride + 7*k + 2] = (GLfloat)MTriangle[k].z();
|
geometry[stride + 7 * k + 2] = (GLfloat) MTriangle[k].z();
|
||||||
|
|
||||||
geometry[stride + 7*k + 3] = (GLfloat)ambientColor[k].r/255.0f;
|
geometry[stride + 7 * k + 3] = (GLfloat) ambientColor[k].r / 255.0f;
|
||||||
geometry[stride + 7*k + 4] = (GLfloat)ambientColor[k].g/255.0f;
|
geometry[stride + 7 * k + 4] = (GLfloat) ambientColor[k].g / 255.0f;
|
||||||
geometry[stride + 7*k + 5] = (GLfloat)ambientColor[k].b/255.0f;
|
geometry[stride + 7 * k + 5] = (GLfloat) ambientColor[k].b / 255.0f;
|
||||||
geometry[stride + 7*k + 6] = (GLfloat)ambientColor[k].a/255.0f;
|
geometry[stride + 7 * k + 6] = (GLfloat) ambientColor[k].a / 255.0f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return geometry;
|
return geometry;
|
||||||
|
|
|
@ -7,9 +7,11 @@
|
||||||
|
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include "Triangle.h"
|
|
||||||
#include <SFML/Graphics.hpp>
|
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
|
#include <SFML/Graphics.hpp>
|
||||||
|
|
||||||
|
#include "Triangle.h"
|
||||||
#include "utils/Time.h"
|
#include "utils/Time.h"
|
||||||
#include "Consts.h"
|
#include "Consts.h"
|
||||||
#include "Mesh.h"
|
#include "Mesh.h"
|
||||||
|
@ -26,33 +28,44 @@ private:
|
||||||
|
|
||||||
const std::shared_ptr<sf::RenderWindow> _window = std::make_shared<sf::RenderWindow>();
|
const std::shared_ptr<sf::RenderWindow> _window = std::make_shared<sf::RenderWindow>();
|
||||||
public:
|
public:
|
||||||
void open(int screenWidth = Consts::STANDARD_SCREEN_WIDTH, int screenHeight = Consts::STANDARD_SCREEN_HEIGHT, const std::string& name = Consts::PROJECT_NAME, bool verticalSync = true, sf::Color background = Consts::BACKGROUND_COLOR, sf::Uint32 style = sf::Style::Default);
|
void open(int screenWidth = Consts::STANDARD_SCREEN_WIDTH, int screenHeight = Consts::STANDARD_SCREEN_HEIGHT,
|
||||||
|
const std::string &name = Consts::PROJECT_NAME, bool verticalSync = true,
|
||||||
|
sf::Color background = Consts::BACKGROUND_COLOR, sf::Uint32 style = sf::Style::Default);
|
||||||
|
|
||||||
void display();
|
void display();
|
||||||
|
|
||||||
void clear();
|
void clear();
|
||||||
|
|
||||||
[[nodiscard]] bool hasFocus() const { return _window->hasFocus(); }
|
[[nodiscard]] bool hasFocus() const { return _window->hasFocus(); }
|
||||||
|
|
||||||
void drawTriangle(const Triangle& triangle);
|
void drawTriangle(const Triangle &triangle);
|
||||||
void drawTetragon(const Vec2D& p1, const Vec2D& p2, const Vec2D& p3, const Vec2D& p4, sf::Color color);
|
|
||||||
void drawText(const std::string& string, const Vec2D& position, int size, sf::Color color);
|
void drawTetragon(const Vec2D &p1, const Vec2D &p2, const Vec2D &p3, const Vec2D &p4, sf::Color color);
|
||||||
void drawText(const sf::Text& text);
|
|
||||||
void drawSprite(const sf::Sprite& sprite);
|
void drawText(const std::string &string, const Vec2D &position, int size, sf::Color color);
|
||||||
|
|
||||||
|
void drawText(const sf::Text &text);
|
||||||
|
|
||||||
|
void drawSprite(const sf::Sprite &sprite);
|
||||||
|
|
||||||
|
void setTitle(const std::string &title);
|
||||||
|
|
||||||
void setTitle(const std::string& title);
|
|
||||||
[[nodiscard]] std::string title() const { return _title; };
|
[[nodiscard]] std::string title() const { return _title; };
|
||||||
|
|
||||||
bool isOpen();
|
bool isOpen();
|
||||||
|
|
||||||
[[nodiscard]] int width() const {return _window->getSize().x;}
|
[[nodiscard]] int width() const { return _window->getSize().x; }
|
||||||
[[nodiscard]] int height() const {return _window->getSize().y;}
|
|
||||||
|
[[nodiscard]] int height() const { return _window->getSize().y; }
|
||||||
|
|
||||||
void close();
|
void close();
|
||||||
|
|
||||||
void setMouseCursorVisible(bool visible);
|
void setMouseCursorVisible(bool visible);
|
||||||
|
|
||||||
// OpenGL functions
|
// OpenGL functions
|
||||||
void glDrawMesh(GLfloat* geometry, GLfloat* view, GLfloat* model, size_t count);
|
void glDrawMesh(GLfloat *geometry, GLfloat *view, GLfloat *model, size_t count);
|
||||||
static GLfloat* glMeshToGLfloatArray(std::shared_ptr<Mesh> mesh, const Vec3D& cameraPosition);
|
|
||||||
|
static GLfloat *glMeshToGLfloatArray(std::shared_ptr<Mesh> mesh, const Vec3D &cameraPosition);
|
||||||
|
|
||||||
[[nodiscard]] std::shared_ptr<sf::RenderWindow> renderWindow() { return _window; }
|
[[nodiscard]] std::shared_ptr<sf::RenderWindow> renderWindow() { return _window; }
|
||||||
};
|
};
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
#include "ResourceManager.h"
|
#include "ResourceManager.h"
|
||||||
#include "utils/Log.h"
|
#include "utils/Log.h"
|
||||||
|
|
||||||
SoundController* SoundController::_instance = nullptr;
|
SoundController *SoundController::_instance = nullptr;
|
||||||
bool SoundController::_validInstance = false;
|
bool SoundController::_validInstance = false;
|
||||||
|
|
||||||
|
|
||||||
|
@ -17,12 +17,12 @@ void SoundController::init() {
|
||||||
Log::log("SoundController::init(): sound controller was initialized");
|
Log::log("SoundController::init(): sound controller was initialized");
|
||||||
}
|
}
|
||||||
|
|
||||||
void SoundController::playSound(const SoundTag& soundTag, const std::string& filename) {
|
void SoundController::playSound(const SoundTag &soundTag, const std::string &filename) {
|
||||||
if(!_validInstance) {
|
if (!_validInstance) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(_instance->_sounds.count(soundTag) == 0) {
|
if (_instance->_sounds.count(soundTag) == 0) {
|
||||||
_instance->_sounds.emplace(soundTag, sf::Sound(*ResourceManager::loadSoundBuffer(filename)));
|
_instance->_sounds.emplace(soundTag, sf::Sound(*ResourceManager::loadSoundBuffer(filename)));
|
||||||
}
|
}
|
||||||
_instance->_sounds[soundTag].play();
|
_instance->_sounds[soundTag].play();
|
||||||
|
@ -30,36 +30,36 @@ void SoundController::playSound(const SoundTag& soundTag, const std::string& fil
|
||||||
Log::log("SoundController::playSound(): play sound '" + soundTag.str() + "'");
|
Log::log("SoundController::playSound(): play sound '" + soundTag.str() + "'");
|
||||||
}
|
}
|
||||||
|
|
||||||
void SoundController::pauseSound(const SoundTag& soundTag) {
|
void SoundController::pauseSound(const SoundTag &soundTag) {
|
||||||
if(!_validInstance) {
|
if (!_validInstance) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(_instance->_sounds.count(soundTag) > 0) {
|
if (_instance->_sounds.count(soundTag) > 0) {
|
||||||
_instance->_sounds[soundTag].pause();
|
_instance->_sounds[soundTag].pause();
|
||||||
}
|
}
|
||||||
|
|
||||||
Log::log("SoundController::pauseSound(): sound '" + soundTag.str() + "' was paused");
|
Log::log("SoundController::pauseSound(): sound '" + soundTag.str() + "' was paused");
|
||||||
}
|
}
|
||||||
|
|
||||||
void SoundController::stopSound(const SoundTag& soundTag) {
|
void SoundController::stopSound(const SoundTag &soundTag) {
|
||||||
if(!_validInstance) {
|
if (!_validInstance) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(_instance->_sounds.count(soundTag) > 0) {
|
if (_instance->_sounds.count(soundTag) > 0) {
|
||||||
_instance->_sounds[soundTag].stop();
|
_instance->_sounds[soundTag].stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
Log::log("SoundController::stopSound(): sound '" + soundTag.str() + "' was stopped");
|
Log::log("SoundController::stopSound(): sound '" + soundTag.str() + "' was stopped");
|
||||||
}
|
}
|
||||||
|
|
||||||
sf::Sound::Status SoundController::getStatus(const SoundTag& soundTag) {
|
sf::Sound::Status SoundController::getStatus(const SoundTag &soundTag) {
|
||||||
if(!_validInstance) {
|
if (!_validInstance) {
|
||||||
return sf::Sound::Status::Stopped;
|
return sf::Sound::Status::Stopped;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(_instance->_sounds.count(soundTag) > 0) {
|
if (_instance->_sounds.count(soundTag) > 0) {
|
||||||
return _instance->_sounds[soundTag].getStatus();
|
return _instance->_sounds[soundTag].getStatus();
|
||||||
} else {
|
} else {
|
||||||
return sf::Sound::Status::Stopped;
|
return sf::Sound::Status::Stopped;
|
||||||
|
@ -67,8 +67,8 @@ sf::Sound::Status SoundController::getStatus(const SoundTag& soundTag) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void SoundController::free() {
|
void SoundController::free() {
|
||||||
if(_validInstance) {
|
if (_validInstance) {
|
||||||
for(auto& [soundTag, sound] : _instance->_sounds) {
|
for (auto&[soundTag, sound] : _instance->_sounds) {
|
||||||
stopSound(soundTag);
|
stopSound(soundTag);
|
||||||
}
|
}
|
||||||
_instance->_sounds.clear();
|
_instance->_sounds.clear();
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
#include <SFML/Audio.hpp>
|
#include <SFML/Audio.hpp>
|
||||||
|
|
||||||
class SoundTag final {
|
class SoundTag final {
|
||||||
|
@ -14,31 +15,40 @@ private:
|
||||||
const std::string _name;
|
const std::string _name;
|
||||||
public:
|
public:
|
||||||
explicit SoundTag(std::string name = "") : _name(std::move(name)) {}
|
explicit SoundTag(std::string name = "") : _name(std::move(name)) {}
|
||||||
|
|
||||||
[[nodiscard]] std::string str() const { return _name; }
|
[[nodiscard]] std::string str() const { return _name; }
|
||||||
|
|
||||||
bool operator==(const SoundTag& tag) const { return _name == tag._name; }
|
bool operator==(const SoundTag &tag) const { return _name == tag._name; }
|
||||||
bool operator!=(const SoundTag& tag) const { return _name != tag._name; }
|
|
||||||
bool operator<(const SoundTag& tag) const { return _name < tag._name; }
|
bool operator!=(const SoundTag &tag) const { return _name != tag._name; }
|
||||||
|
|
||||||
|
bool operator<(const SoundTag &tag) const { return _name < tag._name; }
|
||||||
};
|
};
|
||||||
|
|
||||||
class SoundController final {
|
class SoundController final {
|
||||||
private:
|
private:
|
||||||
std::map<SoundTag, sf::Sound> _sounds;
|
std::map<SoundTag, sf::Sound> _sounds;
|
||||||
|
|
||||||
static SoundController* _instance;
|
static SoundController *_instance;
|
||||||
static bool _validInstance;
|
static bool _validInstance;
|
||||||
|
|
||||||
SoundController() = default;
|
SoundController() = default;
|
||||||
public:
|
|
||||||
SoundController(const SoundController&) = delete;
|
|
||||||
SoundController& operator=(SoundController&) = delete;
|
|
||||||
|
|
||||||
static void playSound(const SoundTag& soundTag, const std::string& filename);
|
public:
|
||||||
static void pauseSound(const SoundTag& soundTag);
|
SoundController(const SoundController &) = delete;
|
||||||
static void stopSound(const SoundTag& soundTag);
|
|
||||||
static sf::Sound::Status getStatus(const SoundTag& soundTag);
|
SoundController &operator=(SoundController &) = delete;
|
||||||
|
|
||||||
|
static void playSound(const SoundTag &soundTag, const std::string &filename);
|
||||||
|
|
||||||
|
static void pauseSound(const SoundTag &soundTag);
|
||||||
|
|
||||||
|
static void stopSound(const SoundTag &soundTag);
|
||||||
|
|
||||||
|
static sf::Sound::Status getStatus(const SoundTag &soundTag);
|
||||||
|
|
||||||
static void init();
|
static void init();
|
||||||
|
|
||||||
static void free();
|
static void free();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -5,10 +5,12 @@
|
||||||
#include "Triangle.h"
|
#include "Triangle.h"
|
||||||
#include "Consts.h"
|
#include "Consts.h"
|
||||||
|
|
||||||
Triangle::Triangle(const Vec4D& p1, const Vec4D& p2, const Vec4D& p3, sf::Color color) : _color(color), _points{p1, p2, p3} {
|
Triangle::Triangle(const Vec4D &p1, const Vec4D &p2, const Vec4D &p3, sf::Color color) : _color(color),
|
||||||
|
_points{p1, p2, p3} {
|
||||||
}
|
}
|
||||||
|
|
||||||
Triangle::Triangle(const Triangle &triangle) : _points{triangle._points[0], triangle._points[1], triangle._points[2]}, _color(triangle._color) {
|
Triangle::Triangle(const Triangle &triangle) : _points{triangle._points[0], triangle._points[1], triangle._points[2]},
|
||||||
|
_color(triangle._color) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Triangle Triangle::operator*(const Matrix4x4 &matrix4X4) const {
|
Triangle Triangle::operator*(const Matrix4x4 &matrix4X4) const {
|
||||||
|
@ -21,7 +23,7 @@ Vec3D Triangle::norm() const {
|
||||||
Vec3D v2 = Vec3D(_points[2] - _points[0]);
|
Vec3D v2 = Vec3D(_points[2] - _points[0]);
|
||||||
Vec3D crossProduct = v1.cross(v2);
|
Vec3D crossProduct = v1.cross(v2);
|
||||||
|
|
||||||
if(crossProduct.sqrAbs() > Consts::EPS) {
|
if (crossProduct.sqrAbs() > Consts::EPS) {
|
||||||
return crossProduct.normalized();
|
return crossProduct.normalized();
|
||||||
} else {
|
} else {
|
||||||
return Vec3D(0);
|
return Vec3D(0);
|
||||||
|
@ -39,7 +41,7 @@ bool Triangle::isPointInside(const Vec3D &point) const {
|
||||||
double dot2 = (point - Vec3D(_points[1])).cross(Vec3D(_points[2] - _points[1])).dot(triangleNorm);
|
double dot2 = (point - Vec3D(_points[1])).cross(Vec3D(_points[2] - _points[1])).dot(triangleNorm);
|
||||||
double dot3 = (point - Vec3D(_points[2])).cross(Vec3D(_points[0] - _points[2])).dot(triangleNorm);
|
double dot3 = (point - Vec3D(_points[2])).cross(Vec3D(_points[0] - _points[2])).dot(triangleNorm);
|
||||||
|
|
||||||
if((dot1 >= 0 && dot2 >= 0 && dot3 >= 0) || (dot1 <= 0 && dot2 <= 0 && dot3 <= 0)) {
|
if ((dot1 >= 0 && dot2 >= 0 && dot3 >= 0) || (dot1 <= 0 && dot2 <= 0 && dot3 <= 0)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -5,10 +5,11 @@
|
||||||
#ifndef ENGINE_TRIANGLE_H
|
#ifndef ENGINE_TRIANGLE_H
|
||||||
#define ENGINE_TRIANGLE_H
|
#define ENGINE_TRIANGLE_H
|
||||||
|
|
||||||
|
#include <SFML/Graphics.hpp>
|
||||||
|
|
||||||
#include "Vec4D.h"
|
#include "Vec4D.h"
|
||||||
#include "Vec3D.h"
|
#include "Vec3D.h"
|
||||||
#include "Matrix4x4.h"
|
#include "Matrix4x4.h"
|
||||||
#include <SFML/Graphics.hpp>
|
|
||||||
|
|
||||||
class Triangle final {
|
class Triangle final {
|
||||||
private:
|
private:
|
||||||
|
@ -16,21 +17,25 @@ private:
|
||||||
Vec4D _points[3];
|
Vec4D _points[3];
|
||||||
public:
|
public:
|
||||||
Triangle() : _points{Vec4D{}, Vec4D{}, Vec4D{}} {};
|
Triangle() : _points{Vec4D{}, Vec4D{}, Vec4D{}} {};
|
||||||
Triangle(const Triangle& triangle);
|
|
||||||
Triangle(const Vec4D& p1, const Vec4D& p2, const Vec4D& p3, sf::Color color = {0, 0, 0});
|
|
||||||
Triangle& operator=(const Triangle&) = default;
|
|
||||||
|
|
||||||
[[nodiscard]] Vec4D operator[] (int i) const;
|
Triangle(const Triangle &triangle);
|
||||||
|
|
||||||
|
Triangle(const Vec4D &p1, const Vec4D &p2, const Vec4D &p3, sf::Color color = {0, 0, 0});
|
||||||
|
|
||||||
|
Triangle &operator=(const Triangle &) = default;
|
||||||
|
|
||||||
|
[[nodiscard]] Vec4D operator[](int i) const;
|
||||||
|
|
||||||
[[nodiscard]] Vec3D norm() const;
|
[[nodiscard]] Vec3D norm() const;
|
||||||
|
|
||||||
// Operations with Matrix4x4
|
// Operations with Matrix4x4
|
||||||
[[nodiscard]] Triangle operator*(const Matrix4x4& matrix4X4) const;
|
[[nodiscard]] Triangle operator*(const Matrix4x4 &matrix4X4) const;
|
||||||
|
|
||||||
[[nodiscard]] bool isPointInside(const Vec3D& point) const;
|
[[nodiscard]] bool isPointInside(const Vec3D &point) const;
|
||||||
|
|
||||||
[[nodiscard]] sf::Color color() const { return _color; }
|
[[nodiscard]] sf::Color color() const { return _color; }
|
||||||
|
|
||||||
[[nodiscard]] double distance(const Vec3D& vec) const { return norm().dot(Vec3D(_points[0]) - vec); }
|
[[nodiscard]] double distance(const Vec3D &vec) const { return norm().dot(Vec3D(_points[0]) - vec); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
//
|
//
|
||||||
|
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
|
||||||
#include "Vec2D.h"
|
#include "Vec2D.h"
|
||||||
#include "Consts.h"
|
#include "Consts.h"
|
||||||
|
|
||||||
|
@ -11,7 +12,7 @@ Vec2D::Vec2D(const Vec2D &vec) {
|
||||||
_arr_point[1] = vec.y();
|
_arr_point[1] = vec.y();
|
||||||
}
|
}
|
||||||
|
|
||||||
Vec2D::Vec2D (double x, double y) {
|
Vec2D::Vec2D(double x, double y) {
|
||||||
_arr_point[0] = x;
|
_arr_point[0] = x;
|
||||||
_arr_point[1] = y;
|
_arr_point[1] = y;
|
||||||
}
|
}
|
||||||
|
@ -25,26 +26,28 @@ Vec2D Vec2D::operator-() const {
|
||||||
return Vec2D(-x(), -y());
|
return Vec2D(-x(), -y());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Vec2D::operator==(const Vec2D& vec) const {
|
bool Vec2D::operator==(const Vec2D &vec) const {
|
||||||
return (*this - vec).sqrAbs() < Consts::EPS;
|
return (*this - vec).sqrAbs() < Consts::EPS;
|
||||||
}
|
}
|
||||||
bool Vec2D::operator!=(const Vec2D& vec) const {
|
|
||||||
|
bool Vec2D::operator!=(const Vec2D &vec) const {
|
||||||
return !(*this == vec);
|
return !(*this == vec);
|
||||||
}
|
}
|
||||||
|
|
||||||
Vec2D Vec2D::operator+(const Vec2D& vec) const {
|
Vec2D Vec2D::operator+(const Vec2D &vec) const {
|
||||||
return Vec2D(x()+vec.x(), y()+vec.y());
|
return Vec2D(x() + vec.x(), y() + vec.y());
|
||||||
}
|
}
|
||||||
Vec2D Vec2D::operator-(const Vec2D& vec) const {
|
|
||||||
|
Vec2D Vec2D::operator-(const Vec2D &vec) const {
|
||||||
return Vec2D(*this) + -vec;
|
return Vec2D(*this) + -vec;
|
||||||
}
|
}
|
||||||
|
|
||||||
Vec2D Vec2D::operator*(double number) const {
|
Vec2D Vec2D::operator*(double number) const {
|
||||||
return Vec2D(x()*number, y()*number);
|
return Vec2D(x() * number, y() * number);
|
||||||
}
|
}
|
||||||
|
|
||||||
Vec2D Vec2D::operator/(double number) const {
|
Vec2D Vec2D::operator/(double number) const {
|
||||||
if(std::abs(number) > Consts::EPS) {
|
if (std::abs(number) > Consts::EPS) {
|
||||||
return Vec2D(*this) * (1.0 / number);
|
return Vec2D(*this) * (1.0 / number);
|
||||||
} else {
|
} else {
|
||||||
throw std::domain_error{"Vec2D::operator/(double number): division by zero"};
|
throw std::domain_error{"Vec2D::operator/(double number): division by zero"};
|
||||||
|
@ -53,7 +56,7 @@ Vec2D Vec2D::operator/(double number) const {
|
||||||
|
|
||||||
// Other useful methods
|
// Other useful methods
|
||||||
double Vec2D::sqrAbs() const {
|
double Vec2D::sqrAbs() const {
|
||||||
return x()*x() + y()*y();
|
return x() * x() + y() * y();
|
||||||
}
|
}
|
||||||
|
|
||||||
double Vec2D::abs() const {
|
double Vec2D::abs() const {
|
||||||
|
@ -62,13 +65,13 @@ double Vec2D::abs() const {
|
||||||
|
|
||||||
Vec2D Vec2D::normalized() const {
|
Vec2D Vec2D::normalized() const {
|
||||||
double vecAbs = abs();
|
double vecAbs = abs();
|
||||||
if(vecAbs > Consts::EPS) {
|
if (vecAbs > Consts::EPS) {
|
||||||
return Vec2D(*this) / abs();
|
return Vec2D(*this) / abs();
|
||||||
} else {
|
} else {
|
||||||
return Vec2D(0);
|
return Vec2D(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
double Vec2D::dot(const Vec2D& vec) const {
|
double Vec2D::dot(const Vec2D &vec) const {
|
||||||
return vec.x() * x() + vec.y() * y();
|
return vec.x() * x() + vec.y() * y();
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#define SHOOTER_VEC2D_H
|
#define SHOOTER_VEC2D_H
|
||||||
|
|
||||||
#include <array>
|
#include <array>
|
||||||
|
|
||||||
#include "Vec4D.h"
|
#include "Vec4D.h"
|
||||||
|
|
||||||
class Vec2D final {
|
class Vec2D final {
|
||||||
|
@ -13,11 +14,15 @@ private:
|
||||||
std::array<double, 2> _arr_point{};
|
std::array<double, 2> _arr_point{};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Vec2D () = default;
|
Vec2D() = default;
|
||||||
Vec2D (const Vec2D& vec);
|
|
||||||
explicit Vec2D (const Vec4D& point4D);
|
Vec2D(const Vec2D &vec);
|
||||||
explicit Vec2D (double x, double y = 0.0);
|
|
||||||
Vec2D& operator=(const Vec2D&) = default;
|
explicit Vec2D(const Vec4D &point4D);
|
||||||
|
|
||||||
|
explicit Vec2D(double x, double y = 0.0);
|
||||||
|
|
||||||
|
Vec2D &operator=(const Vec2D &) = default;
|
||||||
|
|
||||||
[[nodiscard]] double x() const { return _arr_point[0]; }
|
[[nodiscard]] double x() const { return _arr_point[0]; }
|
||||||
[[nodiscard]] double y() const { return _arr_point[1]; }
|
[[nodiscard]] double y() const { return _arr_point[1]; }
|
||||||
|
@ -25,13 +30,13 @@ public:
|
||||||
[[nodiscard]] Vec2D operator-() const;
|
[[nodiscard]] Vec2D operator-() const;
|
||||||
|
|
||||||
// Boolean operations
|
// Boolean operations
|
||||||
bool operator==(const Vec2D& vec) const;
|
bool operator==(const Vec2D &vec) const;
|
||||||
bool operator!=(const Vec2D& vec) const;
|
bool operator!=(const Vec2D &vec) const;
|
||||||
|
|
||||||
[[nodiscard]] Vec2D operator+(const Vec2D& vec) const;
|
[[nodiscard]] Vec2D operator+(const Vec2D &vec) const;
|
||||||
[[nodiscard]] Vec2D operator-(const Vec2D& vec) const;
|
[[nodiscard]] Vec2D operator-(const Vec2D &vec) const;
|
||||||
|
|
||||||
[[nodiscard]] double dot(const Vec2D& vec) const; // Returns dot product
|
[[nodiscard]] double dot(const Vec2D &vec) const; // Returns dot product
|
||||||
|
|
||||||
// Operations with numbers
|
// Operations with numbers
|
||||||
[[nodiscard]] Vec2D operator*(double number) const;
|
[[nodiscard]] Vec2D operator*(double number) const;
|
||||||
|
|
|
@ -2,24 +2,25 @@
|
||||||
// Created by Иван Ильин on 09.10.2021.
|
// Created by Иван Ильин on 09.10.2021.
|
||||||
//
|
//
|
||||||
|
|
||||||
#include "Vec3D.h"
|
|
||||||
#include "Consts.h"
|
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
|
||||||
|
#include "Vec3D.h"
|
||||||
|
#include "Consts.h"
|
||||||
|
|
||||||
Vec3D::Vec3D(const Vec3D &vec) {
|
Vec3D::Vec3D(const Vec3D &vec) {
|
||||||
_arr_point[0] = vec.x();
|
_arr_point[0] = vec.x();
|
||||||
_arr_point[1] = vec.y();
|
_arr_point[1] = vec.y();
|
||||||
_arr_point[2] = vec.z();
|
_arr_point[2] = vec.z();
|
||||||
}
|
}
|
||||||
|
|
||||||
Vec3D::Vec3D (const Vec4D& point4D) {
|
Vec3D::Vec3D(const Vec4D &point4D) {
|
||||||
_arr_point[0] = point4D.x();
|
_arr_point[0] = point4D.x();
|
||||||
_arr_point[1] = point4D.y();
|
_arr_point[1] = point4D.y();
|
||||||
_arr_point[2] = point4D.z();
|
_arr_point[2] = point4D.z();
|
||||||
}
|
}
|
||||||
|
|
||||||
Vec3D::Vec3D (double x, double y, double z) {
|
Vec3D::Vec3D(double x, double y, double z) {
|
||||||
_arr_point[0] = x;
|
_arr_point[0] = x;
|
||||||
_arr_point[1] = y;
|
_arr_point[1] = y;
|
||||||
_arr_point[2] = z;
|
_arr_point[2] = z;
|
||||||
|
@ -29,27 +30,29 @@ Vec3D Vec3D::operator-() const {
|
||||||
return Vec3D(-x(), -y(), -z());
|
return Vec3D(-x(), -y(), -z());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Vec3D::operator==(const Vec3D& vec) const {
|
bool Vec3D::operator==(const Vec3D &vec) const {
|
||||||
return (*this - vec).sqrAbs() < Consts::EPS;
|
return (*this - vec).sqrAbs() < Consts::EPS;
|
||||||
}
|
}
|
||||||
bool Vec3D::operator!=(const Vec3D& vec) const {
|
|
||||||
|
bool Vec3D::operator!=(const Vec3D &vec) const {
|
||||||
return !(*this == vec);
|
return !(*this == vec);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Operations with Vec3D
|
// Operations with Vec3D
|
||||||
Vec3D Vec3D::operator+(const Vec3D& vec) const {
|
Vec3D Vec3D::operator+(const Vec3D &vec) const {
|
||||||
return Vec3D(x()+vec.x(), y()+vec.y(), z()+vec.z());
|
return Vec3D(x() + vec.x(), y() + vec.y(), z() + vec.z());
|
||||||
}
|
}
|
||||||
Vec3D Vec3D::operator-(const Vec3D& vec) const {
|
|
||||||
|
Vec3D Vec3D::operator-(const Vec3D &vec) const {
|
||||||
return Vec3D(*this) + -vec;
|
return Vec3D(*this) + -vec;
|
||||||
}
|
}
|
||||||
|
|
||||||
Vec3D Vec3D::operator*(double number) const {
|
Vec3D Vec3D::operator*(double number) const {
|
||||||
return Vec3D(x()*number, y()*number, z()*number);
|
return Vec3D(x() * number, y() * number, z() * number);
|
||||||
}
|
}
|
||||||
|
|
||||||
Vec3D Vec3D::operator/(double number) const {
|
Vec3D Vec3D::operator/(double number) const {
|
||||||
if(std::abs(number) > Consts::EPS) {
|
if (std::abs(number) > Consts::EPS) {
|
||||||
return Vec3D(*this) * (1.0 / number);
|
return Vec3D(*this) * (1.0 / number);
|
||||||
} else {
|
} else {
|
||||||
throw std::domain_error{"Vec3D::operator/(double number): division by zero"};
|
throw std::domain_error{"Vec3D::operator/(double number): division by zero"};
|
||||||
|
@ -58,7 +61,7 @@ Vec3D Vec3D::operator/(double number) const {
|
||||||
|
|
||||||
// Other useful methods
|
// Other useful methods
|
||||||
double Vec3D::sqrAbs() const {
|
double Vec3D::sqrAbs() const {
|
||||||
return x()*x() + y()*y() + z()*z();
|
return x() * x() + y() * y() + z() * z();
|
||||||
}
|
}
|
||||||
|
|
||||||
double Vec3D::abs() const {
|
double Vec3D::abs() const {
|
||||||
|
@ -67,18 +70,18 @@ double Vec3D::abs() const {
|
||||||
|
|
||||||
Vec3D Vec3D::normalized() const {
|
Vec3D Vec3D::normalized() const {
|
||||||
double vecAbs = abs();
|
double vecAbs = abs();
|
||||||
if(vecAbs > Consts::EPS) {
|
if (vecAbs > Consts::EPS) {
|
||||||
return Vec3D(*this) / abs();
|
return Vec3D(*this) / abs();
|
||||||
} else {
|
} else {
|
||||||
return Vec3D(1);
|
return Vec3D(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
double Vec3D::dot(const Vec3D& vec) const {
|
double Vec3D::dot(const Vec3D &vec) const {
|
||||||
return vec.x() * x() + vec.y() * y() + vec.z() * z();
|
return vec.x() * x() + vec.y() * y() + vec.z() * z();
|
||||||
}
|
}
|
||||||
|
|
||||||
Vec3D Vec3D::cross(const Vec3D& vec) const {
|
Vec3D Vec3D::cross(const Vec3D &vec) const {
|
||||||
return Vec3D{y() * vec.z() - vec.y() * z(),
|
return Vec3D{y() * vec.z() - vec.y() * z(),
|
||||||
z() * vec.x() - vec.z() * x(),
|
z() * vec.x() - vec.z() * x(),
|
||||||
x() * vec.y() - vec.x() * y()};
|
x() * vec.y() - vec.x() * y()};
|
||||||
|
@ -89,5 +92,5 @@ Vec4D Vec3D::makePoint4D() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
Vec3D Vec3D::Random() {
|
Vec3D Vec3D::Random() {
|
||||||
return Vec3D((double)rand()/RAND_MAX, (double)rand()/RAND_MAX, (double)rand()/RAND_MAX);
|
return Vec3D((double) rand() / RAND_MAX, (double) rand() / RAND_MAX, (double) rand() / RAND_MAX);
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#define SHOOTER_VEC3D_H
|
#define SHOOTER_VEC3D_H
|
||||||
|
|
||||||
#include <array>
|
#include <array>
|
||||||
|
|
||||||
#include "Vec4D.h"
|
#include "Vec4D.h"
|
||||||
|
|
||||||
class Vec3D final {
|
class Vec3D final {
|
||||||
|
@ -13,11 +14,15 @@ private:
|
||||||
std::array<double, 3> _arr_point{};
|
std::array<double, 3> _arr_point{};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Vec3D () = default;
|
Vec3D() = default;
|
||||||
Vec3D (const Vec3D& vec);
|
|
||||||
explicit Vec3D (const Vec4D& vec);
|
Vec3D(const Vec3D &vec);
|
||||||
explicit Vec3D (double x, double y = 0.0, double z = 0.0);
|
|
||||||
Vec3D& operator=(const Vec3D&) = default;
|
explicit Vec3D(const Vec4D &vec);
|
||||||
|
|
||||||
|
explicit Vec3D(double x, double y = 0.0, double z = 0.0);
|
||||||
|
|
||||||
|
Vec3D &operator=(const Vec3D &) = default;
|
||||||
|
|
||||||
[[nodiscard]] double x() const { return _arr_point[0]; }
|
[[nodiscard]] double x() const { return _arr_point[0]; }
|
||||||
[[nodiscard]] double y() const { return _arr_point[1]; }
|
[[nodiscard]] double y() const { return _arr_point[1]; }
|
||||||
|
@ -26,15 +31,15 @@ public:
|
||||||
[[nodiscard]] Vec3D operator-() const;
|
[[nodiscard]] Vec3D operator-() const;
|
||||||
|
|
||||||
// Boolean operations
|
// Boolean operations
|
||||||
bool operator==(const Vec3D& vec) const;
|
bool operator==(const Vec3D &vec) const;
|
||||||
bool operator!=(const Vec3D& vec) const;
|
bool operator!=(const Vec3D &vec) const;
|
||||||
|
|
||||||
// Operations with Vec4D
|
// Operations with Vec4D
|
||||||
[[nodiscard]] Vec3D operator+(const Vec3D& vec) const;
|
[[nodiscard]] Vec3D operator+(const Vec3D &vec) const;
|
||||||
[[nodiscard]] Vec3D operator-(const Vec3D& vec) const;
|
[[nodiscard]] Vec3D operator-(const Vec3D &vec) const;
|
||||||
|
|
||||||
[[nodiscard]] double dot(const Vec3D& vec) const; // Returns dot product
|
[[nodiscard]] double dot(const Vec3D &vec) const; // Returns dot product
|
||||||
[[nodiscard]] Vec3D cross(const Vec3D& vec) const; // Returns cross product
|
[[nodiscard]] Vec3D cross(const Vec3D &vec) const; // Returns cross product
|
||||||
|
|
||||||
// Operations with numbers
|
// Operations with numbers
|
||||||
[[nodiscard]] Vec3D operator*(double number) const;
|
[[nodiscard]] Vec3D operator*(double number) const;
|
||||||
|
|
|
@ -2,12 +2,13 @@
|
||||||
// Created by Иван Ильин on 12.01.2021.
|
// Created by Иван Ильин on 12.01.2021.
|
||||||
//
|
//
|
||||||
|
|
||||||
#include "Vec4D.h"
|
|
||||||
#include "Consts.h"
|
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
|
||||||
Vec4D::Vec4D (double x, double y, double z, double w) {
|
#include "Vec4D.h"
|
||||||
|
#include "Consts.h"
|
||||||
|
|
||||||
|
Vec4D::Vec4D(double x, double y, double z, double w) {
|
||||||
_arr_point[0] = x;
|
_arr_point[0] = x;
|
||||||
_arr_point[1] = y;
|
_arr_point[1] = y;
|
||||||
_arr_point[2] = z;
|
_arr_point[2] = z;
|
||||||
|
@ -25,20 +26,20 @@ Vec4D::Vec4D(const Vec4D &point4D) {
|
||||||
return Vec4D(-x(), -y(), -z(), -w());
|
return Vec4D(-x(), -y(), -z(), -w());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Vec4D::operator==(const Vec4D& point4D) const {
|
bool Vec4D::operator==(const Vec4D &point4D) const {
|
||||||
return (*this - point4D).sqrAbs() < Consts::EPS;
|
return (*this - point4D).sqrAbs() < Consts::EPS;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Vec4D::operator!=(const Vec4D& point4D) const {
|
bool Vec4D::operator!=(const Vec4D &point4D) const {
|
||||||
return !(*this == point4D);
|
return !(*this == point4D);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Operations with Vec4D
|
// Operations with Vec4D
|
||||||
Vec4D Vec4D::operator+(const Vec4D& point4D) const {
|
Vec4D Vec4D::operator+(const Vec4D &point4D) const {
|
||||||
return Vec4D(x() + point4D.x(), y() + point4D.y(), z() + point4D.z(), w() + point4D.w());
|
return Vec4D(x() + point4D.x(), y() + point4D.y(), z() + point4D.z(), w() + point4D.w());
|
||||||
}
|
}
|
||||||
|
|
||||||
Vec4D Vec4D::operator-(const Vec4D& point4D) const {
|
Vec4D Vec4D::operator-(const Vec4D &point4D) const {
|
||||||
return Vec4D(*this) + -point4D;
|
return Vec4D(*this) + -point4D;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -47,7 +48,7 @@ Vec4D Vec4D::operator*(double number) const {
|
||||||
}
|
}
|
||||||
|
|
||||||
Vec4D Vec4D::operator/(double number) const {
|
Vec4D Vec4D::operator/(double number) const {
|
||||||
if(std::abs(number) > Consts::EPS) {
|
if (std::abs(number) > Consts::EPS) {
|
||||||
return Vec4D(*this) * (1.0 / number);
|
return Vec4D(*this) * (1.0 / number);
|
||||||
} else {
|
} else {
|
||||||
throw std::domain_error{"Vec4D::operator/(double number): division by zero"};
|
throw std::domain_error{"Vec4D::operator/(double number): division by zero"};
|
||||||
|
@ -56,7 +57,7 @@ Vec4D Vec4D::operator/(double number) const {
|
||||||
|
|
||||||
// Other useful methods
|
// Other useful methods
|
||||||
double Vec4D::sqrAbs() const {
|
double Vec4D::sqrAbs() const {
|
||||||
return x()*x() + y()*y() + z()*z();
|
return x() * x() + y() * y() + z() * z();
|
||||||
}
|
}
|
||||||
|
|
||||||
double Vec4D::abs() const {
|
double Vec4D::abs() const {
|
||||||
|
@ -65,7 +66,7 @@ double Vec4D::abs() const {
|
||||||
|
|
||||||
Vec4D Vec4D::normalized() const {
|
Vec4D Vec4D::normalized() const {
|
||||||
double vecAbs = abs();
|
double vecAbs = abs();
|
||||||
if(vecAbs > Consts::EPS) {
|
if (vecAbs > Consts::EPS) {
|
||||||
return Vec4D(*this) / abs();
|
return Vec4D(*this) / abs();
|
||||||
} else {
|
} else {
|
||||||
return Vec4D(1);
|
return Vec4D(1);
|
||||||
|
|
|
@ -12,11 +12,13 @@ private:
|
||||||
std::array<double, 4> _arr_point{};
|
std::array<double, 4> _arr_point{};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Vec4D () = default;
|
Vec4D() = default;
|
||||||
Vec4D (const Vec4D& point4D);
|
|
||||||
explicit Vec4D (double x, double y = 0.0, double z = 0.0, double w = 0.0);
|
|
||||||
Vec4D& operator=(const Vec4D& point4D) = default;
|
|
||||||
|
|
||||||
|
Vec4D(const Vec4D &point4D);
|
||||||
|
|
||||||
|
explicit Vec4D(double x, double y = 0.0, double z = 0.0, double w = 0.0);
|
||||||
|
|
||||||
|
Vec4D &operator=(const Vec4D &point4D) = default;
|
||||||
|
|
||||||
[[nodiscard]] double x() const { return _arr_point[0]; }
|
[[nodiscard]] double x() const { return _arr_point[0]; }
|
||||||
[[nodiscard]] double y() const { return _arr_point[1]; }
|
[[nodiscard]] double y() const { return _arr_point[1]; }
|
||||||
|
@ -26,12 +28,13 @@ public:
|
||||||
[[nodiscard]] Vec4D operator-() const;
|
[[nodiscard]] Vec4D operator-() const;
|
||||||
|
|
||||||
// Boolean operations
|
// Boolean operations
|
||||||
bool operator==(const Vec4D& point4D) const;
|
bool operator==(const Vec4D &point4D) const;
|
||||||
bool operator!=(const Vec4D& point4D) const;
|
|
||||||
|
bool operator!=(const Vec4D &point4D) const;
|
||||||
|
|
||||||
// Operations with Vec4D
|
// Operations with Vec4D
|
||||||
[[nodiscard]] Vec4D operator+(const Vec4D& point4D) const;
|
[[nodiscard]] Vec4D operator+(const Vec4D &point4D) const;
|
||||||
[[nodiscard]] Vec4D operator-(const Vec4D& point4D) const;
|
[[nodiscard]] Vec4D operator-(const Vec4D &point4D) const;
|
||||||
|
|
||||||
// Operations with numbers
|
// Operations with numbers
|
||||||
[[nodiscard]] Vec4D operator*(double number) const;
|
[[nodiscard]] Vec4D operator*(double number) const;
|
||||||
|
|
|
@ -2,29 +2,32 @@
|
||||||
// Created by Иван Ильин on 13.01.2021.
|
// Created by Иван Ильин on 13.01.2021.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
#include <sstream>
|
||||||
|
#include <cmath>
|
||||||
|
|
||||||
#include "World.h"
|
#include "World.h"
|
||||||
#include "utils/Log.h"
|
#include "utils/Log.h"
|
||||||
#include "Plane.h"
|
#include "Plane.h"
|
||||||
#include "ResourceManager.h"
|
#include "ResourceManager.h"
|
||||||
#include <sstream>
|
|
||||||
#include <cmath>
|
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
void World::addBody(std::shared_ptr<RigidBody> body) {
|
void World::addBody(std::shared_ptr<RigidBody> body) {
|
||||||
_objects.emplace(body->name(), body);
|
_objects.emplace(body->name(), body);
|
||||||
Log::log("World::addBody(): inserted body '" + body->name().str() + "' with " + std::to_string(_objects[body->name()]->triangles().size()) + " tris.");
|
Log::log("World::addBody(): inserted body '" + body->name().str() + "' with " +
|
||||||
|
std::to_string(_objects[body->name()]->triangles().size()) + " tris.");
|
||||||
}
|
}
|
||||||
|
|
||||||
void World::loadBody(const ObjectNameTag& tag, const string &filename, const Vec3D& scale) {
|
void World::loadBody(const ObjectNameTag &tag, const string &filename, const Vec3D &scale) {
|
||||||
_objects.emplace(tag, std::make_shared<RigidBody>(Mesh(tag, filename, scale)));
|
_objects.emplace(tag, std::make_shared<RigidBody>(Mesh(tag, filename, scale)));
|
||||||
Log::log("World::loadBody(): inserted body from " + filename + " with title '" + tag.str() + "' with " + std::to_string(_objects[tag]->triangles().size()) + " tris.");
|
Log::log("World::loadBody(): inserted body from " + filename + " with title '" + tag.str() + "' with " +
|
||||||
|
std::to_string(_objects[tag]->triangles().size()) + " tris.");
|
||||||
}
|
}
|
||||||
|
|
||||||
IntersectionInformation World::rayCast(const Vec3D& from, const Vec3D& to, const std::string& skipTags) {
|
IntersectionInformation World::rayCast(const Vec3D &from, const Vec3D &to, const std::string &skipTags) {
|
||||||
|
|
||||||
// make vector of tags, that we are going to escape
|
// make vector of tags, that we are going to escape
|
||||||
vector <std::string> tagsToSkip;
|
vector<std::string> tagsToSkip;
|
||||||
stringstream s(skipTags);
|
stringstream s(skipTags);
|
||||||
std::string t;
|
std::string t;
|
||||||
while (s >> t) {
|
while (s >> t) {
|
||||||
|
@ -38,27 +41,27 @@ IntersectionInformation World::rayCast(const Vec3D& from, const Vec3D& to, const
|
||||||
double minDistance = Consts::RAY_CAST_MAX_DISTANCE;
|
double minDistance = Consts::RAY_CAST_MAX_DISTANCE;
|
||||||
std::shared_ptr<RigidBody> intersectedBody = nullptr;
|
std::shared_ptr<RigidBody> intersectedBody = nullptr;
|
||||||
|
|
||||||
for(auto& [name, body] : _objects) {
|
for (auto&[name, body] : _objects) {
|
||||||
|
|
||||||
bool escapeThisBody = false;
|
bool escapeThisBody = false;
|
||||||
for (auto& escapeTag : tagsToSkip) {
|
for (auto &escapeTag : tagsToSkip) {
|
||||||
if (name.str().find(escapeTag) != std::string::npos) {
|
if (name.str().find(escapeTag) != std::string::npos) {
|
||||||
escapeThisBody = true;
|
escapeThisBody = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(escapeThisBody) {
|
if (escapeThisBody) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
for(auto& tri : body->triangles()) {
|
for (auto &tri : body->triangles()) {
|
||||||
Matrix4x4 model = body->model();
|
Matrix4x4 model = body->model();
|
||||||
Triangle tri_translated(model*tri[0], model*tri[1], model*tri[2]);
|
Triangle tri_translated(model * tri[0], model * tri[1], model * tri[2]);
|
||||||
|
|
||||||
Plane plane(tri_translated);
|
Plane plane(tri_translated);
|
||||||
auto intersection = plane.intersection(from, to);
|
auto intersection = plane.intersection(from, to);
|
||||||
double distance = (intersection.first - from).sqrAbs();
|
double distance = (intersection.first - from).sqrAbs();
|
||||||
if(intersection.second > 0 && distance < minDistance && tri_translated.isPointInside(intersection.first)) {
|
if (intersection.second > 0 && distance < minDistance && tri_translated.isPointInside(intersection.first)) {
|
||||||
minDistance = distance;
|
minDistance = distance;
|
||||||
point = intersection.first;
|
point = intersection.first;
|
||||||
triangle = tri_translated;
|
triangle = tri_translated;
|
||||||
|
@ -68,27 +71,28 @@ IntersectionInformation World::rayCast(const Vec3D& from, const Vec3D& to, const
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return IntersectionInformation{point, sqrt(minDistance), triangle, ObjectNameTag(bodyName), intersectedBody, intersected};
|
return IntersectionInformation{point, sqrt(minDistance), triangle, ObjectNameTag(bodyName), intersectedBody,
|
||||||
|
intersected};
|
||||||
}
|
}
|
||||||
|
|
||||||
void World::loadMap(const std::string& filename, const Vec3D& scale) {
|
void World::loadMap(const std::string &filename, const Vec3D &scale) {
|
||||||
auto objs = ResourceManager::loadObjects(filename);
|
auto objs = ResourceManager::loadObjects(filename);
|
||||||
for(auto & i : objs) {
|
for (auto &i : objs) {
|
||||||
std::shared_ptr<RigidBody> obj = std::make_shared<RigidBody>(*i);
|
std::shared_ptr<RigidBody> obj = std::make_shared<RigidBody>(*i);
|
||||||
addBody(obj);
|
addBody(obj);
|
||||||
obj->scale(scale);
|
obj->scale(scale);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void World::removeBody(const ObjectNameTag& tag) {
|
void World::removeBody(const ObjectNameTag &tag) {
|
||||||
if(_objects.erase(tag) > 0) {
|
if (_objects.erase(tag) > 0) {
|
||||||
Log::log("World::removeBody(): removed body '" + tag.str() + "'");
|
Log::log("World::removeBody(): removed body '" + tag.str() + "'");
|
||||||
} else {
|
} else {
|
||||||
Log::log("World::removeBody(): cannot remove body '" + tag.str() + "': body does not exist.");
|
Log::log("World::removeBody(): cannot remove body '" + tag.str() + "': body does not exist.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void World::checkCollision(const ObjectNameTag& tag) {
|
void World::checkCollision(const ObjectNameTag &tag) {
|
||||||
if (_objects[tag]->isCollision()) {
|
if (_objects[tag]->isCollision()) {
|
||||||
|
|
||||||
_objects[tag]->setInCollision(false);
|
_objects[tag]->setInCollision(false);
|
||||||
|
@ -98,7 +102,7 @@ void World::checkCollision(const ObjectNameTag& tag) {
|
||||||
ObjectNameTag name = it->first;
|
ObjectNameTag name = it->first;
|
||||||
it++;
|
it++;
|
||||||
|
|
||||||
if(name != tag) {
|
if (name != tag) {
|
||||||
std::pair<bool, Simplex> gjk = _objects[tag]->checkGJKCollision(obj);
|
std::pair<bool, Simplex> gjk = _objects[tag]->checkGJKCollision(obj);
|
||||||
if (gjk.first) {
|
if (gjk.first) {
|
||||||
if (obj->isCollider()) {
|
if (obj->isCollider()) {
|
||||||
|
@ -121,8 +125,8 @@ void World::update() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<RigidBody> World::body(const ObjectNameTag& tag) {
|
std::shared_ptr<RigidBody> World::body(const ObjectNameTag &tag) {
|
||||||
if(_objects.count(tag) == 0) {
|
if (_objects.count(tag) == 0) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
return _objects.find(tag)->second;
|
return _objects.find(tag)->second;
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#define ENGINE_WORLD_H
|
#define ENGINE_WORLD_H
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
#include "Camera.h"
|
#include "Camera.h"
|
||||||
#include "Screen.h"
|
#include "Screen.h"
|
||||||
#include "physics/RigidBody.h"
|
#include "physics/RigidBody.h"
|
||||||
|
@ -25,20 +26,25 @@ private:
|
||||||
public:
|
public:
|
||||||
World() = default;
|
World() = default;
|
||||||
|
|
||||||
void checkCollision(const ObjectNameTag& tag);
|
void checkCollision(const ObjectNameTag &tag);
|
||||||
|
|
||||||
void update();
|
void update();
|
||||||
|
|
||||||
void addBody(std::shared_ptr<RigidBody> mesh);
|
void addBody(std::shared_ptr<RigidBody> mesh);
|
||||||
std::shared_ptr<RigidBody> body(const ObjectNameTag& tag);
|
|
||||||
void removeBody(const ObjectNameTag& tag);
|
std::shared_ptr<RigidBody> body(const ObjectNameTag &tag);
|
||||||
void loadBody(const ObjectNameTag& tag, const std::string &filename, const Vec3D& scale = Vec3D{1, 1, 1});
|
|
||||||
|
void removeBody(const ObjectNameTag &tag);
|
||||||
|
|
||||||
|
void loadBody(const ObjectNameTag &tag, const std::string &filename, const Vec3D &scale = Vec3D{1, 1, 1});
|
||||||
|
|
||||||
// std::string skipTags is a string that consist of all objects we want to skip in ray casting
|
// std::string skipTags is a string that consist of all objects we want to skip in ray casting
|
||||||
IntersectionInformation rayCast(const Vec3D& from, const Vec3D& to, const std::string& skipTags = "");
|
IntersectionInformation rayCast(const Vec3D &from, const Vec3D &to, const std::string &skipTags = "");
|
||||||
|
|
||||||
void loadMap(const std::string& filename, const Vec3D & scale = Vec3D{1, 1, 1});
|
void loadMap(const std::string &filename, const Vec3D &scale = Vec3D{1, 1, 1});
|
||||||
|
|
||||||
std::map<ObjectNameTag, std::shared_ptr<RigidBody>>::iterator begin() { return _objects.begin(); }
|
std::map<ObjectNameTag, std::shared_ptr<RigidBody>>::iterator begin() { return _objects.begin(); }
|
||||||
|
|
||||||
std::map<ObjectNameTag, std::shared_ptr<RigidBody>>::iterator end() { return _objects.end(); }
|
std::map<ObjectNameTag, std::shared_ptr<RigidBody>>::iterator end() { return _objects.end(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -19,12 +19,12 @@ private:
|
||||||
bool _started = false;
|
bool _started = false;
|
||||||
|
|
||||||
void update() override {
|
void update() override {
|
||||||
if(_mesh.expired()) {
|
if (_mesh.expired()) {
|
||||||
stop();
|
stop();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!_started) {
|
if (!_started) {
|
||||||
_started = true;
|
_started = true;
|
||||||
_startColor = _mesh.lock()->color();
|
_startColor = _mesh.lock()->color();
|
||||||
}
|
}
|
||||||
|
@ -33,10 +33,15 @@ private:
|
||||||
Vec4D end(_newColor.r, _newColor.g, _newColor.b, _newColor.a);
|
Vec4D end(_newColor.r, _newColor.g, _newColor.b, _newColor.a);
|
||||||
Vec4D mid = start + (end - start) * progress();
|
Vec4D mid = start + (end - start) * progress();
|
||||||
|
|
||||||
_mesh.lock()->setColor(sf::Color(static_cast<sf::Uint8>(mid.x()), static_cast<sf::Uint8>(mid.y()), static_cast<sf::Uint8>(mid.z()), static_cast<sf::Uint8>(mid.w())));
|
_mesh.lock()->setColor(sf::Color(static_cast<sf::Uint8>(mid.x()), static_cast<sf::Uint8>(mid.y()),
|
||||||
|
static_cast<sf::Uint8>(mid.z()), static_cast<sf::Uint8>(mid.w())));
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
AColor(std::weak_ptr<Mesh> mesh, const sf::Color &color, double duration = 1, LoopOut looped = LoopOut::None, InterpolationType interpolationType = InterpolationType::Linear) : Animation(duration, looped, interpolationType), _mesh(std::move(mesh)), _newColor(color) {
|
AColor(std::weak_ptr<Mesh> mesh, const sf::Color &color, double duration = 1, LoopOut looped = LoopOut::None,
|
||||||
|
InterpolationType interpolationType = InterpolationType::Linear) : Animation(duration, looped,
|
||||||
|
interpolationType),
|
||||||
|
_mesh(std::move(mesh)), _newColor(color) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#define ENGINE_AFUNCTION_H
|
#define ENGINE_AFUNCTION_H
|
||||||
|
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
#include "Animation.h"
|
#include "Animation.h"
|
||||||
|
|
||||||
class AFunction final : public Animation {
|
class AFunction final : public Animation {
|
||||||
|
@ -15,14 +16,16 @@ private:
|
||||||
const std::function<void()> _callBack;
|
const std::function<void()> _callBack;
|
||||||
|
|
||||||
void update() override {
|
void update() override {
|
||||||
if(_allCalls != 0 && progress() >= (double)(_callsCounter + 1) / (_allCalls + 1)) {
|
if (_allCalls != 0 && progress() >= (double) (_callsCounter + 1) / (_allCalls + 1)) {
|
||||||
_callsCounter++;
|
_callsCounter++;
|
||||||
_callBack();
|
_callBack();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit AFunction(std::function<void()> function, int calls = 1, double duration = 1, LoopOut looped = LoopOut::None, InterpolationType interpolationType = InterpolationType::Linear) : Animation(duration, looped, interpolationType), _callBack(std::move(function)), _allCalls(calls) {
|
explicit AFunction(std::function<void()> function, int calls = 1, double duration = 1,
|
||||||
|
LoopOut looped = LoopOut::None, InterpolationType interpolationType = InterpolationType::Linear)
|
||||||
|
: Animation(duration, looped, interpolationType), _callBack(std::move(function)), _allCalls(calls) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -16,15 +16,18 @@ private:
|
||||||
const Vec3D _rotationValue;
|
const Vec3D _rotationValue;
|
||||||
|
|
||||||
void update() override {
|
void update() override {
|
||||||
if(_object.expired()) {
|
if (_object.expired()) {
|
||||||
stop();
|
stop();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_object.lock()->rotate(_rotationValue * dprogress());
|
_object.lock()->rotate(_rotationValue * dprogress());
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ARotate(std::weak_ptr<Object> object, const Vec3D& r, double duration = 1, LoopOut looped = LoopOut::None, InterpolationType interpolationType = InterpolationType::Bezier) : Animation(duration, looped, interpolationType), _object(std::move(object)), _rotationValue(r) {
|
ARotate(std::weak_ptr<Object> object, const Vec3D &r, double duration = 1, LoopOut looped = LoopOut::None,
|
||||||
|
InterpolationType interpolationType = InterpolationType::Bezier)
|
||||||
|
: Animation(duration, looped, interpolationType), _object(std::move(object)), _rotationValue(r) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -16,20 +16,25 @@ private:
|
||||||
const Vec3D _scalingValue;
|
const Vec3D _scalingValue;
|
||||||
|
|
||||||
void update() override {
|
void update() override {
|
||||||
if(_object.expired()) {
|
if (_object.expired()) {
|
||||||
stop();
|
stop();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<Triangle> newTriangles;
|
std::vector<Triangle> newTriangles;
|
||||||
for(auto &t : _object->triangles()) {
|
for (auto &t : _object->triangles()) {
|
||||||
newTriangles.emplace_back(t * Matrix4x4::Scale(Vec3D{1, 1, 1} + (_scalingValue - Vec3D{1, 1, 1}) * progress()));
|
newTriangles.emplace_back(
|
||||||
|
t * Matrix4x4::Scale(Vec3D{1, 1, 1} + (_scalingValue - Vec3D{1, 1, 1}) * progress()));
|
||||||
}
|
}
|
||||||
_object.lock()->setTriangles(newTriangles);
|
_object.lock()->setTriangles(newTriangles);
|
||||||
return updateState();
|
return updateState();
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
AScale(std::weak_ptr<RigidBody> object, const Vec3D &s, double duration = 1, LoopOut looped = LoopOut::None, InterpolationType interpolationType = InterpolationType::Bezier) : Animation(duration, looped, interpolationType), _object(object), _scalingValue(s) {
|
AScale(std::weak_ptr<RigidBody> object, const Vec3D &s, double duration = 1, LoopOut looped = LoopOut::None,
|
||||||
|
InterpolationType interpolationType = InterpolationType::Bezier) : Animation(duration, looped,
|
||||||
|
interpolationType),
|
||||||
|
_object(object), _scalingValue(s) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -16,15 +16,20 @@ private:
|
||||||
const Vec3D _translationValue;
|
const Vec3D _translationValue;
|
||||||
|
|
||||||
void update() override {
|
void update() override {
|
||||||
if(_object.expired()) {
|
if (_object.expired()) {
|
||||||
stop();
|
stop();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_object.lock()->translate(_translationValue * dprogress());
|
_object.lock()->translate(_translationValue * dprogress());
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ATranslate(std::weak_ptr<Object> object, const Vec3D& t, double duration = 1, LoopOut looped = LoopOut::None, InterpolationType interpolationType = InterpolationType::Bezier) : Animation(duration, looped, interpolationType), _object(std::move(object)), _translationValue(t){
|
ATranslate(std::weak_ptr<Object> object, const Vec3D &t, double duration = 1, LoopOut looped = LoopOut::None,
|
||||||
|
InterpolationType interpolationType = InterpolationType::Bezier) : Animation(duration, looped,
|
||||||
|
interpolationType),
|
||||||
|
_object(std::move(object)),
|
||||||
|
_translationValue(t) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -19,19 +19,22 @@ private:
|
||||||
bool _started = false;
|
bool _started = false;
|
||||||
|
|
||||||
void update() override {
|
void update() override {
|
||||||
if(_object.expired()) {
|
if (_object.expired()) {
|
||||||
stop();
|
stop();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!_started) {
|
if (!_started) {
|
||||||
_started = true;
|
_started = true;
|
||||||
_translationValue = _targetPoint - _object.lock()->position();
|
_translationValue = _targetPoint - _object.lock()->position();
|
||||||
}
|
}
|
||||||
_object.lock()->translate(_translationValue * dprogress());
|
_object.lock()->translate(_translationValue * dprogress());
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ATranslateToPoint(std::weak_ptr<Object> object, const Vec3D& p, double duration = 1, LoopOut looped = LoopOut::None, InterpolationType interpolationType = InterpolationType::Bezier) : Animation(duration, looped, interpolationType), _targetPoint(p), _object(object) {
|
ATranslateToPoint(std::weak_ptr<Object> object, const Vec3D &p, double duration = 1, LoopOut looped = LoopOut::None,
|
||||||
|
InterpolationType interpolationType = InterpolationType::Bezier)
|
||||||
|
: Animation(duration, looped, interpolationType), _targetPoint(p), _object(object) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,8 @@
|
||||||
|
|
||||||
class AWait final : public Animation {
|
class AWait final : public Animation {
|
||||||
private:
|
private:
|
||||||
void update() override{}
|
void update() override {}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit AWait(double duration = 1) : Animation(duration, LoopOut::None, InterpolationType::Linear, true) {
|
explicit AWait(double duration = 1) : Animation(duration, LoopOut::None, InterpolationType::Linear, true) {
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,19 +4,21 @@
|
||||||
|
|
||||||
#include "Animation.h"
|
#include "Animation.h"
|
||||||
|
|
||||||
Animation::Animation(double duration, Animation::LoopOut looped, Animation::InterpolationType intType, bool waitFor) : _duration(duration), _looped(looped), _intType(intType), _waitFor(waitFor) {
|
Animation::Animation(double duration, Animation::LoopOut looped, Animation::InterpolationType intType, bool waitFor)
|
||||||
|
: _duration(duration), _looped(looped), _intType(intType), _waitFor(waitFor) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Animation::updateState() {
|
bool Animation::updateState() {
|
||||||
if(_finished || std::abs(_duration) < Consts::EPS) {
|
if (_finished || std::abs(_duration) < Consts::EPS) {
|
||||||
|
_finished = true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// linear normalized time:
|
// linear normalized time:
|
||||||
_dtime = Time::deltaTime()/_duration;
|
_dtime = Time::deltaTime() / _duration;
|
||||||
_time += _dtime;
|
_time += _dtime;
|
||||||
|
|
||||||
if(_looped == LoopOut::Continue && _time > 0.5) {
|
if (_looped == LoopOut::Continue && _time > 0.5) {
|
||||||
_time = 0.5;
|
_time = 0.5;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,7 +40,8 @@ bool Animation::updateState() {
|
||||||
_dprogress = Interpolation::dCos(_time, _dtime);
|
_dprogress = Interpolation::dCos(_time, _dtime);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw std::logic_error{"Animation::updateState: unknown interpolation type " + std::to_string(static_cast<int>(_intType))};
|
throw std::logic_error{
|
||||||
|
"Animation::updateState: unknown interpolation type " + std::to_string(static_cast<int>(_intType))};
|
||||||
}
|
}
|
||||||
|
|
||||||
update();
|
update();
|
||||||
|
|
|
@ -41,8 +41,10 @@ private:
|
||||||
|
|
||||||
// You should override this method for your particular animation
|
// You should override this method for your particular animation
|
||||||
virtual void update() = 0;
|
virtual void update() = 0;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Animation(double duration, LoopOut looped, InterpolationType intType, bool _waitFor = false);
|
Animation(double duration, LoopOut looped, InterpolationType intType, bool _waitFor = false);
|
||||||
|
|
||||||
virtual ~Animation() = default;
|
virtual ~Animation() = default;
|
||||||
|
|
||||||
[[nodiscard]] bool waitFor() const { return _waitFor; }
|
[[nodiscard]] bool waitFor() const { return _waitFor; }
|
||||||
|
@ -50,8 +52,10 @@ public:
|
||||||
bool updateState();
|
bool updateState();
|
||||||
|
|
||||||
[[nodiscard]] double progress() const { return _progress; }
|
[[nodiscard]] double progress() const { return _progress; }
|
||||||
|
|
||||||
[[nodiscard]] double dprogress() const { return _dprogress; }
|
[[nodiscard]] double dprogress() const { return _dprogress; }
|
||||||
void stop() { _finished = true;}
|
|
||||||
|
void stop() { _finished = true; }
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //INC_3DZAVR_ANIMATION_H
|
#endif //INC_3DZAVR_ANIMATION_H
|
||||||
|
|
|
@ -5,31 +5,37 @@
|
||||||
#ifndef ENGINE_INTERPOLATION_H
|
#ifndef ENGINE_INTERPOLATION_H
|
||||||
#define ENGINE_INTERPOLATION_H
|
#define ENGINE_INTERPOLATION_H
|
||||||
|
|
||||||
#include "../Vec2D.h"
|
|
||||||
|
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
|
||||||
|
#include "../Vec2D.h"
|
||||||
#include "../Consts.h"
|
#include "../Consts.h"
|
||||||
|
|
||||||
namespace Interpolation {
|
namespace Interpolation {
|
||||||
static double Linear(double t);
|
static double Linear(double t);
|
||||||
|
|
||||||
static double Cos(double t);
|
static double Cos(double t);
|
||||||
static double Bezier(const Vec2D& p1, const Vec2D& p2, double t);
|
|
||||||
|
static double Bezier(const Vec2D &p1, const Vec2D &p2, double t);
|
||||||
|
|
||||||
static double Bouncing(double t);
|
static double Bouncing(double t);
|
||||||
|
|
||||||
static double dLinear(double t, double dt);
|
static double dLinear(double t, double dt);
|
||||||
|
|
||||||
static double dCos(double t, double dt);
|
static double dCos(double t, double dt);
|
||||||
static double dBezier(const Vec2D& p1, const Vec2D& p2, double t, double dt);
|
|
||||||
|
static double dBezier(const Vec2D &p1, const Vec2D &p2, double t, double dt);
|
||||||
|
|
||||||
static double dBouncing(double t, double dt);
|
static double dBouncing(double t, double dt);
|
||||||
};
|
};
|
||||||
|
|
||||||
double Interpolation::Linear(double t) {
|
double Interpolation::Linear(double t) {
|
||||||
if(t < 0)
|
if (t < 0)
|
||||||
t = -t;
|
t = -t;
|
||||||
return ((int)trunc(t) % 2) ? 1.0 - (t-trunc(t)) : (t-trunc(t));
|
return ((int) trunc(t) % 2) ? 1.0 - (t - trunc(t)) : (t - trunc(t));
|
||||||
}
|
}
|
||||||
|
|
||||||
double Interpolation::Cos(double t) {
|
double Interpolation::Cos(double t) {
|
||||||
return 0.5*(1 - cos(Consts::PI*Interpolation::Linear(t)));
|
return 0.5 * (1 - cos(Consts::PI * Interpolation::Linear(t)));
|
||||||
}
|
}
|
||||||
|
|
||||||
double Interpolation::Bezier(const Vec2D &p1, const Vec2D &p2, double t) {
|
double Interpolation::Bezier(const Vec2D &p1, const Vec2D &p2, double t) {
|
||||||
|
@ -40,23 +46,23 @@ double Interpolation::Bezier(const Vec2D &p1, const Vec2D &p2, double t) {
|
||||||
double eps = Consts::EPS;
|
double eps = Consts::EPS;
|
||||||
|
|
||||||
// We are trying to find 's' when px = t
|
// We are trying to find 's' when px = t
|
||||||
auto f = [=](double s){
|
auto f = [=](double s) {
|
||||||
return 3.0*(1.0-s)*(1.0-s)*s*p1.x() + 3.0*(1.0-s)*s*s*p2.x() + s*s*s - t;
|
return 3.0 * (1.0 - s) * (1.0 - s) * s * p1.x() + 3.0 * (1.0 - s) * s * s * p2.x() + s * s * s - t;
|
||||||
};
|
};
|
||||||
// Using found 's' we will calculate resulting py
|
// Using found 's' we will calculate resulting py
|
||||||
auto py = [=](double s){
|
auto py = [=](double s) {
|
||||||
return 3.0*(1.0-s)*(1.0-s)*s*p1.y() + 3.0*(1.0-s)*s*s*p2.y() + s*s*s;
|
return 3.0 * (1.0 - s) * (1.0 - s) * s * p1.y() + 3.0 * (1.0 - s) * s * s * p2.y() + s * s * s;
|
||||||
};
|
};
|
||||||
|
|
||||||
auto df = [=](double s){
|
auto df = [=](double s) {
|
||||||
return (f(s+h) - f(s-h))/(2.0*h);
|
return (f(s + h) - f(s - h)) / (2.0 * h);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Newton method
|
// Newton method
|
||||||
double s1 = 0.0, s2 = 0.5;
|
double s1 = 0.0, s2 = 0.5;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
while(std::abs(s1 - s2) > eps) {
|
while (std::abs(s1 - s2) > eps) {
|
||||||
s1 = s2;
|
s1 = s2;
|
||||||
s2 = s1 - f(s1) / df(s1);
|
s2 = s1 - f(s1) / df(s1);
|
||||||
i++;
|
i++;
|
||||||
|
@ -67,15 +73,16 @@ double Interpolation::Bezier(const Vec2D &p1, const Vec2D &p2, double t) {
|
||||||
|
|
||||||
double Interpolation::Bouncing(double t) {
|
double Interpolation::Bouncing(double t) {
|
||||||
t = Interpolation::Linear(t);
|
t = Interpolation::Linear(t);
|
||||||
return 0.5*(1.0/(1.0 + exp(10.0*(-4.0*t+0.8))) + (1.0 + 2.5*sin(50.0*(t - 1.0/3.0))*exp(-7.0*t))/(1.0+exp(10.0*(-15.0*t + 3.1))));
|
return 0.5 * (1.0 / (1.0 + exp(10.0 * (-4.0 * t + 0.8))) +
|
||||||
|
(1.0 + 2.5 * sin(50.0 * (t - 1.0 / 3.0)) * exp(-7.0 * t)) / (1.0 + exp(10.0 * (-15.0 * t + 3.1))));
|
||||||
}
|
}
|
||||||
|
|
||||||
double Interpolation::dLinear(double t, double dt) {
|
double Interpolation::dLinear(double t, double dt) {
|
||||||
return ((int)trunc(t) % 2) ? -dt : dt;
|
return ((int) trunc(t) % 2) ? -dt : dt;
|
||||||
}
|
}
|
||||||
|
|
||||||
double Interpolation::dCos(double t, double dt) {
|
double Interpolation::dCos(double t, double dt) {
|
||||||
return 0.5*Consts::PI*sin(Consts::PI*t)*dt;
|
return 0.5 * Consts::PI * sin(Consts::PI * t) * dt;
|
||||||
}
|
}
|
||||||
|
|
||||||
double Interpolation::dBezier(const Vec2D &p1, const Vec2D &p2, double t, double dt) {
|
double Interpolation::dBezier(const Vec2D &p1, const Vec2D &p2, double t, double dt) {
|
||||||
|
|
|
@ -3,12 +3,12 @@
|
||||||
//
|
//
|
||||||
|
|
||||||
#include <list>
|
#include <list>
|
||||||
|
|
||||||
#include "Animation.h"
|
#include "Animation.h"
|
||||||
#include "Timeline.h"
|
#include "Timeline.h"
|
||||||
#include <iostream>
|
|
||||||
#include "../utils/Log.h"
|
#include "../utils/Log.h"
|
||||||
|
|
||||||
Timeline* Timeline::_instance = nullptr;
|
Timeline *Timeline::_instance = nullptr;
|
||||||
bool Timeline::_validInstance = false;
|
bool Timeline::_validInstance = false;
|
||||||
|
|
||||||
void Timeline::init() {
|
void Timeline::init() {
|
||||||
|
@ -18,8 +18,8 @@ void Timeline::init() {
|
||||||
Log::log("Timeline::init(): animation timeline was initialized");
|
Log::log("Timeline::init(): animation timeline was initialized");
|
||||||
}
|
}
|
||||||
|
|
||||||
void Timeline::animate(const AnimationListTag& listName, std::shared_ptr<Animation> anim) {
|
void Timeline::animate(const AnimationListTag &listName, std::shared_ptr<Animation> anim) {
|
||||||
if(!_validInstance) {
|
if (!_validInstance) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,23 +29,23 @@ void Timeline::animate(const AnimationListTag& listName, std::shared_ptr<Animati
|
||||||
}
|
}
|
||||||
|
|
||||||
void Timeline::deleteAllAnimations() {
|
void Timeline::deleteAllAnimations() {
|
||||||
if(!_validInstance) {
|
if (!_validInstance) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int animCounter = 0;
|
int animCounter = 0;
|
||||||
|
|
||||||
for (auto& [listName, animationList] : _instance->_animations) {
|
for (auto&[listName, animationList] : _instance->_animations) {
|
||||||
animCounter += animationList.size();
|
animCounter += animationList.size();
|
||||||
animationList.clear();
|
animationList.clear();
|
||||||
}
|
}
|
||||||
_instance->_animations.clear();
|
_instance->_animations.clear();
|
||||||
|
|
||||||
Log::log("Timeline::deleteAllAnimations(): all " + std::to_string(animCounter) + " animations was deleted" );
|
Log::log("Timeline::deleteAllAnimations(): all " + std::to_string(animCounter) + " animations was deleted");
|
||||||
}
|
}
|
||||||
|
|
||||||
void Timeline::deleteAnimationList(const AnimationListTag& listName) {
|
void Timeline::deleteAnimationList(const AnimationListTag &listName) {
|
||||||
if(!_validInstance) {
|
if (!_validInstance) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,11 +53,12 @@ void Timeline::deleteAnimationList(const AnimationListTag& listName) {
|
||||||
_instance->_animations[listName].clear();
|
_instance->_animations[listName].clear();
|
||||||
_instance->_animations.erase(listName);
|
_instance->_animations.erase(listName);
|
||||||
|
|
||||||
Log::log("Timeline::deleteAnimationList(): list '" + listName.str() +"' with " + std::to_string(animCounter) + " animations was deleted" );
|
Log::log("Timeline::deleteAnimationList(): list '" + listName.str() + "' with " + std::to_string(animCounter) +
|
||||||
|
" animations was deleted");
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] bool Timeline::isInAnimList(const AnimationListTag& listName) {
|
[[nodiscard]] bool Timeline::isInAnimList(const AnimationListTag &listName) {
|
||||||
if(!_validInstance) {
|
if (!_validInstance) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -65,11 +66,11 @@ void Timeline::deleteAnimationList(const AnimationListTag& listName) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Timeline::update() {
|
void Timeline::update() {
|
||||||
if(!_validInstance) {
|
if (!_validInstance) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto& [listName, animationList] : _instance->_animations) {
|
for (auto&[listName, animationList] : _instance->_animations) {
|
||||||
if (animationList.empty()) {
|
if (animationList.empty()) {
|
||||||
_instance->_animations.erase(listName);
|
_instance->_animations.erase(listName);
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -12,34 +12,42 @@ private:
|
||||||
const std::string _name;
|
const std::string _name;
|
||||||
public:
|
public:
|
||||||
explicit AnimationListTag(std::string name = "") : _name(std::move(name)) {}
|
explicit AnimationListTag(std::string name = "") : _name(std::move(name)) {}
|
||||||
|
|
||||||
[[nodiscard]] std::string str() const { return _name; }
|
[[nodiscard]] std::string str() const { return _name; }
|
||||||
|
|
||||||
bool operator==(const AnimationListTag& tag) const { return _name == tag._name; }
|
bool operator==(const AnimationListTag &tag) const { return _name == tag._name; }
|
||||||
bool operator!=(const AnimationListTag& tag) const { return _name != tag._name; }
|
|
||||||
bool operator<(const AnimationListTag& tag) const { return _name < tag._name; }
|
bool operator!=(const AnimationListTag &tag) const { return _name != tag._name; }
|
||||||
|
|
||||||
|
bool operator<(const AnimationListTag &tag) const { return _name < tag._name; }
|
||||||
};
|
};
|
||||||
|
|
||||||
class Timeline {
|
class Timeline {
|
||||||
private:
|
private:
|
||||||
std::map<AnimationListTag, std::list<std::shared_ptr<Animation>>> _animations;
|
std::map<AnimationListTag, std::list<std::shared_ptr<Animation>>> _animations;
|
||||||
|
|
||||||
static Timeline* _instance;
|
static Timeline *_instance;
|
||||||
static bool _validInstance;
|
static bool _validInstance;
|
||||||
|
|
||||||
Timeline() = default;
|
Timeline() = default;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Timeline(const Timeline&) = delete;
|
Timeline(const Timeline &) = delete;
|
||||||
Timeline& operator=(Timeline&) = delete;
|
|
||||||
|
Timeline &operator=(Timeline &) = delete;
|
||||||
|
|
||||||
static void update();
|
static void update();
|
||||||
static void animate(const AnimationListTag& listName, std::shared_ptr<Animation> anim);
|
|
||||||
|
static void animate(const AnimationListTag &listName, std::shared_ptr<Animation> anim);
|
||||||
|
|
||||||
static void deleteAllAnimations();
|
static void deleteAllAnimations();
|
||||||
static void deleteAnimationList(const AnimationListTag& listName);
|
|
||||||
|
|
||||||
[[nodiscard]] static bool isInAnimList(const AnimationListTag& listName);
|
static void deleteAnimationList(const AnimationListTag &listName);
|
||||||
|
|
||||||
|
[[nodiscard]] static bool isInAnimList(const AnimationListTag &listName);
|
||||||
|
|
||||||
static void init();
|
static void init();
|
||||||
|
|
||||||
static void free();
|
static void free();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -2,38 +2,35 @@
|
||||||
// Created by Иван Ильин on 26.03.2021.
|
// Created by Иван Ильин on 26.03.2021.
|
||||||
//
|
//
|
||||||
|
|
||||||
#include "Button.h"
|
|
||||||
|
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
|
#include "Button.h"
|
||||||
#include "../ResourceManager.h"
|
#include "../ResourceManager.h"
|
||||||
|
|
||||||
void Button::select()
|
void Button::select() {
|
||||||
{
|
|
||||||
if (!_selected && !_pressed) {
|
if (!_selected && !_pressed) {
|
||||||
_button.setTextureRect(sf::IntRect(_selectedState.tx, _selectedState.ty, _w, _h));
|
_button.setTextureRect(sf::IntRect(_selectedState.tx, _selectedState.ty, _w, _h));
|
||||||
_selected = true;
|
_selected = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Button::unSelect()
|
void Button::unSelect() {
|
||||||
{
|
|
||||||
if (_selected && !_pressed) {
|
if (_selected && !_pressed) {
|
||||||
_button.setTextureRect(sf::IntRect(_usualState.tx, _usualState.ty, _w, _h));
|
_button.setTextureRect(sf::IntRect(_usualState.tx, _usualState.ty, _w, _h));
|
||||||
_selected = false;
|
_selected = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Button::press()
|
void Button::press() {
|
||||||
{
|
|
||||||
if (!_pressed) {
|
if (!_pressed) {
|
||||||
_button.setTextureRect(sf::IntRect(_pressedState.tx, _pressedState.ty, _w, _h));
|
_button.setTextureRect(sf::IntRect(_pressedState.tx, _pressedState.ty, _w, _h));
|
||||||
if(_checkBox) {
|
if (_checkBox) {
|
||||||
_pressed = true;
|
_pressed = true;
|
||||||
}
|
}
|
||||||
_click();
|
_click();
|
||||||
} else {
|
} else {
|
||||||
_button.setTextureRect(sf::IntRect(_usualState.tx, _usualState.ty, _w, _h));
|
_button.setTextureRect(sf::IntRect(_usualState.tx, _usualState.ty, _w, _h));
|
||||||
if(_checkBox) {
|
if (_checkBox) {
|
||||||
_pressed = false;
|
_pressed = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -42,20 +39,24 @@ void Button::press()
|
||||||
void Button::init() {
|
void Button::init() {
|
||||||
_button.setTexture(*ResourceManager::loadTexture(_texture));
|
_button.setTexture(*ResourceManager::loadTexture(_texture));
|
||||||
_button.setTextureRect(sf::IntRect(_usualState.tx, _usualState.ty, _w, _h));
|
_button.setTextureRect(sf::IntRect(_usualState.tx, _usualState.ty, _w, _h));
|
||||||
_button.scale((float)_sx, (float)_sy);
|
_button.scale(static_cast<float>(_sx), static_cast<float>(_sy));
|
||||||
_button.setPosition((float)(_x - _w * _sx / 2), (float)(_y - _h * _sy / 2));
|
_button.setPosition(static_cast<float>(_x) - static_cast<float>(_w * _sx) / 2.0f,
|
||||||
|
static_cast<float>(_y) - static_cast<float>(_h * _sy) / 2.0f);
|
||||||
|
|
||||||
_text.setFont(*ResourceManager::loadFont(_font));
|
_text.setFont(*ResourceManager::loadFont(_font));
|
||||||
_text.setString(_textString);
|
_text.setString(_textString);
|
||||||
_text.setCharacterSize((unsigned int)(_h * _sy / 2));
|
_text.setCharacterSize(static_cast<unsigned int>((_h * _sy) / 2));
|
||||||
_text.setFillColor(_textColor);
|
_text.setFillColor(_textColor);
|
||||||
_text.setPosition((float)(_x - _text.getLocalBounds().width / 2), (float)(_y - _h * _sy / 2 + _text.getLocalBounds().height / 4));
|
_text.setPosition(static_cast<float>(_x) - _text.getLocalBounds().width / 2.0f,
|
||||||
|
static_cast<float>(_y) - static_cast<float>(_h * _sy) / 2.0f + _text.getLocalBounds().height / 4.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
Button::Button(int x, int y, int width, int height, std::function<void()> click, std::string text, double sx,
|
Button::Button(int x, int y, int width, int height, std::function<void()> click, std::string text, double sx,
|
||||||
double sy, std::string texture, tPos usualState, tPos selectedState, tPos pressedState,
|
double sy, std::string texture, tPos usualState, tPos selectedState, tPos pressedState,
|
||||||
std::string font, sf::Color textColor) : _x(x), _y(y), _w(width), _h(height), _click(std::move(click)),
|
std::string font, sf::Color textColor) : _x(x), _y(y), _w(width), _h(height), _click(std::move(click)),
|
||||||
_textString(std::move(text)), _sx(sx), _sy(sy), _texture(std::move(texture)), _usualState(usualState), _selectedState(selectedState), _pressedState(pressedState),
|
_textString(std::move(text)), _sx(sx), _sy(sy),
|
||||||
_font(std::move(font)), _textColor(textColor) {
|
_texture(std::move(texture)), _usualState(usualState),
|
||||||
|
_selectedState(selectedState), _pressedState(pressedState),
|
||||||
|
_font(std::move(font)), _textColor(textColor) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,9 +5,10 @@
|
||||||
#ifndef ENGINE_BUTTON_H
|
#ifndef ENGINE_BUTTON_H
|
||||||
#define ENGINE_BUTTON_H
|
#define ENGINE_BUTTON_H
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
#include <SFML/Graphics.hpp>
|
#include <SFML/Graphics.hpp>
|
||||||
#include <SFML/Audio.hpp>
|
#include <SFML/Audio.hpp>
|
||||||
#include <functional>
|
|
||||||
|
|
||||||
struct tPos final {
|
struct tPos final {
|
||||||
const int tx;
|
const int tx;
|
||||||
|
@ -46,22 +47,34 @@ private:
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Button() = default;
|
Button() = default;
|
||||||
Button(int x, int y, int width, int height, std::function<void()> click, std::string text, double sx, double sy, std::string texture, tPos usualState, tPos selectedState, tPos pressedState, std::string font, sf::Color textColor);
|
|
||||||
|
Button(int x, int y, int width, int height, std::function<void()> click, std::string text, double sx, double sy,
|
||||||
|
std::string texture, tPos usualState, tPos selectedState, tPos pressedState, std::string font,
|
||||||
|
sf::Color textColor);
|
||||||
|
|
||||||
void select();
|
void select();
|
||||||
|
|
||||||
void unSelect();
|
void unSelect();
|
||||||
|
|
||||||
void press();
|
void press();
|
||||||
|
|
||||||
void init();
|
void init();
|
||||||
|
|
||||||
[[nodiscard]] int x() const { return _x; }
|
[[nodiscard]] int x() const { return _x; }
|
||||||
|
|
||||||
[[nodiscard]] int y() const { return _y; }
|
[[nodiscard]] int y() const { return _y; }
|
||||||
|
|
||||||
[[nodiscard]] int w() const { return _w; }
|
[[nodiscard]] int w() const { return _w; }
|
||||||
|
|
||||||
[[nodiscard]] int h() const { return _h; }
|
[[nodiscard]] int h() const { return _h; }
|
||||||
|
|
||||||
[[nodiscard]] double sx() const { return _sx; }
|
[[nodiscard]] double sx() const { return _sx; }
|
||||||
|
|
||||||
[[nodiscard]] double sy() const { return _sy; }
|
[[nodiscard]] double sy() const { return _sy; }
|
||||||
[[nodiscard]] sf::Sprite const& sprite() const { return _button; }
|
|
||||||
[[nodiscard]] sf::Text const& text() const { return _text; }
|
[[nodiscard]] sf::Sprite const &sprite() const { return _button; }
|
||||||
|
|
||||||
|
[[nodiscard]] sf::Text const &text() const { return _text; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -2,15 +2,17 @@
|
||||||
// Created by Иван Ильин on 26.03.2021.
|
// Created by Иван Ильин on 26.03.2021.
|
||||||
//
|
//
|
||||||
|
|
||||||
#include "Window.h"
|
|
||||||
|
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
|
#include "Window.h"
|
||||||
#include "../ResourceManager.h"
|
#include "../ResourceManager.h"
|
||||||
|
|
||||||
void Window::addButton(int x, int y, int w, int h, std::function<void()> click, const std::string &text, double sx, double sy,
|
void Window::addButton(int x, int y, int w, int h, std::function<void()> click, const std::string &text, double sx,
|
||||||
|
double sy,
|
||||||
const std::string &texture, tPos usualState, tPos selectedState, tPos pressedState,
|
const std::string &texture, tPos usualState, tPos selectedState, tPos pressedState,
|
||||||
const std::string& font, sf::Color textColor) {
|
const std::string &font, sf::Color textColor) {
|
||||||
_buttons.emplace_back(x, y, w, h, std::move(click), text, sx, sy, texture, usualState, selectedState, pressedState, font, textColor);
|
_buttons.emplace_back(x, y, w, h, std::move(click), text, sx, sy, texture, usualState, selectedState, pressedState,
|
||||||
|
font, textColor);
|
||||||
_buttons.back().init();
|
_buttons.back().init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,20 +23,23 @@ void Window::update() {
|
||||||
|
|
||||||
Vec2D mousePos = _mouse->getMousePosition();
|
Vec2D mousePos = _mouse->getMousePosition();
|
||||||
Vec2D dMousePos = mousePos - _prevMousePosition;
|
Vec2D dMousePos = mousePos - _prevMousePosition;
|
||||||
_back.setPosition(_back.getPosition() - sf::Vector2f((float)(dMousePos.x() / 30), (float)(dMousePos.y() / 30)));
|
_back.setPosition(_back.getPosition() - sf::Vector2f(static_cast<float>(dMousePos.x()) / 30.0f,
|
||||||
|
static_cast<float>(dMousePos.y()) / 30.0f));
|
||||||
bool isPressed = _mouse->isButtonTapped(sf::Mouse::Left);
|
bool isPressed = _mouse->isButtonTapped(sf::Mouse::Left);
|
||||||
|
|
||||||
for(auto& button : _buttons) {
|
for (auto &button : _buttons) {
|
||||||
if( mousePos.x() > button.x() - button.w() * button.sx() / 2 && mousePos.y() > button.y() - button.h() * button.sy() / 2 &&
|
if (mousePos.x() > button.x() - button.w() * button.sx() / 2.0f &&
|
||||||
mousePos.x() < button.x() + button.w() * button.sx() / 2 && mousePos.y() < button.y() + button.h() * button.sy() / 2) {
|
mousePos.y() > button.y() - button.h() * button.sy() / 2.0f &&
|
||||||
|
mousePos.x() < button.x() + button.w() * button.sx() / 2.0f &&
|
||||||
|
mousePos.y() < button.y() + button.h() * button.sy() / 2.0f) {
|
||||||
button.select();
|
button.select();
|
||||||
if(isPressed)
|
if (isPressed)
|
||||||
button.press();
|
button.press();
|
||||||
} else {
|
} else {
|
||||||
button.unSelect();
|
button.unSelect();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(_screen->isOpen()) {
|
if (_screen->isOpen()) {
|
||||||
_screen->drawSprite(button.sprite());
|
_screen->drawSprite(button.sprite());
|
||||||
_screen->drawText(button.text());
|
_screen->drawText(button.text());
|
||||||
}
|
}
|
||||||
|
@ -47,7 +52,7 @@ void Window::setBackgroundTexture(const std::string &texture, double sx, double
|
||||||
_backTexture = texture;
|
_backTexture = texture;
|
||||||
std::shared_ptr<sf::Texture> t = ResourceManager::loadTexture(_backTexture);
|
std::shared_ptr<sf::Texture> t = ResourceManager::loadTexture(_backTexture);
|
||||||
t->setRepeated(true);
|
t->setRepeated(true);
|
||||||
_back = sf::Sprite(*t, sf::IntRect(0, 0, (int)(w + w / 30.0), (int)(h + h / 30.0)));
|
_back = sf::Sprite(*t, sf::IntRect(0, 0, static_cast<int>(w + w / 30.0), static_cast<int>(h + h / 30.0)));
|
||||||
_back.scale((float)sx, (float)sy);
|
_back.scale((float) sx, (float) sy);
|
||||||
_back.setPosition(sf::Vector2f(-w / 30.0f, -h / 30.0f));
|
_back.setPosition(sf::Vector2f(static_cast<float>(-w) / 30.0f, static_cast<float>(-h) / 30.0f));
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,17 +25,20 @@ private:
|
||||||
std::shared_ptr<Screen> _screen;
|
std::shared_ptr<Screen> _screen;
|
||||||
std::shared_ptr<Mouse> _mouse;
|
std::shared_ptr<Mouse> _mouse;
|
||||||
public:
|
public:
|
||||||
explicit Window(std::shared_ptr<Screen> screen, std::shared_ptr<Mouse> mouse, std::string name = "Menu", std::string backTexture = "") : _screen(std::move(screen)), _mouse(std::move(mouse)), _name(std::move(name)), _backTexture(std::move(backTexture)){}
|
explicit Window(std::shared_ptr<Screen> screen, std::shared_ptr<Mouse> mouse, std::string name = "Menu",
|
||||||
|
std::string backTexture = "") : _screen(std::move(screen)), _mouse(std::move(mouse)),
|
||||||
|
_name(std::move(name)), _backTexture(std::move(backTexture)) {}
|
||||||
|
|
||||||
void addButton(int x, int y, int w, int h,
|
void addButton(int x, int y, int w, int h,
|
||||||
std::function<void()> click,
|
std::function<void()> click,
|
||||||
const std::string& text = "_button", double sx = 1, double sy = 1,
|
const std::string &text = "_button", double sx = 1, double sy = 1,
|
||||||
const std::string& texture = "", tPos usualState = {}, tPos selectedState = {}, tPos pressedState = {},
|
const std::string &texture = "", tPos usualState = {}, tPos selectedState = {},
|
||||||
const std::string& font = Consts::MEDIUM_FONT, sf::Color textColor = {255, 255, 255});
|
tPos pressedState = {},
|
||||||
|
const std::string &font = Consts::MEDIUM_FONT, sf::Color textColor = {255, 255, 255});
|
||||||
|
|
||||||
void setTitle(const std::string& title) { _name = title; }
|
void setTitle(const std::string &title) { _name = title; }
|
||||||
|
|
||||||
void setBackgroundTexture(const std::string& texture, double sx = 1, double sy = 1, int w = 1920, int h = 1080);
|
void setBackgroundTexture(const std::string &texture, double sx = 1, double sy = 1, int w = 1920, int h = 1080);
|
||||||
|
|
||||||
void update();
|
void update();
|
||||||
};
|
};
|
||||||
|
|
|
@ -4,14 +4,12 @@
|
||||||
|
|
||||||
#include "ClientUDP.h"
|
#include "ClientUDP.h"
|
||||||
#include "MsgType.h"
|
#include "MsgType.h"
|
||||||
#include <thread>
|
|
||||||
#include "../utils/Time.h"
|
#include "../utils/Time.h"
|
||||||
#include <cmath>
|
|
||||||
#include "../utils/Log.h"
|
#include "../utils/Log.h"
|
||||||
#include "../Consts.h"
|
#include "../Consts.h"
|
||||||
|
|
||||||
ClientUDP::ClientUDP() {
|
ClientUDP::ClientUDP() {
|
||||||
_socket.setTimeoutCallback([this](sf::Uint16 id) {return ClientUDP::timeout(id); } );
|
_socket.setTimeoutCallback([this](sf::Uint16 id) { return ClientUDP::timeout(id); });
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ClientUDP::connected() const {
|
bool ClientUDP::connected() const {
|
||||||
|
|
|
@ -18,6 +18,7 @@ protected:
|
||||||
sf::IpAddress _ip{};
|
sf::IpAddress _ip{};
|
||||||
|
|
||||||
bool process();
|
bool process();
|
||||||
|
|
||||||
bool timeout(sf::Uint16 id);
|
bool timeout(sf::Uint16 id);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -25,25 +26,33 @@ public:
|
||||||
explicit ClientUDP();
|
explicit ClientUDP();
|
||||||
|
|
||||||
[[nodiscard]] bool isWorking() const;
|
[[nodiscard]] bool isWorking() const;
|
||||||
|
|
||||||
[[nodiscard]] bool connected() const;
|
[[nodiscard]] bool connected() const;
|
||||||
|
|
||||||
void connect(sf::IpAddress ip, sf::Uint16 port);
|
void connect(sf::IpAddress ip, sf::Uint16 port);
|
||||||
|
|
||||||
void disconnect();
|
void disconnect();
|
||||||
|
|
||||||
void update();
|
void update();
|
||||||
|
|
||||||
[[nodiscard]] sf::IpAddress serverIp() const { return _ip; }
|
[[nodiscard]] sf::IpAddress serverIp() const { return _ip; }
|
||||||
|
|
||||||
[[nodiscard]] sf::Uint16 serverPort() const { return _port; }
|
[[nodiscard]] sf::Uint16 serverPort() const { return _port; }
|
||||||
|
|
||||||
// virtual functions
|
// virtual functions
|
||||||
virtual void updatePacket(){};
|
virtual void updatePacket() {};
|
||||||
|
|
||||||
virtual void processInit(sf::Packet& packet){};
|
virtual void processInit(sf::Packet &packet) {};
|
||||||
virtual void processUpdate(sf::Packet& packet){};
|
|
||||||
virtual void processNewClient(sf::Packet& packet){};
|
|
||||||
virtual void processDisconnect(sf::Uint16 targetId){};
|
|
||||||
|
|
||||||
virtual void processCustomPacket(sf::Packet& packet){};
|
virtual void processUpdate(sf::Packet &packet) {};
|
||||||
|
|
||||||
virtual void processDisconnected(){};
|
virtual void processNewClient(sf::Packet &packet) {};
|
||||||
|
|
||||||
|
virtual void processDisconnect(sf::Uint16 targetId) {};
|
||||||
|
|
||||||
|
virtual void processCustomPacket(sf::Packet &packet) {};
|
||||||
|
|
||||||
|
virtual void processDisconnected() {};
|
||||||
|
|
||||||
virtual ~ClientUDP() = default;
|
virtual ~ClientUDP() = default;
|
||||||
};
|
};
|
||||||
|
|
|
@ -4,15 +4,13 @@
|
||||||
|
|
||||||
#include "MsgType.h"
|
#include "MsgType.h"
|
||||||
|
|
||||||
sf::Packet& operator<<(sf::Packet& packet, MsgType type)
|
sf::Packet &operator<<(sf::Packet &packet, MsgType type) {
|
||||||
{
|
return packet << (sf::Uint16) type;
|
||||||
return packet << (sf::Uint16)type;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sf::Packet& operator>>(sf::Packet& packet, MsgType& type)
|
sf::Packet &operator>>(sf::Packet &packet, MsgType &type) {
|
||||||
{
|
|
||||||
sf::Uint16 temp;
|
sf::Uint16 temp;
|
||||||
packet >> temp;
|
packet >> temp;
|
||||||
type = (MsgType)temp;
|
type = (MsgType) temp;
|
||||||
return packet;
|
return packet;
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,8 +7,7 @@
|
||||||
|
|
||||||
#include <SFML/Network.hpp>
|
#include <SFML/Network.hpp>
|
||||||
|
|
||||||
enum class MsgType
|
enum class MsgType {
|
||||||
{
|
|
||||||
// internal messages
|
// internal messages
|
||||||
Empty, // Empty message (there are no message)
|
Empty, // Empty message (there are no message)
|
||||||
Error, // Error message (something went wrong)
|
Error, // Error message (something went wrong)
|
||||||
|
@ -26,8 +25,9 @@ enum class MsgType
|
||||||
Custom,
|
Custom,
|
||||||
};
|
};
|
||||||
|
|
||||||
sf::Packet& operator<<(sf::Packet& packet, MsgType type);
|
sf::Packet &operator<<(sf::Packet &packet, MsgType type);
|
||||||
sf::Packet& operator>>(sf::Packet& packet, MsgType& type);
|
|
||||||
|
sf::Packet &operator>>(sf::Packet &packet, MsgType &type);
|
||||||
|
|
||||||
|
|
||||||
#endif //INC_3DZAVR_MSGTYPE_H
|
#endif //INC_3DZAVR_MSGTYPE_H
|
||||||
|
|
|
@ -2,16 +2,19 @@
|
||||||
// Created by Neirokan on 30.04.2020
|
// Created by Neirokan on 30.04.2020
|
||||||
//
|
//
|
||||||
|
|
||||||
#include <cmath>
|
|
||||||
#include "ReliableMsg.h"
|
#include "ReliableMsg.h"
|
||||||
#include "../utils/Time.h"
|
#include "../utils/Time.h"
|
||||||
#include "../Consts.h"
|
#include "../Consts.h"
|
||||||
|
|
||||||
ReliableMsg::ReliableMsg(sf::Packet& packet, sf::IpAddress address, sf::Uint16 port) : packet(packet), address(address), port(port), lastTry(-std::numeric_limits<double>::max()), firstTry(Time::time()) {}
|
ReliableMsg::ReliableMsg(sf::Packet &packet, sf::IpAddress address, sf::Uint16 port) : packet(packet), address(address),
|
||||||
ReliableMsg::ReliableMsg(const ReliableMsg& msg) : packet(msg.packet), address(msg.address), port(msg.port), lastTry(msg.lastTry), firstTry(msg.firstTry) {}
|
port(port),
|
||||||
|
lastTry(-std::numeric_limits<double>::max()),
|
||||||
|
firstTry(Time::time()) {}
|
||||||
|
|
||||||
bool ReliableMsg::trySend(sf::UdpSocket& socket)
|
ReliableMsg::ReliableMsg(const ReliableMsg &msg) : packet(msg.packet), address(msg.address), port(msg.port),
|
||||||
{
|
lastTry(msg.lastTry), firstTry(msg.firstTry) {}
|
||||||
|
|
||||||
|
bool ReliableMsg::trySend(sf::UdpSocket &socket) {
|
||||||
if (Time::time() - firstTry > Consts::NETWORK_TIMEOUT) {
|
if (Time::time() - firstTry > Consts::NETWORK_TIMEOUT) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,10 +16,11 @@ private:
|
||||||
double lastTry;
|
double lastTry;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ReliableMsg(sf::Packet& packet, sf::IpAddress address, sf::Uint16 port);
|
ReliableMsg(sf::Packet &packet, sf::IpAddress address, sf::Uint16 port);
|
||||||
ReliableMsg(const ReliableMsg& msg);
|
|
||||||
|
|
||||||
bool trySend(sf::UdpSocket& socket);
|
ReliableMsg(const ReliableMsg &msg);
|
||||||
|
|
||||||
|
bool trySend(sf::UdpSocket &socket);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,7 @@ bool ServerUDP::isWorking() const {
|
||||||
bool ServerUDP::start(sf::Uint16 port) {
|
bool ServerUDP::start(sf::Uint16 port) {
|
||||||
_working = _socket.bind(port);
|
_working = _socket.bind(port);
|
||||||
|
|
||||||
if(_working) {
|
if (_working) {
|
||||||
Log::log("ServerUDP::start(): the server was successfully started.");
|
Log::log("ServerUDP::start(): the server was successfully started.");
|
||||||
} else {
|
} else {
|
||||||
Log::log("ServerUDP::start(): failed to start the server.");
|
Log::log("ServerUDP::start(): failed to start the server.");
|
||||||
|
|
|
@ -19,29 +19,36 @@ protected:
|
||||||
bool _working = false;
|
bool _working = false;
|
||||||
|
|
||||||
bool process();
|
bool process();
|
||||||
|
|
||||||
bool timeout(sf::Uint16 id);
|
bool timeout(sf::Uint16 id);
|
||||||
|
|
||||||
std::set<sf::Uint16> _clients{};
|
std::set<sf::Uint16> _clients{};
|
||||||
public:
|
public:
|
||||||
explicit ServerUDP();
|
explicit ServerUDP();
|
||||||
|
|
||||||
[[nodiscard]] bool isWorking() const;
|
[[nodiscard]] bool isWorking() const;
|
||||||
|
|
||||||
bool start(sf::Uint16 port);
|
bool start(sf::Uint16 port);
|
||||||
|
|
||||||
void stop();
|
void stop();
|
||||||
|
|
||||||
void update();
|
void update();
|
||||||
|
|
||||||
virtual void updateInfo(){};
|
virtual void updateInfo() {};
|
||||||
|
|
||||||
// virtual functions
|
// virtual functions
|
||||||
virtual void broadcast(){};
|
virtual void broadcast() {};
|
||||||
|
|
||||||
// here you have to send Init message _back to 'targetId' and send NewClient message to all '_clients'
|
// here you have to send Init message _back to 'targetId' and send NewClient message to all '_clients'
|
||||||
virtual void processConnect(sf::Uint16 senderId){};
|
virtual void processConnect(sf::Uint16 senderId) {};
|
||||||
virtual void processClientUpdate(sf::Uint16 senderId, sf::Packet& packet){};
|
|
||||||
virtual void processDisconnect(sf::Uint16 senderId){};
|
|
||||||
|
|
||||||
virtual void processCustomPacket(sf::Packet& packet, sf::Uint16 senderId){};
|
virtual void processClientUpdate(sf::Uint16 senderId, sf::Packet &packet) {};
|
||||||
|
|
||||||
virtual void processStop(){};
|
virtual void processDisconnect(sf::Uint16 senderId) {};
|
||||||
|
|
||||||
|
virtual void processCustomPacket(sf::Packet &packet, sf::Uint16 senderId) {};
|
||||||
|
|
||||||
|
virtual void processStop() {};
|
||||||
|
|
||||||
virtual ~ServerUDP();
|
virtual ~ServerUDP();
|
||||||
};
|
};
|
||||||
|
|
|
@ -6,13 +6,14 @@
|
||||||
#include "../utils/Time.h"
|
#include "../utils/Time.h"
|
||||||
#include "../Consts.h"
|
#include "../Consts.h"
|
||||||
|
|
||||||
UDPConnection::UDPConnection(sf::Uint16 id, sf::IpAddress ip, sf::Uint16 port) : _id(id), _ip(ip), _port(port), lastMsg(Time::time()) {}
|
UDPConnection::UDPConnection(sf::Uint16 id, sf::IpAddress ip, sf::Uint16 port) : _id(id), _ip(ip), _port(port),
|
||||||
|
lastMsg(Time::time()) {}
|
||||||
|
|
||||||
sf::Uint16 UDPConnection::id() const {
|
sf::Uint16 UDPConnection::id() const {
|
||||||
return _id;
|
return _id;
|
||||||
}
|
}
|
||||||
|
|
||||||
const sf::IpAddress& UDPConnection::ip() const {
|
const sf::IpAddress &UDPConnection::ip() const {
|
||||||
return _ip;
|
return _ip;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,7 +25,7 @@ bool UDPConnection::timeout() const {
|
||||||
return Time::time() - lastMsg > Consts::NETWORK_TIMEOUT;
|
return Time::time() - lastMsg > Consts::NETWORK_TIMEOUT;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool UDPConnection::same(sf::IpAddress& ip, sf::Uint16 port) const {
|
bool UDPConnection::same(sf::IpAddress &ip, sf::Uint16 port) const {
|
||||||
return _ip == ip && _port == port;
|
return _ip == ip && _port == port;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,6 +33,6 @@ void UDPConnection::update() {
|
||||||
lastMsg = Time::time();
|
lastMsg = Time::time();
|
||||||
}
|
}
|
||||||
|
|
||||||
void UDPConnection::send(sf::UdpSocket& socket, sf::Packet& packet) {
|
void UDPConnection::send(sf::UdpSocket &socket, sf::Packet &packet) {
|
||||||
socket.send(packet, _ip, _port);
|
socket.send(packet, _ip, _port);
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,13 +16,20 @@ private:
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit UDPConnection(sf::Uint16 id, sf::IpAddress ip, sf::Uint16 port);
|
explicit UDPConnection(sf::Uint16 id, sf::IpAddress ip, sf::Uint16 port);
|
||||||
|
|
||||||
[[nodiscard]] sf::Uint16 id() const;
|
[[nodiscard]] sf::Uint16 id() const;
|
||||||
[[nodiscard]] const sf::IpAddress& ip() const;
|
|
||||||
|
[[nodiscard]] const sf::IpAddress &ip() const;
|
||||||
|
|
||||||
[[nodiscard]] sf::Uint16 port() const;
|
[[nodiscard]] sf::Uint16 port() const;
|
||||||
|
|
||||||
[[nodiscard]] bool timeout() const;
|
[[nodiscard]] bool timeout() const;
|
||||||
bool same(sf::IpAddress& ip, sf::Uint16 port) const;
|
|
||||||
|
[[nodiscard]] bool same(sf::IpAddress &ip, sf::Uint16 port) const;
|
||||||
|
|
||||||
void update();
|
void update();
|
||||||
void send(sf::UdpSocket& socket, sf::Packet& packet);
|
|
||||||
|
void send(sf::UdpSocket &socket, sf::Packet &packet);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -2,9 +2,10 @@
|
||||||
// Created by Neirokan on 30.04.2020
|
// Created by Neirokan on 30.04.2020
|
||||||
//
|
//
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
#include "UDPSocket.h"
|
#include "UDPSocket.h"
|
||||||
#include "../utils/Time.h"
|
#include "../utils/Time.h"
|
||||||
#include <algorithm>
|
|
||||||
#include "../Consts.h"
|
#include "../Consts.h"
|
||||||
|
|
||||||
UDPSocket::UDPSocket() : _ownId(0), _nextRelyMsgId(0) {
|
UDPSocket::UDPSocket() : _ownId(0), _nextRelyMsgId(0) {
|
||||||
|
@ -12,7 +13,7 @@ UDPSocket::UDPSocket() : _ownId(0), _nextRelyMsgId(0) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void UDPSocket::addConnection(sf::Uint16 id, sf::IpAddress ip, sf::Uint16 port) {
|
void UDPSocket::addConnection(sf::Uint16 id, sf::IpAddress ip, sf::Uint16 port) {
|
||||||
_connections.insert({ id, UDPConnection(id, ip, port) });
|
_connections.insert({id, UDPConnection(id, ip, port)});
|
||||||
}
|
}
|
||||||
|
|
||||||
void UDPSocket::removeConnection(sf::Uint16 id) {
|
void UDPSocket::removeConnection(sf::Uint16 id) {
|
||||||
|
@ -54,28 +55,28 @@ sf::Uint16 UDPSocket::serverId() const {
|
||||||
return _serverId;
|
return _serverId;
|
||||||
}
|
}
|
||||||
|
|
||||||
void UDPSocket::sendRely(const sf::Packet& packet, const sf::IpAddress& ip, sf::Uint16 port) {
|
void UDPSocket::sendRely(const sf::Packet &packet, const sf::IpAddress &ip, sf::Uint16 port) {
|
||||||
sf::Packet finalPacket;
|
sf::Packet finalPacket;
|
||||||
finalPacket << _ownId << true << _nextRelyMsgId;
|
finalPacket << _ownId << true << _nextRelyMsgId;
|
||||||
finalPacket.append(packet.getData(), packet.getDataSize());
|
finalPacket.append(packet.getData(), packet.getDataSize());
|
||||||
_relyPackets.insert({ _nextRelyMsgId++, ReliableMsg(finalPacket, ip, port) });
|
_relyPackets.insert({_nextRelyMsgId++, ReliableMsg(finalPacket, ip, port)});
|
||||||
}
|
}
|
||||||
|
|
||||||
void UDPSocket::sendRely(const sf::Packet& packet, sf::Uint16 id) {
|
void UDPSocket::sendRely(const sf::Packet &packet, sf::Uint16 id) {
|
||||||
if (!_connections.count(id)) {
|
if (!_connections.count(id)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this->sendRely(packet, _connections.at(id).ip(), _connections.at(id).port());
|
this->sendRely(packet, _connections.at(id).ip(), _connections.at(id).port());
|
||||||
}
|
}
|
||||||
|
|
||||||
void UDPSocket::send(const sf::Packet& packet, const sf::IpAddress& ip, sf::Uint16 port) {
|
void UDPSocket::send(const sf::Packet &packet, const sf::IpAddress &ip, sf::Uint16 port) {
|
||||||
sf::Packet finalPacket;
|
sf::Packet finalPacket;
|
||||||
finalPacket << _ownId << false << _serverId;
|
finalPacket << _ownId << false << _serverId;
|
||||||
finalPacket.append(packet.getData(), packet.getDataSize());
|
finalPacket.append(packet.getData(), packet.getDataSize());
|
||||||
_socket.send(finalPacket, ip, port);
|
_socket.send(finalPacket, ip, port);
|
||||||
}
|
}
|
||||||
|
|
||||||
void UDPSocket::send(const sf::Packet& packet, sf::Uint16 id) {
|
void UDPSocket::send(const sf::Packet &packet, sf::Uint16 id) {
|
||||||
if (!_connections.count(id)) {
|
if (!_connections.count(id)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -111,7 +112,7 @@ void UDPSocket::update() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MsgType UDPSocket::receive(sf::Packet& packet, sf::Uint16& senderId) {
|
MsgType UDPSocket::receive(sf::Packet &packet, sf::Uint16 &senderId) {
|
||||||
// Receive message
|
// Receive message
|
||||||
sf::IpAddress ip;
|
sf::IpAddress ip;
|
||||||
sf::Uint16 port;
|
sf::Uint16 port;
|
||||||
|
@ -155,10 +156,11 @@ MsgType UDPSocket::receive(sf::Packet& packet, sf::Uint16& senderId) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_connections.insert({ senderId, UDPConnection(senderId, ip, port) });
|
_connections.insert({senderId, UDPConnection(senderId, ip, port)});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!_connections.count(senderId) || !_connections.at(senderId).same(ip, port) || reply && confirmed(msgId, senderId)) {
|
if (!_connections.count(senderId) || !_connections.at(senderId).same(ip, port) ||
|
||||||
|
reply && confirmed(msgId, senderId)) {
|
||||||
return MsgType::Error;
|
return MsgType::Error;
|
||||||
}
|
}
|
||||||
return type;
|
return type;
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
|
||||||
#include "ReliableMsg.h"
|
#include "ReliableMsg.h"
|
||||||
#include "UDPConnection.h"
|
#include "UDPConnection.h"
|
||||||
#include "MsgType.h"
|
#include "MsgType.h"
|
||||||
|
@ -28,23 +29,34 @@ private:
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit UDPSocket();
|
explicit UDPSocket();
|
||||||
|
|
||||||
bool bind(sf::Uint16 port);
|
bool bind(sf::Uint16 port);
|
||||||
|
|
||||||
void unbind();
|
void unbind();
|
||||||
|
|
||||||
void setTimeoutCallback(std::function<bool(sf::Uint16)> callback);
|
void setTimeoutCallback(std::function<bool(sf::Uint16)> callback);
|
||||||
|
|
||||||
void addConnection(sf::Uint16 id, sf::IpAddress ip, sf::Uint16 port);
|
void addConnection(sf::Uint16 id, sf::IpAddress ip, sf::Uint16 port);
|
||||||
|
|
||||||
void removeConnection(sf::Uint16 id);
|
void removeConnection(sf::Uint16 id);
|
||||||
|
|
||||||
void setId(sf::Uint16 id);
|
void setId(sf::Uint16 id);
|
||||||
|
|
||||||
[[nodiscard]] sf::Uint16 ownId() const;
|
[[nodiscard]] sf::Uint16 ownId() const;
|
||||||
|
|
||||||
[[nodiscard]] sf::Uint16 serverId() const;
|
[[nodiscard]] sf::Uint16 serverId() const;
|
||||||
|
|
||||||
void send(const sf::Packet& packet, const sf::IpAddress& ip, sf::Uint16 port);
|
void send(const sf::Packet &packet, const sf::IpAddress &ip, sf::Uint16 port);
|
||||||
void send(const sf::Packet& packet, sf::Uint16 id);
|
|
||||||
void sendRely(const sf::Packet& packet, const sf::IpAddress& ip, sf::Uint16 port);
|
void send(const sf::Packet &packet, sf::Uint16 id);
|
||||||
void sendRely(const sf::Packet& packet, sf::Uint16 id);
|
|
||||||
|
void sendRely(const sf::Packet &packet, const sf::IpAddress &ip, sf::Uint16 port);
|
||||||
|
|
||||||
|
void sendRely(const sf::Packet &packet, sf::Uint16 id);
|
||||||
|
|
||||||
void update();
|
void update();
|
||||||
MsgType receive(sf::Packet& packet, sf::Uint16& senderId);
|
|
||||||
|
MsgType receive(sf::Packet &packet, sf::Uint16 &senderId);
|
||||||
|
|
||||||
~UDPSocket();
|
~UDPSocket();
|
||||||
};
|
};
|
||||||
|
|
|
@ -2,28 +2,29 @@
|
||||||
// Created by Иван Ильин on 05.02.2021.
|
// Created by Иван Ильин on 05.02.2021.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
#include <cmath>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
#include "RigidBody.h"
|
#include "RigidBody.h"
|
||||||
#include "../utils/Log.h"
|
#include "../utils/Log.h"
|
||||||
#include "../utils/Time.h"
|
#include "../utils/Time.h"
|
||||||
#include <iostream>
|
|
||||||
#include <cmath>
|
|
||||||
#include <fstream>
|
|
||||||
#include <utility>
|
|
||||||
#include "../Consts.h"
|
#include "../Consts.h"
|
||||||
|
|
||||||
RigidBody::RigidBody(ObjectNameTag nameTag, const std::string &filename, const Vec3D &scale) : Mesh(std::move(nameTag), filename, scale) {
|
RigidBody::RigidBody(ObjectNameTag nameTag, const std::string &filename, const Vec3D &scale) : Mesh(std::move(nameTag),
|
||||||
|
filename, scale) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Vec3D RigidBody::_findFurthestPoint(const Vec3D& direction) {
|
Vec3D RigidBody::_findFurthestPoint(const Vec3D &direction) {
|
||||||
Vec3D maxPoint{0, 0, 0};
|
Vec3D maxPoint{0, 0, 0};
|
||||||
double maxDistance = -std::numeric_limits<double>::max();
|
double maxDistance = -std::numeric_limits<double>::max();
|
||||||
|
|
||||||
for(auto& tri : triangles()){
|
for (auto &tri : triangles()) {
|
||||||
for(int i = 0; i < 3; i++){
|
for (int i = 0; i < 3; i++) {
|
||||||
Vec3D point(model()*tri[i]);
|
// TODO: multiplying model() * tri[i] costs too much time to compute
|
||||||
|
Vec3D point(model() * tri[i]);
|
||||||
|
|
||||||
double distance = point.dot(direction.normalized());
|
double distance = point.dot(direction.normalized());
|
||||||
if(distance > maxDistance) {
|
if (distance > maxDistance) {
|
||||||
maxDistance = distance;
|
maxDistance = distance;
|
||||||
maxPoint = point;
|
maxPoint = point;
|
||||||
}
|
}
|
||||||
|
@ -33,7 +34,7 @@ Vec3D RigidBody::_findFurthestPoint(const Vec3D& direction) {
|
||||||
return maxPoint;
|
return maxPoint;
|
||||||
}
|
}
|
||||||
|
|
||||||
Vec3D RigidBody::_support(std::shared_ptr<RigidBody> obj, const Vec3D& direction) {
|
Vec3D RigidBody::_support(std::shared_ptr<RigidBody> obj, const Vec3D &direction) {
|
||||||
Vec3D p1 = _findFurthestPoint(direction);
|
Vec3D p1 = _findFurthestPoint(direction);
|
||||||
Vec3D p2 = obj->_findFurthestPoint(-direction);
|
Vec3D p2 = obj->_findFurthestPoint(-direction);
|
||||||
Vec3D res = p1 - p2;
|
Vec3D res = p1 - p2;
|
||||||
|
@ -43,15 +44,19 @@ Vec3D RigidBody::_support(std::shared_ptr<RigidBody> obj, const Vec3D& direction
|
||||||
|
|
||||||
NextSimplex RigidBody::_nextSimplex(const Simplex &points) {
|
NextSimplex RigidBody::_nextSimplex(const Simplex &points) {
|
||||||
switch (points.type()) {
|
switch (points.type()) {
|
||||||
case SimplexType::Line: return _lineCase(points);
|
case SimplexType::Line:
|
||||||
case SimplexType::Triangle: return _triangleCase(points);
|
return _lineCase(points);
|
||||||
case SimplexType::Tetrahedron: return _tetrahedronCase(points);
|
case SimplexType::Triangle:
|
||||||
|
return _triangleCase(points);
|
||||||
|
case SimplexType::Tetrahedron:
|
||||||
|
return _tetrahedronCase(points);
|
||||||
|
|
||||||
default: throw std::logic_error{"RigidBody::_nextSimplex: simplex is not Line, Triangle or Tetrahedron"};
|
default:
|
||||||
|
throw std::logic_error{"RigidBody::_nextSimplex: simplex is not Line, Triangle or Tetrahedron"};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
NextSimplex RigidBody::_lineCase(const Simplex& points) {
|
NextSimplex RigidBody::_lineCase(const Simplex &points) {
|
||||||
Simplex newPoints(points);
|
Simplex newPoints(points);
|
||||||
Vec3D newDirection;
|
Vec3D newDirection;
|
||||||
|
|
||||||
|
@ -59,7 +64,7 @@ NextSimplex RigidBody::_lineCase(const Simplex& points) {
|
||||||
Vec3D b = points[1];
|
Vec3D b = points[1];
|
||||||
|
|
||||||
Vec3D ab = b - a;
|
Vec3D ab = b - a;
|
||||||
Vec3D ao = - a;
|
Vec3D ao = -a;
|
||||||
|
|
||||||
if (ab.dot(ao) > 0) {
|
if (ab.dot(ao) > 0) {
|
||||||
newDirection = ab.cross(ao).cross(ab);
|
newDirection = ab.cross(ao).cross(ab);
|
||||||
|
@ -81,27 +86,25 @@ NextSimplex RigidBody::_triangleCase(const Simplex &points) {
|
||||||
|
|
||||||
Vec3D ab = b - a;
|
Vec3D ab = b - a;
|
||||||
Vec3D ac = c - a;
|
Vec3D ac = c - a;
|
||||||
Vec3D ao = - a;
|
Vec3D ao = -a;
|
||||||
|
|
||||||
Vec3D abc = ab.cross(ac);
|
Vec3D abc = ab.cross(ac);
|
||||||
|
|
||||||
if (abc.cross(ac).dot(ao) > 0) {
|
if (abc.cross(ac).dot(ao) > 0) {
|
||||||
if (ac.dot(ao) > 0) {
|
if (ac.dot(ao) > 0) {
|
||||||
newPoints = Simplex{ a, c };
|
newPoints = Simplex{a, c};
|
||||||
newDirection = ac.cross(ao).cross(ac);
|
newDirection = ac.cross(ao).cross(ac);
|
||||||
}
|
} else {
|
||||||
else {
|
return _lineCase(Simplex{a, b});
|
||||||
return _lineCase(Simplex { a, b });
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (ab.cross(abc).dot(ao) > 0) {
|
if (ab.cross(abc).dot(ao) > 0) {
|
||||||
return _lineCase(Simplex { a, b });
|
return _lineCase(Simplex{a, b});
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
if (abc.dot(ao) > 0) {
|
if (abc.dot(ao) > 0) {
|
||||||
newDirection = abc;
|
newDirection = abc;
|
||||||
} else {
|
} else {
|
||||||
newPoints = Simplex{ a, c, b };
|
newPoints = Simplex{a, c, b};
|
||||||
newDirection = -abc;
|
newDirection = -abc;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -119,22 +122,22 @@ NextSimplex RigidBody::_tetrahedronCase(const Simplex &points) {
|
||||||
Vec3D ab = b - a;
|
Vec3D ab = b - a;
|
||||||
Vec3D ac = c - a;
|
Vec3D ac = c - a;
|
||||||
Vec3D ad = d - a;
|
Vec3D ad = d - a;
|
||||||
Vec3D ao = - a;
|
Vec3D ao = -a;
|
||||||
|
|
||||||
Vec3D abc = ab.cross(ac);
|
Vec3D abc = ab.cross(ac);
|
||||||
Vec3D acd = ac.cross(ad);
|
Vec3D acd = ac.cross(ad);
|
||||||
Vec3D adb = ad.cross(ab);
|
Vec3D adb = ad.cross(ab);
|
||||||
|
|
||||||
if (abc.dot(ao) > 0) {
|
if (abc.dot(ao) > 0) {
|
||||||
return _triangleCase(Simplex{ a, b, c });
|
return _triangleCase(Simplex{a, b, c});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (acd.dot(ao) > 0) {
|
if (acd.dot(ao) > 0) {
|
||||||
return _triangleCase(Simplex{ a, c, d });
|
return _triangleCase(Simplex{a, c, d});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (adb.dot(ao) > 0) {
|
if (adb.dot(ao) > 0) {
|
||||||
return _triangleCase(Simplex{ a, d, b });
|
return _triangleCase(Simplex{a, d, b});
|
||||||
}
|
}
|
||||||
|
|
||||||
return NextSimplex{points, Vec3D(), true};
|
return NextSimplex{points, Vec3D(), true};
|
||||||
|
@ -175,7 +178,7 @@ std::pair<bool, Simplex> RigidBody::checkGJKCollision(std::shared_ptr<RigidBody>
|
||||||
points = nextSimplex.newSimplex;
|
points = nextSimplex.newSimplex;
|
||||||
|
|
||||||
if (nextSimplex.finishSearching) {
|
if (nextSimplex.finishSearching) {
|
||||||
if(obj->isCollider()) {
|
if (obj->isCollider()) {
|
||||||
_inCollision = true;
|
_inCollision = true;
|
||||||
}
|
}
|
||||||
return std::make_pair(true, points);
|
return std::make_pair(true, points);
|
||||||
|
@ -184,7 +187,7 @@ std::pair<bool, Simplex> RigidBody::checkGJKCollision(std::shared_ptr<RigidBody>
|
||||||
return std::make_pair(false, points);
|
return std::make_pair(false, points);
|
||||||
}
|
}
|
||||||
|
|
||||||
CollisionPoint RigidBody::EPA(const Simplex& simplex, std::shared_ptr<RigidBody> obj) {
|
CollisionPoint RigidBody::EPA(const Simplex &simplex, std::shared_ptr<RigidBody> obj) {
|
||||||
// This is implementation of EPA algorithm for solving collision.
|
// This is implementation of EPA algorithm for solving collision.
|
||||||
// It uses a simplex from GJK around and expand it to the border.
|
// It uses a simplex from GJK around and expand it to the border.
|
||||||
// The goal is to calculate the nearest normal and the intersection depth.
|
// The goal is to calculate the nearest normal and the intersection depth.
|
||||||
|
@ -193,7 +196,7 @@ CollisionPoint RigidBody::EPA(const Simplex& simplex, std::shared_ptr<RigidBody>
|
||||||
// https://blog.winter.dev/2020/epa-algorithm/
|
// https://blog.winter.dev/2020/epa-algorithm/
|
||||||
|
|
||||||
std::vector<Vec3D> polytope(simplex.begin(), simplex.end());
|
std::vector<Vec3D> polytope(simplex.begin(), simplex.end());
|
||||||
std::vector<size_t> faces = {
|
std::vector<size_t> faces = {
|
||||||
0, 1, 2,
|
0, 1, 2,
|
||||||
0, 3, 1,
|
0, 3, 1,
|
||||||
0, 2, 3,
|
0, 2, 3,
|
||||||
|
@ -220,7 +223,7 @@ CollisionPoint RigidBody::EPA(const Simplex& simplex, std::shared_ptr<RigidBody>
|
||||||
std::vector<std::pair<size_t, size_t>> uniqueEdges;
|
std::vector<std::pair<size_t, size_t>> uniqueEdges;
|
||||||
|
|
||||||
size_t f = 0;
|
size_t f = 0;
|
||||||
for (auto & normal : normals) {
|
for (auto &normal : normals) {
|
||||||
if (normal.normal.dot(support) > 0) {
|
if (normal.normal.dot(support) > 0) {
|
||||||
uniqueEdges = _addIfUniqueEdge(uniqueEdges, faces, f + 0, f + 1);
|
uniqueEdges = _addIfUniqueEdge(uniqueEdges, faces, f + 0, f + 1);
|
||||||
uniqueEdges = _addIfUniqueEdge(uniqueEdges, faces, f + 1, f + 2);
|
uniqueEdges = _addIfUniqueEdge(uniqueEdges, faces, f + 1, f + 2);
|
||||||
|
@ -235,7 +238,7 @@ CollisionPoint RigidBody::EPA(const Simplex& simplex, std::shared_ptr<RigidBody>
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<size_t> newFaces;
|
std::vector<size_t> newFaces;
|
||||||
for (auto [edgeIndex1, edgeIndex2] : uniqueEdges) {
|
for (auto[edgeIndex1, edgeIndex2] : uniqueEdges) {
|
||||||
newFaces.push_back(edgeIndex1);
|
newFaces.push_back(edgeIndex1);
|
||||||
newFaces.push_back(edgeIndex2);
|
newFaces.push_back(edgeIndex2);
|
||||||
newFaces.push_back(polytope.size());
|
newFaces.push_back(polytope.size());
|
||||||
|
@ -252,14 +255,15 @@ CollisionPoint RigidBody::EPA(const Simplex& simplex, std::shared_ptr<RigidBody>
|
||||||
}
|
}
|
||||||
|
|
||||||
_collisionNormal = minNormal;
|
_collisionNormal = minNormal;
|
||||||
if(std::abs(minDistance - std::numeric_limits<double>::max()) < Consts::EPS) {
|
if (std::abs(minDistance - std::numeric_limits<double>::max()) < Consts::EPS) {
|
||||||
return CollisionPoint{minNormal, 0};
|
return CollisionPoint{minNormal, 0};
|
||||||
}
|
}
|
||||||
|
|
||||||
return CollisionPoint{minNormal, minDistance + Consts::EPA_EPS};
|
return CollisionPoint{minNormal, minDistance + Consts::EPA_EPS};
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<std::vector<FaceNormal>, size_t> RigidBody::_getFaceNormals(const std::vector<Vec3D>& polytope, const std::vector<size_t>& faces) {
|
std::pair<std::vector<FaceNormal>, size_t>
|
||||||
|
RigidBody::_getFaceNormals(const std::vector<Vec3D> &polytope, const std::vector<size_t> &faces) {
|
||||||
std::vector<FaceNormal> normals;
|
std::vector<FaceNormal> normals;
|
||||||
size_t nearestFaceIndex = 0;
|
size_t nearestFaceIndex = 0;
|
||||||
double minDistance = std::numeric_limits<double>::max();
|
double minDistance = std::numeric_limits<double>::max();
|
||||||
|
@ -289,7 +293,9 @@ std::pair<std::vector<FaceNormal>, size_t> RigidBody::_getFaceNormals(const std:
|
||||||
return {normals, nearestFaceIndex};
|
return {normals, nearestFaceIndex};
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::pair<size_t, size_t>> RigidBody::_addIfUniqueEdge(const std::vector<std::pair<size_t, size_t>>& edges, const std::vector<size_t>& faces, size_t a, size_t b) {
|
std::vector<std::pair<size_t, size_t>>
|
||||||
|
RigidBody::_addIfUniqueEdge(const std::vector<std::pair<size_t, size_t>> &edges, const std::vector<size_t> &faces,
|
||||||
|
size_t a, size_t b) {
|
||||||
|
|
||||||
std::vector<std::pair<size_t, size_t>> newEdges = edges;
|
std::vector<std::pair<size_t, size_t>> newEdges = edges;
|
||||||
|
|
||||||
|
@ -309,12 +315,12 @@ std::vector<std::pair<size_t, size_t>> RigidBody::_addIfUniqueEdge(const std::ve
|
||||||
return newEdges;
|
return newEdges;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RigidBody::solveCollision(const CollisionPoint& collision) {
|
void RigidBody::solveCollision(const CollisionPoint &collision) {
|
||||||
|
|
||||||
Vec3D velocity_parallel = collision.normal * velocity().dot(collision.normal);
|
Vec3D velocity_parallel = collision.normal * velocity().dot(collision.normal);
|
||||||
Vec3D velocity_perpendicular = velocity() - velocity_parallel;
|
Vec3D velocity_perpendicular = velocity() - velocity_parallel;
|
||||||
|
|
||||||
if(velocity().dot(collision.normal) > 0) {
|
if (velocity().dot(collision.normal) > 0) {
|
||||||
setVelocity(velocity_perpendicular);
|
setVelocity(velocity_perpendicular);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -326,7 +332,7 @@ void RigidBody::updatePhysicsState() {
|
||||||
_velocity = _velocity + _acceleration * Time::deltaTime();
|
_velocity = _velocity + _acceleration * Time::deltaTime();
|
||||||
}
|
}
|
||||||
|
|
||||||
void RigidBody::setVelocity(const Vec3D& velocity) {
|
void RigidBody::setVelocity(const Vec3D &velocity) {
|
||||||
_velocity = velocity;
|
_velocity = velocity;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -334,7 +340,7 @@ void RigidBody::addVelocity(const Vec3D &velocity) {
|
||||||
_velocity = _velocity + velocity;
|
_velocity = _velocity + velocity;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RigidBody::setAcceleration(const Vec3D& acceleration) {
|
void RigidBody::setAcceleration(const Vec3D &acceleration) {
|
||||||
_acceleration = acceleration;
|
_acceleration = acceleration;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
|
||||||
#include "../Triangle.h"
|
#include "../Triangle.h"
|
||||||
#include "Simplex.h"
|
#include "Simplex.h"
|
||||||
#include "../Mesh.h"
|
#include "../Mesh.h"
|
||||||
|
@ -31,18 +32,26 @@ struct NextSimplex final {
|
||||||
|
|
||||||
class RigidBody : public Mesh {
|
class RigidBody : public Mesh {
|
||||||
private:
|
private:
|
||||||
Vec3D _findFurthestPoint(const Vec3D& direction);
|
Vec3D _findFurthestPoint(const Vec3D &direction);
|
||||||
Vec3D _support(std::shared_ptr<RigidBody> obj, const Vec3D& direction);
|
|
||||||
|
|
||||||
std::function<void(const ObjectNameTag&, std::shared_ptr<RigidBody>)> _collisionCallBack;
|
Vec3D _support(std::shared_ptr<RigidBody> obj, const Vec3D &direction);
|
||||||
|
|
||||||
static NextSimplex _nextSimplex(const Simplex& points);
|
std::function<void(const ObjectNameTag &, std::shared_ptr<RigidBody>)> _collisionCallBack;
|
||||||
static NextSimplex _lineCase(const Simplex& points);
|
|
||||||
static NextSimplex _triangleCase(const Simplex& points);
|
|
||||||
static NextSimplex _tetrahedronCase(const Simplex& points);
|
|
||||||
|
|
||||||
static std::pair<std::vector<FaceNormal>, size_t> _getFaceNormals(const std::vector<Vec3D>& polytope, const std::vector<size_t>& faces);
|
static NextSimplex _nextSimplex(const Simplex &points);
|
||||||
static std::vector<std::pair<size_t, size_t>> _addIfUniqueEdge(const std::vector<std::pair<size_t, size_t>>& edges, const std::vector<size_t>& faces, size_t a, size_t b);
|
|
||||||
|
static NextSimplex _lineCase(const Simplex &points);
|
||||||
|
|
||||||
|
static NextSimplex _triangleCase(const Simplex &points);
|
||||||
|
|
||||||
|
static NextSimplex _tetrahedronCase(const Simplex &points);
|
||||||
|
|
||||||
|
static std::pair<std::vector<FaceNormal>, size_t>
|
||||||
|
_getFaceNormals(const std::vector<Vec3D> &polytope, const std::vector<size_t> &faces);
|
||||||
|
|
||||||
|
static std::vector<std::pair<size_t, size_t>>
|
||||||
|
_addIfUniqueEdge(const std::vector<std::pair<size_t, size_t>> &edges, const std::vector<size_t> &faces, size_t a,
|
||||||
|
size_t b);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Vec3D _velocity{0, 0, 0};
|
Vec3D _velocity{0, 0, 0};
|
||||||
|
@ -56,34 +65,50 @@ protected:
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit RigidBody(ObjectNameTag nameTag) : Mesh(std::move(nameTag)) {};
|
explicit RigidBody(ObjectNameTag nameTag) : Mesh(std::move(nameTag)) {};
|
||||||
explicit RigidBody(const RigidBody& rigidBody) = default;
|
|
||||||
explicit RigidBody(const Mesh& mesh);
|
RigidBody(const RigidBody &rigidBody) = default;
|
||||||
RigidBody(ObjectNameTag nameTag, const std::string& filename, const Vec3D& scale = Vec3D{1, 1, 1});
|
|
||||||
|
explicit RigidBody(const Mesh &mesh);
|
||||||
|
|
||||||
|
RigidBody(ObjectNameTag nameTag, const std::string &filename, const Vec3D &scale = Vec3D{1, 1, 1});
|
||||||
|
|
||||||
[[nodiscard]] std::pair<bool, Simplex> checkGJKCollision(std::shared_ptr<RigidBody> obj);
|
[[nodiscard]] std::pair<bool, Simplex> checkGJKCollision(std::shared_ptr<RigidBody> obj);
|
||||||
[[nodiscard]] CollisionPoint EPA(const Simplex& simplex, std::shared_ptr<RigidBody> obj);
|
|
||||||
void solveCollision(const CollisionPoint& collision);
|
[[nodiscard]] CollisionPoint EPA(const Simplex &simplex, std::shared_ptr<RigidBody> obj);
|
||||||
|
|
||||||
|
void solveCollision(const CollisionPoint &collision);
|
||||||
|
|
||||||
[[nodiscard]] Vec3D collisionNormal() const { return _collisionNormal; }
|
[[nodiscard]] Vec3D collisionNormal() const { return _collisionNormal; }
|
||||||
|
|
||||||
[[nodiscard]] bool isCollision() const { return _collision; }
|
[[nodiscard]] bool isCollision() const { return _collision; }
|
||||||
[[nodiscard]] bool inCollision() const {return _inCollision; }
|
|
||||||
[[nodiscard]] bool isCollider() const {return _isCollider; }
|
[[nodiscard]] bool inCollision() const { return _inCollision; }
|
||||||
|
|
||||||
|
[[nodiscard]] bool isCollider() const { return _isCollider; }
|
||||||
|
|
||||||
void setInCollision(bool c) { _inCollision = c; }
|
void setInCollision(bool c) { _inCollision = c; }
|
||||||
void setCollision(bool c) { _collision= c; }
|
|
||||||
|
void setCollision(bool c) { _collision = c; }
|
||||||
|
|
||||||
void setCollider(bool c) { _isCollider = c; }
|
void setCollider(bool c) { _isCollider = c; }
|
||||||
|
|
||||||
void updatePhysicsState();
|
void updatePhysicsState();
|
||||||
|
|
||||||
void setVelocity(const Vec3D& velocity);
|
void setVelocity(const Vec3D &velocity);
|
||||||
void addVelocity(const Vec3D& velocity);
|
|
||||||
void setAcceleration(const Vec3D& acceleration);
|
void addVelocity(const Vec3D &velocity);
|
||||||
|
|
||||||
|
void setAcceleration(const Vec3D &acceleration);
|
||||||
|
|
||||||
[[nodiscard]] Vec3D velocity() const { return _velocity; }
|
[[nodiscard]] Vec3D velocity() const { return _velocity; }
|
||||||
|
|
||||||
[[nodiscard]] Vec3D acceleration() const { return _acceleration; }
|
[[nodiscard]] Vec3D acceleration() const { return _acceleration; }
|
||||||
|
|
||||||
[[nodiscard]] const std::function<void(const ObjectNameTag&, std::shared_ptr<RigidBody>)>& collisionCallBack() const { return _collisionCallBack; }
|
[[nodiscard]] const std::function<void(const ObjectNameTag &, std::shared_ptr<RigidBody>)> &
|
||||||
void setCollisionCallBack(const std::function<void(const ObjectNameTag& tag, std::shared_ptr<RigidBody>)>& f) { _collisionCallBack = f; }
|
collisionCallBack() const { return _collisionCallBack; }
|
||||||
|
|
||||||
|
void setCollisionCallBack(const std::function<void(const ObjectNameTag &tag,
|
||||||
|
std::shared_ptr<RigidBody>)> &f) { _collisionCallBack = f; }
|
||||||
|
|
||||||
~RigidBody() override = default;
|
~RigidBody() override = default;
|
||||||
};
|
};
|
||||||
|
|
|
@ -5,9 +5,10 @@
|
||||||
#ifndef ENGINE_SIMPLEX_H
|
#ifndef ENGINE_SIMPLEX_H
|
||||||
#define ENGINE_SIMPLEX_H
|
#define ENGINE_SIMPLEX_H
|
||||||
|
|
||||||
#include "../Vec3D.h"
|
|
||||||
#include <list>
|
#include <list>
|
||||||
|
|
||||||
|
#include "../Vec3D.h"
|
||||||
|
|
||||||
enum class SimplexType {
|
enum class SimplexType {
|
||||||
Zero,
|
Zero,
|
||||||
Point,
|
Point,
|
||||||
|
@ -24,30 +25,35 @@ public:
|
||||||
Simplex() = default;
|
Simplex() = default;
|
||||||
|
|
||||||
Simplex(std::initializer_list<Vec3D> list) {
|
Simplex(std::initializer_list<Vec3D> list) {
|
||||||
for (const auto & v : list) {
|
for (const auto &v : list) {
|
||||||
_points.push_back(v);
|
_points.push_back(v);
|
||||||
if(_points.size() > 4)
|
if (_points.size() > 4) {
|
||||||
_points.pop_front();
|
_points.pop_front();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void push_front(const Vec3D& point) {
|
void push_front(const Vec3D &point) {
|
||||||
_points.push_front(point);
|
_points.push_front(point);
|
||||||
if(_points.size() > 4)
|
if (_points.size() > 4) {
|
||||||
_points.pop_back();
|
_points.pop_back();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Vec3D operator[](unsigned i) const {
|
Vec3D operator[](unsigned i) const {
|
||||||
auto it = _points.begin();
|
auto it = _points.begin();
|
||||||
for(unsigned k=0; k<i; k++)
|
for (unsigned k = 0; k < i; k++) {
|
||||||
++it;
|
++it;
|
||||||
|
}
|
||||||
return *it;
|
return *it;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] unsigned size() const { return _points.size(); }
|
[[nodiscard]] unsigned size() const { return _points.size(); }
|
||||||
|
|
||||||
[[nodiscard]] auto begin() const { return _points.begin(); }
|
[[nodiscard]] auto begin() const { return _points.begin(); }
|
||||||
[[nodiscard]] auto end() const { return _points.end(); }
|
|
||||||
|
[[nodiscard]] auto end() const { return _points.end(); }
|
||||||
|
|
||||||
[[nodiscard]] SimplexType type() const { return static_cast<SimplexType>(_points.size()); }
|
[[nodiscard]] SimplexType type() const { return static_cast<SimplexType>(_points.size()); }
|
||||||
};
|
};
|
||||||
|
|
|
@ -4,18 +4,18 @@
|
||||||
|
|
||||||
#define _CRT_SECURE_NO_WARNINGS
|
#define _CRT_SECURE_NO_WARNINGS
|
||||||
|
|
||||||
#include "Log.h"
|
|
||||||
#include "Time.h"
|
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
|
#include "Log.h"
|
||||||
|
#include "Time.h"
|
||||||
#include "../Consts.h"
|
#include "../Consts.h"
|
||||||
|
|
||||||
namespace Log
|
namespace Log {
|
||||||
{
|
void log(const std::string &message) {
|
||||||
void log(const std::string& message) {
|
if (Consts::USE_LOG_FILE) {
|
||||||
if(Consts::USE_LOG_FILE) {
|
|
||||||
std::time_t const now_c = std::time(nullptr);
|
std::time_t const now_c = std::time(nullptr);
|
||||||
auto dt = std::put_time(std::localtime(&now_c), "%F %T");
|
auto dt = std::put_time(std::localtime(&now_c), "%F %T");
|
||||||
|
|
||||||
|
|
|
@ -7,9 +7,8 @@
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
namespace Log
|
namespace Log {
|
||||||
{
|
void log(const std::string &message);
|
||||||
void log(const std::string& message);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -3,12 +3,12 @@
|
||||||
//
|
//
|
||||||
|
|
||||||
#include "Time.h"
|
#include "Time.h"
|
||||||
#include "../Consts.h"
|
|
||||||
#include "Log.h"
|
#include "Log.h"
|
||||||
|
#include "../Consts.h"
|
||||||
|
|
||||||
using namespace std::chrono;
|
using namespace std::chrono;
|
||||||
|
|
||||||
Time* Time::_instance = nullptr;
|
Time *Time::_instance = nullptr;
|
||||||
bool Time::_validInstance = false;
|
bool Time::_validInstance = false;
|
||||||
|
|
||||||
void Time::init() {
|
void Time::init() {
|
||||||
|
@ -19,7 +19,7 @@ void Time::init() {
|
||||||
}
|
}
|
||||||
|
|
||||||
double Time::time() {
|
double Time::time() {
|
||||||
if(!_validInstance) {
|
if (!_validInstance) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,7 +27,7 @@ double Time::time() {
|
||||||
}
|
}
|
||||||
|
|
||||||
double Time::deltaTime() {
|
double Time::deltaTime() {
|
||||||
if(!_validInstance) {
|
if (!_validInstance) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -35,7 +35,7 @@ double Time::deltaTime() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Time::update() {
|
void Time::update() {
|
||||||
if(!_validInstance) {
|
if (!_validInstance) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -44,13 +44,15 @@ void Time::update() {
|
||||||
_instance->_deltaTime = duration<double>(t - _instance->_last).count();
|
_instance->_deltaTime = duration<double>(t - _instance->_last).count();
|
||||||
_instance->_time = duration<double>(t - _instance->_start).count();
|
_instance->_time = duration<double>(t - _instance->_start).count();
|
||||||
// in case when fps < 10 it is useful to decrease _deltaTime (to avoid collision problems)
|
// in case when fps < 10 it is useful to decrease _deltaTime (to avoid collision problems)
|
||||||
if(_instance->_deltaTime > Consts::LARGEST_TIME_STEP)
|
if (_instance->_deltaTime > Consts::LARGEST_TIME_STEP) {
|
||||||
_instance->_deltaTime = Consts::LARGEST_TIME_STEP;
|
_instance->_deltaTime = Consts::LARGEST_TIME_STEP;
|
||||||
|
}
|
||||||
|
|
||||||
_instance->_last = t;
|
_instance->_last = t;
|
||||||
|
|
||||||
if(_instance->_deltaTime > 10000)
|
if (_instance->_deltaTime > 10000) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
_instance->_fpsCounter++;
|
_instance->_fpsCounter++;
|
||||||
if (t - _instance->_fpsStart > _instance->_fpsCountTime) {
|
if (t - _instance->_fpsStart > _instance->_fpsCountTime) {
|
||||||
|
@ -61,7 +63,7 @@ void Time::update() {
|
||||||
}
|
}
|
||||||
|
|
||||||
int Time::fps() {
|
int Time::fps() {
|
||||||
if(!_validInstance) {
|
if (!_validInstance) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
// Cast is faster than floor and has the same behavior for positive numbers
|
// Cast is faster than floor and has the same behavior for positive numbers
|
||||||
|
|
|
@ -23,21 +23,26 @@ private:
|
||||||
double _time = 0;
|
double _time = 0;
|
||||||
double _deltaTime = 0;
|
double _deltaTime = 0;
|
||||||
|
|
||||||
static Time* _instance;
|
static Time *_instance;
|
||||||
static bool _validInstance;
|
static bool _validInstance;
|
||||||
|
|
||||||
Time() = default;
|
Time() = default;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Time(const Time&) = delete;
|
Time(const Time &) = delete;
|
||||||
Time& operator=(Time&) = delete;
|
|
||||||
|
Time &operator=(Time &) = delete;
|
||||||
|
|
||||||
static int fps();
|
static int fps();
|
||||||
|
|
||||||
static double time();
|
static double time();
|
||||||
|
|
||||||
static double deltaTime();
|
static double deltaTime();
|
||||||
|
|
||||||
static void update();
|
static void update();
|
||||||
|
|
||||||
static void init();
|
static void init();
|
||||||
|
|
||||||
static void free();
|
static void free();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -8,5 +8,8 @@
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
Ak47::Ak47() : Weapon(100, 30, 3.0, 0.1, 300, 2.0, ShooterConsts::AK47_FIRE_SOUND, ShooterConsts::AK47_RELOAD_SOUND, ObjectNameTag("ak47"), ShooterConsts::AK47_OBJ, Vec3D{3, 3, 3}, Vec3D{-2.2, 1.0, 1.3}, Vec3D{0, Consts::PI, 0}) {
|
Ak47::Ak47() : Weapon(100, 30, 3.0, 0.1, 300, 2.0,
|
||||||
|
ShooterConsts::AK47_FIRE_SOUND, ShooterConsts::AK47_RELOAD_SOUND,
|
||||||
|
ObjectNameTag("ak47"), ShooterConsts::AK47_OBJ,
|
||||||
|
Vec3D{3, 3, 3}, Vec3D{-2.2, 1.0, 1.3},Vec3D{0, Consts::PI, 0}) {
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,11 @@
|
||||||
|
|
||||||
class Gold_Ak47 final : public Weapon {
|
class Gold_Ak47 final : public Weapon {
|
||||||
public:
|
public:
|
||||||
explicit Gold_Ak47() : Weapon(200, 60, 1.5, 0.05, 600, 1.0, ShooterConsts::GOLD_AK47_FIRE_SOUND, ShooterConsts::GOLD_AK47_RELOAD_SOUND, ObjectNameTag("gold_ak47"), ShooterConsts::GOLD_AK47_OBJ, Vec3D{3, 3, 3}, Vec3D{-2.2, 1.0, 1.3}, Vec3D{0, Consts::PI, 0}) {
|
explicit Gold_Ak47() : Weapon(200, 60, 1.5, 0.05, 600, 1.0,
|
||||||
|
ShooterConsts::GOLD_AK47_FIRE_SOUND,
|
||||||
|
ShooterConsts::GOLD_AK47_RELOAD_SOUND, ObjectNameTag("gold_ak47"),
|
||||||
|
ShooterConsts::GOLD_AK47_OBJ, Vec3D{3, 3, 3}, Vec3D{-2.2, 1.0, 1.3},
|
||||||
|
Vec3D{0, Consts::PI, 0}) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -8,5 +8,8 @@
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
Gun::Gun() : Weapon(30, 6, 2.0, 0.3, 800, 3.0, ShooterConsts::GUN_FIRE_SOUND, ShooterConsts::GUN_RELOAD_SOUND, ObjectNameTag("gun"), ShooterConsts::GUN_OBJ, Vec3D{3, 3, 3}, Vec3D{-1.8, 1.3, 1.8}, Vec3D{0, Consts::PI, 0}) {
|
Gun::Gun() : Weapon(30, 6, 2.0, 0.3, 800, 3.0,
|
||||||
|
ShooterConsts::GUN_FIRE_SOUND, ShooterConsts::GUN_RELOAD_SOUND, ObjectNameTag("gun"),
|
||||||
|
ShooterConsts::GUN_OBJ, Vec3D{3, 3, 3},
|
||||||
|
Vec3D{-1.8, 1.3, 1.8}, Vec3D{0, Consts::PI, 0}) {
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,5 +6,8 @@
|
||||||
#include "Rifle.h"
|
#include "Rifle.h"
|
||||||
#include "../ShooterConsts.h"
|
#include "../ShooterConsts.h"
|
||||||
|
|
||||||
Rifle::Rifle() : Weapon(5, 1, 1.0, 1.0, 30000, 0.5, ShooterConsts::RIFLE_FIRE_SOUND, ShooterConsts::RIFLE_RELOAD_SOUND, ObjectNameTag("rifle"), ShooterConsts::RIFLE_OBJ, Vec3D{3, 3, 3}, Vec3D{-2.3, 1, 1.3}, Vec3D{0, Consts::PI, 0}) {
|
Rifle::Rifle() : Weapon(5, 1, 1.0, 1.0, 30000, 0.5,
|
||||||
|
ShooterConsts::RIFLE_FIRE_SOUND, ShooterConsts::RIFLE_RELOAD_SOUND,
|
||||||
|
ObjectNameTag("rifle"), ShooterConsts::RIFLE_OBJ, Vec3D{3, 3, 3},
|
||||||
|
Vec3D{-2.3, 1, 1.3},Vec3D{0, Consts::PI, 0}) {
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,21 +4,23 @@
|
||||||
|
|
||||||
#include "../engine/ResourceManager.h"
|
#include "../engine/ResourceManager.h"
|
||||||
#include "Shotgun.h"
|
#include "Shotgun.h"
|
||||||
#include "../engine/animation/AFunction.h"
|
|
||||||
#include "../ShooterConsts.h"
|
#include "../ShooterConsts.h"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
Shotgun::Shotgun() : Weapon(15, 1, 1.0, 1.0, 400, 5.0, ShooterConsts::SHOTGUN_FIRE_SOUND, ShooterConsts::SHOTGUN_RELOAD_SOUND, ObjectNameTag("shotgun"), ShooterConsts::SHOTGUN_OBJ, Vec3D{3, 3, 3}, Vec3D{-1.95, 0.8, 1.5}, Vec3D{0, Consts::PI, 0}) {
|
Shotgun::Shotgun() : Weapon(15, 1, 1.0, 1.0, 400, 5.0, ShooterConsts::SHOTGUN_FIRE_SOUND,
|
||||||
|
ShooterConsts::SHOTGUN_RELOAD_SOUND, ObjectNameTag("shotgun"), ShooterConsts::SHOTGUN_OBJ,
|
||||||
|
Vec3D{3, 3, 3}, Vec3D{-1.95, 0.8, 1.5}, Vec3D{0, Consts::PI, 0}) {
|
||||||
}
|
}
|
||||||
|
|
||||||
std::map<ObjectNameTag, double>
|
std::map<ObjectNameTag, double>
|
||||||
Shotgun::processFire(std::function<IntersectionInformation(const Vec3D&, const Vec3D&)> rayCastFunction, const Vec3D& position, const Vec3D& direction) {
|
Shotgun::processFire(std::function<IntersectionInformation(const Vec3D &, const Vec3D &)> rayCastFunction,
|
||||||
|
const Vec3D &position, const Vec3D &direction) {
|
||||||
std::map<ObjectNameTag, double> damagedPlayers;
|
std::map<ObjectNameTag, double> damagedPlayers;
|
||||||
|
|
||||||
for(int i = 0; i < 15; i++) {
|
for (int i = 0; i < 15; i++) {
|
||||||
std::map<ObjectNameTag, double> damaged = addTrace(rayCastFunction, position, direction);
|
std::map<ObjectNameTag, double> damaged = addTrace(rayCastFunction, position, direction);
|
||||||
for(auto& player : damaged) {
|
for (auto &player : damaged) {
|
||||||
damagedPlayers[player.first] += player.second;
|
damagedPlayers[player.first] += player.second;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,10 @@
|
||||||
class Shotgun final : public Weapon {
|
class Shotgun final : public Weapon {
|
||||||
public:
|
public:
|
||||||
explicit Shotgun();
|
explicit Shotgun();
|
||||||
std::map<ObjectNameTag, double> processFire(std::function<IntersectionInformation(const Vec3D&, const Vec3D&)> rayCastFunction, const Vec3D& position, const Vec3D& direction) override;
|
|
||||||
|
std::map<ObjectNameTag, double>
|
||||||
|
processFire(std::function<IntersectionInformation(const Vec3D &, const Vec3D &)> rayCastFunction,
|
||||||
|
const Vec3D &position, const Vec3D &direction) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,14 @@
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
Weapon::Weapon(int initialPack, int clipCapacity, double reloadTime, double fireDelay, double damage, double spreading, std::string fireSound, std::string reloadSound, ObjectNameTag weaponName, const std::string& objFileName, const Vec3D& s, const Vec3D& t, const Vec3D& r) : RigidBody(std::move(weaponName), objFileName), _initialPack(initialPack), _clipCapacity(clipCapacity), _reloadTime(reloadTime), _fireDelay(fireDelay), _damage(damage), _spreading(spreading), _fireSound(std::move(fireSound)), _reloadSound(std::move(reloadSound)) {
|
Weapon::Weapon(int initialPack, int clipCapacity, double reloadTime, double fireDelay, double damage, double spreading,
|
||||||
|
std::string fireSound, std::string reloadSound, ObjectNameTag weaponName, const std::string &objFileName,
|
||||||
|
const Vec3D &s, const Vec3D &t, const Vec3D &r) : RigidBody(std::move(weaponName), objFileName),
|
||||||
|
_initialPack(initialPack), _clipCapacity(clipCapacity),
|
||||||
|
_reloadTime(reloadTime), _fireDelay(fireDelay),
|
||||||
|
_damage(damage), _spreading(spreading),
|
||||||
|
_fireSound(std::move(fireSound)),
|
||||||
|
_reloadSound(std::move(reloadSound)) {
|
||||||
_stockAmmo = _initialPack - _clipCapacity;
|
_stockAmmo = _initialPack - _clipCapacity;
|
||||||
_clipAmmo = _clipCapacity;
|
_clipAmmo = _clipCapacity;
|
||||||
|
|
||||||
|
@ -21,22 +28,24 @@ Weapon::Weapon(int initialPack, int clipCapacity, double reloadTime, double fire
|
||||||
translate(t);
|
translate(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
FireInformation Weapon::fire(std::function<IntersectionInformation(const Vec3D&, const Vec3D&)> rayCastFunction, const Vec3D& position, const Vec3D& direction) {
|
FireInformation Weapon::fire(std::function<IntersectionInformation(const Vec3D &, const Vec3D &)> rayCastFunction,
|
||||||
if(_clipAmmo == 0) {
|
const Vec3D &position, const Vec3D &direction) {
|
||||||
|
if (_clipAmmo == 0) {
|
||||||
reload();
|
reload();
|
||||||
if(_clipAmmo == 0) {
|
if (_clipAmmo == 0) {
|
||||||
SoundController::playSound(SoundTag("noAmmo"), ShooterConsts::NO_AMMO_SOUND);
|
SoundController::playSound(SoundTag("noAmmo"), ShooterConsts::NO_AMMO_SOUND);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(_clipAmmo <= 0 || std::abs(Time::time() - _lastFireTime) < _fireDelay || std::abs(Time::time() - _lastReloadTime) < _reloadTime) {
|
if (_clipAmmo <= 0 || std::abs(Time::time() - _lastFireTime) < _fireDelay ||
|
||||||
|
std::abs(Time::time() - _lastReloadTime) < _reloadTime) {
|
||||||
return FireInformation{std::map<ObjectNameTag, double>(), false};
|
return FireInformation{std::map<ObjectNameTag, double>(), false};
|
||||||
}
|
}
|
||||||
|
|
||||||
_lastFireTime = Time::time();
|
_lastFireTime = Time::time();
|
||||||
_clipAmmo--;
|
_clipAmmo--;
|
||||||
|
|
||||||
if(_clipAmmo == 0) {
|
if (_clipAmmo == 0) {
|
||||||
reload();
|
reload();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -50,7 +59,7 @@ void Weapon::reload() {
|
||||||
if (_stockAmmo == 0 || std::abs(Time::time() - _lastReloadTime) < _reloadTime) {
|
if (_stockAmmo == 0 || std::abs(Time::time() - _lastReloadTime) < _reloadTime) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if(_clipCapacity - _clipAmmo <= _stockAmmo) {
|
if (_clipCapacity - _clipAmmo <= _stockAmmo) {
|
||||||
_stockAmmo -= _clipCapacity - _clipAmmo;
|
_stockAmmo -= _clipCapacity - _clipAmmo;
|
||||||
_clipAmmo = _clipCapacity;
|
_clipAmmo = _clipCapacity;
|
||||||
} else {
|
} else {
|
||||||
|
@ -63,27 +72,34 @@ void Weapon::reload() {
|
||||||
_lastReloadTime = Time::time();
|
_lastReloadTime = Time::time();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::map<ObjectNameTag, double> Weapon::processFire(std::function<IntersectionInformation(const Vec3D&, const Vec3D&)> rayCastFunction, const Vec3D& position, const Vec3D& direction) {
|
std::map<ObjectNameTag, double>
|
||||||
|
Weapon::processFire(std::function<IntersectionInformation(const Vec3D &, const Vec3D &)> rayCastFunction,
|
||||||
|
const Vec3D &position, const Vec3D &direction) {
|
||||||
return addTrace(std::move(rayCastFunction), position, direction);
|
return addTrace(std::move(rayCastFunction), position, direction);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::map<ObjectNameTag, double> Weapon::addTrace(std::function<IntersectionInformation(const Vec3D&, const Vec3D&)> rayCastFunction, const Vec3D& from, const Vec3D& directionTo) {
|
std::map<ObjectNameTag, double>
|
||||||
|
Weapon::addTrace(std::function<IntersectionInformation(const Vec3D &, const Vec3D &)> rayCastFunction,
|
||||||
|
const Vec3D &from, const Vec3D &directionTo) {
|
||||||
std::map<ObjectNameTag, double> damagedPlayers;
|
std::map<ObjectNameTag, double> damagedPlayers;
|
||||||
|
|
||||||
double spreading = _spreading*ShooterConsts::FIRE_DISTANCE/100;
|
double spreading = _spreading * ShooterConsts::FIRE_DISTANCE / 100;
|
||||||
|
|
||||||
//generate random vector
|
//generate random vector
|
||||||
Vec3D randV(spreading*(1.0 - 2.0*(double)rand()/RAND_MAX), spreading*(1.0 - 2.0*(double)rand()/RAND_MAX), spreading*(1.0 - 2.0*(double)rand()/RAND_MAX));
|
Vec3D randV(spreading * (1.0 - 2.0 * (double) rand() / RAND_MAX),
|
||||||
|
spreading * (1.0 - 2.0 * (double) rand() / RAND_MAX),
|
||||||
|
spreading * (1.0 - 2.0 * (double) rand() / RAND_MAX));
|
||||||
|
|
||||||
// damage player
|
// damage player
|
||||||
auto rayCast = rayCastFunction(from, from + directionTo * ShooterConsts::FIRE_DISTANCE + randV);
|
auto rayCast = rayCastFunction(from, from + directionTo * ShooterConsts::FIRE_DISTANCE + randV);
|
||||||
if(rayCast.objectName.str().find("Enemy") != std::string::npos) {
|
if (rayCast.objectName.str().find("Enemy") != std::string::npos) {
|
||||||
damagedPlayers[rayCast.objectName] += _damage / (1.0 + rayCast.distanceToObject);
|
damagedPlayers[rayCast.objectName] += _damage / (1.0 + rayCast.distanceToObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
// add trace line
|
// add trace line
|
||||||
Vec3D lineFrom = position() + model()*Vec3D(triangles().back()[0]);
|
Vec3D lineFrom = position() + model() * Vec3D(triangles().back()[0]);
|
||||||
Vec3D lineTo = rayCast.intersected ? rayCast.pointOfIntersection : position() + -lookAt() * ShooterConsts::FIRE_DISTANCE + randV;
|
Vec3D lineTo = rayCast.intersected ? rayCast.pointOfIntersection : position() +
|
||||||
|
-lookAt() * ShooterConsts::FIRE_DISTANCE + randV;
|
||||||
_addTraceCallBack(lineFrom, lineTo);
|
_addTraceCallBack(lineFrom, lineTo);
|
||||||
|
|
||||||
return damagedPlayers;
|
return damagedPlayers;
|
||||||
|
|
|
@ -37,19 +37,29 @@ private:
|
||||||
double _lastFireTime = std::numeric_limits<double>::min();
|
double _lastFireTime = std::numeric_limits<double>::min();
|
||||||
double _lastReloadTime = std::numeric_limits<double>::min();
|
double _lastReloadTime = std::numeric_limits<double>::min();
|
||||||
|
|
||||||
std::function<void(const Vec3D&, const Vec3D&)> _addTraceCallBack;
|
std::function<void(const Vec3D &, const Vec3D &)> _addTraceCallBack;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
std::map<ObjectNameTag, double> addTrace(std::function<IntersectionInformation(const Vec3D&, const Vec3D&)> rayCastFunction, const Vec3D& position, const Vec3D& direction);
|
std::map<ObjectNameTag, double>
|
||||||
virtual std::map<ObjectNameTag, double> processFire(std::function<IntersectionInformation(const Vec3D&, const Vec3D&)> rayCastFunction, const Vec3D& position, const Vec3D& direction);
|
addTrace(std::function<IntersectionInformation(const Vec3D &, const Vec3D &)> rayCastFunction,
|
||||||
|
const Vec3D &position, const Vec3D &direction);
|
||||||
|
|
||||||
|
virtual std::map<ObjectNameTag, double>
|
||||||
|
processFire(std::function<IntersectionInformation(const Vec3D &, const Vec3D &)> rayCastFunction,
|
||||||
|
const Vec3D &position, const Vec3D &direction);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Weapon(int initialPack, int clipCapacity, double reloadTime, double fireDelay, double damage, double spreading, std::string fireSound, std::string reloadSound, ObjectNameTag weaponName, const std::string& objFileName, const Vec3D& s, const Vec3D& t, const Vec3D& r);
|
Weapon(int initialPack, int clipCapacity, double reloadTime, double fireDelay, double damage, double spreading,
|
||||||
|
std::string fireSound, std::string reloadSound, ObjectNameTag weaponName, const std::string &objFileName,
|
||||||
|
const Vec3D &s, const Vec3D &t, const Vec3D &r);
|
||||||
|
|
||||||
|
FireInformation
|
||||||
|
fire(std::function<IntersectionInformation(const Vec3D &, const Vec3D &)> rayCastFunction, const Vec3D &position,
|
||||||
|
const Vec3D &direction);
|
||||||
|
|
||||||
FireInformation fire(std::function<IntersectionInformation(const Vec3D&, const Vec3D&)> rayCastFunction, const Vec3D& position, const Vec3D& direction);
|
|
||||||
void reload();
|
void reload();
|
||||||
|
|
||||||
[[nodiscard]] std::pair<double, double> balance() const{ return std::make_pair(_clipAmmo, _stockAmmo); }
|
[[nodiscard]] std::pair<double, double> balance() const { return std::make_pair(_clipAmmo, _stockAmmo); }
|
||||||
|
|
||||||
void setAddTraceCallBack(std::function<void(Vec3D, Vec3D)> add) { _addTraceCallBack = std::move(add); }
|
void setAddTraceCallBack(std::function<void(Vec3D, Vec3D)> add) { _addTraceCallBack = std::move(add); }
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue