HitBox added. acceleration of collision detection in 20 times.
parent
747f294ec9
commit
6bc5c7dd1f
|
@ -91,7 +91,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 ShooterMsgType.h ShooterMsgType.cpp engine/animation/AAttractToPoint.h engine/animation/ARotateRelativePoint.h engine/animation/ARotateLeft.h engine/utils/Timer.cpp engine/utils/Timer.h)
|
engine/SoundController.cpp engine/SoundController.h ShooterMsgType.h ShooterMsgType.cpp engine/animation/AAttractToPoint.h engine/animation/ARotateRelativePoint.h engine/animation/ARotateLeft.h engine/utils/Timer.cpp engine/utils/Timer.h engine/physics/HitBox.cpp engine/physics/HitBox.h)
|
||||||
|
|
||||||
if(APPLE OR UNIX)
|
if(APPLE OR UNIX)
|
||||||
include_directories(/usr/local/include)
|
include_directories(/usr/local/include)
|
||||||
|
|
|
@ -3,17 +3,19 @@
|
||||||
//
|
//
|
||||||
|
|
||||||
#include "Player.h"
|
#include "Player.h"
|
||||||
|
|
||||||
|
#include <utility>
|
||||||
#include "engine/Screen.h"
|
#include "engine/Screen.h"
|
||||||
#include "engine/utils/Log.h"
|
#include "engine/utils/Log.h"
|
||||||
|
|
||||||
#include "engine/animation/Timeline.h"
|
#include "engine/animation/Timeline.h"
|
||||||
#include "engine/animation/ARotateLeft.h"
|
#include "engine/animation/ARotateLeft.h"
|
||||||
|
|
||||||
Player::Player(ObjectNameTag name) : RigidBody(name) {
|
Player::Player(ObjectNameTag name) : RigidBody(std::move(name), 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);
|
||||||
setVisible(false);
|
setVisible(false);
|
||||||
|
setSimpleHitBox(true);
|
||||||
|
|
||||||
Vec3D randColor = Vec3D::Random();
|
Vec3D randColor = Vec3D::Random();
|
||||||
setColor({static_cast<sf::Uint8>(randColor.x() * 255), static_cast<sf::Uint8>(randColor.y() * 255),
|
setColor({static_cast<sf::Uint8>(randColor.x() * 255), static_cast<sf::Uint8>(randColor.y() * 255),
|
||||||
|
|
|
@ -300,7 +300,7 @@ void Shooter::addFireTrace(const Vec3D &from, const Vec3D &to) {
|
||||||
std::make_shared<AColor>(world->body(ObjectNameTag(traceName)), sf::Color{150, 150, 150, 0}));
|
std::make_shared<AColor>(world->body(ObjectNameTag(traceName)), sf::Color{150, 150, 150, 0}));
|
||||||
Timeline::animate(AnimationListTag(traceName + "_delete"),
|
Timeline::animate(AnimationListTag(traceName + "_delete"),
|
||||||
std::make_shared<AFunction>([this, traceName]() { removeFireTrace(ObjectNameTag(traceName)); }, 1,
|
std::make_shared<AFunction>([this, traceName]() { removeFireTrace(ObjectNameTag(traceName)); }, 1,
|
||||||
2));
|
1));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Shooter::removeFireTrace(const ObjectNameTag &traceName) {
|
void Shooter::removeFireTrace(const ObjectNameTag &traceName) {
|
||||||
|
@ -315,6 +315,8 @@ void Shooter::addBonus(const string &bonusName, const Vec3D &position) {
|
||||||
world->addBody(std::make_shared<RigidBody>(ObjectNameTag(bonusName), "obj/" + name + ".obj", Vec3D{3, 3, 3}));
|
world->addBody(std::make_shared<RigidBody>(ObjectNameTag(bonusName), "obj/" + name + ".obj", Vec3D{3, 3, 3}));
|
||||||
world->body(ObjectNameTag(bonusName))->translateToPoint(position);
|
world->body(ObjectNameTag(bonusName))->translateToPoint(position);
|
||||||
world->body(ObjectNameTag(bonusName))->setCollider(false);
|
world->body(ObjectNameTag(bonusName))->setCollider(false);
|
||||||
|
world->body(ObjectNameTag(bonusName))->setSimpleHitBox(true);
|
||||||
|
world->body(ObjectNameTag(bonusName))->setTrigger(true);
|
||||||
Timeline::animate(AnimationListTag(bonusName + "_rotation"),
|
Timeline::animate(AnimationListTag(bonusName + "_rotation"),
|
||||||
std::make_shared<ARotate>(world->body(ObjectNameTag(bonusName)), Vec3D{0, 2 * Consts::PI, 0}, 4,
|
std::make_shared<ARotate>(world->body(ObjectNameTag(bonusName)), Vec3D{0, 2 * Consts::PI, 0}, 4,
|
||||||
Animation::LoopOut::Continue, Animation::InterpolationType::Linear));
|
Animation::LoopOut::Continue, Animation::InterpolationType::Linear));
|
||||||
|
@ -346,7 +348,7 @@ void Shooter::changeEnemyWeapon(const std::string &weaponName, sf::Uint16 enemyI
|
||||||
world->body(weaponTag)->setCollider(false);
|
world->body(weaponTag)->setCollider(false);
|
||||||
world->body(weaponTag)->scale(Vec3D(3, 3, 3));
|
world->body(weaponTag)->scale(Vec3D(3, 3, 3));
|
||||||
|
|
||||||
world->body(weaponTag)->translateToPoint(head->position() - enemy->left()*2 - enemy->up()*0.5);
|
world->body(weaponTag)->translateToPoint(head->position() - enemy->left() * 2 - enemy->up() * 0.5);
|
||||||
|
|
||||||
world->body(weaponTag)->rotate(Vec3D(0, Consts::PI + enemy->angle().y(), 0));
|
world->body(weaponTag)->rotate(Vec3D(0, Consts::PI + enemy->angle().y(), 0));
|
||||||
world->body(weaponTag)->rotateLeft(-head->angleLeftUpLookAt().x());
|
world->body(weaponTag)->rotateLeft(-head->angleLeftUpLookAt().x());
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
|
|
||||||
class Shooter final : public Engine {
|
class Shooter final : public Engine {
|
||||||
private:
|
private:
|
||||||
std::shared_ptr<Player> player = std::make_shared<Player>(ObjectNameTag("Player"));;
|
std::shared_ptr<Player> player = std::make_shared<Player>(ObjectNameTag("Player"));
|
||||||
std::shared_ptr<PlayerController> playerController = std::make_shared<PlayerController>(player, keyboard, mouse);
|
std::shared_ptr<PlayerController> playerController = std::make_shared<PlayerController>(player, keyboard, mouse);
|
||||||
|
|
||||||
Window mainMenu;
|
Window mainMenu;
|
||||||
|
|
|
@ -38,7 +38,7 @@ namespace ShooterConsts {
|
||||||
const std::string SHOTGUN_RELOAD_SOUND = "sound/weapons/reload_shotgun.ogg";
|
const std::string SHOTGUN_RELOAD_SOUND = "sound/weapons/reload_shotgun.ogg";
|
||||||
|
|
||||||
const std::string CUBE_OBJ = "obj/cube.obj";
|
const std::string CUBE_OBJ = "obj/cube.obj";
|
||||||
const std::string MAP_OBJ = "maps/map2.obj";
|
const std::string MAP_OBJ = "maps/map1.obj";
|
||||||
const std::string MAIN_MENU_BACK = "textures/back.png";
|
const std::string MAIN_MENU_BACK = "textures/back.png";
|
||||||
const std::string MAIN_MENU_GUI = "textures/gui.png";
|
const std::string MAIN_MENU_GUI = "textures/gui.png";
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,7 @@ int main() {
|
||||||
game.create(1280, 720, ShooterConsts::PROJECT_NAME);
|
game.create(1280, 720, ShooterConsts::PROJECT_NAME);
|
||||||
//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);
|
||||||
|
|
||||||
//game.create(2048, 1152, ShooterConsts::PROJECT_NAME, true);
|
//game.create(2048, 1152, ShooterConsts::PROJECT_NAME, false);
|
||||||
//game.create(3072, 1920, ShooterConsts::PROJECT_NAME, true, Consts::BACKGROUND_COLOR, sf::Style::Fullscreen);
|
//game.create(3072, 1920, ShooterConsts::PROJECT_NAME, true, Consts::BACKGROUND_COLOR, sf::Style::Fullscreen);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -93,7 +93,7 @@ void World::removeBody(const ObjectNameTag &tag) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void World::checkCollision(const ObjectNameTag &tag) {
|
void World::checkCollision(const ObjectNameTag &tag) {
|
||||||
if (_objects[tag]->isCollision()) {
|
if (_objects[tag]->hasCollision()) {
|
||||||
|
|
||||||
_objects[tag]->setInCollision(false);
|
_objects[tag]->setInCollision(false);
|
||||||
|
|
||||||
|
@ -102,7 +102,10 @@ void World::checkCollision(const ObjectNameTag &tag) {
|
||||||
ObjectNameTag name = it->first;
|
ObjectNameTag name = it->first;
|
||||||
it++;
|
it++;
|
||||||
|
|
||||||
if (name != tag) {
|
if ((name == tag) || !(obj->isCollider() || obj->isTrigger())) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
std::pair<bool, Simplex> gjk = _objects[tag]->checkGJKCollision(obj);
|
std::pair<bool, Simplex> gjk = _objects[tag]->checkGJKCollision(obj);
|
||||||
if (gjk.first) {
|
if (gjk.first) {
|
||||||
if (obj->isCollider()) {
|
if (obj->isCollider()) {
|
||||||
|
@ -113,7 +116,7 @@ void World::checkCollision(const ObjectNameTag &tag) {
|
||||||
_objects[tag]->collisionCallBack()(name, obj);
|
_objects[tag]->collisionCallBack()(name, obj);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,7 @@ private:
|
||||||
const std::function<void()> _callBack;
|
const std::function<void()> _callBack;
|
||||||
|
|
||||||
void update() override {
|
void update() override {
|
||||||
if (_allCalls != 0 && progress() > (double) _callsCounter / _allCalls) {
|
if (_allCalls != 0 && progress() >= (double) (_callsCounter + 1) / _allCalls) {
|
||||||
_callsCounter++;
|
_callsCounter++;
|
||||||
_callBack();
|
_callBack();
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,76 @@
|
||||||
|
//
|
||||||
|
// Created by Иван Ильин on 04.11.2021.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "HitBox.h"
|
||||||
|
#include "../Consts.h"
|
||||||
|
|
||||||
|
HitBox::HitBox(const Mesh &mesh) {
|
||||||
|
for(const auto& t : mesh.triangles()) {
|
||||||
|
for(int i = 0; i < 3; i++) {
|
||||||
|
// we dont need to add the same points in hit box
|
||||||
|
_addIfUnique(Vec3D(t[i]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void HitBox::_addIfUnique(const Vec3D &point) {
|
||||||
|
bool addPoint = true;
|
||||||
|
for(const auto& p : _hitBox) {
|
||||||
|
if((p - point).sqrAbs() < Consts::EPS) {
|
||||||
|
addPoint = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(addPoint) {
|
||||||
|
_hitBox.push_back(point);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
HitBox HitBox::Box(const Mesh &mesh) {
|
||||||
|
HitBox result;
|
||||||
|
|
||||||
|
double maxX = -std::numeric_limits<double>::max();
|
||||||
|
double maxY = -std::numeric_limits<double>::max();
|
||||||
|
double maxZ = -std::numeric_limits<double>::max();
|
||||||
|
|
||||||
|
double minX = std::numeric_limits<double>::max();
|
||||||
|
double minY = std::numeric_limits<double>::max();
|
||||||
|
double minZ = std::numeric_limits<double>::max();
|
||||||
|
|
||||||
|
for(const auto& t : mesh.triangles()) {
|
||||||
|
for(int i = 0; i < 3; i++) {
|
||||||
|
Vec3D point = Vec3D(t[i]);
|
||||||
|
if(point.x() > maxX) {
|
||||||
|
maxX = point.x();
|
||||||
|
}
|
||||||
|
if(point.y() > maxY) {
|
||||||
|
maxY = point.y();
|
||||||
|
}
|
||||||
|
if(point.z() > maxZ) {
|
||||||
|
maxZ = point.z();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(point.x() < minX) {
|
||||||
|
minX = point.x();
|
||||||
|
}
|
||||||
|
if(point.y() < minY) {
|
||||||
|
minY = point.y();
|
||||||
|
}
|
||||||
|
if(point.z() < minZ) {
|
||||||
|
minZ = point.z();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
result._hitBox.emplace_back(minX, minY, minZ);
|
||||||
|
result._hitBox.emplace_back(minX, maxY, minZ);
|
||||||
|
result._hitBox.emplace_back(maxX, minY, minZ);
|
||||||
|
result._hitBox.emplace_back(maxX, maxY, minZ);
|
||||||
|
|
||||||
|
result._hitBox.emplace_back(minX, minY, maxZ);
|
||||||
|
result._hitBox.emplace_back(minX, maxY, maxZ);
|
||||||
|
result._hitBox.emplace_back(maxX, minY, maxZ);
|
||||||
|
result._hitBox.emplace_back(maxX, maxY, maxZ);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
//
|
||||||
|
// Created by Иван Ильин on 04.11.2021.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef SHOOTER_HITBOX_H
|
||||||
|
#define SHOOTER_HITBOX_H
|
||||||
|
|
||||||
|
#include "../Mesh.h"
|
||||||
|
|
||||||
|
class HitBox {
|
||||||
|
private:
|
||||||
|
std::vector<Vec3D> _hitBox;
|
||||||
|
|
||||||
|
void _addIfUnique(const Vec3D& point);
|
||||||
|
public:
|
||||||
|
HitBox() = default;
|
||||||
|
explicit HitBox(const Mesh& mesh);
|
||||||
|
|
||||||
|
std::vector<Vec3D>::iterator begin() { return _hitBox.begin(); }
|
||||||
|
std::vector<Vec3D>::iterator end() { return _hitBox.end(); }
|
||||||
|
|
||||||
|
HitBox static Box(const Mesh& mesh);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif //SHOOTER_HITBOX_H
|
|
@ -11,7 +11,8 @@
|
||||||
#include "../Consts.h"
|
#include "../Consts.h"
|
||||||
|
|
||||||
RigidBody::RigidBody(ObjectNameTag nameTag, const std::string &filename, const Vec3D &scale) : Mesh(std::move(nameTag),
|
RigidBody::RigidBody(ObjectNameTag nameTag, const std::string &filename, const Vec3D &scale) : Mesh(std::move(nameTag),
|
||||||
filename, scale) {
|
filename, scale),
|
||||||
|
_hitBox(*this) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Vec3D RigidBody::_findFurthestPoint(const Vec3D &direction) {
|
Vec3D RigidBody::_findFurthestPoint(const Vec3D &direction) {
|
||||||
|
@ -21,6 +22,7 @@ Vec3D RigidBody::_findFurthestPoint(const Vec3D &direction) {
|
||||||
|
|
||||||
Vec3D transformedDirection = (view() * direction).normalized();
|
Vec3D transformedDirection = (view() * direction).normalized();
|
||||||
|
|
||||||
|
/*
|
||||||
for (auto &tri : triangles()) {
|
for (auto &tri : triangles()) {
|
||||||
for (int i = 0; i < 3; i++) {
|
for (int i = 0; i < 3; i++) {
|
||||||
Vec3D point = Vec3D(tri[i]);
|
Vec3D point = Vec3D(tri[i]);
|
||||||
|
@ -32,8 +34,19 @@ Vec3D RigidBody::_findFurthestPoint(const Vec3D &direction) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
return model()*maxPoint + position();
|
for(auto & it : _hitBox) {
|
||||||
|
auto point = Vec3D(it);
|
||||||
|
double distance = point.dot(transformedDirection);
|
||||||
|
|
||||||
|
if (distance > maxDistance) {
|
||||||
|
maxDistance = distance;
|
||||||
|
maxPoint = point;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return model() * maxPoint + position();
|
||||||
}
|
}
|
||||||
|
|
||||||
Vec3D RigidBody::_support(std::shared_ptr<RigidBody> obj, const Vec3D &direction) {
|
Vec3D RigidBody::_support(std::shared_ptr<RigidBody> obj, const Vec3D &direction) {
|
||||||
|
@ -346,5 +359,14 @@ void RigidBody::setAcceleration(const Vec3D &acceleration) {
|
||||||
_acceleration = acceleration;
|
_acceleration = acceleration;
|
||||||
}
|
}
|
||||||
|
|
||||||
RigidBody::RigidBody(const Mesh &mesh) : Mesh(mesh) {
|
RigidBody::RigidBody(const Mesh &mesh) : Mesh(mesh), _hitBox(mesh) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void RigidBody::setSimpleHitBox(bool b) {
|
||||||
|
_simpleHitBox = b;
|
||||||
|
if (_simpleHitBox) {
|
||||||
|
_hitBox = HitBox::Box(*this);
|
||||||
|
} else {
|
||||||
|
_hitBox = HitBox(*this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
#include "../Triangle.h"
|
#include "../Triangle.h"
|
||||||
#include "Simplex.h"
|
#include "Simplex.h"
|
||||||
#include "../Mesh.h"
|
#include "../Mesh.h"
|
||||||
|
#include "HitBox.h"
|
||||||
|
|
||||||
struct CollisionPoint final {
|
struct CollisionPoint final {
|
||||||
const Vec3D normal;
|
const Vec3D normal;
|
||||||
|
@ -35,8 +36,12 @@ private:
|
||||||
Vec3D _velocity{0, 0, 0};
|
Vec3D _velocity{0, 0, 0};
|
||||||
Vec3D _acceleration{0, 0, 0};
|
Vec3D _acceleration{0, 0, 0};
|
||||||
|
|
||||||
bool _collision = false;
|
bool _hasCollision = false;
|
||||||
bool _isCollider = true;
|
bool _isCollider = true;
|
||||||
|
bool _isTrigger = false;
|
||||||
|
|
||||||
|
HitBox _hitBox{};
|
||||||
|
bool _simpleHitBox = false;
|
||||||
|
|
||||||
bool _inCollision = false;
|
bool _inCollision = false;
|
||||||
Vec3D _collisionNormal{0, 0, 0};
|
Vec3D _collisionNormal{0, 0, 0};
|
||||||
|
@ -78,18 +83,24 @@ public:
|
||||||
|
|
||||||
[[nodiscard]] Vec3D collisionNormal() const { return _collisionNormal; }
|
[[nodiscard]] Vec3D collisionNormal() const { return _collisionNormal; }
|
||||||
|
|
||||||
[[nodiscard]] bool isCollision() const { return _collision; }
|
[[nodiscard]] bool hasCollision() const { return _hasCollision; }
|
||||||
|
|
||||||
[[nodiscard]] bool inCollision() const { return _inCollision; }
|
[[nodiscard]] bool inCollision() const { return _inCollision; }
|
||||||
|
|
||||||
[[nodiscard]] bool isCollider() const { return _isCollider; }
|
[[nodiscard]] bool isCollider() const { return _isCollider; }
|
||||||
|
|
||||||
|
[[nodiscard]] bool isTrigger() const { return _isTrigger; }
|
||||||
|
|
||||||
void setInCollision(bool c) { _inCollision = c; }
|
void setInCollision(bool c) { _inCollision = c; }
|
||||||
|
|
||||||
void setCollision(bool c) { _collision = c; }
|
void setCollision(bool c) { _hasCollision = c; }
|
||||||
|
|
||||||
void setCollider(bool c) { _isCollider = c; }
|
void setCollider(bool c) { _isCollider = c; }
|
||||||
|
|
||||||
|
void setSimpleHitBox(bool b);
|
||||||
|
|
||||||
|
void setTrigger(bool t) { _isTrigger = t; }
|
||||||
|
|
||||||
void updatePhysicsState();
|
void updatePhysicsState();
|
||||||
|
|
||||||
void setVelocity(const Vec3D &velocity);
|
void setVelocity(const Vec3D &velocity);
|
||||||
|
|
Loading…
Reference in New Issue