bool copyAndFillOperation(OctreeElement* element, void* extraData) { VoxelTreeElement* voxel = (VoxelTreeElement*)element; copyAndFillArgs* args = (copyAndFillArgs*)extraData; char outputMessage[128]; args->inCount++; int percentDone = (100*args->inCount/args->originalCount); // For each leaf node... if (voxel->isLeaf()) { // create a copy of the leaf in the copy destination float x = voxel->getCorner().x; float y = voxel->getCorner().y; float z = voxel->getCorner().z; float s = voxel->getScale(); unsigned char red = voxel->getTrueColor()[RED_INDEX]; unsigned char green = voxel->getTrueColor()[GREEN_INDEX]; unsigned char blue = voxel->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; }
// will average the child colors... void VoxelTreeElement::calculateAverageFromChildren() { int colorArray[4] = {0,0,0,0}; float density = 0.0f; for (int i = 0; i < NUMBER_OF_CHILDREN; i++) { VoxelTreeElement* childAt = getChildAtIndex(i); if (childAt && childAt->isColored()) { for (int j = 0; j < 3; j++) { colorArray[j] += childAt->getTrueColor()[j]; // color averaging should always be based on true colors } colorArray[3]++; } if (childAt) { density += childAt->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}; if (density > VISIBLE_ABOVE_DENSITY) { // The density of material in the space of the voxel sets whether it is actually colored for (int c = 0; c < 3; c++) { // set the average color value newColor[c] = colorArray[c] / colorArray[3]; } // set the alpha to 1 to indicate that this isn't transparent newColor[3] = 1; } // Set the color from the average of the child colors, and update the density setColor(newColor); setDensity(density); }