Skip to content

Commit

Permalink
#80 Add bbox patch to group all small boundingbox
Browse files Browse the repository at this point in the history
  • Loading branch information
ducphamhong committed Oct 12, 2021
1 parent 6229ac4 commit 7018d87
Show file tree
Hide file tree
Showing 7 changed files with 194 additions and 21 deletions.
18 changes: 14 additions & 4 deletions Projects/Editor/Source/Editor/Space/Scene/CSpaceScene.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -266,16 +266,26 @@ namespace Skylicht
CGameObject* lightObj = zone->createEmptyObject();
lightObj->setName(L"DirectionLight");

CDirectionalLight* directionalLight = lightObj->addComponent<CDirectionalLight>();
SColor c(255, 255, 244, 214);
directionalLight->setColor(SColorf(c));

CTransformEuler* lightTransform = lightObj->getTransformEuler();
lightTransform->setPosition(core::vector3df(2.0f, 2.0f, 2.0f));

core::vector3df direction = core::vector3df(0.0f, -1.5f, 2.0f);
lightTransform->setOrientation(direction, CTransform::s_oy);

CDirectionalLight* directionalLight = lightObj->addComponent<CDirectionalLight>();
SColor c(255, 255, 244, 214);
directionalLight->setColor(SColorf(c));

lightObj = zone->createEmptyObject();
lightObj->setName(L"DirectionLight 1");

lightTransform = lightObj->getTransformEuler();
lightTransform->setPosition(core::vector3df(120.0f, 2.0f, 120.0f));

directionalLight = lightObj->addComponent<CDirectionalLight>();
c = SColor(255, 255, 244, 214);
directionalLight->setColor(SColorf(c));

// update search index
m_scene->updateAddRemoveObject();
m_scene->updateIndexSearchObject();
Expand Down
144 changes: 139 additions & 5 deletions Projects/Skylicht/Collision/Source/Collision/CBBoxPatchBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ This file is part of the "Skylicht Engine".

namespace Skylicht
{
CBBoxPatchBuilder::CBBoxPatchBuilder()
CBBoxPatchBuilder::CBBoxPatchBuilder() :
m_patchSize(100.0f)
{

}
Expand All @@ -39,27 +40,160 @@ namespace Skylicht

void CBBoxPatchBuilder::clear()
{
for (int i = 0, n = m_patchs.size(); i < n; i++)
delete m_patchs[i];

m_patchs.set_used(0);
m_collisionPatchs.set_used(0);

CCollisionBuilder::clear();
}

void CBBoxPatchBuilder::build()
{
// delete old patchs
for (int i = 0, n = m_patchs.size(); i < n; i++)
delete m_patchs[i];

m_patchs.set_used(0);
m_collisionPatchs.set_used(0);

const u32 start = os::Timer::getRealTime();
u32 numPoly = 0;

core::aabbox3df size;

// step 1: caculator the box size
for (u32 i = 0, n = m_nodes.size(); i < n; i++)
{
if (i == 0)
size = m_nodes[i]->getTransformBBox();
m_size = m_nodes[i]->getTransformBBox();
else
size.addInternalBox(m_nodes[i]->getTransformBBox());
m_size.addInternalBox(m_nodes[i]->getTransformBBox());
}

// step 2: caculator num patch
core::vector3df s = m_size.getExtent();

m_numX = core::ceil32(s.X / m_patchSize);
m_numY = core::ceil32(s.Y / m_patchSize);
m_numZ = core::ceil32(s.Z / m_patchSize);

for (int x = 0; x < m_numX; x++)
{
for (int z = 0; z < m_numZ; z++)
{
for (int y = 0; y < m_numY; y++)
{
m_patchs.push_back(new SPatch());

SPatch& p = *(m_patchs.getLast());
p.X = x;
p.Y = y;
p.Z = z;

p.BBox.MinEdge = m_size.MinEdge + core::vector3df(x * m_patchSize, y * m_patchSize, z * m_patchSize);
p.BBox.MaxEdge = p.BBox.MinEdge + core::vector3df(m_patchSize, m_patchSize, m_patchSize);
}
}
}

// step 3: index nodes to patch
for (u32 i = 0, n = m_nodes.size(); i < n; i++)
{
addNodeToPatch(m_nodes[i]);
}

// step4: collect the patch have collisions
for (u32 i = 0, n = m_patchs.size(); i < n; i++)
{
if (m_patchs[i]->Collisions.size() > 0)
{
m_collisionPatchs.push_back(m_patchs[i]);
}
}


c8 tmp[256];
sprintf(tmp, "Needed %ums to CBBoxPatchBuilder::build", os::Timer::getRealTime() - start);
os::Printer::log(tmp, ELL_INFORMATION);
}

CBBoxPatchBuilder::SPatch* CBBoxPatchBuilder::getPatch(int x, int y, int z)
{
int id = x * m_numZ * m_numY + z * m_numY + y;
if (id < 0 || id >= (int)m_patchs.size())
return NULL;
return m_patchs[id];
}

void CBBoxPatchBuilder::addNodeToPatch(CCollisionNode* collision)
{
core::aabbox3df bbox = collision->getTransformBBox();
int x1 = core::floor32((bbox.MinEdge.X - m_size.MinEdge.X) / m_patchSize);
int y1 = core::floor32((bbox.MinEdge.Y - m_size.MinEdge.Y) / m_patchSize);
int z1 = core::floor32((bbox.MinEdge.Z - m_size.MinEdge.Z) / m_patchSize);

int x2 = core::floor32((bbox.MaxEdge.X - m_size.MinEdge.X) / m_patchSize);
int y2 = core::floor32((bbox.MaxEdge.Y - m_size.MinEdge.Y) / m_patchSize);
int z2 = core::floor32((bbox.MaxEdge.Z - m_size.MinEdge.Z) / m_patchSize);

for (int x = x1; x <= x2; x++)
{
for (int z = z1; z <= z2; z++)
{
for (int y = y1; y <= y2; y++)
{
SPatch* patch = getPatch(x, y, z);
if (patch)
{
if (patch->BBox.intersectsWithBox(bbox))
{
patch->Collisions.push_back(collision);
}
}
}
}
}
}

void CBBoxPatchBuilder::removeNode(CCollisionNode* collision)
{
core::aabbox3df bbox = collision->getTransformBBox();
int x1 = core::floor32((bbox.MinEdge.X - m_size.MinEdge.X) / m_patchSize);
int y1 = core::floor32((bbox.MinEdge.Y - m_size.MinEdge.Y) / m_patchSize);
int z1 = core::floor32((bbox.MinEdge.Z - m_size.MinEdge.Z) / m_patchSize);

int x2 = core::floor32((bbox.MaxEdge.X - m_size.MinEdge.X) / m_patchSize);
int y2 = core::floor32((bbox.MaxEdge.Y - m_size.MinEdge.Y) / m_patchSize);
int z2 = core::floor32((bbox.MaxEdge.Z - m_size.MinEdge.Z) / m_patchSize);

for (int x = x1; x <= x2; x++)
{
for (int z = z1; z <= z2; z++)
{
for (int y = y1; y <= y2; y++)
{
SPatch* patch = getPatch(x, y, z);
if (patch)
{
if (patch->BBox.intersectsWithBox(bbox))
{
removeNode(collision, patch);
}
}
}
}
}
}

void CBBoxPatchBuilder::removeNode(CCollisionNode* collision, SPatch* patch)
{
for (int i = 0, n = patch->Collisions.size(); i < n; i++)
{
if (patch->Collisions[i] == collision)
{
patch->Collisions.erase(i);
return;
}
}
}
}
27 changes: 27 additions & 0 deletions Projects/Skylicht/Collision/Source/Collision/CBBoxPatchBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,23 @@ namespace Skylicht
{
class CBBoxPatchBuilder : public CCollisionBuilder
{
protected:
struct SPatch
{
core::aabbox3df BBox;
int X;
int Y;
int Z;
core::array<CCollisionNode*> Collisions;
};

core::array<SPatch*> m_collisionPatchs;
core::array<SPatch*> m_patchs;
core::aabbox3df m_size;
float m_patchSize;
int m_numX;
int m_numY;
int m_numZ;
public:
CBBoxPatchBuilder();

Expand All @@ -38,5 +55,15 @@ namespace Skylicht
virtual void clear();

virtual void build();

SPatch* getPatch(int x, int y, int z);

void addNodeToPatch(CCollisionNode* collision);

void removeNode(CCollisionNode* collision);

protected:
void removeNode(CCollisionNode* collision, SPatch *patch);

};
}
Original file line number Diff line number Diff line change
Expand Up @@ -94,8 +94,6 @@ namespace Skylicht
}
}
}

build();
}

void CCollisionBuilder::clear()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,9 @@ namespace Skylicht

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

return ret;
Expand Down
16 changes: 8 additions & 8 deletions Projects/Skylicht/Engine/Source/Graphics2D/CGraphics2D.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -570,7 +570,7 @@ namespace Skylicht
m_indices->set_used(indexUse);

// get indices pointer
s16* indices = (s16*)m_indices->getIndices();
u16* indices = (u16*)m_indices->getIndices();
indices += numIndices;

float texWidth = 512.0f;
Expand All @@ -583,7 +583,7 @@ namespace Skylicht
}

{
s16* ib = indices;
u16* ib = indices;
video::S3DVertex* vb = vertices;
int vertex = numVertices;

Expand Down Expand Up @@ -680,7 +680,7 @@ namespace Skylicht
m_indices->set_used(indexUse);

// get indices pointer
s16* indices = (s16*)m_indices->getIndices();
u16* indices = (u16*)m_indices->getIndices();
indices += numIndices;

float texWidth = 512.0f;
Expand All @@ -694,7 +694,7 @@ namespace Skylicht

for (int i = 0; i < numRect; i++)
{
s16* ib = indices + i * 6;
u16* ib = indices + i * 6;
video::S3DVertex* vb = vertices + i * 4;
int vertex = numVertices + i * 4;

Expand Down Expand Up @@ -826,7 +826,7 @@ namespace Skylicht
m_indices->set_used(indexUse);

// get indices pointer
s16* indices = (s16*)m_indices->getIndices();
u16* indices = (u16*)m_indices->getIndices();
indices += numIndices;

float texWidth = 512.0f;
Expand All @@ -840,7 +840,7 @@ namespace Skylicht

for (int i = 0; i < numRect; i++)
{
s16* ib = indices + i * 6;
u16* ib = indices + i * 6;
video::S3DVertex* vb = vertices + i * 4;
int vertex = numVertices + i * 4;

Expand Down Expand Up @@ -976,7 +976,7 @@ namespace Skylicht
m_indices->set_used(indexUse);

// get indices pointer
s16* indices = (s16*)m_indices->getIndices();
u16* indices = (u16*)m_indices->getIndices();
indices += numIndices;

float texWidth = 512.0f;
Expand All @@ -990,7 +990,7 @@ namespace Skylicht

for (int i = 0; i < numRect; i++)
{
s16* ib = indices + i * 6;
u16* ib = indices + i * 6;
video::S3DVertex* vb = vertices + i * 4;
int vertex = numVertices + i * 4;

Expand Down
4 changes: 4 additions & 0 deletions Projects/Template/Platforms/Win32/MainW32.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -442,6 +442,7 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
break;
case WM_WINDOWPOSCHANGED:
#if defined(SKYLICHT_EDITOR)
/*
RECT client;
WINDOWPLACEMENT wndpl;
GetWindowPlacement(hWnd, &wndpl);
Expand All @@ -453,6 +454,7 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
client.bottom - client.top,
wndpl.showCmd == SW_SHOWMAXIMIZED
);
*/
#endif
return DefWindowProc(hWnd, message, wParam, lParam);
case WM_SIZE:
Expand All @@ -471,6 +473,7 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
dev->postEventFromUser(resize);
}
#if defined(SKYLICHT_EDITOR)
/*
RECT client;
WINDOWPLACEMENT wndpl;
GetWindowPlacement(hWnd, &wndpl);
Expand All @@ -482,6 +485,7 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
client.bottom - client.top,
wndpl.showCmd == SW_SHOWMAXIMIZED
);
*/
#endif
}
return DefWindowProc(hWnd, message, wParam, lParam);
Expand Down

0 comments on commit 7018d87

Please sign in to comment.