Skip to content

Commit

Permalink
#150 Clean code visible system & world transform system
Browse files Browse the repository at this point in the history
  • Loading branch information
ducphamhong committed Jul 19, 2022
1 parent 1b5a545 commit a31c05e
Show file tree
Hide file tree
Showing 9 changed files with 179 additions and 117 deletions.
84 changes: 38 additions & 46 deletions Projects/Skylicht/Engine/Source/Culling/CVisibleSystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,7 @@ This file is part of the "Skylicht Engine".

namespace Skylicht
{
CVisibleSystem::CVisibleSystem() :
m_maxDepth(0)
CVisibleSystem::CVisibleSystem()
{

}
Expand All @@ -42,49 +41,42 @@ namespace Skylicht

void CVisibleSystem::beginQuery(CEntityManager* entityManager)
{
for (int depth = 0; depth < MAX_CHILD_DEPTH; depth++)
{
SVisibleData& data = m_entities[depth];
data.Count = 0;
}

m_maxDepth = 0;
m_queries.Count = 0;
}

void CVisibleSystem::onQuery(CEntityManager* entityManager, CEntity** entities, int numEntity)
{
SVisibleQuery* data = &m_queries;

for (int i = 0; i < numEntity; i++)
{
CEntity* entity = entities[i];

CVisibleData* visible = GET_ENTITY_DATA(entity, CVisibleData);
CWorldTransformData* transform = GET_ENTITY_DATA(entity, CWorldTransformData);

if (transform->Depth > m_maxDepth)
m_maxDepth = transform->Depth;

SVisibleData& data = m_entities[transform->Depth];

// hardcode dynamic array to optimize performance
if ((data.Count + 1) >= data.Alloc)
if ((data->Count + 1) >= data->Alloc)
{
int alloc = (data.Count + 1) * 2;
int alloc = (data->Count + 1) * 2;
if (alloc < 32)
alloc = 32;

data.Visibles.set_used(alloc);
data.Transforms.set_used(alloc);
data.Entities.set_used(alloc);
data->Visibles.set_used(alloc);
data->Transforms.set_used(alloc);
data->Entities.set_used(alloc);

data.VisiblesPtr = data.Visibles.pointer();
data.TransformsPtr = data.Transforms.pointer();
data.EntitiesPtr = data.Entities.pointer();
data->VisiblesPtr = data->Visibles.pointer();
data->TransformsPtr = data->Transforms.pointer();
data->EntitiesPtr = data->Entities.pointer();

data.Alloc = alloc;
data->Alloc = alloc;
}

data.TransformsPtr[data.Count] = transform;
data.VisiblesPtr[data.Count] = visible;
data.EntitiesPtr[data.Count] = entity;
data.Count++;
data->TransformsPtr[data->Count] = transform;
data->VisiblesPtr[data->Count] = visible;
data->EntitiesPtr[data->Count] = entity;
data->Count++;
}
}

Expand All @@ -95,29 +87,29 @@ namespace Skylicht

void CVisibleSystem::update(CEntityManager* entityManager)
{
for (int depth = 0; depth <= m_maxDepth; depth++)
SVisibleQuery* data = &m_queries;

CVisibleData** visibles = data->VisiblesPtr;
CWorldTransformData** transforms = data->TransformsPtr;
CEntity** entities = data->EntitiesPtr;

CEntity** allEntities = entityManager->getEntities();

u32 numEntity = data->Count;

for (u32 i = 0; i < numEntity; i++)
{
SVisibleData& data = m_entities[depth];
CVisibleData* visible = visibles[i];

u32 numEntity = data.Count;
CVisibleData** visibles = data.VisiblesPtr;
CWorldTransformData** transforms = data.TransformsPtr;
CEntity** entities = data.EntitiesPtr;
visible->SelfVisible = entities[i]->isVisible();
visible->Visible = visible->SelfVisible;

for (u32 i = 0; i < numEntity; i++)
if (visible->Visible == true && transforms[i]->ParentIndex >= 0)
{
CVisibleData* visible = visibles[i];

visible->SelfVisible = entities[i]->isVisible();
visible->Visible = visible->SelfVisible;

if (visible->Visible == true && transforms[i]->ParentIndex >= 0)
{
// link parent visible
CEntity* parentEntity = entityManager->getEntity(transforms[i]->ParentIndex);
CVisibleData* parentVisible = GET_ENTITY_DATA(parentEntity, CVisibleData);
visible->Visible = parentVisible->Visible;
}
// link parent visible
CEntity* parentEntity = allEntities[transforms[i]->ParentIndex];
CVisibleData* parentVisible = GET_ENTITY_DATA(parentEntity, CVisibleData);
visible->Visible = parentVisible->Visible;
}
}
}
Expand Down
12 changes: 6 additions & 6 deletions Projects/Skylicht/Engine/Source/Culling/CVisibleSystem.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,12 @@ This file is part of the "Skylicht Engine".
#include "Entity/IRenderSystem.h"
#include "Transform/CWorldTransformData.h"

#define MAX_CHILD_DEPTH 512

namespace Skylicht
{
class CVisibleSystem : public IEntitySystem
{
protected:
struct SVisibleData
struct SVisibleQuery
{
core::array<CVisibleData*> Visibles;
core::array<CWorldTransformData*> Transforms;
Expand All @@ -48,15 +46,17 @@ namespace Skylicht
int Count;
int Alloc;

SVisibleData()
SVisibleQuery()
{
Alloc = 0;
Count = 0;
VisiblesPtr = NULL;
TransformsPtr = NULL;
EntitiesPtr = NULL;
}
};

int m_maxDepth;
SVisibleData m_entities[MAX_CHILD_DEPTH];
SVisibleQuery m_queries;

public:
CVisibleSystem();
Expand Down
6 changes: 4 additions & 2 deletions Projects/Skylicht/Engine/Source/Entity/CEntity.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ namespace Skylicht
{
CEntity::CEntity(CEntityManager* mgr) :
m_alive(true),
m_visible(true)
m_visible(true),
Depth(0)
{
m_index = mgr->getNumEntities();

Expand All @@ -43,7 +44,8 @@ namespace Skylicht

CEntity::CEntity(CEntityPrefab* mgr) :
m_alive(true),
m_visible(true)
m_visible(true),
Depth(0)
{
m_index = mgr->getNumEntities();

Expand Down
2 changes: 2 additions & 0 deletions Projects/Skylicht/Engine/Source/Entity/CEntity.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ namespace Skylicht

IEntityData* Data[MAX_ENTITY_DATA];

int Depth;

public:
CEntity(CEntityManager* mgr);
CEntity(CEntityPrefab* mgr);
Expand Down
73 changes: 62 additions & 11 deletions Projects/Skylicht/Engine/Source/Entity/CEntityManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -225,25 +225,76 @@ namespace Skylicht
m_unused.push_back(entity);
}

void CEntityManager::update()
void CEntityManager::sortAliveEntities()
{
for (IEntitySystem*& s : m_systems)
CEntity** entities = m_entities.pointer();
u32 numEntity = m_entities.size();

int maxDepth = 0;

for (u32 i = 0; i < MAX_ENTITY_DEPTH; i++)
{
s->beginQuery(this);
SEntityDepth* depth = &m_sortDepth[i];
depth->Count = 0;
}

CEntity** entities = m_entities.pointer();
int numEntity = m_entities.size();
for (u32 i = 0; i < numEntity; i++)
{
CEntity* entity = entities[i];

if (entity->isAlive())
{
// sync the depth
CWorldTransformData* world = GET_ENTITY_DATA(entity, CWorldTransformData);
entity->Depth = world->Depth;

SEntityDepth* depth = &m_sortDepth[world->Depth];

if (depth->Count + 1 >= depth->Alloc)
{
int alloc = (depth->Count + 1) * 2;
if (alloc < 32)
alloc = 32;

depth->Entities.set_used(alloc);
depth->EntitiesPtr = depth->Entities.pointer();
depth->Alloc = alloc;
}

// save the alive
depth->EntitiesPtr[depth->Count] = entity;
depth->Count++;

m_alives.set_used(0);
for (int i = 0; i < numEntity; i++)
if (maxDepth < world->Depth)
maxDepth = world->Depth;
}
}

m_alives.set_used(numEntity);
CEntity** alives = m_alives.pointer();

// copy and sort the alives by depth
int count = 0;
for (int i = 0; i <= maxDepth; i++)
{
SEntityDepth* depth = &m_sortDepth[i];
for (int j = 0; j < depth->Count; j++)
alives[count++] = depth->EntitiesPtr[j];
}
m_alives.set_used(count);
}

void CEntityManager::update()
{
for (IEntitySystem*& s : m_systems)
{
if (entities[i]->isAlive())
m_alives.push_back(entities[i]);
s->beginQuery(this);
}

entities = m_alives.pointer();
numEntity = m_alives.size();
sortAliveEntities();

CEntity** entities = m_alives.pointer();
int numEntity = (int)m_alives.size();

for (IEntitySystem*& s : m_systems)
{
Expand Down
29 changes: 29 additions & 0 deletions Projects/Skylicht/Engine/Source/Entity/CEntityManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,15 +31,35 @@ This file is part of the "Skylicht Engine".
#include "GameObject/CGameObject.h"
#include "Camera/CCamera.h"

#define MAX_ENTITY_DEPTH 256

namespace Skylicht
{
struct SEntityDepth
{
core::array<CEntity*> Entities;
int Count;
int Alloc;

CEntity** EntitiesPtr;

SEntityDepth()
{
Count = 0;
Alloc = 0;
EntitiesPtr = NULL;
}
};

class CEntityManager
{
protected:
core::array<CEntity*> m_alives;
core::array<CEntity*> m_entities;
core::array<CEntity*> m_unused;

SEntityDepth m_sortDepth[MAX_ENTITY_DEPTH];

std::vector<IEntitySystem*> m_systems;
std::vector<IRenderSystem*> m_renders;

Expand All @@ -63,6 +83,10 @@ namespace Skylicht

void cullingAndRender();

protected:

void sortAliveEntities();

public:

inline void setCamera(CCamera* camera)
Expand Down Expand Up @@ -103,6 +127,11 @@ namespace Skylicht
return m_entities[index];
}

inline CEntity** getEntities()
{
return m_entities.pointer();
}

CEntity* getEntityByID(const char* id);

void removeEntity(int index);
Expand Down
Loading

0 comments on commit a31c05e

Please sign in to comment.