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/UDPSocket.cpp
|
||||
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)
|
||||
include_directories(/usr/local/include)
|
||||
|
|
|
@ -3,17 +3,19 @@
|
|||
//
|
||||
|
||||
#include "Player.h"
|
||||
|
||||
#include <utility>
|
||||
#include "engine/Screen.h"
|
||||
#include "engine/utils/Log.h"
|
||||
|
||||
#include "engine/animation/Timeline.h"
|
||||
#include "engine/animation/ARotateLeft.h"
|
||||
|
||||
Player::Player(ObjectNameTag name) : RigidBody(name) {
|
||||
loadObj(ShooterConsts::CUBE_OBJ, Vec3D{0.5, 1.9, 0.5});
|
||||
Player::Player(ObjectNameTag name) : RigidBody(std::move(name), ShooterConsts::CUBE_OBJ,Vec3D{0.5, 1.9, 0.5}) {
|
||||
setAcceleration(Vec3D{0, -ShooterConsts::GRAVITY, 0});
|
||||
setCollision(true);
|
||||
setVisible(false);
|
||||
setSimpleHitBox(true);
|
||||
|
||||
Vec3D randColor = Vec3D::Random();
|
||||
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}));
|
||||
Timeline::animate(AnimationListTag(traceName + "_delete"),
|
||||
std::make_shared<AFunction>([this, traceName]() { removeFireTrace(ObjectNameTag(traceName)); }, 1,
|
||||
2));
|
||||
1));
|
||||
}
|
||||
|
||||
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->body(ObjectNameTag(bonusName))->translateToPoint(position);
|
||||
world->body(ObjectNameTag(bonusName))->setCollider(false);
|
||||
world->body(ObjectNameTag(bonusName))->setSimpleHitBox(true);
|
||||
world->body(ObjectNameTag(bonusName))->setTrigger(true);
|
||||
Timeline::animate(AnimationListTag(bonusName + "_rotation"),
|
||||
std::make_shared<ARotate>(world->body(ObjectNameTag(bonusName)), Vec3D{0, 2 * Consts::PI, 0}, 4,
|
||||
Animation::LoopOut::Continue, Animation::InterpolationType::Linear));
|
||||
|
@ -346,7 +348,7 @@ void Shooter::changeEnemyWeapon(const std::string &weaponName, sf::Uint16 enemyI
|
|||
world->body(weaponTag)->setCollider(false);
|
||||
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)->rotateLeft(-head->angleLeftUpLookAt().x());
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
|
||||
class Shooter final : public Engine {
|
||||
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);
|
||||
|
||||
Window mainMenu;
|
||||
|
|
|
@ -38,7 +38,7 @@ namespace ShooterConsts {
|
|||
const std::string SHOTGUN_RELOAD_SOUND = "sound/weapons/reload_shotgun.ogg";
|
||||
|
||||
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_GUI = "textures/gui.png";
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@ int main() {
|
|||
game.create(1280, 720, ShooterConsts::PROJECT_NAME);
|
||||
//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);
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -93,7 +93,7 @@ void World::removeBody(const ObjectNameTag &tag) {
|
|||
}
|
||||
|
||||
void World::checkCollision(const ObjectNameTag &tag) {
|
||||
if (_objects[tag]->isCollision()) {
|
||||
if (_objects[tag]->hasCollision()) {
|
||||
|
||||
_objects[tag]->setInCollision(false);
|
||||
|
||||
|
@ -102,18 +102,21 @@ void World::checkCollision(const ObjectNameTag &tag) {
|
|||
ObjectNameTag name = it->first;
|
||||
it++;
|
||||
|
||||
if (name != tag) {
|
||||
std::pair<bool, Simplex> gjk = _objects[tag]->checkGJKCollision(obj);
|
||||
if (gjk.first) {
|
||||
if (obj->isCollider()) {
|
||||
CollisionPoint epa = _objects[tag]->EPA(gjk.second, obj);
|
||||
_objects[tag]->solveCollision(epa);
|
||||
}
|
||||
if (_objects[tag]->collisionCallBack() != nullptr) {
|
||||
_objects[tag]->collisionCallBack()(name, obj);
|
||||
}
|
||||
if ((name == tag) || !(obj->isCollider() || obj->isTrigger())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
std::pair<bool, Simplex> gjk = _objects[tag]->checkGJKCollision(obj);
|
||||
if (gjk.first) {
|
||||
if (obj->isCollider()) {
|
||||
CollisionPoint epa = _objects[tag]->EPA(gjk.second, obj);
|
||||
_objects[tag]->solveCollision(epa);
|
||||
}
|
||||
if (_objects[tag]->collisionCallBack() != nullptr) {
|
||||
_objects[tag]->collisionCallBack()(name, obj);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@ private:
|
|||
const std::function<void()> _callBack;
|
||||
|
||||
void update() override {
|
||||
if (_allCalls != 0 && progress() > (double) _callsCounter / _allCalls) {
|
||||
if (_allCalls != 0 && progress() >= (double) (_callsCounter + 1) / _allCalls) {
|
||||
_callsCounter++;
|
||||
_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"
|
||||
|
||||
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) {
|
||||
|
@ -21,6 +22,7 @@ Vec3D RigidBody::_findFurthestPoint(const Vec3D &direction) {
|
|||
|
||||
Vec3D transformedDirection = (view() * direction).normalized();
|
||||
|
||||
/*
|
||||
for (auto &tri : triangles()) {
|
||||
for (int i = 0; i < 3; 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) {
|
||||
|
@ -346,5 +359,14 @@ void RigidBody::setAcceleration(const Vec3D &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 "Simplex.h"
|
||||
#include "../Mesh.h"
|
||||
#include "HitBox.h"
|
||||
|
||||
struct CollisionPoint final {
|
||||
const Vec3D normal;
|
||||
|
@ -35,8 +36,12 @@ private:
|
|||
Vec3D _velocity{0, 0, 0};
|
||||
Vec3D _acceleration{0, 0, 0};
|
||||
|
||||
bool _collision = false;
|
||||
bool _hasCollision = false;
|
||||
bool _isCollider = true;
|
||||
bool _isTrigger = false;
|
||||
|
||||
HitBox _hitBox{};
|
||||
bool _simpleHitBox = false;
|
||||
|
||||
bool _inCollision = false;
|
||||
Vec3D _collisionNormal{0, 0, 0};
|
||||
|
@ -78,18 +83,24 @@ public:
|
|||
|
||||
[[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 isCollider() const { return _isCollider; }
|
||||
|
||||
[[nodiscard]] bool isTrigger() const { return _isTrigger; }
|
||||
|
||||
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 setSimpleHitBox(bool b);
|
||||
|
||||
void setTrigger(bool t) { _isTrigger = t; }
|
||||
|
||||
void updatePhysicsState();
|
||||
|
||||
void setVelocity(const Vec3D &velocity);
|
||||
|
|
Loading…
Reference in New Issue