mirror of
https://github.com/overte-org/overte.git
synced 2025-04-20 11:45:36 +02:00
Fixed a bug in LOD boundaries
- changed the way we calculate whether or not to render a parent "average" voxel so that if any of it's most distant child would not be visible, then it's used instead of it's children - added precalculated value for topFarLeft corner of AABox (optimization) - changed VoxelSystem::newTreeToArrays() and VoxelTree::encodeTreeBitstreamRecursion() to use the same help function for determining this LOD boundary behavior - deleted old dead code in voxel-server and VoxelTree for picking which node to start sending with, since it wasn't being used - added VoxelNode::furthestDistanceToCamera() which tells you not the distance to the center of the voxel, but the distance from the camera to the furthest corner relative to the camera. - added ViewFrustum::getFurthestPointFromCamera() which given an axis-aligned box will tell you which vertex of the box is furthest from the camera
This commit is contained in:
parent
861ee9b389
commit
f415f4081a
11 changed files with 98 additions and 169 deletions
|
@ -318,8 +318,8 @@ Audio::Audio(Oscilloscope* scope, int16_t initialJitterBufferSamples) :
|
|||
_lastAcceleration(0),
|
||||
_totalPacketsReceived(0),
|
||||
_firstPacketReceivedTime(),
|
||||
_echoSamplesLeft(NULL),
|
||||
_packetsReceivedThisPlayback(0),
|
||||
_echoSamplesLeft(NULL),
|
||||
_isSendingEchoPing(false),
|
||||
_pingAnalysisPending(false),
|
||||
_pingFramesToRecord(0),
|
||||
|
|
|
@ -319,14 +319,7 @@ int VoxelSystem::newTreeToArrays(VoxelNode* node) {
|
|||
int voxelsUpdated = 0;
|
||||
bool shouldRender = false; // assume we don't need to render it
|
||||
// if it's colored, we might need to render it!
|
||||
if (node->isColored()) {
|
||||
float distanceToNode = node->distanceToCamera(*Application::getInstance()->getViewFrustum());
|
||||
float boundary = boundaryDistanceForRenderLevel(node->getLevel());
|
||||
float childBoundary = boundaryDistanceForRenderLevel(node->getLevel() + 1);
|
||||
bool inBoundary = (distanceToNode <= boundary);
|
||||
bool inChildBoundary = (distanceToNode <= childBoundary);
|
||||
shouldRender = (node->isLeaf() && inChildBoundary) || (inBoundary && !inChildBoundary);
|
||||
}
|
||||
shouldRender = node->calculateShouldRender(Application::getInstance()->getViewFrustum());
|
||||
node->setShouldRender(shouldRender && !node->isStagedForDeletion());
|
||||
// let children figure out their renderness
|
||||
if (!node->isLeaf()) {
|
||||
|
|
|
@ -18,6 +18,7 @@ void AABox::scale(float scale) {
|
|||
_corner = _corner * scale;
|
||||
_size = _size * scale;
|
||||
_center = _center * scale;
|
||||
_topFarLeft = _topFarLeft * scale;
|
||||
}
|
||||
|
||||
|
||||
|
@ -60,6 +61,7 @@ void AABox::setBox(const glm::vec3& corner, const glm::vec3& size) {
|
|||
_corner.z -= _size.z;
|
||||
}
|
||||
_center = _corner + (_size * 0.5f);
|
||||
_topFarLeft = _corner + _size;
|
||||
}
|
||||
|
||||
glm::vec3 AABox::getVertexP(const glm::vec3& normal) const {
|
||||
|
|
|
@ -41,10 +41,13 @@ class AABox
|
|||
|
||||
public:
|
||||
|
||||
AABox(const glm::vec3& corner, float size) : _corner(corner), _size(size, size, size) { };
|
||||
AABox(const glm::vec3& corner, float x, float y, float z) : _corner(corner), _size(x, y, z) { };
|
||||
AABox(const glm::vec3& corner, const glm::vec3& size) : _corner(corner), _size(size) { };
|
||||
AABox() : _corner(0,0,0), _size(0,0,0) { }
|
||||
AABox(const glm::vec3& corner, float size) :
|
||||
_corner(corner), _size(size, size, size) { _topFarLeft = _corner + _size; };
|
||||
AABox(const glm::vec3& corner, float x, float y, float z) :
|
||||
_corner(corner), _size(x, y, z) { _topFarLeft = _corner + _size; };
|
||||
AABox(const glm::vec3& corner, const glm::vec3& size) :
|
||||
_corner(corner), _size(size) { _topFarLeft = _corner + _size; };
|
||||
AABox() : _corner(0,0,0), _size(0,0,0), _topFarLeft(0,0,0) { }
|
||||
~AABox() { }
|
||||
|
||||
void setBox(const glm::vec3& corner, float x, float y, float z) { setBox(corner,glm::vec3(x,y,z)); };
|
||||
|
@ -56,9 +59,10 @@ public:
|
|||
|
||||
void scale(float scale);
|
||||
|
||||
const glm::vec3& getCorner() const { return _corner; };
|
||||
const glm::vec3& getSize() const { return _size; };
|
||||
const glm::vec3& getCenter() const { return _center; };
|
||||
const glm::vec3& getCorner() const { return _corner; };
|
||||
const glm::vec3& getSize() const { return _size; };
|
||||
const glm::vec3& getCenter() const { return _center; };
|
||||
const glm::vec3& getTopFarLeft() const { return _topFarLeft; };
|
||||
|
||||
glm::vec3 getVertex(BoxVertex vertex) const;
|
||||
|
||||
|
@ -81,6 +85,7 @@ private:
|
|||
glm::vec3 _corner;
|
||||
glm::vec3 _center;
|
||||
glm::vec3 _size;
|
||||
glm::vec3 _topFarLeft;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -530,8 +530,10 @@ const int hullVertexLookup[MAX_POSSIBLE_COMBINATIONS][MAX_PROJECTED_POLYGON_VERT
|
|||
};
|
||||
|
||||
VoxelProjectedPolygon ViewFrustum::getProjectedPolygon(const AABox& box) const {
|
||||
glm::vec3 bottomNearRight = box.getCorner();
|
||||
glm::vec3 topFarLeft = box.getCorner() + box.getSize();
|
||||
const glm::vec3& bottomNearRight = box.getCorner();
|
||||
const glm::vec3& topFarLeft = box.getTopFarLeft();
|
||||
|
||||
|
||||
int lookUp = ((_position.x < bottomNearRight.x) ) // 1 = right | compute 6-bit
|
||||
+ ((_position.x > topFarLeft.x ) << 1) // 2 = left | code to
|
||||
+ ((_position.y < bottomNearRight.y) << 2) // 4 = bottom | classify camera
|
||||
|
@ -593,3 +595,40 @@ VoxelProjectedPolygon ViewFrustum::getProjectedPolygon(const AABox& box) const {
|
|||
projectedPolygon.setProjectionType(lookUp); // remember the projection type
|
||||
return projectedPolygon;
|
||||
}
|
||||
|
||||
|
||||
// Similar strategy to getProjectedPolygon() we use the knowledge of camera position relative to the
|
||||
// axis-aligned voxels to determine which of the voxels vertices must be the furthest. No need for
|
||||
// squares and square-roots. Just compares.
|
||||
glm::vec3 ViewFrustum::getFurthestPointFromCamera(const AABox& box) const {
|
||||
const glm::vec3& center = box.getCenter();
|
||||
const glm::vec3& bottomNearRight = box.getCorner();
|
||||
const glm::vec3& topFarLeft = box.getTopFarLeft();
|
||||
|
||||
glm::vec3 furthestPoint;
|
||||
if (_position.x < center.x) {
|
||||
// we are to the right of the center, so the left edge is furthest
|
||||
furthestPoint.x = topFarLeft.x;
|
||||
} else {
|
||||
// we are to the left of the center, so the right edge is furthest (at center ok too)
|
||||
furthestPoint.x = bottomNearRight.x;
|
||||
}
|
||||
|
||||
if (_position.y < center.y) {
|
||||
// we are below of the center, so the top edge is furthest
|
||||
furthestPoint.y = topFarLeft.y;
|
||||
} else {
|
||||
// we are above the center, so the lower edge is furthest (at center ok too)
|
||||
furthestPoint.y = bottomNearRight.y;
|
||||
}
|
||||
|
||||
if (_position.z < center.z) {
|
||||
// we are to the near side of the center, so the far side edge is furthest
|
||||
furthestPoint.z = topFarLeft.z;
|
||||
} else {
|
||||
// we are to the far side of the center, so the near side edge is furthest (at center ok too)
|
||||
furthestPoint.z = bottomNearRight.z;
|
||||
}
|
||||
|
||||
return furthestPoint;
|
||||
}
|
||||
|
|
|
@ -90,6 +90,7 @@ public:
|
|||
|
||||
glm::vec2 projectPoint(glm::vec3 point, bool& pointInView) const;
|
||||
VoxelProjectedPolygon getProjectedPolygon(const AABox& box) const;
|
||||
glm::vec3 getFurthestPointFromCamera(const AABox& box) const;
|
||||
|
||||
private:
|
||||
|
||||
|
|
|
@ -335,6 +335,39 @@ ViewFrustum::location VoxelNode::inFrustum(const ViewFrustum& viewFrustum) const
|
|||
return viewFrustum.boxInFrustum(box);
|
||||
}
|
||||
|
||||
// There are two types of nodes for which we want to "render"
|
||||
// 1) Leaves that are in the LOD
|
||||
// 2) Non-leaves are more complicated though... usually you don't want to render them, but if their children
|
||||
// wouldn't be rendered, then you do want to render them. But sometimes they have some children that ARE
|
||||
// in the LOD, and others that are not. In this case we want to render the parent, and none of the children.
|
||||
//
|
||||
// Since, if we know the camera position and orientation, we can know which of the corners is the "furthest"
|
||||
// corner. We can use we can use this corner as our "voxel position" to do our distance calculations off of.
|
||||
// By doing this, we don't need to test each child voxel's position vs the LOD boundary
|
||||
bool VoxelNode::calculateShouldRender(const ViewFrustum* viewFrustum, int boundaryLevelAdjust) const {
|
||||
bool shouldRender = false;
|
||||
if (isColored()) {
|
||||
float furthestDistance = furthestDistanceToCamera(*viewFrustum);
|
||||
float boundary = boundaryDistanceForRenderLevel(getLevel() + boundaryLevelAdjust);
|
||||
float childBoundary = boundaryDistanceForRenderLevel(getLevel() + 1 + boundaryLevelAdjust);
|
||||
bool inBoundary = (furthestDistance <= boundary);
|
||||
bool inChildBoundary = (furthestDistance <= childBoundary);
|
||||
shouldRender = (isLeaf() && inChildBoundary) || (inBoundary && !inChildBoundary);
|
||||
}
|
||||
return shouldRender;
|
||||
}
|
||||
|
||||
// Calculates the distance to the furthest point of the voxel to the camera
|
||||
float VoxelNode::furthestDistanceToCamera(const ViewFrustum& viewFrustum) const {
|
||||
AABox box = getAABox();
|
||||
box.scale(TREE_SCALE);
|
||||
glm::vec3 furthestPoint = viewFrustum.getFurthestPointFromCamera(box);
|
||||
glm::vec3 temp = viewFrustum.getPosition() - furthestPoint;
|
||||
float distanceSquared = glm::dot(temp, temp);
|
||||
float distanceToVoxelCenter = sqrtf(distanceSquared);
|
||||
return distanceToVoxelCenter;
|
||||
}
|
||||
|
||||
float VoxelNode::distanceToCamera(const ViewFrustum& viewFrustum) const {
|
||||
glm::vec3 center = _box.getCenter() * (float)TREE_SCALE;
|
||||
glm::vec3 temp = viewFrustum.getPosition() - center;
|
||||
|
|
|
@ -70,6 +70,9 @@ public:
|
|||
bool isInView(const ViewFrustum& viewFrustum) const;
|
||||
ViewFrustum::location inFrustum(const ViewFrustum& viewFrustum) const;
|
||||
float distanceToCamera(const ViewFrustum& viewFrustum) const;
|
||||
float furthestDistanceToCamera(const ViewFrustum& viewFrustum) const;
|
||||
|
||||
bool calculateShouldRender(const ViewFrustum* viewFrustum, int boundaryLevelAdjust = 0) const;
|
||||
|
||||
// points are assumed to be in Voxel Coordinates (not TREE_SCALE'd)
|
||||
float distanceSquareToPoint(const glm::vec3& point) const; // when you don't need the actual distance, use this.
|
||||
|
|
|
@ -891,17 +891,6 @@ void VoxelTree::createSphere(float radius, float xc, float yc, float zc, float v
|
|||
}
|
||||
}
|
||||
|
||||
int VoxelTree::searchForColoredNodes(int maxSearchLevel, VoxelNode* node, const ViewFrustum& viewFrustum, VoxelNodeBag& bag,
|
||||
bool deltaViewFrustum, const ViewFrustum* lastViewFrustum) {
|
||||
|
||||
// call the recursive version, this will add all found colored node roots to the bag
|
||||
int currentSearchLevel = 0;
|
||||
|
||||
int levelReached = searchForColoredNodesRecursion(maxSearchLevel, currentSearchLevel, rootNode,
|
||||
viewFrustum, bag, deltaViewFrustum, lastViewFrustum);
|
||||
return levelReached;
|
||||
}
|
||||
|
||||
// combines the ray cast arguments into a single object
|
||||
class RayArgs {
|
||||
public:
|
||||
|
@ -1014,88 +1003,6 @@ bool VoxelTree::findCapsulePenetration(const glm::vec3& start, const glm::vec3&
|
|||
return args.found;
|
||||
}
|
||||
|
||||
int VoxelTree::searchForColoredNodesRecursion(int maxSearchLevel, int& currentSearchLevel,
|
||||
VoxelNode* node, const ViewFrustum& viewFrustum, VoxelNodeBag& bag,
|
||||
bool deltaViewFrustum, const ViewFrustum* lastViewFrustum) {
|
||||
|
||||
// Keep track of how deep we've searched.
|
||||
currentSearchLevel++;
|
||||
|
||||
// If we've passed our max Search Level, then stop searching. return last level searched
|
||||
if (currentSearchLevel > maxSearchLevel) {
|
||||
return currentSearchLevel-1;
|
||||
}
|
||||
|
||||
// If we're at a node that is out of view, then we can return, because no nodes below us will be in view!
|
||||
if (!node->isInView(viewFrustum)) {
|
||||
return currentSearchLevel;
|
||||
}
|
||||
|
||||
// Ok, this is a little tricky, each child may have been deeper than the others, so we need to track
|
||||
// how deep each child went. And we actually return the maximum of each child. We use these variables below
|
||||
// when we recurse the children.
|
||||
int thisLevel = currentSearchLevel;
|
||||
int maxChildLevel = thisLevel;
|
||||
|
||||
VoxelNode* inViewChildren[NUMBER_OF_CHILDREN];
|
||||
float distancesToChildren[NUMBER_OF_CHILDREN];
|
||||
int positionOfChildren[NUMBER_OF_CHILDREN];
|
||||
int inViewCount = 0;
|
||||
int inViewNotLeafCount = 0;
|
||||
int inViewWithColorCount = 0;
|
||||
|
||||
// for each child node, check to see if they exist, are colored, and in view, and if so
|
||||
// add them to our distance ordered array of children
|
||||
for (int i = 0; i < NUMBER_OF_CHILDREN; i++) {
|
||||
VoxelNode* childNode = node->getChildAtIndex(i);
|
||||
bool childIsColored = (childNode && childNode->isColored());
|
||||
bool childIsInView = (childNode && childNode->isInView(viewFrustum));
|
||||
bool childIsLeaf = (childNode && childNode->isLeaf());
|
||||
|
||||
if (childIsInView) {
|
||||
|
||||
// track children in view as existing and not a leaf
|
||||
if (!childIsLeaf) {
|
||||
inViewNotLeafCount++;
|
||||
}
|
||||
|
||||
// track children with actual color
|
||||
if (childIsColored) {
|
||||
inViewWithColorCount++;
|
||||
}
|
||||
|
||||
float distance = childNode->distanceToCamera(viewFrustum);
|
||||
|
||||
if (distance < boundaryDistanceForRenderLevel(*childNode->getOctalCode() + 1)) {
|
||||
inViewCount = insertIntoSortedArrays((void*)childNode, distance, i,
|
||||
(void**)&inViewChildren, (float*)&distancesToChildren,
|
||||
(int*)&positionOfChildren, inViewCount, NUMBER_OF_CHILDREN);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If we have children with color, then we do want to add this node (and it's descendants) to the bag to be written
|
||||
// we don't need to dig deeper.
|
||||
//
|
||||
// XXXBHG - this might be a good time to look at colors and add them to a dictionary? But we're not planning
|
||||
// on scanning the whole tree, so we won't actually see all the colors, so maybe no point in that.
|
||||
if (inViewWithColorCount) {
|
||||
bag.insert(node);
|
||||
} else {
|
||||
// at this point, we need to iterate the children who are in view, even if not colored
|
||||
// and we need to determine if there's a deeper tree below them that we care about. We will iterate
|
||||
// these based on which tree is closer.
|
||||
for (int i = 0; i < inViewCount; i++) {
|
||||
VoxelNode* childNode = inViewChildren[i];
|
||||
thisLevel = currentSearchLevel; // reset this, since the children will munge it up
|
||||
int childLevelReached = searchForColoredNodesRecursion(maxSearchLevel, thisLevel, childNode, viewFrustum, bag,
|
||||
deltaViewFrustum, lastViewFrustum);
|
||||
maxChildLevel = std::max(maxChildLevel, childLevelReached);
|
||||
}
|
||||
}
|
||||
return maxChildLevel;
|
||||
}
|
||||
|
||||
int VoxelTree::encodeTreeBitstream(VoxelNode* node, unsigned char* outputBuffer, int availableBytes, VoxelNodeBag& bag,
|
||||
EncodeBitstreamParams& params) const {
|
||||
|
||||
|
@ -1344,19 +1251,10 @@ int VoxelTree::encodeTreeBitstreamRecursion(VoxelNode* node, unsigned char* outp
|
|||
} // wants occlusion culling & isLeaf()
|
||||
|
||||
|
||||
// There are two types of nodes for which we want to send colors:
|
||||
// 1) Leaves - obviously
|
||||
// 2) Non-leaves who's children would be visible but are beyond our LOD.
|
||||
bool isLeafOrLOD = childNode->isLeaf();
|
||||
if (params.viewFrustum && childNode->isColored() && !childNode->isLeaf()) {
|
||||
int childLevel = childNode->getLevel();
|
||||
float childBoundary = boundaryDistanceForRenderLevel(childLevel + params.boundaryLevelAdjust);
|
||||
float grandChildBoundary = boundaryDistanceForRenderLevel(childLevel + 1 + params.boundaryLevelAdjust);
|
||||
isLeafOrLOD = ((distance <= childBoundary) && !(distance <= grandChildBoundary));
|
||||
}
|
||||
bool shouldRender = childNode->calculateShouldRender(params.viewFrustum, params.boundaryLevelAdjust);
|
||||
|
||||
// track children with actual color, only if the child wasn't previously in view!
|
||||
if (childNode && isLeafOrLOD && childNode->isColored() && !childIsOccluded) {
|
||||
if (shouldRender && !childIsOccluded) {
|
||||
bool childWasInView = false;
|
||||
|
||||
if (childNode && params.deltaViewFrustum && params.lastViewFrustum) {
|
||||
|
@ -1368,7 +1266,7 @@ int VoxelTree::encodeTreeBitstreamRecursion(VoxelNode* node, unsigned char* outp
|
|||
} else {
|
||||
childWasInView = location == ViewFrustum::INSIDE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If our child wasn't in view (or we're ignoring wasInView) then we add it to our sending items
|
||||
if (!childWasInView) {
|
||||
|
|
|
@ -123,9 +123,6 @@ public:
|
|||
int encodeTreeBitstream(VoxelNode* node, unsigned char* outputBuffer, int availableBytes, VoxelNodeBag& bag,
|
||||
EncodeBitstreamParams& params) const;
|
||||
|
||||
int searchForColoredNodes(int maxSearchLevel, VoxelNode* node, const ViewFrustum& viewFrustum, VoxelNodeBag& bag,
|
||||
bool deltaViewFrustum = false, const ViewFrustum* lastViewFrustum = NULL);
|
||||
|
||||
bool isDirty() const { return _isDirty; };
|
||||
void clearDirtyBit() { _isDirty = false; };
|
||||
void setDirtyBit() { _isDirty = true; };
|
||||
|
@ -171,10 +168,6 @@ private:
|
|||
int encodeTreeBitstreamRecursion(VoxelNode* node, unsigned char* outputBuffer, int availableBytes, VoxelNodeBag& bag,
|
||||
EncodeBitstreamParams& params, int& currentEncodeLevel) const;
|
||||
|
||||
int searchForColoredNodesRecursion(int maxSearchLevel, int& currentSearchLevel,
|
||||
VoxelNode* node, const ViewFrustum& viewFrustum, VoxelNodeBag& bag,
|
||||
bool deltaViewFrustum, const ViewFrustum* lastViewFrustum);
|
||||
|
||||
static bool countVoxelsOperation(VoxelNode* node, void* extraData);
|
||||
|
||||
VoxelNode* nodeForOctalCode(VoxelNode* ancestorNode, unsigned char* needleCode, VoxelNode** parentOfFoundNode) const;
|
||||
|
|
|
@ -60,7 +60,6 @@ bool wantLocalDomain = false;
|
|||
bool wantColorRandomizer = false;
|
||||
bool debugVoxelSending = false;
|
||||
bool shouldShowAnimationDebug = false;
|
||||
bool wantSearchForColoredNodes = false;
|
||||
|
||||
EnvironmentData environmentData[3];
|
||||
|
||||
|
@ -121,8 +120,6 @@ void deepestLevelVoxelDistributor(NodeList* nodeList,
|
|||
|
||||
pthread_mutex_lock(&::treeLock);
|
||||
|
||||
int maxLevelReached = 0;
|
||||
uint64_t start = usecTimestampNow();
|
||||
int truePacketsSent = 0;
|
||||
int trueBytesSent = 0;
|
||||
|
||||
|
@ -200,38 +197,7 @@ void deepestLevelVoxelDistributor(NodeList* nodeList,
|
|||
nodeData->map.erase();
|
||||
}
|
||||
|
||||
// For now, we're going to disable the "search for colored nodes" because that strategy doesn't work when we support
|
||||
// deletion of nodes. Instead if we just start at the root we get the correct behavior we want. We are keeping this
|
||||
// code for now because we want to be able to go back to it and find a solution to support both. The search method
|
||||
// helps improve overall bitrate performance.
|
||||
if (::wantSearchForColoredNodes) {
|
||||
// If the bag was empty, then send everything in view, not just the delta
|
||||
maxLevelReached = serverTree.searchForColoredNodes(INT_MAX, serverTree.rootNode, nodeData->getCurrentViewFrustum(),
|
||||
nodeData->nodeBag, wantDelta, lastViewFrustum);
|
||||
|
||||
// if nothing was found in view, send the root node.
|
||||
if (nodeData->nodeBag.isEmpty()){
|
||||
nodeData->nodeBag.insert(serverTree.rootNode);
|
||||
}
|
||||
nodeData->setViewSent(false);
|
||||
} else {
|
||||
nodeData->nodeBag.insert(serverTree.rootNode);
|
||||
}
|
||||
}
|
||||
uint64_t end = usecTimestampNow();
|
||||
int elapsedmsec = (end - start)/1000;
|
||||
if (elapsedmsec > 100) {
|
||||
if (elapsedmsec > 1000) {
|
||||
int elapsedsec = (end - start)/1000000;
|
||||
printf("WARNING! searchForColoredNodes() took %d seconds to identify %d nodes at level %d\n",
|
||||
elapsedsec, nodeData->nodeBag.count(), maxLevelReached);
|
||||
} else {
|
||||
printf("WARNING! searchForColoredNodes() took %d milliseconds to identify %d nodes at level %d\n",
|
||||
elapsedmsec, nodeData->nodeBag.count(), maxLevelReached);
|
||||
}
|
||||
} else if (::debugVoxelSending) {
|
||||
printf("searchForColoredNodes() took %d milliseconds to identify %d nodes at level %d\n",
|
||||
elapsedmsec, nodeData->nodeBag.count(), maxLevelReached);
|
||||
nodeData->nodeBag.insert(serverTree.rootNode);
|
||||
}
|
||||
|
||||
// If we have something in our nodeBag, then turn them into packets and send them out...
|
||||
|
@ -438,10 +404,6 @@ int main(int argc, const char * argv[]) {
|
|||
::wantColorRandomizer = cmdOptionExists(argc, argv, WANT_COLOR_RANDOMIZER);
|
||||
printf("wantColorRandomizer=%s\n", debug::valueOf(::wantColorRandomizer));
|
||||
|
||||
const char* WANT_SEARCH_FOR_NODES = "--wantSearchForColoredNodes";
|
||||
::wantSearchForColoredNodes = cmdOptionExists(argc, argv, WANT_SEARCH_FOR_NODES);
|
||||
printf("wantSearchForColoredNodes=%s\n", debug::valueOf(::wantSearchForColoredNodes));
|
||||
|
||||
// By default we will voxel persist, if you want to disable this, then pass in this parameter
|
||||
const char* NO_VOXEL_PERSIST = "--NoVoxelPersist";
|
||||
if (cmdOptionExists(argc, argv, NO_VOXEL_PERSIST)) {
|
||||
|
|
Loading…
Reference in a new issue