Collision stuff

This commit is contained in:
Bailey Harrison 2023-02-12 14:50:29 +00:00
parent 0a0f4758b1
commit f32a42b393
6 changed files with 33 additions and 26 deletions

View File

@ -19,11 +19,7 @@ namespace engine {
bool isTrigger = false; // entity receives an event on collision enter and exit bool isTrigger = false; // entity receives an event on collision enter and exit
AABB aabb{}; // broad phase AABB aabb{}; // broad phase
bool getIsColliding() { return isColliding; }
private: private:
bool isColliding = false;
}; };
} }

View File

@ -21,6 +21,7 @@ namespace engine {
bool isCollisionEnter; // false == collision exit bool isCollisionEnter; // false == collision exit
uint32_t collidedEntity; // the entity that this entity collided with uint32_t collidedEntity; // the entity that this entity collided with
glm::vec3 normal; // the normal of the surface this entity collided with; ignored on collision exit glm::vec3 normal; // the normal of the surface this entity collided with; ignored on collision exit
glm::vec3 point; // where the collision was detected
}; };
private: private:

View File

@ -35,8 +35,8 @@ namespace engine {
const float PZdistance = glm::abs(subjectCentre.z - object.pos2.z); const float PZdistance = glm::abs(subjectCentre.z - object.pos2.z);
const float NZdistance = glm::abs(subjectCentre.z - object.pos1.z); const float NZdistance = glm::abs(subjectCentre.z - object.pos1.z);
const std::array<float, 6> distances { PXdistance, NXdistance, PYdistance, NYdistance, PZdistance, NZdistance }; const std::array<float, 6> distances { PXdistance, NXdistance, PYdistance, NYdistance, PZdistance, NZdistance };
const auto maxDistance = std::max_element(distances.begin(), distances.end()); const auto minDistance = std::min_element(distances.begin(), distances.end());
const int index = maxDistance - distances.begin(); const int index = minDistance - distances.begin();
switch (index) { switch (index) {
case 0: case 0:
// P_X // P_X
@ -135,6 +135,10 @@ namespace engine {
info.isCollisionEnter = true; info.isCollisionEnter = true;
info.collidedEntity = possibleCollision.dynamicEntity; info.collidedEntity = possibleCollision.dynamicEntity;
info.normal = getAABBNormal(possibleCollision.staticAABB, possibleCollision.dynamicAABB); info.normal = getAABBNormal(possibleCollision.staticAABB, possibleCollision.dynamicAABB);
AABB object = possibleCollision.dynamicAABB;
info.point = object.pos2;
m_collisionInfos.emplace_back(possibleCollision.staticEntity, info); m_collisionInfos.emplace_back(possibleCollision.staticEntity, info);
} }
if (possibleCollision.dynamicTrigger) { if (possibleCollision.dynamicTrigger) {
@ -142,6 +146,11 @@ namespace engine {
info.isCollisionEnter = true; info.isCollisionEnter = true;
info.collidedEntity = possibleCollision.staticEntity; info.collidedEntity = possibleCollision.staticEntity;
info.normal = getAABBNormal(possibleCollision.dynamicAABB, possibleCollision.staticAABB); info.normal = getAABBNormal(possibleCollision.dynamicAABB, possibleCollision.staticAABB);
AABB object = possibleCollision.staticAABB;
info.point = object.pos2;
m_collisionInfos.emplace_back(possibleCollision.dynamicEntity, info); m_collisionInfos.emplace_back(possibleCollision.dynamicEntity, info);
} }
} }

View File

@ -40,13 +40,12 @@ void CameraControllerSystem::onUpdate(float ts)
const float dt = ts; const float dt = ts;
/*
constexpr float G = 9.8f; constexpr float G = 9.8f;
// constexpr float MAX_SLOPE_ANGLE = glm::radians(20.0f); // constexpr float MAX_SLOPE_ANGLE = glm::radians(20.0f);
constexpr float MAX_SLOPE_ANGLE = glm::radians(1000.0f); // treat every collider as a floor, (TODO: get wall collisions working so this can be removed) constexpr float MAX_SLOPE_ANGLE = glm::radians(1000.0f); // treat every collider as a floor, (TODO: get wall collisions working so this can be removed)
constexpr float FLOOR_SINK_LEVEL = 0.05f; // how far into the floor to ground the player constexpr float FLOOR_SINK_LEVEL = 0.05f; // how far into the floor to ground the player
glm::vec3 norm = col->getLastCollisionNormal(); glm::vec3 norm = c->lastCollisionNormal;
norm.y = 0.0f; norm.y = 0.0f;
@ -55,22 +54,22 @@ void CameraControllerSystem::onUpdate(float ts)
bool isSliding = false; bool isSliding = false;
if (col->getIsColliding()) { if (c->justCollided) {
if (slope > MAX_SLOPE_ANGLE) { if (slope > MAX_SLOPE_ANGLE) {
// slide across wall // slide across wall
isSliding = true; isSliding = true;
} else { } else {
if (c->dy < 0.0f && c->isGrounded == false) { if (c->dy < 0.0f && c->isGrounded == false) {
// in the ground, push up a bit // in the ground, push up a bit
float floorY = col->getLastCollisionPoint().y; float floorY = c->lastCollisionPoint.y;
t->position.y = floorY + col->colliders.sphereCollider.r - FLOOR_SINK_LEVEL; t->position.y = floorY + 1.5f - FLOOR_SINK_LEVEL;
c->dy = 0.0f; c->dy = 0.0f;
c->isGrounded = true; c->isGrounded = true;
} }
} }
} }
if (col->getJustUncollided() && slope <= MAX_SLOPE_ANGLE) { if (c->justCollided == false && slope <= MAX_SLOPE_ANGLE) {
// just stopped colliding with a floor collider // just stopped colliding with a floor collider
c->isGrounded = false; c->isGrounded = false;
} }
@ -88,15 +87,10 @@ void CameraControllerSystem::onUpdate(float ts)
c->dy += dt * c->thrust; c->dy += dt * c->thrust;
} }
*/
// in metres per second // in metres per second
float SPEED = c->walk_speed; float SPEED = c->walk_speed;
if (m_scene->app()->inputManager()->getButton("sprint")) SPEED *= 10.0f; if (m_scene->app()->inputManager()->getButton("sprint")) SPEED *= 10.0f;
if (m_scene->app()->inputManager()->getButton("fire")) t->position.y += dt * SPEED;
if (m_scene->app()->inputManager()->getButton("aim")) t->position.y -= dt * SPEED;
float dx = m_scene->app()->inputManager()->getAxis("movex"); float dx = m_scene->app()->inputManager()->getAxis("movex");
float dz = (-m_scene->app()->inputManager()->getAxis("movey")); float dz = (-m_scene->app()->inputManager()->getAxis("movey"));
@ -116,10 +110,9 @@ void CameraControllerSystem::onUpdate(float ts)
const glm::vec3 d2xRotated = glm::rotateY(glm::vec3{ dx, 0.0f, 0.0f }, c->m_yaw); const glm::vec3 d2xRotated = glm::rotateY(glm::vec3{ dx, 0.0f, 0.0f }, c->m_yaw);
const glm::vec3 d2zRotated = glm::rotateY(glm::vec3{ 0.0f, 0.0f, dz }, c->m_yaw); const glm::vec3 d2zRotated = glm::rotateY(glm::vec3{ 0.0f, 0.0f, dz }, c->m_yaw);
glm::vec3 hVel = (d2xRotated + d2zRotated); glm::vec3 hVel = (d2xRotated + d2zRotated);
/* if (isSliding) { if (isSliding) {
hVel = glm::vec3{norm.z, 0.0f, -norm.x}; hVel = glm::vec3{norm.z, 0.0f, -norm.x};
} }
*/
hVel *= SPEED; hVel *= SPEED;
t->position += hVel * dt; t->position += hVel * dt;
t->position.y += c->dy * dt; t->position.y += c->dy * dt;
@ -170,11 +163,14 @@ void CameraControllerSystem::onUpdate(float ts)
m_scene->app()->window()->toggleFullscreen(); m_scene->app()->window()->toggleFullscreen();
} }
c->justCollided = false;
} }
// called once per frame // called once per frame
void CameraControllerSystem::onEvent(engine::PhysicsSystem::CollisionEvent info) void CameraControllerSystem::onEvent(engine::PhysicsSystem::CollisionEvent info)
{ {
INFO("NORMAL X: {}, Y: {}, Z: {}", info.normal.x, info.normal.y, info.normal.z); c->justCollided = info.isCollisionEnter;
t->position += info.normal; c->lastCollisionNormal = info.normal;
c->lastCollisionPoint = info.point;
} }

View File

@ -19,6 +19,9 @@ struct CameraControllerComponent {
float standingHeight = 0.0f; float standingHeight = 0.0f;
const float thrust = 25.0f; const float thrust = 25.0f;
glm::vec3 lastCollisionNormal{};
glm::vec3 lastCollisionPoint{};
bool justCollided = false;
}; };
class CameraControllerSystem : public engine::System, public engine::EventHandler<engine::PhysicsSystem::CollisionEvent> { class CameraControllerSystem : public engine::System, public engine::EventHandler<engine::PhysicsSystem::CollisionEvent> {

View File

@ -97,20 +97,20 @@ void playGame(bool enableFrameLimiter)
myScene->getComponent<engine::TransformComponent>(skybox)->position = { -1.0f, -1.0f, -1.0f }; myScene->getComponent<engine::TransformComponent>(skybox)->position = { -1.0f, -1.0f, -1.0f };
} }
/* enemy sphere */ /* enemy cube */
{ {
uint32_t enemy = myScene->createEntity("enemy"); uint32_t enemy = myScene->createEntity("enemy");
auto enemyRenderable = myScene->addComponent<engine::RenderableComponent>(enemy); auto enemyRenderable = myScene->addComponent<engine::RenderableComponent>(enemy);
enemyRenderable->material = std::make_unique<engine::resources::Material>(app.getResource<engine::resources::Shader>("engine.textured")); enemyRenderable->material = std::make_unique<engine::resources::Material>(app.getResource<engine::resources::Shader>("engine.textured"));
enemyRenderable->material->m_texture = app.getResource<engine::resources::Texture>("engine.white"); enemyRenderable->material->m_texture = app.getResource<engine::resources::Texture>("engine.white");
enemyRenderable->mesh = genSphereMesh(app.gfx(), 5.0f, 50, false); enemyRenderable->mesh = genCuboidMesh(app.gfx(), 10.0f, 10.0f, 10.0f);
auto enemyTransform = myScene->getComponent<engine::TransformComponent>(enemy); auto enemyTransform = myScene->getComponent<engine::TransformComponent>(enemy);
enemyTransform->position.x = 10.0f; enemyTransform->position.x = 10.0f;
enemyTransform->position.y = 0.0f; enemyTransform->position.y = 0.0f;
enemyTransform->position.z = 14.0f; enemyTransform->position.z = 14.0f;
auto enemyCollider = myScene->addComponent<engine::ColliderComponent>(enemy); auto enemyCollider = myScene->addComponent<engine::ColliderComponent>(enemy);
enemyCollider->isStatic = true; enemyCollider->isStatic = true;
enemyCollider->aabb = { { -5.0f, -5.0f, -5.0f }, { 5.0f, 5.0f, 5.0f } }; // A box enclosing the sphere enemyCollider->aabb = { { 0.0f, 0.0f, 0.0f }, { 10.0f, 10.0f, 10.0f } }; // A box enclosing the sphere
} }
/* floor */ /* floor */
@ -127,11 +127,13 @@ void playGame(bool enableFrameLimiter)
} }
// cubes! // cubes!
{ if (0) {
constexpr int SIZE = 10; constexpr int SIZE = 10;
const uint32_t cubeParent = myScene->createEntity("cubeParent"); const uint32_t cubeParent = myScene->createEntity("cubeParent");
myScene->getComponent<engine::TransformComponent>(cubeParent)->position = { 10.0f, 5.0f, 10.0f }; engine::TransformComponent* cubeParentTransform = myScene->getComponent<engine::TransformComponent>(cubeParent);
cubeParentTransform->position = { 100.0f, 0.0f, 100.0f };
cubeParentTransform->scale = { 100.0f, 100.0f, 100.0f };
std::shared_ptr<engine::resources::Mesh> cubeMesh = genCuboidMesh(app.gfx(), 0.1f, 0.1f, 0.1f); std::shared_ptr<engine::resources::Mesh> cubeMesh = genCuboidMesh(app.gfx(), 0.1f, 0.1f, 0.1f);
const auto cubeMaterial = std::make_shared<engine::resources::Material>(app.getResource<engine::resources::Shader>("engine.textured")); const auto cubeMaterial = std::make_shared<engine::resources::Material>(app.getResource<engine::resources::Shader>("engine.textured"));