Skip to content

Commit

Permalink
#80 Update pick system & culling by camera
Browse files Browse the repository at this point in the history
  • Loading branch information
ducphamhong committed Oct 23, 2021
1 parent 2de5aa7 commit 85c2365
Show file tree
Hide file tree
Showing 62 changed files with 227 additions and 141 deletions.
6 changes: 5 additions & 1 deletion Projects/Editor/Source/Editor/Space/Scene/CSpaceScene.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ namespace Skylicht
m_view(NULL),
m_handlesRenderer(NULL),
m_gizmosRenderer(NULL),
m_pickSystem(NULL),
m_enableRender(true)
{
initDefaultScene();
Expand Down Expand Up @@ -236,7 +237,10 @@ namespace Skylicht

// add handle renderer
CEntityManager* entityMgr = m_scene->getEntityManager();
entityMgr->addSystem<CPickCollisionSystem>();

m_pickSystem = entityMgr->addSystem<CPickCollisionSystem>();
m_pickSystem->setCullingCamera(m_editorCamera);

m_handlesRenderer = entityMgr->addRenderSystem<CHandlesRenderer>();
m_gizmosRenderer = entityMgr->addRenderSystem<CGizmosRenderer>();

Expand Down
2 changes: 2 additions & 0 deletions Projects/Editor/Source/Editor/Space/Scene/CSpaceScene.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,8 @@ namespace Skylicht
CHandlesRenderer* m_handlesRenderer;
CGizmosRenderer* m_gizmosRenderer;

CPickCollisionSystem* m_pickSystem;

GUI::CButton* m_toolbarButton[ToolbarCount];

GUI::CToggleGroup* m_groupEditor;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ This file is part of the "Skylicht Engine".
#include "Components/CDependentComponent.h"

#include "GameObject/CGameObject.h"
#include "Transform/CWorldInverseTransformData.h"

#include "Editor/CEditor.h"
#include "Handles/CHandles.h"

Expand Down Expand Up @@ -66,11 +68,14 @@ namespace Skylicht

addLinkComponent(m_sprite);

// m_collisionNode = bbCollision->addBBCollision(m_gameObject, core::aabbox3df(core::vector3df(-1.0f, -1.0f, -1.0f), core::vector3df(1.0f, 1.0f, 1.0f)));
m_defaultBBox = core::aabbox3df(core::vector3df(-1.0f, -1.0f, -1.0f), core::vector3df(1.0f, 1.0f, 1.0f));

// CPickCollisionData* pickData = m_gameObject->getEntity()->addData<CPickCollisionData>();
// pickData->CollisionNode = m_collisionNode;
// pickData->IsBBoxCollision = true;
// pick collision
CEntity* entity = m_gameObject->getEntity();
entity->addData<CWorldInverseTransformData>();
CPickCollisionData* pickData = entity->addData<CPickCollisionData>();
pickData->GameObject = m_gameObject;
pickData->BBox = m_defaultBBox;
}

void CGDirectionLight::updateComponent()
Expand All @@ -83,8 +88,11 @@ namespace Skylicht
CHandles::getInstance()->drawArrowInViewSpace(m_gameObject->getPosition(), m_directionLight->getDirection(), 0.5f, 0.05f, lightColor);

// update collision bbox
// float boxScale = m_sprite->getViewScale() * 10.0f;
// m_collisionNode->updateBBox(core::aabbox3df(core::vector3df(-1.0f, -1.0f, -1.0f) * boxScale, core::vector3df(1.0f, 1.0f, 1.0f) * boxScale));
float boxScale = m_sprite->getViewScale() * 10.0f;
CPickCollisionData* pickData = m_gameObject->getEntity()->getData<CPickCollisionData>();
pickData->GameObject = m_gameObject;
pickData->BBox.MinEdge = m_defaultBBox.MinEdge * boxScale;
pickData->BBox.MaxEdge = m_defaultBBox.MaxEdge * boxScale;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ namespace Skylicht
class CGDirectionLight : public CGizmosComponent
{
protected:
core::aabbox3df m_defaultBBox;

CDirectionalLight* m_directionLight;
CSprite* m_sprite;
CCollisionNode* m_collisionNode;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ namespace Skylicht

}

void CGizmosRenderer::beginQuery()
void CGizmosRenderer::beginQuery(CEntityManager* entityManager)
{

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ namespace Skylicht

virtual void init(CEntityManager* entityManager);

virtual void beginQuery();
virtual void beginQuery(CEntityManager* entityManager);

virtual void onQuery(CEntityManager* entityManager, CEntity* entity);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ namespace Skylicht
delete m_data;
}

void CHandlesRenderer::beginQuery()
void CHandlesRenderer::beginQuery(CEntityManager* entityManager)
{

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ namespace Skylicht

virtual ~CHandlesRenderer();

virtual void beginQuery();
virtual void beginQuery(CEntityManager* entityManager);

virtual void onQuery(CEntityManager* entityManager, CEntity* entity);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,7 @@ namespace Skylicht
{
namespace Editor
{
CPickCollisionData::CPickCollisionData() :
CollisionNode(NULL),
IsBBoxCollision(false),
IsChanged(true)
CPickCollisionData::CPickCollisionData()
{

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,9 @@ namespace Skylicht
class CPickCollisionData : public IEntityData
{
public:
CCollisionNode* CollisionNode;
bool IsBBoxCollision;
bool IsChanged;
CGameObject* GameObject;

core::aabbox3df BBox;

public:
CPickCollisionData();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,35 +26,66 @@ This file is part of the "Skylicht Engine".
#include "CPickCollisionSystem.h"
#include "Editor/SpaceController/CCollisionController.h"

#include "Culling/CCullingData.h"
#include "Culling/CVisibleData.h"

#include "Entity/CEntityManager.h"

namespace Skylicht
{
namespace Editor
{
CPickCollisionSystem::CPickCollisionSystem()
CPickCollisionSystem::CPickCollisionSystem() :
m_cullingCamera(NULL)
{


}

CPickCollisionSystem::~CPickCollisionSystem()
{

}

void CPickCollisionSystem::beginQuery()
void CPickCollisionSystem::beginQuery(CEntityManager* entityManager)
{
m_pickCollisions.set_used(0);
if (entityManager->getCamera() != m_cullingCamera)
{
m_skipUpdate = true;
return;
}

m_results.set_used(0);
m_collision.set_used(0);
m_transform.set_used(0);
m_invTransform.set_used(0);

m_skipUpdate = false;
}

void CPickCollisionSystem::onQuery(CEntityManager* entityManager, CEntity* entity)
{
// if transform is changed
if (m_skipUpdate)
return;

// check this entity is culled from camera?
CCullingData* cullingData = entity->getData<CCullingData>();
if (cullingData != NULL && !cullingData->Visible)
return;

// check this entity is visible?
CVisibleData* visibleData = entity->getData<CVisibleData>();
if (visibleData != NULL && !visibleData->Visible)
return;

CPickCollisionData* collisionData = entity->getData<CPickCollisionData>();
if (collisionData != NULL &&
collisionData->CollisionNode != NULL &&
collisionData->IsChanged)
if (collisionData != NULL)
{
m_pickCollisions.push_back(collisionData);
CWorldTransformData* transform = entity->getData<CWorldTransformData>();
CWorldInverseTransformData* invTransform = entity->getData<CWorldInverseTransformData>();

m_collision.push_back(collisionData);
m_transform.push_back(transform);
m_invTransform.push_back(invTransform);
}
}

Expand All @@ -65,12 +96,65 @@ namespace Skylicht

void CPickCollisionSystem::update(CEntityManager* entityManager)
{
CPickCollisionData** listCollision = m_pickCollisions.pointer();
u32 numCollision = m_pickCollisions.size();
if (m_skipUpdate)
return;

for (u32 i = 0; i < numCollision; i++)
{
CPickCollisionData** collisions = m_collision.pointer();
CWorldTransformData** transforms = m_transform.pointer();
CWorldInverseTransformData** invTransforms = m_invTransform.pointer();

CCamera* camera = entityManager->getCamera();

core::matrix4 invTrans;

u32 numEntity = m_collision.size();
for (u32 i = 0; i < numEntity; i++)
{
CWorldTransformData* transform = transforms[i];
CWorldInverseTransformData* invTransform = invTransforms[i];
CPickCollisionData* collision = collisions[i];

core::aabbox3df transformBBox = collision->BBox;
transform->World.transformBoxEx(transformBBox);

// 1. Detect by bounding box
SViewFrustum frust;

frust = camera->getViewFrustum();
bool visible = transformBBox.intersectsWithBox(frust.getBoundingBox());

// 2. Detect algorithm
if (visible == true && invTransform != NULL)
{
// transform the frustum to the node's current absolute transformation
invTrans = invTransform->WorldInverse;
frust.transform(invTrans);

core::vector3df edges[8];
collision->BBox.getEdges(edges);

for (s32 i = 0; i < scene::SViewFrustum::VF_PLANE_COUNT; ++i)
{
bool boxInFrustum = false;
for (u32 j = 0; j < 8; ++j)
{
if (frust.planes[i].classifyPointRelation(edges[j]) != core::ISREL3D_FRONT)
{
boxInFrustum = true;
break;
}
}

if (!boxInFrustum)
{
visible = false;
break;
}
}
}

if (visible)
m_results.push_back(collision);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ This file is part of the "Skylicht Engine".

#include "CPickCollisionData.h"
#include "Transform/CWorldTransformData.h"
#include "Transform/CWorldInverseTransformData.h"

#include "Camera/CCamera.h"

namespace Skylicht
{
Expand All @@ -37,20 +40,38 @@ namespace Skylicht
class CPickCollisionSystem : public IEntitySystem
{
protected:
core::array<CPickCollisionData*> m_pickCollisions;
core::array<CPickCollisionData*> m_results;

core::array<CPickCollisionData*> m_collision;
core::array<CWorldTransformData*> m_transform;
core::array<CWorldInverseTransformData*> m_invTransform;

CCamera* m_cullingCamera;

bool m_skipUpdate;

public:
CPickCollisionSystem();

virtual ~CPickCollisionSystem();

virtual void beginQuery();
virtual void beginQuery(CEntityManager* entityManager);

virtual void onQuery(CEntityManager* entityManager, CEntity* entity);

virtual void init(CEntityManager* entityManager);

virtual void update(CEntityManager* entityManager);

inline void setCullingCamera(CCamera* camera)
{
m_cullingCamera = camera;
}

inline core::array<CPickCollisionData*>& getCulledCollision()
{
return m_results;
}
};
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ namespace Skylicht

}

void CViewpointRenderer::beginQuery()
void CViewpointRenderer::beginQuery(CEntityManager* entityManager)
{
m_viewpoints.set_used(0);
m_transforms.set_used(0);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ namespace Skylicht

virtual ~CViewpointRenderer();

virtual void beginQuery();
virtual void beginQuery(CEntityManager* entityManager);

virtual void onQuery(CEntityManager* entityManager, CEntity* entity);

Expand Down
22 changes: 0 additions & 22 deletions Projects/Skylicht/Collision/Source/Collision/CCollisionNode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,26 +52,4 @@ namespace Skylicht
Selector->getTriangles(Triangles.pointer(), &world);
}
}

void CCollisionNode::updateBBox(const core::aabbox3df& box)
{
if (Selector != NULL)
{
Selector->updateBBox(box);
}
}

core::aabbox3df CCollisionNode::getTransformBBox()
{
core::aabbox3df ret;

if (Selector != NULL && Entity != NULL)
{
core::matrix4 world = GameObject->getTransform()->calcWorldTransform();
ret = Selector->getBBox();
world.transformBoxEx(ret);
}

return ret;
}
}
4 changes: 0 additions & 4 deletions Projects/Skylicht/Collision/Source/Collision/CCollisionNode.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,5 @@ namespace Skylicht
virtual ~CCollisionNode();

void updateTransform();

void updateBBox(const core::aabbox3df& box);

core::aabbox3df getTransformBBox();
};
}
Loading

0 comments on commit 85c2365

Please sign in to comment.