Merge pull request #517 from PhilipRosedale/master

Added voxel system physical 'density' for better/correct appearance of objects at distance
This commit is contained in:
ZappoMan 2013-06-09 21:27:15 -07:00
commit 008ac5b357
3 changed files with 36 additions and 20 deletions

View file

@ -35,7 +35,7 @@ void VoxelNode::init(unsigned char * octalCode) {
_currentColor[0] = _currentColor[1] = _currentColor[2] = _currentColor[3] = 0; _currentColor[0] = _currentColor[1] = _currentColor[2] = _currentColor[3] = 0;
#endif #endif
_trueColor[0] = _trueColor[1] = _trueColor[2] = _trueColor[3] = 0; _trueColor[0] = _trueColor[1] = _trueColor[2] = _trueColor[3] = 0;
_density = 0.0f;
// default pointers to child nodes to NULL // default pointers to child nodes to NULL
for (int i = 0; i < NUMBER_OF_CHILDREN; i++) { for (int i = 0; i < NUMBER_OF_CHILDREN; i++) {
@ -161,10 +161,10 @@ void VoxelNode::safeDeepDeleteChildAtIndex(int childIndex, bool& stagedForDeleti
} }
} }
// will average the child colors... // will average the child colors...
void VoxelNode::setColorFromAverageOfChildren() { void VoxelNode::setColorFromAverageOfChildren() {
int colorArray[4] = {0,0,0,0}; int colorArray[4] = {0,0,0,0};
float density = 0.0f;
for (int i = 0; i < NUMBER_OF_CHILDREN; i++) { for (int i = 0; i < NUMBER_OF_CHILDREN; i++) {
if (_children[i] && !_children[i]->isStagedForDeletion() && _children[i]->isColored()) { if (_children[i] && !_children[i]->isStagedForDeletion() && _children[i]->isColored()) {
for (int j = 0; j < 3; j++) { for (int j = 0; j < 3; j++) {
@ -172,11 +172,24 @@ void VoxelNode::setColorFromAverageOfChildren() {
} }
colorArray[3]++; colorArray[3]++;
} }
if (_children[i]) {
density += _children[i]->getDensity();
}
} }
density /= (float) NUMBER_OF_CHILDREN;
//
// The VISIBLE_ABOVE_DENSITY sets the density of matter above which an averaged color voxel will
// be set. It is an important physical constant in our universe. A number below 0.5 will cause
// things to get 'fatter' at a distance, because upward averaging will make larger voxels out of
// less data, which is (probably) going to be preferable because it gives a sense that there is
// something out there to go investigate. A number above 0.5 would cause the world to become
// more 'empty' at a distance. Exactly 0.5 would match the physical world, at least for materials
// that are not shiny and have equivalent ambient reflectance.
//
const float VISIBLE_ABOVE_DENSITY = 0.10f;
nodeColor newColor = { 0, 0, 0, 0}; nodeColor newColor = { 0, 0, 0, 0};
if (colorArray[3] > 4) { if (density > VISIBLE_ABOVE_DENSITY) {
// we need at least 4 colored children to have an average color value // The density of material in the space of the voxel sets whether it is actually colored
// or if we have none we generate random values
for (int c = 0; c < 3; c++) { for (int c = 0; c < 3; c++) {
// set the average color value // set the average color value
newColor[c] = colorArray[c] / colorArray[3]; newColor[c] = colorArray[c] / colorArray[3];
@ -184,10 +197,9 @@ void VoxelNode::setColorFromAverageOfChildren() {
// set the alpha to 1 to indicate that this isn't transparent // set the alpha to 1 to indicate that this isn't transparent
newColor[3] = 1; newColor[3] = 1;
} }
// actually set our color, note, if we didn't have enough children // Set the color from the average of the child colors, and update the density
// this will be the default value all zeros, and therefore be marked as
// transparent with a 4th element of 0
setColor(newColor); setColor(newColor);
setDensity(density);
} }
// Note: !NO_FALSE_COLOR implementations of setFalseColor(), setFalseColored(), and setColor() here. // Note: !NO_FALSE_COLOR implementations of setFalseColor(), setFalseColored(), and setColor() here.
@ -214,20 +226,21 @@ void VoxelNode::setFalseColored(bool isFalseColored) {
_falseColored = isFalseColored; _falseColored = isFalseColored;
_isDirty = true; _isDirty = true;
markWithChangedTime(); markWithChangedTime();
_density = 1.0f; // If color set, assume leaf, re-averaging will update density if needed.
} }
}; };
void VoxelNode::setColor(const nodeColor& color) { void VoxelNode::setColor(const nodeColor& color) {
if (_trueColor[0] != color[0] || _trueColor[1] != color[1] || _trueColor[2] != color[2]) { if (_trueColor[0] != color[0] || _trueColor[1] != color[1] || _trueColor[2] != color[2]) {
//printLog("VoxelNode::setColor() was: (%d,%d,%d) is: (%d,%d,%d)\n",
// _trueColor[0],_trueColor[1],_trueColor[2],color[0],color[1],color[2]);
memcpy(&_trueColor,&color,sizeof(nodeColor)); memcpy(&_trueColor,&color,sizeof(nodeColor));
if (!_falseColored) { if (!_falseColored) {
memcpy(&_currentColor,&color,sizeof(nodeColor)); memcpy(&_currentColor,&color,sizeof(nodeColor));
} }
_isDirty = true; _isDirty = true;
markWithChangedTime(); markWithChangedTime();
_density = 1.0f; // If color set, assume leaf, re-averaging will update density if needed.
} }
} }
#endif #endif

View file

@ -36,6 +36,7 @@ private:
unsigned char* _octalCode; unsigned char* _octalCode;
VoxelNode* _children[8]; VoxelNode* _children[8];
int _childCount; int _childCount;
float _density; // If leaf: density = 1, if internal node: 0-1 density of voxels inside
void calculateAABox(); void calculateAABox();
@ -102,11 +103,14 @@ public:
void setColor(const nodeColor& color); void setColor(const nodeColor& color);
const nodeColor& getTrueColor() const { return _trueColor; }; const nodeColor& getTrueColor() const { return _trueColor; };
const nodeColor& getColor() const { return _currentColor; }; const nodeColor& getColor() const { return _currentColor; };
void setDensity(const float density) { _density = density; };
const float getDensity() const { return _density; };
#else #else
void setFalseColor(colorPart red, colorPart green, colorPart blue) { /* no op */ }; void setFalseColor(colorPart red, colorPart green, colorPart blue) { /* no op */ };
void setFalseColored(bool isFalseColored) { /* no op */ }; void setFalseColored(bool isFalseColored) { /* no op */ };
bool getFalseColored() { return false; }; bool getFalseColored() { return false; };
void setColor(const nodeColor& color) { memcpy(_trueColor,color,sizeof(nodeColor)); }; void setColor(const nodeColor& color) { memcpy(_trueColor,color,sizeof(nodeColor)); };
void setDensity(const float density) { _density = density; };
const nodeColor& getTrueColor() const { return _trueColor; }; const nodeColor& getTrueColor() const { return _trueColor; };
const nodeColor& getColor() const { return _trueColor; }; const nodeColor& getColor() const { return _trueColor; };
#endif #endif

View file

@ -387,16 +387,6 @@ void persistVoxelsWhenDirty() {
// check the dirty bit and persist here... // check the dirty bit and persist here...
if (::wantVoxelPersist && ::serverTree.isDirty() && sinceLastTime > VOXEL_PERSIST_INTERVAL) { if (::wantVoxelPersist && ::serverTree.isDirty() && sinceLastTime > VOXEL_PERSIST_INTERVAL) {
{
PerformanceWarning warn(::shouldShowAnimationDebug,
"persistVoxelsWhenDirty() - reaverageVoxelColors()", ::shouldShowAnimationDebug);
// after done inserting all these voxels, then reaverage colors
serverTree.reaverageVoxelColors(serverTree.rootNode);
}
{ {
PerformanceWarning warn(::shouldShowAnimationDebug, PerformanceWarning warn(::shouldShowAnimationDebug,
"persistVoxelsWhenDirty() - writeToSVOFile()", ::shouldShowAnimationDebug); "persistVoxelsWhenDirty() - writeToSVOFile()", ::shouldShowAnimationDebug);
@ -506,6 +496,15 @@ int main(int argc, const char * argv[]) {
if (::wantVoxelPersist) { if (::wantVoxelPersist) {
printf("loading voxels from file...\n"); printf("loading voxels from file...\n");
persistantFileRead = ::serverTree.readFromSVOFile(::wantLocalDomain ? LOCAL_VOXELS_PERSIST_FILE : VOXELS_PERSIST_FILE); persistantFileRead = ::serverTree.readFromSVOFile(::wantLocalDomain ? LOCAL_VOXELS_PERSIST_FILE : VOXELS_PERSIST_FILE);
if (persistantFileRead) {
PerformanceWarning warn(::shouldShowAnimationDebug,
"persistVoxelsWhenDirty() - reaverageVoxelColors()", ::shouldShowAnimationDebug);
// after done inserting all these voxels, then reaverage colors
serverTree.reaverageVoxelColors(serverTree.rootNode);
printf("Voxels reAveraged\n");
}
::serverTree.clearDirtyBit(); // the tree is clean since we just loaded it ::serverTree.clearDirtyBit(); // the tree is clean since we just loaded it
printf("DONE loading voxels from file... fileRead=%s\n", debug::valueOf(persistantFileRead)); printf("DONE loading voxels from file... fileRead=%s\n", debug::valueOf(persistantFileRead));
unsigned long nodeCount = ::serverTree.getVoxelCount(); unsigned long nodeCount = ::serverTree.getVoxelCount();