I have a lot of non-moving/static objects in my scene so i thought i could speed up culling with octree instead with camera frustum-bbox check with all of these. Can you spot what am i doing wrong?
octree.h
class OcTree
{
private:
std::shared_ptr<OcTree> child[8];
sp_StaticMeshSceneNode sNode; // shared_ptr
bool leaf;
bounding_box3d bbox;
SceneManager* pSmgr;
enum OctreeParts
{
TOP_FRONT_LEFT = 0,
TOP_FRONT_RIGHT = 1,
TOP_BACK_LEFT = 2,
TOP_BACK_RIGHT = 3,
BOTTOM_FRONT_LEFT = 4,
BOTTOM_FRONT_RIGHT = 5,
BOTTOM_BACK_LEFT = 6,
BOTTOM_BACK_RIGHT = 7
};
public:
OcTree(SceneManager* _smgr, const bounding_box3d& _bbox);
void create(std::shared_ptr<OcTree> _tree);
bounding_box3d subdivide(std::shared_ptr<OcTree> _parent, int witchPart);
void cullChildren(std::shared_ptr<OcTree> _root);
static std::size_t levelCnt;
};
octree.cpp
std::size_t OcTree::levelCnt = 0;
OcTree::OcTree(SceneManager* _smgr, const bounding_box3d& _bbox)
{
bbox = _bbox;
pSmgr = _smgr;
for(std::size_t i = 0; i < 8; ++i)
{
child = nullptr;
}
leaf = false;
sNode = nullptr;
}
void OcTree::create(std::shared_ptr<OcTree> _tree)
{
++levelCnt;
std::size_t cnt = 0;
const auto& nodes = pSmgr->getNodes();
for(std::size_t i = 0; i < nodes.size(); ++i)
{
bool result = _tree->bbox.intersects(nodes->getBBox());
if(result)
{
sNode = nodes;
++cnt;
}
}
if(cnt <= 1)
{
_tree->leaf = true;
return;
}
else
{
sNode = nullptr;
for(std::size_t i = 0; i < 8; ++i)
{
child = std::shared_ptr<OcTree>(new OcTree(pSmgr, subdivide(_tree, i)));
create(child);
}
}
}
bounding_box3d OcTree::subdivide(std::shared_ptr<OcTree> _parent, int witchPart)
{
bounding_box3d outBB;
float3 ext = _parent->bbox.getExtent() * 0.5f; // (max - min) / 2
float3 cen = _parent->bbox.getCenter(); // (min + max) / 2
switch(witchPart)
{
case TOP_FRONT_LEFT:
{
float3 min = cen - float3(ext.x, 0.0f, 0.0f);
float3 max = cen + float3(0.0f, ext.y, ext.z);
outBB = oma::bounding_box3d(min, max);
}break;
case TOP_FRONT_RIGHT:
{
float3 min = cen;
float3 max = cen + float3(ext.x, ext.y, ext.z);
outBB = bounding_box3d(min, max);
}break;
case TOP_BACK_LEFT:
{
float3 min = cen - float3(ext.x, 0.0f, ext.z);
float3 max = cen + float3(0.0f, ext.y, 0.0f);
outBB = bounding_box3d(min, max);
}break;
case TOP_BACK_RIGHT:
{
float3 min = cen - float3(0.0f, 0.0f, ext.z);
float3 max = cen + float3(ext.x, ext.y, 0.0f);
outBB = bounding_box3d(min, max);
}break;
case BOTTOM_FRONT_LEFT:
{
float3 min = cen - float3(ext.x, ext.y, 0.0f);
float3 max = cen + float3(0.0f, 0.0f, ext.z);
outBB = bounding_box3d(min, max);
}break;
case BOTTOM_FRONT_RIGHT:
{
float3 min = cen - float3(0.0f, ext.y, 0.0f);
float3 max = cen + float3(ext.x, 0.0f, ext.z);
outBB = bounding_box3d(min, max);
}break;
case BOTTOM_BACK_LEFT:
{
float3 min = cen - float3(ext.x, ext.y, ext.z);
float3 max = cen;
outBB = bounding_box3d(min, max);
}break;
case BOTTOM_BACK_RIGHT:
{
float3 min = cen - float3(0.0f, ext.y, ext.z);
float3 max = cen + float3(ext.x, 0.0f, 0.0f);
outBB = bounding_box3d(min, max);
}break;
default:
{
assert(false);
}break;
};
return outBB;
}
void OcTree::cullChildren(std::shared_ptr<OcTree> _root)
{
if(nullptr == _root)
return;
sp_Camera cam = pSmgr->getPlayerCamera();
if(cam->getFrustum().isBoxInFrustum(_root->bbox))
{
if(_root->leaf)
{
if(nullptr != _root->sNode)
_root->sNode->visible = true;
}
else
{
for(std::size_t i = 0; i < 8; ++i)
{
cullChildren(_root->child);
}
}
}
}
Then i create octree:
bounding_box3d ocBB(float3(-8.1028748f, -10.665000f, -147.71899f), float3(270.58899f, 18.529583f, 98.760002f));
ocTree = std::shared_ptr<OcTree>(new OcTree(this, ocBB));
ocTree->create(ocTree); // stack overflow
Stack overflow is in create method.
Thank you for your time.