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) {