@@ -1,4 +1,5 @@
|
||||
#include <algorithm>
|
||||
#include <bitset>
|
||||
|
||||
#include "Collision/Collision.h"
|
||||
#include "Engine/GLM.h"
|
||||
@@ -564,47 +565,50 @@ 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<RawModel, true>(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<EntityAABB> 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;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
#include "Collision/FillFrustumOctreeSystem.h"
|
||||
|
||||
void FillFrustumOctreeSystem::Update(double dt)
|
||||
{
|
||||
m_Octree->ClearDynamicObjects();
|
||||
}
|
||||
|
||||
void FillFrustumOctreeSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& component, double dt)
|
||||
{
|
||||
if (entity.HasComponent("ExplosionEffect")) {
|
||||
//TODO: Fix hack, get real box by using shader equation.
|
||||
EntityAABB aabb = AABB(glm::vec3(-300), glm::vec3(300));
|
||||
aabb.Entity = entity;
|
||||
m_Octree->AddDynamicObject(aabb);
|
||||
} else {
|
||||
boost::optional<EntityAABB> absoluteAABB = Collision::EntityAbsoluteAABB(entity);
|
||||
if (absoluteAABB) {
|
||||
m_Octree->AddDynamicObject(*absoluteAABB);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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<EntityAABB> absoluteAABB = Collision::EntityAbsoluteAABB(entity);
|
||||
if (absoluteAABB) {
|
||||
m_Octree->AddDynamicObject(*absoluteAABB);
|
||||
|
||||
@@ -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<EntityAABB> triggerBox = Collision::EntityAbsoluteAABB(triggerEntity);
|
||||
if (!triggerBox) {
|
||||
return;
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
#include "Rendering/RenderSystem.h"
|
||||
#include "Collision/Collision.h"
|
||||
#include "Core/Frustum.h"
|
||||
|
||||
RenderSystem::RenderSystem(World* world, EventBroker* eventBroker, const IRenderer* renderer, RenderFrame* renderFrame)
|
||||
RenderSystem::RenderSystem(World* world, EventBroker* eventBroker, const IRenderer* renderer, RenderFrame* renderFrame, Octree<EntityAABB>* frustumCullOctree)
|
||||
: System(world, eventBroker)
|
||||
, m_Renderer(renderer)
|
||||
, m_RenderFrame(renderFrame)
|
||||
, m_World(world)
|
||||
, m_Octree(frustumCullOctree)
|
||||
{
|
||||
EVENT_SUBSCRIBE_MEMBER(m_ESetCamera, &RenderSystem::OnSetCamera);
|
||||
EVENT_SUBSCRIBE_MEMBER(m_EInputCommand, &RenderSystem::OnInputCommand);
|
||||
@@ -42,12 +45,13 @@ bool RenderSystem::isChildOfCurrentCamera(EntityWrapper entity)
|
||||
|
||||
void RenderSystem::fillModels(RenderScene::Queues &Jobs)
|
||||
{
|
||||
auto models = m_World->GetComponents("Model");
|
||||
if (models == nullptr) {
|
||||
return;
|
||||
}
|
||||
Frustum frustum(m_Camera->ProjectionMatrix() * m_Camera->ViewMatrix());
|
||||
std::vector<EntityAABB> seenEntities;
|
||||
m_Octree->ObjectsInFrustum(frustum, seenEntities);
|
||||
|
||||
for (auto& cModel : *models) {
|
||||
for (auto& seenEntity : seenEntities) {
|
||||
EntityWrapper entity = seenEntity.Entity;
|
||||
ComponentWrapper cModel = entity["Model"];
|
||||
bool visible = cModel["Visible"];
|
||||
if (!visible) {
|
||||
continue;
|
||||
@@ -57,8 +61,6 @@ void RenderSystem::fillModels(RenderScene::Queues &Jobs)
|
||||
continue;
|
||||
}
|
||||
|
||||
EntityWrapper entity(m_World, cModel.EntityID);
|
||||
|
||||
// Only render children of a camera if that camera is currently active
|
||||
if (isChildOfACamera(entity) && !isChildOfCurrentCamera(entity)) {
|
||||
continue;
|
||||
|
||||
Reference in New Issue
Block a user