merge with brad's sphere/load file changes

This commit is contained in:
Stephen Birarda 2013-03-28 14:46:44 -07:00
parent 1b3c15a701
commit 3ead1a5827
3 changed files with 164 additions and 48 deletions

View file

@ -88,45 +88,6 @@ VoxelNode * VoxelTree::createMissingNode(VoxelNode *lastParentNode, unsigned cha
}
}
// if node has color & <= 4 children then prune children
void VoxelTree::pruneTree(VoxelNode* pruneAt) {
int childCount = 0;
int childMask = 0;
// determine how many children we have
for (int i = 0; i < 8; i++) {
if (pruneAt->children[i]) {
childCount++;
}
}
// if appropriate, prune them
if (pruneAt->color[3] && childCount <= 4) {
for (int i = 0; i < 8; i++) {
if (pruneAt->children[i]) {
delete pruneAt->children[i];
pruneAt->children[i]=NULL;
}
}
} else {
// Otherwise, iterate the children and recursively call
// prune on all of them
for (int i = 0; i < 8; i++) {
if (pruneAt->children[i]) {
this->pruneTree(pruneAt->children[i]);
}
}
}
// repair our child mask
// determine how many children we have
pruneAt->childMask = 0;
for (int i = 0; i < 8; i++) {
if (pruneAt->children[i]) {
pruneAt->childMask += (1 << (7 - i));
}
}
}
int VoxelTree::readNodeData(VoxelNode *destinationNode,
unsigned char * nodeData,
int bytesLeftToRead) {
@ -422,3 +383,129 @@ void VoxelTree::printTreeForDebugging(VoxelNode *startNode) {
}
}
}
//////////////////////////////////////////////////////////////////////////////////////////
// Method: VoxelTree::loadVoxelsFile()
// Description: Loads HiFidelity encoded Voxels from a binary file. The current file
// format is a stream of single voxels with color data.
// Complaints: Brad :)
void VoxelTree::loadVoxelsFile(const char* fileName, bool wantColorRandomizer) {
int vCount = 0;
std::ifstream file(fileName, std::ios::in|std::ios::binary);
char octets;
unsigned int lengthInBytes;
int totalBytesRead = 0;
if(file.is_open()) {
printf("loading file...\n");
bool bail = false;
while (!file.eof() && !bail) {
file.get(octets);
//printf("octets=%d...\n",octets);
totalBytesRead++;
lengthInBytes = bytesRequiredForCodeLength(octets)-1; //(octets*3/8)+1;
unsigned char * voxelData = new unsigned char[lengthInBytes+1+3];
voxelData[0]=octets;
char byte;
for (size_t i = 0; i < lengthInBytes; i++) {
file.get(byte);
totalBytesRead++;
voxelData[i+1] = byte;
}
// read color data
char colorRead;
unsigned char red,green,blue;
file.get(colorRead);
red = (unsigned char)colorRead;
file.get(colorRead);
green = (unsigned char)colorRead;
file.get(colorRead);
blue = (unsigned char)colorRead;
printf("voxel color from file red:%d, green:%d, blue:%d \n",red,green,blue);
vCount++;
int colorRandomizer = wantColorRandomizer ? randIntInRange (-5, 5) : 0;
voxelData[lengthInBytes+1] = std::max(0,std::min(255,red + colorRandomizer));
voxelData[lengthInBytes+2] = std::max(0,std::min(255,green + colorRandomizer));
voxelData[lengthInBytes+3] = std::max(0,std::min(255,blue + colorRandomizer));
printf("voxel color after rand red:%d, green:%d, blue:%d\n",
voxelData[lengthInBytes+1], voxelData[lengthInBytes+2], voxelData[lengthInBytes+3]);
//printVoxelCode(voxelData);
this->readCodeColorBufferToTree(voxelData);
delete voxelData;
}
file.close();
}
}
//////////////////////////////////////////////////////////////////////////////////////////
// Method: VoxelTree::createSphere()
// Description: Creates a sphere of voxels in the local system at a given location/radius
// To Do: Move this function someplace better?
// Complaints: Brad :)
void VoxelTree::createSphere(float r,float xc, float yc, float zc, float s, bool solid) {
// 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 r1 = randomColorValue(165);
unsigned char g1 = randomColorValue(165);
unsigned char b1 = randomColorValue(165);
unsigned char r2 = randomColorValue(65);
unsigned char g2 = randomColorValue(65);
unsigned char b2 = randomColorValue(65);
// we don't want them to match!!
if (r1==r2 && g1==g2 && b1==b2) {
r2=r1/2;
g2=g1/2;
b2=b1/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)
int t=0; // total points
// We want to make sure that as we "sweep" through our angles we use a delta angle that's 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 = (s/r);
// assume solid for now
float ri = 0.0;
if (!solid) {
ri=r; // just the outer surface
}
// If you also iterate form the interior of the sphere to the radius, makeing
// larger and larger sphere's you'd end up with a solid sphere. And lots of voxels!
for (; ri <= r; ri+=s) {
for (float theta=0.0; theta <= 2*M_PI; theta += angleDelta) {
for (float phi=0.0; phi <= M_PI; phi += angleDelta) {
t++; // total voxels
float x = xc+r*cos(theta)*sin(phi);
float y = yc+r*sin(theta)*sin(phi);
float z = zc+r*cos(phi);
// gradient color data
float gradient = (phi/M_PI);
unsigned char red = r1+((r2-r1)*gradient);
unsigned char green = g1+((g2-g1)*gradient);
unsigned char blue = b1+((b2-b1)*gradient);
unsigned char* voxelData = pointToVoxel(x,y,z,s,red,green,blue);
this->readCodeColorBufferToTree(voxelData);
delete voxelData;
}
}
}
}

View file

@ -36,8 +36,7 @@ public:
float * agentPosition,
float thisNodePosition[3],
unsigned char * octalCode = NULL);
void pruneTree(VoxelNode* pruneAt);
void loadVoxelsFile(const char* fileName, bool wantColorRandomizer);
void createSphere(float r,float xc, float yc, float zc, float s, bool solid);
};

View file

@ -47,6 +47,23 @@ const int MAX_VOXEL_TREE_DEPTH_LEVELS = 4;
AgentList agentList('V', VOXEL_LISTEN_PORT);
VoxelTree randomTree;
void addRandomSphere(VoxelTree * tree) {
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 = true;
printf("random sphere\n");
printf("radius=%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);
}
void randomlyFillVoxelTree(int levelsToGo, VoxelNode *currentRootNode) {
// randomly generate children for this node
// the first level of the tree (where levelsToGo = MAX_VOXEL_TREE_DEPTH_LEVELS) has all 8
@ -193,14 +210,29 @@ int main(int argc, const char * argv[])
agentList.startDomainServerCheckInThread();
srand((unsigned)time(0));
// create an octal code buffer and load it with 0 so that the recursive tree fill can give
// octal codes to the tree nodes that it is creating
randomlyFillVoxelTree(MAX_VOXEL_TREE_DEPTH_LEVELS, randomTree.rootNode);
// Check to see if the user passed in a command line option for loading a local
// Voxel File. If so, load it now.
bool wantColorRandomizer = !cmdOptionExists(argc, argv, "--NoColorRandomizer");
const char* voxelsFilename = getCmdOption(argc, argv, "-i");
if (voxelsFilename) {
randomTree.loadVoxelsFile(voxelsFilename,wantColorRandomizer);
}
if (!cmdOptionExists(argc, argv, "--NoRandomVoxelSheet")) {
// create an octal code buffer and load it with 0 so that the recursive tree fill can give
// octal codes to the tree nodes that it is creating
randomlyFillVoxelTree(MAX_VOXEL_TREE_DEPTH_LEVELS, randomTree.rootNode);
}
if (cmdOptionExists(argc, argv, "--AddRandomSpheres")) {
addRandomSphere(&randomTree);
}
pthread_t sendVoxelThread;
pthread_create(&sendVoxelThread, NULL, distributeVoxelsToListeners, NULL);
sockaddr agentPublicAddress;
char *packetData = new char[MAX_PACKET_SIZE];
@ -224,8 +256,6 @@ int main(int argc, const char * argv[])
pVoxelData+=voxelDataSize;
atByte+=voxelDataSize;
}
//printf("about to call pruneTree()\n");
//randomTree.pruneTree(randomTree.rootNode); // hack
}
if (packetData[0] == 'H') {
if (agentList.addOrUpdateAgent(&agentPublicAddress,