Conflicts:
	voxel-server/src/main.cpp
This commit is contained in:
Andrzej Kapolka 2013-05-08 11:56:03 -07:00
commit c34b6df2f4
14 changed files with 323 additions and 304 deletions

View file

@ -63,11 +63,6 @@ void VoxelSystem::loadVoxelsFile(const char* fileName, bool wantColorRandomizer)
setupNewVoxelsForDrawing();
}
void VoxelSystem::createSphere(float r,float xc, float yc, float zc, float s, bool solid, bool wantColorRandomizer) {
_tree->createSphere(r, xc, yc, zc, s, solid, wantColorRandomizer);
setupNewVoxelsForDrawing();
}
long int VoxelSystem::getVoxelsCreated() {
return _tree->voxelsCreated;
}

View file

@ -42,7 +42,6 @@ public:
void setViewerAvatar(Avatar *newViewerAvatar) { _viewerAvatar = newViewerAvatar; };
void setCamera(Camera* newCamera) { _camera = newCamera; };
void loadVoxelsFile(const char* fileName,bool wantColorRandomizer);
void createSphere(float r,float xc, float yc, float zc, float s, bool solid, bool wantColorRandomizer);
long int getVoxelsCreated();
long int getVoxelsColored();

View file

@ -1444,23 +1444,6 @@ void setupPaintingVoxel() {
shiftPaintingColor();
}
void addRandomSphere(bool wantColorRandomizer) {
float r = randFloatInRange(0.05,0.1);
float xc = randFloatInRange(r,(1-r));
float yc = randFloatInRange(r,(1-r));
float zc = randFloatInRange(r,(1-r));
float s = 0.001; // size of voxels to make up surface of sphere
bool solid = false;
printLog("random sphere\n");
printLog("radius=%f\n",r);
printLog("xc=%f\n",xc);
printLog("yc=%f\n",yc);
printLog("zc=%f\n",zc);
voxels.createSphere(r,xc,yc,zc,s,solid,wantColorRandomizer);
}
const float KEYBOARD_YAW_RATE = 0.8;
const float KEYBOARD_PITCH_RATE = 0.6;
const float KEYBOARD_STRAFE_RATE = 0.03;

View file

@ -170,7 +170,7 @@ bool cmdOptionExists(int argc, const char * argv[],const char* option) {
// Complaints: Brad :)
#define GUESS_OF_VOXELCODE_SIZE 10
#define MAXIMUM_EDIT_VOXEL_MESSAGE_SIZE 1500
#define SIZE_OF_COLOR_DATA 3
#define SIZE_OF_COLOR_DATA sizeof(rgbColor)
bool createVoxelEditMessage(unsigned char command, short int sequence,
int voxelCount, VoxelDetail* voxelDetails, unsigned char*& bufferOut, int& sizeOut) {
@ -231,27 +231,26 @@ bool createVoxelEditMessage(unsigned char command, short int sequence,
unsigned char* pointToVoxel(float x, float y, float z, float s, unsigned char r, unsigned char g, unsigned char b ) {
float xTest, yTest, zTest, sTest;
xTest = yTest = zTest = sTest = 0.5;
xTest = yTest = zTest = sTest = 0.5f;
// First determine the voxelSize that will properly encode a
// voxel of size S.
int voxelSizeInBits = 0;
unsigned int voxelSizeInOctets = 1;
while (sTest > s) {
sTest /= 2.0;
voxelSizeInBits+=3;
voxelSizeInOctets++;
}
unsigned int voxelSizeInBytes = (voxelSizeInBits/8)+1;
unsigned int voxelSizeInOctets = (voxelSizeInBits/3);
unsigned int voxelBufferSize = voxelSizeInBytes+1+3; // 1 for size, 3 for color
unsigned int voxelSizeInBytes = bytesRequiredForCodeLength(voxelSizeInOctets); // (voxelSizeInBits/8)+1;
unsigned int voxelBufferSize = voxelSizeInBytes + sizeof(rgbColor); // 3 for color
// allocate our resulting buffer
unsigned char* voxelOut = new unsigned char[voxelBufferSize];
// first byte of buffer is always our size in octets
voxelOut[0]=voxelSizeInOctets;
sTest = 0.5; // reset sTest so we can do this again.
sTest = 0.5f; // reset sTest so we can do this again.
unsigned char byte = 0; // we will be adding coding bits here
int bitInByteNDX = 0; // keep track of where we are in byte as we go
@ -260,7 +259,7 @@ unsigned char* pointToVoxel(float x, float y, float z, float s, unsigned char r,
// Now we actually fill out the voxel code
while (octetsDone < voxelSizeInOctets) {
if (x > xTest) {
if (x >= xTest) {
//<write 1 bit>
byte = (byte << 1) | true;
xTest += sTest/2.0;
@ -272,14 +271,14 @@ unsigned char* pointToVoxel(float x, float y, float z, float s, unsigned char r,
bitInByteNDX++;
// If we've reached the last bit of the byte, then we want to copy this byte
// into our buffer. And get ready to start on a new byte
if (bitInByteNDX > 7) {
if (bitInByteNDX == 8) {
voxelOut[byteNDX]=byte;
byteNDX++;
bitInByteNDX=0;
byte=0;
}
if (y > yTest) {
if (y >= yTest) {
//<write 1 bit>
byte = (byte << 1) | true;
yTest += sTest/2.0;
@ -291,14 +290,14 @@ unsigned char* pointToVoxel(float x, float y, float z, float s, unsigned char r,
bitInByteNDX++;
// If we've reached the last bit of the byte, then we want to copy this byte
// into our buffer. And get ready to start on a new byte
if (bitInByteNDX > 7) {
if (bitInByteNDX == 8) {
voxelOut[byteNDX]=byte;
byteNDX++;
bitInByteNDX=0;
byte=0;
}
if (z > zTest) {
if (z >= zTest) {
//<write 1 bit>
byte = (byte << 1) | true;
zTest += sTest/2.0;
@ -310,7 +309,7 @@ unsigned char* pointToVoxel(float x, float y, float z, float s, unsigned char r,
bitInByteNDX++;
// If we've reached the last bit of the byte, then we want to copy this byte
// into our buffer. And get ready to start on a new byte
if (bitInByteNDX > 7) {
if (bitInByteNDX == 8) {
voxelOut[byteNDX]=byte;
byteNDX++;
bitInByteNDX=0;
@ -323,13 +322,13 @@ unsigned char* pointToVoxel(float x, float y, float z, float s, unsigned char r,
// If we've got here, and we didn't fill the last byte, we need to zero pad this
// byte before we copy it into our buffer.
if (bitInByteNDX > 0 && bitInByteNDX < 7) {
if (bitInByteNDX > 0 && bitInByteNDX < 8) {
// Pad the last byte
while (bitInByteNDX <= 7) {
while (bitInByteNDX < 8) {
byte = (byte << 1) | false;
bitInByteNDX++;
}
// Copy it into our output buffer
voxelOut[byteNDX]=byte;
byteNDX++;

View file

@ -18,6 +18,8 @@
#include <sys/time.h>
#endif
typedef unsigned char rgbColor[3];
static const float ZERO = 0.0f;
static const float ONE = 1.0f;
static const float ONE_HALF = 0.5f;

View file

@ -0,0 +1,106 @@
//
// SceneUtils.cpp
// hifi
//
// Created by Brad Hefta-Gaub on 5/7/2013.
//
//
#include "SceneUtils.h"
#include <glm/gtc/noise.hpp>
void addCornersAndAxisLines(VoxelTree* tree) {
// We want our corner voxels to be about 1/2 meter high, and our TREE_SCALE is in meters, so...
float voxelSize = 0.5f / TREE_SCALE;
// Now some more examples... a little more complex
printf("creating corner points...\n");
tree->createVoxel(0 , 0 , 0 , voxelSize, 255, 255 ,255);
tree->createVoxel(1.0 - voxelSize, 0 , 0 , voxelSize, 255, 0 ,0 );
tree->createVoxel(0 , 1.0 - voxelSize, 0 , voxelSize, 0 , 255 ,0 );
tree->createVoxel(0 , 0 , 1.0 - voxelSize, voxelSize, 0 , 0 ,255);
tree->createVoxel(1.0 - voxelSize, 0 , 1.0 - voxelSize, voxelSize, 255, 0 ,255);
tree->createVoxel(0 , 1.0 - voxelSize, 1.0 - voxelSize, voxelSize, 0 , 255 ,255);
tree->createVoxel(1.0 - voxelSize, 1.0 - voxelSize, 0 , voxelSize, 255, 255 ,0 );
tree->createVoxel(1.0 - voxelSize, 1.0 - voxelSize, 1.0 - voxelSize, voxelSize, 255, 255 ,255);
printf("DONE creating corner points...\n");
// Now some more examples... creating some lines using the line primitive
printf("creating voxel lines...\n");
// We want our line voxels to be about 1/32 meter high, and our TREE_SCALE is in meters, so...
float lineVoxelSize = 1.f / (32 * TREE_SCALE);
rgbColor red = {255, 0, 0};
rgbColor green = {0, 255, 0};
rgbColor blue = {0, 0, 255};
tree->createLine(glm::vec3(0, 0, 0), glm::vec3(0, 0, 1), lineVoxelSize, blue);
tree->createLine(glm::vec3(0, 0, 0), glm::vec3(1, 0, 0), lineVoxelSize, red);
tree->createLine(glm::vec3(0, 0, 0), glm::vec3(0, 1, 0), lineVoxelSize, green);
printf("DONE creating lines...\n");
}
void addSphereScene(VoxelTree * tree) {
printf("adding sphere scene...\n");
// Now some more examples... creating some spheres using the sphere primitive
// We want the smallest unit of our spheres to be about 1/16th of a meter tall
float sphereVoxelSize = 1.f / (8 * TREE_SCALE);
printf("creating spheres... sphereVoxelSize=%f\n",sphereVoxelSize);
tree->createSphere(0.030625, 0.5, 0.5, (0.25 - 0.06125), sphereVoxelSize, true, NATURAL);
printf("1 spheres added... sphereVoxelSize=%f\n",sphereVoxelSize);
tree->createSphere(0.030625, (0.75 - 0.030625), (0.75 - 0.030625), (0.75 - 0.06125), sphereVoxelSize, true, GRADIENT);
printf("2 spheres added... sphereVoxelSize=%f\n",sphereVoxelSize);
tree->createSphere(0.030625, (0.75 - 0.030625), (0.75 - 0.030625), 0.06125, sphereVoxelSize, true, RANDOM);
printf("3 spheres added... sphereVoxelSize=%f\n",sphereVoxelSize);
tree->createSphere(0.030625, (0.75 - 0.030625), 0.06125, (0.75 - 0.06125), sphereVoxelSize, true, GRADIENT);
printf("4 spheres added... sphereVoxelSize=%f\n",sphereVoxelSize);
tree->createSphere(0.06125, 0.125, 0.125, (0.75 - 0.125), sphereVoxelSize, true, GRADIENT);
/**
float radius = 0.0125f;
printf("5 spheres added...\n");
tree->createSphere(radius, 0.25, radius * 5.0f, 0.25, sphereVoxelSize, true, GRADIENT);
printf("6 spheres added...\n");
tree->createSphere(radius, 0.125, radius * 5.0f, 0.25, sphereVoxelSize, true, RANDOM);
printf("7 spheres added...\n");
tree->createSphere(radius, 0.075, radius * 5.0f, 0.25, sphereVoxelSize, true, GRADIENT);
printf("8 spheres added...\n");
tree->createSphere(radius, 0.05, radius * 5.0f, 0.25, sphereVoxelSize, true, RANDOM);
printf("9 spheres added...\n");
tree->createSphere(radius, 0.025, radius * 5.0f, 0.25, sphereVoxelSize, true, GRADIENT);
printf("10 spheres added...\n");
*/
float largeRadius = 0.1875f;
tree->createSphere(largeRadius, 0.5, 0.5, 0.5, sphereVoxelSize, true, NATURAL);
printf("11 - last large sphere added... largeRadius=%f sphereVoxelSize=%f\n", largeRadius, sphereVoxelSize);
printf("DONE adding scene of spheres...\n");
}
void addSurfaceScene(VoxelTree * tree) {
printf("adding surface scene...\n");
float voxelSize = 1.f / (8 * TREE_SCALE);
// color 1= blue, color 2=green
unsigned char r1, g1, b1, r2, g2, b2, red, green, blue;
r1 = r2 = b2 = g1 = 0;
b1 = g2 = 255;
for (float x = 0.0; x < 1.0; x += voxelSize) {
for (float z = 0.0; z < 1.0; z += voxelSize) {
glm::vec2 position = glm::vec2(x, z);
float perlin = glm::perlin(position) + .25f * glm::perlin(position * 4.f) + .125f * glm::perlin(position * 16.f);
float gradient = (1.0f + perlin)/ 2.0f;
red = (unsigned char)std::min(255, std::max(0, (int)(r1 + ((r2 - r1) * gradient))));
green = (unsigned char)std::min(255, std::max(0, (int)(g1 + ((g2 - g1) * gradient))));
blue = (unsigned char)std::min(255, std::max(0, (int)(b1 + ((b2 - b1) * gradient))));
int height = (4 * gradient)+1; // make it at least 4 thick, so we get some averaging
for (int i = 0; i < height; i++) {
tree->createVoxel(x, ((i+1) * voxelSize) , z, voxelSize, red, green, blue);
}
}
}
printf("DONE adding surface scene...\n");
}

View file

@ -0,0 +1,20 @@
//
// SceneUtils.h
// hifi
//
// Created by Brad Hefta-Gaub on 5/7/2013.
//
//
#ifndef __hifi__SceneUtil__
#define __hifi__SceneUtil__
#include "VoxelTree.h"
#include <SharedUtil.h>
void addCornersAndAxisLines(VoxelTree* tree);
void addSphereScene(VoxelTree * tree);
void addSurfaceScene(VoxelTree * tree);
#endif /* defined(__hifi__SceneUtil__) */

View file

@ -14,12 +14,12 @@
#include <limits.h>
const int TREE_SCALE = 100;
const int TREE_SCALE = 128;
const int NUMBER_OF_CHILDREN = 8;
const int MAX_VOXEL_PACKET_SIZE = 1492;
const int MAX_TREE_SLICE_BYTES = 26;
const int MAX_VOXELS_PER_SYSTEM = 250000;
const int MAX_VOXELS_PER_SYSTEM = 500000;
const int VERTICES_PER_VOXEL = 24;
const int VERTEX_POINTS_PER_VOXEL = 3 * VERTICES_PER_VOXEL;
const int INDICES_PER_VOXEL = 3 * 12;

View file

@ -123,7 +123,6 @@ void VoxelNode::setColorFromAverageOfChildren() {
colorArray[3]++;
}
}
nodeColor newColor = { 0, 0, 0, 0};
if (colorArray[3] > 4) {
// we need at least 4 colored children to have an average color value
@ -179,9 +178,7 @@ void VoxelNode::setColor(const nodeColor& color) {
if (!_falseColored) {
memcpy(&_currentColor,&color,sizeof(nodeColor));
}
//if (_shouldRender) {
_isDirty = true;
//}
_isDirty = true;
}
}
#endif

View file

@ -22,10 +22,12 @@
#include <fstream> // to load voxels from file
#include "VoxelConstants.h"
#include <glm/gtc/noise.hpp>
using voxels_lib::printLog;
int boundaryDistanceForRenderLevel(unsigned int renderLevel) {
float voxelSizeScale = 500.0*TREE_SCALE;
float voxelSizeScale = 50000.0f;
return voxelSizeScale / powf(2, renderLevel);
}
@ -113,9 +115,7 @@ VoxelNode* VoxelTree::createMissingNode(VoxelNode* lastParentNode, unsigned char
}
}
int VoxelTree::readNodeData(VoxelNode* destinationNode,
unsigned char* nodeData,
int bytesLeftToRead) {
int VoxelTree::readNodeData(VoxelNode* destinationNode, unsigned char* nodeData, int bytesLeftToRead) {
// instantiate variable for bytes already read
int bytesRead = 1;
for (int i = 0; i < NUMBER_OF_CHILDREN; i++) {
@ -457,87 +457,136 @@ void VoxelTree::createLine(glm::vec3 point1, glm::vec3 point2, float unitSize, r
}
void VoxelTree::createSphere(float radius, float xc, float yc, float zc, float voxelSize,
bool solid, bool wantColorRandomizer, bool debug) {
bool solid, creationMode mode, bool debug) {
// About the color of the sphere... we're going to make this sphere be a gradient
// between two RGB colors. We will do the gradient along the phi spectrum
unsigned char dominantColor1 = randIntInRange(1, 3); //1=r, 2=g, 3=b dominant
unsigned char dominantColor2 = randIntInRange(1, 3);
bool wantColorRandomizer = (mode == RANDOM);
bool wantNaturalSurface = (mode == NATURAL);
bool wantNaturalColor = (mode == NATURAL);
if (dominantColor1 == dominantColor2) {
dominantColor2 = dominantColor1 + 1 % 3;
// About the color of the sphere... we're going to make this sphere be a mixture of two colors
// in NATURAL mode, those colors will be green dominant and blue dominant. In GRADIENT mode we
// will randomly pick which color family red, green, or blue to be dominant. In RANDOM mode we
// ignore these dominant colors and make every voxel a completely random color.
unsigned char r1, g1, b1, r2, g2, b2;
if (wantNaturalColor) {
r1 = r2 = b2 = g1 = 0;
b1 = g2 = 255;
} else if (!wantColorRandomizer) {
unsigned char dominantColor1 = randIntInRange(1, 3); //1=r, 2=g, 3=b dominant
unsigned char dominantColor2 = randIntInRange(1, 3);
if (dominantColor1 == dominantColor2) {
dominantColor2 = dominantColor1 + 1 % 3;
}
r1 = (dominantColor1 == 1) ? randIntInRange(200, 255) : randIntInRange(40, 100);
g1 = (dominantColor1 == 2) ? randIntInRange(200, 255) : randIntInRange(40, 100);
b1 = (dominantColor1 == 3) ? randIntInRange(200, 255) : randIntInRange(40, 100);
r2 = (dominantColor2 == 1) ? randIntInRange(200, 255) : randIntInRange(40, 100);
g2 = (dominantColor2 == 2) ? randIntInRange(200, 255) : randIntInRange(40, 100);
b2 = (dominantColor2 == 3) ? randIntInRange(200, 255) : randIntInRange(40, 100);
}
unsigned char r1 = (dominantColor1 == 1) ? randIntInRange(200, 255) : randIntInRange(40, 100);
unsigned char g1 = (dominantColor1 == 2) ? randIntInRange(200, 255) : randIntInRange(40, 100);
unsigned char b1 = (dominantColor1 == 3) ? randIntInRange(200, 255) : randIntInRange(40, 100);
unsigned char r2 = (dominantColor2 == 1) ? randIntInRange(200, 255) : randIntInRange(40, 100);
unsigned char g2 = (dominantColor2 == 2) ? randIntInRange(200, 255) : randIntInRange(40, 100);
unsigned char b2 = (dominantColor2 == 3) ? randIntInRange(200, 255) : randIntInRange(40, 100);
// We initialize our rgb to be either "grey" in case of randomized surface, or
// the average of the gradient, in the case of the gradient sphere.
// We initialize our rgb to be either "grey" in case of randomized surface, or
// the average of the gradient, in the case of the gradient sphere.
unsigned char red = wantColorRandomizer ? 128 : (r1 + r2) / 2; // average of the colors
unsigned char green = wantColorRandomizer ? 128 : (g1 + g2) / 2;
unsigned char blue = wantColorRandomizer ? 128 : (b1 + b2) / 2;
// Psuedocode for creating a sphere:
//
// for (theta from 0 to 2pi):
// for (phi from 0 to pi):
// x = xc+r*cos(theta)*sin(phi)
// y = yc+r*sin(theta)*sin(phi)
// z = zc+r*cos(phi)
// assume solid for now
float thisRadius = 0.0;
float thisVoxelSize = radius / 4.0f;
if (!solid) {
thisRadius = radius; // just the outer surface
thisVoxelSize = voxelSize;
}
// If you also iterate form the interior of the sphere to the radius, makeing
// larger and larger sphere'voxelSize you'd end up with a solid sphere. And lots of voxels!
while (thisRadius <= (radius + (voxelSize / 2.0))) {
if (debug) {
printLog("radius: thisRadius=%f thisVoxelSize=%f thisRadius+thisVoxelSize=%f (radius+(voxelSize/2.0))=%f\n",
thisRadius, thisVoxelSize, thisRadius+thisVoxelSize, (radius + (voxelSize / 2.0)));
}
// I want to do something smart like make these inside circles with bigger voxels, but this doesn't seem to work.
float thisVoxelSize = voxelSize; // radius / 2.0f;
float thisRadius = 0.0;
if (!solid) {
thisRadius = radius; // just the outer surface
thisVoxelSize = voxelSize;
}
// If you also iterate form the interior of the sphere to the radius, making
// larger and larger spheres you'd end up with a solid sphere. And lots of voxels!
bool lastLayer = false;
while (!lastLayer) {
lastLayer = (thisRadius + (voxelSize * 2.0) >= radius);
// We want to make sure that as we "sweep" through our angles we use a delta angle that voxelSize
// small enough to not skip any voxels we can calculate theta from our desired arc length
// lenArc = ndeg/360deg * 2pi*R ---> lenArc = theta/2pi * 2pi*R
// lenArc = theta*R ---> theta = lenArc/R ---> theta = g/r
float angleDelta = (thisVoxelSize / thisRadius);
for (float theta=0.0; theta <= 2 * M_PI; theta += angleDelta) {
for (float phi=0.0; phi <= M_PI; phi += angleDelta) {
float x = xc + thisRadius * cos(theta) * sin(phi);
float y = yc + thisRadius * sin(theta) * sin(phi);
float z = zc + thisRadius * cos(phi);
// gradient color data
float gradient = (phi / M_PI);
// only use our actual desired color on the outer edge, otherwise
// use our "average" color
if (thisRadius + (voxelSize * 2.0) >= radius) {
//printLog("painting candy shell radius: thisRadius=%f radius=%f\n",thisRadius,radius);
red = wantColorRandomizer ? randomColorValue(165) : r1 + ((r2 - r1) * gradient);
green = wantColorRandomizer ? randomColorValue(165) : g1 + ((g2 - g1) * gradient);
blue = wantColorRandomizer ? randomColorValue(165) : b1 + ((b2 - b1) * gradient);
}
unsigned char* voxelData = pointToVoxel(x, y, z, thisVoxelSize, red, green, blue);
this->readCodeColorBufferToTree(voxelData);
delete voxelData;
}
}
if (debug) {
int percentComplete = 100 * (thisRadius/radius);
printLog("percentComplete=%d\n",percentComplete);
}
for (float theta=0.0; theta <= 2 * M_PI; theta += angleDelta) {
for (float phi=0.0; phi <= M_PI; phi += angleDelta) {
bool naturalSurfaceRendered = false;
float x = xc + thisRadius * cos(theta) * sin(phi);
float y = yc + thisRadius * sin(theta) * sin(phi);
float z = zc + thisRadius * cos(phi);
// if we're on the outer radius, then we do a couple of things differently.
// 1) If we're in NATURAL mode we will actually draw voxels from our surface outward (from the surface) up
// some random height. This will give our sphere some contours.
// 2) In all modes, we will use our "outer" color to draw the voxels. Otherwise we will use the average color
if (lastLayer) {
if (false && debug) {
printLog("adding candy shell: theta=%f phi=%f thisRadius=%f radius=%f\n",
theta, phi, thisRadius,radius);
}
switch (mode) {
case RANDOM: {
red = randomColorValue(165);
green = randomColorValue(165);
blue = randomColorValue(165);
} break;
case GRADIENT: {
float gradient = (phi / M_PI);
red = r1 + ((r2 - r1) * gradient);
green = g1 + ((g2 - g1) * gradient);
blue = b1 + ((b2 - b1) * gradient);
} break;
case NATURAL: {
glm::vec3 position = glm::vec3(theta,phi,radius);
float perlin = glm::perlin(position) + .25f * glm::perlin(position * 4.f)
+ .125f * glm::perlin(position * 16.f);
float gradient = (1.0f + perlin)/ 2.0f;
red = (unsigned char)std::min(255, std::max(0, (int)(r1 + ((r2 - r1) * gradient))));
green = (unsigned char)std::min(255, std::max(0, (int)(g1 + ((g2 - g1) * gradient))));
blue = (unsigned char)std::min(255, std::max(0, (int)(b1 + ((b2 - b1) * gradient))));
if (debug) {
printLog("perlin=%f gradient=%f color=(%d,%d,%d)\n",perlin, gradient, red, green, blue);
}
} break;
}
if (wantNaturalSurface) {
// for natural surfaces, we will render up to 16 voxel's above the surface of the sphere
glm::vec3 position = glm::vec3(theta,phi,radius);
float perlin = glm::perlin(position) + .25f * glm::perlin(position * 4.f)
+ .125f * glm::perlin(position * 16.f);
float gradient = (1.0f + perlin)/ 2.0f;
int height = (4 * gradient)+1; // make it at least 4 thick, so we get some averaging
float subVoxelScale = thisVoxelSize;
for (int i = 0; i < height; i++) {
x = xc + (thisRadius + i * subVoxelScale) * cos(theta) * sin(phi);
y = yc + (thisRadius + i * subVoxelScale) * sin(theta) * sin(phi);
z = zc + (thisRadius + i * subVoxelScale) * cos(phi);
this->createVoxel(x, y, z, subVoxelScale, red, green, blue);
}
naturalSurfaceRendered = true;
}
}
if (!naturalSurfaceRendered) {
this->createVoxel(x, y, z, thisVoxelSize, red, green, blue);
}
}
}
thisRadius += thisVoxelSize;
thisVoxelSize = std::max(voxelSize, thisVoxelSize / 2.0f);
}
this->reaverageVoxelColors(this->rootNode);
thisVoxelSize = std::max(voxelSize, thisVoxelSize / 2.0f);
}
this->reaverageVoxelColors(this->rootNode);
}
int VoxelTree::searchForColoredNodes(int maxSearchLevel, VoxelNode* node, const ViewFrustum& viewFrustum, VoxelNodeBag& bag) {
@ -923,3 +972,13 @@ void VoxelTree::writeToFileV2(const char* fileName) const {
file.close();
}
unsigned long VoxelTree::getVoxelCount() {
unsigned long nodeCount = 0;
recurseTreeWithOperation(countVoxelsOperation, &nodeCount);
return nodeCount;
}
bool VoxelTree::countVoxelsOperation(VoxelNode* node, void* extraData) {
(*(unsigned long*)extraData)++;
return true; // keep going
}

View file

@ -17,6 +17,7 @@
// Callback function, for recuseTreeWithOperation
typedef bool (*RecurseVoxelTreeOperation)(VoxelNode* node, void* extraData);
typedef enum {GRADIENT, RANDOM, NATURAL} creationMode;
class VoxelTree {
public:
@ -49,7 +50,7 @@ public:
VoxelNode* getVoxelAt(float x, float y, float z, float s) const;
void createVoxel(float x, float y, float z, float s, unsigned char red, unsigned char green, unsigned char blue);
void createLine(glm::vec3 point1, glm::vec3 point2, float unitSize, rgbColor color);
void createSphere(float r,float xc, float yc, float zc, float s, bool solid, bool wantColorRandomizer, bool debug = false);
void createSphere(float r,float xc, float yc, float zc, float s, bool solid, creationMode mode, bool debug = false);
void recurseTreeWithOperation(RecurseVoxelTreeOperation operation, void* extraData=NULL);
@ -70,6 +71,8 @@ public:
// these will read/write files that match the wireformat, excluding the 'V' leading
void writeToFileV2(const char* filename) const;
bool readFromFileV2(const char* filename);
unsigned long getVoxelCount();
private:
int encodeTreeBitstreamRecursion(int maxEncodeLevel, int& currentEncodeLevel,
@ -79,6 +82,8 @@ private:
int searchForColoredNodesRecursion(int maxSearchLevel, int& currentSearchLevel,
VoxelNode* node, const ViewFrustum& viewFrustum, VoxelNodeBag& bag);
static bool countVoxelsOperation(VoxelNode* node, void* extraData);
void recurseNodeWithOperation(VoxelNode* node, RecurseVoxelTreeOperation operation, void* extraData);
VoxelNode* nodeForOctalCode(VoxelNode* ancestorNode, unsigned char* needleCode, VoxelNode** parentOfFoundNode) const;
VoxelNode* createMissingNode(VoxelNode* lastParentNode, unsigned char* deepestCodeToCreate);

View file

@ -8,23 +8,14 @@
#include <VoxelTree.h>
#include <SharedUtil.h>
#include <SceneUtils.h>
VoxelTree myTree;
int _nodeCount=0;
bool countVoxelsOperation(VoxelNode* node, void* extraData) {
if (node->isColored()){
_nodeCount++;
}
return true; // keep going
}
void addScene(VoxelTree * tree) {
printf("adding scene...\n");
void voxelTutorial(VoxelTree* tree) {
// We want our corner voxels to be about 1/2 meter high, and our TREE_SCALE is in meters, so...
float voxelSize = 0.5f / TREE_SCALE;
// Here's an example of how to create a voxel.
printf("creating corner points...\n");
tree->createVoxel(0, 0, 0, voxelSize, 255, 255 ,255);
@ -47,72 +38,8 @@ void addScene(VoxelTree * tree) {
} else {
printf("corner point 0,0,0 does not exists...\n");
}
// Now some more examples... a little more complex
printf("creating corner points...\n");
tree->createVoxel(0 , 0 , 0 , voxelSize, 255, 255 ,255);
tree->createVoxel(1.0 - voxelSize, 0 , 0 , voxelSize, 255, 0 ,0 );
tree->createVoxel(0 , 1.0 - voxelSize, 0 , voxelSize, 0 , 255 ,0 );
tree->createVoxel(0 , 0 , 1.0 - voxelSize, voxelSize, 0 , 0 ,255);
tree->createVoxel(1.0 - voxelSize, 0 , 1.0 - voxelSize, voxelSize, 255, 0 ,255);
tree->createVoxel(0 , 1.0 - voxelSize, 1.0 - voxelSize, voxelSize, 0 , 255 ,255);
tree->createVoxel(1.0 - voxelSize, 1.0 - voxelSize, 0 , voxelSize, 255, 255 ,0 );
tree->createVoxel(1.0 - voxelSize, 1.0 - voxelSize, 1.0 - voxelSize, voxelSize, 255, 255 ,255);
printf("DONE creating corner points...\n");
// Now some more examples... creating some lines using the line primitive
printf("creating voxel lines...\n");
// We want our line voxels to be about 1/32 meter high, and our TREE_SCALE is in meters, so...
float lineVoxelSize = 1.f / (32 * TREE_SCALE);
rgbColor red = {255, 0, 0};
rgbColor green = {0, 255, 0};
rgbColor blue = {0, 0, 255};
tree->createLine(glm::vec3(0, 0, 0), glm::vec3(0, 0, 1), lineVoxelSize, blue);
tree->createLine(glm::vec3(0, 0, 0), glm::vec3(1, 0, 0), lineVoxelSize, red);
tree->createLine(glm::vec3(0, 0, 0), glm::vec3(0, 1, 0), lineVoxelSize, green);
printf("DONE creating lines...\n");
// Now some more examples... creating some spheres using the sphere primitive
// We want the smallest unit of our spheres to be about 1/16th of a meter tall
float sphereVoxelSize = 1.f / (16 * TREE_SCALE);
printf("creating spheres... sphereVoxelSize=%f\n",sphereVoxelSize);
tree->createSphere(0.25, 0.5, 0.5, 0.5, sphereVoxelSize, true, false, true);
printf("one sphere added... sphereVoxelSize=%f\n",sphereVoxelSize);
tree->createSphere(0.030625, 0.5, 0.5, (0.25 - 0.06125), sphereVoxelSize, true, true);
printf("two spheres added... sphereVoxelSize=%f\n",sphereVoxelSize);
tree->createSphere(0.030625, (0.75 - 0.030625), (0.75 - 0.030625), (0.75 - 0.06125), sphereVoxelSize, true, true);
printf("three spheres added... sphereVoxelSize=%f\n",sphereVoxelSize);
tree->createSphere(0.030625, (0.75 - 0.030625), (0.75 - 0.030625), 0.06125, sphereVoxelSize, true, true);
printf("four spheres added... sphereVoxelSize=%f\n",sphereVoxelSize);
tree->createSphere(0.030625, (0.75 - 0.030625), 0.06125, (0.75 - 0.06125), sphereVoxelSize, true, true);
printf("five spheres added... sphereVoxelSize=%f\n",sphereVoxelSize);
tree->createSphere(0.06125, 0.125, 0.125, (0.75 - 0.125), sphereVoxelSize, true, true);
float radius = 0.0125f;
printf("6 spheres added...\n");
tree->createSphere(radius, 0.25, radius * 5.0f, 0.25, (1.0 / 4096), true, true);
printf("7 spheres added...\n");
tree->createSphere(radius, 0.125, radius * 5.0f, 0.25, (1.0 / 4096), true, true);
printf("8 spheres added...\n");
tree->createSphere(radius, 0.075, radius * 5.0f, 0.25, (1.0 / 4096), true, true);
printf("9 spheres added...\n");
tree->createSphere(radius, 0.05, radius * 5.0f, 0.25, (1.0 / 4096), true, true);
printf("10 spheres added...\n");
tree->createSphere(radius, 0.025, radius * 5.0f, 0.25, (1.0 / 4096), true, true);
printf("11 spheres added...\n");
printf("DONE creating spheres...\n");
// Here's an example of how to recurse the tree and do some operation on the nodes as you recurse them.
// This one is really simple, it just couts them...
// Look at the function countVoxelsOperation() for an example of how you could use this function
_nodeCount=0;
tree->recurseTreeWithOperation(countVoxelsOperation);
printf("Nodes after adding scene %d nodes\n", _nodeCount);
printf("DONE adding scene of spheres...\n");
}
int main(int argc, const char * argv[])
{
const char* SAY_HELLO = "--sayHello";
@ -127,8 +54,32 @@ int main(int argc, const char * argv[])
printf("You asked us not to create a scene file, so we will not.\n");
} else {
printf("Creating Scene File...\n");
addScene(&myTree);
const char* RUN_TUTORIAL = "--runTutorial";
if (cmdOptionExists(argc, argv, RUN_TUTORIAL)) {
voxelTutorial(&myTree);
}
const char* ADD_CORNERS_AND_AXIS_LINES = "--addCornersAndAxisLines";
if (cmdOptionExists(argc, argv, ADD_CORNERS_AND_AXIS_LINES)) {
addCornersAndAxisLines(&myTree);
}
const char* ADD_SPHERE_SCENE = "--addSphereScene";
if (cmdOptionExists(argc, argv, ADD_SPHERE_SCENE)) {
addSphereScene(&myTree);
}
const char* ADD_SURFACE_SCENE = "--addSurfaceScene";
if (cmdOptionExists(argc, argv, ADD_SURFACE_SCENE)) {
addSurfaceScene(&myTree);
}
unsigned long nodeCount = myTree.getVoxelCount();
printf("Nodes after adding scenes: %ld nodes\n", nodeCount);
myTree.writeToFileV2("voxels.hio2");
}
return 0;
}

Binary file not shown.

View file

@ -18,6 +18,7 @@
#include "VoxelAgentData.h"
#include <SharedUtil.h>
#include <PacketHeaders.h>
#include <SceneUtils.h>
#ifdef _WIN32
#include "Syssocket.h"
@ -28,6 +29,8 @@
#include <ifaddrs.h>
#endif
const char* VOXELS_PERSIST_FILE = "resources/voxels.hio2";
const int VOXEL_LISTEN_PORT = 40106;
@ -51,99 +54,6 @@ bool debugVoxelSending = false;
EnvironmentData environmentData;
void addSphere(VoxelTree * tree,bool random, bool wantColorRandomizer) {
float r = random ? randFloatInRange(0.05,0.1) : 0.25;
float xc = random ? randFloatInRange(r,(1-r)) : 0.5;
float yc = random ? randFloatInRange(r,(1-r)) : 0.5;
float zc = random ? randFloatInRange(r,(1-r)) : 0.5;
float s = (1.0/256); // size of voxels to make up surface of sphere
bool solid = true;
printf("adding sphere:");
if (random)
printf(" random");
printf("\nradius=%f\n",r);
printf("xc=%f\n",xc);
printf("yc=%f\n",yc);
printf("zc=%f\n",zc);
tree->createSphere(r,xc,yc,zc,s,solid,wantColorRandomizer);
}
int _nodeCount=0;
bool countVoxelsOperation(VoxelNode* node, void* extraData) {
if (node->isColored()){
_nodeCount++;
}
return true; // keep going
}
void addSphereScene(VoxelTree * tree, bool wantColorRandomizer) {
printf("adding scene...\n");
float voxelSize = 1.f/32;
printf("creating corner points...\n");
tree->createVoxel(0 , 0 , 0 , voxelSize, 255, 255 ,255);
tree->createVoxel(1.0 - voxelSize, 0 , 0 , voxelSize, 255, 0 ,0 );
tree->createVoxel(0 , 1.0 - voxelSize, 0 , voxelSize, 0 , 255 ,0 );
tree->createVoxel(0 , 0 , 1.0 - voxelSize, voxelSize, 0 , 0 ,255);
tree->createVoxel(1.0 - voxelSize, 0 , 1.0 - voxelSize, voxelSize, 255, 0 ,255);
tree->createVoxel(0 , 1.0 - voxelSize, 1.0 - voxelSize, voxelSize, 0 , 255 ,255);
tree->createVoxel(1.0 - voxelSize, 1.0 - voxelSize, 0 , voxelSize, 255, 255 ,0 );
tree->createVoxel(1.0 - voxelSize, 1.0 - voxelSize, 1.0 - voxelSize, voxelSize, 255, 255 ,255);
printf("DONE creating corner points...\n");
printf("creating voxel lines...\n");
float lineVoxelSize = 0.99f/256;
rgbColor red = {255,0,0};
rgbColor green = {0,255,0};
rgbColor blue = {0,0,255};
tree->createLine(glm::vec3(0, 0, 0), glm::vec3(0, 0, 1), lineVoxelSize, blue);
tree->createLine(glm::vec3(0, 0, 0), glm::vec3(1, 0, 0), lineVoxelSize, red);
tree->createLine(glm::vec3(0, 0, 0), glm::vec3(0, 1, 0), lineVoxelSize, green);
printf("DONE creating lines...\n");
int sphereBaseSize = 512;
printf("creating spheres...\n");
tree->createSphere(0.25, 0.5, 0.5, 0.5, (1.0 / sphereBaseSize), true, wantColorRandomizer);
printf("one sphere added...\n");
tree->createSphere(0.030625, 0.5, 0.5, (0.25-0.06125), (1.0 / (sphereBaseSize * 2)), true, true);
printf("two spheres added...\n");
tree->createSphere(0.030625, (0.75 - 0.030625), (0.75 - 0.030625), (0.75 - 0.06125), (1.0 / (sphereBaseSize * 2)), true, true);
printf("three spheres added...\n");
tree->createSphere(0.030625, (0.75 - 0.030625), (0.75 - 0.030625), 0.06125, (1.0 / (sphereBaseSize * 2)), true, true);
printf("four spheres added...\n");
tree->createSphere(0.030625, (0.75 - 0.030625), 0.06125, (0.75 - 0.06125), (1.0 / (sphereBaseSize * 2)), true, true);
printf("five spheres added...\n");
tree->createSphere(0.06125, 0.125, 0.125, (0.75 - 0.125), (1.0 / (sphereBaseSize * 2)), true, true);
float radius = 0.0125f;
printf("6 spheres added...\n");
tree->createSphere(radius, 0.25, radius * 5.0f, 0.25, (1.0 / 4096), true, true);
printf("7 spheres added...\n");
tree->createSphere(radius, 0.125, radius * 5.0f, 0.25, (1.0 / 4096), true, true);
printf("8 spheres added...\n");
tree->createSphere(radius, 0.075, radius * 5.0f, 0.25, (1.0 / 4096), true, true);
printf("9 spheres added...\n");
tree->createSphere(radius, 0.05, radius * 5.0f, 0.25, (1.0 / 4096), true, true);
printf("10 spheres added...\n");
tree->createSphere(radius, 0.025, radius * 5.0f, 0.25, (1.0 / 4096), true, true);
printf("11 spheres added...\n");
printf("DONE creating spheres...\n");
_nodeCount=0;
tree->recurseTreeWithOperation(countVoxelsOperation);
printf("Nodes after adding scene %d nodes\n", _nodeCount);
printf("DONE adding scene of spheres...\n");
}
void randomlyFillVoxelTree(int levelsToGo, VoxelNode *currentRootNode) {
// randomly generate children for this node
@ -307,7 +217,7 @@ void persistVoxelsWhenDirty() {
// check the dirty bit and persist here...
if (::wantVoxelPersist && ::randomTree.isDirty()) {
printf("saving voxels to file...\n");
randomTree.writeToFileV2("voxels.hio2");
randomTree.writeToFileV2(VOXELS_PERSIST_FILE);
randomTree.clearDirtyBit(); // tree is clean after saving
printf("DONE saving voxels to file...\n");
}
@ -402,12 +312,11 @@ int main(int argc, const char * argv[])
bool persistantFileRead = false;
if (::wantVoxelPersist) {
printf("loading voxels from file...\n");
persistantFileRead = ::randomTree.readFromFileV2("voxels.hio2");
persistantFileRead = ::randomTree.readFromFileV2(VOXELS_PERSIST_FILE);
::randomTree.clearDirtyBit(); // the tree is clean since we just loaded it
printf("DONE loading voxels from file...\n");
_nodeCount=0;
::randomTree.recurseTreeWithOperation(countVoxelsOperation);
printf("Nodes after loading scene %d nodes\n", _nodeCount);
unsigned long nodeCount = ::randomTree.getVoxelCount();
printf("Nodes after loading scene %ld nodes\n", nodeCount);
}
// Check to see if the user passed in a command line option for loading an old style local
@ -436,14 +345,6 @@ int main(int argc, const char * argv[])
randomlyFillVoxelTree(MAX_VOXEL_TREE_DEPTH_LEVELS, randomTree.rootNode);
}
const char* ADD_SPHERE = "--AddSphere";
const char* ADD_RANDOM_SPHERE = "--AddRandomSphere";
if (cmdOptionExists(argc, argv, ADD_SPHERE)) {
addSphere(&randomTree,false,wantColorRandomizer);
} else if (cmdOptionExists(argc, argv, ADD_RANDOM_SPHERE)) {
addSphere(&randomTree,true,wantColorRandomizer);
}
const char* ADD_SCENE = "--AddScene";
bool addScene = cmdOptionExists(argc, argv, ADD_SCENE);
const char* NO_ADD_SCENE = "--NoAddScene";
@ -456,9 +357,11 @@ int main(int argc, const char * argv[])
// 1) we attempted to load a persistant file and it wasn't there
// 2) you asked us to add a scene
// HOWEVER -- we will NEVER add a scene if you explicitly tell us not to!
bool actuallyAddScene = !noAddScene && (addScene || (::wantVoxelPersist && !persistantFileRead));
//
// TEMPORARILY DISABLED!!!
bool actuallyAddScene = false; // !noAddScene && (addScene || (::wantVoxelPersist && !persistantFileRead));
if (actuallyAddScene) {
addSphereScene(&randomTree,wantColorRandomizer);
addSphereScene(&randomTree);
}
pthread_t sendVoxelThread;
@ -544,7 +447,7 @@ int main(int argc, const char * argv[])
}
if (0==strcmp(command,(char*)"add scene")) {
printf("got Z message == add scene\n");
addSphereScene(&randomTree,false);
addSphereScene(&randomTree);
}
totalLength += commandLength+1;
}