diff --git a/include/Engine/Collision/Collision.h b/include/Engine/Collision/Collision.h index 6d16e090..6e4858b2 100644 --- a/include/Engine/Collision/Collision.h +++ b/include/Engine/Collision/Collision.h @@ -78,8 +78,6 @@ 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/Rendering/Model.h b/include/Engine/Rendering/Model.h index f751a8cc..1f5231e2 100644 --- a/include/Engine/Rendering/Model.h +++ b/include/Engine/Rendering/Model.h @@ -4,6 +4,7 @@ #include "Rendering/RawModelCustom.h" //#include "Rendering/RawModelAssimp.h" #include "../OpenGL.h" +#include "Core/AABB.h" class Model : public ThreadUnsafeResource { @@ -17,13 +18,15 @@ public: const std::vector& MaterialGroups() const { return m_RawModel->MaterialGroups; } const glm::mat4& Matrix() const { return m_RawModel->m_Matrix; } const std::vector& Vertices() const { return m_RawModel->m_Vertices; } + const AABB& Box() const { return m_Box; } GLuint VAO; GLuint ElementBuffer; RawModel* m_RawModel; private: - + AABB m_Box; + GLuint VertexBuffer; GLuint NormalBuffer; GLuint TangentNormalsBuffer; diff --git a/src/Engine/Collision/Collision.cpp b/src/Engine/Collision/Collision.cpp index b150d667..db2319c7 100644 --- a/src/Engine/Collision/Collision.cpp +++ b/src/Engine/Collision/Collision.cpp @@ -1,4 +1,5 @@ #include +#include #include "Collision/Collision.h" #include "Engine/GLM.h" @@ -564,45 +565,49 @@ bool AABBvsTriangles(const AABB& box, return hit; } -bool AttachAABBComponentFromModel(EntityWrapper entity) -{ - if (!entity.HasComponent("Model")) { - return false; - } - //Derive AABB from model - RawModel* model; - try { - model = ResourceManager::Load(entity["Model"]["Resource"]); - } catch (const std::exception&) { - return false; - } - - 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); - } - - entity.AttachComponent("AABB"); - entity["AABB"]["Origin"] = 0.5f * (maxi + mini); - entity["AABB"]["Size"] = maxi - mini; - return true; -} - boost::optional EntityAbsoluteAABB(EntityWrapper& entity) { - if (!entity.HasComponent("AABB")) { + AABB modelSpaceBox; + if (entity.HasComponent("AABB")) { + ComponentWrapper& cAABB = entity["AABB"]; + modelSpaceBox = EntityAABB::FromOriginSize((glm::vec3)cAABB["Origin"], (glm::vec3)cAABB["Size"]); + } else if (entity.HasComponent("Model")) { + Model* model; + std::string res = entity["Model"]["Resource"]; + if (res.empty()) { + return boost::none; + } + try { + model = ResourceManager::Load<::Model, true>(res); + } catch (const Resource::StillLoadingException&) { + return boost::none; + } catch (const std::exception&) { + return boost::none; + } + modelSpaceBox = model->Box(); + } else { return boost::none; } - ComponentWrapper& cAABB = entity["AABB"]; - glm::vec3 absPosition = Transform::AbsolutePosition(entity.World, entity.ID); - glm::vec3 absScale = Transform::AbsoluteScale(entity.World, entity.ID); - glm::vec3 origin = absPosition + (glm::vec3)cAABB["Origin"]; - glm::vec3 size = (glm::vec3)cAABB["Size"] * absScale; + glm::mat4 modelMat = Transform::AbsoluteTransformation(entity); + glm::vec3 mini(INFINITY); + glm::vec3 maxi(-INFINITY); + glm::vec3 maxCorner = modelSpaceBox.MaxCorner(); + glm::vec3 minCorner = modelSpaceBox.MinCorner(); + for (int i = 0; i < 8; ++i) { + std::bitset<3> bits(i); + glm::vec3 corner; + corner.x = bits.test(0) ? maxCorner.x : minCorner.x; + corner.y = bits.test(1) ? maxCorner.y : minCorner.y; + corner.z = bits.test(2) ? maxCorner.z : minCorner.z; + corner = Transform::TransformPoint(corner, modelMat); + mini = glm::min(mini, corner); + maxi = glm::max(maxi, corner); + } + + EntityAABB aabb; + aabb = AABB(mini, maxi); - EntityAABB aabb = EntityAABB::FromOriginSize(origin, size); aabb.Entity = entity; return aabb; diff --git a/src/Engine/Collision/FillOctreeSystem.cpp b/src/Engine/Collision/FillOctreeSystem.cpp index 8c03b5c2..a727eb86 100644 --- a/src/Engine/Collision/FillOctreeSystem.cpp +++ b/src/Engine/Collision/FillOctreeSystem.cpp @@ -7,12 +7,6 @@ void FillOctreeSystem::Update(double dt) void FillOctreeSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& component, double dt) { - if (!entity.HasComponent("AABB")) { - //Derive AABB from model. - if (!Collision::AttachAABBComponentFromModel(entity)) { - return; - } - } boost::optional absoluteAABB = Collision::EntityAbsoluteAABB(entity); if (absoluteAABB) { m_Octree->AddDynamicObject(*absoluteAABB); diff --git a/src/Engine/Collision/TriggerSystem.cpp b/src/Engine/Collision/TriggerSystem.cpp index adc778e5..21a47721 100644 --- a/src/Engine/Collision/TriggerSystem.cpp +++ b/src/Engine/Collision/TriggerSystem.cpp @@ -5,11 +5,6 @@ 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/Rendering/Model.cpp b/src/Engine/Rendering/Model.cpp index cf4923a3..a61cf8e3 100644 --- a/src/Engine/Rendering/Model.cpp +++ b/src/Engine/Rendering/Model.cpp @@ -64,6 +64,15 @@ Model::Model(std::string fileName) GLERROR("GLEW: BufferFail5"); //CreateBuffers(); + + glm::vec3 mini(INFINITY); + glm::vec3 maxi(-INFINITY); + for (const auto& v : m_RawModel->m_Vertices) { + mini = glm::min(mini, v.Position); + maxi = glm::max(maxi, v.Position); + } + + m_Box = AABB(maxi, mini); } Model::~Model()