From 7018d875c12ded4418e4fb6cf514927453e1a289 Mon Sep 17 00:00:00 2001 From: Pham Hong Duc Date: Tue, 12 Oct 2021 22:14:29 +0700 Subject: [PATCH] #80 Add bbox patch to group all small boundingbox --- .../Source/Editor/Space/Scene/CSpaceScene.cpp | 18 ++- .../Source/Collision/CBBoxPatchBuilder.cpp | 144 +++++++++++++++++- .../Source/Collision/CBBoxPatchBuilder.h | 27 ++++ .../Source/Collision/CCollisionBuilder.cpp | 2 - .../Source/Collision/CCollisionNode.cpp | 4 +- .../Engine/Source/Graphics2D/CGraphics2D.cpp | 16 +- Projects/Template/Platforms/Win32/MainW32.cpp | 4 + 7 files changed, 194 insertions(+), 21 deletions(-) diff --git a/Projects/Editor/Source/Editor/Space/Scene/CSpaceScene.cpp b/Projects/Editor/Source/Editor/Space/Scene/CSpaceScene.cpp index 666dc0c65..553b61186 100644 --- a/Projects/Editor/Source/Editor/Space/Scene/CSpaceScene.cpp +++ b/Projects/Editor/Source/Editor/Space/Scene/CSpaceScene.cpp @@ -266,16 +266,26 @@ namespace Skylicht CGameObject* lightObj = zone->createEmptyObject(); lightObj->setName(L"DirectionLight"); - CDirectionalLight* directionalLight = lightObj->addComponent(); - 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(); + 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(); + c = SColor(255, 255, 244, 214); + directionalLight->setColor(SColorf(c)); + // update search index m_scene->updateAddRemoveObject(); m_scene->updateIndexSearchObject(); diff --git a/Projects/Skylicht/Collision/Source/Collision/CBBoxPatchBuilder.cpp b/Projects/Skylicht/Collision/Source/Collision/CBBoxPatchBuilder.cpp index 32510a97a..ce33d68ea 100644 --- a/Projects/Skylicht/Collision/Source/Collision/CBBoxPatchBuilder.cpp +++ b/Projects/Skylicht/Collision/Source/Collision/CBBoxPatchBuilder.cpp @@ -27,7 +27,8 @@ This file is part of the "Skylicht Engine". namespace Skylicht { - CBBoxPatchBuilder::CBBoxPatchBuilder() + CBBoxPatchBuilder::CBBoxPatchBuilder() : + m_patchSize(100.0f) { } @@ -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; + } + } + } } \ No newline at end of file diff --git a/Projects/Skylicht/Collision/Source/Collision/CBBoxPatchBuilder.h b/Projects/Skylicht/Collision/Source/Collision/CBBoxPatchBuilder.h index 82661dcd5..4f1c05aff 100644 --- a/Projects/Skylicht/Collision/Source/Collision/CBBoxPatchBuilder.h +++ b/Projects/Skylicht/Collision/Source/Collision/CBBoxPatchBuilder.h @@ -30,6 +30,23 @@ namespace Skylicht { class CBBoxPatchBuilder : public CCollisionBuilder { + protected: + struct SPatch + { + core::aabbox3df BBox; + int X; + int Y; + int Z; + core::array Collisions; + }; + + core::array m_collisionPatchs; + core::array m_patchs; + core::aabbox3df m_size; + float m_patchSize; + int m_numX; + int m_numY; + int m_numZ; public: CBBoxPatchBuilder(); @@ -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); + }; } \ No newline at end of file diff --git a/Projects/Skylicht/Collision/Source/Collision/CCollisionBuilder.cpp b/Projects/Skylicht/Collision/Source/Collision/CCollisionBuilder.cpp index e068b6438..b19ff3cb8 100644 --- a/Projects/Skylicht/Collision/Source/Collision/CCollisionBuilder.cpp +++ b/Projects/Skylicht/Collision/Source/Collision/CCollisionBuilder.cpp @@ -94,8 +94,6 @@ namespace Skylicht } } } - - build(); } void CCollisionBuilder::clear() diff --git a/Projects/Skylicht/Collision/Source/Collision/CCollisionNode.cpp b/Projects/Skylicht/Collision/Source/Collision/CCollisionNode.cpp index da11c041d..e1d10b491 100644 --- a/Projects/Skylicht/Collision/Source/Collision/CCollisionNode.cpp +++ b/Projects/Skylicht/Collision/Source/Collision/CCollisionNode.cpp @@ -59,9 +59,9 @@ namespace Skylicht if (Selector != NULL && Entity != NULL) { - CWorldTransformData* world = Entity->getData(); + core::matrix4 world = GameObject->getTransform()->calcWorldTransform(); ret = Selector->getBBox(); - world->World.transformBoxEx(ret); + world.transformBoxEx(ret); } return ret; diff --git a/Projects/Skylicht/Engine/Source/Graphics2D/CGraphics2D.cpp b/Projects/Skylicht/Engine/Source/Graphics2D/CGraphics2D.cpp index 3b54a141b..b6a1160c7 100644 --- a/Projects/Skylicht/Engine/Source/Graphics2D/CGraphics2D.cpp +++ b/Projects/Skylicht/Engine/Source/Graphics2D/CGraphics2D.cpp @@ -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; @@ -583,7 +583,7 @@ namespace Skylicht } { - s16* ib = indices; + u16* ib = indices; video::S3DVertex* vb = vertices; int vertex = numVertices; @@ -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; @@ -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; @@ -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; @@ -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; @@ -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; @@ -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; diff --git a/Projects/Template/Platforms/Win32/MainW32.cpp b/Projects/Template/Platforms/Win32/MainW32.cpp index 90d6ec333..6ab4d5c73 100644 --- a/Projects/Template/Platforms/Win32/MainW32.cpp +++ b/Projects/Template/Platforms/Win32/MainW32.cpp @@ -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); @@ -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: @@ -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); @@ -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);