122 lines
3.8 KiB
C++
122 lines
3.8 KiB
C++
#include "StandardOctreeBuilder.h"
|
|
#include "../Util/Stopwatch.h"
|
|
#include "OctreeLoader.h"
|
|
|
|
#define DAGFINALTREE
|
|
|
|
StandardOctreeBuilder::StandardOctreeBuilder() :
|
|
BaseStandardOctreeBuilder(),
|
|
mTree(NULL)
|
|
{}
|
|
|
|
StandardOctreeBuilder::~StandardOctreeBuilder() {}
|
|
|
|
std::string StandardOctreeBuilder::GetTreeType() { return "s"; }
|
|
|
|
void StandardOctreeBuilder::FinalizeTree()
|
|
{
|
|
// Read all subtrees from cache and append them
|
|
if (!IsSinglePass())
|
|
{
|
|
Stopwatch watch;
|
|
mTree = new Tree<>(GetTreeDepth());
|
|
|
|
int i = 1;
|
|
for (const glm::uvec3& coord : GetValidCoords())
|
|
{
|
|
if (verbose) printf("Reading subtree %u / %u at (%u, %u, %u) from cache...\n", i, (unsigned32)(GetValidCoords().size()), coord.x, coord.y, coord.z);
|
|
Tree<>* subTree = (Tree<>*)OctreeLoader::ReadCache(GetTreeType(), GetSinglePassTreeDepth(), GetSinglePassTreeFilename(coord), verbose);
|
|
if (subTree != NULL)
|
|
{
|
|
if (verbose) printf("Appending subtree... ");
|
|
watch.Reset();
|
|
mTree->AppendAndMerge(coord, GetAppendedTreeLevel(), subTree);
|
|
//mTree->Append(mCurPassTreeCoord, mainTreeLevel, mCurPassTree);
|
|
delete subTree;
|
|
if (verbose) printf("Appended subtree in %d ms.\n", (int)(watch.GetTime() * 1000));
|
|
}
|
|
//mTree->SortNodes();
|
|
//#ifdef DAGFINALTREE
|
|
// if (verbose) printf("Converting current tree to DAG...\n");
|
|
// mTree->ToDAG(mainTreeLevel);
|
|
//#endif
|
|
|
|
i++;
|
|
}
|
|
|
|
// Delete the cache files
|
|
if (verbose) printf("Deleting cache...");
|
|
watch.Reset();
|
|
for (const glm::uvec3& coord : GetValidCoords())
|
|
OctreeLoader::DeleteCache(GetTreeType(), GetSinglePassTreeDepth(), GetSinglePassTreeFilename(coord));
|
|
if (verbose) printf("Cache deleted in %d ms\n", (int)(watch.GetTime() * 1000));
|
|
}
|
|
}
|
|
|
|
void StandardOctreeBuilder::TerminateTree()
|
|
{
|
|
OctreeLoader::WriteCache(mTree, GetTreeType(), GetOutputFile(), GetVerbose());
|
|
delete mTree;
|
|
}
|
|
|
|
bool StandardOctreeBuilder::CancelCurPassTree(const glm::uvec3& coord)
|
|
{
|
|
return OctreeLoader::VerifyCache(GetTreeType(), GetSinglePassTreeDepth(), GetSinglePassTreeFilename(coord));
|
|
}
|
|
|
|
void StandardOctreeBuilder::InitCurPassTree(glm::uvec3 coord)
|
|
{
|
|
mTree = new Tree<>(GetSinglePassTreeDepth());
|
|
}
|
|
|
|
void StandardOctreeBuilder::FinalizeCurPassTree(glm::uvec3 coord)
|
|
{
|
|
Stopwatch watch;
|
|
|
|
if (!mTree->IsEmpty()) // Only append the tree (and compress) if it is not empty
|
|
{
|
|
// Convert the subtree to a DAG first, this saved time when appending and converting the total tree.
|
|
// If it is a single pass tree it needs to be converted anyway :)
|
|
// Benchmark (Total build time for subtrees of depth 10, final tree of depth 12, run in Release mode with pool):
|
|
// 209.922 seconds without early converting
|
|
// 163.645 seconds with early converting
|
|
if (verbose) printf("Converting %s to DAG...\n", IsSinglePass() ? "tree" : "subtree");
|
|
watch.Reset();
|
|
//mCurPassTree->SortNodes();
|
|
mTree->ToDAG();
|
|
if (verbose) printf("Converting took %d ms.\n", (int)(watch.GetTime() * 1000));
|
|
|
|
if (!IsSinglePass())
|
|
{
|
|
if (verbose) printf("Writing subtree to cache...");
|
|
watch.Reset();
|
|
OctreeLoader::WriteCache(mTree, GetTreeType(), GetSinglePassTreeFilename(coord), verbose);
|
|
if (verbose) printf("Wrote cache in %d ms.\n", (int)(watch.GetTime() * 1000));
|
|
|
|
delete mTree;
|
|
mTree = NULL;
|
|
}
|
|
}
|
|
}
|
|
|
|
void StandardOctreeBuilder::AddNode(const glm::uvec3& coordinate)
|
|
{
|
|
mTree->AddLeafNode(coordinate);
|
|
}
|
|
|
|
std::vector<size_t> StandardOctreeBuilder::GetOctreeNodesPerLevel()
|
|
{
|
|
return mTree->GetOctreeNodesPerLevel();
|
|
}
|
|
|
|
std::vector<size_t> StandardOctreeBuilder::GetNodesPerLevel()
|
|
{
|
|
return mTree->GetNodesPerLevel();
|
|
}
|
|
|
|
std::string StandardOctreeBuilder::GetSinglePassTreeFilename(const glm::uvec3& coord) const
|
|
{
|
|
char buffer[255];
|
|
sprintf(buffer, "%s_%u_(%u_%u_%u)", GetOutputFile().c_str(), GetTreeDepth(), coord.x, coord.y, coord.z);
|
|
return std::string(buffer);
|
|
} |