From aacd4f6c9ee90622fa895971c33e24e3bf410090 Mon Sep 17 00:00:00 2001 From: Godzil Date: Fri, 13 Mar 2020 01:07:28 +0000 Subject: [PATCH] Make BVH and Octree to not flatten the world before parsing It may help a lot on some scene that already use groups. So each exiting group have their own BVH or Octree in. It does help a lot on already organised scene like the Christmas balls. --- source/worldoptimiser/octreeoptimisation.cpp | 118 +++++++++---------- 1 file changed, 58 insertions(+), 60 deletions(-) diff --git a/source/worldoptimiser/octreeoptimisation.cpp b/source/worldoptimiser/octreeoptimisation.cpp index 29046fa..3160644 100644 --- a/source/worldoptimiser/octreeoptimisation.cpp +++ b/source/worldoptimiser/octreeoptimisation.cpp @@ -8,6 +8,7 @@ */ #include #include +#include #include void OctreeOptimisation::makeTree(Group *leaf, int depth) @@ -19,103 +20,100 @@ void OctreeOptimisation::makeTree(Group *leaf, int depth) double midX = (rootBB.max.x - rootBB.min.x) / 2.0 + rootBB.min.x; double midY = (rootBB.max.y - rootBB.min.y) / 2.0 + rootBB.min.y; double midZ = (rootBB.max.z - rootBB.min.z) / 2.0 + rootBB.min.z; - BoundingBox QuadrantBB[8]; - int quadrantIdx; - Group *Quadrants[8]; + BoundingBox octantBB[8]; + int octantIdx; + Group *octants[8]; int i; - if (leaf->getObjectCount() > 2) + //if (leaf->getObjectCount() > 2) { /* Split the main bounding box into 8 boxes */ - QuadrantBB[0] | Point(rootBB.min.x, rootBB.min.y, rootBB.min.z); - QuadrantBB[0] | Point(midX, midY, midZ); + octantBB[0] | Point(rootBB.min.x, rootBB.min.y, rootBB.min.z); + octantBB[0] | Point(midX, midY, midZ); - QuadrantBB[1] | Point(midX, rootBB.min.y, rootBB.min.z); - QuadrantBB[1] | Point(rootBB.max.x, midY, midZ); + octantBB[1] | Point(midX, rootBB.min.y, rootBB.min.z); + octantBB[1] | Point(rootBB.max.x, midY, midZ); - QuadrantBB[2] | Point(rootBB.min.x, midY, rootBB.min.z); - QuadrantBB[2] | Point(midX, rootBB.max.y, midZ); + octantBB[2] | Point(rootBB.min.x, midY, rootBB.min.z); + octantBB[2] | Point(midX, rootBB.max.y, midZ); - QuadrantBB[3] | Point(midX, midY, rootBB.min.z); - QuadrantBB[3] | Point(rootBB.max.x, rootBB.max.y, midZ); + octantBB[3] | Point(midX, midY, rootBB.min.z); + octantBB[3] | Point(rootBB.max.x, rootBB.max.y, midZ); - QuadrantBB[4] | Point(rootBB.min.x, midY, midZ); - QuadrantBB[4] | Point(midX, rootBB.max.y, rootBB.max.z); + octantBB[4] | Point(rootBB.min.x, midY, midZ); + octantBB[4] | Point(midX, rootBB.max.y, rootBB.max.z); - QuadrantBB[5] | Point(midX, midY, midZ); - QuadrantBB[5] | Point(rootBB.max.x, rootBB.max.y, rootBB.max.z); + octantBB[5] | Point(midX, midY, midZ); + octantBB[5] | Point(rootBB.max.x, rootBB.max.y, rootBB.max.z); - QuadrantBB[6] | Point(rootBB.min.x, rootBB.min.y, midZ); - QuadrantBB[6] | Point(midX, midY, rootBB.max.z); + octantBB[6] | Point(rootBB.min.x, rootBB.min.y, midZ); + octantBB[6] | Point(midX, midY, rootBB.max.z); - QuadrantBB[7] | Point(midX, rootBB.min.y, midZ); - QuadrantBB[7] | Point(rootBB.max.x, midY, rootBB.max.z); + octantBB[7] | Point(midX, rootBB.min.y, midZ); + octantBB[7] | Point(rootBB.max.x, midY, rootBB.max.z); - for (quadrantIdx = 0 ; quadrantIdx < 8 ; quadrantIdx++) + for (octantIdx = 0 ; octantIdx < 8 ; octantIdx++) { - Quadrants[quadrantIdx] = nullptr; + octants[octantIdx] = nullptr; } for (i = 0 ; i < leaf->getObjectCount(); i++) { Shape *shp = leaf->getObject(i); - if ((shp->getType() != Shape::GROUP) && (shp->getType() != Shape::OBJFILE)) + + BoundingBox objBB = shp->getBounds(); + //if ((shp->getType() != Shape::GROUP) && (shp->getType() != Shape::OBJFILE)) + for (octantIdx = 0 ; octantIdx < 8 ; octantIdx++) { - BoundingBox objBB = shp->getBounds(); - - for (quadrantIdx = 0 ; quadrantIdx < 8 ; quadrantIdx++) + if (octantBB[octantIdx].fitsIn(objBB)) { - if (QuadrantBB[quadrantIdx].fitsIn(objBB)) + if (octants[octantIdx] == nullptr) { - if (Quadrants[quadrantIdx] == nullptr) - { - char name[32]; - snprintf(name, 32, "%d_Quadrant %d", depth, quadrantIdx); - //for(int j=0; j < depth; j++) { printf(" "); } - //printf("%s\n", name); - Quadrants[quadrantIdx] = new Group(name); + char name[32]; + snprintf(name, 32, "%d_Quadrant %d", depth, octantIdx); + octants[octantIdx] = new Group(name); - Quadrants[quadrantIdx]->setBounds(QuadrantBB[quadrantIdx]); - } - - Quadrants[quadrantIdx]->addObject(shp); - leaf->removeObject(shp); - - i -= 1; - break; + octants[octantIdx]->setBounds(octantBB[octantIdx]); } + + octants[octantIdx]->addObject(shp); + leaf->removeObject(shp); + + i -= 1; + break; } } - else + if (shp->getType() == Shape::GROUP) { - leaf->removeObject(shp); - /* No cleanup for now, it's bad, I know */ - //delete shp; - i -= 1; + this->makeTree((Group *)shp, depth + 1); + } + if (shp->getType() == Shape::OBJFILE) + { + this->makeTree((Group *)((OBJFile *)shp)->getBaseGroup(), depth + 1); } } //if (depth < 1) { /* Now add the quadrant to the root and recurse in it */ - for (quadrantIdx = 0 ; quadrantIdx < 8 ; quadrantIdx++) + for (octantIdx = 0 ; octantIdx < 8 ; octantIdx++) { - if (Quadrants[quadrantIdx] != nullptr) + if (octants[octantIdx] != nullptr) { - this->makeTree(Quadrants[quadrantIdx], depth + 1); + this->makeTree(octants[octantIdx], depth + 1); - Quadrants[quadrantIdx]->updateBoundingBox(); + octants[octantIdx]->updateBoundingBox(); - leaf->addObject(Quadrants[quadrantIdx]); + leaf->addObject(octants[octantIdx]); #if 0 Cube *cb = new Cube(); - double sx = QuadrantBB[quadrantIdx].max.x - QuadrantBB[quadrantIdx].min.x; - double sy = QuadrantBB[quadrantIdx].max.y - QuadrantBB[quadrantIdx].min.y; - double sz = QuadrantBB[quadrantIdx].max.z - QuadrantBB[quadrantIdx].min.z; + double sx = octantBB[octantIdx].max.x - octantBB[octantIdx].min.x; + double sy = octantBB[octantIdx].max.y - octantBB[octantIdx].min.y; + double sz = octantBB[octantIdx].max.z - octantBB[octantIdx].min.z; - cb->setTransform(translation(QuadrantBB[quadrantIdx].min.x, QuadrantBB[quadrantIdx].min.y, - QuadrantBB[quadrantIdx].min.z) * scaling(sx, sy, sz)); + cb->setTransform(translation(octantBB[octantIdx].min.x, octantBB[octantIdx].min.y, + octantBB[octantIdx].min.z) * scaling(sx, sy, sz)); cb->material.colour = Colour(0.01, 0.01, 0); cb->materialSet = true; cb->dropShadow = false; @@ -126,8 +124,8 @@ void OctreeOptimisation::makeTree(Group *leaf, int depth) cb->material.specular = 0; leaf->addObject(cb); - printf("%s: %d objs\n", Quadrants[quadrantIdx]->getName(), - Quadrants[quadrantIdx]->getObjectCount()); + printf("%s: %d objs\n", octants[octantIdx]->getName(), + octants[octantIdx]->getObjectCount()); #endif } } @@ -141,7 +139,7 @@ void OctreeOptimisation::run() this->moveInfiniteObjects(); /* Then let's have some fun! */ - this->moveAllObjects(); + //this->moveAllObjects(); /* Now.. The fun start ! */ makeTree(this->root, 0);