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/render.cpp"
|
||||
"src/systems/physics.cpp"
|
||||
|
||||
"src/resources/shader.cpp"
|
||||
"src/resources/material.cpp"
|
||||
@ -43,6 +44,7 @@ set(INCLUDE_FILES
|
||||
|
||||
"include/systems/transform.hpp"
|
||||
"include/systems/render.hpp"
|
||||
"include/systems/physics.hpp"
|
||||
|
||||
"include/resources/shader.hpp"
|
||||
"include/resources/material.hpp"
|
||||
@ -66,6 +68,7 @@ set(INCLUDE_FILES
|
||||
|
||||
"include/components/transform.hpp"
|
||||
"include/components/renderable.hpp"
|
||||
"include/components/collider.hpp"
|
||||
)
|
||||
|
||||
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 {
|
||||
std::shared_ptr<resources::Mesh> mesh;
|
||||
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/renderable.hpp"
|
||||
#include "components/collider.hpp"
|
||||
#include "systems/transform.hpp"
|
||||
#include "systems/render.hpp"
|
||||
#include "systems/physics.hpp"
|
||||
|
||||
namespace engine {
|
||||
|
||||
@ -12,7 +14,11 @@ namespace engine {
|
||||
{
|
||||
registerComponent<TransformComponent>();
|
||||
registerComponent<RenderableComponent>();
|
||||
registerComponent<ColliderComponent>();
|
||||
|
||||
// Order here matters:
|
||||
registerSystem<TransformSystem>();
|
||||
registerSystem<PhysicsSystem>();
|
||||
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) {
|
||||
|
||||
auto t = m_scene->getComponent<TransformComponent>(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->mesh != nullptr);
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include "scene.hpp"
|
||||
|
||||
#include "components/transform.hpp"
|
||||
#include "components/collider.hpp"
|
||||
#include "components/renderable.hpp"
|
||||
|
||||
#include "systems/transform.hpp"
|
||||
@ -76,6 +77,9 @@ void playGame()
|
||||
|
||||
|
||||
|
||||
|
||||
// scene setup
|
||||
|
||||
auto myScene = app.sceneManager()->createEmptyScene();
|
||||
|
||||
myScene->registerComponent<RotateComponent>();
|
||||
@ -87,8 +91,13 @@ void playGame()
|
||||
myScene->registerResourceManager<engine::resources::Shader>();
|
||||
myScene->registerResourceManager<engine::resources::Texture>();
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
auto camera = myScene->createEntity("camera");
|
||||
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);
|
||||
|
||||
engine::resources::Shader::VertexParams vertParams{};
|
||||
@ -110,7 +119,22 @@ void playGame()
|
||||
auto keepShader = myScene->addResource<engine::resources::Shader>("theShader", std::move(theShader));
|
||||
|
||||
// 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");
|
||||
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};
|
||||
auto lightRenderable = myScene->addComponent<engine::RenderableComponent>(light);
|
||||
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");
|
||||
myScene->getComponent<engine::TransformComponent>(floor)->position = glm::vec3{-50.0f, -0.1f, -50.0f};
|
||||
auto floorRenderable = myScene->addComponent<engine::RenderableComponent>(floor);
|
||||
floorRenderable->material = std::make_shared<engine::resources::Material>(*sphereRenderable->material);
|
||||
auto grassTexture = std::make_unique<engine::resources::Texture>(
|
||||
app.gfx(),
|
||||
app.getResourcePath("textures/grass.jpg")
|
||||
);
|
||||
floorRenderable->material->m_texture = std::move(grassTexture);
|
||||
floorRenderable->material->m_texture = grassTexture;
|
||||
floorRenderable->mesh = genCuboidMesh(app.gfx(), 100.0f, 0.1f, 100.0f);
|
||||
|
||||
|
||||
app.gameLoop();
|
||||
|
||||
INFO("texture addr: {}, shader addr: {}", (void*)keepTexture->getHandle(), (void*)keepShader->getPipeline());
|
||||
|
Loading…
Reference in New Issue
Block a user