From 6610bb974db8da0ae68db595d49a7e3bf25b5046 Mon Sep 17 00:00:00 2001 From: William Moberg Date: Mon, 8 Feb 2016 13:32:45 +0100 Subject: [PATCH 1/3] Only apply air friction if the ground is never hit during the frame. --- src/Engine/Collision/CollisionSystem.cpp | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/src/Engine/Collision/CollisionSystem.cpp b/src/Engine/Collision/CollisionSystem.cpp index b5d7a1f0..7d8905a8 100644 --- a/src/Engine/Collision/CollisionSystem.cpp +++ b/src/Engine/Collision/CollisionSystem.cpp @@ -20,6 +20,7 @@ void CollisionSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& c // Collide against octree items m_OctreeResult.clear(); m_Octree->ObjectsInSameRegion(*boundingBox, m_OctreeResult); + bool everHitTheGround = false; for (auto& boxB : m_OctreeResult) { glm::vec3 resolutionVector; if (boxA.Entity == boxB.Entity) { @@ -43,17 +44,24 @@ void CollisionSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& c if (Collision::AABBvsTriangles(boxA, model->m_Vertices, model->m_Indices, modelMatrix, inOutVelocity, verticalStepHeight, isOnGround, resolutionVector)) { (glm::vec3&)cTransform["Position"] += resolutionVector; cPhysics["Velocity"] = inOutVelocity; - (bool)cPhysics["IsOnGround"] = isOnGround; - } else { - (bool)cPhysics["IsOnGround"] = false; + if (isOnGround) { + everHitTheGround = true; + (bool)cPhysics["IsOnGround"] = true; + } } } else if (Collision::AABBVsAABB(boxA, boxB, resolutionVector)) { //Enter here if boxB has no Model. (glm::vec3&)cTransform["Position"] += resolutionVector; - (bool)cPhysics["IsOnGround"] = resolutionVector.y > 0; - if ((bool)cPhysics["IsOnGround"]){ + if (resolutionVector.y > 0) { + everHitTheGround = true; + (bool)cPhysics["IsOnGround"] = true; ((glm::vec3&)cPhysics["Velocity"]).y = 0.f; } } } + + //This should apply air friction and such, iff zero models were hit. + if (!everHitTheGround) { + (bool)cPhysics["IsOnGround"] = false; + } } From 11cf85cc7346f6e189e513c9204b3a79e07096b9 Mon Sep 17 00:00:00 2001 From: William Moberg Date: Mon, 8 Feb 2016 14:17:19 +0100 Subject: [PATCH 2/3] Renamed CollidableOctreeSystem to FillOctreeSystem. --- .../{CollidableOctreeSystem.h => FillOctreeSystem.h} | 6 +++--- .../{CollidableOctreeSystem.cpp => FillOctreeSystem.cpp} | 6 +++--- src/Game/Game.cpp | 6 +++--- 3 files changed, 9 insertions(+), 9 deletions(-) rename include/Engine/Collision/{CollidableOctreeSystem.h => FillOctreeSystem.h} (66%) rename src/Engine/Collision/{CollidableOctreeSystem.cpp => FillOctreeSystem.cpp} (64%) diff --git a/include/Engine/Collision/CollidableOctreeSystem.h b/include/Engine/Collision/FillOctreeSystem.h similarity index 66% rename from include/Engine/Collision/CollidableOctreeSystem.h rename to include/Engine/Collision/FillOctreeSystem.h index 0aa01d2e..9fd87b94 100644 --- a/include/Engine/Collision/CollidableOctreeSystem.h +++ b/include/Engine/Collision/FillOctreeSystem.h @@ -6,12 +6,12 @@ #include "Collision.h" #include "EntityAABB.h" -class CollidableOctreeSystem : public ImpureSystem, public PureSystem +class FillOctreeSystem : public ImpureSystem, public PureSystem { public: - CollidableOctreeSystem(World* world, EventBroker* eventBroker, Octree* octree, const std::string& componentType) + FillOctreeSystem(World* world, EventBroker* eventBroker, Octree* octree, const std::string& fillComponentType) : System(world, eventBroker) - , PureSystem(componentType) + , PureSystem(fillComponentType) , m_Octree(octree) { } diff --git a/src/Engine/Collision/CollidableOctreeSystem.cpp b/src/Engine/Collision/FillOctreeSystem.cpp similarity index 64% rename from src/Engine/Collision/CollidableOctreeSystem.cpp rename to src/Engine/Collision/FillOctreeSystem.cpp index 476414dd..d69319de 100644 --- a/src/Engine/Collision/CollidableOctreeSystem.cpp +++ b/src/Engine/Collision/FillOctreeSystem.cpp @@ -1,11 +1,11 @@ -#include "Collision/CollidableOctreeSystem.h" +#include "Collision/FillOctreeSystem.h" -void CollidableOctreeSystem::Update(double dt) +void FillOctreeSystem::Update(double dt) { m_Octree->ClearDynamicObjects(); } -void CollidableOctreeSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& component, double dt) +void FillOctreeSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& component, double dt) { if (entity.HasComponent("AABB")) { boost::optional absoluteAABB = Collision::EntityAbsoluteAABB(entity); diff --git a/src/Game/Game.cpp b/src/Game/Game.cpp index f5afcaeb..157ea5ab 100644 --- a/src/Game/Game.cpp +++ b/src/Game/Game.cpp @@ -1,5 +1,5 @@ #include "Game.h" -#include "Collision/CollidableOctreeSystem.h" +#include "Collision/FillOctreeSystem.h" #include "Collision/EntityAABB.h" #include "Collision/TriggerSystem.h" #include "Collision/CollisionSystem.h" @@ -93,8 +93,8 @@ Game::Game(int argc, char* argv[]) m_SystemPipeline->AddSystem(updateOrderLevel); // Populate Octree with collidables ++updateOrderLevel; - m_SystemPipeline->AddSystem(updateOrderLevel, m_OctreeCollision, "Collidable"); - m_SystemPipeline->AddSystem(updateOrderLevel, m_OctreeTrigger, "Player"); + m_SystemPipeline->AddSystem(updateOrderLevel, m_OctreeCollision, "Collidable"); + m_SystemPipeline->AddSystem(updateOrderLevel, m_OctreeTrigger, "Player"); m_SystemPipeline->AddSystem(updateOrderLevel); m_SystemPipeline->AddSystem(updateOrderLevel); From 93c6f3c0a35e0ff673e37f956b65a989770ce8af Mon Sep 17 00:00:00 2001 From: William Moberg Date: Mon, 8 Feb 2016 14:34:37 +0100 Subject: [PATCH 3/3] AABBs are auto attached when adding Trigger/Collideable/etc, also added AttachComponent method to ComponentWrapper. --- include/Engine/Collision/Collision.h | 2 ++ include/Engine/Core/EntityWrapper.h | 1 + resources/Schema/Entities/GameMap.xml | 3 +- src/Engine/Collision/Collision.cpp | 36 ++++++++++------------- src/Engine/Collision/FillOctreeSystem.cpp | 14 +++++---- src/Engine/Collision/TriggerSystem.cpp | 4 +++ src/Engine/Core/EntityWrapper.cpp | 9 ++++++ 7 files changed, 42 insertions(+), 27 deletions(-) diff --git a/include/Engine/Collision/Collision.h b/include/Engine/Collision/Collision.h index 6e4858b2..6d16e090 100644 --- a/include/Engine/Collision/Collision.h +++ b/include/Engine/Collision/Collision.h @@ -78,6 +78,8 @@ bool AABBVsAABB(const AABB& a, const AABB& b); //Also outputs the minimum translation that box [a] would need in order to resolve collision. bool AABBVsAABB(const AABB& a, const AABB& b, glm::vec3& minimumTranslation); +//Attaches an AABB which contains all vertices in the entitys Model. +bool AttachAABBComponentFromModel(EntityWrapper entity); // Calculates an absolute AABB from an entity AABB component boost::optional EntityAbsoluteAABB(EntityWrapper& entity); diff --git a/include/Engine/Core/EntityWrapper.h b/include/Engine/Core/EntityWrapper.h index bf34b9be..087471c0 100644 --- a/include/Engine/Core/EntityWrapper.h +++ b/include/Engine/Core/EntityWrapper.h @@ -25,6 +25,7 @@ struct EntityWrapper const std::string Name(); bool HasComponent(const std::string& componentType); + void AttachComponent(const char* componentName); EntityWrapper Parent(); EntityWrapper FirstChildByName(const std::string& name); EntityWrapper FirstParentWithComponent(const std::string& componentType); diff --git a/resources/Schema/Entities/GameMap.xml b/resources/Schema/Entities/GameMap.xml index 4d0a2716..90807eb5 100644 --- a/resources/Schema/Entities/GameMap.xml +++ b/resources/Schema/Entities/GameMap.xml @@ -9,7 +9,8 @@ - + + diff --git a/src/Engine/Collision/Collision.cpp b/src/Engine/Collision/Collision.cpp index fe4eb5e0..b150d667 100644 --- a/src/Engine/Collision/Collision.cpp +++ b/src/Engine/Collision/Collision.cpp @@ -564,33 +564,29 @@ bool AABBvsTriangles(const AABB& box, return hit; } -bool attachAABBComponentFromModel(World* world, EntityID id) +bool AttachAABBComponentFromModel(EntityWrapper entity) { - if (!world->HasComponent(id, "Model")) { + if (!entity.HasComponent("Model")) { return false; } - ComponentWrapper model = world->GetComponent(id, "Model"); - ComponentWrapper collision = world->AttachComponent(id, "AABB"); - Model* modelRes = ResourceManager::Load(model["Resource"]); - if (modelRes == nullptr) { + //Derive AABB from model + RawModel* model; + try { + model = ResourceManager::Load(entity["Model"]["Resource"]); + } catch (const std::exception&) { return false; } - glm::mat4 modelMatrix = modelRes->Matrix(); - - glm::vec3 mini = glm::vec3(INFINITY, INFINITY, INFINITY); - glm::vec3 maxi = glm::vec3(-INFINITY, -INFINITY, -INFINITY); - for (const auto& v : modelRes->Vertices()) { - const auto& wPos = modelMatrix * glm::vec4(v.Position.x, v.Position.y, v.Position.z, 1); - maxi.x = std::max(wPos.x, maxi.x); - maxi.y = std::max(wPos.y, maxi.y); - maxi.z = std::max(wPos.z, maxi.z); - mini.x = std::min(wPos.x, mini.x); - mini.y = std::min(wPos.y, mini.y); - mini.z = std::min(wPos.z, mini.z); + glm::vec3 mini(INFINITY); + glm::vec3 maxi(-INFINITY); + for (const auto& v : model->m_Vertices) { + mini = glm::min(mini, v.Position); + maxi = glm::max(maxi, v.Position); } - collision["Origin"] = 0.5f * (maxi + mini); - collision["Size"] = maxi - mini; + + entity.AttachComponent("AABB"); + entity["AABB"]["Origin"] = 0.5f * (maxi + mini); + entity["AABB"]["Size"] = maxi - mini; return true; } diff --git a/src/Engine/Collision/FillOctreeSystem.cpp b/src/Engine/Collision/FillOctreeSystem.cpp index d69319de..8c03b5c2 100644 --- a/src/Engine/Collision/FillOctreeSystem.cpp +++ b/src/Engine/Collision/FillOctreeSystem.cpp @@ -7,12 +7,14 @@ void FillOctreeSystem::Update(double dt) void FillOctreeSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& component, double dt) { - if (entity.HasComponent("AABB")) { - boost::optional absoluteAABB = Collision::EntityAbsoluteAABB(entity); - if (absoluteAABB) { - m_Octree->AddDynamicObject(*absoluteAABB); + if (!entity.HasComponent("AABB")) { + //Derive AABB from model. + if (!Collision::AttachAABBComponentFromModel(entity)) { + return; } - } else if (entity.HasComponent("Model")) { - // TODO: Derive AABB from model + } + boost::optional absoluteAABB = Collision::EntityAbsoluteAABB(entity); + if (absoluteAABB) { + m_Octree->AddDynamicObject(*absoluteAABB); } } \ No newline at end of file diff --git a/src/Engine/Collision/TriggerSystem.cpp b/src/Engine/Collision/TriggerSystem.cpp index 410a7fa1..adc778e5 100644 --- a/src/Engine/Collision/TriggerSystem.cpp +++ b/src/Engine/Collision/TriggerSystem.cpp @@ -6,6 +6,10 @@ void TriggerSystem::UpdateComponent(EntityWrapper& triggerEntity, ComponentWrapper& cTrigger, double dt) { // The trigger *should* have a bounding box, or something, to test against so it can be triggered. + // If it doesn't, add one as big as the model for now, then size can be modified in editor if necessary. + if (!triggerEntity.HasComponent("AABB")) { + Collision::AttachAABBComponentFromModel(triggerEntity); + } boost::optional triggerBox = Collision::EntityAbsoluteAABB(triggerEntity); if (!triggerBox) { return; diff --git a/src/Engine/Core/EntityWrapper.cpp b/src/Engine/Core/EntityWrapper.cpp index 071329a3..b0d08e66 100644 --- a/src/Engine/Core/EntityWrapper.cpp +++ b/src/Engine/Core/EntityWrapper.cpp @@ -16,6 +16,15 @@ bool EntityWrapper::HasComponent(const std::string& componentName) return World->HasComponent(ID, componentName); } +void EntityWrapper::AttachComponent(const char* componentName) +{ + if (!Valid()) { + LOG_WARNING("Could not attach \"%s\" component to #%i, component is not valid.", componentName, ID); + return; + } + World->AttachComponent(ID, componentName); +} + EntityWrapper EntityWrapper::Parent() { if (this->World == nullptr || this->ID == EntityID_Invalid) {