mirror of
https://github.com/bailwillharr/engine.git
synced 2024-09-21 04:51:18 +00:00
Add basic sphere collision testing
This commit is contained in:
parent
17f513d30f
commit
0a39baea20
@ -16,6 +16,7 @@ set(SRC_FILES
|
|||||||
|
|
||||||
"src/systems/transform.cpp"
|
"src/systems/transform.cpp"
|
||||||
"src/systems/render.cpp"
|
"src/systems/render.cpp"
|
||||||
|
"src/systems/physics.cpp"
|
||||||
|
|
||||||
"src/resources/shader.cpp"
|
"src/resources/shader.cpp"
|
||||||
"src/resources/material.cpp"
|
"src/resources/material.cpp"
|
||||||
@ -43,6 +44,7 @@ set(INCLUDE_FILES
|
|||||||
|
|
||||||
"include/systems/transform.hpp"
|
"include/systems/transform.hpp"
|
||||||
"include/systems/render.hpp"
|
"include/systems/render.hpp"
|
||||||
|
"include/systems/physics.hpp"
|
||||||
|
|
||||||
"include/resources/shader.hpp"
|
"include/resources/shader.hpp"
|
||||||
"include/resources/material.hpp"
|
"include/resources/material.hpp"
|
||||||
@ -66,6 +68,7 @@ set(INCLUDE_FILES
|
|||||||
|
|
||||||
"include/components/transform.hpp"
|
"include/components/transform.hpp"
|
||||||
"include/components/renderable.hpp"
|
"include/components/renderable.hpp"
|
||||||
|
"include/components/collider.hpp"
|
||||||
)
|
)
|
||||||
|
|
||||||
add_library(${PROJECT_NAME} STATIC
|
add_library(${PROJECT_NAME} STATIC
|
||||||
|
22
include/components/collider.hpp
Normal file
22
include/components/collider.hpp
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace engine {
|
||||||
|
|
||||||
|
class PhysicsSystem;
|
||||||
|
|
||||||
|
struct ColliderComponent {
|
||||||
|
friend PhysicsSystem;
|
||||||
|
|
||||||
|
float r;
|
||||||
|
|
||||||
|
bool getIsColliding() { return m_isColliding; }
|
||||||
|
bool getJustCollided() { return m_justCollided; }
|
||||||
|
bool getJustUncollided() { return m_justUncollided; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool m_isColliding;
|
||||||
|
bool m_justCollided;
|
||||||
|
bool m_justUncollided;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
@ -12,6 +12,7 @@ namespace engine {
|
|||||||
struct RenderableComponent {
|
struct RenderableComponent {
|
||||||
std::shared_ptr<resources::Mesh> mesh;
|
std::shared_ptr<resources::Mesh> mesh;
|
||||||
std::shared_ptr<resources::Material> material;
|
std::shared_ptr<resources::Material> material;
|
||||||
|
bool shown = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
17
include/systems/physics.hpp
Normal file
17
include/systems/physics.hpp
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "ecs_system.hpp"
|
||||||
|
|
||||||
|
namespace engine {
|
||||||
|
|
||||||
|
class PhysicsSystem : public System {
|
||||||
|
|
||||||
|
public:
|
||||||
|
PhysicsSystem(Scene* scene);
|
||||||
|
|
||||||
|
void onUpdate(float ts) override;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -2,8 +2,10 @@
|
|||||||
|
|
||||||
#include "components/transform.hpp"
|
#include "components/transform.hpp"
|
||||||
#include "components/renderable.hpp"
|
#include "components/renderable.hpp"
|
||||||
|
#include "components/collider.hpp"
|
||||||
#include "systems/transform.hpp"
|
#include "systems/transform.hpp"
|
||||||
#include "systems/render.hpp"
|
#include "systems/render.hpp"
|
||||||
|
#include "systems/physics.hpp"
|
||||||
|
|
||||||
namespace engine {
|
namespace engine {
|
||||||
|
|
||||||
@ -12,7 +14,11 @@ namespace engine {
|
|||||||
{
|
{
|
||||||
registerComponent<TransformComponent>();
|
registerComponent<TransformComponent>();
|
||||||
registerComponent<RenderableComponent>();
|
registerComponent<RenderableComponent>();
|
||||||
|
registerComponent<ColliderComponent>();
|
||||||
|
|
||||||
|
// Order here matters:
|
||||||
registerSystem<TransformSystem>();
|
registerSystem<TransformSystem>();
|
||||||
|
registerSystem<PhysicsSystem>();
|
||||||
registerSystem<RenderSystem>();
|
registerSystem<RenderSystem>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
97
src/systems/physics.cpp
Normal file
97
src/systems/physics.cpp
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
#include "systems/physics.hpp"
|
||||||
|
|
||||||
|
#include "components/transform.hpp"
|
||||||
|
#include "components/collider.hpp"
|
||||||
|
#include "components/renderable.hpp"
|
||||||
|
#include "scene.hpp"
|
||||||
|
|
||||||
|
#include "log.hpp"
|
||||||
|
|
||||||
|
namespace engine {
|
||||||
|
|
||||||
|
PhysicsSystem::PhysicsSystem(Scene* scene)
|
||||||
|
: System(scene, { typeid(TransformComponent).hash_code(), typeid(ColliderComponent).hash_code() })
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void PhysicsSystem::onUpdate(float ts)
|
||||||
|
{
|
||||||
|
(void)ts;
|
||||||
|
|
||||||
|
using glm::vec3;
|
||||||
|
|
||||||
|
struct CollisionInfo {
|
||||||
|
uint32_t entity;
|
||||||
|
TransformComponent* t;
|
||||||
|
ColliderComponent* c;
|
||||||
|
|
||||||
|
vec3 pos;
|
||||||
|
|
||||||
|
bool wasColliding;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::vector<CollisionInfo> entityColliders(m_entities.size());
|
||||||
|
|
||||||
|
uint32_t i = 0;
|
||||||
|
for (uint32_t entity : m_entities) {
|
||||||
|
auto t = m_scene->getComponent<TransformComponent>(entity);
|
||||||
|
auto c = m_scene->getComponent<ColliderComponent>(entity);
|
||||||
|
|
||||||
|
entityColliders[i].entity = entity;
|
||||||
|
entityColliders[i].t = t;
|
||||||
|
entityColliders[i].c = c;
|
||||||
|
|
||||||
|
entityColliders[i].wasColliding = c->getIsColliding();
|
||||||
|
c->m_isColliding = false;
|
||||||
|
c->m_justCollided = false;
|
||||||
|
c->m_justUncollided = false;
|
||||||
|
|
||||||
|
vec3 pos = reinterpret_cast<vec3&>(t->worldMatrix[3]);
|
||||||
|
entityColliders[i].pos = pos;
|
||||||
|
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (size_t i = 0; i < entityColliders.size(); i++) {
|
||||||
|
for (size_t j = i + 1; j < entityColliders.size(); j++) {
|
||||||
|
const vec3 v = entityColliders[i].pos - entityColliders[j].pos;
|
||||||
|
const float distanceSquared = v.x * v.x + v.y * v.y + v.z * v.z;
|
||||||
|
const float sumOfRadii = entityColliders[i].c->r + entityColliders[j].c->r;
|
||||||
|
const float sumOfRadiiSquared = sumOfRadii * sumOfRadii;
|
||||||
|
|
||||||
|
if (distanceSquared < sumOfRadiiSquared) {
|
||||||
|
entityColliders[i].c->m_isColliding = true;
|
||||||
|
entityColliders[j].c->m_isColliding = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (entityColliders[i].wasColliding != entityColliders[i].c->getIsColliding()) {
|
||||||
|
if (entityColliders[i].c->getIsColliding()) {
|
||||||
|
entityColliders[i].c->m_justCollided = true;
|
||||||
|
} else {
|
||||||
|
entityColliders[i].c->m_justUncollided = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (entityColliders[i].c->getJustCollided()) {
|
||||||
|
TRACE("'{}' has collided!", entityColliders[i].t->tag);
|
||||||
|
auto r = m_scene->getComponent<RenderableComponent>(entityColliders[i].entity);
|
||||||
|
if (r != nullptr) {
|
||||||
|
r->shown = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (entityColliders[i].c->getJustUncollided()) {
|
||||||
|
TRACE("'{}' has stopped colliding!", entityColliders[i].t->tag);
|
||||||
|
auto r = m_scene->getComponent<RenderableComponent>(entityColliders[i].entity);
|
||||||
|
if (r != nullptr) {
|
||||||
|
r->shown = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -48,8 +48,10 @@ namespace engine {
|
|||||||
|
|
||||||
for (uint32_t entity : m_entities) {
|
for (uint32_t entity : m_entities) {
|
||||||
|
|
||||||
auto t = m_scene->getComponent<TransformComponent>(entity);
|
|
||||||
auto r = m_scene->getComponent<RenderableComponent>(entity);
|
auto r = m_scene->getComponent<RenderableComponent>(entity);
|
||||||
|
if (r->shown == false) continue;
|
||||||
|
|
||||||
|
auto t = m_scene->getComponent<TransformComponent>(entity);
|
||||||
|
|
||||||
assert(r->material != nullptr);
|
assert(r->material != nullptr);
|
||||||
assert(r->mesh != nullptr);
|
assert(r->mesh != nullptr);
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
#include "scene.hpp"
|
#include "scene.hpp"
|
||||||
|
|
||||||
#include "components/transform.hpp"
|
#include "components/transform.hpp"
|
||||||
|
#include "components/collider.hpp"
|
||||||
#include "components/renderable.hpp"
|
#include "components/renderable.hpp"
|
||||||
|
|
||||||
#include "systems/transform.hpp"
|
#include "systems/transform.hpp"
|
||||||
@ -76,6 +77,9 @@ void playGame()
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// scene setup
|
||||||
|
|
||||||
auto myScene = app.sceneManager()->createEmptyScene();
|
auto myScene = app.sceneManager()->createEmptyScene();
|
||||||
|
|
||||||
myScene->registerComponent<RotateComponent>();
|
myScene->registerComponent<RotateComponent>();
|
||||||
@ -87,8 +91,13 @@ void playGame()
|
|||||||
myScene->registerResourceManager<engine::resources::Shader>();
|
myScene->registerResourceManager<engine::resources::Shader>();
|
||||||
myScene->registerResourceManager<engine::resources::Texture>();
|
myScene->registerResourceManager<engine::resources::Texture>();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
auto camera = myScene->createEntity("camera");
|
auto camera = myScene->createEntity("camera");
|
||||||
myScene->addComponent<CameraControllerComponent>(camera)->standingHeight = myScene->getComponent<engine::TransformComponent>(camera)->position.y = 2.0f;
|
myScene->addComponent<CameraControllerComponent>(camera)->standingHeight = myScene->getComponent<engine::TransformComponent>(camera)->position.y = 2.0f;
|
||||||
|
myScene->addComponent<engine::ColliderComponent>(camera)->r = 1.0f;
|
||||||
myScene->getSystem<engine::RenderSystem>()->setCameraEntity(camera);
|
myScene->getSystem<engine::RenderSystem>()->setCameraEntity(camera);
|
||||||
|
|
||||||
engine::resources::Shader::VertexParams vertParams{};
|
engine::resources::Shader::VertexParams vertParams{};
|
||||||
@ -110,7 +119,22 @@ void playGame()
|
|||||||
auto keepShader = myScene->addResource<engine::resources::Shader>("theShader", std::move(theShader));
|
auto keepShader = myScene->addResource<engine::resources::Shader>("theShader", std::move(theShader));
|
||||||
|
|
||||||
// uint32_t astronaut = engine::util::loadMeshFromFile(myScene, app.getResourcePath("models/astronaut/astronaut.dae"));
|
// uint32_t astronaut = engine::util::loadMeshFromFile(myScene, app.getResourcePath("models/astronaut/astronaut.dae"));
|
||||||
// myScene->addComponent<RotateComponent>(astronaut);
|
|
||||||
|
auto grassTexture = std::make_shared<engine::resources::Texture>(
|
||||||
|
app.gfx(),
|
||||||
|
app.getResourcePath("textures/grass.jpg")
|
||||||
|
);
|
||||||
|
|
||||||
|
uint32_t enemy = myScene->createEntity("enemy");
|
||||||
|
auto enemyRenderable = myScene->addComponent<engine::RenderableComponent>(enemy);
|
||||||
|
enemyRenderable->material = std::make_unique<engine::resources::Material>(keepShader);
|
||||||
|
enemyRenderable->material->m_texture = grassTexture;
|
||||||
|
enemyRenderable->mesh = genSphereMesh(app.gfx(), 2.0f, 30, false);
|
||||||
|
auto enemyT = myScene->getComponent<engine::TransformComponent>(enemy);
|
||||||
|
enemyT->position.x += 5.0f;
|
||||||
|
enemyT->position.y += 2.0f;
|
||||||
|
enemyT->position.z += 3.0f;
|
||||||
|
myScene->addComponent<engine::ColliderComponent>(enemy)->r = 10.0f;
|
||||||
|
|
||||||
uint32_t sphere = myScene->createEntity("sphere");
|
uint32_t sphere = myScene->createEntity("sphere");
|
||||||
auto sphereRenderable = myScene->addComponent<engine::RenderableComponent>(sphere);
|
auto sphereRenderable = myScene->addComponent<engine::RenderableComponent>(sphere);
|
||||||
@ -122,19 +146,16 @@ void playGame()
|
|||||||
myScene->getComponent<engine::TransformComponent>(light)->position = glm::vec3{-10.0f, 10.0f, 10.0f};
|
myScene->getComponent<engine::TransformComponent>(light)->position = glm::vec3{-10.0f, 10.0f, 10.0f};
|
||||||
auto lightRenderable = myScene->addComponent<engine::RenderableComponent>(light);
|
auto lightRenderable = myScene->addComponent<engine::RenderableComponent>(light);
|
||||||
lightRenderable->material = sphereRenderable->material;
|
lightRenderable->material = sphereRenderable->material;
|
||||||
lightRenderable->mesh = genSphereMesh(app.gfx(), 0.5f, 10, false, true);
|
lightRenderable->mesh = genSphereMesh(app.gfx(), 0.5f, 40, false, true);
|
||||||
|
|
||||||
uint32_t floor = myScene->createEntity("floor");
|
uint32_t floor = myScene->createEntity("floor");
|
||||||
myScene->getComponent<engine::TransformComponent>(floor)->position = glm::vec3{-50.0f, -0.1f, -50.0f};
|
myScene->getComponent<engine::TransformComponent>(floor)->position = glm::vec3{-50.0f, -0.1f, -50.0f};
|
||||||
auto floorRenderable = myScene->addComponent<engine::RenderableComponent>(floor);
|
auto floorRenderable = myScene->addComponent<engine::RenderableComponent>(floor);
|
||||||
floorRenderable->material = std::make_shared<engine::resources::Material>(*sphereRenderable->material);
|
floorRenderable->material = std::make_shared<engine::resources::Material>(*sphereRenderable->material);
|
||||||
auto grassTexture = std::make_unique<engine::resources::Texture>(
|
floorRenderable->material->m_texture = grassTexture;
|
||||||
app.gfx(),
|
|
||||||
app.getResourcePath("textures/grass.jpg")
|
|
||||||
);
|
|
||||||
floorRenderable->material->m_texture = std::move(grassTexture);
|
|
||||||
floorRenderable->mesh = genCuboidMesh(app.gfx(), 100.0f, 0.1f, 100.0f);
|
floorRenderable->mesh = genCuboidMesh(app.gfx(), 100.0f, 0.1f, 100.0f);
|
||||||
|
|
||||||
|
|
||||||
app.gameLoop();
|
app.gameLoop();
|
||||||
|
|
||||||
INFO("texture addr: {}, shader addr: {}", (void*)keepTexture->getHandle(), (void*)keepShader->getPipeline());
|
INFO("texture addr: {}, shader addr: {}", (void*)keepTexture->getHandle(), (void*)keepShader->getPipeline());
|
||||||
|
Loading…
Reference in New Issue
Block a user