mirror of
https://github.com/bailwillharr/engine.git
synced 2024-09-21 04:51:18 +00:00
Try add player collision
This commit is contained in:
parent
adb47d810c
commit
2985a3af81
@ -4,10 +4,21 @@ namespace engine {
|
|||||||
|
|
||||||
class PhysicsSystem;
|
class PhysicsSystem;
|
||||||
|
|
||||||
|
enum class ColliderType {
|
||||||
|
SPHERE,
|
||||||
|
PLANE,
|
||||||
|
};
|
||||||
|
|
||||||
struct ColliderComponent {
|
struct ColliderComponent {
|
||||||
friend PhysicsSystem;
|
friend PhysicsSystem;
|
||||||
|
|
||||||
float r;
|
ColliderType colliderType;
|
||||||
|
|
||||||
|
union {
|
||||||
|
struct {
|
||||||
|
float r;
|
||||||
|
} sphereCollider;
|
||||||
|
} colliders;
|
||||||
|
|
||||||
bool getIsColliding() { return m_isColliding; }
|
bool getIsColliding() { return m_isColliding; }
|
||||||
bool getJustCollided() { return m_justCollided; }
|
bool getJustCollided() { return m_justCollided; }
|
||||||
|
@ -22,7 +22,7 @@ namespace engine {
|
|||||||
struct {
|
struct {
|
||||||
// only uses transform component, which is required for all entities anyway
|
// only uses transform component, which is required for all entities anyway
|
||||||
uint32_t camEntity = 0;
|
uint32_t camEntity = 0;
|
||||||
float horizontalFovDegrees = 70.0f;
|
float verticalFovDegrees = 70.0f;
|
||||||
float clipNear = 0.1f;
|
float clipNear = 0.1f;
|
||||||
float clipFar = 1000.0f;
|
float clipFar = 1000.0f;
|
||||||
} m_camera;
|
} m_camera;
|
||||||
|
@ -54,36 +54,64 @@ namespace engine {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (size_t i = 0; i < entityColliders.size(); i++) {
|
for (size_t i = 0; i < entityColliders.size(); i++) {
|
||||||
|
auto* ec1 = &entityColliders[i];
|
||||||
|
|
||||||
for (size_t j = i + 1; j < entityColliders.size(); j++) {
|
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) {
|
auto* ec2 = &entityColliders[j];
|
||||||
entityColliders[i].c->m_isColliding = true;
|
|
||||||
entityColliders[j].c->m_isColliding = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (entityColliders[i].wasColliding != entityColliders[i].c->getIsColliding()) {
|
if ( ec1->c->colliderType == ColliderType::SPHERE &&
|
||||||
if (entityColliders[i].c->getIsColliding()) {
|
ec2->c->colliderType == ColliderType::SPHERE ) {
|
||||||
entityColliders[i].c->m_justCollided = true;
|
const vec3 v = ec1->pos - ec2->pos;
|
||||||
|
const float distanceSquared = v.x * v.x + v.y * v.y + v.z * v.z;
|
||||||
|
const float sumOfRadii = ec1->c->colliders.sphereCollider.r + ec2->c->colliders.sphereCollider.r;
|
||||||
|
const float sumOfRadiiSquared = sumOfRadii * sumOfRadii;
|
||||||
|
if (distanceSquared < sumOfRadiiSquared) {
|
||||||
|
ec1->c->m_isColliding = true;
|
||||||
|
ec2->c->m_isColliding = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if ( (ec1->c->colliderType == ColliderType::PLANE &&
|
||||||
|
ec2->c->colliderType == ColliderType::SPHERE) ||
|
||||||
|
(ec1->c->colliderType == ColliderType::SPHERE &&
|
||||||
|
ec2->c->colliderType == ColliderType::PLANE)) {
|
||||||
|
CollisionInfo *plane, *sphere;
|
||||||
|
if (ec1->c->colliderType == ColliderType::PLANE) {
|
||||||
|
plane = ec1;
|
||||||
|
sphere = ec2;
|
||||||
|
} else {
|
||||||
|
sphere = ec1;
|
||||||
|
plane = ec2;
|
||||||
|
}
|
||||||
|
float distance = plane->pos.y - sphere->pos.y;
|
||||||
|
if (distance < 0.0f) distance = -distance; // make positive
|
||||||
|
if (distance < sphere->c->colliders.sphereCollider.r) {
|
||||||
|
plane->c->m_isColliding = true;
|
||||||
|
sphere->c->m_isColliding = true;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
entityColliders[i].c->m_justUncollided = true;
|
throw std::runtime_error("Collision combination not supported!");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (entityColliders[i].c->getJustCollided()) {
|
if (ec1->wasColliding != ec1->c->getIsColliding()) {
|
||||||
TRACE("'{}' has collided!", entityColliders[i].t->tag);
|
if (ec1->c->getIsColliding()) {
|
||||||
auto r = m_scene->getComponent<RenderableComponent>(entityColliders[i].entity);
|
ec1->c->m_justCollided = true;
|
||||||
|
} else {
|
||||||
|
ec1->c->m_justUncollided = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ec1->c->getJustCollided()) {
|
||||||
|
TRACE("'{}' has collided!", ec1->t->tag);
|
||||||
|
auto r = m_scene->getComponent<RenderableComponent>(ec1->entity);
|
||||||
if (r != nullptr) {
|
if (r != nullptr) {
|
||||||
r->shown = true;
|
r->shown = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (entityColliders[i].c->getJustUncollided()) {
|
if (ec1->c->getJustUncollided()) {
|
||||||
TRACE("'{}' has stopped colliding!", entityColliders[i].t->tag);
|
TRACE("'{}' has stopped colliding!", ec1->t->tag);
|
||||||
auto r = m_scene->getComponent<RenderableComponent>(entityColliders[i].entity);
|
auto r = m_scene->getComponent<RenderableComponent>(ec1->entity);
|
||||||
if (r != nullptr) {
|
if (r != nullptr) {
|
||||||
r->shown = false;
|
r->shown = false;
|
||||||
}
|
}
|
||||||
|
@ -40,9 +40,10 @@ namespace engine {
|
|||||||
gfx->getViewportSize(&w, &h);
|
gfx->getViewportSize(&w, &h);
|
||||||
m_viewportAspectRatio = (float)w / (float)h;
|
m_viewportAspectRatio = (float)w / (float)h;
|
||||||
}
|
}
|
||||||
const float horizontalFovRadians = glm::radians(m_camera.horizontalFovDegrees);
|
const float verticalFovRadians = glm::radians(m_camera.verticalFovDegrees);
|
||||||
const float verticalFov = glm::atan( glm::tan(horizontalFovRadians / 2.0f) / m_viewportAspectRatio ) * 2.0f;
|
// const float horizontalFovRadians = glm::radians(m_camera.horizontalFovDegrees);
|
||||||
const glm::mat4 projMatrix = glm::perspectiveZO(verticalFov, m_viewportAspectRatio, m_camera.clipNear, m_camera.clipFar);
|
// const float verticalFov = glm::atan( glm::tan(horizontalFovRadians / 2.0f) / m_viewportAspectRatio ) * 2.0f;
|
||||||
|
const glm::mat4 projMatrix = glm::perspectiveZO(verticalFovRadians, m_viewportAspectRatio, m_camera.clipNear, m_camera.clipFar);
|
||||||
|
|
||||||
/* render all renderable entities */
|
/* render all renderable entities */
|
||||||
|
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
#include "scene.hpp"
|
#include "scene.hpp"
|
||||||
|
|
||||||
#include "components/transform.hpp"
|
#include "components/transform.hpp"
|
||||||
|
#include "components/collider.hpp"
|
||||||
|
|
||||||
#include <glm/trigonometric.hpp>
|
#include <glm/trigonometric.hpp>
|
||||||
#include <glm/gtc/constants.hpp>
|
#include <glm/gtc/constants.hpp>
|
||||||
@ -23,14 +24,17 @@ void CameraControllerSystem::onUpdate(float ts)
|
|||||||
{
|
{
|
||||||
|
|
||||||
engine::TransformComponent* t = nullptr;
|
engine::TransformComponent* t = nullptr;
|
||||||
|
engine::ColliderComponent* col = nullptr;
|
||||||
CameraControllerComponent* c = nullptr;
|
CameraControllerComponent* c = nullptr;
|
||||||
for (uint32_t entity : m_entities) {
|
for (uint32_t entity : m_entities) {
|
||||||
t = m_scene->getComponent<engine::TransformComponent>(entity);
|
t = m_scene->getComponent<engine::TransformComponent>(entity);
|
||||||
|
col = m_scene->getComponent<engine::ColliderComponent>(entity);
|
||||||
c = m_scene->getComponent<CameraControllerComponent>(entity);
|
c = m_scene->getComponent<CameraControllerComponent>(entity);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (t == nullptr) return;
|
if (t == nullptr) return;
|
||||||
if (c == nullptr) return;
|
if (c == nullptr) return;
|
||||||
|
if (col == nullptr) return;
|
||||||
|
|
||||||
// calculate new position
|
// calculate new position
|
||||||
|
|
||||||
@ -48,23 +52,26 @@ void CameraControllerSystem::onUpdate(float ts)
|
|||||||
if (m_scene->app()->inputManager()->getButton("jump") && c->isJumping == false) {
|
if (m_scene->app()->inputManager()->getButton("jump") && c->isJumping == false) {
|
||||||
c->isJumping = true;
|
c->isJumping = true;
|
||||||
c->dy = JUMPVEL;
|
c->dy = JUMPVEL;
|
||||||
//standingHeight = tcomp->position.y;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (c->isJumping) {
|
if (c->isJumping) {
|
||||||
c->dy -= G * dt;
|
c->dy -= G * dt;
|
||||||
t->position.y += c->dy * dt;
|
if (col->getIsColliding()) {
|
||||||
if (t->position.y < c->standingHeight) {
|
|
||||||
c->isJumping = false;
|
c->isJumping = false;
|
||||||
c->dy = 0.0f;
|
c->dy = 0.0f;
|
||||||
t->position.y = c->standingHeight;
|
}
|
||||||
|
} else {
|
||||||
|
if (col->getIsColliding()) {
|
||||||
|
c->dy = -c->dy;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (col->getJustUncollided()) {
|
||||||
|
c->isJumping = true;
|
||||||
|
}
|
||||||
|
// c->dy -= c->dy * dt; // damp velocity
|
||||||
|
|
||||||
if (m_scene->app()->window()->getButton(engine::inputs::MouseButton::M_LEFT)) {
|
if (m_scene->app()->window()->getButton(engine::inputs::MouseButton::M_LEFT)) {
|
||||||
//standingHeight = tcomp->position.y;
|
|
||||||
c->dy += dt * c->thrust;
|
c->dy += dt * c->thrust;
|
||||||
c->isJumping = true;
|
c->isJumping = true;
|
||||||
}
|
}
|
||||||
@ -98,9 +105,9 @@ void CameraControllerSystem::onUpdate(float ts)
|
|||||||
constexpr float MAX_DISTANCE_FROM_ORIGIN = 1000.0f;
|
constexpr float MAX_DISTANCE_FROM_ORIGIN = 1000.0f;
|
||||||
|
|
||||||
if (glm::length(t->position) > MAX_DISTANCE_FROM_ORIGIN) {
|
if (glm::length(t->position) > MAX_DISTANCE_FROM_ORIGIN) {
|
||||||
t->position = { 0.0f, c->standingHeight, 0.0f };
|
t->position = { 0.0f, 5.0f, 0.0f };
|
||||||
c->dy = 0.0f;
|
c->dy = 0.0f;
|
||||||
c->isJumping = false;
|
c->isJumping = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ROTATION STUFF */
|
/* ROTATION STUFF */
|
||||||
|
@ -14,6 +14,7 @@ struct CameraControllerComponent {
|
|||||||
float dy = 0.0f;
|
float dy = 0.0f;
|
||||||
float standingHeight = 0.0f;
|
float standingHeight = 0.0f;
|
||||||
const float thrust = 25.0f;
|
const float thrust = 25.0f;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class CameraControllerSystem : public engine::System {
|
class CameraControllerSystem : public engine::System {
|
||||||
|
@ -53,8 +53,11 @@ void playGame()
|
|||||||
myScene->registerSystem<CameraControllerSystem>();
|
myScene->registerSystem<CameraControllerSystem>();
|
||||||
|
|
||||||
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->getComponent<engine::TransformComponent>(camera)->position.y = 2.0f;
|
||||||
myScene->addComponent<engine::ColliderComponent>(camera)->r = 1.0f;
|
auto cameraCollider = myScene->addComponent<engine::ColliderComponent>(camera);
|
||||||
|
cameraCollider->colliderType = engine::ColliderType::SPHERE;
|
||||||
|
cameraCollider->colliders.sphereCollider.r = 1.8f;
|
||||||
|
myScene->addComponent<CameraControllerComponent>(camera);
|
||||||
|
|
||||||
myScene->getSystem<engine::RenderSystem>()->setCameraEntity(camera);
|
myScene->getSystem<engine::RenderSystem>()->setCameraEntity(camera);
|
||||||
|
|
||||||
@ -69,12 +72,14 @@ void playGame()
|
|||||||
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 = grassTexture;
|
enemyRenderable->material->m_texture = grassTexture;
|
||||||
enemyRenderable->mesh = genSphereMesh(app.gfx(), 2.0f, 30, false);
|
enemyRenderable->mesh = genSphereMesh(app.gfx(), 5.0f, 50, false);
|
||||||
auto enemyT = myScene->getComponent<engine::TransformComponent>(enemy);
|
auto enemyT = myScene->getComponent<engine::TransformComponent>(enemy);
|
||||||
enemyT->position.x += 5.0f;
|
enemyT->position.x += 5.0f;
|
||||||
enemyT->position.y += 2.0f;
|
enemyT->position.y += 2.0f;
|
||||||
enemyT->position.z += 3.0f;
|
enemyT->position.z += 3.0f;
|
||||||
myScene->addComponent<engine::ColliderComponent>(enemy)->r = 10.0f;
|
auto enemyCollider = myScene->addComponent<engine::ColliderComponent>(enemy);
|
||||||
|
enemyCollider->colliderType = engine::ColliderType::SPHERE;
|
||||||
|
enemyCollider->colliders.sphereCollider.r = 5.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);
|
||||||
@ -94,6 +99,7 @@ void playGame()
|
|||||||
floorRenderable->material = std::make_shared<engine::resources::Material>(*sphereRenderable->material);
|
floorRenderable->material = std::make_shared<engine::resources::Material>(*sphereRenderable->material);
|
||||||
floorRenderable->material->m_texture = grassTexture;
|
floorRenderable->material->m_texture = grassTexture;
|
||||||
floorRenderable->mesh = genCuboidMesh(app.gfx(), 100.0f, 0.1f, 100.0f);
|
floorRenderable->mesh = genCuboidMesh(app.gfx(), 100.0f, 0.1f, 100.0f);
|
||||||
|
myScene->addComponent<engine::ColliderComponent>(floor)->colliderType = engine::ColliderType::PLANE;
|
||||||
|
|
||||||
app.gameLoop();
|
app.gameLoop();
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user