
#include <WFX/scene/OctreeBuilder.h>
#include <WFX/scene/BoundingCubeFinder.h>
#include <WFX/scene/SceneGraphTransformer.h>

using namespace WFX;
using namespace WFX::scene;
using namespace WFX::math;
using namespace std;

UInt OctreeBuilder::MaxFaces = 250;
UInt OctreeBuilder::MaxDivisions = 10;

OctreeBuilder::OctreeBuilder() {
    RootNode = new OctreeNode(OctreeNode::TOP_LEFT_FRONT);
    SourceNodes = new Node();
}

OctreeBuilder::~OctreeBuilder() {
    deleteSources();
}

void OctreeBuilder::build() {
    LOG("building Octree " << SourceNodes->size());

    //transform all Vertices in Tree
    SceneGraphTransformer t;
    SourceNodes->accept(t);

    //find bounding cube
    BoundingCubeFinder f;
    SourceNodes->accept(f);
    RootNode->setBoundingCube(f.getBoundingCube().clone());
    f.getBoundingCube().printDebug();

    //visit all source nodes and insert them
    SourceNodes->accept(*this);

}

void OctreeBuilder::visitNode(Node& n) {
    std::list<Spatial*>::iterator it;
    for (it = n.Children.begin(); it != n.Children.end(); it++) {
        (*it)->accept(*this);
    }
}

void OctreeBuilder::visitTriMesh(TriMesh& m) {
    RootNode->addTriMesh(m, 0);
}

void OctreeBuilder::visitOctreeNode(OctreeNode& n) {
    THROW("visitOctreeNode: not yet implemented");
}

void OctreeBuilder::deleteSources() {
    if (SourceNodes)
        delete SourceNodes;
    SourceNodes = NULL;
}

