add cubez

This commit is contained in:
Bailey Harrison 2023-02-09 20:44:37 +00:00
parent b23d6d0fe4
commit 0a0f4758b1
5 changed files with 97 additions and 28 deletions

View File

@ -15,14 +15,9 @@ namespace engine {
struct ColliderComponent { struct ColliderComponent {
friend PhysicsSystem; friend PhysicsSystem;
ColliderComponent()
{
}
bool isStatic = true; bool isStatic = true;
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{}; AABB aabb{}; // broad phase
bool getIsColliding() { return isColliding; } bool getIsColliding() { return isColliding; }

View File

@ -13,13 +13,6 @@ namespace engine {
static bool checkCollisionFast(AABB a, AABB b) static bool checkCollisionFast(AABB a, AABB b)
{ {
if (a.pos1.x > a.pos2.x) std::swap(a.pos1.x, a.pos2.x);
if (a.pos1.y > a.pos2.y) std::swap(a.pos1.y, a.pos2.y);
if (a.pos1.z > a.pos2.z) std::swap(a.pos1.z, a.pos2.z);
if (b.pos1.x > b.pos2.x) std::swap(b.pos1.x, b.pos2.x);
if (b.pos1.y > b.pos2.y) std::swap(b.pos1.y, b.pos2.y);
if (b.pos1.z > b.pos2.z) std::swap(b.pos1.z, b.pos2.z);
return ( return (
a.pos1.x <= b.pos2.x && a.pos1.x <= b.pos2.x &&
a.pos2.x >= b.pos1.x && a.pos2.x >= b.pos1.x &&
@ -30,6 +23,44 @@ namespace engine {
); );
} }
static glm::vec3 getAABBNormal(AABB subject, AABB object)
{
// get centre position of static entity:
glm::vec3 subjectCentre = subject.pos1 + ((subject.pos2 - subject.pos1) / glm::vec3{ 2.0f, 2.0f, 2.0f });
// find which face the centre is closest to:
const float PXdistance = glm::abs(subjectCentre.x - object.pos2.x);
const float NXdistance = glm::abs(subjectCentre.x - object.pos1.x);
const float PYdistance = glm::abs(subjectCentre.y - object.pos2.y);
const float NYdistance = glm::abs(subjectCentre.y - object.pos1.y);
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();
switch (index) {
case 0:
// P_X
return {1.0f, 0.0f, 0.0f};
case 1:
// N_X
return {-1.0f, 0.0f, 0.0f};
case 2:
// P_Y
return {0.0f, 1.0f, 0.0f};
case 3:
// N_Y
return {0.0f, -1.0f, 0.0f};
case 4:
// P_Z
return {0.0f, 0.0f, 1.0f};
case 5:
// N_Z
return {0.0f, 0.0f, -1.0f};
default:
throw std::runtime_error("wtf");
}
}
// class methods // class methods
PhysicsSystem::PhysicsSystem(Scene* scene) PhysicsSystem::PhysicsSystem(Scene* scene)
@ -68,6 +99,11 @@ namespace engine {
globalBoundingBox.pos1 = globalPosition + localBoundingBox.pos1; globalBoundingBox.pos1 = globalPosition + localBoundingBox.pos1;
globalBoundingBox.pos2 = globalPosition + localBoundingBox.pos2; globalBoundingBox.pos2 = globalPosition + localBoundingBox.pos2;
auto& a = globalBoundingBox;
if (a.pos1.x > a.pos2.x) std::swap(a.pos1.x, a.pos2.x);
if (a.pos1.y > a.pos2.y) std::swap(a.pos1.y, a.pos2.y);
if (a.pos1.z > a.pos2.z) std::swap(a.pos1.z, a.pos2.z);
if (c->isStatic) { if (c->isStatic) {
m_staticAABBs.emplace_back(std::make_tuple(entity, globalBoundingBox, c->isTrigger)); m_staticAABBs.emplace_back(std::make_tuple(entity, globalBoundingBox, c->isTrigger));
} else { } else {
@ -98,18 +134,20 @@ namespace engine {
CollisionEvent info{}; CollisionEvent info{};
info.isCollisionEnter = true; info.isCollisionEnter = true;
info.collidedEntity = possibleCollision.dynamicEntity; info.collidedEntity = possibleCollision.dynamicEntity;
info.normal = getAABBNormal(possibleCollision.staticAABB, possibleCollision.dynamicAABB);
m_collisionInfos.emplace_back(possibleCollision.staticEntity, info); m_collisionInfos.emplace_back(possibleCollision.staticEntity, info);
} }
if (possibleCollision.dynamicTrigger) { if (possibleCollision.dynamicTrigger) {
CollisionEvent info{}; CollisionEvent info{};
info.isCollisionEnter = true; info.isCollisionEnter = true;
info.collidedEntity = possibleCollision.staticEntity; info.collidedEntity = possibleCollision.staticEntity;
info.normal = getAABBNormal(possibleCollision.dynamicAABB, possibleCollision.staticAABB);
m_collisionInfos.emplace_back(possibleCollision.dynamicEntity, info); m_collisionInfos.emplace_back(possibleCollision.dynamicEntity, info);
} }
} }
for (auto [entity, info] : m_collisionInfos) { for (auto [entity, info] : m_collisionInfos) {
m_scene->events()->queueEvent(EventSubscriberKind::ENTITY, entity, info); m_scene->events()->queueEvent<CollisionEvent>(EventSubscriberKind::ENTITY, entity, info);
} }
} }

View File

@ -23,19 +23,17 @@ CameraControllerSystem::CameraControllerSystem(engine::Scene* scene)
void CameraControllerSystem::onUpdate(float ts) void CameraControllerSystem::onUpdate(float ts)
{ {
engine::TransformComponent* t = nullptr; if (t == nullptr || c == nullptr || col == nullptr) {
engine::ColliderComponent* col = nullptr; for (uint32_t entity : m_entities) {
CameraControllerComponent* c = nullptr; t = m_scene->getComponent<engine::TransformComponent>(entity);
for (uint32_t entity : m_entities) { col = m_scene->getComponent<engine::ColliderComponent>(entity);
t = m_scene->getComponent<engine::TransformComponent>(entity); c = m_scene->getComponent<CameraControllerComponent>(entity);
col = m_scene->getComponent<engine::ColliderComponent>(entity); break;
c = m_scene->getComponent<CameraControllerComponent>(entity); }
break; if (t == nullptr) return;
if (c == nullptr) return;
if (col == nullptr) return;
} }
if (t == nullptr) return;
if (c == nullptr) return;
if (col == nullptr) return;
// calculate new position // calculate new position
// use one unit per meter // use one unit per meter
@ -177,5 +175,6 @@ void CameraControllerSystem::onUpdate(float ts)
// called once per frame // called once per frame
void CameraControllerSystem::onEvent(engine::PhysicsSystem::CollisionEvent info) void CameraControllerSystem::onEvent(engine::PhysicsSystem::CollisionEvent info)
{ {
(void)info; INFO("NORMAL X: {}, Y: {}, Z: {}", info.normal.x, info.normal.y, info.normal.z);
t->position += info.normal;
} }

View File

@ -3,6 +3,7 @@
#include "ecs_system.hpp" #include "ecs_system.hpp"
#include "event_system.hpp" #include "event_system.hpp"
#include "components/transform.hpp"
#include "systems/collisions.hpp" #include "systems/collisions.hpp"
struct CameraControllerComponent { struct CameraControllerComponent {
@ -30,4 +31,8 @@ public:
// engine::EventHandler overrides // engine::EventHandler overrides
void onEvent(engine::PhysicsSystem::CollisionEvent info) override; void onEvent(engine::PhysicsSystem::CollisionEvent info) override;
engine::TransformComponent* t = nullptr;
engine::ColliderComponent* col = nullptr;
CameraControllerComponent* c = nullptr;
}; };

View File

@ -87,7 +87,7 @@ void playGame(bool enableFrameLimiter)
); );
/* skybox */ /* skybox */
if (0) { {
uint32_t skybox = myScene->createEntity("skybox"); uint32_t skybox = myScene->createEntity("skybox");
auto skyboxRenderable = myScene->addComponent<engine::RenderableComponent>(skybox); auto skyboxRenderable = myScene->addComponent<engine::RenderableComponent>(skybox);
skyboxRenderable->material = std::make_unique<engine::resources::Material>(app.getResource<engine::resources::Shader>("engine.skybox")); skyboxRenderable->material = std::make_unique<engine::resources::Material>(app.getResource<engine::resources::Shader>("engine.skybox"));
@ -126,6 +126,38 @@ void playGame(bool enableFrameLimiter)
floorCollider->aabb = { { 0.0f, 0.0f, 0.0f }, { 100.0f, 0.1f, 100.0f } }; floorCollider->aabb = { { 0.0f, 0.0f, 0.0f }, { 100.0f, 0.1f, 100.0f } };
} }
// cubes!
{
constexpr int SIZE = 10;
const uint32_t cubeParent = myScene->createEntity("cubeParent");
myScene->getComponent<engine::TransformComponent>(cubeParent)->position = { 10.0f, 5.0f, 10.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"));
cubeMaterial->m_texture = app.getResource<engine::resources::Texture>("engine.white");
uint32_t cubes[SIZE][SIZE][SIZE];
for (int x = 0; x < SIZE; x++) {
for (int y = 0; y < SIZE; y++) {
for (int z = 0; z < SIZE; z++) {
const uint32_t cube = myScene->createEntity("cube" + std::to_string(x * 100 + y * 10 + z), cubeParent);
auto transform = myScene->getComponent<engine::TransformComponent>(cube);
auto renderable = myScene->addComponent<engine::RenderableComponent>(cube);
transform->position = { (float)x, (float)y, (float)z };
renderable->mesh = cubeMesh;
renderable->material = cubeMaterial;
cubes[x][y][z] = cube;
}
}
}
(void)cubes;
}
app.gameLoop(); app.gameLoop();
} }