Huge refactoring v3

master
Vectozavr 2021-10-28 20:58:02 +07:00
parent 31722ca109
commit 870842b682
98 changed files with 1175 additions and 1163 deletions

View File

@ -1,11 +0,0 @@
//
// Created by Иван Ильин on 05.06.2021.
//
#include "Bonus.h"
Bonus::Bonus(const std::string &bonusName, const std::string &filename, const Vec3D &scale) {
_name = bonusName;
loadObj(filename, scale);
setCollider(false);
}

21
Bonus.h
View File

@ -1,21 +0,0 @@
//
// Created by Иван Ильин on 05.06.2021.
//
#ifndef SHOOTER_BONUS_H
#define SHOOTER_BONUS_H
#include "engine/World.h"
#include "Player.h"
class Bonus final : public RigidBody {
private:
std::string _name;
public:
explicit Bonus(const std::string &bonusName, const std::string& filename, const Vec3D& scale = Vec3D{1, 1, 1});
[[nodiscard]] std::string name() const { return _name; }
};
#endif //SHOOTER_3DZAVR_BONUS_H

View File

@ -22,8 +22,6 @@ add_executable(shooter
weapon/Shotgun.h weapon/Shotgun.h
weapon/Gun.cpp weapon/Gun.cpp
weapon/Gun.h weapon/Gun.h
Bonus.cpp
Bonus.h
weapon/Gold_Ak47.h weapon/Gold_Ak47.h
weapon/Rifle.cpp weapon/Rifle.cpp
weapon/Rifle.h weapon/Rifle.h
@ -34,8 +32,8 @@ add_executable(shooter
ShooterConsts.h ShooterConsts.h
# 3d engine: # 3d engine:
engine/Consts.h engine/Consts.h
engine/Point4D.h engine/Vec4D.h
engine/Point4D.cpp engine/Vec4D.cpp
engine/Vec3D.cpp engine/Vec3D.cpp
engine/Vec3D.h engine/Vec3D.h
engine/Vec2D.cpp engine/Vec2D.cpp
@ -97,7 +95,7 @@ add_executable(shooter
engine/network/UDPConnection.h engine/network/UDPConnection.h
engine/network/UDPSocket.cpp engine/network/UDPSocket.cpp
engine/network/UDPSocket.h engine/network/UDPSocket.h
engine/SoundController.cpp engine/SoundController.h) engine/SoundController.cpp engine/SoundController.h ShooterMsgType.h ShooterMsgType.cpp)
if(APPLE OR UNIX) if(APPLE OR UNIX)
include_directories(/usr/local/include) include_directories(/usr/local/include)

View File

@ -6,13 +6,13 @@
#include <utility> #include <utility>
#include "engine/utils/Log.h" #include "engine/utils/Log.h"
#include "Bonus.h"
#include "engine/animation/Timeline.h" #include "engine/animation/Timeline.h"
#include "engine/animation/ATranslateToPoint.h" #include "engine/animation/ATranslateToPoint.h"
#include "ShooterMsgType.h"
void Client::updatePacket() { void Client::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->playerName(); 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());
} }
@ -24,8 +24,9 @@ void Client::processInit(sf::Packet& packet) {
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]);
@ -42,24 +43,23 @@ void Client::processUpdate(sf::Packet& packet) {
while (packet >> targetId >> buf[0] >> buf[1] >> buf[2] >> buf[3] >> buf[4] >> buf[5] >> playerName) { while (packet >> targetId >> buf[0] >> buf[1] >> buf[2] >> buf[3] >> buf[4] >> buf[5] >> playerName) {
if (_players.count(targetId)) { if (_players.count(targetId)) {
std::string tagName = "Player_" + std::to_string(targetId); std::string name = "Enemy_" + std::to_string(targetId);
// old approach (no animation): _players[targetId]->translateToPoint(Vec3D{buf[0], buf[1], buf[2]});
//_players[targetId]->translateToPoint(Vec3D{buf[0], buf[1], buf[2]});
// new approach (linear extrapolational animations)
double duration = 1.0 / Consts::NETWORK_WORLD_UPDATE_RATE;
Timeline::animate(AnimationListTag(tagName + "_linearTranslation"), new ATranslateToPoint(_players[targetId], Vec3D{buf[0], buf[1], buf[2]}, duration, Animation::LoopOut::None, Animation::InterpolationType::linear));
_players[targetId]->setHealth(buf[3]); _players[targetId]->setHealth(buf[3]);
_players[targetId]->rotateToAngle(Vec3D{0, buf[4], 0}); _players[targetId]->rotateToAngle(Vec3D{0, buf[4], 0});
_players[targetId]->setPlayerName(playerName); _players[targetId]->setPlayerNickName(playerName);
auto head = _players[targetId]->attached(ObjectNameTag("head")); auto head = _players[targetId]->attached(ObjectNameTag(name + "_head"));
auto weapon = _players[targetId]->attached(ObjectNameTag("Weapon")); auto weapon = _players[targetId]->attached(ObjectNameTag("Enemy_" + std::to_string(targetId) + "_weapon"));
head->rotateLeft(buf[5] - _players[targetId]->headAngle()); if(head != nullptr) {
weapon->rotateLeft(-(buf[5] - _players[targetId]->headAngle())); head->rotateLeft(buf[5] - _players[targetId]->headAngle());
}
if(weapon != nullptr) {
weapon->rotateLeft(-(buf[5] - _players[targetId]->headAngle()));
}
_players[targetId]->setHeadAngle(buf[5]); _players[targetId]->setHeadAngle(buf[5]);
} else if (targetId == _socket.ownId()) { } else if (targetId == _socket.ownId()) {
@ -73,8 +73,9 @@ void Client::processNewClient(sf::Packet& packet) {
packet >> targetId; packet >> targetId;
if(_spawnPlayerCallBack != nullptr) if(_spawnPlayerCallBack != nullptr) {
_spawnPlayerCallBack(targetId); _spawnPlayerCallBack(targetId);
}
} }
void Client::processDisconnect(sf::Uint16 targetId) { void Client::processDisconnect(sf::Uint16 targetId) {
@ -85,23 +86,26 @@ void Client::processDisconnect(sf::Uint16 targetId) {
} }
void Client::processCustomPacket(MsgType type, sf::Packet& packet) { void Client::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;
ShooterMsgType type;
packet >> type;
switch (type) { switch (type) {
case MsgType::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->playerName(); _lastEvent += _player->playerNickName();
} }
else { else {
_players[buffId[1]]->addKill(); _players[buffId[1]]->addKill();
_lastEvent += _players[buffId[1]]->playerName(); _lastEvent += _players[buffId[1]]->playerNickName();
} }
_lastEvent += " ~> "; _lastEvent += " ~> ";
@ -112,45 +116,51 @@ void Client::processCustomPacket(MsgType type, sf::Packet& packet) {
_player->initWeapons(); _player->initWeapons();
_player->setFullAbility(); _player->setFullAbility();
SoundController::playSound(SoundTag("death"), ShooterConsts::DEATH_SOUND); SoundController::playSound(SoundTag("death"), ShooterConsts::DEATH_SOUND);
_lastEvent += _player->playerName(); _lastEvent += _player->playerNickName();
} }
else { else {
_players[buffId[0]]->addDeath(); _players[buffId[0]]->addDeath();
_lastEvent += _players[buffId[0]]->playerName(); _lastEvent += _players[buffId[0]]->playerNickName();
} }
break; break;
case MsgType::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 MsgType::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]));
}
} }
break; break;
case MsgType::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 MsgType::RemoveBonus: case ShooterMsgType::RemoveBonus:
packet >> tmp; packet >> tmp;
if(_removeBonusCallBack != nullptr) if(_removeBonusCallBack != nullptr) {
_removeBonusCallBack(ObjectNameTag(tmp)); _removeBonusCallBack(ObjectNameTag(tmp));
}
break; break;
case MsgType::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("Client::processCustomPacket: unknown message type " + std::to_string(static_cast<int>(type)));
return; return;
} }
} }
@ -164,7 +174,7 @@ void Client::processDisconnected() {
void Client::damagePlayer(sf::Uint16 targetId, double damage) { void Client::damagePlayer(sf::Uint16 targetId, double damage) {
sf::Packet packet; sf::Packet packet;
packet << MsgType::Damage << targetId << damage; packet << MsgType::Custom << ShooterMsgType::Damage << targetId << damage;
_socket.sendRely(packet, _socket.serverId()); _socket.sendRely(packet, _socket.serverId());
Log::log("Client: damagePlayer " + std::to_string(targetId) + " ( -" + std::to_string(damage) + "hp )"); Log::log("Client: damagePlayer " + std::to_string(targetId) + " ( -" + std::to_string(damage) + "hp )");
@ -173,24 +183,25 @@ void Client::damagePlayer(sf::Uint16 targetId, double damage) {
void Client::addTrace(const Vec3D& from, const Vec3D& to) { void Client::addTrace(const Vec3D& from, const Vec3D& to) {
sf::Packet packet; sf::Packet packet;
packet << MsgType::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 Client::takeBonus(const std::string& bonusName) { void Client::takeBonus(const std::string& bonusName) {
sf::Packet packet; sf::Packet packet;
packet << MsgType::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));
}
} }
void Client::changeWeapon(const std::string &weaponName) { void Client::changeWeapon(const std::string &weaponName) {
sf::Packet packet; sf::Packet packet;
packet << MsgType::ChangeWeapon << weaponName; packet << MsgType::Custom << ShooterMsgType::ChangeWeapon << weaponName;
_socket.sendRely(packet, _socket.serverId()); _socket.sendRely(packet, _socket.serverId());
} }

View File

@ -39,7 +39,7 @@ public:
void processNewClient(sf::Packet& packet) override; void processNewClient(sf::Packet& packet) override;
void processDisconnect(sf::Uint16 targetId) override; void processDisconnect(sf::Uint16 targetId) override;
void processCustomPacket(MsgType type, sf::Packet& packet) override; void processCustomPacket(sf::Packet& packet) override;
void processDisconnected() override; void processDisconnected() override;

View File

@ -7,7 +7,7 @@
#include "engine/ResourceManager.h" #include "engine/ResourceManager.h"
#include "engine/utils/Log.h" #include "engine/utils/Log.h"
Player::Player() { Player::Player(ObjectNameTag name) : RigidBody(name) {
loadObj(ShooterConsts::CUBE_OBJ, Vec3D{0.5, 1.9, 0.5}); loadObj(ShooterConsts::CUBE_OBJ, Vec3D{0.5, 1.9, 0.5});
setAcceleration(Vec3D{0, -ShooterConsts::GRAVITY, 0}); setAcceleration(Vec3D{0, -ShooterConsts::GRAVITY, 0});
setCollision(true); setCollision(true);
@ -18,31 +18,39 @@ Player::Player() {
} }
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());
@ -60,10 +68,10 @@ void Player::addWeapon(std::shared_ptr<Weapon> weapon) {
} }
_weapons.push_back(weapon); _weapons.push_back(weapon);
attach(weapon, ObjectNameTag(weapon->name())); attach(weapon);
_weapons.back()->translate(position()); _weapons.back()->translate(position());
_weapons.back()->rotateRelativePoint(position() + Vec3D{0, 1.8, 0}, Vec3D{0, 1, 0}, _angle->y()); _weapons.back()->rotateRelativePoint(position() + Vec3D{0, 1.8, 0}, Vec3D{0, 1, 0}, _angle.y());
_weapons.back()->rotateRelativePoint(position() + Vec3D{0, 1.8, 0}, left(), headAngle()); _weapons.back()->rotateRelativePoint(position() + Vec3D{0, 1.8, 0}, left(), headAngle());
_weapons.back()->setAddTraceCallBack(_addTraceCallBack); _weapons.back()->setAddTraceCallBack(_addTraceCallBack);
@ -72,8 +80,9 @@ 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()));
}
_removeWeaponCallBack(_weapons[_selectedWeapon]); _removeWeaponCallBack(_weapons[_selectedWeapon]);
_weapons.clear(); _weapons.clear();
@ -99,10 +108,11 @@ 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) {
_selectedWeapon = (_selectedWeapon - 1) % _weapons.size(); _selectedWeapon = (_selectedWeapon - 1) % _weapons.size();
else } else {
_selectedWeapon = _weapons.size() - 1; _selectedWeapon = _weapons.size() - 1;
}
_addWeaponCallBack(_weapons[_selectedWeapon]); _addWeaponCallBack(_weapons[_selectedWeapon]);
Log::log("selectedWeapon " + std::to_string(_selectedWeapon)); Log::log("selectedWeapon " + std::to_string(_selectedWeapon));
SoundController::playSound(SoundTag("changeWeapon"), ShooterConsts::CHANGE_WEAPON_SOUND); SoundController::playSound(SoundTag("changeWeapon"), ShooterConsts::CHANGE_WEAPON_SOUND);

View File

@ -30,7 +30,7 @@ private:
std::vector<std::shared_ptr<Weapon>> _weapons; std::vector<std::shared_ptr<Weapon>> _weapons;
size_t _selectedWeapon = 0; size_t _selectedWeapon = 0;
std::string _name = 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;
@ -41,7 +41,7 @@ private:
std::function<IntersectionInformation(const Vec3D&, const Vec3D&)> _rayCastFunction; std::function<IntersectionInformation(const Vec3D&, const Vec3D&)> _rayCastFunction;
public: public:
Player(); 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; }
@ -100,8 +100,8 @@ public:
void collisionWithObject(const ObjectNameTag& tag, std::shared_ptr<RigidBody> obj); void collisionWithObject(const ObjectNameTag& tag, std::shared_ptr<RigidBody> obj);
[[nodiscard]] std::string playerName() const { return _name; } [[nodiscard]] std::string playerNickName() const { return _nickName; }
void setPlayerName(const std::string& name) { _name = name; } void setPlayerNickName(const std::string& name) { _nickName = name; }
}; };

View File

@ -4,12 +4,10 @@
#include "PlayerController.h" #include "PlayerController.h"
#include "engine/utils/Log.h" #include "engine/utils/Log.h"
#include "engine/animation/AFunction.h"
#include "engine/animation/AWait.h" #include "engine/animation/AWait.h"
#include "engine/animation/ATranslate.h" #include "engine/animation/ATranslate.h"
#include "engine/animation/ATranslateToPoint.h" #include "engine/animation/ATranslateToPoint.h"
#include "engine/animation/Timeline.h" #include "engine/animation/Timeline.h"
#include "engine/animation/ARotate.h"
#include "ShooterConsts.h" #include "ShooterConsts.h"
PlayerController::PlayerController(std::shared_ptr<Player> player, PlayerController::PlayerController(std::shared_ptr<Player> player,
@ -18,13 +16,14 @@ PlayerController::PlayerController(std::shared_ptr<Player> player,
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);
@ -45,52 +44,56 @@ void PlayerController::update() {
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"), new ATranslate(camera, -camera->left() / 6, 0.3,Animation::LoopOut::None, Animation::InterpolationType::cos)); Timeline::animate(AnimationListTag("camera_hor_oscil"), new ATranslate(camera, -camera->left() / 6, 0.3,Animation::LoopOut::None, Animation::InterpolationType::Cos));
Timeline::animate(AnimationListTag("camera_hor_oscil"), new AWait(0)); Timeline::animate(AnimationListTag("camera_hor_oscil"), new AWait(0));
Timeline::animate(AnimationListTag("camera_hor_oscil"), new ATranslate(camera, camera->left() / 6, 0.3, Animation::LoopOut::None, Animation::InterpolationType::cos)); Timeline::animate(AnimationListTag("camera_hor_oscil"), new ATranslate(camera, camera->left() / 6, 0.3, Animation::LoopOut::None, Animation::InterpolationType::Cos));
Timeline::animate(AnimationListTag("camera_vert_oscil"), new ATranslate(camera, -Vec3D{0, 1, 0} / 12, 0.15, Animation::LoopOut::None, Animation::InterpolationType::cos)); Timeline::animate(AnimationListTag("camera_vert_oscil"), new ATranslate(camera, -Vec3D{0, 1, 0} / 12, 0.15, Animation::LoopOut::None, Animation::InterpolationType::Cos));
Timeline::animate(AnimationListTag("camera_vert_oscil"), new AWait(0)); Timeline::animate(AnimationListTag("camera_vert_oscil"), new AWait(0));
Timeline::animate(AnimationListTag("camera_vert_oscil"), new ATranslate(camera, Vec3D{0, 1, 0} / 12, 0.15, Animation::LoopOut::None, Animation::InterpolationType::cos)); Timeline::animate(AnimationListTag("camera_vert_oscil"), new ATranslate(camera, Vec3D{0, 1, 0} / 12, 0.15, Animation::LoopOut::None, Animation::InterpolationType::Cos));
Timeline::animate(AnimationListTag("camera_vert_oscil"), new AWait(0)); Timeline::animate(AnimationListTag("camera_vert_oscil"), new AWait(0));
Timeline::animate(AnimationListTag("camera_vert_oscil"), new ATranslate(camera, -Vec3D{0, 1, 0} / 12, 0.15, Animation::LoopOut::None, Animation::InterpolationType::cos)); Timeline::animate(AnimationListTag("camera_vert_oscil"), new ATranslate(camera, -Vec3D{0, 1, 0} / 12, 0.15, Animation::LoopOut::None, Animation::InterpolationType::Cos));
Timeline::animate(AnimationListTag("camera_vert_oscil"), new AWait(0)); Timeline::animate(AnimationListTag("camera_vert_oscil"), new AWait(0));
Timeline::animate(AnimationListTag("camera_vert_oscil"), new ATranslate(camera, Vec3D{0, 1, 0} / 12, 0.15, Animation::LoopOut::None, Animation::InterpolationType::cos)); Timeline::animate(AnimationListTag("camera_vert_oscil"), new ATranslate(camera, Vec3D{0, 1, 0} / 12, 0.15, Animation::LoopOut::None, Animation::InterpolationType::Cos));
Timeline::animate(AnimationListTag("camera_init"), new ATranslateToPoint( camera, _player->position() + Vec3D{0, 1.8, 0}, 0.3, Animation::LoopOut::None, Animation::InterpolationType::cos)); Timeline::animate(AnimationListTag("camera_init"), new 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"), new ATranslateToPoint( camera, _player->position() + Vec3D{0, 1.8, 0}, 0.15, Animation::LoopOut::None, Animation::InterpolationType::cos)); Timeline::animate(AnimationListTag("camera_init"), new 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});
}
} }
// 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});
}
} }
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});
}
} }
if (_player->ability() > 0 && !_isInSlowMo && Keyboard::isKeyPressed(sf::Keyboard::LShift)) { if (_player->ability() > 0 && !_isInSlowMo && Keyboard::isKeyPressed(sf::Keyboard::LShift)) {
@ -112,19 +115,24 @@ void PlayerController::update() {
bool shot = _player->fire(); bool shot = _player->fire();
if(shot) { if(shot) {
if(!_player->inCollision() && (_player->weaponName() == ObjectNameTag("shotgun"))) if(!_player->inCollision() && (_player->weaponName() == ObjectNameTag("weapon_shotgun"))) {
_player->addVelocity(-camera->lookAt() * 30 * coeff); _player->addVelocity(-camera->lookAt() * 30 * coeff);
}
} }
} }
if (Keyboard::isKeyPressed(sf::Keyboard::Space) && _player->inCollision()) { if (Keyboard::isKeyPressed(sf::Keyboard::Space) && _player->inCollision()) {
// if we just want to jump, we have to add particular speed // if we just want to jump, we have to add particular speed
if (!_isSliding) if (!_isSliding) {
_player->addVelocity(Vec3D{ 0, std::abs(_player->collisionNormal().y()) * sqrt(2 * -_player->acceleration().y() * ShooterConsts::JUMP_HEIGHT) * coeff, 0 }); _player->addVelocity(Vec3D{0, std::abs(_player->collisionNormal().y()) *
// if we want to slide, we have to add speed * 60/fps to make it independent on frame rate sqrt(2 * -_player->acceleration().y() * ShooterConsts::JUMP_HEIGHT) * coeff,
else 0});
_player->addVelocity(Vec3D{ 0, std::abs(_player->collisionNormal().y()) * sqrt(2 * -_player->acceleration().y() * ShooterConsts::JUMP_HEIGHT) * coeff * Time::deltaTime() * 60, 0 }); // if we want to slide, we have to add speed * 60/fps to make it independent on frame rate
} else {
_player->addVelocity(Vec3D{0, std::abs(_player->collisionNormal().y()) *
sqrt(2 * -_player->acceleration().y() * ShooterConsts::JUMP_HEIGHT) * coeff *
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 {
@ -140,16 +148,19 @@ void PlayerController::update() {
double rotationLeft = displacement.y() * ShooterConsts::MOUSE_SENSITIVITY; double rotationLeft = displacement.y() * ShooterConsts::MOUSE_SENSITIVITY;
// You can only see in range [-90 : 90] grad // You can only see in range [-90 : 90] grad
if (_player->headAngle() + rotationLeft > Consts::PI / 2) if (_player->headAngle() + rotationLeft > Consts::PI / 2) {
rotationLeft = Consts::PI / 2 - _player->headAngle(); rotationLeft = Consts::PI / 2 - _player->headAngle();
if (_player->headAngle() + rotationLeft < -Consts::PI / 2) }
if (_player->headAngle() + rotationLeft < -Consts::PI / 2) {
rotationLeft = -Consts::PI / 2 - _player->headAngle(); rotationLeft = -Consts::PI / 2 - _player->headAngle();
}
_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());
}
if (_keyboard->isKeyTapped(sf::Keyboard::Right) || _keyboard->isKeyTapped(sf::Keyboard::E)) { if (_keyboard->isKeyTapped(sf::Keyboard::Right) || _keyboard->isKeyTapped(sf::Keyboard::E)) {
_player->nextWeapon(); _player->nextWeapon();

View File

@ -106,7 +106,7 @@ Static Public Member Functions</h2></td></tr>
<tr class="memdesc:aa917c9435330e6e0368d3893672d1b74"><td class="mdescLeft">&#160;</td><td class="mdescRight">Get the joystick information. <a href="#aa917c9435330e6e0368d3893672d1b74">More...</a><br /></td></tr> <tr class="memdesc:aa917c9435330e6e0368d3893672d1b74"><td class="mdescLeft">&#160;</td><td class="mdescRight">Get the joystick information. <a href="#aa917c9435330e6e0368d3893672d1b74">More...</a><br /></td></tr>
<tr class="separator:aa917c9435330e6e0368d3893672d1b74"><td class="memSeparator" colspan="2">&#160;</td></tr> <tr class="separator:aa917c9435330e6e0368d3893672d1b74"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:ab85fa9175b4edd3e5a07ee3cde0b0f48"><td class="memItemLeft" align="right" valign="top">static void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classsf_1_1Joystick.html#ab85fa9175b4edd3e5a07ee3cde0b0f48">update</a> ()</td></tr> <tr class="memitem:ab85fa9175b4edd3e5a07ee3cde0b0f48"><td class="memItemLeft" align="right" valign="top">static void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classsf_1_1Joystick.html#ab85fa9175b4edd3e5a07ee3cde0b0f48">update</a> ()</td></tr>
<tr class="memdesc:ab85fa9175b4edd3e5a07ee3cde0b0f48"><td class="mdescLeft">&#160;</td><td class="mdescRight">Update the states of all joysticks. <a href="#ab85fa9175b4edd3e5a07ee3cde0b0f48">More...</a><br /></td></tr> <tr class="memdesc:ab85fa9175b4edd3e5a07ee3cde0b0f48"><td class="mdescLeft">&#160;</td><td class="mdescRight">ServerUpdate the states of all joysticks. <a href="#ab85fa9175b4edd3e5a07ee3cde0b0f48">More...</a><br /></td></tr>
<tr class="separator:ab85fa9175b4edd3e5a07ee3cde0b0f48"><td class="memSeparator" colspan="2">&#160;</td></tr> <tr class="separator:ab85fa9175b4edd3e5a07ee3cde0b0f48"><td class="memSeparator" colspan="2">&#160;</td></tr>
</table> </table>
<a name="details" id="details"></a><h2 class="groupheader">Detailed Description</h2> <a name="details" id="details"></a><h2 class="groupheader">Detailed Description</h2>
@ -119,7 +119,7 @@ Static Public Member Functions</h2></td></tr>
<li>32 buttons per joystick (<a class="el" href="classsf_1_1Joystick.html#aee00dd432eacd8369d279b47c3ab4cc5a2f1b8a0a59f2c12a4775c0e1e69e1816" title="Maximum number of supported buttons. ">sf::Joystick::ButtonCount</a>) </li> <li>32 buttons per joystick (<a class="el" href="classsf_1_1Joystick.html#aee00dd432eacd8369d279b47c3ab4cc5a2f1b8a0a59f2c12a4775c0e1e69e1816" title="Maximum number of supported buttons. ">sf::Joystick::ButtonCount</a>) </li>
<li>8 axes per joystick (<a class="el" href="classsf_1_1Joystick.html#aee00dd432eacd8369d279b47c3ab4cc5accf3e487c9f6ee2f384351323626a42c" title="Maximum number of supported axes. ">sf::Joystick::AxisCount</a>)</li> <li>8 axes per joystick (<a class="el" href="classsf_1_1Joystick.html#aee00dd432eacd8369d279b47c3ab4cc5accf3e487c9f6ee2f384351323626a42c" title="Maximum number of supported axes. ">sf::Joystick::AxisCount</a>)</li>
</ul> </ul>
<p>Unlike the keyboard or mouse, the state of joysticks is sometimes not directly available (depending on the OS), therefore an <a class="el" href="classsf_1_1Joystick.html#ab85fa9175b4edd3e5a07ee3cde0b0f48" title="Update the states of all joysticks. ">update()</a> function must be called in order to update the current state of joysticks. When you have a window with event handling, this is done automatically, you don't need to call anything. But if you have no window, or if you want to check joysticks state before creating one, you must call <a class="el" href="classsf_1_1Joystick.html#ab85fa9175b4edd3e5a07ee3cde0b0f48" title="Update the states of all joysticks. ">sf::Joystick::update</a> explicitly.</p> <p>Unlike the keyboard or mouse, the state of joysticks is sometimes not directly available (depending on the OS), therefore an <a class="el" href="classsf_1_1Joystick.html#ab85fa9175b4edd3e5a07ee3cde0b0f48" title="ServerUpdate the states of all joysticks. ">update()</a> function must be called in order to update the current state of joysticks. When you have a window with event handling, this is done automatically, you don't need to call anything. But if you have no window, or if you want to check joysticks state before creating one, you must call <a class="el" href="classsf_1_1Joystick.html#ab85fa9175b4edd3e5a07ee3cde0b0f48" title="ServerUpdate the states of all joysticks. ">sf::Joystick::update</a> explicitly.</p>
<p>Usage example: </p><div class="fragment"><div class="line"><span class="comment">// Is joystick #0 connected?</span></div><div class="line"><span class="keywordtype">bool</span> connected = <a class="code" href="classsf_1_1Joystick.html#ac7d4e1923e9f9420174f26703ea63d6c">sf::Joystick::isConnected</a>(0);</div><div class="line"></div><div class="line"><span class="comment">// How many buttons does joystick #0 support?</span></div><div class="line"><span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> buttons = <a class="code" href="classsf_1_1Joystick.html#a4de9f445c6582bfe9f0873f695682885">sf::Joystick::getButtonCount</a>(0);</div><div class="line"></div><div class="line"><span class="comment">// Does joystick #0 define a X axis?</span></div><div class="line"><span class="keywordtype">bool</span> hasX = <a class="code" href="classsf_1_1Joystick.html#a268e8f2a11ae6af4a47c727cb4ab4d95">sf::Joystick::hasAxis</a>(0, <a class="code" href="classsf_1_1Joystick.html#a48db337092c2e263774f94de6d50baa7a95dc8b9bf7b0a2157fc67891c54c401e">sf::Joystick::X</a>);</div><div class="line"></div><div class="line"><span class="comment">// Is button #2 pressed on joystick #0?</span></div><div class="line"><span class="keywordtype">bool</span> pressed = <a class="code" href="classsf_1_1Joystick.html#ae0d97a4b84268cbe6a7078e1b2717835">sf::Joystick::isButtonPressed</a>(0, 2);</div><div class="line"></div><div class="line"><span class="comment">// What&#39;s the current position of the Y axis on joystick #0?</span></div><div class="line"><span class="keywordtype">float</span> position = <a class="code" href="classsf_1_1Joystick.html#aea4930193331df1851b709f3060ba58b">sf::Joystick::getAxisPosition</a>(0, <a class="code" href="classsf_1_1Joystick.html#a48db337092c2e263774f94de6d50baa7a51ef1455f7511ad4a78ba241d66593ce">sf::Joystick::Y</a>);</div></div><!-- fragment --><dl class="section see"><dt>See also</dt><dd><a class="el" href="classsf_1_1Keyboard.html" title="Give access to the real-time state of the keyboard. ">sf::Keyboard</a>, <a class="el" href="classsf_1_1Mouse.html" title="Give access to the real-time state of the mouse. ">sf::Mouse</a> </dd></dl> <p>Usage example: </p><div class="fragment"><div class="line"><span class="comment">// Is joystick #0 connected?</span></div><div class="line"><span class="keywordtype">bool</span> connected = <a class="code" href="classsf_1_1Joystick.html#ac7d4e1923e9f9420174f26703ea63d6c">sf::Joystick::isConnected</a>(0);</div><div class="line"></div><div class="line"><span class="comment">// How many buttons does joystick #0 support?</span></div><div class="line"><span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> buttons = <a class="code" href="classsf_1_1Joystick.html#a4de9f445c6582bfe9f0873f695682885">sf::Joystick::getButtonCount</a>(0);</div><div class="line"></div><div class="line"><span class="comment">// Does joystick #0 define a X axis?</span></div><div class="line"><span class="keywordtype">bool</span> hasX = <a class="code" href="classsf_1_1Joystick.html#a268e8f2a11ae6af4a47c727cb4ab4d95">sf::Joystick::hasAxis</a>(0, <a class="code" href="classsf_1_1Joystick.html#a48db337092c2e263774f94de6d50baa7a95dc8b9bf7b0a2157fc67891c54c401e">sf::Joystick::X</a>);</div><div class="line"></div><div class="line"><span class="comment">// Is button #2 pressed on joystick #0?</span></div><div class="line"><span class="keywordtype">bool</span> pressed = <a class="code" href="classsf_1_1Joystick.html#ae0d97a4b84268cbe6a7078e1b2717835">sf::Joystick::isButtonPressed</a>(0, 2);</div><div class="line"></div><div class="line"><span class="comment">// What&#39;s the current position of the Y axis on joystick #0?</span></div><div class="line"><span class="keywordtype">float</span> position = <a class="code" href="classsf_1_1Joystick.html#aea4930193331df1851b709f3060ba58b">sf::Joystick::getAxisPosition</a>(0, <a class="code" href="classsf_1_1Joystick.html#a48db337092c2e263774f94de6d50baa7a51ef1455f7511ad4a78ba241d66593ce">sf::Joystick::Y</a>);</div></div><!-- fragment --><dl class="section see"><dt>See also</dt><dd><a class="el" href="classsf_1_1Keyboard.html" title="Give access to the real-time state of the keyboard. ">sf::Keyboard</a>, <a class="el" href="classsf_1_1Mouse.html" title="Give access to the real-time state of the mouse. ">sf::Mouse</a> </dd></dl>
<p class="definition">Definition at line <a class="el" href="Joystick_8hpp_source.html#l00041">41</a> of file <a class="el" href="Joystick_8hpp_source.html">Joystick.hpp</a>.</p> <p class="definition">Definition at line <a class="el" href="Joystick_8hpp_source.html#l00041">41</a> of file <a class="el" href="Joystick_8hpp_source.html">Joystick.hpp</a>.</p>
@ -457,7 +457,7 @@ Static Public Member Functions</h2></td></tr>
</table> </table>
</div><div class="memdoc"> </div><div class="memdoc">
<p>Update the states of all joysticks. </p> <p>ServerUpdate the states of all joysticks. </p>
<p>This function is used internally by SFML, so you normally don't have to call it explicitly. However, you may need to call it if you have no window yet (or no window at all): in this case the joystick states are not updated automatically. </p> <p>This function is used internally by SFML, so you normally don't have to call it explicitly. However, you may need to call it if you have no window yet (or no window at all): in this case the joystick states are not updated automatically. </p>
</div> </div>

View File

@ -99,7 +99,7 @@ Public Member Functions</h2></td></tr>
<tr class="memdesc:a5da95ecdbce615a80bb78399012508cf"><td class="mdescLeft">&#160;</td><td class="mdescRight">Activate or deactivate the render-texture for rendering. <a href="#a5da95ecdbce615a80bb78399012508cf">More...</a><br /></td></tr> <tr class="memdesc:a5da95ecdbce615a80bb78399012508cf"><td class="mdescLeft">&#160;</td><td class="mdescRight">Activate or deactivate the render-texture for rendering. <a href="#a5da95ecdbce615a80bb78399012508cf">More...</a><br /></td></tr>
<tr class="separator:a5da95ecdbce615a80bb78399012508cf"><td class="memSeparator" colspan="2">&#160;</td></tr> <tr class="separator:a5da95ecdbce615a80bb78399012508cf"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:af92886d5faef3916caff9fa9ab32c555"><td class="memItemLeft" align="right" valign="top">void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classsf_1_1RenderTexture.html#af92886d5faef3916caff9fa9ab32c555">display</a> ()</td></tr> <tr class="memitem:af92886d5faef3916caff9fa9ab32c555"><td class="memItemLeft" align="right" valign="top">void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classsf_1_1RenderTexture.html#af92886d5faef3916caff9fa9ab32c555">display</a> ()</td></tr>
<tr class="memdesc:af92886d5faef3916caff9fa9ab32c555"><td class="mdescLeft">&#160;</td><td class="mdescRight">Update the contents of the target texture. <a href="#af92886d5faef3916caff9fa9ab32c555">More...</a><br /></td></tr> <tr class="memdesc:af92886d5faef3916caff9fa9ab32c555"><td class="mdescLeft">&#160;</td><td class="mdescRight">ServerUpdate the contents of the target texture. <a href="#af92886d5faef3916caff9fa9ab32c555">More...</a><br /></td></tr>
<tr class="separator:af92886d5faef3916caff9fa9ab32c555"><td class="memSeparator" colspan="2">&#160;</td></tr> <tr class="separator:af92886d5faef3916caff9fa9ab32c555"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a6685315b5c4c25a5dcb75b4280b381ba"><td class="memItemLeft" align="right" valign="top">virtual <a class="el" href="classsf_1_1Vector2.html">Vector2u</a>&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classsf_1_1RenderTexture.html#a6685315b5c4c25a5dcb75b4280b381ba">getSize</a> () const</td></tr> <tr class="memitem:a6685315b5c4c25a5dcb75b4280b381ba"><td class="memItemLeft" align="right" valign="top">virtual <a class="el" href="classsf_1_1Vector2.html">Vector2u</a>&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classsf_1_1RenderTexture.html#a6685315b5c4c25a5dcb75b4280b381ba">getSize</a> () const</td></tr>
<tr class="memdesc:a6685315b5c4c25a5dcb75b4280b381ba"><td class="mdescLeft">&#160;</td><td class="mdescRight">Return the size of the rendering region of the texture. <a href="#a6685315b5c4c25a5dcb75b4280b381ba">More...</a><br /></td></tr> <tr class="memdesc:a6685315b5c4c25a5dcb75b4280b381ba"><td class="mdescLeft">&#160;</td><td class="mdescRight">Return the size of the rendering region of the texture. <a href="#a6685315b5c4c25a5dcb75b4280b381ba">More...</a><br /></td></tr>
@ -376,7 +376,7 @@ Protected Member Functions</h2></td></tr>
</table> </table>
</div><div class="memdoc"> </div><div class="memdoc">
<p>Update the contents of the target texture. </p> <p>ServerUpdate the contents of the target texture. </p>
<p>This function updates the target texture with what has been drawn so far. Like for windows, calling this function is mandatory at the end of rendering. Not calling it may leave the texture in an undefined state. </p> <p>This function updates the target texture with what has been drawn so far. Like for windows, calling this function is mandatory at the end of rendering. Not calling it may leave the texture in an undefined state. </p>
</div> </div>

View File

@ -403,7 +403,7 @@ Protected Member Functions</h2></td></tr>
</div><div class="memdoc"> </div><div class="memdoc">
<p>Copy the current contents of the window to an image. </p> <p>Copy the current contents of the window to an image. </p>
<dl class="deprecated"><dt><b><a class="el" href="deprecated.html#_deprecated000005">Deprecated:</a></b></dt><dd>Use a <a class="el" href="classsf_1_1Texture.html" title="Image living on the graphics card that can be used for drawing. ">sf::Texture</a> and its <a class="el" href="classsf_1_1Texture.html#ad3cceef238f7d5d2108a98dd38c17fc5" title="Update the texture from the contents of a window. ">sf::Texture::update(const Window&amp;)</a> function and copy its contents into an <a class="el" href="classsf_1_1Image.html" title="Class for loading, manipulating and saving images. ">sf::Image</a> instead. </dd></dl> <dl class="deprecated"><dt><b><a class="el" href="deprecated.html#_deprecated000005">Deprecated:</a></b></dt><dd>Use a <a class="el" href="classsf_1_1Texture.html" title="Image living on the graphics card that can be used for drawing. ">sf::Texture</a> and its <a class="el" href="classsf_1_1Texture.html#ad3cceef238f7d5d2108a98dd38c17fc5" title="ServerUpdate the texture from the contents of a window. ">sf::Texture::update(const Window&amp;)</a> function and copy its contents into an <a class="el" href="classsf_1_1Image.html" title="Class for loading, manipulating and saving images. ">sf::Image</a> instead. </dd></dl>
<div class="fragment"><div class="line"><a class="code" href="classsf_1_1Vector2.html">sf::Vector2u</a> windowSize = window.<a class="code" href="classsf_1_1Window.html#a3969926741cbe83d7f9eeaf5333d4e71">getSize</a>();</div><div class="line"><a class="code" href="classsf_1_1Texture.html">sf::Texture</a> texture;</div><div class="line">texture.<a class="code" href="classsf_1_1Texture.html#a89b4c7d204acf1033c3a1b6e0a3ad0a3">create</a>(windowSize.<a class="code" href="classsf_1_1Vector2.html#a1e6ad77fa155f3753bfb92699bd28141">x</a>, windowSize.<a class="code" href="classsf_1_1Vector2.html#a420f2481b015f4eb929c75f2af564299">y</a>);</div><div class="line">texture.<a class="code" href="classsf_1_1Texture.html#ae4eab5c6781316840b0c50ad08370963">update</a>(window);</div><div class="line"><a class="code" href="classsf_1_1Image.html">sf::Image</a> screenshot = texture.<a class="code" href="classsf_1_1Texture.html#a77e18a70de2e525ac5e4a7cd95f614b9">copyToImage</a>();</div></div><!-- fragment --><p>This is a slow operation, whose main purpose is to make screenshots of the application. If you want to update an image with the contents of the window and then use it for drawing, you should rather use a <a class="el" href="classsf_1_1Texture.html" title="Image living on the graphics card that can be used for drawing. ">sf::Texture</a> and its update(Window&amp;) function. You can also draw things directly to a texture with the <a class="el" href="classsf_1_1RenderTexture.html" title="Target for off-screen 2D rendering into a texture. ">sf::RenderTexture</a> class.</p> <div class="fragment"><div class="line"><a class="code" href="classsf_1_1Vector2.html">sf::Vector2u</a> windowSize = window.<a class="code" href="classsf_1_1Window.html#a3969926741cbe83d7f9eeaf5333d4e71">getSize</a>();</div><div class="line"><a class="code" href="classsf_1_1Texture.html">sf::Texture</a> texture;</div><div class="line">texture.<a class="code" href="classsf_1_1Texture.html#a89b4c7d204acf1033c3a1b6e0a3ad0a3">create</a>(windowSize.<a class="code" href="classsf_1_1Vector2.html#a1e6ad77fa155f3753bfb92699bd28141">x</a>, windowSize.<a class="code" href="classsf_1_1Vector2.html#a420f2481b015f4eb929c75f2af564299">y</a>);</div><div class="line">texture.<a class="code" href="classsf_1_1Texture.html#ae4eab5c6781316840b0c50ad08370963">update</a>(window);</div><div class="line"><a class="code" href="classsf_1_1Image.html">sf::Image</a> screenshot = texture.<a class="code" href="classsf_1_1Texture.html#a77e18a70de2e525ac5e4a7cd95f614b9">copyToImage</a>();</div></div><!-- fragment --><p>This is a slow operation, whose main purpose is to make screenshots of the application. If you want to update an image with the contents of the window and then use it for drawing, you should rather use a <a class="el" href="classsf_1_1Texture.html" title="Image living on the graphics card that can be used for drawing. ">sf::Texture</a> and its update(Window&amp;) function. You can also draw things directly to a texture with the <a class="el" href="classsf_1_1RenderTexture.html" title="Target for off-screen 2D rendering into a texture. ">sf::RenderTexture</a> class.</p>
<dl class="section return"><dt>Returns</dt><dd><a class="el" href="classsf_1_1Image.html" title="Class for loading, manipulating and saving images. ">Image</a> containing the captured contents </dd></dl> <dl class="section return"><dt>Returns</dt><dd><a class="el" href="classsf_1_1Image.html" title="Class for loading, manipulating and saving images. ">Image</a> containing the captured contents </dd></dl>

View File

@ -108,28 +108,28 @@ Public Member Functions</h2></td></tr>
<tr class="memdesc:a77e18a70de2e525ac5e4a7cd95f614b9"><td class="mdescLeft">&#160;</td><td class="mdescRight">Copy the texture pixels to an image. <a href="#a77e18a70de2e525ac5e4a7cd95f614b9">More...</a><br /></td></tr> <tr class="memdesc:a77e18a70de2e525ac5e4a7cd95f614b9"><td class="mdescLeft">&#160;</td><td class="mdescRight">Copy the texture pixels to an image. <a href="#a77e18a70de2e525ac5e4a7cd95f614b9">More...</a><br /></td></tr>
<tr class="separator:a77e18a70de2e525ac5e4a7cd95f614b9"><td class="memSeparator" colspan="2">&#160;</td></tr> <tr class="separator:a77e18a70de2e525ac5e4a7cd95f614b9"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:ae4eab5c6781316840b0c50ad08370963"><td class="memItemLeft" align="right" valign="top">void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classsf_1_1Texture.html#ae4eab5c6781316840b0c50ad08370963">update</a> (const Uint8 *pixels)</td></tr> <tr class="memitem:ae4eab5c6781316840b0c50ad08370963"><td class="memItemLeft" align="right" valign="top">void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classsf_1_1Texture.html#ae4eab5c6781316840b0c50ad08370963">update</a> (const Uint8 *pixels)</td></tr>
<tr class="memdesc:ae4eab5c6781316840b0c50ad08370963"><td class="mdescLeft">&#160;</td><td class="mdescRight">Update the whole texture from an array of pixels. <a href="#ae4eab5c6781316840b0c50ad08370963">More...</a><br /></td></tr> <tr class="memdesc:ae4eab5c6781316840b0c50ad08370963"><td class="mdescLeft">&#160;</td><td class="mdescRight">ServerUpdate the whole texture from an array of pixels. <a href="#ae4eab5c6781316840b0c50ad08370963">More...</a><br /></td></tr>
<tr class="separator:ae4eab5c6781316840b0c50ad08370963"><td class="memSeparator" colspan="2">&#160;</td></tr> <tr class="separator:ae4eab5c6781316840b0c50ad08370963"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a1352d8e16c2aeb4df586ed65dd2c36b9"><td class="memItemLeft" align="right" valign="top">void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classsf_1_1Texture.html#a1352d8e16c2aeb4df586ed65dd2c36b9">update</a> (const Uint8 *pixels, unsigned int width, unsigned int height, unsigned int x, unsigned int y)</td></tr> <tr class="memitem:a1352d8e16c2aeb4df586ed65dd2c36b9"><td class="memItemLeft" align="right" valign="top">void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classsf_1_1Texture.html#a1352d8e16c2aeb4df586ed65dd2c36b9">update</a> (const Uint8 *pixels, unsigned int width, unsigned int height, unsigned int x, unsigned int y)</td></tr>
<tr class="memdesc:a1352d8e16c2aeb4df586ed65dd2c36b9"><td class="mdescLeft">&#160;</td><td class="mdescRight">Update a part of the texture from an array of pixels. <a href="#a1352d8e16c2aeb4df586ed65dd2c36b9">More...</a><br /></td></tr> <tr class="memdesc:a1352d8e16c2aeb4df586ed65dd2c36b9"><td class="mdescLeft">&#160;</td><td class="mdescRight">ServerUpdate a part of the texture from an array of pixels. <a href="#a1352d8e16c2aeb4df586ed65dd2c36b9">More...</a><br /></td></tr>
<tr class="separator:a1352d8e16c2aeb4df586ed65dd2c36b9"><td class="memSeparator" colspan="2">&#160;</td></tr> <tr class="separator:a1352d8e16c2aeb4df586ed65dd2c36b9"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:af9885ca00b74950d60feea28132d9691"><td class="memItemLeft" align="right" valign="top">void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classsf_1_1Texture.html#af9885ca00b74950d60feea28132d9691">update</a> (const <a class="el" href="classsf_1_1Texture.html">Texture</a> &amp;texture)</td></tr> <tr class="memitem:af9885ca00b74950d60feea28132d9691"><td class="memItemLeft" align="right" valign="top">void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classsf_1_1Texture.html#af9885ca00b74950d60feea28132d9691">update</a> (const <a class="el" href="classsf_1_1Texture.html">Texture</a> &amp;texture)</td></tr>
<tr class="memdesc:af9885ca00b74950d60feea28132d9691"><td class="mdescLeft">&#160;</td><td class="mdescRight">Update a part of this texture from another texture. <a href="#af9885ca00b74950d60feea28132d9691">More...</a><br /></td></tr> <tr class="memdesc:af9885ca00b74950d60feea28132d9691"><td class="mdescLeft">&#160;</td><td class="mdescRight">ServerUpdate a part of this texture from another texture. <a href="#af9885ca00b74950d60feea28132d9691">More...</a><br /></td></tr>
<tr class="separator:af9885ca00b74950d60feea28132d9691"><td class="memSeparator" colspan="2">&#160;</td></tr> <tr class="separator:af9885ca00b74950d60feea28132d9691"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a89beb474da1da84b5e38c9fc0b441fe4"><td class="memItemLeft" align="right" valign="top">void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classsf_1_1Texture.html#a89beb474da1da84b5e38c9fc0b441fe4">update</a> (const <a class="el" href="classsf_1_1Texture.html">Texture</a> &amp;texture, unsigned int x, unsigned int y)</td></tr> <tr class="memitem:a89beb474da1da84b5e38c9fc0b441fe4"><td class="memItemLeft" align="right" valign="top">void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classsf_1_1Texture.html#a89beb474da1da84b5e38c9fc0b441fe4">update</a> (const <a class="el" href="classsf_1_1Texture.html">Texture</a> &amp;texture, unsigned int x, unsigned int y)</td></tr>
<tr class="memdesc:a89beb474da1da84b5e38c9fc0b441fe4"><td class="mdescLeft">&#160;</td><td class="mdescRight">Update a part of this texture from another texture. <a href="#a89beb474da1da84b5e38c9fc0b441fe4">More...</a><br /></td></tr> <tr class="memdesc:a89beb474da1da84b5e38c9fc0b441fe4"><td class="mdescLeft">&#160;</td><td class="mdescRight">ServerUpdate a part of this texture from another texture. <a href="#a89beb474da1da84b5e38c9fc0b441fe4">More...</a><br /></td></tr>
<tr class="separator:a89beb474da1da84b5e38c9fc0b441fe4"><td class="memSeparator" colspan="2">&#160;</td></tr> <tr class="separator:a89beb474da1da84b5e38c9fc0b441fe4"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a037cdf171af0fb392d07626a44a4ea17"><td class="memItemLeft" align="right" valign="top">void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classsf_1_1Texture.html#a037cdf171af0fb392d07626a44a4ea17">update</a> (const <a class="el" href="classsf_1_1Image.html">Image</a> &amp;image)</td></tr> <tr class="memitem:a037cdf171af0fb392d07626a44a4ea17"><td class="memItemLeft" align="right" valign="top">void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classsf_1_1Texture.html#a037cdf171af0fb392d07626a44a4ea17">update</a> (const <a class="el" href="classsf_1_1Image.html">Image</a> &amp;image)</td></tr>
<tr class="memdesc:a037cdf171af0fb392d07626a44a4ea17"><td class="mdescLeft">&#160;</td><td class="mdescRight">Update the texture from an image. <a href="#a037cdf171af0fb392d07626a44a4ea17">More...</a><br /></td></tr> <tr class="memdesc:a037cdf171af0fb392d07626a44a4ea17"><td class="mdescLeft">&#160;</td><td class="mdescRight">ServerUpdate the texture from an image. <a href="#a037cdf171af0fb392d07626a44a4ea17">More...</a><br /></td></tr>
<tr class="separator:a037cdf171af0fb392d07626a44a4ea17"><td class="memSeparator" colspan="2">&#160;</td></tr> <tr class="separator:a037cdf171af0fb392d07626a44a4ea17"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a87f916490b757fe900798eedf3abf3ba"><td class="memItemLeft" align="right" valign="top">void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classsf_1_1Texture.html#a87f916490b757fe900798eedf3abf3ba">update</a> (const <a class="el" href="classsf_1_1Image.html">Image</a> &amp;image, unsigned int x, unsigned int y)</td></tr> <tr class="memitem:a87f916490b757fe900798eedf3abf3ba"><td class="memItemLeft" align="right" valign="top">void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classsf_1_1Texture.html#a87f916490b757fe900798eedf3abf3ba">update</a> (const <a class="el" href="classsf_1_1Image.html">Image</a> &amp;image, unsigned int x, unsigned int y)</td></tr>
<tr class="memdesc:a87f916490b757fe900798eedf3abf3ba"><td class="mdescLeft">&#160;</td><td class="mdescRight">Update a part of the texture from an image. <a href="#a87f916490b757fe900798eedf3abf3ba">More...</a><br /></td></tr> <tr class="memdesc:a87f916490b757fe900798eedf3abf3ba"><td class="mdescLeft">&#160;</td><td class="mdescRight">ServerUpdate a part of the texture from an image. <a href="#a87f916490b757fe900798eedf3abf3ba">More...</a><br /></td></tr>
<tr class="separator:a87f916490b757fe900798eedf3abf3ba"><td class="memSeparator" colspan="2">&#160;</td></tr> <tr class="separator:a87f916490b757fe900798eedf3abf3ba"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:ad3cceef238f7d5d2108a98dd38c17fc5"><td class="memItemLeft" align="right" valign="top">void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classsf_1_1Texture.html#ad3cceef238f7d5d2108a98dd38c17fc5">update</a> (const <a class="el" href="classsf_1_1Window.html">Window</a> &amp;window)</td></tr> <tr class="memitem:ad3cceef238f7d5d2108a98dd38c17fc5"><td class="memItemLeft" align="right" valign="top">void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classsf_1_1Texture.html#ad3cceef238f7d5d2108a98dd38c17fc5">update</a> (const <a class="el" href="classsf_1_1Window.html">Window</a> &amp;window)</td></tr>
<tr class="memdesc:ad3cceef238f7d5d2108a98dd38c17fc5"><td class="mdescLeft">&#160;</td><td class="mdescRight">Update the texture from the contents of a window. <a href="#ad3cceef238f7d5d2108a98dd38c17fc5">More...</a><br /></td></tr> <tr class="memdesc:ad3cceef238f7d5d2108a98dd38c17fc5"><td class="mdescLeft">&#160;</td><td class="mdescRight">ServerUpdate the texture from the contents of a window. <a href="#ad3cceef238f7d5d2108a98dd38c17fc5">More...</a><br /></td></tr>
<tr class="separator:ad3cceef238f7d5d2108a98dd38c17fc5"><td class="memSeparator" colspan="2">&#160;</td></tr> <tr class="separator:ad3cceef238f7d5d2108a98dd38c17fc5"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a154f246eb8059b602076009ab1cfd175"><td class="memItemLeft" align="right" valign="top">void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classsf_1_1Texture.html#a154f246eb8059b602076009ab1cfd175">update</a> (const <a class="el" href="classsf_1_1Window.html">Window</a> &amp;window, unsigned int x, unsigned int y)</td></tr> <tr class="memitem:a154f246eb8059b602076009ab1cfd175"><td class="memItemLeft" align="right" valign="top">void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classsf_1_1Texture.html#a154f246eb8059b602076009ab1cfd175">update</a> (const <a class="el" href="classsf_1_1Window.html">Window</a> &amp;window, unsigned int x, unsigned int y)</td></tr>
<tr class="memdesc:a154f246eb8059b602076009ab1cfd175"><td class="mdescLeft">&#160;</td><td class="mdescRight">Update a part of the texture from the contents of a window. <a href="#a154f246eb8059b602076009ab1cfd175">More...</a><br /></td></tr> <tr class="memdesc:a154f246eb8059b602076009ab1cfd175"><td class="mdescLeft">&#160;</td><td class="mdescRight">ServerUpdate a part of the texture from the contents of a window. <a href="#a154f246eb8059b602076009ab1cfd175">More...</a><br /></td></tr>
<tr class="separator:a154f246eb8059b602076009ab1cfd175"><td class="memSeparator" colspan="2">&#160;</td></tr> <tr class="separator:a154f246eb8059b602076009ab1cfd175"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a0c3bd6825b9a99714f10d44179d74324"><td class="memItemLeft" align="right" valign="top">void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classsf_1_1Texture.html#a0c3bd6825b9a99714f10d44179d74324">setSmooth</a> (bool smooth)</td></tr> <tr class="memitem:a0c3bd6825b9a99714f10d44179d74324"><td class="memItemLeft" align="right" valign="top">void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classsf_1_1Texture.html#a0c3bd6825b9a99714f10d44179d74324">setSmooth</a> (bool smooth)</td></tr>
<tr class="memdesc:a0c3bd6825b9a99714f10d44179d74324"><td class="mdescLeft">&#160;</td><td class="mdescRight">Enable or disable the smooth filter. <a href="#a0c3bd6825b9a99714f10d44179d74324">More...</a><br /></td></tr> <tr class="memdesc:a0c3bd6825b9a99714f10d44179d74324"><td class="mdescLeft">&#160;</td><td class="mdescRight">Enable or disable the smooth filter. <a href="#a0c3bd6825b9a99714f10d44179d74324">More...</a><br /></td></tr>
@ -193,7 +193,7 @@ class&#160;</td><td class="memItemRight" valign="bottom"><b>RenderTarget</b></td
<div class="textblock"><p><a class="el" href="classsf_1_1Image.html" title="Class for loading, manipulating and saving images. ">Image</a> living on the graphics card that can be used for drawing. </p> <div class="textblock"><p><a class="el" href="classsf_1_1Image.html" title="Class for loading, manipulating and saving images. ">Image</a> living on the graphics card that can be used for drawing. </p>
<p><a class="el" href="classsf_1_1Texture.html" title="Image living on the graphics card that can be used for drawing. ">sf::Texture</a> stores pixels that can be drawn, with a sprite for example.</p> <p><a class="el" href="classsf_1_1Texture.html" title="Image living on the graphics card that can be used for drawing. ">sf::Texture</a> stores pixels that can be drawn, with a sprite for example.</p>
<p>A texture lives in the graphics card memory, therefore it is very fast to draw a texture to a render target, or copy a render target to a texture (the graphics card can access both directly).</p> <p>A texture lives in the graphics card memory, therefore it is very fast to draw a texture to a render target, or copy a render target to a texture (the graphics card can access both directly).</p>
<p>Being stored in the graphics card memory has some drawbacks. A texture cannot be manipulated as freely as a <a class="el" href="classsf_1_1Image.html" title="Class for loading, manipulating and saving images. ">sf::Image</a>, you need to prepare the pixels first and then upload them to the texture in a single operation (see <a class="el" href="classsf_1_1Texture.html#ae4eab5c6781316840b0c50ad08370963" title="Update the whole texture from an array of pixels. ">Texture::update</a>).</p> <p>Being stored in the graphics card memory has some drawbacks. A texture cannot be manipulated as freely as a <a class="el" href="classsf_1_1Image.html" title="Class for loading, manipulating and saving images. ">sf::Image</a>, you need to prepare the pixels first and then upload them to the texture in a single operation (see <a class="el" href="classsf_1_1Texture.html#ae4eab5c6781316840b0c50ad08370963" title="ServerUpdate the whole texture from an array of pixels. ">Texture::update</a>).</p>
<p><a class="el" href="classsf_1_1Texture.html" title="Image living on the graphics card that can be used for drawing. ">sf::Texture</a> makes it easy to convert from/to <a class="el" href="classsf_1_1Image.html" title="Class for loading, manipulating and saving images. ">sf::Image</a>, but keep in mind that these calls require transfers between the graphics card and the central memory, therefore they are slow operations.</p> <p><a class="el" href="classsf_1_1Texture.html" title="Image living on the graphics card that can be used for drawing. ">sf::Texture</a> makes it easy to convert from/to <a class="el" href="classsf_1_1Image.html" title="Class for loading, manipulating and saving images. ">sf::Image</a>, but keep in mind that these calls require transfers between the graphics card and the central memory, therefore they are slow operations.</p>
<p>A texture can be loaded from an image, but also directly from a file/memory/stream. The necessary shortcuts are defined so that you don't need an image first for the most common cases. However, if you want to perform some modifications on the pixels before creating the final texture, you can load your file to a <a class="el" href="classsf_1_1Image.html" title="Class for loading, manipulating and saving images. ">sf::Image</a>, do whatever you need with the pixels, and then call <a class="el" href="classsf_1_1Texture.html#abec4567ad9856a3596dc74803f26fba2" title="Load the texture from an image. ">Texture::loadFromImage</a>.</p> <p>A texture can be loaded from an image, but also directly from a file/memory/stream. The necessary shortcuts are defined so that you don't need an image first for the most common cases. However, if you want to perform some modifications on the pixels before creating the final texture, you can load your file to a <a class="el" href="classsf_1_1Image.html" title="Class for loading, manipulating and saving images. ">sf::Image</a>, do whatever you need with the pixels, and then call <a class="el" href="classsf_1_1Texture.html#abec4567ad9856a3596dc74803f26fba2" title="Load the texture from an image. ">Texture::loadFromImage</a>.</p>
<p>Since they live in the graphics card memory, the pixels of a texture cannot be accessed without a slow copy first. And they cannot be accessed individually. Therefore, if you need to read the texture's pixels (like for pixel-perfect collisions), it is recommended to store the collision information separately, for example in an array of booleans.</p> <p>Since they live in the graphics card memory, the pixels of a texture cannot be accessed without a slow copy first. And they cannot be accessed individually. Therefore, if you need to read the texture's pixels (like for pixel-perfect collisions), it is recommended to store the collision information separately, for example in an array of booleans.</p>
@ -886,7 +886,7 @@ class&#160;</td><td class="memItemRight" valign="bottom"><b>RenderTarget</b></td
</table> </table>
</div><div class="memdoc"> </div><div class="memdoc">
<p>Update the whole texture from an array of pixels. </p> <p>ServerUpdate the whole texture from an array of pixels. </p>
<p>The <em>pixel</em> array is assumed to have the same size as the <em>area</em> rectangle, and to contain 32-bits RGBA pixels.</p> <p>The <em>pixel</em> array is assumed to have the same size as the <em>area</em> rectangle, and to contain 32-bits RGBA pixels.</p>
<p>No additional check is performed on the size of the pixel array, passing invalid arguments will lead to an undefined behavior.</p> <p>No additional check is performed on the size of the pixel array, passing invalid arguments will lead to an undefined behavior.</p>
<p>This function does nothing if <em>pixels</em> is null or if the texture was not previously created.</p> <p>This function does nothing if <em>pixels</em> is null or if the texture was not previously created.</p>
@ -943,7 +943,7 @@ class&#160;</td><td class="memItemRight" valign="bottom"><b>RenderTarget</b></td
</table> </table>
</div><div class="memdoc"> </div><div class="memdoc">
<p>Update a part of the texture from an array of pixels. </p> <p>ServerUpdate a part of the texture from an array of pixels. </p>
<p>The size of the <em>pixel</em> array must match the <em>width</em> and <em>height</em> arguments, and it must contain 32-bits RGBA pixels.</p> <p>The size of the <em>pixel</em> array must match the <em>width</em> and <em>height</em> arguments, and it must contain 32-bits RGBA pixels.</p>
<p>No additional check is performed on the size of the pixel array or the bounds of the area to update, passing invalid arguments will lead to an undefined behavior.</p> <p>No additional check is performed on the size of the pixel array or the bounds of the area to update, passing invalid arguments will lead to an undefined behavior.</p>
<p>This function does nothing if <em>pixels</em> is null or if the texture was not previously created.</p> <p>This function does nothing if <em>pixels</em> is null or if the texture was not previously created.</p>
@ -976,7 +976,7 @@ class&#160;</td><td class="memItemRight" valign="bottom"><b>RenderTarget</b></td
</table> </table>
</div><div class="memdoc"> </div><div class="memdoc">
<p>Update a part of this texture from another texture. </p> <p>ServerUpdate a part of this texture from another texture. </p>
<p>Although the source texture can be smaller than this texture, this function is usually used for updating the whole texture. The other overload, which has (x, y) additional arguments, is more convenient for updating a sub-area of this texture.</p> <p>Although the source texture can be smaller than this texture, this function is usually used for updating the whole texture. The other overload, which has (x, y) additional arguments, is more convenient for updating a sub-area of this texture.</p>
<p>No additional check is performed on the size of the passed texture, passing a texture bigger than this texture will lead to an undefined behavior.</p> <p>No additional check is performed on the size of the passed texture, passing a texture bigger than this texture will lead to an undefined behavior.</p>
<p>This function does nothing if either texture was not previously created.</p> <p>This function does nothing if either texture was not previously created.</p>
@ -1021,7 +1021,7 @@ class&#160;</td><td class="memItemRight" valign="bottom"><b>RenderTarget</b></td
</table> </table>
</div><div class="memdoc"> </div><div class="memdoc">
<p>Update a part of this texture from another texture. </p> <p>ServerUpdate a part of this texture from another texture. </p>
<p>No additional check is performed on the size of the texture, passing an invalid combination of texture size and offset will lead to an undefined behavior.</p> <p>No additional check is performed on the size of the texture, passing an invalid combination of texture size and offset will lead to an undefined behavior.</p>
<p>This function does nothing if either texture was not previously created.</p> <p>This function does nothing if either texture was not previously created.</p>
<dl class="params"><dt>Parameters</dt><dd> <dl class="params"><dt>Parameters</dt><dd>
@ -1051,7 +1051,7 @@ class&#160;</td><td class="memItemRight" valign="bottom"><b>RenderTarget</b></td
</table> </table>
</div><div class="memdoc"> </div><div class="memdoc">
<p>Update the texture from an image. </p> <p>ServerUpdate the texture from an image. </p>
<p>Although the source image can be smaller than the texture, this function is usually used for updating the whole texture. The other overload, which has (x, y) additional arguments, is more convenient for updating a sub-area of the texture.</p> <p>Although the source image can be smaller than the texture, this function is usually used for updating the whole texture. The other overload, which has (x, y) additional arguments, is more convenient for updating a sub-area of the texture.</p>
<p>No additional check is performed on the size of the image, passing an image bigger than the texture will lead to an undefined behavior.</p> <p>No additional check is performed on the size of the image, passing an image bigger than the texture will lead to an undefined behavior.</p>
<p>This function does nothing if the texture was not previously created.</p> <p>This function does nothing if the texture was not previously created.</p>
@ -1096,7 +1096,7 @@ class&#160;</td><td class="memItemRight" valign="bottom"><b>RenderTarget</b></td
</table> </table>
</div><div class="memdoc"> </div><div class="memdoc">
<p>Update a part of the texture from an image. </p> <p>ServerUpdate a part of the texture from an image. </p>
<p>No additional check is performed on the size of the image, passing an invalid combination of image size and offset will lead to an undefined behavior.</p> <p>No additional check is performed on the size of the image, passing an invalid combination of image size and offset will lead to an undefined behavior.</p>
<p>This function does nothing if the texture was not previously created.</p> <p>This function does nothing if the texture was not previously created.</p>
<dl class="params"><dt>Parameters</dt><dd> <dl class="params"><dt>Parameters</dt><dd>
@ -1126,7 +1126,7 @@ class&#160;</td><td class="memItemRight" valign="bottom"><b>RenderTarget</b></td
</table> </table>
</div><div class="memdoc"> </div><div class="memdoc">
<p>Update the texture from the contents of a window. </p> <p>ServerUpdate the texture from the contents of a window. </p>
<p>Although the source window can be smaller than the texture, this function is usually used for updating the whole texture. The other overload, which has (x, y) additional arguments, is more convenient for updating a sub-area of the texture.</p> <p>Although the source window can be smaller than the texture, this function is usually used for updating the whole texture. The other overload, which has (x, y) additional arguments, is more convenient for updating a sub-area of the texture.</p>
<p>No additional check is performed on the size of the window, passing a window bigger than the texture will lead to an undefined behavior.</p> <p>No additional check is performed on the size of the window, passing a window bigger than the texture will lead to an undefined behavior.</p>
<p>This function does nothing if either the texture or the window was not previously created.</p> <p>This function does nothing if either the texture or the window was not previously created.</p>
@ -1171,7 +1171,7 @@ class&#160;</td><td class="memItemRight" valign="bottom"><b>RenderTarget</b></td
</table> </table>
</div><div class="memdoc"> </div><div class="memdoc">
<p>Update a part of the texture from the contents of a window. </p> <p>ServerUpdate a part of the texture from the contents of a window. </p>
<p>No additional check is performed on the size of the window, passing an invalid combination of window size and offset will lead to an undefined behavior.</p> <p>No additional check is performed on the size of the window, passing an invalid combination of window size and offset will lead to an undefined behavior.</p>
<p>This function does nothing if either the texture or the window was not previously created.</p> <p>This function does nothing if either the texture or the window was not previously created.</p>
<dl class="params"><dt>Parameters</dt><dd> <dl class="params"><dt>Parameters</dt><dd>

View File

@ -103,10 +103,10 @@ Public Member Functions</h2></td></tr>
<tr class="memdesc:a6c534536ed186a2ad65e75484c8abafe"><td class="mdescLeft">&#160;</td><td class="mdescRight">Return the vertex count. <a href="#a6c534536ed186a2ad65e75484c8abafe">More...</a><br /></td></tr> <tr class="memdesc:a6c534536ed186a2ad65e75484c8abafe"><td class="mdescLeft">&#160;</td><td class="mdescRight">Return the vertex count. <a href="#a6c534536ed186a2ad65e75484c8abafe">More...</a><br /></td></tr>
<tr class="separator:a6c534536ed186a2ad65e75484c8abafe"><td class="memSeparator" colspan="2">&#160;</td></tr> <tr class="separator:a6c534536ed186a2ad65e75484c8abafe"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:ad100a5f578a91c49a9009e3c6956c82d"><td class="memItemLeft" align="right" valign="top">bool&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classsf_1_1VertexBuffer.html#ad100a5f578a91c49a9009e3c6956c82d">update</a> (const <a class="el" href="classsf_1_1Vertex.html">Vertex</a> *vertices)</td></tr> <tr class="memitem:ad100a5f578a91c49a9009e3c6956c82d"><td class="memItemLeft" align="right" valign="top">bool&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classsf_1_1VertexBuffer.html#ad100a5f578a91c49a9009e3c6956c82d">update</a> (const <a class="el" href="classsf_1_1Vertex.html">Vertex</a> *vertices)</td></tr>
<tr class="memdesc:ad100a5f578a91c49a9009e3c6956c82d"><td class="mdescLeft">&#160;</td><td class="mdescRight">Update the whole buffer from an array of vertices. <a href="#ad100a5f578a91c49a9009e3c6956c82d">More...</a><br /></td></tr> <tr class="memdesc:ad100a5f578a91c49a9009e3c6956c82d"><td class="mdescLeft">&#160;</td><td class="mdescRight">ServerUpdate the whole buffer from an array of vertices. <a href="#ad100a5f578a91c49a9009e3c6956c82d">More...</a><br /></td></tr>
<tr class="separator:ad100a5f578a91c49a9009e3c6956c82d"><td class="memSeparator" colspan="2">&#160;</td></tr> <tr class="separator:ad100a5f578a91c49a9009e3c6956c82d"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:ae6c8649a64861507010d21e77fbd53fa"><td class="memItemLeft" align="right" valign="top">bool&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classsf_1_1VertexBuffer.html#ae6c8649a64861507010d21e77fbd53fa">update</a> (const <a class="el" href="classsf_1_1Vertex.html">Vertex</a> *vertices, std::size_t vertexCount, unsigned int offset)</td></tr> <tr class="memitem:ae6c8649a64861507010d21e77fbd53fa"><td class="memItemLeft" align="right" valign="top">bool&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classsf_1_1VertexBuffer.html#ae6c8649a64861507010d21e77fbd53fa">update</a> (const <a class="el" href="classsf_1_1Vertex.html">Vertex</a> *vertices, std::size_t vertexCount, unsigned int offset)</td></tr>
<tr class="memdesc:ae6c8649a64861507010d21e77fbd53fa"><td class="mdescLeft">&#160;</td><td class="mdescRight">Update a part of the buffer from an array of vertices. <a href="#ae6c8649a64861507010d21e77fbd53fa">More...</a><br /></td></tr> <tr class="memdesc:ae6c8649a64861507010d21e77fbd53fa"><td class="mdescLeft">&#160;</td><td class="mdescRight">ServerUpdate a part of the buffer from an array of vertices. <a href="#ae6c8649a64861507010d21e77fbd53fa">More...</a><br /></td></tr>
<tr class="separator:ae6c8649a64861507010d21e77fbd53fa"><td class="memSeparator" colspan="2">&#160;</td></tr> <tr class="separator:ae6c8649a64861507010d21e77fbd53fa"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a41f8bbcf07f403e7fe29b1b905dc7544"><td class="memItemLeft" align="right" valign="top">bool&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classsf_1_1VertexBuffer.html#a41f8bbcf07f403e7fe29b1b905dc7544">update</a> (const <a class="el" href="classsf_1_1VertexBuffer.html">VertexBuffer</a> &amp;vertexBuffer)</td></tr> <tr class="memitem:a41f8bbcf07f403e7fe29b1b905dc7544"><td class="memItemLeft" align="right" valign="top">bool&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classsf_1_1VertexBuffer.html#a41f8bbcf07f403e7fe29b1b905dc7544">update</a> (const <a class="el" href="classsf_1_1VertexBuffer.html">VertexBuffer</a> &amp;vertexBuffer)</td></tr>
<tr class="memdesc:a41f8bbcf07f403e7fe29b1b905dc7544"><td class="mdescLeft">&#160;</td><td class="mdescRight">Copy the contents of another buffer into this buffer. <a href="#a41f8bbcf07f403e7fe29b1b905dc7544">More...</a><br /></td></tr> <tr class="memdesc:a41f8bbcf07f403e7fe29b1b905dc7544"><td class="mdescLeft">&#160;</td><td class="mdescRight">Copy the contents of another buffer into this buffer. <a href="#a41f8bbcf07f403e7fe29b1b905dc7544">More...</a><br /></td></tr>
@ -664,7 +664,7 @@ Static Private Member Functions</h2></td></tr>
</table> </table>
</div><div class="memdoc"> </div><div class="memdoc">
<p>Update the whole buffer from an array of vertices. </p> <p>ServerUpdate the whole buffer from an array of vertices. </p>
<p>The <em>vertex</em> array is assumed to have the same size as the <em>created</em> buffer.</p> <p>The <em>vertex</em> array is assumed to have the same size as the <em>created</em> buffer.</p>
<p>No additional check is performed on the size of the vertex array, passing invalid arguments will lead to undefined behavior.</p> <p>No additional check is performed on the size of the vertex array, passing invalid arguments will lead to undefined behavior.</p>
<p>This function does nothing if <em>vertices</em> is null or if the buffer was not previously created.</p> <p>This function does nothing if <em>vertices</em> is null or if the buffer was not previously created.</p>
@ -710,7 +710,7 @@ Static Private Member Functions</h2></td></tr>
</table> </table>
</div><div class="memdoc"> </div><div class="memdoc">
<p>Update a part of the buffer from an array of vertices. </p> <p>ServerUpdate a part of the buffer from an array of vertices. </p>
<p><code>offset</code> is specified as the number of vertices to skip from the beginning of the buffer.</p> <p><code>offset</code> is specified as the number of vertices to skip from the beginning of the buffer.</p>
<p>If <code>offset</code> is 0 and <code>vertexCount</code> is equal to the size of the currently created buffer, its whole contents are replaced.</p> <p>If <code>offset</code> is 0 and <code>vertexCount</code> is equal to the size of the currently created buffer, its whole contents are replaced.</p>
<p>If <code>offset</code> is 0 and <code>vertexCount</code> is greater than the size of the currently created buffer, a new buffer is created containing the vertex data.</p> <p>If <code>offset</code> is 0 and <code>vertexCount</code> is greater than the size of the currently created buffer, a new buffer is created containing the vertex data.</p>

View File

@ -51,7 +51,7 @@
<dt><a class="anchor" id="_deprecated000004"></a>Member <a class="el" href="classsf_1_1RenderTexture.html#a0e945c4ce7703591c7f240b169744603">sf::RenderTexture::create</a> (unsigned int width, unsigned int height, bool depthBuffer)</dt> <dt><a class="anchor" id="_deprecated000004"></a>Member <a class="el" href="classsf_1_1RenderTexture.html#a0e945c4ce7703591c7f240b169744603">sf::RenderTexture::create</a> (unsigned int width, unsigned int height, bool depthBuffer)</dt>
<dd>Use <a class="el" href="classsf_1_1RenderTexture.html#a49b7b723a80f89bc409a942364351dc3" title="Create the render-texture. ">create(unsigned int, unsigned int, const ContextSettings&amp;)</a> instead. </dd> <dd>Use <a class="el" href="classsf_1_1RenderTexture.html#a49b7b723a80f89bc409a942364351dc3" title="Create the render-texture. ">create(unsigned int, unsigned int, const ContextSettings&amp;)</a> instead. </dd>
<dt><a class="anchor" id="_deprecated000005"></a>Member <a class="el" href="classsf_1_1RenderWindow.html#a5a784b8a09bf4a8bc97ef9e0a8957c35">sf::RenderWindow::capture</a> () const</dt> <dt><a class="anchor" id="_deprecated000005"></a>Member <a class="el" href="classsf_1_1RenderWindow.html#a5a784b8a09bf4a8bc97ef9e0a8957c35">sf::RenderWindow::capture</a> () const</dt>
<dd>Use a <a class="el" href="classsf_1_1Texture.html" title="Image living on the graphics card that can be used for drawing. ">sf::Texture</a> and its <a class="el" href="classsf_1_1Texture.html#ad3cceef238f7d5d2108a98dd38c17fc5" title="Update the texture from the contents of a window. ">sf::Texture::update(const Window&amp;)</a> function and copy its contents into an <a class="el" href="classsf_1_1Image.html" title="Class for loading, manipulating and saving images. ">sf::Image</a> instead. </dd> <dd>Use a <a class="el" href="classsf_1_1Texture.html" title="Image living on the graphics card that can be used for drawing. ">sf::Texture</a> and its <a class="el" href="classsf_1_1Texture.html#ad3cceef238f7d5d2108a98dd38c17fc5" title="ServerUpdate the texture from the contents of a window. ">sf::Texture::update(const Window&amp;)</a> function and copy its contents into an <a class="el" href="classsf_1_1Image.html" title="Class for loading, manipulating and saving images. ">sf::Image</a> instead. </dd>
<dt><a class="anchor" id="_deprecated000012"></a>Member <a class="el" href="classsf_1_1Shader.html#aa8618119ed4399df3fd33e78ee96b4fc">sf::Shader::setParameter</a> (const std::string &amp;name, const <a class="el" href="classsf_1_1Color.html" title="Utility class for manipulating RGBA colors. ">Color</a> &amp;color)</dt> <dt><a class="anchor" id="_deprecated000012"></a>Member <a class="el" href="classsf_1_1Shader.html#aa8618119ed4399df3fd33e78ee96b4fc">sf::Shader::setParameter</a> (const std::string &amp;name, const <a class="el" href="classsf_1_1Color.html" title="Utility class for manipulating RGBA colors. ">Color</a> &amp;color)</dt>
<dd>Use <a class="el" href="classsf_1_1Shader.html#abc1aee8343800680fd62e1f3d43c24bf" title="Specify value for vec4 uniform. ">setUniform(const std::string&amp;, const Glsl::Vec4&amp;)</a> instead. </dd> <dd>Use <a class="el" href="classsf_1_1Shader.html#abc1aee8343800680fd62e1f3d43c24bf" title="Specify value for vec4 uniform. ">setUniform(const std::string&amp;, const Glsl::Vec4&amp;)</a> instead. </dd>
<dt><a class="anchor" id="_deprecated000015"></a>Member <a class="el" href="classsf_1_1Shader.html#af06b4cba0bab915fa01032b063909044">sf::Shader::setParameter</a> (const std::string &amp;name, <a class="el" href="structsf_1_1Shader_1_1CurrentTextureType.html" title="Special type that can be passed to setUniform(), and that represents the texture of the object being ...">CurrentTextureType</a>)</dt> <dt><a class="anchor" id="_deprecated000015"></a>Member <a class="el" href="classsf_1_1Shader.html#af06b4cba0bab915fa01032b063909044">sf::Shader::setParameter</a> (const std::string &amp;name, <a class="el" href="structsf_1_1Shader_1_1CurrentTextureType.html" title="Special type that can be passed to setUniform(), and that represents the texture of the object being ...">CurrentTextureType</a>)</dt>

File diff suppressed because one or more lines are too long

View File

@ -106,7 +106,7 @@ Static Public Member Functions</h2></td></tr>
<tr class="memdesc:aa917c9435330e6e0368d3893672d1b74"><td class="mdescLeft">&#160;</td><td class="mdescRight">Get the joystick information. <a href="#aa917c9435330e6e0368d3893672d1b74">More...</a><br /></td></tr> <tr class="memdesc:aa917c9435330e6e0368d3893672d1b74"><td class="mdescLeft">&#160;</td><td class="mdescRight">Get the joystick information. <a href="#aa917c9435330e6e0368d3893672d1b74">More...</a><br /></td></tr>
<tr class="separator:aa917c9435330e6e0368d3893672d1b74"><td class="memSeparator" colspan="2">&#160;</td></tr> <tr class="separator:aa917c9435330e6e0368d3893672d1b74"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:ab85fa9175b4edd3e5a07ee3cde0b0f48"><td class="memItemLeft" align="right" valign="top">static void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classsf_1_1Joystick.html#ab85fa9175b4edd3e5a07ee3cde0b0f48">update</a> ()</td></tr> <tr class="memitem:ab85fa9175b4edd3e5a07ee3cde0b0f48"><td class="memItemLeft" align="right" valign="top">static void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classsf_1_1Joystick.html#ab85fa9175b4edd3e5a07ee3cde0b0f48">update</a> ()</td></tr>
<tr class="memdesc:ab85fa9175b4edd3e5a07ee3cde0b0f48"><td class="mdescLeft">&#160;</td><td class="mdescRight">Update the states of all joysticks. <a href="#ab85fa9175b4edd3e5a07ee3cde0b0f48">More...</a><br /></td></tr> <tr class="memdesc:ab85fa9175b4edd3e5a07ee3cde0b0f48"><td class="mdescLeft">&#160;</td><td class="mdescRight">ServerUpdate the states of all joysticks. <a href="#ab85fa9175b4edd3e5a07ee3cde0b0f48">More...</a><br /></td></tr>
<tr class="separator:ab85fa9175b4edd3e5a07ee3cde0b0f48"><td class="memSeparator" colspan="2">&#160;</td></tr> <tr class="separator:ab85fa9175b4edd3e5a07ee3cde0b0f48"><td class="memSeparator" colspan="2">&#160;</td></tr>
</table> </table>
<a name="details" id="details"></a><h2 class="groupheader">Detailed Description</h2> <a name="details" id="details"></a><h2 class="groupheader">Detailed Description</h2>
@ -119,7 +119,7 @@ Static Public Member Functions</h2></td></tr>
<li>32 buttons per joystick (<a class="el" href="classsf_1_1Joystick.html#aee00dd432eacd8369d279b47c3ab4cc5a2f1b8a0a59f2c12a4775c0e1e69e1816" title="Maximum number of supported buttons. ">sf::Joystick::ButtonCount</a>) </li> <li>32 buttons per joystick (<a class="el" href="classsf_1_1Joystick.html#aee00dd432eacd8369d279b47c3ab4cc5a2f1b8a0a59f2c12a4775c0e1e69e1816" title="Maximum number of supported buttons. ">sf::Joystick::ButtonCount</a>) </li>
<li>8 axes per joystick (<a class="el" href="classsf_1_1Joystick.html#aee00dd432eacd8369d279b47c3ab4cc5accf3e487c9f6ee2f384351323626a42c" title="Maximum number of supported axes. ">sf::Joystick::AxisCount</a>)</li> <li>8 axes per joystick (<a class="el" href="classsf_1_1Joystick.html#aee00dd432eacd8369d279b47c3ab4cc5accf3e487c9f6ee2f384351323626a42c" title="Maximum number of supported axes. ">sf::Joystick::AxisCount</a>)</li>
</ul> </ul>
<p>Unlike the keyboard or mouse, the state of joysticks is sometimes not directly available (depending on the OS), therefore an <a class="el" href="classsf_1_1Joystick.html#ab85fa9175b4edd3e5a07ee3cde0b0f48" title="Update the states of all joysticks. ">update()</a> function must be called in order to update the current state of joysticks. When you have a window with event handling, this is done automatically, you don't need to call anything. But if you have no window, or if you want to check joysticks state before creating one, you must call <a class="el" href="classsf_1_1Joystick.html#ab85fa9175b4edd3e5a07ee3cde0b0f48" title="Update the states of all joysticks. ">sf::Joystick::update</a> explicitly.</p> <p>Unlike the keyboard or mouse, the state of joysticks is sometimes not directly available (depending on the OS), therefore an <a class="el" href="classsf_1_1Joystick.html#ab85fa9175b4edd3e5a07ee3cde0b0f48" title="ServerUpdate the states of all joysticks. ">update()</a> function must be called in order to update the current state of joysticks. When you have a window with event handling, this is done automatically, you don't need to call anything. But if you have no window, or if you want to check joysticks state before creating one, you must call <a class="el" href="classsf_1_1Joystick.html#ab85fa9175b4edd3e5a07ee3cde0b0f48" title="ServerUpdate the states of all joysticks. ">sf::Joystick::update</a> explicitly.</p>
<p>Usage example: </p><div class="fragment"><div class="line"><span class="comment">// Is joystick #0 connected?</span></div><div class="line"><span class="keywordtype">bool</span> connected = <a class="code" href="classsf_1_1Joystick.html#ac7d4e1923e9f9420174f26703ea63d6c">sf::Joystick::isConnected</a>(0);</div><div class="line"></div><div class="line"><span class="comment">// How many buttons does joystick #0 support?</span></div><div class="line"><span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> buttons = <a class="code" href="classsf_1_1Joystick.html#a4de9f445c6582bfe9f0873f695682885">sf::Joystick::getButtonCount</a>(0);</div><div class="line"></div><div class="line"><span class="comment">// Does joystick #0 define a X axis?</span></div><div class="line"><span class="keywordtype">bool</span> hasX = <a class="code" href="classsf_1_1Joystick.html#a268e8f2a11ae6af4a47c727cb4ab4d95">sf::Joystick::hasAxis</a>(0, <a class="code" href="classsf_1_1Joystick.html#a48db337092c2e263774f94de6d50baa7a95dc8b9bf7b0a2157fc67891c54c401e">sf::Joystick::X</a>);</div><div class="line"></div><div class="line"><span class="comment">// Is button #2 pressed on joystick #0?</span></div><div class="line"><span class="keywordtype">bool</span> pressed = <a class="code" href="classsf_1_1Joystick.html#ae0d97a4b84268cbe6a7078e1b2717835">sf::Joystick::isButtonPressed</a>(0, 2);</div><div class="line"></div><div class="line"><span class="comment">// What&#39;s the current position of the Y axis on joystick #0?</span></div><div class="line"><span class="keywordtype">float</span> position = <a class="code" href="classsf_1_1Joystick.html#aea4930193331df1851b709f3060ba58b">sf::Joystick::getAxisPosition</a>(0, <a class="code" href="classsf_1_1Joystick.html#a48db337092c2e263774f94de6d50baa7a51ef1455f7511ad4a78ba241d66593ce">sf::Joystick::Y</a>);</div></div><!-- fragment --><dl class="section see"><dt>See also</dt><dd><a class="el" href="classsf_1_1Keyboard.html" title="Give access to the real-time state of the keyboard. ">sf::Keyboard</a>, <a class="el" href="classsf_1_1Mouse.html" title="Give access to the real-time state of the mouse. ">sf::Mouse</a> </dd></dl> <p>Usage example: </p><div class="fragment"><div class="line"><span class="comment">// Is joystick #0 connected?</span></div><div class="line"><span class="keywordtype">bool</span> connected = <a class="code" href="classsf_1_1Joystick.html#ac7d4e1923e9f9420174f26703ea63d6c">sf::Joystick::isConnected</a>(0);</div><div class="line"></div><div class="line"><span class="comment">// How many buttons does joystick #0 support?</span></div><div class="line"><span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> buttons = <a class="code" href="classsf_1_1Joystick.html#a4de9f445c6582bfe9f0873f695682885">sf::Joystick::getButtonCount</a>(0);</div><div class="line"></div><div class="line"><span class="comment">// Does joystick #0 define a X axis?</span></div><div class="line"><span class="keywordtype">bool</span> hasX = <a class="code" href="classsf_1_1Joystick.html#a268e8f2a11ae6af4a47c727cb4ab4d95">sf::Joystick::hasAxis</a>(0, <a class="code" href="classsf_1_1Joystick.html#a48db337092c2e263774f94de6d50baa7a95dc8b9bf7b0a2157fc67891c54c401e">sf::Joystick::X</a>);</div><div class="line"></div><div class="line"><span class="comment">// Is button #2 pressed on joystick #0?</span></div><div class="line"><span class="keywordtype">bool</span> pressed = <a class="code" href="classsf_1_1Joystick.html#ae0d97a4b84268cbe6a7078e1b2717835">sf::Joystick::isButtonPressed</a>(0, 2);</div><div class="line"></div><div class="line"><span class="comment">// What&#39;s the current position of the Y axis on joystick #0?</span></div><div class="line"><span class="keywordtype">float</span> position = <a class="code" href="classsf_1_1Joystick.html#aea4930193331df1851b709f3060ba58b">sf::Joystick::getAxisPosition</a>(0, <a class="code" href="classsf_1_1Joystick.html#a48db337092c2e263774f94de6d50baa7a51ef1455f7511ad4a78ba241d66593ce">sf::Joystick::Y</a>);</div></div><!-- fragment --><dl class="section see"><dt>See also</dt><dd><a class="el" href="classsf_1_1Keyboard.html" title="Give access to the real-time state of the keyboard. ">sf::Keyboard</a>, <a class="el" href="classsf_1_1Mouse.html" title="Give access to the real-time state of the mouse. ">sf::Mouse</a> </dd></dl>
<p class="definition">Definition at line <a class="el" href="Joystick_8hpp_source.html#l00041">41</a> of file <a class="el" href="Joystick_8hpp_source.html">Joystick.hpp</a>.</p> <p class="definition">Definition at line <a class="el" href="Joystick_8hpp_source.html#l00041">41</a> of file <a class="el" href="Joystick_8hpp_source.html">Joystick.hpp</a>.</p>
@ -457,7 +457,7 @@ Static Public Member Functions</h2></td></tr>
</table> </table>
</div><div class="memdoc"> </div><div class="memdoc">
<p>Update the states of all joysticks. </p> <p>ServerUpdate the states of all joysticks. </p>
<p>This function is used internally by SFML, so you normally don't have to call it explicitly. However, you may need to call it if you have no window yet (or no window at all): in this case the joystick states are not updated automatically. </p> <p>This function is used internally by SFML, so you normally don't have to call it explicitly. However, you may need to call it if you have no window yet (or no window at all): in this case the joystick states are not updated automatically. </p>
</div> </div>

View File

@ -99,7 +99,7 @@ Public Member Functions</h2></td></tr>
<tr class="memdesc:a5da95ecdbce615a80bb78399012508cf"><td class="mdescLeft">&#160;</td><td class="mdescRight">Activate or deactivate the render-texture for rendering. <a href="#a5da95ecdbce615a80bb78399012508cf">More...</a><br /></td></tr> <tr class="memdesc:a5da95ecdbce615a80bb78399012508cf"><td class="mdescLeft">&#160;</td><td class="mdescRight">Activate or deactivate the render-texture for rendering. <a href="#a5da95ecdbce615a80bb78399012508cf">More...</a><br /></td></tr>
<tr class="separator:a5da95ecdbce615a80bb78399012508cf"><td class="memSeparator" colspan="2">&#160;</td></tr> <tr class="separator:a5da95ecdbce615a80bb78399012508cf"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:af92886d5faef3916caff9fa9ab32c555"><td class="memItemLeft" align="right" valign="top">void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classsf_1_1RenderTexture.html#af92886d5faef3916caff9fa9ab32c555">display</a> ()</td></tr> <tr class="memitem:af92886d5faef3916caff9fa9ab32c555"><td class="memItemLeft" align="right" valign="top">void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classsf_1_1RenderTexture.html#af92886d5faef3916caff9fa9ab32c555">display</a> ()</td></tr>
<tr class="memdesc:af92886d5faef3916caff9fa9ab32c555"><td class="mdescLeft">&#160;</td><td class="mdescRight">Update the contents of the target texture. <a href="#af92886d5faef3916caff9fa9ab32c555">More...</a><br /></td></tr> <tr class="memdesc:af92886d5faef3916caff9fa9ab32c555"><td class="mdescLeft">&#160;</td><td class="mdescRight">ServerUpdate the contents of the target texture. <a href="#af92886d5faef3916caff9fa9ab32c555">More...</a><br /></td></tr>
<tr class="separator:af92886d5faef3916caff9fa9ab32c555"><td class="memSeparator" colspan="2">&#160;</td></tr> <tr class="separator:af92886d5faef3916caff9fa9ab32c555"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a6685315b5c4c25a5dcb75b4280b381ba"><td class="memItemLeft" align="right" valign="top">virtual <a class="el" href="classsf_1_1Vector2.html">Vector2u</a>&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classsf_1_1RenderTexture.html#a6685315b5c4c25a5dcb75b4280b381ba">getSize</a> () const</td></tr> <tr class="memitem:a6685315b5c4c25a5dcb75b4280b381ba"><td class="memItemLeft" align="right" valign="top">virtual <a class="el" href="classsf_1_1Vector2.html">Vector2u</a>&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classsf_1_1RenderTexture.html#a6685315b5c4c25a5dcb75b4280b381ba">getSize</a> () const</td></tr>
<tr class="memdesc:a6685315b5c4c25a5dcb75b4280b381ba"><td class="mdescLeft">&#160;</td><td class="mdescRight">Return the size of the rendering region of the texture. <a href="#a6685315b5c4c25a5dcb75b4280b381ba">More...</a><br /></td></tr> <tr class="memdesc:a6685315b5c4c25a5dcb75b4280b381ba"><td class="mdescLeft">&#160;</td><td class="mdescRight">Return the size of the rendering region of the texture. <a href="#a6685315b5c4c25a5dcb75b4280b381ba">More...</a><br /></td></tr>
@ -376,7 +376,7 @@ Protected Member Functions</h2></td></tr>
</table> </table>
</div><div class="memdoc"> </div><div class="memdoc">
<p>Update the contents of the target texture. </p> <p>ServerUpdate the contents of the target texture. </p>
<p>This function updates the target texture with what has been drawn so far. Like for windows, calling this function is mandatory at the end of rendering. Not calling it may leave the texture in an undefined state. </p> <p>This function updates the target texture with what has been drawn so far. Like for windows, calling this function is mandatory at the end of rendering. Not calling it may leave the texture in an undefined state. </p>
</div> </div>

View File

@ -403,7 +403,7 @@ Protected Member Functions</h2></td></tr>
</div><div class="memdoc"> </div><div class="memdoc">
<p>Copy the current contents of the window to an image. </p> <p>Copy the current contents of the window to an image. </p>
<dl class="deprecated"><dt><b><a class="el" href="deprecated.html#_deprecated000005">Deprecated:</a></b></dt><dd>Use a <a class="el" href="classsf_1_1Texture.html" title="Image living on the graphics card that can be used for drawing. ">sf::Texture</a> and its <a class="el" href="classsf_1_1Texture.html#ad3cceef238f7d5d2108a98dd38c17fc5" title="Update the texture from the contents of a window. ">sf::Texture::update(const Window&amp;)</a> function and copy its contents into an <a class="el" href="classsf_1_1Image.html" title="Class for loading, manipulating and saving images. ">sf::Image</a> instead. </dd></dl> <dl class="deprecated"><dt><b><a class="el" href="deprecated.html#_deprecated000005">Deprecated:</a></b></dt><dd>Use a <a class="el" href="classsf_1_1Texture.html" title="Image living on the graphics card that can be used for drawing. ">sf::Texture</a> and its <a class="el" href="classsf_1_1Texture.html#ad3cceef238f7d5d2108a98dd38c17fc5" title="ServerUpdate the texture from the contents of a window. ">sf::Texture::update(const Window&amp;)</a> function and copy its contents into an <a class="el" href="classsf_1_1Image.html" title="Class for loading, manipulating and saving images. ">sf::Image</a> instead. </dd></dl>
<div class="fragment"><div class="line"><a class="code" href="classsf_1_1Vector2.html">sf::Vector2u</a> windowSize = window.<a class="code" href="classsf_1_1Window.html#a3969926741cbe83d7f9eeaf5333d4e71">getSize</a>();</div><div class="line"><a class="code" href="classsf_1_1Texture.html">sf::Texture</a> texture;</div><div class="line">texture.<a class="code" href="classsf_1_1Texture.html#a89b4c7d204acf1033c3a1b6e0a3ad0a3">create</a>(windowSize.<a class="code" href="classsf_1_1Vector2.html#a1e6ad77fa155f3753bfb92699bd28141">x</a>, windowSize.<a class="code" href="classsf_1_1Vector2.html#a420f2481b015f4eb929c75f2af564299">y</a>);</div><div class="line">texture.<a class="code" href="classsf_1_1Texture.html#ae4eab5c6781316840b0c50ad08370963">update</a>(window);</div><div class="line"><a class="code" href="classsf_1_1Image.html">sf::Image</a> screenshot = texture.<a class="code" href="classsf_1_1Texture.html#a77e18a70de2e525ac5e4a7cd95f614b9">copyToImage</a>();</div></div><!-- fragment --><p>This is a slow operation, whose main purpose is to make screenshots of the application. If you want to update an image with the contents of the window and then use it for drawing, you should rather use a <a class="el" href="classsf_1_1Texture.html" title="Image living on the graphics card that can be used for drawing. ">sf::Texture</a> and its update(Window&amp;) function. You can also draw things directly to a texture with the <a class="el" href="classsf_1_1RenderTexture.html" title="Target for off-screen 2D rendering into a texture. ">sf::RenderTexture</a> class.</p> <div class="fragment"><div class="line"><a class="code" href="classsf_1_1Vector2.html">sf::Vector2u</a> windowSize = window.<a class="code" href="classsf_1_1Window.html#a3969926741cbe83d7f9eeaf5333d4e71">getSize</a>();</div><div class="line"><a class="code" href="classsf_1_1Texture.html">sf::Texture</a> texture;</div><div class="line">texture.<a class="code" href="classsf_1_1Texture.html#a89b4c7d204acf1033c3a1b6e0a3ad0a3">create</a>(windowSize.<a class="code" href="classsf_1_1Vector2.html#a1e6ad77fa155f3753bfb92699bd28141">x</a>, windowSize.<a class="code" href="classsf_1_1Vector2.html#a420f2481b015f4eb929c75f2af564299">y</a>);</div><div class="line">texture.<a class="code" href="classsf_1_1Texture.html#ae4eab5c6781316840b0c50ad08370963">update</a>(window);</div><div class="line"><a class="code" href="classsf_1_1Image.html">sf::Image</a> screenshot = texture.<a class="code" href="classsf_1_1Texture.html#a77e18a70de2e525ac5e4a7cd95f614b9">copyToImage</a>();</div></div><!-- fragment --><p>This is a slow operation, whose main purpose is to make screenshots of the application. If you want to update an image with the contents of the window and then use it for drawing, you should rather use a <a class="el" href="classsf_1_1Texture.html" title="Image living on the graphics card that can be used for drawing. ">sf::Texture</a> and its update(Window&amp;) function. You can also draw things directly to a texture with the <a class="el" href="classsf_1_1RenderTexture.html" title="Target for off-screen 2D rendering into a texture. ">sf::RenderTexture</a> class.</p>
<dl class="section return"><dt>Returns</dt><dd><a class="el" href="classsf_1_1Image.html" title="Class for loading, manipulating and saving images. ">Image</a> containing the captured contents </dd></dl> <dl class="section return"><dt>Returns</dt><dd><a class="el" href="classsf_1_1Image.html" title="Class for loading, manipulating and saving images. ">Image</a> containing the captured contents </dd></dl>

View File

@ -108,28 +108,28 @@ Public Member Functions</h2></td></tr>
<tr class="memdesc:a77e18a70de2e525ac5e4a7cd95f614b9"><td class="mdescLeft">&#160;</td><td class="mdescRight">Copy the texture pixels to an image. <a href="#a77e18a70de2e525ac5e4a7cd95f614b9">More...</a><br /></td></tr> <tr class="memdesc:a77e18a70de2e525ac5e4a7cd95f614b9"><td class="mdescLeft">&#160;</td><td class="mdescRight">Copy the texture pixels to an image. <a href="#a77e18a70de2e525ac5e4a7cd95f614b9">More...</a><br /></td></tr>
<tr class="separator:a77e18a70de2e525ac5e4a7cd95f614b9"><td class="memSeparator" colspan="2">&#160;</td></tr> <tr class="separator:a77e18a70de2e525ac5e4a7cd95f614b9"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:ae4eab5c6781316840b0c50ad08370963"><td class="memItemLeft" align="right" valign="top">void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classsf_1_1Texture.html#ae4eab5c6781316840b0c50ad08370963">update</a> (const Uint8 *pixels)</td></tr> <tr class="memitem:ae4eab5c6781316840b0c50ad08370963"><td class="memItemLeft" align="right" valign="top">void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classsf_1_1Texture.html#ae4eab5c6781316840b0c50ad08370963">update</a> (const Uint8 *pixels)</td></tr>
<tr class="memdesc:ae4eab5c6781316840b0c50ad08370963"><td class="mdescLeft">&#160;</td><td class="mdescRight">Update the whole texture from an array of pixels. <a href="#ae4eab5c6781316840b0c50ad08370963">More...</a><br /></td></tr> <tr class="memdesc:ae4eab5c6781316840b0c50ad08370963"><td class="mdescLeft">&#160;</td><td class="mdescRight">ServerUpdate the whole texture from an array of pixels. <a href="#ae4eab5c6781316840b0c50ad08370963">More...</a><br /></td></tr>
<tr class="separator:ae4eab5c6781316840b0c50ad08370963"><td class="memSeparator" colspan="2">&#160;</td></tr> <tr class="separator:ae4eab5c6781316840b0c50ad08370963"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a1352d8e16c2aeb4df586ed65dd2c36b9"><td class="memItemLeft" align="right" valign="top">void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classsf_1_1Texture.html#a1352d8e16c2aeb4df586ed65dd2c36b9">update</a> (const Uint8 *pixels, unsigned int width, unsigned int height, unsigned int x, unsigned int y)</td></tr> <tr class="memitem:a1352d8e16c2aeb4df586ed65dd2c36b9"><td class="memItemLeft" align="right" valign="top">void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classsf_1_1Texture.html#a1352d8e16c2aeb4df586ed65dd2c36b9">update</a> (const Uint8 *pixels, unsigned int width, unsigned int height, unsigned int x, unsigned int y)</td></tr>
<tr class="memdesc:a1352d8e16c2aeb4df586ed65dd2c36b9"><td class="mdescLeft">&#160;</td><td class="mdescRight">Update a part of the texture from an array of pixels. <a href="#a1352d8e16c2aeb4df586ed65dd2c36b9">More...</a><br /></td></tr> <tr class="memdesc:a1352d8e16c2aeb4df586ed65dd2c36b9"><td class="mdescLeft">&#160;</td><td class="mdescRight">ServerUpdate a part of the texture from an array of pixels. <a href="#a1352d8e16c2aeb4df586ed65dd2c36b9">More...</a><br /></td></tr>
<tr class="separator:a1352d8e16c2aeb4df586ed65dd2c36b9"><td class="memSeparator" colspan="2">&#160;</td></tr> <tr class="separator:a1352d8e16c2aeb4df586ed65dd2c36b9"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:af9885ca00b74950d60feea28132d9691"><td class="memItemLeft" align="right" valign="top">void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classsf_1_1Texture.html#af9885ca00b74950d60feea28132d9691">update</a> (const <a class="el" href="classsf_1_1Texture.html">Texture</a> &amp;texture)</td></tr> <tr class="memitem:af9885ca00b74950d60feea28132d9691"><td class="memItemLeft" align="right" valign="top">void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classsf_1_1Texture.html#af9885ca00b74950d60feea28132d9691">update</a> (const <a class="el" href="classsf_1_1Texture.html">Texture</a> &amp;texture)</td></tr>
<tr class="memdesc:af9885ca00b74950d60feea28132d9691"><td class="mdescLeft">&#160;</td><td class="mdescRight">Update a part of this texture from another texture. <a href="#af9885ca00b74950d60feea28132d9691">More...</a><br /></td></tr> <tr class="memdesc:af9885ca00b74950d60feea28132d9691"><td class="mdescLeft">&#160;</td><td class="mdescRight">ServerUpdate a part of this texture from another texture. <a href="#af9885ca00b74950d60feea28132d9691">More...</a><br /></td></tr>
<tr class="separator:af9885ca00b74950d60feea28132d9691"><td class="memSeparator" colspan="2">&#160;</td></tr> <tr class="separator:af9885ca00b74950d60feea28132d9691"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a89beb474da1da84b5e38c9fc0b441fe4"><td class="memItemLeft" align="right" valign="top">void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classsf_1_1Texture.html#a89beb474da1da84b5e38c9fc0b441fe4">update</a> (const <a class="el" href="classsf_1_1Texture.html">Texture</a> &amp;texture, unsigned int x, unsigned int y)</td></tr> <tr class="memitem:a89beb474da1da84b5e38c9fc0b441fe4"><td class="memItemLeft" align="right" valign="top">void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classsf_1_1Texture.html#a89beb474da1da84b5e38c9fc0b441fe4">update</a> (const <a class="el" href="classsf_1_1Texture.html">Texture</a> &amp;texture, unsigned int x, unsigned int y)</td></tr>
<tr class="memdesc:a89beb474da1da84b5e38c9fc0b441fe4"><td class="mdescLeft">&#160;</td><td class="mdescRight">Update a part of this texture from another texture. <a href="#a89beb474da1da84b5e38c9fc0b441fe4">More...</a><br /></td></tr> <tr class="memdesc:a89beb474da1da84b5e38c9fc0b441fe4"><td class="mdescLeft">&#160;</td><td class="mdescRight">ServerUpdate a part of this texture from another texture. <a href="#a89beb474da1da84b5e38c9fc0b441fe4">More...</a><br /></td></tr>
<tr class="separator:a89beb474da1da84b5e38c9fc0b441fe4"><td class="memSeparator" colspan="2">&#160;</td></tr> <tr class="separator:a89beb474da1da84b5e38c9fc0b441fe4"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a037cdf171af0fb392d07626a44a4ea17"><td class="memItemLeft" align="right" valign="top">void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classsf_1_1Texture.html#a037cdf171af0fb392d07626a44a4ea17">update</a> (const <a class="el" href="classsf_1_1Image.html">Image</a> &amp;image)</td></tr> <tr class="memitem:a037cdf171af0fb392d07626a44a4ea17"><td class="memItemLeft" align="right" valign="top">void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classsf_1_1Texture.html#a037cdf171af0fb392d07626a44a4ea17">update</a> (const <a class="el" href="classsf_1_1Image.html">Image</a> &amp;image)</td></tr>
<tr class="memdesc:a037cdf171af0fb392d07626a44a4ea17"><td class="mdescLeft">&#160;</td><td class="mdescRight">Update the texture from an image. <a href="#a037cdf171af0fb392d07626a44a4ea17">More...</a><br /></td></tr> <tr class="memdesc:a037cdf171af0fb392d07626a44a4ea17"><td class="mdescLeft">&#160;</td><td class="mdescRight">ServerUpdate the texture from an image. <a href="#a037cdf171af0fb392d07626a44a4ea17">More...</a><br /></td></tr>
<tr class="separator:a037cdf171af0fb392d07626a44a4ea17"><td class="memSeparator" colspan="2">&#160;</td></tr> <tr class="separator:a037cdf171af0fb392d07626a44a4ea17"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a87f916490b757fe900798eedf3abf3ba"><td class="memItemLeft" align="right" valign="top">void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classsf_1_1Texture.html#a87f916490b757fe900798eedf3abf3ba">update</a> (const <a class="el" href="classsf_1_1Image.html">Image</a> &amp;image, unsigned int x, unsigned int y)</td></tr> <tr class="memitem:a87f916490b757fe900798eedf3abf3ba"><td class="memItemLeft" align="right" valign="top">void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classsf_1_1Texture.html#a87f916490b757fe900798eedf3abf3ba">update</a> (const <a class="el" href="classsf_1_1Image.html">Image</a> &amp;image, unsigned int x, unsigned int y)</td></tr>
<tr class="memdesc:a87f916490b757fe900798eedf3abf3ba"><td class="mdescLeft">&#160;</td><td class="mdescRight">Update a part of the texture from an image. <a href="#a87f916490b757fe900798eedf3abf3ba">More...</a><br /></td></tr> <tr class="memdesc:a87f916490b757fe900798eedf3abf3ba"><td class="mdescLeft">&#160;</td><td class="mdescRight">ServerUpdate a part of the texture from an image. <a href="#a87f916490b757fe900798eedf3abf3ba">More...</a><br /></td></tr>
<tr class="separator:a87f916490b757fe900798eedf3abf3ba"><td class="memSeparator" colspan="2">&#160;</td></tr> <tr class="separator:a87f916490b757fe900798eedf3abf3ba"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:ad3cceef238f7d5d2108a98dd38c17fc5"><td class="memItemLeft" align="right" valign="top">void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classsf_1_1Texture.html#ad3cceef238f7d5d2108a98dd38c17fc5">update</a> (const <a class="el" href="classsf_1_1Window.html">Window</a> &amp;window)</td></tr> <tr class="memitem:ad3cceef238f7d5d2108a98dd38c17fc5"><td class="memItemLeft" align="right" valign="top">void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classsf_1_1Texture.html#ad3cceef238f7d5d2108a98dd38c17fc5">update</a> (const <a class="el" href="classsf_1_1Window.html">Window</a> &amp;window)</td></tr>
<tr class="memdesc:ad3cceef238f7d5d2108a98dd38c17fc5"><td class="mdescLeft">&#160;</td><td class="mdescRight">Update the texture from the contents of a window. <a href="#ad3cceef238f7d5d2108a98dd38c17fc5">More...</a><br /></td></tr> <tr class="memdesc:ad3cceef238f7d5d2108a98dd38c17fc5"><td class="mdescLeft">&#160;</td><td class="mdescRight">ServerUpdate the texture from the contents of a window. <a href="#ad3cceef238f7d5d2108a98dd38c17fc5">More...</a><br /></td></tr>
<tr class="separator:ad3cceef238f7d5d2108a98dd38c17fc5"><td class="memSeparator" colspan="2">&#160;</td></tr> <tr class="separator:ad3cceef238f7d5d2108a98dd38c17fc5"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a154f246eb8059b602076009ab1cfd175"><td class="memItemLeft" align="right" valign="top">void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classsf_1_1Texture.html#a154f246eb8059b602076009ab1cfd175">update</a> (const <a class="el" href="classsf_1_1Window.html">Window</a> &amp;window, unsigned int x, unsigned int y)</td></tr> <tr class="memitem:a154f246eb8059b602076009ab1cfd175"><td class="memItemLeft" align="right" valign="top">void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classsf_1_1Texture.html#a154f246eb8059b602076009ab1cfd175">update</a> (const <a class="el" href="classsf_1_1Window.html">Window</a> &amp;window, unsigned int x, unsigned int y)</td></tr>
<tr class="memdesc:a154f246eb8059b602076009ab1cfd175"><td class="mdescLeft">&#160;</td><td class="mdescRight">Update a part of the texture from the contents of a window. <a href="#a154f246eb8059b602076009ab1cfd175">More...</a><br /></td></tr> <tr class="memdesc:a154f246eb8059b602076009ab1cfd175"><td class="mdescLeft">&#160;</td><td class="mdescRight">ServerUpdate a part of the texture from the contents of a window. <a href="#a154f246eb8059b602076009ab1cfd175">More...</a><br /></td></tr>
<tr class="separator:a154f246eb8059b602076009ab1cfd175"><td class="memSeparator" colspan="2">&#160;</td></tr> <tr class="separator:a154f246eb8059b602076009ab1cfd175"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a0c3bd6825b9a99714f10d44179d74324"><td class="memItemLeft" align="right" valign="top">void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classsf_1_1Texture.html#a0c3bd6825b9a99714f10d44179d74324">setSmooth</a> (bool smooth)</td></tr> <tr class="memitem:a0c3bd6825b9a99714f10d44179d74324"><td class="memItemLeft" align="right" valign="top">void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classsf_1_1Texture.html#a0c3bd6825b9a99714f10d44179d74324">setSmooth</a> (bool smooth)</td></tr>
<tr class="memdesc:a0c3bd6825b9a99714f10d44179d74324"><td class="mdescLeft">&#160;</td><td class="mdescRight">Enable or disable the smooth filter. <a href="#a0c3bd6825b9a99714f10d44179d74324">More...</a><br /></td></tr> <tr class="memdesc:a0c3bd6825b9a99714f10d44179d74324"><td class="mdescLeft">&#160;</td><td class="mdescRight">Enable or disable the smooth filter. <a href="#a0c3bd6825b9a99714f10d44179d74324">More...</a><br /></td></tr>
@ -193,7 +193,7 @@ class&#160;</td><td class="memItemRight" valign="bottom"><b>RenderTarget</b></td
<div class="textblock"><p><a class="el" href="classsf_1_1Image.html" title="Class for loading, manipulating and saving images. ">Image</a> living on the graphics card that can be used for drawing. </p> <div class="textblock"><p><a class="el" href="classsf_1_1Image.html" title="Class for loading, manipulating and saving images. ">Image</a> living on the graphics card that can be used for drawing. </p>
<p><a class="el" href="classsf_1_1Texture.html" title="Image living on the graphics card that can be used for drawing. ">sf::Texture</a> stores pixels that can be drawn, with a sprite for example.</p> <p><a class="el" href="classsf_1_1Texture.html" title="Image living on the graphics card that can be used for drawing. ">sf::Texture</a> stores pixels that can be drawn, with a sprite for example.</p>
<p>A texture lives in the graphics card memory, therefore it is very fast to draw a texture to a render target, or copy a render target to a texture (the graphics card can access both directly).</p> <p>A texture lives in the graphics card memory, therefore it is very fast to draw a texture to a render target, or copy a render target to a texture (the graphics card can access both directly).</p>
<p>Being stored in the graphics card memory has some drawbacks. A texture cannot be manipulated as freely as a <a class="el" href="classsf_1_1Image.html" title="Class for loading, manipulating and saving images. ">sf::Image</a>, you need to prepare the pixels first and then upload them to the texture in a single operation (see <a class="el" href="classsf_1_1Texture.html#ae4eab5c6781316840b0c50ad08370963" title="Update the whole texture from an array of pixels. ">Texture::update</a>).</p> <p>Being stored in the graphics card memory has some drawbacks. A texture cannot be manipulated as freely as a <a class="el" href="classsf_1_1Image.html" title="Class for loading, manipulating and saving images. ">sf::Image</a>, you need to prepare the pixels first and then upload them to the texture in a single operation (see <a class="el" href="classsf_1_1Texture.html#ae4eab5c6781316840b0c50ad08370963" title="ServerUpdate the whole texture from an array of pixels. ">Texture::update</a>).</p>
<p><a class="el" href="classsf_1_1Texture.html" title="Image living on the graphics card that can be used for drawing. ">sf::Texture</a> makes it easy to convert from/to <a class="el" href="classsf_1_1Image.html" title="Class for loading, manipulating and saving images. ">sf::Image</a>, but keep in mind that these calls require transfers between the graphics card and the central memory, therefore they are slow operations.</p> <p><a class="el" href="classsf_1_1Texture.html" title="Image living on the graphics card that can be used for drawing. ">sf::Texture</a> makes it easy to convert from/to <a class="el" href="classsf_1_1Image.html" title="Class for loading, manipulating and saving images. ">sf::Image</a>, but keep in mind that these calls require transfers between the graphics card and the central memory, therefore they are slow operations.</p>
<p>A texture can be loaded from an image, but also directly from a file/memory/stream. The necessary shortcuts are defined so that you don't need an image first for the most common cases. However, if you want to perform some modifications on the pixels before creating the final texture, you can load your file to a <a class="el" href="classsf_1_1Image.html" title="Class for loading, manipulating and saving images. ">sf::Image</a>, do whatever you need with the pixels, and then call <a class="el" href="classsf_1_1Texture.html#abec4567ad9856a3596dc74803f26fba2" title="Load the texture from an image. ">Texture::loadFromImage</a>.</p> <p>A texture can be loaded from an image, but also directly from a file/memory/stream. The necessary shortcuts are defined so that you don't need an image first for the most common cases. However, if you want to perform some modifications on the pixels before creating the final texture, you can load your file to a <a class="el" href="classsf_1_1Image.html" title="Class for loading, manipulating and saving images. ">sf::Image</a>, do whatever you need with the pixels, and then call <a class="el" href="classsf_1_1Texture.html#abec4567ad9856a3596dc74803f26fba2" title="Load the texture from an image. ">Texture::loadFromImage</a>.</p>
<p>Since they live in the graphics card memory, the pixels of a texture cannot be accessed without a slow copy first. And they cannot be accessed individually. Therefore, if you need to read the texture's pixels (like for pixel-perfect collisions), it is recommended to store the collision information separately, for example in an array of booleans.</p> <p>Since they live in the graphics card memory, the pixels of a texture cannot be accessed without a slow copy first. And they cannot be accessed individually. Therefore, if you need to read the texture's pixels (like for pixel-perfect collisions), it is recommended to store the collision information separately, for example in an array of booleans.</p>
@ -886,7 +886,7 @@ class&#160;</td><td class="memItemRight" valign="bottom"><b>RenderTarget</b></td
</table> </table>
</div><div class="memdoc"> </div><div class="memdoc">
<p>Update the whole texture from an array of pixels. </p> <p>ServerUpdate the whole texture from an array of pixels. </p>
<p>The <em>pixel</em> array is assumed to have the same size as the <em>area</em> rectangle, and to contain 32-bits RGBA pixels.</p> <p>The <em>pixel</em> array is assumed to have the same size as the <em>area</em> rectangle, and to contain 32-bits RGBA pixels.</p>
<p>No additional check is performed on the size of the pixel array, passing invalid arguments will lead to an undefined behavior.</p> <p>No additional check is performed on the size of the pixel array, passing invalid arguments will lead to an undefined behavior.</p>
<p>This function does nothing if <em>pixels</em> is null or if the texture was not previously created.</p> <p>This function does nothing if <em>pixels</em> is null or if the texture was not previously created.</p>
@ -943,7 +943,7 @@ class&#160;</td><td class="memItemRight" valign="bottom"><b>RenderTarget</b></td
</table> </table>
</div><div class="memdoc"> </div><div class="memdoc">
<p>Update a part of the texture from an array of pixels. </p> <p>ServerUpdate a part of the texture from an array of pixels. </p>
<p>The size of the <em>pixel</em> array must match the <em>width</em> and <em>height</em> arguments, and it must contain 32-bits RGBA pixels.</p> <p>The size of the <em>pixel</em> array must match the <em>width</em> and <em>height</em> arguments, and it must contain 32-bits RGBA pixels.</p>
<p>No additional check is performed on the size of the pixel array or the bounds of the area to update, passing invalid arguments will lead to an undefined behavior.</p> <p>No additional check is performed on the size of the pixel array or the bounds of the area to update, passing invalid arguments will lead to an undefined behavior.</p>
<p>This function does nothing if <em>pixels</em> is null or if the texture was not previously created.</p> <p>This function does nothing if <em>pixels</em> is null or if the texture was not previously created.</p>
@ -976,7 +976,7 @@ class&#160;</td><td class="memItemRight" valign="bottom"><b>RenderTarget</b></td
</table> </table>
</div><div class="memdoc"> </div><div class="memdoc">
<p>Update a part of this texture from another texture. </p> <p>ServerUpdate a part of this texture from another texture. </p>
<p>Although the source texture can be smaller than this texture, this function is usually used for updating the whole texture. The other overload, which has (x, y) additional arguments, is more convenient for updating a sub-area of this texture.</p> <p>Although the source texture can be smaller than this texture, this function is usually used for updating the whole texture. The other overload, which has (x, y) additional arguments, is more convenient for updating a sub-area of this texture.</p>
<p>No additional check is performed on the size of the passed texture, passing a texture bigger than this texture will lead to an undefined behavior.</p> <p>No additional check is performed on the size of the passed texture, passing a texture bigger than this texture will lead to an undefined behavior.</p>
<p>This function does nothing if either texture was not previously created.</p> <p>This function does nothing if either texture was not previously created.</p>
@ -1021,7 +1021,7 @@ class&#160;</td><td class="memItemRight" valign="bottom"><b>RenderTarget</b></td
</table> </table>
</div><div class="memdoc"> </div><div class="memdoc">
<p>Update a part of this texture from another texture. </p> <p>ServerUpdate a part of this texture from another texture. </p>
<p>No additional check is performed on the size of the texture, passing an invalid combination of texture size and offset will lead to an undefined behavior.</p> <p>No additional check is performed on the size of the texture, passing an invalid combination of texture size and offset will lead to an undefined behavior.</p>
<p>This function does nothing if either texture was not previously created.</p> <p>This function does nothing if either texture was not previously created.</p>
<dl class="params"><dt>Parameters</dt><dd> <dl class="params"><dt>Parameters</dt><dd>
@ -1051,7 +1051,7 @@ class&#160;</td><td class="memItemRight" valign="bottom"><b>RenderTarget</b></td
</table> </table>
</div><div class="memdoc"> </div><div class="memdoc">
<p>Update the texture from an image. </p> <p>ServerUpdate the texture from an image. </p>
<p>Although the source image can be smaller than the texture, this function is usually used for updating the whole texture. The other overload, which has (x, y) additional arguments, is more convenient for updating a sub-area of the texture.</p> <p>Although the source image can be smaller than the texture, this function is usually used for updating the whole texture. The other overload, which has (x, y) additional arguments, is more convenient for updating a sub-area of the texture.</p>
<p>No additional check is performed on the size of the image, passing an image bigger than the texture will lead to an undefined behavior.</p> <p>No additional check is performed on the size of the image, passing an image bigger than the texture will lead to an undefined behavior.</p>
<p>This function does nothing if the texture was not previously created.</p> <p>This function does nothing if the texture was not previously created.</p>
@ -1096,7 +1096,7 @@ class&#160;</td><td class="memItemRight" valign="bottom"><b>RenderTarget</b></td
</table> </table>
</div><div class="memdoc"> </div><div class="memdoc">
<p>Update a part of the texture from an image. </p> <p>ServerUpdate a part of the texture from an image. </p>
<p>No additional check is performed on the size of the image, passing an invalid combination of image size and offset will lead to an undefined behavior.</p> <p>No additional check is performed on the size of the image, passing an invalid combination of image size and offset will lead to an undefined behavior.</p>
<p>This function does nothing if the texture was not previously created.</p> <p>This function does nothing if the texture was not previously created.</p>
<dl class="params"><dt>Parameters</dt><dd> <dl class="params"><dt>Parameters</dt><dd>
@ -1126,7 +1126,7 @@ class&#160;</td><td class="memItemRight" valign="bottom"><b>RenderTarget</b></td
</table> </table>
</div><div class="memdoc"> </div><div class="memdoc">
<p>Update the texture from the contents of a window. </p> <p>ServerUpdate the texture from the contents of a window. </p>
<p>Although the source window can be smaller than the texture, this function is usually used for updating the whole texture. The other overload, which has (x, y) additional arguments, is more convenient for updating a sub-area of the texture.</p> <p>Although the source window can be smaller than the texture, this function is usually used for updating the whole texture. The other overload, which has (x, y) additional arguments, is more convenient for updating a sub-area of the texture.</p>
<p>No additional check is performed on the size of the window, passing a window bigger than the texture will lead to an undefined behavior.</p> <p>No additional check is performed on the size of the window, passing a window bigger than the texture will lead to an undefined behavior.</p>
<p>This function does nothing if either the texture or the window was not previously created.</p> <p>This function does nothing if either the texture or the window was not previously created.</p>
@ -1171,7 +1171,7 @@ class&#160;</td><td class="memItemRight" valign="bottom"><b>RenderTarget</b></td
</table> </table>
</div><div class="memdoc"> </div><div class="memdoc">
<p>Update a part of the texture from the contents of a window. </p> <p>ServerUpdate a part of the texture from the contents of a window. </p>
<p>No additional check is performed on the size of the window, passing an invalid combination of window size and offset will lead to an undefined behavior.</p> <p>No additional check is performed on the size of the window, passing an invalid combination of window size and offset will lead to an undefined behavior.</p>
<p>This function does nothing if either the texture or the window was not previously created.</p> <p>This function does nothing if either the texture or the window was not previously created.</p>
<dl class="params"><dt>Parameters</dt><dd> <dl class="params"><dt>Parameters</dt><dd>

View File

@ -103,10 +103,10 @@ Public Member Functions</h2></td></tr>
<tr class="memdesc:a6c534536ed186a2ad65e75484c8abafe"><td class="mdescLeft">&#160;</td><td class="mdescRight">Return the vertex count. <a href="#a6c534536ed186a2ad65e75484c8abafe">More...</a><br /></td></tr> <tr class="memdesc:a6c534536ed186a2ad65e75484c8abafe"><td class="mdescLeft">&#160;</td><td class="mdescRight">Return the vertex count. <a href="#a6c534536ed186a2ad65e75484c8abafe">More...</a><br /></td></tr>
<tr class="separator:a6c534536ed186a2ad65e75484c8abafe"><td class="memSeparator" colspan="2">&#160;</td></tr> <tr class="separator:a6c534536ed186a2ad65e75484c8abafe"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:ad100a5f578a91c49a9009e3c6956c82d"><td class="memItemLeft" align="right" valign="top">bool&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classsf_1_1VertexBuffer.html#ad100a5f578a91c49a9009e3c6956c82d">update</a> (const <a class="el" href="classsf_1_1Vertex.html">Vertex</a> *vertices)</td></tr> <tr class="memitem:ad100a5f578a91c49a9009e3c6956c82d"><td class="memItemLeft" align="right" valign="top">bool&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classsf_1_1VertexBuffer.html#ad100a5f578a91c49a9009e3c6956c82d">update</a> (const <a class="el" href="classsf_1_1Vertex.html">Vertex</a> *vertices)</td></tr>
<tr class="memdesc:ad100a5f578a91c49a9009e3c6956c82d"><td class="mdescLeft">&#160;</td><td class="mdescRight">Update the whole buffer from an array of vertices. <a href="#ad100a5f578a91c49a9009e3c6956c82d">More...</a><br /></td></tr> <tr class="memdesc:ad100a5f578a91c49a9009e3c6956c82d"><td class="mdescLeft">&#160;</td><td class="mdescRight">ServerUpdate the whole buffer from an array of vertices. <a href="#ad100a5f578a91c49a9009e3c6956c82d">More...</a><br /></td></tr>
<tr class="separator:ad100a5f578a91c49a9009e3c6956c82d"><td class="memSeparator" colspan="2">&#160;</td></tr> <tr class="separator:ad100a5f578a91c49a9009e3c6956c82d"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:ae6c8649a64861507010d21e77fbd53fa"><td class="memItemLeft" align="right" valign="top">bool&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classsf_1_1VertexBuffer.html#ae6c8649a64861507010d21e77fbd53fa">update</a> (const <a class="el" href="classsf_1_1Vertex.html">Vertex</a> *vertices, std::size_t vertexCount, unsigned int offset)</td></tr> <tr class="memitem:ae6c8649a64861507010d21e77fbd53fa"><td class="memItemLeft" align="right" valign="top">bool&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classsf_1_1VertexBuffer.html#ae6c8649a64861507010d21e77fbd53fa">update</a> (const <a class="el" href="classsf_1_1Vertex.html">Vertex</a> *vertices, std::size_t vertexCount, unsigned int offset)</td></tr>
<tr class="memdesc:ae6c8649a64861507010d21e77fbd53fa"><td class="mdescLeft">&#160;</td><td class="mdescRight">Update a part of the buffer from an array of vertices. <a href="#ae6c8649a64861507010d21e77fbd53fa">More...</a><br /></td></tr> <tr class="memdesc:ae6c8649a64861507010d21e77fbd53fa"><td class="mdescLeft">&#160;</td><td class="mdescRight">ServerUpdate a part of the buffer from an array of vertices. <a href="#ae6c8649a64861507010d21e77fbd53fa">More...</a><br /></td></tr>
<tr class="separator:ae6c8649a64861507010d21e77fbd53fa"><td class="memSeparator" colspan="2">&#160;</td></tr> <tr class="separator:ae6c8649a64861507010d21e77fbd53fa"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a41f8bbcf07f403e7fe29b1b905dc7544"><td class="memItemLeft" align="right" valign="top">bool&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classsf_1_1VertexBuffer.html#a41f8bbcf07f403e7fe29b1b905dc7544">update</a> (const <a class="el" href="classsf_1_1VertexBuffer.html">VertexBuffer</a> &amp;vertexBuffer)</td></tr> <tr class="memitem:a41f8bbcf07f403e7fe29b1b905dc7544"><td class="memItemLeft" align="right" valign="top">bool&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classsf_1_1VertexBuffer.html#a41f8bbcf07f403e7fe29b1b905dc7544">update</a> (const <a class="el" href="classsf_1_1VertexBuffer.html">VertexBuffer</a> &amp;vertexBuffer)</td></tr>
<tr class="memdesc:a41f8bbcf07f403e7fe29b1b905dc7544"><td class="mdescLeft">&#160;</td><td class="mdescRight">Copy the contents of another buffer into this buffer. <a href="#a41f8bbcf07f403e7fe29b1b905dc7544">More...</a><br /></td></tr> <tr class="memdesc:a41f8bbcf07f403e7fe29b1b905dc7544"><td class="mdescLeft">&#160;</td><td class="mdescRight">Copy the contents of another buffer into this buffer. <a href="#a41f8bbcf07f403e7fe29b1b905dc7544">More...</a><br /></td></tr>
@ -664,7 +664,7 @@ Static Private Member Functions</h2></td></tr>
</table> </table>
</div><div class="memdoc"> </div><div class="memdoc">
<p>Update the whole buffer from an array of vertices. </p> <p>ServerUpdate the whole buffer from an array of vertices. </p>
<p>The <em>vertex</em> array is assumed to have the same size as the <em>created</em> buffer.</p> <p>The <em>vertex</em> array is assumed to have the same size as the <em>created</em> buffer.</p>
<p>No additional check is performed on the size of the vertex array, passing invalid arguments will lead to undefined behavior.</p> <p>No additional check is performed on the size of the vertex array, passing invalid arguments will lead to undefined behavior.</p>
<p>This function does nothing if <em>vertices</em> is null or if the buffer was not previously created.</p> <p>This function does nothing if <em>vertices</em> is null or if the buffer was not previously created.</p>
@ -710,7 +710,7 @@ Static Private Member Functions</h2></td></tr>
</table> </table>
</div><div class="memdoc"> </div><div class="memdoc">
<p>Update a part of the buffer from an array of vertices. </p> <p>ServerUpdate a part of the buffer from an array of vertices. </p>
<p><code>offset</code> is specified as the number of vertices to skip from the beginning of the buffer.</p> <p><code>offset</code> is specified as the number of vertices to skip from the beginning of the buffer.</p>
<p>If <code>offset</code> is 0 and <code>vertexCount</code> is equal to the size of the currently created buffer, its whole contents are replaced.</p> <p>If <code>offset</code> is 0 and <code>vertexCount</code> is equal to the size of the currently created buffer, its whole contents are replaced.</p>
<p>If <code>offset</code> is 0 and <code>vertexCount</code> is greater than the size of the currently created buffer, a new buffer is created containing the vertex data.</p> <p>If <code>offset</code> is 0 and <code>vertexCount</code> is greater than the size of the currently created buffer, a new buffer is created containing the vertex data.</p>

View File

@ -51,7 +51,7 @@
<dt><a class="anchor" id="_deprecated000004"></a>Member <a class="el" href="classsf_1_1RenderTexture.html#a0e945c4ce7703591c7f240b169744603">sf::RenderTexture::create</a> (unsigned int width, unsigned int height, bool depthBuffer)</dt> <dt><a class="anchor" id="_deprecated000004"></a>Member <a class="el" href="classsf_1_1RenderTexture.html#a0e945c4ce7703591c7f240b169744603">sf::RenderTexture::create</a> (unsigned int width, unsigned int height, bool depthBuffer)</dt>
<dd>Use <a class="el" href="classsf_1_1RenderTexture.html#a49b7b723a80f89bc409a942364351dc3" title="Create the render-texture. ">create(unsigned int, unsigned int, const ContextSettings&amp;)</a> instead. </dd> <dd>Use <a class="el" href="classsf_1_1RenderTexture.html#a49b7b723a80f89bc409a942364351dc3" title="Create the render-texture. ">create(unsigned int, unsigned int, const ContextSettings&amp;)</a> instead. </dd>
<dt><a class="anchor" id="_deprecated000005"></a>Member <a class="el" href="classsf_1_1RenderWindow.html#a5a784b8a09bf4a8bc97ef9e0a8957c35">sf::RenderWindow::capture</a> () const</dt> <dt><a class="anchor" id="_deprecated000005"></a>Member <a class="el" href="classsf_1_1RenderWindow.html#a5a784b8a09bf4a8bc97ef9e0a8957c35">sf::RenderWindow::capture</a> () const</dt>
<dd>Use a <a class="el" href="classsf_1_1Texture.html" title="Image living on the graphics card that can be used for drawing. ">sf::Texture</a> and its <a class="el" href="classsf_1_1Texture.html#ad3cceef238f7d5d2108a98dd38c17fc5" title="Update the texture from the contents of a window. ">sf::Texture::update(const Window&amp;)</a> function and copy its contents into an <a class="el" href="classsf_1_1Image.html" title="Class for loading, manipulating and saving images. ">sf::Image</a> instead. </dd> <dd>Use a <a class="el" href="classsf_1_1Texture.html" title="Image living on the graphics card that can be used for drawing. ">sf::Texture</a> and its <a class="el" href="classsf_1_1Texture.html#ad3cceef238f7d5d2108a98dd38c17fc5" title="ServerUpdate the texture from the contents of a window. ">sf::Texture::update(const Window&amp;)</a> function and copy its contents into an <a class="el" href="classsf_1_1Image.html" title="Class for loading, manipulating and saving images. ">sf::Image</a> instead. </dd>
<dt><a class="anchor" id="_deprecated000012"></a>Member <a class="el" href="classsf_1_1Shader.html#aa8618119ed4399df3fd33e78ee96b4fc">sf::Shader::setParameter</a> (const std::string &amp;name, const <a class="el" href="classsf_1_1Color.html" title="Utility class for manipulating RGBA colors. ">Color</a> &amp;color)</dt> <dt><a class="anchor" id="_deprecated000012"></a>Member <a class="el" href="classsf_1_1Shader.html#aa8618119ed4399df3fd33e78ee96b4fc">sf::Shader::setParameter</a> (const std::string &amp;name, const <a class="el" href="classsf_1_1Color.html" title="Utility class for manipulating RGBA colors. ">Color</a> &amp;color)</dt>
<dd>Use <a class="el" href="classsf_1_1Shader.html#abc1aee8343800680fd62e1f3d43c24bf" title="Specify value for vec4 uniform. ">setUniform(const std::string&amp;, const Glsl::Vec4&amp;)</a> instead. </dd> <dd>Use <a class="el" href="classsf_1_1Shader.html#abc1aee8343800680fd62e1f3d43c24bf" title="Specify value for vec4 uniform. ">setUniform(const std::string&amp;, const Glsl::Vec4&amp;)</a> instead. </dd>
<dt><a class="anchor" id="_deprecated000015"></a>Member <a class="el" href="classsf_1_1Shader.html#af06b4cba0bab915fa01032b063909044">sf::Shader::setParameter</a> (const std::string &amp;name, <a class="el" href="structsf_1_1Shader_1_1CurrentTextureType.html" title="Special type that can be passed to setUniform(), and that represents the texture of the object being ...">CurrentTextureType</a>)</dt> <dt><a class="anchor" id="_deprecated000015"></a>Member <a class="el" href="classsf_1_1Shader.html#af06b4cba0bab915fa01032b063909044">sf::Shader::setParameter</a> (const std::string &amp;name, <a class="el" href="structsf_1_1Shader_1_1CurrentTextureType.html" title="Special type that can be passed to setUniform(), and that represents the texture of the object being ...">CurrentTextureType</a>)</dt>

File diff suppressed because one or more lines are too long

View File

@ -4,13 +4,14 @@
#include "Server.h" #include "Server.h"
#include "engine/utils/Log.h" #include "engine/utils/Log.h"
#include "ShooterMsgType.h"
void Server::broadcast() { void Server::broadcast() {
sf::Packet updatePacket; sf::Packet updatePacket;
updatePacket << MsgType::Update; 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->playerName(); 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) {
@ -26,9 +27,8 @@ void Server::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>() }); _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);
@ -36,10 +36,11 @@ void Server::processConnect(sf::Uint16 targetId) {
_socket.sendRely(sendPacket1, targetId); _socket.sendRely(sendPacket1, targetId);
// bonuses init // bonuses init
sendPacket2 << MsgType::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();
}
} }
_socket.sendRely(sendPacket2, targetId); _socket.sendRely(sendPacket2, targetId);
@ -53,7 +54,7 @@ void Server::processClientUpdate(sf::Uint16 senderId, sf::Packet& packet) {
_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)->setPlayerName(playerName); _players.at(senderId)->setPlayerNickName(playerName);
} }
void Server::processDisconnect(sf::Uint16 senderId) { void Server::processDisconnect(sf::Uint16 senderId) {
@ -61,12 +62,13 @@ void Server::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 Server::processCustomPacket(MsgType type, sf::Packet& packet, sf::Uint16 senderId) { void Server::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;
@ -74,34 +76,37 @@ void Server::processCustomPacket(MsgType type, sf::Packet& packet, sf::Uint16 se
std::string tmp; std::string tmp;
double newHealth; double newHealth;
ShooterMsgType type;
packet >> type;
switch (type) { switch (type) {
case MsgType::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();
_players[targetId]->setFullAbility(); _players[targetId]->setFullAbility();
_players[targetId]->addDeath(); _players[targetId]->addDeath();
_players[senderId]->addKill(); _players[senderId]->addKill();
sendPacket << MsgType::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 MsgType::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::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] << dbuff[4] << dbuff[5];
for (auto& player : _players) { for (auto& player : _players) {
if(player.first != senderId) if(player.first != senderId) {
_socket.send(sendPacket, player.first); _socket.send(sendPacket, player.first);
}
} }
break; break;
case MsgType::RemoveBonus: case ShooterMsgType::RemoveBonus:
packet >> tmp; packet >> tmp;
if(tmp.find("Bonus_hill") != std::string::npos) { if(tmp.find("Bonus_hill") != std::string::npos) {
@ -113,23 +118,26 @@ void Server::processCustomPacket(MsgType type, sf::Packet& packet, sf::Uint16 se
_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::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);
}
} }
break; break;
case MsgType::ChangeWeapon: case ShooterMsgType::ChangeWeapon:
packet >> tmp; packet >> tmp;
sendPacket << MsgType::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("Server::processCustomPacket: unknown message type " + std::to_string(static_cast<int>(type)));
return; return;
} }
} }
@ -166,9 +174,10 @@ void Server::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::AddBonus << bonusName << bonusInfo->position.x() << bonusInfo->position.y() << bonusInfo->position.z(); sendPacket << MsgType::Custom << ShooterMsgType::AddBonus << bonusName << bonusInfo->position.x() << bonusInfo->position.y() << bonusInfo->position.z();
for (const auto& player : _players) 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});
} }
} }

View File

@ -7,7 +7,6 @@
#include "engine/network/ServerUDP.h" #include "engine/network/ServerUDP.h"
#include "Player.h" #include "Player.h"
#include "Bonus.h"
struct BonusInfo final { struct BonusInfo final {
const Vec3D position{}; const Vec3D position{};
@ -28,7 +27,7 @@ public:
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(MsgType type, sf::Packet& packet, sf::Uint16 senderId) override; void processCustomPacket(sf::Packet& packet, sf::Uint16 senderId) override;
void processStop() override; void processStop() override;

View File

@ -11,13 +11,13 @@
#include "engine/animation/Timeline.h" #include "engine/animation/Timeline.h"
#include "ShooterConsts.h" #include "ShooterConsts.h"
#include "engine/SoundController.h" #include "engine/SoundController.h"
#include "engine/animation/ATranslateToPoint.h"
using namespace std; using namespace std;
// Read server/client settings and start both. // Read server/client settings and start both.
// If client doesn't connect to the localhost - server doesn't start. // If client doesn't connect to the localhost - server doesn't start.
void Shooter::InitNetwork() void Shooter::InitNetwork() {
{
std::string clientIp; std::string clientIp;
sf::Uint16 clientPort; sf::Uint16 clientPort;
sf::Uint16 serverPort; sf::Uint16 serverPort;
@ -58,7 +58,7 @@ void Shooter::InitNetwork()
} }
client->connect(clientIp, clientPort); client->connect(clientIp, clientPort);
player->setPlayerName(playerName); player->setPlayerNickName(playerName);
// TODO: encapsulate call backs inside Client // TODO: encapsulate call backs inside Client
client->setSpawnPlayerCallBack([this](sf::Uint16 id){ spawnPlayer(id); }); client->setSpawnPlayerCallBack([this](sf::Uint16 id){ spawnPlayer(id); });
@ -74,11 +74,11 @@ void Shooter::start() {
setDebugText(false); setDebugText(false);
setUpdateWorld(false); setUpdateWorld(false);
mouse->setMouseCursorVisible(true); screen->setMouseCursorVisible(true);
world->loadMap(ShooterConsts::MAP_OBJ, Vec3D{5, 5, 5}); world->loadMap(ShooterConsts::MAP_OBJ, Vec3D{5, 5, 5});
player = std::make_shared<Player>(); player = std::make_shared<Player>(ObjectNameTag("Player"));
player->scale(Vec3D(3, 1, 3)); player->scale(Vec3D(3, 1, 3));
playerController = std::make_shared<PlayerController>(player, keyboard, mouse); playerController = std::make_shared<PlayerController>(player, keyboard, mouse);
@ -93,9 +93,9 @@ void Shooter::start() {
player->initWeapons(); player->initWeapons();
camera->translateToPoint(player->position() + Vec3D{0, 1.8, 0}); camera->translateToPoint(player->position() + Vec3D{0, 1.8, 0});
player->attach(camera, ObjectNameTag("Camera")); player->attach(camera);
world->addBody(player, ObjectNameTag("Player")); world->addBody(player);
player->translate(Vec3D{0, 10, 0}); player->translate(Vec3D{0, 10, 0});
client = std::make_shared<Client>(player); client = std::make_shared<Client>(player);
@ -104,24 +104,22 @@ void Shooter::start() {
// connecting to the server // connecting to the server
InitNetwork(); InitNetwork();
// Waiting for connect and updating server if it's same window // Waiting for connect and updating server if it's same window
while (client->isWorking() && !client->connected()) while (client->isWorking() && !client->connected()) {
{
client->update(); client->update();
server->update(); server->update();
Time::update(); Time::update();
} }
// If connect fail - return to menu // If connect fail - return to menu
if (!client->isWorking()) if (!client->isWorking()) {
{
inGame = false; inGame = false;
server->stop(); server->stop();
} }
// windows init: // windows init:
mainMenu.title("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->ip().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] () { 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, 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});
@ -134,12 +132,13 @@ void Shooter::update() {
client->update(); client->update();
// Check all input after this condition please // Check all input after this condition please
if (!screen->hasFocus()) if (!screen->hasFocus()) {
return; return;
}
if(keyboard->isKeyTapped(sf::Keyboard::Escape)) { if(keyboard->isKeyTapped(sf::Keyboard::Escape)) {
inGame = !inGame; inGame = !inGame;
mouse->setMouseCursorVisible(!inGame); screen->setMouseCursorVisible(!inGame);
} }
if(inGame) { if(inGame) {
@ -153,8 +152,9 @@ 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);
}
} }
void Shooter::gui() { void Shooter::gui() {
@ -187,7 +187,7 @@ void Shooter::drawStatsTable() {
} ); } );
for(auto& p : allPlayers) { for(auto& p : allPlayers) {
screen->drawText(std::to_string(i) + "\t" + p->playerName() + "\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()) + " / " + std::to_string(p->deaths()),
Vec2D{10, 15 + 35.0*i}, 25, sf::Color(0, 0, 0, 150)); Vec2D{10, 15 + 35.0*i}, 25, sf::Color(0, 0, 0, 150));
i++; i++;
} }
@ -217,23 +217,21 @@ void Shooter::drawPlayerStats() {
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, 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)); screen->drawText(std::to_string((int)balance.second), Vec2D{50, static_cast<double>(screen->height() - 100)}, 50, sf::Color(0, 0, 0, 70));
//screen->drawText("KILLS: " + std::to_string(player->kills()) + " | " + "DEATHS: " + std::to_string(player->deaths()),
// Vec2D{10, 10},25, sf::Color(0, 0, 0, 100));
} }
void Shooter::play() { void Shooter::play() {
inGame = true; inGame = true;
mouse->setMouseCursorVisible(false); screen->setMouseCursorVisible(false);
} }
void Shooter::spawnPlayer(sf::Uint16 id) { void Shooter::spawnPlayer(sf::Uint16 id) {
std::string name = "Enemy_" + std::to_string(id); std::string name = "Enemy_" + std::to_string(id);
std::shared_ptr<Player> newPlayer = std::make_shared<Player>();
std::shared_ptr<Player> newPlayer = std::make_shared<Player>(ObjectNameTag(name));
newPlayer->setCollision(false); newPlayer->setCollision(false);
client->addPlayer(id, newPlayer); client->addPlayer(id, newPlayer);
world->addBody(newPlayer, ObjectNameTag(name)); world->addBody(newPlayer);
newPlayer->setVisible(true); newPlayer->setVisible(true);
newPlayer->setAcceleration(Vec3D{0, 0, 0}); newPlayer->setAcceleration(Vec3D{0, 0, 0});
@ -241,19 +239,19 @@ void Shooter::spawnPlayer(sf::Uint16 id) {
world->loadBody(ObjectNameTag(name + "_head"), ShooterConsts::CUBE_OBJ, Vec3D{0.7, 0.7, 0.7}); world->loadBody(ObjectNameTag(name + "_head"), ShooterConsts::CUBE_OBJ, Vec3D{0.7, 0.7, 0.7});
world->body(ObjectNameTag(name + "_head"))->translate(Vec3D{0, 2, 0}); world->body(ObjectNameTag(name + "_head"))->translate(Vec3D{0, 2, 0});
world->body(ObjectNameTag(name + "_head"))->setCollider(false); world->body(ObjectNameTag(name + "_head"))->setCollider(false);
newPlayer->attach(world->body(ObjectNameTag(name + "_head")), ObjectNameTag("head")); newPlayer->attach(world->body(ObjectNameTag(name + "_head")));
world->loadBody(ObjectNameTag(name + "_eye1"), ShooterConsts::CUBE_OBJ, Vec3D{0.2, 0.2, 0.05}); world->loadBody(ObjectNameTag(name + "_eye1"), ShooterConsts::CUBE_OBJ, Vec3D{0.2, 0.2, 0.05});
world->body(ObjectNameTag(name + "_eye1"))->translate(Vec3D{0.3, 2.1, 0.7}); world->body(ObjectNameTag(name + "_eye1"))->translate(Vec3D{0.3, 2.1, 0.7});
world->body(ObjectNameTag(name + "_eye1"))->setCollider(false); world->body(ObjectNameTag(name + "_eye1"))->setCollider(false);
world->body(ObjectNameTag(name + "_eye1"))->setColor({147, 159, 255}); world->body(ObjectNameTag(name + "_eye1"))->setColor({147, 159, 255});
world->body(ObjectNameTag(name + "_head"))->attach(world->body(ObjectNameTag(name + "_eye1")), ObjectNameTag("eye1")); world->body(ObjectNameTag(name + "_head"))->attach(world->body(ObjectNameTag(name + "_eye1")));
world->loadBody(ObjectNameTag(name + "_eye2"), ShooterConsts::CUBE_OBJ, Vec3D{0.2, 0.2, 0.05}); world->loadBody(ObjectNameTag(name + "_eye2"), ShooterConsts::CUBE_OBJ, Vec3D{0.2, 0.2, 0.05});
world->body(ObjectNameTag(name + "_eye2"))->translate(Vec3D{-0.3, 2.1, 0.7}); world->body(ObjectNameTag(name + "_eye2"))->translate(Vec3D{-0.3, 2.1, 0.7});
world->body(ObjectNameTag(name + "_eye2"))->setCollider(false); world->body(ObjectNameTag(name + "_eye2"))->setCollider(false);
world->body(ObjectNameTag(name + "_eye2"))->setColor({147, 159, 255}); world->body(ObjectNameTag(name + "_eye2"))->setColor({147, 159, 255});
world->body(ObjectNameTag(name + "_head"))->attach(world->body(ObjectNameTag(name + "_eye2")), ObjectNameTag("eye2")); world->body(ObjectNameTag(name + "_head"))->attach(world->body(ObjectNameTag(name + "_eye2")));
changeEnemyWeapon("gun", id); changeEnemyWeapon("gun", id);
} }
@ -264,12 +262,12 @@ void Shooter::removePlayer(sf::Uint16 id) {
world->removeBody(ObjectNameTag(name + "_head")); world->removeBody(ObjectNameTag(name + "_head"));
world->removeBody(ObjectNameTag(name + "_eye1")); world->removeBody(ObjectNameTag(name + "_eye1"));
world->removeBody(ObjectNameTag(name + "_eye2")); world->removeBody(ObjectNameTag(name + "_eye2"));
world->removeBody(ObjectNameTag("enemyWeapon_" + std::to_string(id))); world->removeBody(ObjectNameTag("Enemy_" + std::to_string(id) + "_weapon"));
} }
void Shooter::addFireTrace(const Vec3D &from, const Vec3D &to) { void Shooter::addFireTrace(const Vec3D &from, const Vec3D &to) {
std::string traceName = "Client_fireTraces_" + std::to_string(fireTraces++); std::string traceName = "Client_fireTraces_" + std::to_string(fireTraces++);
world->addBody(std::make_shared<RigidBody>(Mesh::LineTo(from, to, 0.05)), ObjectNameTag(traceName)); 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"), new AColor(world->body(ObjectNameTag(traceName)), {150, 150, 150, 0})); Timeline::animate(AnimationListTag(traceName + "_fadeOut"), new AColor(world->body(ObjectNameTag(traceName)), {150, 150, 150, 0}));
@ -282,9 +280,13 @@ void Shooter::removeFireTrace(const ObjectNameTag& 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);
world->addBody(std::make_shared<Bonus>(bonusName, "obj/" + name + ".obj", Vec3D{3, 3, 3}), ObjectNameTag(bonusName));
ObjectNameTag nameTag(bonusName);
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);
Timeline::animate(AnimationListTag(bonusName + "_rotation"), new ARotate(world->body(ObjectNameTag(bonusName)), Vec3D{0, 2*Consts::PI, 0}, 4, Animation::LoopOut::Continue, Animation::InterpolationType::linear)); world->body(ObjectNameTag(bonusName))->setCollider(false);
Timeline::animate(AnimationListTag(bonusName + "_rotation"), new 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) {
@ -293,14 +295,15 @@ 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, ObjectNameTag("weapon_" + weapon->name().str())); 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("enemyWeapon_" + std::to_string(enemyId)); 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)));
@ -317,9 +320,9 @@ void Shooter::changeEnemyWeapon(const std::string& weaponName, sf::Uint16 enemyI
world->body(weaponTag)->rotate(Vec3D(0, Consts::PI + head->angle().y(), 0)); world->body(weaponTag)->rotate(Vec3D(0, Consts::PI + head->angle().y(), 0));
world->body(weaponTag)->rotateLeft(-head->angleLeftUpLookAt().x()); world->body(weaponTag)->rotateLeft(-head->angleLeftUpLookAt().x());
enemy->attach(world->body(weaponTag), ObjectNameTag("Weapon")); enemy->attach(world->body(weaponTag));
} }
void Shooter::removeWeapon(std::shared_ptr<Weapon> weapon) { void Shooter::removeWeapon(std::shared_ptr<Weapon> weapon) {
world->removeBody(ObjectNameTag("weapon_" + weapon->name().str())); world->removeBody(weapon->name());
} }

18
ShooterMsgType.cpp Normal file
View File

@ -0,0 +1,18 @@
//
// Created by Иван Ильин on 27.10.2021.
//
#include "ShooterMsgType.h"
sf::Packet& operator<<(sf::Packet& packet, ShooterMsgType type)
{
return packet << (sf::Uint16)type;
}
sf::Packet& operator>>(sf::Packet& packet, ShooterMsgType& type)
{
sf::Uint16 temp;
packet >> temp;
type = (ShooterMsgType)temp;
return packet;
}

24
ShooterMsgType.h Normal file
View File

@ -0,0 +1,24 @@
//
// Created by Иван Ильин on 27.10.2021.
//
#ifndef SHOOTER_SHOOTERMSGTYPE_H
#define SHOOTER_SHOOTERMSGTYPE_H
#include <SFML/Network.hpp>
enum class ShooterMsgType
{
Damage,
Kill,
FireTrace,
InitBonuses,
AddBonus,
RemoveBonus,
ChangeWeapon
};
sf::Packet& operator<<(sf::Packet& packet, ShooterMsgType type);
sf::Packet& operator>>(sf::Packet& packet, ShooterMsgType& type);
#endif //SHOOTER_SHOOTERMSGTYPE_H

View File

@ -4,7 +4,7 @@
#include "Camera.h" #include "Camera.h"
#include "utils/Log.h" #include "utils/Log.h"
#include "Consts.h"
#include <cmath> #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) {
@ -14,8 +14,9 @@ std::vector<std::shared_ptr<Triangle>> Camera::project(std::shared_ptr<Mesh> mes
return _triangles; return _triangles;
} }
if(!mesh->isVisible()) if(!mesh->isVisible()) {
return this->_triangles; return this->_triangles;
}
// Model transform matrix: translate _tris in the origin of body. // Model transform matrix: translate _tris in the origin of body.
Matrix4x4 M = Matrix4x4::Translation(mesh->position()); Matrix4x4 M = Matrix4x4::Translation(mesh->position());
@ -26,11 +27,11 @@ std::vector<std::shared_ptr<Triangle>> Camera::project(std::shared_ptr<Mesh> mes
for(auto& t : mesh->triangles()) { for(auto& t : mesh->triangles()) {
double dot = t.norm().dot((mesh->position() + Vec3D(t[0]) - position()).normalized()); double dot = t.norm().dot((mesh->position() + Vec3D(t[0]) - position()).normalized());
if(dot > 0) if(dot > 0) {
continue; continue;
}
// It needs to be cleared because it's reused through iterations. Usually it doesn't free memory. // It needs to be cleared because it's reused through iterations. Usually it doesn't free memory.
clippedTriangles.clear(); clippedTriangles.clear();
@ -39,14 +40,13 @@ 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(t * VM); clippedTriangles.emplace_back(t * VM);
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);
} }
@ -103,8 +103,7 @@ std::vector<std::shared_ptr<Triangle>> Camera::sorted() {
// Sort _tris from _back to front // Sort _tris from _back to front
// This is some replacement for Z-buffer // This is some replacement for Z-buffer
std::sort(_triangles.begin(), _triangles.end(), [](std::shared_ptr<Triangle> &t1, std::shared_ptr<Triangle> &t2) std::sort(_triangles.begin(), _triangles.end(), [](std::shared_ptr<Triangle> &t1, std::shared_ptr<Triangle> &t2) {
{
std::vector<double> v_z1({(*t1)[0].z(), (*t1)[1].z(), (*t1)[2].z()}); std::vector<double> v_z1({(*t1)[0].z(), (*t1)[1].z(), (*t1)[2].z()});
std::vector<double> v_z2({(*t2)[0].z(), (*t2)[1].z(), (*t2)[2].z()}); std::vector<double> v_z2({(*t2)[0].z(), (*t2)[1].z(), (*t2)[2].z()});

View File

@ -26,7 +26,7 @@ private:
double _aspect = 0; double _aspect = 0;
public: public:
Camera() = default; 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);

View File

@ -5,7 +5,7 @@
#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"
namespace Consts { namespace Consts {
const int STANDARD_SCREEN_WIDTH = 1920; const int STANDARD_SCREEN_WIDTH = 1920;
@ -29,11 +29,15 @@ namespace Consts {
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 unsigned NETWORK_VERSION = 2U; const Vec2D BEZIER[2] = {Vec2D{0.8, 0}, Vec2D{0.2, 1}};
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

View File

@ -14,20 +14,11 @@ Engine::Engine() {
Timeline::init(); Timeline::init();
ResourceManager::init(); ResourceManager::init();
SoundController::init(); SoundController::init();
screen = std::make_shared<Screen>();
keyboard = std::make_shared<Keyboard>();
mouse = std::make_shared<Mouse>();
world = std::make_shared<World>();
camera = std::make_shared<Camera>();
} }
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);
screen->attachMouse(mouse);
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();
@ -65,11 +56,13 @@ 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
for (auto &t : camera->sorted()) for (auto &t : camera->sorted()) {
screen->drawTriangle(*t); screen->drawTriangle(*t);
}
_triPerSec = camera->buffSize() * Time::fps(); _triPerSec = camera->buffSize() * Time::fps();
} }

View File

@ -24,12 +24,12 @@ private:
void printDebugText() const; void printDebugText() const;
protected: protected:
std::shared_ptr<Screen> screen; const std::shared_ptr<Screen> screen = std::make_shared<Screen>();
std::shared_ptr<Keyboard> keyboard; const std::shared_ptr<Keyboard> keyboard = std::make_shared<Keyboard>();
std::shared_ptr<Mouse> mouse; const std::shared_ptr<Mouse> mouse = std::make_shared<Mouse>(screen);
std::shared_ptr<World> world; const std::shared_ptr<World> world = std::make_shared<World>();
std::shared_ptr<Camera> camera; const std::shared_ptr<Camera> camera = std::make_shared<Camera>();
virtual void start() {}; virtual void start() {};
virtual void update() {}; virtual void update() {};

View File

@ -11,8 +11,9 @@ bool Keyboard::isKeyPressed(sf::Keyboard::Key key) {
} }
bool Keyboard::isKeyTapped(sf::Keyboard::Key key) { bool Keyboard::isKeyTapped(sf::Keyboard::Key key) {
if (!Keyboard::isKeyPressed(key)) if (!Keyboard::isKeyPressed(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());

View File

@ -18,8 +18,8 @@ Matrix4x4 Matrix4x4::operator*(const Matrix4x4 &matrix4X4) const {
return result; return result;
} }
Point4D Matrix4x4::operator*(const Point4D &point4D) const { Vec4D Matrix4x4::operator*(const Vec4D &point4D) const {
return Point4D( return Vec4D(
_arr[0][0] * point4D.x() + _arr[0][1] * point4D.y() + _arr[0][2] * point4D.z() + _arr[0][3] * point4D.w(), _arr[0][0] * point4D.x() + _arr[0][1] * point4D.y() + _arr[0][2] * point4D.z() + _arr[0][3] * point4D.w(),
_arr[1][0] * point4D.x() + _arr[1][1] * point4D.y() + _arr[1][2] * point4D.z() + _arr[1][3] * point4D.w(), _arr[1][0] * point4D.x() + _arr[1][1] * point4D.y() + _arr[1][2] * point4D.z() + _arr[1][3] * point4D.w(),
_arr[2][0] * point4D.x() + _arr[2][1] * point4D.y() + _arr[2][2] * point4D.z() + _arr[2][3] * point4D.w(), _arr[2][0] * point4D.x() + _arr[2][1] * point4D.y() + _arr[2][2] * point4D.z() + _arr[2][3] * point4D.w(),
@ -38,12 +38,15 @@ Vec3D Matrix4x4::operator*(const Vec3D &vec) const {
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;
else } else {
result._arr[j][i] = 0.0; result._arr[j][i] = 0.0;
}
}
}
return result; return result;
} }
@ -51,9 +54,11 @@ 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;
}
}
return result; return result;
} }

View File

@ -6,7 +6,7 @@
#define ENGINE_MATRIX4X4_H #define ENGINE_MATRIX4X4_H
#include <array> #include <array>
#include "Point4D.h" #include "Vec4D.h"
#include "Vec3D.h" #include "Vec3D.h"
class Matrix4x4 final { class Matrix4x4 final {
@ -18,7 +18,7 @@ public:
Matrix4x4& operator=(const Matrix4x4& matrix4X4) = default; Matrix4x4& operator=(const Matrix4x4& matrix4X4) = default;
[[nodiscard]] Matrix4x4 operator*(const Matrix4x4& matrix4X4) const; [[nodiscard]] Matrix4x4 operator*(const Matrix4x4& matrix4X4) const;
[[nodiscard]] Point4D operator*(const Point4D& point4D) const; [[nodiscard]] Vec4D operator*(const Vec4D& point4D) const;
[[nodiscard]] Vec3D operator*(const Vec3D& vec) const; [[nodiscard]] Vec3D operator*(const Vec3D& vec) const;
// Any useful matrix (static methods) // Any useful matrix (static methods)

View File

@ -18,7 +18,7 @@ Mesh &Mesh::operator*=(const Matrix4x4 &matrix4X4) {
return *this; return *this;
} }
Mesh &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) {
@ -27,19 +27,17 @@ Mesh &Mesh::loadObj(const std::string& filename, const Vec3D& scale) {
} }
} }
this->scale(scale); this->scale(scale);
return *this;
} }
Mesh::Mesh(const std::string& filename, const Vec3D& scale){ Mesh::Mesh(ObjectNameTag nameTag, const std::string& filename, const Vec3D& scale) : Object(nameTag) {
loadObj(filename, scale); loadObj(filename, scale);
} }
Mesh::Mesh(const vector<Triangle> &tries) : _tris(tries) { Mesh::Mesh(ObjectNameTag nameTag, const vector<Triangle> &tries) : Object(nameTag), _tris(tries) {
} }
Mesh Mesh::Obj(const std::string& filename) { Mesh Mesh::Obj(ObjectNameTag nameTag, const std::string& filename) {
return Mesh(filename); return Mesh(std::move(nameTag), filename);
} }
void Mesh::rotate(const Vec3D &r) { void Mesh::rotate(const Vec3D &r) {
@ -78,24 +76,24 @@ void Mesh::setColor(const sf::Color& c) {
setTriangles(newTriangles); setTriangles(newTriangles);
} }
Mesh Mesh::LineTo(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; Mesh line(nameTag);
Vec3D v1 = (to - from).normalized(); Vec3D v1 = (to - from).normalized();
Vec3D v2 = from.cross(from + Vec3D{1, 0, 0}).normalized(); Vec3D v2 = from.cross(from + Vec3D{1, 0, 0}).normalized();
Vec3D v3 = v1.cross(v2).normalized(); Vec3D v3 = v1.cross(v2).normalized();
// from plane // from plane
Point4D p1 = (from - v2 * line_width/2.0 - v3 * line_width/2.0).makePoint4D(); Vec4D p1 = (from - v2 * line_width / 2.0 - v3 * line_width / 2.0).makePoint4D();
Point4D p2 = (from - v2 * line_width/2.0 + v3 * line_width/2.0).makePoint4D(); Vec4D p2 = (from - v2 * line_width / 2.0 + v3 * line_width / 2.0).makePoint4D();
Point4D p3 = (from + v2 * line_width/2.0 + v3 * line_width/2.0).makePoint4D(); Vec4D p3 = (from + v2 * line_width / 2.0 + v3 * line_width / 2.0).makePoint4D();
Point4D p4 = (from + v2 * line_width/2.0 - v3 * line_width/2.0).makePoint4D(); Vec4D p4 = (from + v2 * line_width / 2.0 - v3 * line_width / 2.0).makePoint4D();
// to plane // to plane
Point4D p5 = (to - v2 * line_width/2.0 - v3 * line_width/2.0).makePoint4D(); Vec4D p5 = (to - v2 * line_width / 2.0 - v3 * line_width / 2.0).makePoint4D();
Point4D p6 = (to - v2 * line_width/2.0 + v3 * line_width/2.0).makePoint4D(); Vec4D p6 = (to - v2 * line_width / 2.0 + v3 * line_width / 2.0).makePoint4D();
Point4D p7 = (to + v2 * line_width/2.0 + v3 * line_width/2.0).makePoint4D(); Vec4D p7 = (to + v2 * line_width / 2.0 + v3 * line_width / 2.0).makePoint4D();
Point4D p8 = (to + v2 * line_width/2.0 - v3 * line_width/2.0).makePoint4D(); Vec4D p8 = (to + v2 * line_width / 2.0 - v3 * line_width / 2.0).makePoint4D();
line._tris = std::move(std::vector<Triangle>{ line._tris = std::move(std::vector<Triangle>{
@ -117,7 +115,7 @@ Mesh Mesh::LineTo(const Vec3D& from, const Vec3D& to, double line_width, const s
return line; return line;
} }
Mesh::Mesh(const Mesh &mesh) : _tris(mesh._tris), _color(mesh._color), _visible(mesh._visible) { Mesh::Mesh(const Mesh &mesh) : Object(mesh.name()), _tris(mesh._tris), _color(mesh._color), _visible(mesh._visible) {
} }

View File

@ -5,6 +5,7 @@
#ifndef ENGINE_MESH_H #ifndef ENGINE_MESH_H
#define ENGINE_MESH_H #define ENGINE_MESH_H
#include <utility>
#include <vector> #include <vector>
#include "Triangle.h" #include "Triangle.h"
#include <SFML/Graphics.hpp> #include <SFML/Graphics.hpp>
@ -18,14 +19,14 @@ private:
Mesh& operator*=(const Matrix4x4& matrix4X4); Mesh& operator*=(const Matrix4x4& matrix4X4);
public: public:
Mesh() = default; explicit Mesh(ObjectNameTag nameTag) : Object(std::move(nameTag)) {};
Mesh& operator=(const Mesh& mesh) = delete; Mesh& operator=(const Mesh& mesh) = delete;
Mesh(const Mesh& mesh); Mesh(const Mesh& mesh);
explicit Mesh(const std::vector<Triangle>& tries); explicit Mesh(ObjectNameTag nameTag, const std::vector<Triangle>& tries);
explicit Mesh(const std::string& filename, const Vec3D& scale = Vec3D{1, 1, 1}); explicit Mesh(ObjectNameTag nameTag, const std::string& filename, const Vec3D& scale = Vec3D{1, 1, 1});
Mesh& loadObj(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>const &triangles() const { return _tris; }
[[nodiscard]] std::vector<Triangle>& triangles() { return _tris; } [[nodiscard]] std::vector<Triangle>& triangles() { return _tris; }
@ -51,8 +52,8 @@ public:
~Mesh() override; ~Mesh() override;
Mesh static Obj(const std::string& filename); Mesh static Obj(ObjectNameTag nameTag, const std::string& filename);
Mesh static LineTo(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

View File

@ -4,15 +4,16 @@
#include "Mouse.h" #include "Mouse.h"
#include "utils/Time.h" #include "utils/Time.h"
#include "Consts.h"
Vec2D Mouse::getMousePosition() const { Vec2D Mouse::getMousePosition() const {
sf::Vector2<int> pos = sf::Mouse::getPosition(*_window); sf::Vector2<int> pos = sf::Mouse::getPosition(*_screen->renderWindow());
return Vec2D(pos.x, pos.y); return Vec2D(pos.x, pos.y);
} }
Vec2D Mouse::getMouseDisplacement() const { Vec2D Mouse::getMouseDisplacement() const {
sf::Vector2<int> mousePos = sf::Mouse::getPosition(*_window); sf::Vector2<int> mousePos = sf::Mouse::getPosition(*_screen->renderWindow());
sf::Vector2<int> center = sf::Vector2<int>(_window->getSize().x/2, _window->getSize().y/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(); //setMouseInCenter();
@ -20,7 +21,7 @@ Vec2D Mouse::getMouseDisplacement() const {
} }
void Mouse::setMouseInCenter() const { void Mouse::setMouseInCenter() const {
sf::Mouse::setPosition({ static_cast<int>(_window->getSize().x / 2), static_cast<int>(_window->getSize().y / 2) }, *_window); 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) {
@ -28,8 +29,9 @@ bool Mouse::isButtonPressed(sf::Mouse::Button button) {
} }
bool Mouse::isButtonTapped(sf::Mouse::Button button) { bool Mouse::isButtonTapped(sf::Mouse::Button button) {
if (!Mouse::isButtonPressed(button)) if (!Mouse::isButtonPressed(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());
@ -40,11 +42,3 @@ bool Mouse::isButtonTapped(sf::Mouse::Button button) {
} }
return false; return false;
} }
void Mouse::setWindow(std::shared_ptr<sf::RenderWindow> window) {
_window = window;
}
void Mouse::setMouseCursorVisible(bool visible) {
_window->setMouseCursorVisible(visible);
}

View File

@ -6,18 +6,17 @@
#define SHOOTER_MOUSE_H #define SHOOTER_MOUSE_H
#include <memory> #include <memory>
#include <SFML/Graphics.hpp> #include <utility>
#include "Screen.h"
#include "Vec2D.h" #include "Vec2D.h"
class Mouse final { class Mouse final {
private: private:
std::shared_ptr<sf::RenderWindow> _window; const std::shared_ptr<Screen> _screen;
std::map<sf::Mouse::Button, double> _tappedButtons; std::map<sf::Mouse::Button, double> _tappedButtons;
public: public:
Mouse() = default; explicit Mouse(std::shared_ptr<Screen> screen) : _screen(std::move(screen)) {};
void setWindow(std::shared_ptr<sf::RenderWindow> window);
static bool isButtonPressed(sf::Mouse::Button button); // returns true if this _button is _pressed static bool isButtonPressed(sf::Mouse::Button button); // 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) bool isButtonTapped(sf::Mouse::Button button); // returns true if this _button is tapped and 1/5 sec passed (_button bouncing problem solved)
@ -25,7 +24,6 @@ public:
[[nodiscard]] Vec2D getMousePosition() const; [[nodiscard]] Vec2D getMousePosition() const;
[[nodiscard]] Vec2D getMouseDisplacement() const; [[nodiscard]] Vec2D getMouseDisplacement() const;
void setMouseInCenter() const; void setMouseInCenter() const;
void setMouseCursorVisible(bool visible);
}; };

View File

@ -7,123 +7,155 @@
#include "utils/Log.h" #include "utils/Log.h"
void Object::translate(const Vec3D &dv) { void Object::translate(const Vec3D &dv) {
_position = std::make_unique<Vec3D>(*_position + dv); _position = _position + dv;
for(auto &[attachedName, attachedObject] : _attachedObjects) for(auto &[attachedName, attachedObject] : _attachedObjects) {
attachedObject->translate(dv); if(!attachedObject.expired()) {
attachedObject.lock()->translate(dv);
}
}
} }
void Object::scale(const Vec3D &s) { void Object::scale(const Vec3D &s) {
for(auto &[attachedName, attachedObject] : _attachedObjects) for(auto &[attachedName, attachedObject] : _attachedObjects) {
attachedObject->scale(s); if(!attachedObject.expired()) {
attachedObject.lock()->scale(s);
}
}
} }
void Object::rotate(const Vec3D &r) { void Object::rotate(const Vec3D &r) {
_angle = std::make_unique<Vec3D>(*_angle + r); _angle = _angle + r;
Matrix4x4 rotationMatrix = Matrix4x4::RotationZ(r.z())*Matrix4x4::RotationY(r.y())*Matrix4x4::RotationX(r.z()); Matrix4x4 rotationMatrix = Matrix4x4::RotationZ(r.z())*Matrix4x4::RotationY(r.y())*Matrix4x4::RotationX(r.z());
_left = std::make_unique<Vec3D>(rotationMatrix * *_left); _left = rotationMatrix * _left;
_up = std::make_unique<Vec3D>(rotationMatrix * *_up); _up = rotationMatrix * _up;
_lookAt = std::make_unique<Vec3D>(rotationMatrix * *_lookAt); _lookAt = rotationMatrix * _lookAt;
for(auto &[attachedName, attachedObject] : _attachedObjects) for(auto &[attachedName, attachedObject] : _attachedObjects) {
attachedObject->rotateRelativePoint(position(), r); if(!attachedObject.expired()) {
attachedObject.lock()->rotateRelativePoint(position(), r);
}
}
} }
void Object::rotate(const Vec3D &v, double rv) { void Object::rotate(const Vec3D &v, double rv) {
Matrix4x4 rotationMatrix = Matrix4x4::Rotation(v, rv); Matrix4x4 rotationMatrix = Matrix4x4::Rotation(v, rv);
_left = std::make_unique<Vec3D>(rotationMatrix * *_left); _left = rotationMatrix * _left;
_up = std::make_unique<Vec3D>(rotationMatrix * *_up); _up = rotationMatrix * _up;
_lookAt = std::make_unique<Vec3D>(rotationMatrix * *_lookAt); _lookAt = rotationMatrix * _lookAt;
for(auto &[attachedName, attachedObject] : _attachedObjects) for(auto &[attachedName, attachedObject] : _attachedObjects) {
attachedObject->rotateRelativePoint(position(), v, rv); if(!attachedObject.expired()) {
attachedObject.lock()->rotateRelativePoint(position(), v, rv);
}
}
} }
void Object::rotateRelativePoint(const Vec3D &s, const Vec3D &r) { void Object::rotateRelativePoint(const Vec3D &s, const Vec3D &r) {
_angle = std::make_unique<Vec3D>(*_angle + r); _angle = _angle + r;
// Translate XYZ by vector r1 // Translate XYZ by vector r1
Vec3D r1(*_position - s); Vec3D r1(_position - s);
// In translated coordinate system we rotate body and position // In translated coordinate system we rotate body and position
Matrix4x4 rotationMatrix = Matrix4x4::Rotation(r); Matrix4x4 rotationMatrix = Matrix4x4::Rotation(r);
Vec3D r2(rotationMatrix*r1); Vec3D r2(rotationMatrix*r1);
_left = std::make_unique<Vec3D>(rotationMatrix * *_left); _left = rotationMatrix * _left;
_up = std::make_unique<Vec3D>(rotationMatrix * *_up); _up = rotationMatrix * _up;
_lookAt = std::make_unique<Vec3D>(rotationMatrix * *_lookAt); _lookAt = rotationMatrix * _lookAt;
// After rotation we translate XYZ by vector -r2 and recalculate position // After rotation we translate XYZ by vector -r2 and recalculate position
_position = std::make_unique<Vec3D>(s + r2); _position = s + r2;
for(auto &[attachedName, attachedObject] : _attachedObjects) for(auto &[attachedName, attachedObject] : _attachedObjects) {
attachedObject->rotateRelativePoint(s, r); if(!attachedObject.expired()) {
attachedObject.lock()->rotateRelativePoint(s, r);
}
}
} }
void Object::rotateRelativePoint(const Vec3D &s, const Vec3D &v, double r) { void Object::rotateRelativePoint(const Vec3D &s, const Vec3D &v, double r) {
// Translate XYZ by vector r1 // Translate XYZ by vector r1
Vec3D r1(*_position - s); Vec3D r1(_position - s);
// In translated coordinate system we rotate body and position // In translated coordinate system we rotate body and position
Matrix4x4 rotationMatrix = Matrix4x4::Rotation(v, r); Matrix4x4 rotationMatrix = Matrix4x4::Rotation(v, r);
Vec3D r2 = rotationMatrix*r1; Vec3D r2 = rotationMatrix*r1;
_left = std::make_unique<Vec3D>(rotationMatrix * *_left); _left = rotationMatrix * _left;
_up = std::make_unique<Vec3D>(rotationMatrix * *_up); _up = rotationMatrix * _up;
_lookAt = std::make_unique<Vec3D>(rotationMatrix * *_lookAt); _lookAt = rotationMatrix * _lookAt;
// After rotation we translate XYZ by vector -r2 and recalculate position // After rotation we translate XYZ by vector -r2 and recalculate position
_position = std::make_unique<Vec3D>(s + r2); _position = s + r2;
for(auto &[attachedName, attachedObject] : _attachedObjects) for(auto &[attachedName, attachedObject] : _attachedObjects) {
attachedObject->rotateRelativePoint(s, v, r); if(!attachedObject.expired()) {
attachedObject.lock()->rotateRelativePoint(s, v, r);
}
}
} }
void Object::rotateLeft(double rl) { void Object::rotateLeft(double rl) {
_angleLeftUpLookAt = std::make_unique<Vec3D>(Vec3D{_angleLeftUpLookAt->x() + rl, _angleLeftUpLookAt = Vec3D{_angleLeftUpLookAt.x() + rl,
_angleLeftUpLookAt->y(), _angleLeftUpLookAt.y(),
_angleLeftUpLookAt->z()}); _angleLeftUpLookAt.z()};
rotate(Vec3D(*_left), rl); rotate(Vec3D(_left), rl);
} }
void Object::rotateUp(double ru) { void Object::rotateUp(double ru) {
_angleLeftUpLookAt = std::make_unique<Vec3D>(Vec3D{_angleLeftUpLookAt->x(), _angleLeftUpLookAt = Vec3D{_angleLeftUpLookAt.x(),
_angleLeftUpLookAt->y() + ru, _angleLeftUpLookAt.y() + ru,
_angleLeftUpLookAt->z()}); _angleLeftUpLookAt.z()};
rotate(Vec3D(*_up), ru); rotate(Vec3D(_up), ru);
} }
void Object::rotateLookAt(double rlAt) { void Object::rotateLookAt(double rlAt) {
_angleLeftUpLookAt = std::make_unique<Vec3D>(Vec3D{_angleLeftUpLookAt->x(), _angleLeftUpLookAt = Vec3D{_angleLeftUpLookAt.x(),
_angleLeftUpLookAt->y(), _angleLeftUpLookAt.y(),
_angleLeftUpLookAt->z() + rlAt}); _angleLeftUpLookAt.z() + rlAt};
rotate(Vec3D(*_lookAt), rlAt); rotate(Vec3D(_lookAt), rlAt);
} }
void Object::translateToPoint(const Vec3D &point) { void Object::translateToPoint(const Vec3D &point) {
translate(point - *_position); translate(point - _position);
} }
void Object::rotateToAngle(const Vec3D &v) { 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) if(_attachedObjects.count(tag) == 0 || _attachedObjects.find(tag)->second.expired()) {
return nullptr; return nullptr;
return _attachedObjects.find(tag)->second; }
return _attachedObjects.find(tag)->second.lock();
} }
void Object::attach(std::shared_ptr<Object> object, const ObjectNameTag& tag) { bool Object::checkIfAttached(Object *obj) {
// TODO: solve problem with possible infinite recursive call chains for(const auto& [nameTag, attachedObject] : _attachedObjects) {
if(this != object.get()) if (obj == attachedObject.lock().get() || attachedObject.lock()->checkIfAttached(obj)) {
_attachedObjects.emplace(tag, object); return true;
else }
}
return false;
}
void Object::attach(std::shared_ptr<Object> object) {
if(this != object.get()) {
if(!object->checkIfAttached(this)) {
_attachedObjects.emplace(object->name(), object);
} else {
throw std::invalid_argument{"Object::attach: You tried to create infinite recursive call chains"};
}
} else {
throw std::invalid_argument{"Object::attach: You cannot attach object to itself"}; throw std::invalid_argument{"Object::attach: You cannot attach object to itself"};
}
} }
void Object::unattach(const ObjectNameTag& tag) { void Object::unattach(const ObjectNameTag& tag) {

View File

@ -24,18 +24,22 @@ public:
}; };
class Object { class Object {
private:
bool checkIfAttached(Object* obj);
const ObjectNameTag _nameTag;
protected: protected:
std::unique_ptr<Vec3D> _left = std::make_unique<Vec3D>(Vec3D{1, 0, 0}); // internal X Vec3D _left {1, 0, 0}; // internal X
std::unique_ptr<Vec3D> _up = std::make_unique<Vec3D>(Vec3D{0, 1, 0}); // internal Y Vec3D _up {0, 1, 0}; // internal Y
std::unique_ptr<Vec3D> _lookAt = std::make_unique<Vec3D>(Vec3D{0, 0, 1}); // internal Z Vec3D _lookAt {0, 0, 1}; // internal Z
std::map<ObjectNameTag, std::shared_ptr<Object>> _attachedObjects; std::map<ObjectNameTag, std::weak_ptr<Object>> _attachedObjects;
std::unique_ptr<Vec3D> _position = std::make_unique<Vec3D>(Vec3D{0, 0, 0}); Vec3D _position {0, 0, 0};
std::unique_ptr<Vec3D> _angle = std::make_unique<Vec3D>(Vec3D{0, 0, 0}); Vec3D _angle {0, 0, 0};
std::unique_ptr<Vec3D> _angleLeftUpLookAt = std::make_unique<Vec3D>(Vec3D{0, 0, 0}); Vec3D _angleLeftUpLookAt{0, 0, 0};
public: public:
Object() = default; Object(ObjectNameTag nameTag) : _nameTag(nameTag) {};
virtual void translate(const Vec3D& dv); virtual void translate(const Vec3D& dv);
virtual void translateToPoint(const Vec3D& point); virtual void translateToPoint(const Vec3D& point);
@ -49,18 +53,20 @@ public:
void rotateUp(double ru); void rotateUp(double ru);
void rotateLookAt(double rlAt); void rotateLookAt(double rlAt);
[[nodiscard]] Vec3D position() const { return *_position; } [[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; }
[[nodiscard]] Vec3D left() const { return *_left; } [[nodiscard]] Vec3D left() const { return _left; }
[[nodiscard]] Vec3D up() const { return *_up; } [[nodiscard]] Vec3D up() const { return _up; }
[[nodiscard]] Vec3D lookAt() const { return *_lookAt; } [[nodiscard]] Vec3D lookAt() const { return _lookAt; }
void attach(std::shared_ptr<Object> object, const ObjectNameTag& tag); void attach(std::shared_ptr<Object> object);
void unattach(const ObjectNameTag& tag); void unattach(const ObjectNameTag& tag);
std::shared_ptr<Object> attached(const ObjectNameTag& tag); std::shared_ptr<Object> attached(const ObjectNameTag& tag);
ObjectNameTag name() const { return _nameTag; }
virtual ~Object(); virtual ~Object();
}; };

View File

@ -4,21 +4,19 @@
#include "Plane.h" #include "Plane.h"
Plane::Plane(const Triangle& tri) : _triangle(tri), _n(tri.norm()), _p(tri[0]) { Plane::Plane(const Triangle& tri) : _normal(tri.norm()), _point(tri[0]) {
} }
Plane::Plane(const Vec3D &N, const Vec3D &P) : _n(N.normalized()), _p(P) { Plane::Plane(const Vec3D &N, const Vec3D &P) : _normal(N.normalized()), _point(P) {
} }
double Plane::distance(const Vec3D &point) const { double Plane::distance(const Vec3D &point) const {
return point.dot(_n) - _p.dot(_n); return point.dot(_normal) - _point.dot(_normal);
} }
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(_n); double s_dot_n = start.dot(_normal);
double k = (s_dot_n - _p.dot(_n)) / (s_dot_n - end.dot(_n)); 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);
} }

View File

@ -5,30 +5,28 @@
#ifndef ENGINE_PLANE_H #ifndef ENGINE_PLANE_H
#define ENGINE_PLANE_H #define ENGINE_PLANE_H
#include "Point4D.h" #include "Vec4D.h"
#include "Triangle.h" #include "Triangle.h"
class Plane final { class Plane final {
private: private:
// You can define plane by defining the points in 3D space const Vec3D _normal;
Triangle _triangle; const Vec3D _point;
// Or by defining normal vector and one val laying on the plane
Vec3D _n = Vec3D{0, 0, 1};
Vec3D _p{};
public: public:
// A plain with normal vector '_n' and val '_p' lays on the plane Plane() = delete;
Plane() = default;
Plane(const Vec3D& N, const Vec3D& P);
Plane(const Plane& plane) = default; Plane(const Plane& plane) = default;
// You can define plane by defining the points in 3D space
explicit Plane(const Triangle& tri); 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; [[nodiscard]] double distance(const Vec3D& point4D) const;
// Point4D 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 _n; } [[nodiscard]] Vec3D N() const { return _normal; }
[[nodiscard]] Vec3D P() const { return _p; } [[nodiscard]] Vec3D P() const { return _point; }
}; };

View File

@ -1,70 +0,0 @@
//
// Created by Иван Ильин on 12.01.2021.
//
#include "Point4D.h"
#include <cmath>
#include <stdexcept>
Point4D::Point4D (double x, double y, double z, double w) {
_arr_point[0] = x;
_arr_point[1] = y;
_arr_point[2] = z;
_arr_point[3] = w;
}
Point4D::Point4D(const Point4D &point4D) {
_arr_point[0] = point4D.x();
_arr_point[1] = point4D.y();
_arr_point[2] = point4D.z();
_arr_point[3] = point4D.w();
}
[[nodiscard]] Point4D Point4D::operator-() const {
return Point4D(-x(), -y(), -z(), -w());
}
bool Point4D::operator==(const Point4D& point4D) const {
return (*this - point4D).sqrAbs() < Consts::EPS;
}
bool Point4D::operator!=(const Point4D& point4D) const {
return !(*this == point4D);
}
// Operations with Point4D
Point4D Point4D::operator+(const Point4D& point4D) const {
return Point4D(x()+point4D.x(), y()+point4D.y(), z()+point4D.z(), w()+point4D.w());
}
Point4D Point4D::operator-(const Point4D& point4D) const {
return Point4D(*this) + -point4D;
}
Point4D Point4D::operator*(double number) const {
return Point4D(x()*number, y()*number, z()*number, w()*number);
}
Point4D Point4D::operator/(double number) const {
if(std::abs(number) > Consts::EPS)
return Point4D(*this)*(1.0/number);
else
throw std::domain_error{"Point4D::operator/(double number): division by zero"};
}
// Other useful methods
double Point4D::sqrAbs() const {
return x()*x() + y()*y() + z()*z();
}
double Point4D::abs() const {
return sqrt(sqrAbs());
}
Point4D Point4D::normalized() const {
double vecAbs = abs();
if(vecAbs > Consts::EPS)
return Point4D(*this)/abs();
else
return Point4D(1);
}

View File

@ -1,47 +0,0 @@
//
// Created by Иван Ильин on 12.01.2021.
//
#ifndef ENGINE_POINT4D_H
#define ENGINE_POINT4D_H
#include <array>
#include "Consts.h"
class Point4D final {
private:
std::array<double, 4> _arr_point{};
public:
Point4D () = default;
Point4D (const Point4D& point4D);
explicit Point4D (double x, double y = 0.0, double z = 0.0, double w = 0.0);
Point4D& operator=(const Point4D& point4D) = delete;
[[nodiscard]] double x() const { return _arr_point[0]; }
[[nodiscard]] double y() const { return _arr_point[1]; }
[[nodiscard]] double z() const { return _arr_point[2]; }
[[nodiscard]] double w() const { return _arr_point[3]; }
[[nodiscard]] Point4D operator-() const;
// Boolean operations
bool operator==(const Point4D& point4D) const;
bool operator!=(const Point4D& point4D) const;
// Operations with Point4D
[[nodiscard]] Point4D operator+(const Point4D& point4D) const;
[[nodiscard]] Point4D operator-(const Point4D& point4D) const;
// Operations with numbers
[[nodiscard]] Point4D operator*(double number) const;
[[nodiscard]] Point4D operator/(double number) const;
// Other useful methods
[[nodiscard]] double sqrAbs() const; // Returns squared vector length
[[nodiscard]] double abs() const; // Returns vector length
[[nodiscard]] Point4D normalized() const; // Returns normalized vector without changing
};
#endif //INC_3DZAVR_POINT4D_H

View File

@ -16,20 +16,23 @@ void ResourceManager::init() {
} }
void ResourceManager::unloadTextures() { void ResourceManager::unloadTextures() {
for (auto & _texture : _instance->_textures) for (auto & _texture : _instance->_textures) {
_texture.second.reset(); _texture.second.reset();
}
_instance->_textures.clear(); _instance->_textures.clear();
} }
void ResourceManager::unloadSoundBuffers() { void ResourceManager::unloadSoundBuffers() {
for (auto & _soundBuffer : _instance->_soundBuffers) for (auto & _soundBuffer : _instance->_soundBuffers) {
_soundBuffer.second.reset(); _soundBuffer.second.reset();
}
_instance->_soundBuffers.clear(); _instance->_soundBuffers.clear();
} }
void ResourceManager::unloadFonts() { void ResourceManager::unloadFonts() {
for (auto & _font : _instance->_fonts) for (auto & _font : _instance->_fonts) {
_font.second.reset(); _font.second.reset();
}
_instance->_fonts.clear(); _instance->_fonts.clear();
} }
@ -51,18 +54,21 @@ void ResourceManager::free() {
} }
std::shared_ptr<sf::Texture> ResourceManager::loadTexture(const std::string& filename) { std::shared_ptr<sf::Texture> ResourceManager::loadTexture(const std::string& filename) {
if(!_instance) if(!_instance) {
return nullptr; return nullptr;
}
// If texture is already loaded - return pointer to it // If texture is already loaded - return pointer to it
auto it = _instance->_textures.find(filename); auto it = _instance->_textures.find(filename);
if (it != _instance->_textures.end()) if (it != _instance->_textures.end()) {
return it->second; return it->second;
}
// Otherwise - try to load it. If failure - return zero // Otherwise - try to load it. If failure - return zero
std::shared_ptr<sf::Texture> texture(new sf::Texture); std::shared_ptr<sf::Texture> texture(new sf::Texture);
if (!texture->loadFromFile(filename)) if (!texture->loadFromFile(filename)) {
return nullptr; return nullptr;
}
// If success - remember and return texture pointer // If success - remember and return texture pointer
texture->setRepeated(true); texture->setRepeated(true);
@ -72,18 +78,21 @@ std::shared_ptr<sf::Texture> ResourceManager::loadTexture(const std::string& fil
} }
std::shared_ptr<sf::SoundBuffer> ResourceManager::loadSoundBuffer(const std::string& filename) { std::shared_ptr<sf::SoundBuffer> ResourceManager::loadSoundBuffer(const std::string& filename) {
if(!_instance) if(!_instance) {
return nullptr; return nullptr;
}
// If sound buffer is already loaded - return pointer to it // If sound buffer is already loaded - return pointer to it
auto it = _instance->_soundBuffers.find(filename); auto it = _instance->_soundBuffers.find(filename);
if (it != _instance->_soundBuffers.end()) if (it != _instance->_soundBuffers.end()) {
return it->second; return it->second;
}
// Otherwise - try to load it. If failure - return zero // Otherwise - try to load it. If failure - return zero
std::shared_ptr<sf::SoundBuffer> soundBuffer(new sf::SoundBuffer); std::shared_ptr<sf::SoundBuffer> soundBuffer(new sf::SoundBuffer);
if (!soundBuffer->loadFromFile(filename)) if (!soundBuffer->loadFromFile(filename)) {
return nullptr; return nullptr;
}
// If success - remember and return sound pointer // If success - remember and return sound pointer
_instance->_soundBuffers.emplace(filename, soundBuffer); _instance->_soundBuffers.emplace(filename, soundBuffer);
@ -92,18 +101,21 @@ std::shared_ptr<sf::SoundBuffer> ResourceManager::loadSoundBuffer(const std::str
} }
std::shared_ptr<sf::Font> ResourceManager::loadFont(const std::string& filename) { std::shared_ptr<sf::Font> ResourceManager::loadFont(const std::string& filename) {
if(!_instance) if(!_instance) {
return nullptr; return nullptr;
}
// If font is already loaded - return pointer to it // If font is already loaded - return pointer to it
auto it = _instance->_fonts.find(filename); auto it = _instance->_fonts.find(filename);
if (it != _instance->_fonts.end()) if (it != _instance->_fonts.end()) {
return it->second; return it->second;
}
// Otherwise - try to load it. If failure - return zero // Otherwise - try to load it. If failure - return zero
std::shared_ptr<sf::Font> font(new sf::Font); std::shared_ptr<sf::Font> font(new sf::Font);
if (!font->loadFromFile(filename)) if (!font->loadFromFile(filename)) {
return nullptr; return nullptr;
}
// If success - remember and return font pointer // If success - remember and return font pointer
_instance->_fonts.emplace(filename, font); _instance->_fonts.emplace(filename, font);
@ -122,18 +134,16 @@ std::vector<std::shared_ptr<Mesh>> ResourceManager::loadObjects(const std::strin
} }
std::ifstream file(filename); std::ifstream file(filename);
if (!file.is_open()) if (!file.is_open()) {
{
Log::log("Mesh::LoadObjects(): cannot load file from " + filename); Log::log("Mesh::LoadObjects(): cannot load file from " + filename);
return objects; return objects;
} }
std::vector<Point4D> verts{}; std::vector<Vec4D> verts{};
std::vector<Triangle> tris{}; std::vector<Triangle> tris{};
sf::Color currentColor = sf::Color(255, 245, 194, 255); sf::Color currentColor = sf::Color(255, 245, 194, 255);
while (!file.eof()) while (!file.eof()) {
{
char line[128]; char line[128];
file.getline(line, 128); file.getline(line, 128);
@ -143,14 +153,14 @@ std::vector<std::shared_ptr<Mesh>> ResourceManager::loadObjects(const std::strin
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>(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); verts.emplace_back(x, y, z, 1.0);
} }
if(line[0] == 'g') { if(line[0] == 'g') {
std::string matInfo; std::string matInfo;
@ -174,8 +184,11 @@ std::vector<std::shared_ptr<Mesh>> ResourceManager::loadObjects(const std::strin
} }
} }
if(!tris.empty()) if(!tris.empty()) {
objects.push_back(std::make_shared<Mesh>(tris)); objects.push_back(
std::make_shared<Mesh>(ObjectNameTag(filename + "_temp_obj_" + std::to_string(objects.size())), tris));
}
tris.clear();
file.close(); file.close();

View File

@ -21,7 +21,6 @@ void Screen::open(int screenWidth, int screenHeight, const std::string &name, bo
settings.depthBits = 24; settings.depthBits = 24;
settings.antialiasingLevel = 8; settings.antialiasingLevel = 8;
_window = std::make_shared<sf::RenderWindow>();
_window->create(sf::VideoMode(_w, _h), name, style, settings); _window->create(sf::VideoMode(_w, _h), name, style, settings);
_window->setVerticalSyncEnabled(verticalSync); _window->setVerticalSyncEnabled(verticalSync);
} }
@ -88,6 +87,10 @@ void Screen::debugText(const std::string& text) {
_window->popGLStates(); _window->popGLStates();
} }
void Screen::setMouseCursorVisible(bool visible) {
_window->setMouseCursorVisible(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);
@ -131,10 +134,6 @@ void Screen::drawText(const sf::Text &text) {
_window->popGLStates(); _window->popGLStates();
} }
void Screen::attachMouse(std::shared_ptr<Mouse> mouse) {
mouse->setWindow(_window);
}
// OpenGL functions // OpenGL functions
void Screen::glDrawMesh(GLfloat* geometry, GLfloat* view, size_t count) { void Screen::glDrawMesh(GLfloat* geometry, GLfloat* view, size_t count) {
// OpenGL: // OpenGL:

View File

@ -11,7 +11,6 @@
#include <SFML/Graphics.hpp> #include <SFML/Graphics.hpp>
#include <map> #include <map>
#include "utils/Time.h" #include "utils/Time.h"
#include "Mouse.h"
#include "Consts.h" #include "Consts.h"
#include "Mesh.h" #include "Mesh.h"
#include "Camera.h" #include "Camera.h"
@ -25,7 +24,7 @@ private:
sf::Color _background; sf::Color _background;
std::shared_ptr<sf::RenderWindow> _window; 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);
@ -51,11 +50,13 @@ public:
void debugText(const std::string& text); void debugText(const std::string& text);
void attachMouse(std::shared_ptr<Mouse> mouse); void setMouseCursorVisible(bool visible);
// OpenGL functions // OpenGL functions
void glDrawMesh(GLfloat* geometry, GLfloat* view, size_t count); void glDrawMesh(GLfloat* geometry, GLfloat* view, 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; }
}; };

View File

@ -12,8 +12,9 @@ void SoundController::init() {
} }
void SoundController::playSound(const SoundTag& soundTag, const std::string& filename) { void SoundController::playSound(const SoundTag& soundTag, const std::string& filename) {
if(!_instance) if(!_instance) {
return; return;
}
stopSound(soundTag); stopSound(soundTag);
_instance->_sounds.emplace(soundTag, sf::Sound(*ResourceManager::loadSoundBuffer(filename))); _instance->_sounds.emplace(soundTag, sf::Sound(*ResourceManager::loadSoundBuffer(filename)));
@ -21,8 +22,9 @@ void SoundController::playSound(const SoundTag& soundTag, const std::string& fil
} }
void SoundController::pauseSound(const SoundTag& soundTag) { void SoundController::pauseSound(const SoundTag& soundTag) {
if(!_instance) if(!_instance) {
return; return;
}
if(_instance->_sounds.count(soundTag) > 0) { if(_instance->_sounds.count(soundTag) > 0) {
_instance->_sounds[soundTag].pause(); _instance->_sounds[soundTag].pause();
@ -30,8 +32,9 @@ void SoundController::pauseSound(const SoundTag& soundTag) {
} }
void SoundController::stopSound(const SoundTag& soundTag) { void SoundController::stopSound(const SoundTag& soundTag) {
if(!_instance) if(!_instance) {
return; return;
}
if(_instance->_sounds.count(soundTag) > 0) { if(_instance->_sounds.count(soundTag) > 0) {
_instance->_sounds[soundTag].stop(); _instance->_sounds[soundTag].stop();
@ -40,12 +43,13 @@ void SoundController::stopSound(const SoundTag& soundTag) {
} }
sf::Sound::Status SoundController::getStatus(const SoundTag& soundTag) { sf::Sound::Status SoundController::getStatus(const SoundTag& soundTag) {
if(_instance == nullptr) if(_instance == nullptr) {
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 {
_instance->_sounds.erase(soundTag); _instance->_sounds.erase(soundTag);
return sf::Sound::Status::Stopped; return sf::Sound::Status::Stopped;
} }

View File

@ -3,21 +3,12 @@
// //
#include "Triangle.h" #include "Triangle.h"
#include "Consts.h"
Triangle::Triangle () { Triangle::Triangle(const Vec4D& p1, const Vec4D& p2, const Vec4D& p3, sf::Color color) : _color(color), _points{p1, p2, p3} {
_points.emplace_back(Point4D(0, 0, 0, 1));
_points.emplace_back(Point4D(0, 0, 0, 1));
_points.emplace_back(Point4D(0, 0, 0, 1));
} }
Triangle::Triangle(const Point4D& p1, const Point4D& p2, const Point4D& p3, sf::Color color) : _color(color) { Triangle::Triangle(const Triangle &triangle) : _points{triangle._points[0], triangle._points[1], triangle._points[2]}, _color(triangle._color) {
_points.emplace_back(Point4D(p1));
_points.emplace_back(Point4D(p2));
_points.emplace_back(Point4D(p3));
}
Triangle::Triangle(const Triangle &triangle) : _points(triangle._points), _color(triangle._color) {
} }
Triangle Triangle::operator*(const Matrix4x4 &matrix4X4) const { Triangle Triangle::operator*(const Matrix4x4 &matrix4X4) const {
@ -30,13 +21,14 @@ 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);
}
} }
Point4D Triangle::operator[](int i) const { Vec4D Triangle::operator[](int i) const {
return _points[i]; return _points[i];
} }
@ -47,7 +39,8 @@ 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;
} }

View File

@ -5,7 +5,7 @@
#ifndef ENGINE_TRIANGLE_H #ifndef ENGINE_TRIANGLE_H
#define ENGINE_TRIANGLE_H #define ENGINE_TRIANGLE_H
#include "Point4D.h" #include "Vec4D.h"
#include "Vec3D.h" #include "Vec3D.h"
#include "Matrix4x4.h" #include "Matrix4x4.h"
#include <SFML/Graphics.hpp> #include <SFML/Graphics.hpp>
@ -13,14 +13,14 @@
class Triangle final { class Triangle final {
private: private:
sf::Color _color; sf::Color _color;
std::vector<Point4D> _points; Vec4D _points[3];
public: public:
Triangle (); Triangle() : _points{Vec4D{}, Vec4D{}, Vec4D{}} {};
Triangle (const Triangle& triangle); Triangle(const Triangle& triangle);
Triangle (const Point4D& p1, const Point4D& p2, const Point4D& p3, sf::Color color = {0, 0, 0}); Triangle(const Vec4D& p1, const Vec4D& p2, const Vec4D& p3, sf::Color color = {0, 0, 0});
Triangle& operator=(const Triangle&) = delete; Triangle& operator=(const Triangle&) = default;
[[nodiscard]] Point4D operator[] (int i) const; [[nodiscard]] Vec4D operator[] (int i) const;
[[nodiscard]] Vec3D norm() const; [[nodiscard]] Vec3D norm() const;
// Operations with Matrix4x4 // Operations with Matrix4x4

View File

@ -4,6 +4,7 @@
#include <cmath> #include <cmath>
#include "Vec2D.h" #include "Vec2D.h"
#include "Consts.h"
Vec2D::Vec2D(const Vec2D &vec) { Vec2D::Vec2D(const Vec2D &vec) {
_arr_point[0] = vec.x(); _arr_point[0] = vec.x();
@ -15,7 +16,7 @@ Vec2D::Vec2D (double x, double y) {
_arr_point[1] = y; _arr_point[1] = y;
} }
Vec2D::Vec2D(const Point4D &point4D) { Vec2D::Vec2D(const Vec4D &point4D) {
_arr_point[0] = point4D.x(); _arr_point[0] = point4D.x();
_arr_point[1] = point4D.y(); _arr_point[1] = point4D.y();
} }
@ -43,10 +44,11 @@ Vec2D Vec2D::operator*(double number) const {
} }
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"};
}
} }
// Other useful methods // Other useful methods
@ -60,10 +62,11 @@ 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 {

View File

@ -5,9 +5,8 @@
#ifndef SHOOTER_VEC2D_H #ifndef SHOOTER_VEC2D_H
#define SHOOTER_VEC2D_H #define SHOOTER_VEC2D_H
#include <array> #include <array>
#include "Point4D.h" #include "Vec4D.h"
class Vec2D final { class Vec2D final {
private: private:
@ -16,9 +15,9 @@ private:
public: public:
Vec2D () = default; Vec2D () = default;
Vec2D (const Vec2D& vec); Vec2D (const Vec2D& vec);
explicit Vec2D (const Point4D& point4D); explicit Vec2D (const Vec4D& point4D);
explicit Vec2D (double x, double y = 0.0); explicit Vec2D (double x, double y = 0.0);
Vec2D& operator=(const Vec2D&) = delete; 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]; }

View File

@ -3,6 +3,7 @@
// //
#include "Vec3D.h" #include "Vec3D.h"
#include "Consts.h"
#include <cmath> #include <cmath>
#include <stdexcept> #include <stdexcept>
@ -12,7 +13,7 @@ Vec3D::Vec3D(const Vec3D &vec) {
_arr_point[2] = vec.z(); _arr_point[2] = vec.z();
} }
Vec3D::Vec3D (const Point4D& 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();
@ -48,10 +49,11 @@ Vec3D Vec3D::operator*(double number) const {
} }
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"};
}
} }
// Other useful methods // Other useful methods
@ -65,10 +67,11 @@ 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 {
@ -81,6 +84,6 @@ Vec3D Vec3D::cross(const Vec3D& vec) const {
x() * vec.y() - vec.x() * y()}; x() * vec.y() - vec.x() * y()};
} }
Point4D Vec3D::makePoint4D() const { Vec4D Vec3D::makePoint4D() const {
return Point4D(x(), y(), z(), 1.0); return Vec4D(x(), y(), z(), 1.0);
} }

View File

@ -6,7 +6,7 @@
#define SHOOTER_VEC3D_H #define SHOOTER_VEC3D_H
#include <array> #include <array>
#include "Point4D.h" #include "Vec4D.h"
class Vec3D final { class Vec3D final {
private: private:
@ -15,9 +15,9 @@ private:
public: public:
Vec3D () = default; Vec3D () = default;
Vec3D (const Vec3D& vec); Vec3D (const Vec3D& vec);
explicit Vec3D (const Point4D& vec); explicit Vec3D (const Vec4D& vec);
explicit Vec3D (double x, double y = 0.0, double z = 0.0); explicit Vec3D (double x, double y = 0.0, double z = 0.0);
Vec3D& operator=(const Vec3D&) = delete; 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]; }
@ -29,7 +29,7 @@ public:
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 Point4D // 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;
@ -44,7 +44,7 @@ public:
[[nodiscard]] double sqrAbs() const; // Returns squared vector length [[nodiscard]] double sqrAbs() const; // Returns squared vector length
[[nodiscard]] double abs() const; // Returns vector length [[nodiscard]] double abs() const; // Returns vector length
[[nodiscard]] Vec3D normalized() const; // Returns normalized vector without changing [[nodiscard]] Vec3D normalized() const; // Returns normalized vector without changing
[[nodiscard]] Point4D makePoint4D() const; [[nodiscard]] Vec4D makePoint4D() const;
}; };

73
engine/Vec4D.cpp Normal file
View File

@ -0,0 +1,73 @@
//
// Created by Иван Ильин on 12.01.2021.
//
#include "Vec4D.h"
#include "Consts.h"
#include <cmath>
#include <stdexcept>
Vec4D::Vec4D (double x, double y, double z, double w) {
_arr_point[0] = x;
_arr_point[1] = y;
_arr_point[2] = z;
_arr_point[3] = w;
}
Vec4D::Vec4D(const Vec4D &point4D) {
_arr_point[0] = point4D.x();
_arr_point[1] = point4D.y();
_arr_point[2] = point4D.z();
_arr_point[3] = point4D.w();
}
[[nodiscard]] Vec4D Vec4D::operator-() const {
return Vec4D(-x(), -y(), -z(), -w());
}
bool Vec4D::operator==(const Vec4D& point4D) const {
return (*this - point4D).sqrAbs() < Consts::EPS;
}
bool Vec4D::operator!=(const Vec4D& point4D) const {
return !(*this == point4D);
}
// Operations with Vec4D
Vec4D Vec4D::operator+(const Vec4D& point4D) const {
return Vec4D(x() + point4D.x(), y() + point4D.y(), z() + point4D.z(), w() + point4D.w());
}
Vec4D Vec4D::operator-(const Vec4D& point4D) const {
return Vec4D(*this) + -point4D;
}
Vec4D Vec4D::operator*(double number) const {
return Vec4D(x() * number, y() * number, z() * number, w() * number);
}
Vec4D Vec4D::operator/(double number) const {
if(std::abs(number) > Consts::EPS) {
return Vec4D(*this) * (1.0 / number);
} else {
throw std::domain_error{"Vec4D::operator/(double number): division by zero"};
}
}
// Other useful methods
double Vec4D::sqrAbs() const {
return x()*x() + y()*y() + z()*z();
}
double Vec4D::abs() const {
return sqrt(sqrAbs());
}
Vec4D Vec4D::normalized() const {
double vecAbs = abs();
if(vecAbs > Consts::EPS) {
return Vec4D(*this) / abs();
} else {
return Vec4D(1);
}
}

46
engine/Vec4D.h Normal file
View File

@ -0,0 +1,46 @@
//
// Created by Иван Ильин on 12.01.2021.
//
#ifndef ENGINE_POINT4D_H
#define ENGINE_POINT4D_H
#include <array>
class Vec4D final {
private:
std::array<double, 4> _arr_point{};
public:
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;
[[nodiscard]] double x() const { return _arr_point[0]; }
[[nodiscard]] double y() const { return _arr_point[1]; }
[[nodiscard]] double z() const { return _arr_point[2]; }
[[nodiscard]] double w() const { return _arr_point[3]; }
[[nodiscard]] Vec4D operator-() const;
// Boolean operations
bool operator==(const Vec4D& point4D) const;
bool operator!=(const Vec4D& point4D) const;
// Operations with Vec4D
[[nodiscard]] Vec4D operator+(const Vec4D& point4D) const;
[[nodiscard]] Vec4D operator-(const Vec4D& point4D) const;
// Operations with numbers
[[nodiscard]] Vec4D operator*(double number) const;
[[nodiscard]] Vec4D operator/(double number) const;
// Other useful methods
[[nodiscard]] double sqrAbs() const; // Returns squared vector length
[[nodiscard]] double abs() const; // Returns vector length
[[nodiscard]] Vec4D normalized() const; // Returns normalized vector without changing
};
#endif //INC_3DZAVR_POINT4D_H

View File

@ -11,13 +11,13 @@
using namespace std; using namespace std;
void World::addBody(std::shared_ptr<RigidBody> body, const ObjectNameTag& tag) { void World::addBody(std::shared_ptr<RigidBody> body) {
_objects.emplace(tag, body); _objects.emplace(body->name(), body);
Log::log("World::addBody(): inserted body '" + tag.str() + "' with " + std::to_string(_objects[tag]->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(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.");
} }
@ -30,20 +30,23 @@ IntersectionInformation World::rayCast(const Vec3D& from, const Vec3D& to, const
while (s >> t) tagsToSkip.push_back(t); while (s >> t) tagsToSkip.push_back(t);
bool intersected = false; bool intersected = false;
std::unique_ptr<Vec3D> point = std::make_unique<Vec3D>(); Vec3D point{};
std::unique_ptr<Triangle> triangle = std::make_unique<Triangle>(); Triangle triangle;
std::string bodyName; std::string bodyName;
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) {
// TODO: check this stuff:
//for (auto& escapeTag : tagsToSkip) //for (auto& escapeTag : tagsToSkip)
// if(name.str().find(escapeTag) != std::string::npos) // if(name.str().find(escapeTag) != std::string::npos)
// continue; // continue;
if(name.str().find("Player") != std::string::npos || name.str().find("weapon") != std::string::npos) if(name.str().find("Player") != std::string::npos || name.str().find("weapon") != std::string::npos) {
continue; continue;
}
for(auto& tri : body->triangles()) { for(auto& tri : body->triangles()) {
Triangle tri_translated(tri[0] + body->position().makePoint4D(), tri[1] + body->position().makePoint4D(), tri[2] + body->position().makePoint4D()); Triangle tri_translated(tri[0] + body->position().makePoint4D(), tri[1] + body->position().makePoint4D(), tri[2] + body->position().makePoint4D());
@ -53,33 +56,32 @@ IntersectionInformation World::rayCast(const Vec3D& from, const Vec3D& to, const
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 = std::make_unique<Vec3D>(intersection.first); point = intersection.first;
triangle = std::make_unique<Triangle>(tri_translated); triangle = tri_translated;
bodyName = name.str(); bodyName = name.str();
intersected = true; intersected = true;
intersectedBody = body; intersectedBody = body;
} }
} }
} }
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(unsigned i = 0; i < objs.size(); i++) { for(auto & i : objs) {
ObjectNameTag meshName = ObjectNameTag("map_" + to_string(i)); std::shared_ptr<RigidBody> obj = std::make_shared<RigidBody>(*i);
addBody(std::make_shared<RigidBody>(*objs[i]), meshName); addBody(obj);
body(meshName)->scale(scale); obj->scale(scale);
} }
auto it = _objects.begin();
} }
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) {
@ -88,7 +90,6 @@ void World::checkCollision(const ObjectNameTag& tag) {
_objects[tag]->setInCollision(false); _objects[tag]->setInCollision(false);
for (auto it = _objects.begin(); it != _objects.end();) { for (auto it = _objects.begin(); it != _objects.end();) {
auto obj = it->second; auto obj = it->second;
ObjectNameTag name = it->first; ObjectNameTag name = it->first;
it++; it++;
@ -100,8 +101,9 @@ void World::checkCollision(const ObjectNameTag& tag) {
CollisionPoint epa = _objects[tag]->EPA(gjk.second, obj); CollisionPoint epa = _objects[tag]->EPA(gjk.second, obj);
_objects[tag]->solveCollision(epa); _objects[tag]->solveCollision(epa);
} }
if (_objects[tag]->collisionCallBack() != nullptr) if (_objects[tag]->collisionCallBack() != nullptr) {
_objects[tag]->collisionCallBack()(name, obj); _objects[tag]->collisionCallBack()(name, obj);
}
} }
} }
} }
@ -116,7 +118,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;
} }

View File

@ -28,7 +28,7 @@ public:
void checkCollision(const ObjectNameTag& tag); void checkCollision(const ObjectNameTag& tag);
void update(); void update();
void addBody(std::shared_ptr<RigidBody> mesh, const ObjectNameTag& tag); void addBody(std::shared_ptr<RigidBody> mesh);
std::shared_ptr<RigidBody> body(const ObjectNameTag& tag); std::shared_ptr<RigidBody> body(const ObjectNameTag& tag);
void removeBody(const ObjectNameTag& tag); void removeBody(const ObjectNameTag& tag);
void loadBody(const ObjectNameTag& tag, const std::string &filename, const Vec3D& scale = Vec3D{1, 1, 1}); void loadBody(const ObjectNameTag& tag, const std::string &filename, const Vec3D& scale = Vec3D{1, 1, 1});

View File

@ -5,38 +5,38 @@
#ifndef ENGINE_ACOLOR_H #ifndef ENGINE_ACOLOR_H
#define ENGINE_ACOLOR_H #define ENGINE_ACOLOR_H
#include <utility>
#include "Animation.h" #include "Animation.h"
#include "../Mesh.h" #include "../Mesh.h"
class AColor final : public Animation { class AColor final : public Animation {
private: private:
std::shared_ptr<Mesh> _mesh; const std::weak_ptr<Mesh> _mesh;
sf::Color newColor; sf::Color _startColor;
sf::Color startColor; const sf::Color _newColor;
bool _started = false;
public: void update() override {
AColor(std::shared_ptr<Mesh> mesh, const sf::Color &color, double duration = 1, LoopOut looped = LoopOut::None, InterpolationType interpolationType = InterpolationType::linear) { if(_mesh.expired()) {
_mesh = mesh; stop();
_duration = duration; return;
_looped = looped; }
_intType = interpolationType;
_waitFor = true;
newColor = color; if(!_started) {
_started = true;
_startColor = _mesh.lock()->color();
}
Vec4D start(_startColor.r, _startColor.g, _startColor.b, _startColor.a);
Vec4D end(_newColor.r, _newColor.g, _newColor.b, _newColor.a);
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())));
} }
public:
bool update() override { 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) {
if(!_started)
startColor = _mesh->color();
Point4D start(startColor.r, startColor.g, startColor.b, startColor.a);
Point4D end(newColor.r, newColor.g, newColor.b, newColor.a);
Point4D mid = start + (end - start)*_p;
_mesh->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())));
return updateState();
} }
}; };

View File

@ -2,34 +2,27 @@
// Created by Иван Ильин on 06.04.2021. // Created by Иван Ильин on 06.04.2021.
// //
#include <utility>
#include "Animation.h"
#ifndef ENGINE_AFUNCTION_H #ifndef ENGINE_AFUNCTION_H
#define ENGINE_AFUNCTION_H #define ENGINE_AFUNCTION_H
#include <utility>
#include "Animation.h"
class AFunction final : public Animation { class AFunction final : public Animation {
private: private:
int _calls = 0; int _callsCounter = 0;
int _allCalls = 1; const int _allCalls = 1;
std::function<void()> _callBack; const std::function<void()> _callBack;
public: void update() override {
explicit AFunction(std::function<void()> function, int calls = 1, double duration = 1, LoopOut looped = LoopOut::None, InterpolationType interpolationType = InterpolationType::linear) { if(_allCalls != 0 && progress() >= (double)(_callsCounter + 1) / (_allCalls + 1)) {
_callBack = std::move(function); _callsCounter++;
_allCalls = calls;
_duration = duration;
_looped = looped;
_intType = interpolationType;
}
bool update() override {
if(_allCalls != 0 && _p >= (double)(_calls + 1) / (_allCalls + 1)) {
_calls++;
_callBack(); _callBack();
} }
return updateState(); }
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) {
} }
}; };

View File

@ -5,25 +5,26 @@
#ifndef ENGINE_AROTATE_H #ifndef ENGINE_AROTATE_H
#define ENGINE_AROTATE_H #define ENGINE_AROTATE_H
#include <utility>
#include "Animation.h" #include "Animation.h"
#include "../Object.h" #include "../Object.h"
class ARotate final : public Animation { class ARotate final : public Animation {
private: private:
std::shared_ptr<Object> _object; const std::weak_ptr<Object> _object;
const Vec3D _rotationValue;
Vec3D value; void update() override {
public: if(_object.expired()) {
ARotate(std::shared_ptr<Object> object, const Vec3D& r, double duration = 1, LoopOut looped = LoopOut::None, InterpolationType interpolationType = InterpolationType::bezier) : value(r) { stop();
_object = object; return;
_duration = duration; }
_looped = looped;
_intType = interpolationType; _object.lock()->rotate(_rotationValue * dprogress());
} }
public:
bool update() override { 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) {
_object->rotate(value * _dp);
return updateState();
} }
}; };

View File

@ -5,36 +5,32 @@
#ifndef ENGINE_ASCALE_H #ifndef ENGINE_ASCALE_H
#define ENGINE_ASCALE_H #define ENGINE_ASCALE_H
#include "Animatable.h" #include <utility>
#include "Animation.h" #include "Animation.h"
#include "Mesh.h" #include "../physics/RigidBody.h"
class AScale final : public Animation { class AScale final : public Animation {
private: private:
std::shared_ptr<Mesh> _mesh; const std::weak_ptr<RigidBody> _object;
const Vec3D _scalingValue;
Vec3D value; void update() override {
std::vector<Triangle> triangles{}; if(_object.expired()) {
public: stop();
AScale(std::shared_ptr<Mesh> mesh, const Vec3D &s, double duration = 1, LoopOut looped = LoopOut::None, InterpolationType interpolationType = InterpolationType::bezier) : value(s) { return;
_mesh = mesh; }
_duration = duration;
_looped = looped;
_intType = interpolationType;
_waitFor = true;
}
bool update() override {
if(!_started)
triangles = _mesh->triangles();
std::vector<Triangle> newTriangles; std::vector<Triangle> newTriangles;
for(auto &t : triangles) { for(auto &t : _object->triangles()) {
newTriangles.emplace_back(t * Matrix4x4::Scale(Point4D{1, 1, 1} + (value - Point4D{1, 1, 1}) * _p)); newTriangles.emplace_back(t * Matrix4x4::Scale(Vec3D{1, 1, 1} + (_scalingValue - Vec3D{1, 1, 1}) * progress()));
} }
_mesh->setTriangles(newTriangles); _object.lock()->setTriangles(newTriangles);
return updateState(); return updateState();
} }
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) {
}
}; };
#endif //INC_3DZAVR_ASCALE_H #endif //INC_3DZAVR_ASCALE_H

View File

@ -5,25 +5,26 @@
#ifndef ENGINE_ATRANSLATE_H #ifndef ENGINE_ATRANSLATE_H
#define ENGINE_ATRANSLATE_H #define ENGINE_ATRANSLATE_H
#include <utility>
#include "Animation.h" #include "Animation.h"
#include "../Object.h" #include "../Object.h"
class ATranslate final : public Animation { class ATranslate final : public Animation {
private: private:
std::shared_ptr<Object> _object; const std::weak_ptr<Object> _object;
const Vec3D _translationValue;
Vec3D value; void update() override {
public: if(_object.expired()) {
ATranslate(std::shared_ptr<Object> object, const Vec3D& t, double duration = 1, LoopOut looped = LoopOut::None, InterpolationType interpolationType = InterpolationType::bezier) : value(t){ stop();
_object = object; return;
_duration = duration; }
_looped = looped;
_intType = interpolationType; _object.lock()->translate(_translationValue * dprogress());
} }
public:
bool update() override { 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){
_object->translate(value * _dp);
return updateState();
} }
}; };

View File

@ -5,30 +5,33 @@
#ifndef ENGINE_ATRANSLATETOPOINT_H #ifndef ENGINE_ATRANSLATETOPOINT_H
#define ENGINE_ATRANSLATETOPOINT_H #define ENGINE_ATRANSLATETOPOINT_H
#include <utility>
#include "Animation.h" #include "Animation.h"
#include "../Object.h" #include "../Object.h"
class ATranslateToPoint final : public Animation { class ATranslateToPoint final : public Animation {
private: private:
std::shared_ptr<Object> _object; const std::weak_ptr<Object> _object;
const Vec3D _targetPoint;
Vec3D _translationValue;
Vec3D point; bool _started = false;
std::unique_ptr<Vec3D> value;
public:
ATranslateToPoint(std::shared_ptr<Object> object, const Vec3D& p, double duration = 1, LoopOut looped = LoopOut::None, InterpolationType interpolationType = InterpolationType::bezier) : point(p) {
_object = object;
_duration = duration;
_looped = looped;
_intType = interpolationType;
}
bool update() override { void update() override {
if(!_started) { if(_object.expired()) {
value = std::make_unique<Vec3D>(point - _object->position()); stop();
return;
} }
_object->translate(*value * _dp);
return updateState(); if(!_started) {
_started = true;
_translationValue = _targetPoint - _object.lock()->position();
}
_object.lock()->translate(_translationValue * dprogress());
}
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) {
} }
}; };

View File

@ -8,15 +8,10 @@
#include "Animation.h" #include "Animation.h"
class AWait final : public Animation { class AWait final : public Animation {
private:
void update() override{}
public: public:
explicit AWait(double duration = 1) { explicit AWait(double duration = 1) : Animation(duration, LoopOut::None, InterpolationType::Linear, true) {
_duration = duration;
_intType = InterpolationType::linear;
_waitFor = true;
}
bool update() override {
return updateState();
} }
}; };

View File

@ -4,37 +4,44 @@
#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) {
}
bool Animation::updateState() { bool Animation::updateState() {
if(!_started) { if(_finished || std::abs(_duration) < Consts::EPS) {
_started = true; return false;
return _duration != 0;
} }
// 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;
switch (_intType) {
case InterpolationType::bezier:
_p = Interpolation::Bezier(*_bezier[0], *_bezier[1], _time);
_dp = Interpolation::dBezier(*_bezier[0], *_bezier[1], _time, _dtime);
break;
case InterpolationType::bouncing:
_p = Interpolation::Bouncing(_time);
_dp = Interpolation::dBouncing(_time, _dtime);
break;
case InterpolationType::linear:
_p = Interpolation::Linear(_time);
_dp = Interpolation::dLinear(_time, _dtime);
break;
case InterpolationType::cos:
_p = Interpolation::Cos(_time);
_dp = Interpolation::dCos(_time, _dtime);
break;
} }
switch (_intType) {
case InterpolationType::Bezier:
_progress = Interpolation::Bezier(Consts::BEZIER[0], Consts::BEZIER[1], _time);
_dprogress = Interpolation::dBezier(Consts::BEZIER[0], Consts::BEZIER[1], _time, _dtime);
break;
case InterpolationType::Bouncing:
_progress = Interpolation::Bouncing(_time);
_dprogress = Interpolation::dBouncing(_time, _dtime);
break;
case InterpolationType::Linear:
_progress = Interpolation::Linear(_time);
_dprogress = Interpolation::dLinear(_time, _dtime);
break;
case InterpolationType::Cos:
_progress = Interpolation::Cos(_time);
_dprogress = Interpolation::dCos(_time, _dtime);
break;
default:
throw std::logic_error{"Animation::updateState: unknown interpolation type " + std::to_string(static_cast<int>(_intType))};
}
update();
return (_time < 1) || _looped == LoopOut::Cycle; return (_time < 1) || _looped == LoopOut::Cycle;
} }

View File

@ -13,48 +13,45 @@
class Animation { class Animation {
public: public:
enum class InterpolationType { enum class InterpolationType {
linear, Linear,
cos, Cos,
bezier, Bezier,
bouncing Bouncing
}; };
enum class LoopOut { enum class LoopOut {
None, None,
Cycle, Cycle,
Continue Continue
}; };
protected: private:
double _time = 0; // normalized time (from 0 to 1) // normalized time (from 0 to 1)
double _time = 0;
double _dtime = 0; double _dtime = 0;
double _duration = 0; bool _finished = false;
bool _started = false;
LoopOut _looped = LoopOut::None;
// _p - animation progress
double _p = 0;
double _dp = 0;
InterpolationType _intType = InterpolationType::bezier; double _progress = 0;
std::unique_ptr<Vec2D> _bezier[2] = {std::make_unique<Vec2D>(Vec2D{0.8, 0}), double _dprogress = 0;
std::make_unique<Vec2D>(Vec2D{0.2, 1})};
// If '_waitFor' == true then we need to finish all animation before starting this one. (for example for a_wait() or a_scale()) // If '_waitFor' == true then we need to finish all animation before starting this one. (for example for a_wait() or a_scale())
bool _waitFor = false; const bool _waitFor = false;
const double _duration = 0;
bool updateState(); const LoopOut _looped = LoopOut::None;
public: const InterpolationType _intType = InterpolationType::Bezier;
Animation() = default;
virtual ~Animation() = default;
void setBezierPoints(const Vec2D& p1, const Vec2D& p2) {
_bezier[0] = std::make_unique<Vec2D>(p1);
_bezier[1] = std::make_unique<Vec2D>(p2);
}
[[nodiscard]] bool waitFor() const { return _waitFor; }
// You should override this method for your particular animation // You should override this method for your particular animation
virtual bool update() = 0; virtual void update() = 0;
public:
Animation(double duration, LoopOut looped, InterpolationType intType, bool _waitFor = false);
virtual ~Animation() = default;
[[nodiscard]] bool waitFor() const { return _waitFor; }
bool updateState();
[[nodiscard]] double progress() const { return _progress; }
[[nodiscard]] double dprogress() const { return _dprogress; }
void stop() { _finished = true;}
}; };
#endif //INC_3DZAVR_ANIMATION_H #endif //INC_3DZAVR_ANIMATION_H

View File

@ -22,8 +22,6 @@ namespace Interpolation {
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;

View File

@ -13,63 +13,72 @@ void Timeline::init() {
} }
void Timeline::animate(const AnimationListTag& listName, Animation* anim) { void Timeline::animate(const AnimationListTag& listName, Animation* anim) {
if(!_instance) if(!_instance) {
return; return;
}
_instance->_animations[listName].emplace_back(anim); _instance->_animations[listName].emplace_back(anim);
} }
void Timeline::deleteAllAnimations() { void Timeline::deleteAllAnimations() {
if(!_instance) if(!_instance) {
return; return;
}
for (auto& [listName, animationList] : _instance->_animations) { for (auto& [listName, animationList] : _instance->_animations) {
auto it = animationList.begin(); auto it = animationList.begin();
while(it != animationList.end()) while(it != animationList.end()) {
delete *(it++); delete *(it++);
}
animationList.clear(); animationList.clear();
} }
_instance->_animations.clear(); _instance->_animations.clear();
} }
void Timeline::deleteAnimationList(const AnimationListTag& listName) { void Timeline::deleteAnimationList(const AnimationListTag& listName) {
if(!_instance) if(!_instance) {
return; return;
}
_instance->_animations[listName].clear(); _instance->_animations[listName].clear();
_instance->_animations.erase(listName); _instance->_animations.erase(listName);
} }
[[nodiscard]] bool Timeline::isInAnimList(const AnimationListTag& listName) { [[nodiscard]] bool Timeline::isInAnimList(const AnimationListTag& listName) {
if(!_instance) if(!_instance) {
return false; return false;
}
return !_instance->_animations[listName].empty(); return !_instance->_animations[listName].empty();
} }
void Timeline::update() { void Timeline::update() {
if(!_instance) if(!_instance) {
return; return;
}
for (auto& [listName, animationList] : _instance->_animations) { for (auto& [listName, animationList] : _instance->_animations) {
if (animationList.empty()) if (animationList.empty()) {
continue; continue;
}
auto it = animationList.begin(); auto it = animationList.begin();
// If it the front animation is 'a_wait()' we should wait until waiting time is over // If it the front animation is 'a_wait()' we should wait until waiting time is over
if (it.operator*()->waitFor()) { if (it.operator*()->waitFor()) {
if (!it.operator*()->update()) if (!it.operator*()->updateState()) {
animationList.erase(it); animationList.erase(it);
}
continue; continue;
} }
// Otherwise we iterate over all animation until we meet animations.end() or wait animation // Otherwise we iterate over all animation until we meet animations.end() or wait animation
while (!animationList.empty() && (it != animationList.end()) && (!it.operator*()->waitFor())) { while (!animationList.empty() && (it != animationList.end()) && (!it.operator*()->waitFor())) {
if (!it.operator*()->update()) if (!it.operator*()->updateState()) {
animationList.erase(it++); animationList.erase(it++);
else } else {
it++; it++;
}
} }
} }
} }

View File

@ -9,8 +9,7 @@
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;
} }
@ -18,8 +17,7 @@ void Button::select()
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;
} }
@ -27,19 +25,17 @@ void Button::unSelect()
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;
//_clickSound.play(); }
_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;
}
} }
} }
@ -54,9 +50,6 @@ void Button::init() {
_text.setCharacterSize((unsigned int)(_h * _sy / 2)); _text.setCharacterSize((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((float)(_x - _text.getLocalBounds().width / 2), (float)(_y - _h * _sy / 2 + _text.getLocalBounds().height / 4));
//_clickSound.setBuffer(*ResourceManager::loadSoundBuffer(_clickSoundName));
//_clickSound.setVolume(15);
} }
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,

View File

@ -16,26 +16,26 @@ struct tPos final {
class Button final { class Button final {
private: private:
int _x{}; const int _x{};
int _y{}; const int _y{};
int _w{}; const int _w{};
int _h{}; const int _h{};
std::function<void()> _click; const std::function<void()> _click;
std::string _textString; const std::string _textString;
double _sx{}; const double _sx{};
double _sy{}; const double _sy{};
std::string _texture; const std::string _texture;
tPos _usualState{}; const tPos _usualState{};
tPos _selectedState{}; const tPos _selectedState{};
tPos _pressedState{}; const tPos _pressedState{};
std::string _font; const std::string _font;
sf::Color _textColor; const sf::Color _textColor;
sf::Sprite _button; sf::Sprite _button;
sf::Text _text; sf::Text _text;

View File

@ -10,7 +10,7 @@
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.push_back(Button{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();
} }
@ -20,7 +20,7 @@ void Window::update() {
_screen->drawSprite(_back); _screen->drawSprite(_back);
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((float)(dMousePos.x() / 30), (float)(dMousePos.y() / 30)));
bool isPressed = _mouse->isButtonTapped(sf::Mouse::Left); bool isPressed = _mouse->isButtonTapped(sf::Mouse::Left);
@ -40,7 +40,7 @@ void Window::update() {
} }
} }
_prevMousePosition = std::make_unique<Vec2D>(mousePos); _prevMousePosition = mousePos;
} }
void Window::setBackgroundTexture(const std::string &texture, double sx, double sy, int w, int h) { void Window::setBackgroundTexture(const std::string &texture, double sx, double sy, int w, int h) {

View File

@ -20,12 +20,12 @@ private:
sf::Sprite _back; sf::Sprite _back;
std::unique_ptr<Vec2D> _prevMousePosition = std::make_unique<Vec2D>(Vec2D{0, 0}); Vec2D _prevMousePosition{0, 0};
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(screen), _mouse(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,
@ -33,8 +33,7 @@ public:
const std::string& texture = "", tPos usualState = {}, tPos selectedState = {}, tPos pressedState = {}, const std::string& texture = "", tPos usualState = {}, tPos selectedState = {}, tPos pressedState = {},
const std::string& font = Consts::MEDIUM_FONT, sf::Color textColor = {255, 255, 255}); const std::string& font = Consts::MEDIUM_FONT, sf::Color textColor = {255, 255, 255});
[[nodiscard]] std::string title() const { return _name; } void setTitle(const std::string& title) { _name = title; }
void title(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);

View File

@ -93,8 +93,7 @@ bool ClientUDP::process()
if (!connected() && type != MsgType::Init) if (!connected() && type != MsgType::Init)
return true; return true;
switch (type) switch (type) {
{
// here we process any operations based on msg type // here we process any operations based on msg type
case MsgType::Init: case MsgType::Init:
packet >> targetId; packet >> targetId;
@ -104,7 +103,7 @@ bool ClientUDP::process()
processInit(packet); processInit(packet);
break; break;
case MsgType::Update: case MsgType::ServerUpdate:
processUpdate(packet); processUpdate(packet);
break; break;
@ -123,8 +122,14 @@ bool ClientUDP::process()
processDisconnect(targetId); processDisconnect(targetId);
break; break;
case MsgType::Custom:
processCustomPacket(packet);
break;
case MsgType::Error:
Log::log("ClientUDP::process(): Error message");
break;
default: default:
processCustomPacket(type, packet); Log::log("ClientUDP::process(): unknown message type " + std::to_string(static_cast<int>(type)));
} }
return true; return true;

View File

@ -31,8 +31,8 @@ public:
void disconnect(); void disconnect();
void update(); void update();
[[nodiscard]] sf::IpAddress ip() const { return _ip; } [[nodiscard]] sf::IpAddress serverIp() const { return _ip; }
[[nodiscard]] sf::Uint16 port() const { return _port; } [[nodiscard]] sf::Uint16 serverPort() const { return _port; }
// virtual functions // virtual functions
virtual void updatePacket(){}; virtual void updatePacket(){};
@ -42,7 +42,7 @@ public:
virtual void processNewClient(sf::Packet& packet){}; virtual void processNewClient(sf::Packet& packet){};
virtual void processDisconnect(sf::Uint16 targetId){}; virtual void processDisconnect(sf::Uint16 targetId){};
virtual void processCustomPacket(MsgType type, sf::Packet& packet){}; virtual void processCustomPacket(sf::Packet& packet){};
virtual void processDisconnected(){}; virtual void processDisconnected(){};

View File

@ -18,18 +18,12 @@ enum class MsgType
Connect, // connection (client ---> server) Connect, // connection (client ---> server)
Disconnect, // disconnect (client <==> server) Disconnect, // disconnect (client <==> server)
Init, // initialization (client <--- server) Init, // initialization (client <--- server)
Update, // update (client <--- server) ServerUpdate, // update (client <--- server)
ClientUpdate, // update (client ---> server) ClientUpdate, // update (client ---> server)
NewClient, // add new client (client <--- server) NewClient, // add new client (client <--- server)
// custom // this is for higher level clients & servers
Damage, Custom,
Kill,
FireTrace,
InitBonuses,
AddBonus,
RemoveBonus,
ChangeWeapon,
}; };
sf::Packet& operator<<(sf::Packet& packet, MsgType type); sf::Packet& operator<<(sf::Packet& packet, MsgType type);

View File

@ -12,10 +12,10 @@ ReliableMsg::ReliableMsg(const ReliableMsg& msg) : packet(msg.packet), address(m
bool ReliableMsg::trySend(sf::UdpSocket& socket) bool ReliableMsg::trySend(sf::UdpSocket& socket)
{ {
if (Time::time() - firstTry > Consts::NETWORK_TIMEOUT) if (Time::time() - firstTry > Consts::NETWORK_TIMEOUT) {
return false; return false;
if (Time::time() - lastTry > Consts::NETWORK_RELIABLE_RETRY_TIME) }
{ if (Time::time() - lastTry > Consts::NETWORK_RELIABLE_RETRY_TIME) {
lastTry = Time::time(); lastTry = Time::time();
socket.send(packet, address, port); socket.send(packet, address, port);
} }

View File

@ -7,14 +7,13 @@
#include <SFML/Network.hpp> #include <SFML/Network.hpp>
class ReliableMsg final class ReliableMsg final {
{
private: private:
sf::Packet packet; sf::Packet packet;
sf::IpAddress address; const sf::IpAddress address;
sf::Uint16 port; const sf::Uint16 port;
const double firstTry;
double lastTry; double lastTry;
double firstTry;
public: public:
ReliableMsg(sf::Packet& packet, sf::IpAddress address, sf::Uint16 port); ReliableMsg(sf::Packet& packet, sf::IpAddress address, sf::Uint16 port);

View File

@ -7,32 +7,31 @@
#include "../utils/Log.h" #include "../utils/Log.h"
#include <cmath> #include <cmath>
ServerUDP::ServerUDP() : _lastBroadcast(-std::numeric_limits<double>::max()), _working(false) ServerUDP::ServerUDP() : _lastBroadcast(-std::numeric_limits<double>::max()), _working(false) {
{ // TODO: replace this with lambda:
_socket.setTimeoutCallback(std::bind(&ServerUDP::timeout, this, std::placeholders::_1)); _socket.setTimeoutCallback(std::bind(&ServerUDP::timeout, this, std::placeholders::_1));
} }
bool ServerUDP::isWorking() const bool ServerUDP::isWorking() const {
{
return _working; return _working;
} }
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.");
}
return _working; return _working;
} }
void ServerUDP::update() void ServerUDP::update() {
{ if (!isWorking()) {
if (!isWorking())
return; return;
}
while (process()); while (process());
@ -48,10 +47,8 @@ void ServerUDP::update()
updateInfo(); updateInfo();
} }
void ServerUDP::stop() void ServerUDP::stop() {
{ for (auto it = _clients.begin(); it != _clients.end();) {
for (auto it = _clients.begin(); it != _clients.end();)
{
sf::Packet packet; sf::Packet packet;
packet << MsgType::Disconnect << *it; packet << MsgType::Disconnect << *it;
_socket.send(packet, *it); _socket.send(packet, *it);
@ -66,15 +63,15 @@ void ServerUDP::stop()
Log::log("ServerUDP::stop(): the server was killed."); Log::log("ServerUDP::stop(): the server was killed.");
} }
bool ServerUDP::timeout(sf::Uint16 playerId) bool ServerUDP::timeout(sf::Uint16 playerId) {
{
sf::Packet packet; sf::Packet packet;
packet << MsgType::Disconnect << playerId; packet << MsgType::Disconnect << playerId;
_clients.erase(playerId); _clients.erase(playerId);
for (auto client : _clients) for (auto client : _clients) {
_socket.sendRely(packet, client); _socket.sendRely(packet, client);
}
Log::log("ServerUDP::timeout(): client Id = " + std::to_string(playerId) + " disconnected due to timeout."); Log::log("ServerUDP::timeout(): client Id = " + std::to_string(playerId) + " disconnected due to timeout.");
processDisconnect(playerId); processDisconnect(playerId);
@ -84,21 +81,20 @@ bool ServerUDP::timeout(sf::Uint16 playerId)
// Recive and process message. // Recive and process message.
// Returns true, if some message was received. // Returns true, if some message was received.
bool ServerUDP::process() bool ServerUDP::process() {
{
sf::Packet packet; sf::Packet packet;
sf::Packet sendPacket; sf::Packet sendPacket;
sf::Uint16 senderId; sf::Uint16 senderId;
MsgType type = _socket.receive(packet, senderId); MsgType type = _socket.receive(packet, senderId);
if (type == MsgType::Empty) if (type == MsgType::Empty) {
return false; return false;
}
switch (type) { switch (type) {
// here we process any operations based on msg type // here we process any operations based on msg type
case MsgType::Connect: case MsgType::Connect:
Log::log("ServerUDP::process(): client Id = " + std::to_string(senderId) + " connecting..."); Log::log("ServerUDP::process(): client Id = " + std::to_string(senderId) + " connecting...");
processConnect(senderId); processConnect(senderId);
@ -113,13 +109,20 @@ bool ServerUDP::process()
sendPacket << MsgType::Disconnect << senderId; sendPacket << MsgType::Disconnect << senderId;
_clients.erase(senderId); _clients.erase(senderId);
_socket.removeConnection(senderId); _socket.removeConnection(senderId);
for (auto client : _clients) for (auto client : _clients) {
_socket.sendRely(sendPacket, client); _socket.sendRely(sendPacket, client);
}
processDisconnect(senderId); processDisconnect(senderId);
break; break;
case MsgType::Custom:
processCustomPacket(packet, senderId);
break;
case MsgType::Error:
Log::log("ServerUDP::process(): Error message");
break;
default: default:
processCustomPacket(type, packet, senderId); Log::log("ServerUDP::process(): message type " + std::to_string(static_cast<int>(type)));
} }
return true; return true;

View File

@ -40,7 +40,7 @@ public:
virtual void processClientUpdate(sf::Uint16 senderId, sf::Packet& packet){}; virtual void processClientUpdate(sf::Uint16 senderId, sf::Packet& packet){};
virtual void processDisconnect(sf::Uint16 senderId){}; virtual void processDisconnect(sf::Uint16 senderId){};
virtual void processCustomPacket(MsgType type, sf::Packet& packet, sf::Uint16 senderId){}; virtual void processCustomPacket(sf::Packet& packet, sf::Uint16 senderId){};
virtual void processStop(){}; virtual void processStop(){};

View File

@ -8,37 +8,30 @@
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;
} }
sf::Uint16 UDPConnection::port() const sf::Uint16 UDPConnection::port() const {
{
return _port; return _port;
} }
bool UDPConnection::timeout() const 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;
} }
void UDPConnection::update() 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);
} }

View File

@ -9,9 +9,9 @@
class UDPConnection final { class UDPConnection final {
private: private:
sf::Uint16 _id; const sf::Uint16 _id;
sf::IpAddress _ip; const sf::IpAddress _ip;
sf::Uint16 _port; const sf::Uint16 _port;
double lastMsg; double lastMsg;
public: public:

View File

@ -7,28 +7,23 @@
#include <algorithm> #include <algorithm>
#include "../Consts.h" #include "../Consts.h"
UDPSocket::UDPSocket() : _ownId(0), _nextRelyMsgId(0) UDPSocket::UDPSocket() : _ownId(0), _nextRelyMsgId(0) {
{
_socket.setBlocking(false); _socket.setBlocking(false);
} }
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) {
{
_connections.erase(id); _connections.erase(id);
} }
bool UDPSocket::bind(sf::Uint16 port) bool UDPSocket::bind(sf::Uint16 port) {
{
return _socket.bind(port) == sf::Socket::Status::Done; return _socket.bind(port) == sf::Socket::Status::Done;
} }
void UDPSocket::unbind() void UDPSocket::unbind() {
{
sf::Packet packet; sf::Packet packet;
packet << MsgType::Disconnect << _ownId; packet << MsgType::Disconnect << _ownId;
@ -44,143 +39,133 @@ void UDPSocket::unbind()
setId(0); setId(0);
} }
void UDPSocket::setTimeoutCallback(std::function<bool(sf::Uint16)> callback) void UDPSocket::setTimeoutCallback(std::function<bool(sf::Uint16)> callback) {
{
_timeoutCallback = std::move(callback); _timeoutCallback = std::move(callback);
} }
void UDPSocket::clearTimeoutCallback() void UDPSocket::setId(sf::Uint16 id) {
{
_timeoutCallback = nullptr;
}
void UDPSocket::setId(sf::Uint16 id)
{
_ownId = id; _ownId = id;
} }
sf::Uint16 UDPSocket::ownId() const sf::Uint16 UDPSocket::ownId() const {
{
return _ownId; return _ownId;
} }
sf::Uint16 UDPSocket::serverId() const 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;
}
this->send(packet, _connections.at(id).ip(), _connections.at(id).port()); this->send(packet, _connections.at(id).ip(), _connections.at(id).port());
} }
void UDPSocket::update() void UDPSocket::update() {
{ for (auto it = _connections.begin(); it != _connections.end();) {
for (auto it = _connections.begin(); it != _connections.end();) if (!it->second.timeout()) {
{
if (!it->second.timeout())
++it; ++it;
else } else {
{ if (_timeoutCallback && !_timeoutCallback(it->first)) {
if (_timeoutCallback && !_timeoutCallback(it->first))
return; return;
}
_connections.erase(it++); _connections.erase(it++);
} }
} }
for (auto it = _relyPackets.begin(); it != _relyPackets.end();) for (auto it = _relyPackets.begin(); it != _relyPackets.end();) {
{ if (!it->second.trySend(_socket)) {
if (!it->second.trySend(_socket))
_relyPackets.erase(it++); _relyPackets.erase(it++);
else } else {
++it; ++it;
}
} }
for (auto it = _confirmTimes.begin(); it != _confirmTimes.end();) for (auto it = _confirmTimes.begin(); it != _confirmTimes.end();) {
{ if (Time::time() - it->second > Consts::NETWORK_TIMEOUT) {
if (Time::time() - it->second > Consts::NETWORK_TIMEOUT)
_confirmTimes.erase(it++); _confirmTimes.erase(it++);
else } else {
++it; ++it;
}
} }
} }
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;
packet.clear(); packet.clear();
if (_socket.receive(packet, ip, port) != sf::Socket::Status::Done) if (_socket.receive(packet, ip, port) != sf::Socket::Status::Done) {
return MsgType::Empty; return MsgType::Empty;
}
// Read header // Read header
bool reply = false; bool reply = false;
sf::Uint16 msgId = 0; sf::Uint16 msgId = 0;
MsgType type; MsgType type;
senderId = 0; senderId = 0;
if (!(packet >> senderId >> reply >> msgId >> type)) if (!(packet >> senderId >> reply >> msgId >> type)) {
return MsgType::Error; return MsgType::Error;
if (_connections.count(senderId))
_connections.at(senderId).update();
if (type == MsgType::Confirm)
{
_relyPackets.erase(msgId);
return MsgType::Confirm;
} }
if (type == MsgType::Connect) if (_connections.count(senderId)) {
{ _connections.at(senderId).update();
}
if (type == MsgType::Confirm) {
_relyPackets.erase(msgId);
// you don't need this information on the highest levels
return MsgType::Empty;
}
if (type == MsgType::Connect) {
sf::Uint32 version = 0; sf::Uint32 version = 0;
if (!(packet >> version) || version != Consts::NETWORK_VERSION) if (!(packet >> version) || version != Consts::NETWORK_VERSION) {
return MsgType::Error; return MsgType::Error;
}
sf::Uint16 tmp; sf::Uint16 tmp;
for (tmp = Consts::NETWORK_MAX_CLIENTS; tmp >= 1; tmp--) for (tmp = Consts::NETWORK_MAX_CLIENTS; tmp >= 1; tmp--) {
{ if (!_connections.count(tmp)) {
if (!_connections.count(tmp))
senderId = tmp; senderId = tmp;
else } else {
if (_connections.at(tmp).same(ip, port)) if (_connections.at(tmp).same(ip, port)) {
return MsgType::Error; return MsgType::Error;
}
}
} }
_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;
} }
bool UDPSocket::confirmed(sf::Uint16 msgId, sf::Uint16 senderId) bool UDPSocket::confirmed(sf::Uint16 msgId, sf::Uint16 senderId) {
{
sf::Packet confirmPacket; sf::Packet confirmPacket;
confirmPacket << _ownId << false << msgId << MsgType::Confirm; confirmPacket << _ownId << false << msgId << MsgType::Confirm;
_connections.at(senderId).send(_socket, confirmPacket); _connections.at(senderId).send(_socket, confirmPacket);

View File

@ -31,7 +31,6 @@ public:
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 clearTimeoutCallback();
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);

View File

@ -8,9 +8,14 @@
#include <iostream> #include <iostream>
#include <cmath> #include <cmath>
#include <fstream> #include <fstream>
#include <utility>
#include "../Consts.h"
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) {
std::shared_ptr<Vec3D> maxPoint = std::make_shared<Vec3D>(Vec3D{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()){
@ -20,12 +25,12 @@ Vec3D RigidBody::_findFurthestPoint(const Vec3D& direction) {
double distance = point.dot(direction.normalized()); double distance = point.dot(direction.normalized());
if(distance > maxDistance) { if(distance > maxDistance) {
maxDistance = distance; maxDistance = distance;
maxPoint = std::make_shared<Vec3D>(point); maxPoint = point;
} }
} }
} }
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) {
@ -47,8 +52,8 @@ NextSimplex RigidBody::_nextSimplex(const Simplex &points) {
} }
NextSimplex RigidBody::_lineCase(const Simplex& points) { NextSimplex RigidBody::_lineCase(const Simplex& points) {
std::shared_ptr<Simplex> newPoints = std::make_shared<Simplex>(points); Simplex newPoints(points);
std::shared_ptr<Vec3D> newDirection; Vec3D newDirection;
Vec3D a = points[0]; Vec3D a = points[0];
Vec3D b = points[1]; Vec3D b = points[1];
@ -57,18 +62,18 @@ NextSimplex RigidBody::_lineCase(const Simplex& points) {
Vec3D ao = - a; Vec3D ao = - a;
if (ab.dot(ao) > 0) { if (ab.dot(ao) > 0) {
newDirection = std::make_shared<Vec3D>(ab.cross(ao).cross(ab)); newDirection = ab.cross(ao).cross(ab);
} else { } else {
newPoints = std::make_shared<Simplex>(Simplex{a}); newPoints = Simplex{a};
newDirection = std::make_shared<Vec3D>(ao); newDirection = ao;
} }
return NextSimplex{*newPoints, *newDirection, false}; return NextSimplex{newPoints, newDirection, false};
} }
NextSimplex RigidBody::_triangleCase(const Simplex &points) { NextSimplex RigidBody::_triangleCase(const Simplex &points) {
std::shared_ptr<Simplex> newPoints = std::make_shared<Simplex>(points); Simplex newPoints(points);
std::shared_ptr<Vec3D> newDirection; Vec3D newDirection;
Vec3D a = points[0]; Vec3D a = points[0];
Vec3D b = points[1]; Vec3D b = points[1];
@ -82,8 +87,8 @@ NextSimplex RigidBody::_triangleCase(const Simplex &points) {
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 = std::make_shared<Simplex>(Simplex{ a, c }); newPoints = Simplex{ a, c };
newDirection = std::make_shared<Vec3D>(ac.cross(ao).cross(ac)); newDirection = ac.cross(ao).cross(ac);
} }
else { else {
return _lineCase(Simplex { a, b }); return _lineCase(Simplex { a, b });
@ -94,15 +99,15 @@ NextSimplex RigidBody::_triangleCase(const Simplex &points) {
} }
else { else {
if (abc.dot(ao) > 0) { if (abc.dot(ao) > 0) {
newDirection = std::make_shared<Vec3D>(abc); newDirection = abc;
} else { } else {
newPoints = std::make_shared<Simplex>(Simplex{ a, c, b }); newPoints = Simplex{ a, c, b };
newDirection = std::make_shared<Vec3D>(-abc); newDirection = -abc;
} }
} }
} }
return NextSimplex{*newPoints, *newDirection, false}; return NextSimplex{newPoints, newDirection, false};
} }
NextSimplex RigidBody::_tetrahedronCase(const Simplex &points) { NextSimplex RigidBody::_tetrahedronCase(const Simplex &points) {
@ -145,34 +150,38 @@ std::pair<bool, Simplex> RigidBody::checkGJKCollision(std::shared_ptr<RigidBody>
// Get initial support point in any direction // Get initial support point in any direction
std::shared_ptr<Vec3D> support = std::make_shared<Vec3D>(_support(obj, Vec3D{1, 0, 0})); Vec3D support = _support(obj, Vec3D{1, 0, 0});
// Simplex is an array of points, max count is 4 // Simplex is an array of points, max count is 4
std::shared_ptr<Simplex> points = std::make_shared<Simplex>(); Simplex points{};
points->push_front(*support); points.push_front(support);
// New direction is towards the origin // New direction is towards the origin
std::shared_ptr<Vec3D> direction = std::make_shared<Vec3D>(-*support); Vec3D direction = -support;
while (true) { int iters = 0;
support = std::make_shared<Vec3D>(_support(obj, *direction)); while (iters++ < size() + obj->size()) {
support = _support(obj, direction);
if (support->dot(*direction) <= 0) if (support.dot(direction) <= 0) {
return std::make_pair(false, *points); // no collision return std::make_pair(false, points); // no collision
}
points->push_front(*support); points.push_front(support);
NextSimplex nextSimplex = _nextSimplex(*points); NextSimplex nextSimplex = _nextSimplex(points);
direction = std::make_shared<Vec3D>(nextSimplex.newDirection); direction = nextSimplex.newDirection;
points = std::make_shared<Simplex>(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);
} }
} }
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) {
@ -192,28 +201,27 @@ CollisionPoint RigidBody::EPA(const Simplex& simplex, std::shared_ptr<RigidBody>
}; };
auto faceNormals = _getFaceNormals(polytope, faces); auto faceNormals = _getFaceNormals(polytope, faces);
std::vector<std::shared_ptr<FaceNormal>> normals = faceNormals.first; std::vector<FaceNormal> normals = faceNormals.first;
size_t minFace = faceNormals.second; size_t minFace = faceNormals.second;
std::shared_ptr<Vec3D> minNormal = std::make_shared<Vec3D>(normals[minFace]->normal); Vec3D minNormal = normals[minFace].normal;
double minDistance = std::numeric_limits<double>::max(); double minDistance = std::numeric_limits<double>::max();
int iters = 0; int iters = 0;
while (minDistance == std::numeric_limits<double>::max() && iters++ < size() + obj->size()) { while (minDistance == std::numeric_limits<double>::max() && iters++ < size() + obj->size()) {
minNormal = std::make_shared<Vec3D>(normals[minFace]->normal); minNormal = normals[minFace].normal;
minDistance = normals[minFace]->distance; minDistance = normals[minFace].distance;
Vec3D support = _support(obj, *minNormal); Vec3D support = _support(obj, minNormal);
double sDistance = minNormal->dot(support); double sDistance = minNormal.dot(support);
if (std::abs(sDistance - minDistance) > Consts::EPA_EPS) { if (std::abs(sDistance - minDistance) > Consts::EPA_EPS) {
minDistance = std::numeric_limits<double>::max(); minDistance = std::numeric_limits<double>::max();
std::vector<std::pair<size_t, size_t>> uniqueEdges; std::vector<std::pair<size_t, size_t>> uniqueEdges;
for (size_t i = 0; i < normals.size(); i++) { size_t f = 0;
if (normals[i]->normal.dot(support) > 0) { for (auto & normal : normals) {
size_t f = i * 3; 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);
uniqueEdges = _addIfUniqueEdge(uniqueEdges, faces, f + 2, f + 0); uniqueEdges = _addIfUniqueEdge(uniqueEdges, faces, f + 2, f + 0);
@ -221,7 +229,8 @@ CollisionPoint RigidBody::EPA(const Simplex& simplex, std::shared_ptr<RigidBody>
faces.erase(faces.begin() + f); faces.erase(faces.begin() + f);
faces.erase(faces.begin() + f); faces.erase(faces.begin() + f);
faces.erase(faces.begin() + f); faces.erase(faces.begin() + f);
normals.erase(normals.begin() + i--); } else {
f += 3;
} }
} }
@ -237,20 +246,21 @@ CollisionPoint RigidBody::EPA(const Simplex& simplex, std::shared_ptr<RigidBody>
auto newFaceNormals = _getFaceNormals(polytope, faces); auto newFaceNormals = _getFaceNormals(polytope, faces);
normals = newFaceNormals.first; normals = std::move(newFaceNormals.first);
minFace = newFaceNormals.second; minFace = newFaceNormals.second;
} }
} }
_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<std::shared_ptr<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<std::shared_ptr<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();
@ -259,16 +269,16 @@ std::pair<std::vector<std::shared_ptr<FaceNormal>>, size_t> RigidBody::_getFaceN
Vec3D b = polytope[faces[i + 1]]; Vec3D b = polytope[faces[i + 1]];
Vec3D c = polytope[faces[i + 2]]; Vec3D c = polytope[faces[i + 2]];
std::shared_ptr<Vec3D> normal = std::make_shared<Vec3D>((b - a).cross(c - a).normalized()); Vec3D normal = (b - a).cross(c - a).normalized();
double distance = normal->dot(a); double distance = normal.dot(a);
if (distance < -Consts::EPS) { if (distance < -Consts::EPS) {
normal = std::make_unique<Vec3D>(-*normal); normal = -normal;
distance *= -1; distance *= -1;
} }
normals.emplace_back(std::make_shared<FaceNormal>(FaceNormal{*normal, distance})); normals.emplace_back(FaceNormal{normal, distance});
if (distance < minDistance) { if (distance < minDistance) {
nearestFaceIndex = i / 3; nearestFaceIndex = i / 3;
@ -304,41 +314,29 @@ 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);
}
translate(-collision.normal * collision.depth); translate(-collision.normal * collision.depth);
} }
void RigidBody::updatePhysicsState() { void RigidBody::updatePhysicsState() {
translate(*_velocity * Time::deltaTime()); translate(_velocity * Time::deltaTime());
_velocity = std::make_unique<Vec3D>(*_velocity + *_acceleration * Time::deltaTime()); _velocity = _velocity + _acceleration * Time::deltaTime();
} }
void RigidBody::setVelocity(const Vec3D& velocity) { void RigidBody::setVelocity(const Vec3D& velocity) {
_velocity = std::make_unique<Vec3D>(velocity); _velocity = velocity;
} }
void RigidBody::addVelocity(const Vec3D &velocity) { void RigidBody::addVelocity(const Vec3D &velocity) {
_velocity = std::make_unique<Vec3D>(*_velocity + velocity); _velocity = _velocity + velocity;
} }
void RigidBody::setAcceleration(const Vec3D& acceleration) { void RigidBody::setAcceleration(const Vec3D& acceleration) {
_acceleration = std::make_unique<Vec3D>(acceleration); _acceleration = acceleration;
} }
RigidBody::RigidBody(const Mesh &mesh) : Mesh(mesh) { RigidBody::RigidBody(const Mesh &mesh) : Mesh(mesh) {
}
void RigidBody::makeLogObjPolytope(const std::vector<Vec3D> &polytope, const std::vector<size_t> &faces) {
std::fstream file("polytope_log.obj", std::ios::out);
for(auto &p : polytope)
file << "v " << p.x() << " " << p.y() << " " << p.z() << std::endl;
for(size_t i = 0; i < faces.size(); i += 3)
file << "f " << faces[i + 0]+1 << " " << faces[i + 1]+1 << " " << faces[i + 2]+1 << std::endl;
file.close();
} }

View File

@ -5,6 +5,7 @@
#ifndef ENGINE_RIGIDBODY_H #ifndef ENGINE_RIGIDBODY_H
#define ENGINE_RIGIDBODY_H #define ENGINE_RIGIDBODY_H
#include <utility>
#include <vector> #include <vector>
#include <memory> #include <memory>
#include <functional> #include <functional>
@ -40,29 +41,29 @@ private:
static NextSimplex _triangleCase(const Simplex& points); static NextSimplex _triangleCase(const Simplex& points);
static NextSimplex _tetrahedronCase(const Simplex& points); static NextSimplex _tetrahedronCase(const Simplex& points);
static std::pair<std::vector<std::shared_ptr<FaceNormal>>, size_t> _getFaceNormals(const std::vector<Vec3D>& polytope, const std::vector<size_t>& faces); 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); 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 void makeLogObjPolytope(const std::vector<Vec3D>& polytope, const std::vector<size_t>& faces);
protected: protected:
std::unique_ptr<Vec3D> _velocity = std::make_unique<Vec3D>(Vec3D{0, 0, 0});; Vec3D _velocity{0, 0, 0};
std::unique_ptr<Vec3D> _acceleration = std::make_unique<Vec3D>(Vec3D{0, 0, 0});; Vec3D _acceleration{0, 0, 0};
bool _collision = false; bool _collision = false;
bool _isCollider = true; bool _isCollider = true;
bool _inCollision = false; bool _inCollision = false;
std::shared_ptr<Vec3D> _collisionNormal = std::make_unique<Vec3D>(Vec3D{0, 0, 0});; Vec3D _collisionNormal{0, 0, 0};
public: public:
RigidBody() = default; explicit RigidBody(ObjectNameTag nameTag) : Mesh(std::move(nameTag)) {};
explicit RigidBody(const Mesh& mesh); 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); [[nodiscard]] CollisionPoint EPA(const Simplex& simplex, std::shared_ptr<RigidBody> obj);
void solveCollision(const CollisionPoint& collision); 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 inCollision() const {return _inCollision; }
@ -77,8 +78,8 @@ public:
void addVelocity(const Vec3D& velocity); void addVelocity(const Vec3D& velocity);
void setAcceleration(const Vec3D& acceleration); 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>)>& collisionCallBack() const { return _collisionCallBack; }
void setCollisionCallBack(const std::function<void(const ObjectNameTag& tag, std::shared_ptr<RigidBody>)>& f) { _collisionCallBack = f; } void setCollisionCallBack(const std::function<void(const ObjectNameTag& tag, std::shared_ptr<RigidBody>)>& f) { _collisionCallBack = f; }

View File

@ -8,11 +8,5 @@
using namespace std; using namespace std;
Ak47::Ak47(int ammo, const std::string& weaponName) : Weapon(weaponName, ShooterConsts::AK47_OBJ, Vec3D{3, 3, 3}, Vec3D{-2.2, 1.0, 1.3}, Vec3D{0, Consts::PI, 0}) { Ak47::Ak47(const std::string& weaponName) : Weapon(100, 30, 3.0, 0.1, 300, 2.0, ShooterConsts::AK47_FIRE_SOUND, ShooterConsts::AK47_RELOAD_SOUND, weaponName, ShooterConsts::AK47_OBJ, Vec3D{3, 3, 3}, Vec3D{-2.2, 1.0, 1.3}, Vec3D{0, Consts::PI, 0}) {
fireSound = ShooterConsts::AK47_FIRE_SOUND;
reloadSound = ShooterConsts::AK47_RELOAD_SOUND;
_stockAmmo = ammo - _clipCapacity;
_fireDelay = 0.1;
} }

View File

@ -9,7 +9,7 @@
class Ak47 final : public Weapon { class Ak47 final : public Weapon {
public: public:
explicit Ak47(int ammo = 100, const std::string& weaponName = "ak47"); explicit Ak47(const std::string& weaponName = "ak47");
}; };

View File

@ -10,18 +10,7 @@
class Gold_Ak47 final : public Weapon { class Gold_Ak47 final : public Weapon {
public: public:
explicit Gold_Ak47(int ammo = 200, const std::string& weaponName = "gold_ak47") : Weapon(weaponName, ShooterConsts::GOLD_AK47_OBJ, Vec3D{3, 3, 3}, Vec3D{-2.2, 1.0, 1.3}, Vec3D{0, Consts::PI, 0}) { explicit Gold_Ak47(const std::string& weaponName = "gold_ak47") : Weapon(200, 60, 1.5, 0.05, 600, 1.0, ShooterConsts::GOLD_AK47_FIRE_SOUND, ShooterConsts::GOLD_AK47_RELOAD_SOUND, weaponName, ShooterConsts::GOLD_AK47_OBJ, Vec3D{3, 3, 3}, Vec3D{-2.2, 1.0, 1.3}, Vec3D{0, Consts::PI, 0}) {
fireSound = ShooterConsts::GOLD_AK47_FIRE_SOUND;
reloadSound = ShooterConsts::GOLD_AK47_RELOAD_SOUND;
_initialPack = 200;
_spreading = 1.0;
_reloadTime = 1.5;
_clipCapacity = 60;
_stockAmmo = ammo - _clipCapacity;
_fireDelay = 0.05;
_damage = 600;
_clipAmmo = _clipCapacity;
} }
}; };

View File

@ -8,16 +8,5 @@
using namespace std; using namespace std;
Gun::Gun(int ammo, const std::string& weaponName) : Weapon(weaponName, 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, "gun", ShooterConsts::GUN_OBJ, Vec3D{3, 3, 3}, Vec3D{-1.8, 1.3, 1.8}, Vec3D{0, Consts::PI, 0}) {
fireSound = ShooterConsts::GUN_FIRE_SOUND;
reloadSound = ShooterConsts::GUN_RELOAD_SOUND;
_initialPack = 30;
_clipCapacity = 6; // how much ammo can be stored in one clip
_stockAmmo = ammo - _clipCapacity; // how much ammo do you have in stock
_clipAmmo = _clipCapacity; // how much ammo do you have in current clip
_reloadTime = 2;
_fireDelay = 0.3; // time delay between fires
_damage = 800;
_spreading = 3.0;
} }

View File

@ -9,7 +9,7 @@
class Gun final : public Weapon { class Gun final : public Weapon {
public: public:
explicit Gun(int ammo = 30, const std::string& weaponName = "gun"); explicit Gun();
}; };

View File

@ -6,16 +6,5 @@
#include "Rifle.h" #include "Rifle.h"
#include "../ShooterConsts.h" #include "../ShooterConsts.h"
Rifle::Rifle(int ammo, const std::string &weaponName) : Weapon(weaponName, 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, "rifle", ShooterConsts::RIFLE_OBJ, Vec3D{3, 3, 3}, Vec3D{-2.3, 1, 1.3}, Vec3D{0, Consts::PI, 0}) {
fireSound = ShooterConsts::RIFLE_FIRE_SOUND;
reloadSound = ShooterConsts::RIFLE_RELOAD_SOUND;
_initialPack = 5;
_clipCapacity = 1; // how much ammo can be stored in one clip
_stockAmmo = ammo - _clipCapacity; // how much ammo do you have in stock
_clipAmmo = _clipCapacity; // how much ammo do you have in current clip
_reloadTime = 1;
_fireDelay = 1; // time delay between fires
_damage = 30000;
_spreading = 0.5;
} }

View File

@ -9,7 +9,7 @@
class Rifle final : public Weapon { class Rifle final : public Weapon {
public: public:
explicit Rifle(int ammo = 5, const std::string& weaponName = "rifle"); explicit Rifle();
}; };

View File

@ -9,19 +9,7 @@
using namespace std; using namespace std;
Shotgun::Shotgun(int ammo, const std::string& weaponName) : Weapon(weaponName, ShooterConsts::SHOTGUN_OBJ, Vec3D{3, 3, 3}, Vec3D{-1.95, 0.8, 1.5}, Vec3D{0, Consts::PI, 0}) { Shotgun::Shotgun(const std::string& weaponName) : Weapon(15, 1, 1.0, 1.0, 400, 5.0, ShooterConsts::SHOTGUN_FIRE_SOUND, ShooterConsts::SHOTGUN_RELOAD_SOUND, weaponName, ShooterConsts::SHOTGUN_OBJ, Vec3D{3, 3, 3}, Vec3D{-1.95, 0.8, 1.5}, Vec3D{0, Consts::PI, 0}) {
fireSound = ShooterConsts::SHOTGUN_FIRE_SOUND;
reloadSound = ShooterConsts::SHOTGUN_RELOAD_SOUND;
//reloadSound.setVolume(30);
_initialPack = 15;
_clipCapacity = 1; // how much ammo can be stored in one clipx
_stockAmmo = ammo - _clipCapacity; // how much ammo do you have in stock
_clipAmmo = _clipCapacity; // how much ammo do you have in current clip
_reloadTime = 1;
_fireDelay = 1; // time delay between fires
_damage = 400;
_spreading = 5;
} }
std::map<ObjectNameTag, double> std::map<ObjectNameTag, double>
@ -30,8 +18,9 @@ Shotgun::processFire(std::function<IntersectionInformation(const Vec3D&, const V
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;
}
} }
return damagedPlayers; return damagedPlayers;

View File

@ -9,7 +9,7 @@
class Shotgun final : public Weapon { class Shotgun final : public Weapon {
public: public:
explicit Shotgun(int ammo = 15, const std::string& weaponName = "shotgun"); explicit Shotgun(const std::string& weaponName = "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;
}; };

View File

@ -7,15 +7,15 @@
#include "../engine/ResourceManager.h" #include "../engine/ResourceManager.h"
#include "../engine/utils/Log.h" #include "../engine/utils/Log.h"
#include "../engine/animation/AColor.h" #include "../engine/animation/AColor.h"
#include "../engine/animation/AFunction.h"
#include "../ShooterConsts.h" #include "../ShooterConsts.h"
using namespace std; using namespace std;
Weapon::Weapon(const std::string& weaponName, const std::string& objFileName, const Vec3D& scale, const Vec3D& t, const Vec3D& r) { Weapon::Weapon(int initialPack, int clipCapacity, double reloadTime, double fireDelay, double damage, double spreading, std::string fireSound, std::string reloadSound, const std::string& weaponName, const std::string& objFileName, const Vec3D& s, const Vec3D& t, const Vec3D& r) : RigidBody(ObjectNameTag("weapon_" + weaponName), weaponName), _initialPack(initialPack), _clipCapacity(clipCapacity), _reloadTime(reloadTime), _fireDelay(fireDelay), _damage(damage), _spreading(spreading), _fireSound(std::move(fireSound)), _reloadSound(std::move(reloadSound)) {
_name = weaponName; _stockAmmo = _initialPack - _clipCapacity;
_clipAmmo = _clipCapacity;
loadObj(objFileName, scale); loadObj(objFileName, s);
setCollider(false); setCollider(false);
rotate(r); rotate(r);
translate(t); translate(t);
@ -24,12 +24,14 @@ Weapon::Weapon(const std::string& weaponName, const std::string& objFileName, co
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, const Vec3D& position, const Vec3D& direction) {
if(_clipAmmo == 0) { 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--;
@ -38,15 +40,16 @@ FireInformation Weapon::fire(std::function<IntersectionInformation(const Vec3D&,
reload(); reload();
} }
SoundController::playSound(SoundTag("fire"), fireSound); SoundController::playSound(SoundTag("fire"), _fireSound);
Log::log("Weapon::fire (" + std::to_string(_stockAmmo) + " : " + std::to_string(_clipAmmo) + ")"); Log::log("Weapon::fire (" + std::to_string(_stockAmmo) + " : " + std::to_string(_clipAmmo) + ")");
return FireInformation{processFire(std::move(rayCastFunction), position, direction), true}; return FireInformation{processFire(std::move(rayCastFunction), position, direction), true};
} }
void Weapon::reload() { 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;
@ -55,7 +58,7 @@ void Weapon::reload() {
_stockAmmo = 0; _stockAmmo = 0;
} }
SoundController::playSound(SoundTag("reload"), reloadSound); SoundController::playSound(SoundTag("reload"), _reloadSound);
Log::log("Weapon::reload (" + std::to_string(_stockAmmo) + " : " + std::to_string(_clipAmmo) + ")"); Log::log("Weapon::reload (" + std::to_string(_stockAmmo) + " : " + std::to_string(_clipAmmo) + ")");
_lastReloadTime = Time::time(); _lastReloadTime = Time::time();
} }
@ -74,8 +77,9 @@ std::map<ObjectNameTag, double> Weapon::addTrace(std::function<IntersectionInfor
// 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() + Vec3D(triangles().back()[0]); Vec3D lineFrom = position() + Vec3D(triangles().back()[0]);

View File

@ -15,56 +15,47 @@
#include "../engine/SoundController.h" #include "../engine/SoundController.h"
#include "../engine/Consts.h" #include "../engine/Consts.h"
struct FireInformation { struct FireInformation final {
const std::map<ObjectNameTag, double> damagedPlayers; const std::map<ObjectNameTag, double> damagedPlayers;
const bool shot; const bool shot;
}; };
class Weapon : public RigidBody { class Weapon : public RigidBody {
protected: private:
int _initialPack = 100; // how much ammo do you have when you find the weapon const int _initialPack = 100; // how much ammo do you have when you find the weapon
const int _clipCapacity = 30; // how much ammo can be stored in one clip
int _stockAmmo; // how much ammo do you have in stock
int _clipAmmo; // how much ammo do you have in current clip
const double _reloadTime = 3.0;
const double _fireDelay = 0.1; // time delay between fires
const double _damage = 300;
const double _spreading = 2.0;
int _clipCapacity = 30; // how much ammo can be stored in one clip const std::string _fireSound;
int _stockAmmo = _initialPack - _clipCapacity; // how much ammo do you have in stock const std::string _reloadSound;
int _clipAmmo = _clipCapacity; // how much ammo do you have in current clip
double _reloadTime = 3;
double _fireDelay = 0.1; // time delay between fires
double _damage = 300;
double _spreading = 2.0;
std::string _name = "Weapon";
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::string fireSound;
std::string reloadSound;
std::function<void(const Vec3D&, const Vec3D&)> _addTraceCallBack; std::function<void(const Vec3D&, const Vec3D&)> _addTraceCallBack;
protected:
std::map<ObjectNameTag, double> addTrace(std::function<IntersectionInformation(const Vec3D&, const Vec3D&)> rayCastFunction, const Vec3D& position, const Vec3D& direction); std::map<ObjectNameTag, double> 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); virtual std::map<ObjectNameTag, double> processFire(std::function<IntersectionInformation(const Vec3D&, const Vec3D&)> rayCastFunction, const Vec3D& position, const Vec3D& direction);
public: public:
Weapon(const std::string& weaponName, const std::string& objFileName, const Vec3D& scale, const Vec3D& translate, const Vec3D& rotate); Weapon(int initialPack, int clipCapacity, double reloadTime, double fireDelay, double damage, double spreading, std::string fireSound, std::string reloadSound, const std::string& 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) { void setAddTraceCallBack(std::function<void(Vec3D, Vec3D)> add) { _addTraceCallBack = std::move(add); }
_addTraceCallBack = std::move(add);
}
[[nodiscard]] ObjectNameTag name() const { return ObjectNameTag(_name); }
void addAmmo(int ammoAdd) { _stockAmmo += ammoAdd; } void addAmmo(int ammoAdd) { _stockAmmo += ammoAdd; }
[[nodiscard]] int initialPack() const {return _initialPack; } [[nodiscard]] int initialPack() const { return _initialPack; }
}; };