@@ -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.
|
//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);
|
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
|
// Calculates an absolute AABB from an entity AABB component
|
||||||
boost::optional<EntityAABB> EntityAbsoluteAABB(EntityWrapper& entity);
|
boost::optional<EntityAABB> EntityAbsoluteAABB(EntityWrapper& entity);
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,25 @@
|
|||||||
|
#ifndef FillFrustumOctreeSystem_h__
|
||||||
|
#define FillFrustumOctreeSystem_h__
|
||||||
|
|
||||||
|
#include "../Core/System.h"
|
||||||
|
#include "../Core/Octree.h"
|
||||||
|
#include "Collision.h"
|
||||||
|
#include "EntityAABB.h"
|
||||||
|
|
||||||
|
class FillFrustumOctreeSystem : public ImpureSystem, public PureSystem
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
FillFrustumOctreeSystem(World* world, EventBroker* eventBroker, Octree<EntityAABB>* octree)
|
||||||
|
: System(world, eventBroker)
|
||||||
|
, PureSystem("Model")
|
||||||
|
, m_Octree(octree)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
virtual void Update(double dt) override;
|
||||||
|
virtual void UpdateComponent(EntityWrapper& entity, ComponentWrapper& component, double dt) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
Octree<EntityAABB>* m_Octree;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
#ifndef CollidableOctreeSystem_h__
|
#ifndef FillOctreeSystem_h__
|
||||||
#define CollidableOctreeSystem_h__
|
#define FillOctreeSystem_h__
|
||||||
|
|
||||||
#include "../Core/System.h"
|
#include "../Core/System.h"
|
||||||
#include "../Core/Octree.h"
|
#include "../Core/Octree.h"
|
||||||
|
|||||||
@@ -0,0 +1,77 @@
|
|||||||
|
#ifndef Frustum_h__
|
||||||
|
#define Frustum_h__
|
||||||
|
|
||||||
|
#include "../GLM.h"
|
||||||
|
#include "AABB.h"
|
||||||
|
#include <bitset>
|
||||||
|
|
||||||
|
//A frustum defined by 6 planes.
|
||||||
|
struct Frustum
|
||||||
|
{
|
||||||
|
//Contains points P in: dot(normal, P) + d = 0
|
||||||
|
struct Plane
|
||||||
|
{
|
||||||
|
glm::vec3 Normal;
|
||||||
|
float Distance;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class Output
|
||||||
|
{
|
||||||
|
Inside,
|
||||||
|
Outside,
|
||||||
|
Intersects
|
||||||
|
};
|
||||||
|
Plane Planes[6];
|
||||||
|
|
||||||
|
Frustum() = default;
|
||||||
|
Frustum(glm::mat4x4 viewProjMatrix)
|
||||||
|
{
|
||||||
|
//Order: Right, left, top, bottom, far, near.
|
||||||
|
int sign = 1;
|
||||||
|
for (int i = 0; i < 6; ++i) {
|
||||||
|
sign = -sign;
|
||||||
|
int index = i / 2;
|
||||||
|
Plane& plane = Planes[i];
|
||||||
|
plane.Normal.x = viewProjMatrix[0].w + sign * viewProjMatrix[0][index];
|
||||||
|
plane.Normal.y = viewProjMatrix[1].w + sign * viewProjMatrix[1][index];
|
||||||
|
plane.Normal.z = viewProjMatrix[2].w + sign * viewProjMatrix[2][index];
|
||||||
|
plane.Distance = viewProjMatrix[3].w + sign * viewProjMatrix[3][index];
|
||||||
|
float divByNormalLength = 1.0f / glm::length(plane.Normal);
|
||||||
|
plane.Normal *= divByNormalLength;
|
||||||
|
plane.Distance *= divByNormalLength;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Output VsAABB(const AABB& box) const
|
||||||
|
{
|
||||||
|
const glm::vec3& maxCorner = box.MaxCorner();
|
||||||
|
const glm::vec3& minCorner = box.MinCorner();
|
||||||
|
bool completelyInside = true;
|
||||||
|
for (const Plane& p : Planes) {
|
||||||
|
bool anyWasInside = false;
|
||||||
|
bool anyWasOutside = false;
|
||||||
|
//If points are on both sides of the plane, we can stop.
|
||||||
|
for (int i = 0; i < 8 && (!anyWasInside || !anyWasOutside); ++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;
|
||||||
|
if (glm::dot(p.Normal, corner) > -p.Distance) {
|
||||||
|
anyWasInside = true;
|
||||||
|
} else {
|
||||||
|
anyWasOutside = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!anyWasInside) {
|
||||||
|
return Output::Outside;
|
||||||
|
}
|
||||||
|
if (anyWasOutside) {
|
||||||
|
completelyInside = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return completelyInside ? Output::Inside : Output::Intersects;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
#include "../Common.h"
|
#include "../Common.h"
|
||||||
#include "AABB.h"
|
#include "AABB.h"
|
||||||
|
#include "Frustum.h"
|
||||||
|
|
||||||
//Fwd declarations.
|
//Fwd declarations.
|
||||||
class Ray;
|
class Ray;
|
||||||
@@ -40,6 +41,8 @@ public:
|
|||||||
//The type Box must be AABB, or inherit from AABB.
|
//The type Box must be AABB, or inherit from AABB.
|
||||||
template<typename Box>
|
template<typename Box>
|
||||||
void ObjectsInSameRegion(const Box& box, std::vector<T>& outObjects);
|
void ObjectsInSameRegion(const Box& box, std::vector<T>& outObjects);
|
||||||
|
//Get the objects that are inside the frustum, the objects are put in outObjects.
|
||||||
|
void ObjectsInFrustum(const Frustum& frustum, std::vector<T>& outObjects);
|
||||||
//Empty the tree of all objects, static and dynamic.
|
//Empty the tree of all objects, static and dynamic.
|
||||||
void ClearObjects();
|
void ClearObjects();
|
||||||
//Empty the tree of all dynamic objects. Static objects remain in the tree.
|
//Empty the tree of all dynamic objects. Static objects remain in the tree.
|
||||||
@@ -97,6 +100,8 @@ struct Child
|
|||||||
void AddStaticObject(const AABB& box);
|
void AddStaticObject(const AABB& box);
|
||||||
template<typename T, typename Box>
|
template<typename T, typename Box>
|
||||||
void ObjectsInSameRegion(const Box& box, std::vector<T>& outObjects) const;
|
void ObjectsInSameRegion(const Box& box, std::vector<T>& outObjects) const;
|
||||||
|
template<typename T>
|
||||||
|
void ObjectsInFrustum(const Frustum& frustum, std::vector<T>& outObjects, bool takeAllDontTest) const;
|
||||||
void ClearObjects();
|
void ClearObjects();
|
||||||
void ClearDynamicObjects();
|
void ClearDynamicObjects();
|
||||||
bool RayCollides(const Ray& ray, Output& data) const;
|
bool RayCollides(const Ray& ray, Output& data) const;
|
||||||
@@ -154,6 +159,13 @@ void Octree<T>::ObjectsInSameRegion(const Box& box, std::vector<T>& outObjects)
|
|||||||
m_Root->ObjectsInSameRegion(box, outObjects);
|
m_Root->ObjectsInSameRegion(box, outObjects);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
void Octree<T>::ObjectsInFrustum(const Frustum& frustum, std::vector<T>& outObjects)
|
||||||
|
{
|
||||||
|
falsifyObjectChecks();
|
||||||
|
m_Root->ObjectsInFrustum(frustum, outObjects, false);
|
||||||
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void Octree<T>::ClearObjects()
|
void Octree<T>::ClearObjects()
|
||||||
{
|
{
|
||||||
@@ -230,4 +242,46 @@ void OctSpace::Child::ObjectsInSameRegion(const Box& box, std::vector<T>& outObj
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
void OctSpace::Child::ObjectsInFrustum(const Frustum& frustum, std::vector<T>& outObjects, bool takeAllDontTest) const
|
||||||
|
{
|
||||||
|
if (hasChildren()) {
|
||||||
|
for (const Child* c : m_Children) {
|
||||||
|
Frustum::Output out = Frustum::Output::Inside;
|
||||||
|
if (!takeAllDontTest) {
|
||||||
|
out = frustum.VsAABB(c->m_Box);
|
||||||
|
if (out == Frustum::Output::Outside) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
c->ObjectsInFrustum(frustum, outObjects, out == Frustum::Output::Inside);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
size_t startIndex = outObjects.size();
|
||||||
|
int numDuplicates = 0;
|
||||||
|
outObjects.resize(outObjects.size() + m_StaticObjIndices.size() + m_DynamicObjIndices.size());
|
||||||
|
for (size_t i = 0; i < m_StaticObjIndices.size(); ++i) {
|
||||||
|
ContainedObject& obj = m_StaticObjectsRef[m_StaticObjIndices[i]];
|
||||||
|
if (obj.Checked || frustum.VsAABB(*obj.Box) == Frustum::Output::Outside) {
|
||||||
|
++numDuplicates;
|
||||||
|
} else {
|
||||||
|
obj.Checked = true;
|
||||||
|
outObjects[startIndex + i - numDuplicates] = *static_cast<T*>(obj.Box.get());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (size_t i = 0; i < m_DynamicObjIndices.size(); ++i) {
|
||||||
|
ContainedObject& obj = m_DynamicObjectsRef[m_DynamicObjIndices[i]];
|
||||||
|
if (obj.Checked || frustum.VsAABB(*obj.Box) == Frustum::Output::Outside) {
|
||||||
|
++numDuplicates;
|
||||||
|
} else {
|
||||||
|
obj.Checked = true;
|
||||||
|
outObjects[startIndex + i - numDuplicates] = *static_cast<T*>(obj.Box.get());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (size_t i = 0; i < numDuplicates; ++i) {
|
||||||
|
outObjects.pop_back();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -4,6 +4,7 @@
|
|||||||
#include "Rendering/RawModelCustom.h"
|
#include "Rendering/RawModelCustom.h"
|
||||||
//#include "Rendering/RawModelAssimp.h"
|
//#include "Rendering/RawModelAssimp.h"
|
||||||
#include "../OpenGL.h"
|
#include "../OpenGL.h"
|
||||||
|
#include "Core/AABB.h"
|
||||||
|
|
||||||
class Model : public ThreadUnsafeResource
|
class Model : public ThreadUnsafeResource
|
||||||
{
|
{
|
||||||
@@ -17,12 +18,14 @@ public:
|
|||||||
const std::vector<RawModel::MaterialGroup>& MaterialGroups() const { return m_RawModel->MaterialGroups; }
|
const std::vector<RawModel::MaterialGroup>& MaterialGroups() const { return m_RawModel->MaterialGroups; }
|
||||||
const glm::mat4& Matrix() const { return m_RawModel->m_Matrix; }
|
const glm::mat4& Matrix() const { return m_RawModel->m_Matrix; }
|
||||||
const std::vector<RawModel::Vertex>& Vertices() const { return m_RawModel->m_Vertices; }
|
const std::vector<RawModel::Vertex>& Vertices() const { return m_RawModel->m_Vertices; }
|
||||||
|
const AABB& Box() const { return m_Box; }
|
||||||
|
|
||||||
GLuint VAO;
|
GLuint VAO;
|
||||||
GLuint ElementBuffer;
|
GLuint ElementBuffer;
|
||||||
RawModel* m_RawModel;
|
RawModel* m_RawModel;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
AABB m_Box;
|
||||||
|
|
||||||
GLuint VertexBuffer;
|
GLuint VertexBuffer;
|
||||||
GLuint NormalBuffer;
|
GLuint NormalBuffer;
|
||||||
|
|||||||
@@ -16,11 +16,13 @@
|
|||||||
#include "PointLightJob.h"
|
#include "PointLightJob.h"
|
||||||
#include "../Core/Transform.h"
|
#include "../Core/Transform.h"
|
||||||
#include "../Core/EPlayerSpawned.h"
|
#include "../Core/EPlayerSpawned.h"
|
||||||
|
#include "../Core/Octree.h"
|
||||||
|
#include "../Collision/EntityAABB.h"
|
||||||
|
|
||||||
class RenderSystem : public ImpureSystem
|
class RenderSystem : public ImpureSystem
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
RenderSystem(World* world, EventBroker* eventBrokerer, const IRenderer* renderer, RenderFrame* renderFrame);
|
RenderSystem(World* world, EventBroker* eventBrokerer, const IRenderer* renderer, RenderFrame* renderFrame, Octree<EntityAABB>* frustumCullOctree);
|
||||||
~RenderSystem();
|
~RenderSystem();
|
||||||
|
|
||||||
virtual void Update(double dt) override;
|
virtual void Update(double dt) override;
|
||||||
@@ -32,6 +34,7 @@ private:
|
|||||||
World* m_World;
|
World* m_World;
|
||||||
EntityWrapper m_CurrentCamera = EntityWrapper::Invalid;
|
EntityWrapper m_CurrentCamera = EntityWrapper::Invalid;
|
||||||
EntityWrapper m_LocalPlayer = EntityWrapper::Invalid;
|
EntityWrapper m_LocalPlayer = EntityWrapper::Invalid;
|
||||||
|
Octree<EntityAABB>* m_Octree;
|
||||||
|
|
||||||
EventRelay<RenderSystem, Events::SetCamera> m_ESetCamera;
|
EventRelay<RenderSystem, Events::SetCamera> m_ESetCamera;
|
||||||
bool OnSetCamera(Events::SetCamera &event);
|
bool OnSetCamera(Events::SetCamera &event);
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <bitset>
|
||||||
|
|
||||||
#include "Collision/Collision.h"
|
#include "Collision/Collision.h"
|
||||||
#include "Engine/GLM.h"
|
#include "Engine/GLM.h"
|
||||||
@@ -564,47 +565,50 @@ bool AABBvsTriangles(const AABB& box,
|
|||||||
return hit;
|
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)
|
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;
|
return boost::none;
|
||||||
}
|
}
|
||||||
|
|
||||||
ComponentWrapper& cAABB = entity["AABB"];
|
glm::mat4 modelMat = Transform::AbsoluteTransformation(entity);
|
||||||
glm::vec3 absPosition = Transform::AbsolutePosition(entity.World, entity.ID);
|
glm::vec3 mini(INFINITY);
|
||||||
glm::vec3 absScale = Transform::AbsoluteScale(entity.World, entity.ID);
|
glm::vec3 maxi(-INFINITY);
|
||||||
glm::vec3 origin = absPosition + (glm::vec3)cAABB["Origin"];
|
glm::vec3 maxCorner = modelSpaceBox.MaxCorner();
|
||||||
glm::vec3 size = (glm::vec3)cAABB["Size"] * absScale;
|
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;
|
aabb.Entity = entity;
|
||||||
|
|
||||||
return aabb;
|
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)
|
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);
|
boost::optional<EntityAABB> absoluteAABB = Collision::EntityAbsoluteAABB(entity);
|
||||||
if (absoluteAABB) {
|
if (absoluteAABB) {
|
||||||
m_Octree->AddDynamicObject(*absoluteAABB);
|
m_Octree->AddDynamicObject(*absoluteAABB);
|
||||||
|
|||||||
@@ -5,11 +5,6 @@
|
|||||||
|
|
||||||
void TriggerSystem::UpdateComponent(EntityWrapper& triggerEntity, ComponentWrapper& cTrigger, double dt)
|
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);
|
boost::optional<EntityAABB> triggerBox = Collision::EntityAbsoluteAABB(triggerEntity);
|
||||||
if (!triggerBox) {
|
if (!triggerBox) {
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -64,6 +64,15 @@ Model::Model(std::string fileName)
|
|||||||
GLERROR("GLEW: BufferFail5");
|
GLERROR("GLEW: BufferFail5");
|
||||||
|
|
||||||
//CreateBuffers();
|
//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()
|
Model::~Model()
|
||||||
|
|||||||
@@ -1,10 +1,13 @@
|
|||||||
#include "Rendering/RenderSystem.h"
|
#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)
|
: System(world, eventBroker)
|
||||||
, m_Renderer(renderer)
|
, m_Renderer(renderer)
|
||||||
, m_RenderFrame(renderFrame)
|
, m_RenderFrame(renderFrame)
|
||||||
, m_World(world)
|
, m_World(world)
|
||||||
|
, m_Octree(frustumCullOctree)
|
||||||
{
|
{
|
||||||
EVENT_SUBSCRIBE_MEMBER(m_ESetCamera, &RenderSystem::OnSetCamera);
|
EVENT_SUBSCRIBE_MEMBER(m_ESetCamera, &RenderSystem::OnSetCamera);
|
||||||
EVENT_SUBSCRIBE_MEMBER(m_EInputCommand, &RenderSystem::OnInputCommand);
|
EVENT_SUBSCRIBE_MEMBER(m_EInputCommand, &RenderSystem::OnInputCommand);
|
||||||
@@ -42,12 +45,13 @@ bool RenderSystem::isChildOfCurrentCamera(EntityWrapper entity)
|
|||||||
|
|
||||||
void RenderSystem::fillModels(RenderScene::Queues &Jobs)
|
void RenderSystem::fillModels(RenderScene::Queues &Jobs)
|
||||||
{
|
{
|
||||||
auto models = m_World->GetComponents("Model");
|
Frustum frustum(m_Camera->ProjectionMatrix() * m_Camera->ViewMatrix());
|
||||||
if (models == nullptr) {
|
std::vector<EntityAABB> seenEntities;
|
||||||
return;
|
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"];
|
bool visible = cModel["Visible"];
|
||||||
if (!visible) {
|
if (!visible) {
|
||||||
continue;
|
continue;
|
||||||
@@ -57,8 +61,6 @@ void RenderSystem::fillModels(RenderScene::Queues &Jobs)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
EntityWrapper entity(m_World, cModel.EntityID);
|
|
||||||
|
|
||||||
// Only render children of a camera if that camera is currently active
|
// Only render children of a camera if that camera is currently active
|
||||||
if (isChildOfACamera(entity) && !isChildOfCurrentCamera(entity)) {
|
if (isChildOfACamera(entity) && !isChildOfCurrentCamera(entity)) {
|
||||||
continue;
|
continue;
|
||||||
|
|||||||
+8
-4
@@ -1,5 +1,6 @@
|
|||||||
#include "Game.h"
|
#include "Game.h"
|
||||||
#include "Collision/FillOctreeSystem.h"
|
#include "Collision/FillOctreeSystem.h"
|
||||||
|
#include "Collision/FillFrustumOctreeSystem.h"
|
||||||
#include "Collision/EntityAABB.h"
|
#include "Collision/EntityAABB.h"
|
||||||
#include "Collision/TriggerSystem.h"
|
#include "Collision/TriggerSystem.h"
|
||||||
#include "Collision/CollisionSystem.h"
|
#include "Collision/CollisionSystem.h"
|
||||||
@@ -77,9 +78,11 @@ Game::Game(int argc, char* argv[])
|
|||||||
m_SoundManager = new SoundManager(m_World, m_EventBroker);
|
m_SoundManager = new SoundManager(m_World, m_EventBroker);
|
||||||
|
|
||||||
// Create Octrees
|
// Create Octrees
|
||||||
m_OctreeCollision = new Octree<EntityAABB>(AABB(glm::vec3(-100), glm::vec3(100)), 4);
|
// TODO: Perhaps the world bounds should be set in some non-arbitrary way instead of this.
|
||||||
m_OctreeTrigger = new Octree<EntityAABB>(AABB(glm::vec3(-100), glm::vec3(100)), 4);
|
AABB boxContainingTheWorld(glm::vec3(-300), glm::vec3(300));
|
||||||
m_OctreeFrustrumCulling = new Octree<EntityAABB>(AABB(glm::vec3(-100), glm::vec3(100)), 4);
|
m_OctreeCollision = new Octree<EntityAABB>(boxContainingTheWorld, 4);
|
||||||
|
m_OctreeTrigger = new Octree<EntityAABB>(boxContainingTheWorld, 4);
|
||||||
|
m_OctreeFrustrumCulling = new Octree<EntityAABB>(boxContainingTheWorld, 4);
|
||||||
// Create system pipeline
|
// Create system pipeline
|
||||||
m_SystemPipeline = new SystemPipeline(m_World, m_EventBroker);
|
m_SystemPipeline = new SystemPipeline(m_World, m_EventBroker);
|
||||||
|
|
||||||
@@ -102,6 +105,7 @@ Game::Game(int argc, char* argv[])
|
|||||||
++updateOrderLevel;
|
++updateOrderLevel;
|
||||||
m_SystemPipeline->AddSystem<FillOctreeSystem>(updateOrderLevel, m_OctreeCollision, "Collidable");
|
m_SystemPipeline->AddSystem<FillOctreeSystem>(updateOrderLevel, m_OctreeCollision, "Collidable");
|
||||||
m_SystemPipeline->AddSystem<FillOctreeSystem>(updateOrderLevel, m_OctreeTrigger, "Player");
|
m_SystemPipeline->AddSystem<FillOctreeSystem>(updateOrderLevel, m_OctreeTrigger, "Player");
|
||||||
|
m_SystemPipeline->AddSystem<FillFrustumOctreeSystem>(updateOrderLevel, m_OctreeFrustrumCulling);
|
||||||
m_SystemPipeline->AddSystem<PlayerHUD>(updateOrderLevel);
|
m_SystemPipeline->AddSystem<PlayerHUD>(updateOrderLevel);
|
||||||
m_SystemPipeline->AddSystem<AnimationSystem>(updateOrderLevel);
|
m_SystemPipeline->AddSystem<AnimationSystem>(updateOrderLevel);
|
||||||
|
|
||||||
@@ -110,7 +114,7 @@ Game::Game(int argc, char* argv[])
|
|||||||
m_SystemPipeline->AddSystem<CollisionSystem>(updateOrderLevel, m_OctreeCollision);
|
m_SystemPipeline->AddSystem<CollisionSystem>(updateOrderLevel, m_OctreeCollision);
|
||||||
m_SystemPipeline->AddSystem<TriggerSystem>(updateOrderLevel, m_OctreeTrigger);
|
m_SystemPipeline->AddSystem<TriggerSystem>(updateOrderLevel, m_OctreeTrigger);
|
||||||
++updateOrderLevel;
|
++updateOrderLevel;
|
||||||
m_SystemPipeline->AddSystem<RenderSystem>(updateOrderLevel, m_Renderer, m_RenderFrame);
|
m_SystemPipeline->AddSystem<RenderSystem>(updateOrderLevel, m_Renderer, m_RenderFrame, m_OctreeFrustrumCulling);
|
||||||
++updateOrderLevel;
|
++updateOrderLevel;
|
||||||
m_SystemPipeline->AddSystem<EditorSystem>(updateOrderLevel, m_Renderer, m_RenderFrame);
|
m_SystemPipeline->AddSystem<EditorSystem>(updateOrderLevel, m_Renderer, m_RenderFrame);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user