small refactoring

master
Vectozavr 2022-07-07 17:14:00 +07:00
parent b6f6c94133
commit 8afabf94c0
19 changed files with 207 additions and 50 deletions

View File

@ -85,6 +85,7 @@ add_executable(${CMAKE_PROJECT_NAME}
engine/animation/Animations.h engine/animation/Animations.h
engine/animation/AShowCreation.h engine/animation/AShowCreation.h
engine/animation/AShowUncreation.h engine/animation/AShowUncreation.h
engine/animation/ARotateLeftUpLookAt.h
engine/physics/RigidBody.cpp engine/physics/RigidBody.cpp
engine/physics/RigidBody.h engine/physics/RigidBody.h
engine/physics/Simplex.h engine/physics/Simplex.h

View File

@ -80,12 +80,29 @@ void Player::addWeapon(std::shared_ptr<Weapon> weapon) {
_weapons.back()->setReloadCallBack([this]() { _weapons.back()->setReloadCallBack([this]() {
Timeline::addAnimation<ARotateLeft>(AnimationListTag("reload_weapon"), Timeline::addAnimation<ARotateLeft>(AnimationListTag("reload_weapon"),
_weapons[_selectedWeapon], _weapons[_selectedWeapon],
-4 * Consts::PI, -2 * Consts::PI,
_weapons[_selectedWeapon]->reloadTime() / 2, _weapons[_selectedWeapon]->reloadTime() / 2,
Animation::LoopOut::None, Animation::LoopOut::None,
Animation::InterpolationType::Cos); Animation::InterpolationType::Cos);
}); });
// adding fire animation
_weapons.back()->setFireCallBack([this]() {
Timeline::addAnimation<ARotateLeft>(AnimationListTag("fire_weapon"),
_weapons[_selectedWeapon],
-_weapons[_selectedWeapon]->fireDelay(),
_weapons[_selectedWeapon]->fireDelay()/3,
Animation::LoopOut::None,
Animation::InterpolationType::Cos);
Timeline::addAnimation<AWait>(AnimationListTag("fire_weapon"), 0);
Timeline::addAnimation<ARotateLeft>(AnimationListTag("fire_weapon"),
_weapons[_selectedWeapon],
_weapons[_selectedWeapon]->fireDelay(),
_weapons[_selectedWeapon]->fireDelay()/3,
Animation::LoopOut::None,
Animation::InterpolationType::Cos);
});
// add call back function to create fire traces // add call back function to create fire traces
if (_addTraceCallBack != nullptr) { if (_addTraceCallBack != nullptr) {
_weapons.back()->setAddTraceCallBack(_addTraceCallBack); _weapons.back()->setAddTraceCallBack(_addTraceCallBack);
@ -126,7 +143,9 @@ void Player::selectNextWeapon() {
} }
Log::log("selectedWeapon " + std::to_string(_selectedWeapon)); Log::log("selectedWeapon " + std::to_string(_selectedWeapon));
SoundController::loadAndPlay(SoundTag("changeWeapon"), ShooterConsts::CHANGE_WEAPON_SOUND); SoundController::loadAndPlay(SoundTag("changeWeapon"), ShooterConsts::CHANGE_WEAPON_SOUND);
rotateWeapon();
} }
} }
void Player::selectPreviousWeapon() { void Player::selectPreviousWeapon() {
@ -145,6 +164,7 @@ void Player::selectPreviousWeapon() {
} }
Log::log("selectedWeapon " + std::to_string(_selectedWeapon)); Log::log("selectedWeapon " + std::to_string(_selectedWeapon));
SoundController::loadAndPlay(SoundTag("changeWeapon"), ShooterConsts::CHANGE_WEAPON_SOUND); SoundController::loadAndPlay(SoundTag("changeWeapon"), ShooterConsts::CHANGE_WEAPON_SOUND);
rotateWeapon();
} }
} }
@ -176,3 +196,12 @@ void Player::setFullAbility() {
_ability = ShooterConsts::ABILITY_MAX; _ability = ShooterConsts::ABILITY_MAX;
SoundController::loadAndPlay(SoundTag("addAbility"), ShooterConsts::RESTORE_ABILITY_SOUND); SoundController::loadAndPlay(SoundTag("addAbility"), ShooterConsts::RESTORE_ABILITY_SOUND);
} }
void Player::rotateWeapon() {
Timeline::addAnimation<ARotateLeft>(AnimationListTag("select_weapon"),
_weapons[_selectedWeapon],
-2 * Consts::PI,
0.3,
Animation::LoopOut::None,
Animation::InterpolationType::Cos);
}

View File

@ -42,6 +42,7 @@ private:
std::function<IntersectionInformation(const Vec3D &, const Vec3D &)> _rayCastFunction; std::function<IntersectionInformation(const Vec3D &, const Vec3D &)> _rayCastFunction;
void collisionWithObject(const ObjectNameTag &tag, std::shared_ptr<RigidBody> obj); void collisionWithObject(const ObjectNameTag &tag, std::shared_ptr<RigidBody> obj);
void rotateWeapon();
public: public:
explicit Player(ObjectNameTag name, const std::string &filename = ShooterConsts::CUBE_OBJ, const Vec3D &scale = Vec3D{1, 1, 1}); explicit Player(ObjectNameTag name, const std::string &filename = ShooterConsts::CUBE_OBJ, const Vec3D &scale = Vec3D{1, 1, 1});

View File

@ -41,6 +41,28 @@ void PlayerController::update() {
Keyboard::isKeyPressed(sf::Keyboard::S)); Keyboard::isKeyPressed(sf::Keyboard::S));
std::shared_ptr<Object> camera = _player->attached(ObjectNameTag("Camera")); std::shared_ptr<Object> camera = _player->attached(ObjectNameTag("Camera"));
if(camera != nullptr) {
// random motion during high speed
if (!Timeline::isInAnimList(AnimationListTag("high_speed_motion"))) {
double d_alpha = _player->velocity().abs()/3000*rand()/RAND_MAX;
double dt = 0.07;
Timeline::addAnimation<ARotateLeftUpLookAt>(AnimationListTag("high_speed_motion"),
camera, Vec3D(0, 0, d_alpha), dt,
Animation::LoopOut::None,
Animation::InterpolationType::Cos);
Timeline::addAnimation<AWait>(AnimationListTag("high_speed_motion"), 0);
Timeline::addAnimation<ARotateLeftUpLookAt>(AnimationListTag("high_speed_motion"),
camera, Vec3D(0, 0, -d_alpha), dt,
Animation::LoopOut::None,
Animation::InterpolationType::Cos);
Timeline::addAnimation<AWait>(AnimationListTag("high_speed_motion"), 0);
}
}
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::addAnimation<ATranslate>(AnimationListTag("camera_hor_oscil"), Timeline::addAnimation<ATranslate>(AnimationListTag("camera_hor_oscil"),
@ -149,6 +171,7 @@ void PlayerController::update() {
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()) * _player->addVelocity(Vec3D{0, std::abs(_player->collisionNormal().y()) *
sqrt(2 * -_player->acceleration().y() * ShooterConsts::JUMP_HEIGHT) * coeff, sqrt(2 * -_player->acceleration().y() * ShooterConsts::JUMP_HEIGHT) * coeff,
@ -160,6 +183,8 @@ void PlayerController::update() {
Time::deltaTime() * 60, 0}); Time::deltaTime() * 60, 0});
} }
_player->translate(Vec3D{0, Time::deltaTime() * ShooterConsts::WALK_SPEED * 2 * coeff, 0}); _player->translate(Vec3D{0, Time::deltaTime() * ShooterConsts::WALK_SPEED * 2 * coeff, 0});
//_player->setVelocity(Vec3D{_player->velocity().x(), sqrt(2 * -_player->acceleration().y() * ShooterConsts::JUMP_HEIGHT) * coeff,_player->velocity().z()});
_isSliding = true; _isSliding = true;
} else { } else {
_isSliding = false; _isSliding = false;
@ -169,8 +194,7 @@ void PlayerController::update() {
Vec2D displacement = _mouse->getMouseDisplacement(); Vec2D displacement = _mouse->getMouseDisplacement();
_player->rotate(Vec3D{0, -displacement.x() * ShooterConsts::MOUSE_SENSITIVITY, 0}); _player->rotate(Vec3D{0, -displacement.x() * ShooterConsts::MOUSE_SENSITIVITY, 0});
_player->setVelocity( _player->setVelocity(Matrix4x4::RotationY(-displacement.x() * ShooterConsts::MOUSE_SENSITIVITY) * _player->velocity());
Matrix4x4::RotationY(-displacement.x() * ShooterConsts::MOUSE_SENSITIVITY) * _player->velocity());
double rotationLeft = displacement.y() * ShooterConsts::MOUSE_SENSITIVITY; double rotationLeft = displacement.y() * ShooterConsts::MOUSE_SENSITIVITY;
@ -186,7 +210,10 @@ void PlayerController::update() {
_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) {
double lookAtAngle = camera->angleLeftUpLookAt().z();
camera->rotateLookAt(-lookAtAngle);
camera->rotateLeft(_player->headAngle() - camera->angleLeftUpLookAt().x()); camera->rotateLeft(_player->headAngle() - camera->angleLeftUpLookAt().x());
camera->rotateLookAt(lookAtAngle);
} }
if (_keyboard->isKeyTapped(sf::Keyboard::Right) || _keyboard->isKeyTapped(sf::Keyboard::E)) { if (_keyboard->isKeyTapped(sf::Keyboard::Right) || _keyboard->isKeyTapped(sf::Keyboard::E)) {

View File

@ -82,7 +82,7 @@ void Shooter::start() {
player->setDamagePlayerCallBack( player->setDamagePlayerCallBack(
[this](sf::Uint16 targetId, double damage) { client->damagePlayer(targetId, damage); }); [this](sf::Uint16 targetId, double damage) { client->damagePlayer(targetId, damage); });
player->setRayCastFunction( player->setRayCastFunction(
[this](const Vec3D &from, const Vec3D &to) { return world->rayCast(from, to, "Player Weapon"); }); [this](const Vec3D &from, const Vec3D &to) { return world->rayCast(from, to, "Player Weapon fireTrace bulletHole"); });
player->setTakeBonusCallBack([this](const string &bonusName) { client->takeBonus(bonusName); }); player->setTakeBonusCallBack([this](const string &bonusName) { client->takeBonus(bonusName); });
player->setAddWeaponCallBack([this](std::shared_ptr<Weapon> weapon) { addWeapon(std::move(weapon)); }); player->setAddWeaponCallBack([this](std::shared_ptr<Weapon> weapon) { addWeapon(std::move(weapon)); });
player->setRemoveWeaponCallBack([this](std::shared_ptr<Weapon> weapon) { removeWeapon(std::move(weapon)); }); player->setRemoveWeaponCallBack([this](std::shared_ptr<Weapon> weapon) { removeWeapon(std::move(weapon)); });
@ -303,7 +303,7 @@ void Shooter::removePlayer(sf::Uint16 id) {
} }
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_fireTrace_" + std::to_string(fireTraces++);
world->addBody(std::make_shared<RigidBody>(Mesh::LineTo(ObjectNameTag(traceName), from, to, 0.05))); world->addBody(std::make_shared<RigidBody>(Mesh::LineTo(ObjectNameTag(traceName), from, to, 0.05)));
world->body(ObjectNameTag(traceName))->setCollider(false); world->body(ObjectNameTag(traceName))->setCollider(false);
@ -312,6 +312,17 @@ void Shooter::addFireTrace(const Vec3D &from, const Vec3D &to) {
Timeline::addAnimation<AFunction>(AnimationListTag(traceName + "_delete"), Timeline::addAnimation<AFunction>(AnimationListTag(traceName + "_delete"),
[this, traceName]() { removeFireTrace(ObjectNameTag(traceName)); }, 1, [this, traceName]() { removeFireTrace(ObjectNameTag(traceName)); }, 1,
1); 1);
std::string bulletHoleName = "Client_bulletHole_" + std::to_string(fireTraces++);
auto bulletHole = Mesh::Cube(ObjectNameTag(bulletHoleName), 0.2, sf::Color(70, 70, 70));
bulletHole.translate(to);
world->addBody(std::make_shared<RigidBody>(bulletHole));
world->body(ObjectNameTag(bulletHoleName))->setCollider(false);
Timeline::addAnimation<AFunction>(AnimationListTag(bulletHoleName + "_delete"),
[this, bulletHoleName]() { removeFireTrace(ObjectNameTag(bulletHoleName)); }, 1,
7);
} }
void Shooter::removeFireTrace(const ObjectNameTag &traceName) { void Shooter::removeFireTrace(const ObjectNameTag &traceName) {
@ -367,12 +378,18 @@ void Shooter::changeEnemyWeapon(const std::string &weaponName, sf::Uint16 enemyI
world->body(weaponTag)->setCollider(false); world->body(weaponTag)->setCollider(false);
world->body(weaponTag)->scale(Vec3D(3, 3, 3)); world->body(weaponTag)->scale(Vec3D(3, 3, 3));
world->body(weaponTag)->translateToPoint( world->body(weaponTag)->translateToPoint(head->position() - enemy->left() * 1.0 - enemy->up() * 1.0 + enemy->lookAt());
head->position() - enemy->left() * 2.5 - enemy->up() * 2.5 + enemy->lookAt());
world->body(weaponTag)->rotate(Vec3D(0, enemy->angle().y(), 0)); world->body(weaponTag)->rotate(Vec3D(0, enemy->angle().y(), 0));
world->body(weaponTag)->rotateLeft(head->angleLeftUpLookAt().x()); world->body(weaponTag)->rotateLeft(head->angleLeftUpLookAt().x());
enemy->attach(world->body(weaponTag)); enemy->attach(world->body(weaponTag));
Timeline::addAnimation<ARotateLeft>(AnimationListTag("select_weapon_" + std::to_string(enemyId)),
world->body(weaponTag),
-2 * Consts::PI,
0.3,
Animation::LoopOut::None,
Animation::InterpolationType::Cos);
} }
void Shooter::removeWeapon(std::shared_ptr<Weapon> weapon) { void Shooter::removeWeapon(std::shared_ptr<Weapon> weapon) {

View File

@ -15,8 +15,8 @@ int main() {
//game.create(1920, 1080, ShooterConsts::PROJECT_NAME, true, Consts::BACKGROUND_COLOR, sf::Style::Fullscreen); //game.create(1920, 1080, ShooterConsts::PROJECT_NAME, true, Consts::BACKGROUND_COLOR, sf::Style::Fullscreen);
// Optimal for MacBook Pro 16 display: // Optimal for MacBook Pro 16 display:
game.create(2048, 1152, ShooterConsts::PROJECT_NAME, false, Consts::BACKGROUND_COLOR); game.create(2048, 1152, ShooterConsts::PROJECT_NAME, true, Consts::BACKGROUND_COLOR);
//game.create(3072, 1920, ShooterConsts::PROJECT_NAME, true, Consts::BACKGROUND_COLOR); //game.create(3072, 1920, ShooterConsts::PROJECT_NAME, true, Consts::BACKGROUND_COLOR, sf::Style::Fullscreen);
return 0; return 0;
} }

View File

@ -21,7 +21,7 @@ std::vector<std::shared_ptr<Triangle>> Camera::project(std::shared_ptr<Mesh> mes
// Model transform matrix: translate _tris in the origin of body. // Model transform matrix: translate _tris in the origin of body.
Matrix4x4 M = mesh->model(); Matrix4x4 M = mesh->model();
Matrix4x4 V = Matrix4x4::View(left(), up(), lookAt(), position()); Matrix4x4 V = invModel();
// We don't want to waste time re-allocating memory every time // We don't want to waste time re-allocating memory every time
std::vector<Triangle> clippedTriangles, tempBuffer; std::vector<Triangle> clippedTriangles, tempBuffer;

View File

@ -191,23 +191,32 @@ Matrix4x4 Matrix4x4::ScreenSpace(int width, int height) {
return s; return s;
} }
Matrix4x4 Matrix4x4::View(const Vec3D &left, const Vec3D &up, const Vec3D &lookAt, const Vec3D &eye) { Matrix4x4 Matrix4x4::View(const Matrix4x4 &transformMatrix) {
Matrix4x4 V = Zero(); Matrix4x4 V = Zero();
V._arr[0][0] = left.x(); Vec3D left = transformMatrix.x();
V._arr[0][1] = left.y(); Vec3D up = transformMatrix.y();
V._arr[0][2] = left.z(); Vec3D lookAt = transformMatrix.z();
V._arr[0][3] = -eye.dot(left); Vec3D eye = transformMatrix.w();
V._arr[1][0] = up.x(); double left_sqrAbs = left.sqrAbs();
V._arr[1][1] = up.y(); double up_sqrAbs = up.sqrAbs();
V._arr[1][2] = up.z(); double lookAt_sqrAbs = lookAt.sqrAbs();
V._arr[1][3] = -eye.dot(up);
V._arr[2][0] = lookAt.x(); V._arr[0][0] = left.x()/left_sqrAbs;
V._arr[2][1] = lookAt.y(); V._arr[0][1] = left.y()/left_sqrAbs;
V._arr[2][2] = lookAt.z(); V._arr[0][2] = left.z()/left_sqrAbs;
V._arr[2][3] = -eye.dot(lookAt); V._arr[0][3] = -eye.dot(left)/left_sqrAbs;
V._arr[1][0] = up.x()/up_sqrAbs;
V._arr[1][1] = up.y()/up_sqrAbs;
V._arr[1][2] = up.z()/up_sqrAbs;
V._arr[1][3] = -eye.dot(up)/up_sqrAbs;
V._arr[2][0] = lookAt.x()/lookAt_sqrAbs;
V._arr[2][1] = lookAt.y()/lookAt_sqrAbs;
V._arr[2][2] = lookAt.z()/lookAt_sqrAbs;
V._arr[2][3] = -eye.dot(lookAt)/lookAt_sqrAbs;
V._arr[3][3] = 1.0; V._arr[3][3] = 1.0;

View File

@ -55,7 +55,7 @@ public:
Matrix4x4 static Rotation(const Vec3D &v, double rv); Matrix4x4 static Rotation(const Vec3D &v, double rv);
Matrix4x4 static View(const Vec3D &left, const Vec3D &up, const Vec3D &lookAt, const Vec3D &eye); Matrix4x4 static View(const Matrix4x4 &transformMatrix);
Matrix4x4 static Projection(double fov = 90.0, double aspect = 1.0, double ZNear = 1.0, double ZFar = 10.0); Matrix4x4 static Projection(double fov = 90.0, double aspect = 1.0, double ZNear = 1.0, double ZFar = 10.0);

View File

@ -36,8 +36,7 @@ Mesh::Mesh(ObjectNameTag nameTag, const std::string &filename, const Vec3D &scal
loadObj(filename, scale); loadObj(filename, scale);
} }
Mesh::Mesh(ObjectNameTag nameTag, const vector<Triangle> &tries) : Object(std::move(nameTag)), _tris(tries) { Mesh::Mesh(ObjectNameTag nameTag, const vector<Triangle> &tries) : Object(std::move(nameTag)), _tris(tries) {}
}
void Mesh::setColor(const sf::Color &c) { void Mesh::setColor(const sf::Color &c) {
_color = c; _color = c;
@ -200,3 +199,25 @@ GLfloat *Mesh::glFloatArray() const {
return _geometry; return _geometry;
} }
Mesh Mesh::Cube(ObjectNameTag tag, double size, sf::Color color) {
Mesh cube(std::move(tag));
cube._tris = {
{ Vec4D{0.0, 0.0, 0.0, 1.0}, Vec4D{0.0, 1.0, 0.0, 1.0}, Vec4D{1.0, 1.0, 0.0, 1.0} },
{ Vec4D{0.0, 0.0, 0.0, 1.0}, Vec4D{1.0, 1.0, 0.0, 1.0}, Vec4D{1.0, 0.0, 0.0, 1.0} },
{ Vec4D{1.0, 0.0, 0.0, 1.0}, Vec4D{1.0, 1.0, 0.0, 1.0}, Vec4D{1.0, 1.0, 1.0, 1.0} },
{ Vec4D{1.0, 0.0, 0.0, 1.0}, Vec4D{1.0, 1.0, 1.0, 1.0}, Vec4D{1.0, 0.0, 1.0, 1.0} },
{ Vec4D{1.0, 0.0, 1.0, 1.0}, Vec4D{1.0, 1.0, 1.0, 1.0}, Vec4D{0.0, 1.0, 1.0, 1.0} },
{ Vec4D{1.0, 0.0, 1.0, 1.0}, Vec4D{0.0, 1.0, 1.0, 1.0}, Vec4D{0.0, 0.0, 1.0, 1.0} },
{ Vec4D{0.0, 0.0, 1.0, 1.0}, Vec4D{0.0, 1.0, 1.0, 1.0}, Vec4D{0.0, 1.0, 0.0, 1.0} },
{ Vec4D{0.0, 0.0, 1.0, 1.0}, Vec4D{0.0, 1.0, 0.0, 1.0}, Vec4D{0.0, 0.0, 0.0, 1.0} },
{ Vec4D{0.0, 1.0, 0.0, 1.0}, Vec4D{0.0, 1.0, 1.0, 1.0}, Vec4D{1.0, 1.0, 1.0, 1.0} },
{ Vec4D{0.0, 1.0, 0.0, 1.0}, Vec4D{1.0, 1.0, 1.0, 1.0}, Vec4D{1.0, 1.0, 0.0, 1.0} },
{ Vec4D{1.0, 0.0, 1.0, 1.0}, Vec4D{0.0, 0.0, 1.0, 1.0}, Vec4D{0.0, 0.0, 0.0, 1.0} },
{ Vec4D{1.0, 0.0, 1.0, 1.0}, Vec4D{0.0, 0.0, 0.0, 1.0}, Vec4D{1.0, 0.0, 0.0, 1.0} },
};
cube.setColor(color);
return cube *= Matrix4x4::Scale(Vec3D(size, size, size))*Matrix4x4::Translation(Vec3D(-0.5, -0.5, -0.5));
}

View File

@ -54,6 +54,8 @@ public:
~Mesh() override; ~Mesh() override;
Mesh static Cube(ObjectNameTag tag, double size = 1.0, sf::Color color = sf::Color(0,0,0));
Mesh static LineTo(ObjectNameTag nameTag, const Vec3D &from, const Vec3D &to, double line_width = 0.1, Mesh static LineTo(ObjectNameTag nameTag, const Vec3D &from, const Vec3D &to, double line_width = 0.1,
const sf::Color &color = {150, 150, 150, 100}); const sf::Color &color = {150, 150, 150, 100});

View File

@ -87,7 +87,7 @@ public:
[[nodiscard]] ObjectNameTag name() const { return _nameTag; } [[nodiscard]] ObjectNameTag name() const { return _nameTag; }
[[nodiscard]] Matrix4x4 model() const { return Matrix4x4::Translation(_position) * _transformMatrix; } [[nodiscard]] Matrix4x4 model() const { return Matrix4x4::Translation(_position) * _transformMatrix; }
[[nodiscard]] Matrix4x4 invModel() const { return Matrix4x4::View(left(), up(), lookAt(), position()); } [[nodiscard]] Matrix4x4 invModel() const { return Matrix4x4::View(model()); }
// OpenGL function // OpenGL function
[[nodiscard]] GLfloat *glModel() const; [[nodiscard]] GLfloat *glModel() const;

View File

@ -135,8 +135,7 @@ std::vector<std::shared_ptr<Mesh>> ResourceManager::loadObjects(const std::strin
if (line[0] == 'o') { if (line[0] == 'o') {
if (!tris.empty()) if (!tris.empty())
objects.push_back( objects.push_back(
std::make_shared<Mesh>(ObjectNameTag(filename + "_temp_obj_" + std::to_string(objects.size())), std::make_shared<Mesh>(ObjectNameTag(filename + "_temp_obj_" + std::to_string(objects.size())), tris));
tris));
tris.clear(); tris.clear();
} }
if (line[0] == 'v') { if (line[0] == 'v') {

View File

@ -56,25 +56,38 @@ IntersectionInformation World::rayCast(const Vec3D &from, const Vec3D &to, const
continue; continue;
} }
for (auto &tri : body->triangles()) {
Matrix4x4 model = body->model(); Matrix4x4 model = body->model();
Triangle tri_translated(model * tri[0], model * tri[1], model * tri[2], tri.color()); Matrix4x4 invModel = body->invModel();
Plane plane(tri_translated); Vec3D v = (to - from).normalized();
auto intersection = plane.intersection(from, to); Vec3D v_model = invModel*v;
double distance = (intersection.first - from).sqrAbs(); Vec3D from_model = invModel*(from - body->position());
if (intersection.second > 0 && distance < minDistance && tri_translated.isPointInside(intersection.first)) { Vec3D to_model = invModel*(to - body->position());
for (auto &tri : body->triangles()) {
if(tri.norm().dot(v_model) > 0) {
continue;
}
Plane plane(tri);
auto intersection = plane.intersection(from_model, to_model);
double distance = (intersection.first - from_model).sqrAbs();
if (intersection.second > 0 && distance < minDistance && tri.isPointInside(intersection.first)) {
minDistance = distance; minDistance = distance;
point = intersection.first; point = model*intersection.first + body->position();
triangle = tri_translated; triangle = Triangle(model * tri[0], model * tri[1], model * tri[2], tri.color());
bodyName = name.str(); bodyName = name.str();
intersected = true; intersected = true;
intersectedBody = body; intersectedBody = body;
//Triangle triangleRED = Triangle(model * tri[0], model * tri[1], model * tri[2], sf::Color(255, 0, 0));
//addBody(std::make_shared<RigidBody>(Mesh(ObjectNameTag("Test" + std::to_string(rand())), std::vector<Triangle>({triangleRED}))));
} }
} }
} }
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) {

View File

@ -0,0 +1,36 @@
//
// Created by Иван Ильин on 01.11.2021.
//
#ifndef SHOOTER_AROTATELEFTUPLOOKAT_H
#define SHOOTER_AROTATELEFTUPLOOKAT_H
#include "Animation.h"
#include "../Object.h"
class ARotateLeftUpLookAt final : public Animation {
private:
const std::weak_ptr<Object> _object;
const Vec3D _rotationValue;
void update() override {
auto obj = _object.lock();
if (obj == nullptr) {
stop();
return;
}
obj->rotateLeft(_rotationValue.x()*dprogress());
obj->rotateUp(_rotationValue.y()*dprogress());
obj->rotateLookAt(_rotationValue.z()*dprogress());
}
public:
ARotateLeftUpLookAt(std::weak_ptr<Object> object, const Vec3D &r, double duration = 1, LoopOut looped = LoopOut::None,
InterpolationType interpolationType = InterpolationType::Bezier)
: Animation(duration, looped, interpolationType), _object(object), _rotationValue(r) {}
};
#endif //SHOOTER_AROTATELEFT_H

View File

@ -19,6 +19,7 @@
#include "AWait.h" #include "AWait.h"
#include "AShowCreation.h" #include "AShowCreation.h"
#include "AShowUncreation.h" #include "AShowUncreation.h"
#include "ARotateLeftUpLookAt.h"
#endif //SHOOTER_ANIMATIONS_H #endif //SHOOTER_ANIMATIONS_H

View File

@ -321,12 +321,10 @@ RigidBody::_addIfUniqueEdge(const std::vector<std::pair<size_t, size_t>> &edges,
void RigidBody::solveCollision(const CollisionPoint &collision) { void RigidBody::solveCollision(const CollisionPoint &collision) {
Vec3D velocity_parallel = collision.normal * velocity().dot(collision.normal); Vec3D velocity_perpendicular = collision.normal * velocity().dot(collision.normal);
Vec3D velocity_perpendicular = velocity() - velocity_parallel; Vec3D velocity_parallel = velocity() - velocity_perpendicular;
if (velocity().dot(collision.normal) > 0) { setVelocity(velocity_parallel);
setVelocity(velocity_perpendicular);
}
translate(-collision.normal * collision.depth); translate(-collision.normal * collision.depth);
} }

View File

@ -43,18 +43,18 @@ FireInformation Weapon::fire(std::function<IntersectionInformation(const Vec3D &
_lastFireTime = Time::time(); _lastFireTime = Time::time();
_clipAmmo--; _clipAmmo--;
if (_clipAmmo == 0) {
reload();
}
SoundController::loadAndPlay(SoundTag("fireSound_" + name().str()), _fireSound); SoundController::loadAndPlay(SoundTag("fireSound_" + name().str()), _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) + ")");
if (_fireCallBack != nullptr) {
_fireCallBack();
}
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 || _clipAmmo == _clipCapacity) {
return; return;
} }
if (_clipCapacity - _clipAmmo <= _stockAmmo) { if (_clipCapacity - _clipAmmo <= _stockAmmo) {

View File

@ -39,6 +39,7 @@ private:
std::function<void(const Vec3D &, const Vec3D &)> _addTraceCallBack; std::function<void(const Vec3D &, const Vec3D &)> _addTraceCallBack;
std::function<void()> _reloadCallBack; std::function<void()> _reloadCallBack;
std::function<void()> _fireCallBack;
protected: protected:
std::map<ObjectNameTag, double> std::map<ObjectNameTag, double>
@ -60,11 +61,13 @@ public:
void reload(); void reload();
[[nodiscard]] double reloadTime() const { return _reloadTime; } [[nodiscard]] double reloadTime() const { return _reloadTime; }
[[nodiscard]] double fireDelay() const { return _fireDelay; }
[[nodiscard]] std::pair<double, double> balance() const { return std::make_pair(_clipAmmo, _stockAmmo); } [[nodiscard]] std::pair<double, double> balance() const { return std::make_pair(_clipAmmo, _stockAmmo); }
void setAddTraceCallBack(std::function<void(Vec3D, Vec3D)> add) { _addTraceCallBack = std::move(add); } void setAddTraceCallBack(std::function<void(Vec3D, Vec3D)> add) { _addTraceCallBack = std::move(add); }
void setReloadCallBack(std::function<void()> reload) { _reloadCallBack = std::move(reload); } void setReloadCallBack(std::function<void()> reload) { _reloadCallBack = std::move(reload); }
void setFireCallBack(std::function<void()> fire) { _fireCallBack = std::move(fire); }
void addAPack() { _stockAmmo += initialPack(); } void addAPack() { _stockAmmo += initialPack(); }