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
AABB aabb{}; // broad phase
bool getIsColliding() { return isColliding; }
private:
bool isColliding = false;
};
}

View File

@ -21,6 +21,7 @@ namespace engine {
bool isCollisionEnter; // false == collision exit
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 point; // where the collision was detected
};
private:

View File

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

View File

@ -40,13 +40,12 @@ void CameraControllerSystem::onUpdate(float ts)
const float dt = ts;
/*
constexpr float G = 9.8f;
// 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 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;
@ -55,22 +54,22 @@ void CameraControllerSystem::onUpdate(float ts)
bool isSliding = false;
if (col->getIsColliding()) {
if (c->justCollided) {
if (slope > MAX_SLOPE_ANGLE) {
// slide across wall
isSliding = true;
} else {
if (c->dy < 0.0f && c->isGrounded == false) {
// in the ground, push up a bit
float floorY = col->getLastCollisionPoint().y;
t->position.y = floorY + col->colliders.sphereCollider.r - FLOOR_SINK_LEVEL;
float floorY = c->lastCollisionPoint.y;
t->position.y = floorY + 1.5f - FLOOR_SINK_LEVEL;
c->dy = 0.0f;
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
c->isGrounded = false;
}
@ -88,15 +87,10 @@ void CameraControllerSystem::onUpdate(float ts)
c->dy += dt * c->thrust;
}
*/
// in metres per second
float SPEED = c->walk_speed;
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 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 d2zRotated = glm::rotateY(glm::vec3{ 0.0f, 0.0f, dz }, c->m_yaw);
glm::vec3 hVel = (d2xRotated + d2zRotated);
/* if (isSliding) {
if (isSliding) {
hVel = glm::vec3{norm.z, 0.0f, -norm.x};
}
*/
hVel *= SPEED;
t->position += hVel * dt;
t->position.y += c->dy * dt;
@ -170,11 +163,14 @@ void CameraControllerSystem::onUpdate(float ts)
m_scene->app()->window()->toggleFullscreen();
}
c->justCollided = false;
}
// called once per frame
void CameraControllerSystem::onEvent(engine::PhysicsSystem::CollisionEvent info)
{
INFO("NORMAL X: {}, Y: {}, Z: {}", info.normal.x, info.normal.y, info.normal.z);
t->position += info.normal;
c->justCollided = info.isCollisionEnter;
c->lastCollisionNormal = info.normal;
c->lastCollisionPoint = info.point;
}

View File

@ -19,6 +19,9 @@ struct CameraControllerComponent {
float standingHeight = 0.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> {

View File

@ -97,20 +97,20 @@ void playGame(bool enableFrameLimiter)
myScene->getComponent<engine::TransformComponent>(skybox)->position = { -1.0f, -1.0f, -1.0f };
}
/* enemy sphere */
/* enemy cube */
{
uint32_t enemy = myScene->createEntity("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->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);
enemyTransform->position.x = 10.0f;
enemyTransform->position.y = 0.0f;
enemyTransform->position.z = 14.0f;
auto enemyCollider = myScene->addComponent<engine::ColliderComponent>(enemy);
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 */
@ -127,11 +127,13 @@ void playGame(bool enableFrameLimiter)
}
// cubes!
{
if (0) {
constexpr int SIZE = 10;
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);
const auto cubeMaterial = std::make_shared<engine::resources::Material>(app.getResource<engine::resources::Shader>("engine.textured"));