mirror of
https://github.com/AleziaKurdis/overte.git
synced 2025-04-14 06:46:58 +02:00
implement SVO fill down in voxel-edit
This commit is contained in:
parent
cde5ffbbf9
commit
02bc25f797
1 changed files with 188 additions and 79 deletions
|
@ -55,6 +55,184 @@ void voxelTutorial(VoxelTree * tree) {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
void processSplitSVOFile(const char* splitSVOFile,const char* splitJurisdictionRoot,const char* splitJurisdictionEndNodes) {
|
||||
char outputFileName[512];
|
||||
|
||||
printf("splitSVOFile: %s Jurisdictions Root: %s EndNodes: %s\n",
|
||||
splitSVOFile, splitJurisdictionRoot, splitJurisdictionEndNodes);
|
||||
|
||||
VoxelTree rootSVO;
|
||||
|
||||
rootSVO.readFromSVOFile(splitSVOFile);
|
||||
JurisdictionMap jurisdiction(splitJurisdictionRoot, splitJurisdictionEndNodes);
|
||||
|
||||
printf("Jurisdiction Root Octcode: ");
|
||||
printOctalCode(jurisdiction.getRootOctalCode());
|
||||
|
||||
printf("Jurisdiction End Nodes: %d \n", jurisdiction.getEndNodeCount());
|
||||
for (int i = 0; i < jurisdiction.getEndNodeCount(); i++) {
|
||||
unsigned char* endNodeCode = jurisdiction.getEndNodeOctalCode(i);
|
||||
printf("End Node: %d ", i);
|
||||
printOctalCode(endNodeCode);
|
||||
|
||||
// get the endNode details
|
||||
VoxelPositionSize endNodeDetails;
|
||||
voxelDetailsForCode(endNodeCode, endNodeDetails);
|
||||
|
||||
// Now, create a split SVO for the EndNode.
|
||||
// copy the EndNode into a temporary tree
|
||||
VoxelTree endNodeTree;
|
||||
|
||||
// create a small voxels at corners of the endNode Tree, this will is a hack
|
||||
// to work around a bug in voxel server that will send Voxel not exists
|
||||
// for regions that don't contain anything even if they're not in the
|
||||
// jurisdiction of the server
|
||||
// This hack assumes the end nodes for demo dinner since it only guarantees
|
||||
// nodes in the 8 child voxels of the main root voxel
|
||||
const float verySmall = 0.015625;
|
||||
endNodeTree.createVoxel(0.0, 0.0, 0.0, verySmall, 1, 1, 1, true);
|
||||
endNodeTree.createVoxel(1.0, 0.0, 0.0, verySmall, 1, 1, 1, true);
|
||||
endNodeTree.createVoxel(0.0, 1.0, 0.0, verySmall, 1, 1, 1, true);
|
||||
endNodeTree.createVoxel(0.0, 0.0, 1.0, verySmall, 1, 1, 1, true);
|
||||
endNodeTree.createVoxel(1.0, 1.0, 1.0, verySmall, 1, 1, 1, true);
|
||||
endNodeTree.createVoxel(1.0, 1.0, 0.0, verySmall, 1, 1, 1, true);
|
||||
endNodeTree.createVoxel(0.0, 1.0, 1.0, verySmall, 1, 1, 1, true);
|
||||
endNodeTree.createVoxel(1.0, 0.0, 1.0, verySmall, 1, 1, 1, true);
|
||||
|
||||
// Delete the voxel for the EndNode from the temporary tree, so we can
|
||||
// import our endNode content into it...
|
||||
endNodeTree.deleteVoxelCodeFromTree(endNodeCode, COLLAPSE_EMPTY_TREE);
|
||||
|
||||
VoxelNode* endNode = rootSVO.getVoxelAt(endNodeDetails.x,
|
||||
endNodeDetails.y,
|
||||
endNodeDetails.z,
|
||||
endNodeDetails.s);
|
||||
|
||||
rootSVO.copySubTreeIntoNewTree(endNode, &endNodeTree, false);
|
||||
|
||||
sprintf(outputFileName, "splitENDNODE%d%s", i, splitSVOFile);
|
||||
printf("outputFile: %s\n", outputFileName);
|
||||
endNodeTree.writeToSVOFile(outputFileName);
|
||||
|
||||
// Delete the voxel for the EndNode from the root tree...
|
||||
rootSVO.deleteVoxelCodeFromTree(endNodeCode, COLLAPSE_EMPTY_TREE);
|
||||
|
||||
// create a small voxel in center of each EndNode, this will is a hack
|
||||
// to work around a bug in voxel server that will send Voxel not exists
|
||||
// for regions that don't contain anything even if they're not in the
|
||||
// jurisdiction of the server
|
||||
float x = endNodeDetails.x + endNodeDetails.s * 0.5;
|
||||
float y = endNodeDetails.y + endNodeDetails.s * 0.5;
|
||||
float z = endNodeDetails.z + endNodeDetails.s * 0.5;
|
||||
float s = endNodeDetails.s * verySmall;
|
||||
|
||||
rootSVO.createVoxel(x, y, z, s, 1, 1, 1, true);
|
||||
|
||||
}
|
||||
|
||||
sprintf(outputFileName, "splitROOT%s", splitSVOFile);
|
||||
printf("outputFile: %s\n", outputFileName);
|
||||
rootSVO.writeToSVOFile(outputFileName);
|
||||
|
||||
printf("exiting now\n");
|
||||
}
|
||||
|
||||
class copyAndFillArgs {
|
||||
public:
|
||||
VoxelTree* destinationTree;
|
||||
unsigned long outCount;
|
||||
unsigned long inCount;
|
||||
unsigned long originalCount;
|
||||
|
||||
};
|
||||
|
||||
bool copyAndFillOperation(VoxelNode* node, void* extraData) {
|
||||
copyAndFillArgs* args = (copyAndFillArgs*)extraData;
|
||||
char outputMessage[128];
|
||||
|
||||
args->inCount++;
|
||||
int percentDone = (100*args->inCount/args->originalCount);
|
||||
|
||||
// For each leaf node...
|
||||
if (node->isLeaf()) {
|
||||
// create a copy of the leaf in the copy destination
|
||||
float x = node->getCorner().x;
|
||||
float y = node->getCorner().y;
|
||||
float z = node->getCorner().z;
|
||||
float s = node->getScale();
|
||||
unsigned char red = node->getTrueColor()[RED_INDEX];
|
||||
unsigned char green = node->getTrueColor()[GREEN_INDEX];
|
||||
unsigned char blue = node->getTrueColor()[BLUE_INDEX];
|
||||
bool destructive = true;
|
||||
|
||||
args->destinationTree->createVoxel(x, y, z, s, red, green, blue, destructive);
|
||||
args->outCount++;
|
||||
|
||||
sprintf(outputMessage,"Completed: %d%% (%lu of %lu) - Creating voxel %lu at [%f,%f,%f,%f]",
|
||||
percentDone,args->inCount,args->originalCount,args->outCount,x,y,z,s);
|
||||
printf("%s",outputMessage);
|
||||
for (int b = 0; b < strlen(outputMessage); b++) {
|
||||
printf("\b");
|
||||
}
|
||||
|
||||
// and create same sized leafs from this leaf voxel down to zero in the destination tree
|
||||
for (float yFill = y-s; yFill >= 0.0f; yFill -= s) {
|
||||
args->destinationTree->createVoxel(x, yFill, z, s, red, green, blue, destructive);
|
||||
|
||||
args->outCount++;
|
||||
|
||||
sprintf(outputMessage,"Completed: %d%% (%lu of %lu) - Creating fill voxel %lu at [%f,%f,%f,%f]",
|
||||
percentDone,args->inCount,args->originalCount,args->outCount,x,y,z,s);
|
||||
printf("%s",outputMessage);
|
||||
for (int b = 0; b < strlen(outputMessage); b++) {
|
||||
printf("\b");
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void processFillSVOFile(const char* fillSVOFile) {
|
||||
char outputFileName[512];
|
||||
|
||||
printf("fillSVOFile: %s\n", fillSVOFile);
|
||||
|
||||
VoxelTree originalSVO(true); // reaveraging
|
||||
VoxelTree filledSVO(true); // reaveraging
|
||||
|
||||
originalSVO.readFromSVOFile(fillSVOFile);
|
||||
qDebug("Nodes after loading %lu nodes\n", originalSVO.getVoxelCount());
|
||||
originalSVO.reaverageVoxelColors(originalSVO.rootNode);
|
||||
qDebug("Original Voxels reAveraged\n");
|
||||
qDebug("Nodes after reaveraging %lu nodes\n", originalSVO.getVoxelCount());
|
||||
|
||||
copyAndFillArgs args;
|
||||
args.destinationTree = &filledSVO;
|
||||
args.inCount = 0;
|
||||
args.outCount = 0;
|
||||
args.originalCount = originalSVO.getVoxelCount();
|
||||
|
||||
printf("Begin processing...\n");
|
||||
originalSVO.recurseTreeWithOperation(copyAndFillOperation, &args);
|
||||
printf("DONE processing...\n");
|
||||
|
||||
qDebug("Original input nodes used for filling %lu nodes\n", args.originalCount);
|
||||
qDebug("Input nodes traversed during filling %lu nodes\n", args.inCount);
|
||||
qDebug("Nodes created during filling %lu nodes\n", args.outCount);
|
||||
qDebug("Nodes after filling %lu nodes\n", filledSVO.getVoxelCount());
|
||||
|
||||
filledSVO.reaverageVoxelColors(filledSVO.rootNode);
|
||||
qDebug("Nodes after reaveraging %lu nodes\n", filledSVO.getVoxelCount());
|
||||
|
||||
sprintf(outputFileName, "filled%s", fillSVOFile);
|
||||
printf("outputFile: %s\n", outputFileName);
|
||||
filledSVO.writeToSVOFile(outputFileName);
|
||||
|
||||
printf("exiting now\n");
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, const char * argv[])
|
||||
{
|
||||
qInstallMessageHandler(sharedMessageHandler);
|
||||
|
@ -68,88 +246,19 @@ int main(int argc, const char * argv[])
|
|||
const char* splitJurisdictionRoot = getCmdOption(argc, argv, SPLIT_JURISDICTION_ROOT);
|
||||
const char* splitJurisdictionEndNodes = getCmdOption(argc, argv, SPLIT_JURISDICTION_ENDNODES);
|
||||
if (splitSVOFile && splitJurisdictionRoot && splitJurisdictionEndNodes) {
|
||||
char outputFileName[512];
|
||||
|
||||
printf("splitSVOFile: %s Jurisdictions Root: %s EndNodes: %s\n",
|
||||
splitSVOFile, splitJurisdictionRoot, splitJurisdictionEndNodes);
|
||||
|
||||
VoxelTree rootSVO;
|
||||
|
||||
rootSVO.readFromSVOFile(splitSVOFile);
|
||||
JurisdictionMap jurisdiction(splitJurisdictionRoot, splitJurisdictionEndNodes);
|
||||
|
||||
printf("Jurisdiction Root Octcode: ");
|
||||
printOctalCode(jurisdiction.getRootOctalCode());
|
||||
|
||||
printf("Jurisdiction End Nodes: %d \n", jurisdiction.getEndNodeCount());
|
||||
for (int i = 0; i < jurisdiction.getEndNodeCount(); i++) {
|
||||
unsigned char* endNodeCode = jurisdiction.getEndNodeOctalCode(i);
|
||||
printf("End Node: %d ", i);
|
||||
printOctalCode(endNodeCode);
|
||||
|
||||
// get the endNode details
|
||||
VoxelPositionSize endNodeDetails;
|
||||
voxelDetailsForCode(endNodeCode, endNodeDetails);
|
||||
|
||||
// Now, create a split SVO for the EndNode.
|
||||
// copy the EndNode into a temporary tree
|
||||
VoxelTree endNodeTree;
|
||||
|
||||
// create a small voxels at corners of the endNode Tree, this will is a hack
|
||||
// to work around a bug in voxel server that will send Voxel not exists
|
||||
// for regions that don't contain anything even if they're not in the
|
||||
// jurisdiction of the server
|
||||
// This hack assumes the end nodes for demo dinner since it only guarantees
|
||||
// nodes in the 8 child voxels of the main root voxel
|
||||
const float verySmall = 0.015625;
|
||||
endNodeTree.createVoxel(0.0, 0.0, 0.0, verySmall, 1, 1, 1, true);
|
||||
endNodeTree.createVoxel(1.0, 0.0, 0.0, verySmall, 1, 1, 1, true);
|
||||
endNodeTree.createVoxel(0.0, 1.0, 0.0, verySmall, 1, 1, 1, true);
|
||||
endNodeTree.createVoxel(0.0, 0.0, 1.0, verySmall, 1, 1, 1, true);
|
||||
endNodeTree.createVoxel(1.0, 1.0, 1.0, verySmall, 1, 1, 1, true);
|
||||
endNodeTree.createVoxel(1.0, 1.0, 0.0, verySmall, 1, 1, 1, true);
|
||||
endNodeTree.createVoxel(0.0, 1.0, 1.0, verySmall, 1, 1, 1, true);
|
||||
endNodeTree.createVoxel(1.0, 0.0, 1.0, verySmall, 1, 1, 1, true);
|
||||
|
||||
// Delete the voxel for the EndNode from the temporary tree, so we can
|
||||
// import our endNode content into it...
|
||||
endNodeTree.deleteVoxelCodeFromTree(endNodeCode, COLLAPSE_EMPTY_TREE);
|
||||
|
||||
VoxelNode* endNode = rootSVO.getVoxelAt(endNodeDetails.x,
|
||||
endNodeDetails.y,
|
||||
endNodeDetails.z,
|
||||
endNodeDetails.s);
|
||||
|
||||
rootSVO.copySubTreeIntoNewTree(endNode, &endNodeTree, false);
|
||||
|
||||
sprintf(outputFileName, "splitENDNODE%d%s", i, splitSVOFile);
|
||||
printf("outputFile: %s\n", outputFileName);
|
||||
endNodeTree.writeToSVOFile(outputFileName);
|
||||
|
||||
// Delete the voxel for the EndNode from the root tree...
|
||||
rootSVO.deleteVoxelCodeFromTree(endNodeCode, COLLAPSE_EMPTY_TREE);
|
||||
|
||||
// create a small voxel in center of each EndNode, this will is a hack
|
||||
// to work around a bug in voxel server that will send Voxel not exists
|
||||
// for regions that don't contain anything even if they're not in the
|
||||
// jurisdiction of the server
|
||||
float x = endNodeDetails.x + endNodeDetails.s * 0.5;
|
||||
float y = endNodeDetails.y + endNodeDetails.s * 0.5;
|
||||
float z = endNodeDetails.z + endNodeDetails.s * 0.5;
|
||||
float s = endNodeDetails.s * verySmall;
|
||||
|
||||
rootSVO.createVoxel(x, y, z, s, 1, 1, 1, true);
|
||||
|
||||
}
|
||||
|
||||
sprintf(outputFileName, "splitROOT%s", splitSVOFile);
|
||||
printf("outputFile: %s\n", outputFileName);
|
||||
rootSVO.writeToSVOFile(outputFileName);
|
||||
|
||||
printf("exiting now\n");
|
||||
processSplitSVOFile(splitSVOFile, splitJurisdictionRoot, splitJurisdictionEndNodes);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// Handles taking an SVO and filling in the empty space below the voxels to make it solid.
|
||||
const char* FILL_SVO = "--fillSVO";
|
||||
const char* fillSVOFile = getCmdOption(argc, argv, FILL_SVO);
|
||||
if (fillSVOFile) {
|
||||
processFillSVOFile(fillSVOFile);
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char* DONT_CREATE_FILE = "--dontCreateSceneFile";
|
||||
bool dontCreateFile = cmdOptionExists(argc, argv, DONT_CREATE_FILE);
|
||||
|
||||
|
|
Loading…
Reference in a new issue