temporarily force external child storage

This commit is contained in:
ZappoMan 2013-10-25 14:03:49 -07:00
parent 51f97f65fd
commit dcccfb7ef0

View file

@ -351,6 +351,7 @@ VoxelNode* VoxelNode::getChildAtIndex(int childIndex) const {
int indexTwo = getNthBit(_childBitmask, 2); int indexTwo = getNthBit(_childBitmask, 2);
if (_childrenExternal) { if (_childrenExternal) {
//assert(_children.external);
if (indexOne == childIndex) { if (indexOne == childIndex) {
result = _children.external[0]; result = _children.external[0];
} else if (indexTwo == childIndex) { } else if (indexTwo == childIndex) {
@ -375,6 +376,7 @@ VoxelNode* VoxelNode::getChildAtIndex(int childIndex) const {
int indexThree = getNthBit(_childBitmask, 3); int indexThree = getNthBit(_childBitmask, 3);
if (_childrenExternal) { if (_childrenExternal) {
//assert(_children.external);
if (indexOne == childIndex) { if (indexOne == childIndex) {
result = _children.external[0]; result = _children.external[0];
} else if (indexTwo == childIndex) { } else if (indexTwo == childIndex) {
@ -430,9 +432,11 @@ void VoxelNode::storeTwoChildren(VoxelNode* childOne, VoxelNode* childTwo) {
const int64_t minOffset = std::numeric_limits<int32_t>::min(); const int64_t minOffset = std::numeric_limits<int32_t>::min();
const int64_t maxOffset = std::numeric_limits<int32_t>::max(); const int64_t maxOffset = std::numeric_limits<int32_t>::max();
if (isBetween(offsetOne, maxOffset, minOffset) && isBetween(offsetTwo, maxOffset, minOffset)) { bool forceExternal = true;
if (!forceExternal && isBetween(offsetOne, maxOffset, minOffset) && isBetween(offsetTwo, maxOffset, minOffset)) {
// if previously external, then clean it up... // if previously external, then clean it up...
if (_childrenExternal) { if (_childrenExternal) {
//assert(_children.external);
const int previousChildCount = 2; const int previousChildCount = 2;
_externalChildrenMemoryUsage -= previousChildCount * sizeof(VoxelNode*); _externalChildrenMemoryUsage -= previousChildCount * sizeof(VoxelNode*);
delete[] _children.external; delete[] _children.external;
@ -539,7 +543,9 @@ void VoxelNode::storeThreeChildren(VoxelNode* childOne, VoxelNode* childTwo, Vox
const int64_t minOffset = -1048576; // what can fit in 20 bits // std::numeric_limits<int16_t>::min(); const int64_t minOffset = -1048576; // what can fit in 20 bits // std::numeric_limits<int16_t>::min();
const int64_t maxOffset = 1048576; // what can fit in 20 bits // std::numeric_limits<int16_t>::max(); const int64_t maxOffset = 1048576; // what can fit in 20 bits // std::numeric_limits<int16_t>::max();
if (isBetween(offsetOne, maxOffset, minOffset) && bool forceExternal = true;
if (!forceExternal &&
isBetween(offsetOne, maxOffset, minOffset) &&
isBetween(offsetTwo, maxOffset, minOffset) && isBetween(offsetTwo, maxOffset, minOffset) &&
isBetween(offsetThree, maxOffset, minOffset)) { isBetween(offsetThree, maxOffset, minOffset)) {
// if previously external, then clean it up... // if previously external, then clean it up...
@ -601,7 +607,9 @@ void VoxelNode::checkStoreFourChildren(VoxelNode* childOne, VoxelNode* childTwo,
const int64_t minOffset = std::numeric_limits<int16_t>::min(); const int64_t minOffset = std::numeric_limits<int16_t>::min();
const int64_t maxOffset = std::numeric_limits<int16_t>::max(); const int64_t maxOffset = std::numeric_limits<int16_t>::max();
if (isBetween(offsetOne, maxOffset, minOffset) && bool forceExternal = true;
if (!forceExternal &&
isBetween(offsetOne, maxOffset, minOffset) &&
isBetween(offsetTwo, maxOffset, minOffset) && isBetween(offsetTwo, maxOffset, minOffset) &&
isBetween(offsetThree, maxOffset, minOffset) && isBetween(offsetThree, maxOffset, minOffset) &&
isBetween(offsetFour, maxOffset, minOffset) isBetween(offsetFour, maxOffset, minOffset)
@ -720,7 +728,7 @@ void VoxelNode::setChildAtIndex(int childIndex, VoxelNode* child) {
storeTwoChildren(childOne, childTwo); storeTwoChildren(childOne, childTwo);
} else if (previousChildCount == 2 && newChildCount == 1) { } else if (previousChildCount == 2 && newChildCount == 1) {
// If we had 2 children, and we're removing one, then we know we can go down to single mode // If we had 2 children, and we're removing one, then we know we can go down to single mode
assert(child == NULL); // this is the only logical case //assert(child == NULL); // this is the only logical case
int indexTwo = getNthBit(previousChildMask, 2); int indexTwo = getNthBit(previousChildMask, 2);
bool keepChildOne = indexTwo == childIndex; bool keepChildOne = indexTwo == childIndex;
@ -743,31 +751,19 @@ void VoxelNode::setChildAtIndex(int childIndex, VoxelNode* child) {
int indexOne = getNthBit(previousChildMask, 1); int indexOne = getNthBit(previousChildMask, 1);
bool replaceChildOne = indexOne == childIndex; bool replaceChildOne = indexOne == childIndex;
// If we previously had an external array, then just replace the right one... that's easy. // Get the existing two children out of their encoding...
if (_childrenExternal) { VoxelNode* childOne;
// technically, we could look to see if these are now in the offsets to handle be encoded, but VoxelNode* childTwo;
// we're going to go ahead and keep this as an array. retrieveTwoChildren(childOne, childTwo);
if (replaceChildOne) {
_children.external[0] = child;
} else {
_children.external[1] = child;
}
} else {
// If we were previously encoded as offsets, then we need to see if we can still encode as offsets
VoxelNode* childOne;
VoxelNode* childTwo;
if (replaceChildOne) {
childOne = child;
childTwo = (VoxelNode*)((uint8_t*)this + _children.offsetsTwoChildren[1]);
} else {
childOne = (VoxelNode*)((uint8_t*)this + _children.offsetsTwoChildren[0]);
childTwo = child;
}
_twoChildrenOffsetCount--; // will end up one or the other if (replaceChildOne) {
storeTwoChildren(childOne, childTwo); childOne = child;
} else {
childTwo = child;
} }
storeTwoChildren(childOne, childTwo);
} else if (previousChildCount == 2 && newChildCount == 3) { } else if (previousChildCount == 2 && newChildCount == 3) {
// If we had 2 children, and now have 3, then we know we are going to an external case... // If we had 2 children, and now have 3, then we know we are going to an external case...
@ -893,7 +889,7 @@ void VoxelNode::setChildAtIndex(int childIndex, VoxelNode* child) {
_externalChildrenCount++; _externalChildrenCount++;
} else if (previousChildCount == 4 && newChildCount == 3) { } else if (previousChildCount == 4 && newChildCount == 3) {
// If we had 4 children, and now have 3, then we know we are going from an external case to a potential internal case // If we had 4 children, and now have 3, then we know we are going from an external case to a potential internal case
assert(_childrenExternal); //assert(_children.external && _childrenExternal && previousChildCount == 4);
// We need to determine which children we had, and which one we got rid of... // We need to determine which children we had, and which one we got rid of...
int indexOne = getNthBit(previousChildMask, 1); int indexOne = getNthBit(previousChildMask, 1);
@ -928,10 +924,11 @@ void VoxelNode::setChildAtIndex(int childIndex, VoxelNode* child) {
_children.external = NULL; _children.external = NULL;
_externalChildrenCount--; _externalChildrenCount--;
_externalChildrenMemoryUsage -= previousChildCount * sizeof(VoxelNode*); _externalChildrenMemoryUsage -= previousChildCount * sizeof(VoxelNode*);
storeThreeChildren(childOne, childTwo, childThree); storeThreeChildren(childOne, childTwo, childThree);
} else if (previousChildCount == newChildCount) { } else if (previousChildCount == newChildCount) {
//assert(_children.external && _childrenExternal && previousChildCount >= 4);
//assert(previousChildCount == newChildCount);
// 4 or more children, one item being replaced, we know we're stored externally, we just need to find the one // 4 or more children, one item being replaced, we know we're stored externally, we just need to find the one
// that needs to be replaced and replace it. // that needs to be replaced and replace it.
for (int ordinal = 1; ordinal <= 8; ordinal++) { for (int ordinal = 1; ordinal <= 8; ordinal++) {
@ -944,6 +941,10 @@ void VoxelNode::setChildAtIndex(int childIndex, VoxelNode* child) {
} }
} }
} else if (previousChildCount < newChildCount) { } else if (previousChildCount < newChildCount) {
// Growing case... previous must be 4 or greater
//assert(_children.external && _childrenExternal && previousChildCount >= 4);
//assert(previousChildCount == newChildCount-1);
// 4 or more children, one item being added, we know we're stored externally, we just figure out where to insert // 4 or more children, one item being added, we know we're stored externally, we just figure out where to insert
// this child pointer into our external list // this child pointer into our external list
VoxelNode** newExternalList = new VoxelNode*[newChildCount]; VoxelNode** newExternalList = new VoxelNode*[newChildCount];
@ -975,13 +976,16 @@ void VoxelNode::setChildAtIndex(int childIndex, VoxelNode* child) {
_externalChildrenMemoryUsage += newChildCount * sizeof(VoxelNode*); _externalChildrenMemoryUsage += newChildCount * sizeof(VoxelNode*);
} else if (previousChildCount > newChildCount) { } else if (previousChildCount > newChildCount) {
//assert(_children.external && _childrenExternal && previousChildCount >= 4);
//assert(previousChildCount == newChildCount+1);
// 4 or more children, one item being removed, we know we're stored externally, we just figure out which // 4 or more children, one item being removed, we know we're stored externally, we just figure out which
// item to remove from our external list // item to remove from our external list
VoxelNode** newExternalList = new VoxelNode*[newChildCount]; VoxelNode** newExternalList = new VoxelNode*[newChildCount];
for (int ordinal = 1; ordinal <= previousChildCount; ordinal++) { for (int ordinal = 1; ordinal <= previousChildCount; ordinal++) {
int index = getNthBit(previousChildMask, ordinal); int index = getNthBit(previousChildMask, ordinal);
assert(index != -1); //assert(index != -1);
if (index < childIndex) { if (index < childIndex) {
newExternalList[ordinal - 1] = _children.external[ordinal - 1]; newExternalList[ordinal - 1] = _children.external[ordinal - 1];
} else { } else {
@ -997,7 +1001,7 @@ void VoxelNode::setChildAtIndex(int childIndex, VoxelNode* child) {
_externalChildrenMemoryUsage -= previousChildCount * sizeof(VoxelNode*); _externalChildrenMemoryUsage -= previousChildCount * sizeof(VoxelNode*);
_externalChildrenMemoryUsage += newChildCount * sizeof(VoxelNode*); _externalChildrenMemoryUsage += newChildCount * sizeof(VoxelNode*);
} else { } else {
assert(false); //assert(false);
qDebug("THIS SHOULD NOT HAPPEN previousChildCount == %d && newChildCount == %d\n",previousChildCount, newChildCount); qDebug("THIS SHOULD NOT HAPPEN previousChildCount == %d && newChildCount == %d\n",previousChildCount, newChildCount);
} }
@ -1024,7 +1028,6 @@ VoxelNode* VoxelNode::addChildAtIndex(int childIndex) {
childAt = new VoxelNode(childOctalCode(getOctalCode(), childIndex)); childAt = new VoxelNode(childOctalCode(getOctalCode(), childIndex));
childAt->setVoxelSystem(getVoxelSystem()); // our child is always part of our voxel system NULL ok childAt->setVoxelSystem(getVoxelSystem()); // our child is always part of our voxel system NULL ok
setChildAtIndex(childIndex, childAt); setChildAtIndex(childIndex, childAt);
_isDirty = true; _isDirty = true;