From bd45740dc6c761719d30e2e279ed92dbeb8db484 Mon Sep 17 00:00:00 2001 From: Philip Rosedale Date: Mon, 18 Feb 2013 08:59:44 -0800 Subject: [PATCH 1/4] Partial progress on new voxel model. --- interface/src/Cube.cpp | 80 ------------------------- interface/src/Head.cpp | 2 +- interface/src/SerialInterface.cpp | 3 +- interface/src/VoxelSystem.cpp | 68 +++++++++++++++++++++ interface/src/{Cube.h => VoxelSystem.h} | 25 ++++---- interface/src/main.cpp | 22 ++++--- 6 files changed, 97 insertions(+), 103 deletions(-) delete mode 100644 interface/src/Cube.cpp create mode 100644 interface/src/VoxelSystem.cpp rename interface/src/{Cube.h => VoxelSystem.h} (62%) diff --git a/interface/src/Cube.cpp b/interface/src/Cube.cpp deleted file mode 100644 index 5b093016e3..0000000000 --- a/interface/src/Cube.cpp +++ /dev/null @@ -1,80 +0,0 @@ -// -// Cube.cpp -// interface -// -// Created by Philip on 12/31/12. -// Copyright (c) 2012 High Fidelity, Inc. All rights reserved. -// - -#include "Cube.h" - -#define MAX_CUBES 250000 -#define SMALLEST_CUBE 0.2 - -float cubes_position[MAX_CUBES*3]; -float cubes_scale[MAX_CUBES]; -float cubes_color[MAX_CUBES*3]; -int cube_count = 0; - -void makeCubes2D(float location[3], float scale, int * index, - float * cubes_position, float * cubes_scale, float * cubes_color) { - int i; - float spot[3]; - float distance = powf(location[0]*location[0] + location[2]*location[2], 0.5); - - if (*index >= MAX_CUBES) return; - if ((scale <= SMALLEST_CUBE) || (scale/distance < 0.025) || ((scale < 0.1) && (randFloat()<0.01))) { - // Make a cube - for (i = 0; i < 3; i++) cubes_position[*index*3 + i] = location[i]+scale/2.0; - //glm::vec2 noisepoint(location[0], location[2]); - //float color = glm::noise(noisepoint); - float color = 0.3 + randFloat()*0.7; - cubes_scale[*index] = scale; - cubes_color[*index*3] = color; - cubes_color[*index*3 + 1] = color; - cubes_color[*index*3 + 2] = color; - *index += 1; - } else { - for (i = 0; i < 4; i++) { - spot[0] = location[0] + (i%2)*scale/2.0; - spot[2] = location[2] + ((i/2)%2)*scale/2.0; - spot[1] = sinf(location[0])*0.15 + cosf(location[2]/0.2)*0.10 + randFloat()*0.005; - makeCubes2D(spot, scale/2.0, index, cubes_position, cubes_scale, cubes_color); - } - } -} - -VoxelSystem::VoxelSystem(int num, - glm::vec3 box) { - - float location[] = {0,0,0}; - float scale = 10.0; - int j = 0; - int index = 0; - if (num > 0) - makeCubes2D(location, scale, &index, cubes_position, cubes_scale, cubes_color); - std::cout << "Run " << j << " Made " << index << " cubes\n"; - cube_count = index; - -} - -void VoxelSystem::render() { - int i = 0; - while (i < cube_count) { - glPushMatrix(); - glTranslatef(cubes_position[i*3], cubes_position[i*3+1], cubes_position[i*3+2]); - glColor3fv(&cubes_color[i*3]); - glutSolidCube(cubes_scale[i]); - glPopMatrix(); - i++; - } -} - -void VoxelSystem::simulate(float deltaTime) { - -} - - - - - diff --git a/interface/src/Head.cpp b/interface/src/Head.cpp index fdd3a7e2c9..64220626e6 100644 --- a/interface/src/Head.cpp +++ b/interface/src/Head.cpp @@ -216,7 +216,7 @@ void Head::render(int faceToFace, float * myLocation) //std::cout << distanceToCamera << "\n"; // Don't render a head if it is really close to your location, because that is your own head! - if ((distanceToCamera > 0.1) || faceToFace) { + if ((distanceToCamera > 1.0) || faceToFace) { glEnable(GL_DEPTH_TEST); glPushMatrix(); diff --git a/interface/src/SerialInterface.cpp b/interface/src/SerialInterface.cpp index c53d8dad55..d39ca74d7e 100644 --- a/interface/src/SerialInterface.cpp +++ b/interface/src/SerialInterface.cpp @@ -203,7 +203,7 @@ void SerialInterface::readData() { serial_buffer_pos = 0; } } - + /* if (initialSamples == totalSamples) { noReadCount++; std::cout << "#" << noReadCount << " blank read from serial.\n"; @@ -212,6 +212,7 @@ void SerialInterface::readData() { resetSerial(); } } + */ } void SerialInterface::resetSerial() { diff --git a/interface/src/VoxelSystem.cpp b/interface/src/VoxelSystem.cpp new file mode 100644 index 0000000000..fe328d89e7 --- /dev/null +++ b/interface/src/VoxelSystem.cpp @@ -0,0 +1,68 @@ +// +// Cube.cpp +// interface +// +// Created by Philip on 12/31/12. +// Copyright (c) 2012 High Fidelity, Inc. All rights reserved. +// + +#include "VoxelSystem.h" + +void VoxelSystem::init() { + root = new Voxel; +} + +// +// Recursively initialize the voxel tree +// +int VoxelSystem::initVoxels(Voxel * voxel, float scale) { + float childColor[3], averageColor[3]; + int averageCount = 0; + int newVoxels = 0; + if (voxel == NULL) voxel = root; + averageColor[0] = averageColor[1] = averageColor[2] = 0.0; + for (unsigned char i = 0; i < NUM_CHILDREN; i++) { + if ((scale > 0.01) && (randFloat() < 0.5)) { + voxel->children[i] = new Voxel; + newVoxels += initVoxels(voxel->children[i], scale/2.0); + for (int j = 0; j < 3; j++) averageColor[j] += childColor[j]; + averageCount++; + } + else { + voxel->children[i] = NULL; + } + } + if (averageCount == 0) { + // This is a leaf, so just pick a random color + voxel->color.x = voxel->color.y = voxel->color.z = randFloat(); + } else { + voxel->color.x = averageColor[0]/averageCount; + voxel->color.y = averageColor[1]/averageCount; + voxel->color.z = averageColor[2]/averageCount; + } + newVoxels++; + return newVoxels; +} + +void VoxelSystem::render(Voxel * voxel, float scale) { + if (voxel == NULL) voxel = root; + unsigned char i; + for (i = 0; i < NUM_CHILDREN; i++) { + if (voxel->children[i] != NULL) { + glTranslatef(scale/2.0*((i&4)>>2), scale/2.0*((i&2)>>1), scale/2.0*(i&1)); + render(voxel->children[i], scale/2.0); + glTranslatef(-scale/2.0*((i&4)>>2), -scale/2.0*((i&2)>>1), -scale/2.0*(i&1)); + } + } + glColor4f(voxel->color.x, voxel->color.y, voxel->color.z, 0.5); + glutSolidCube(scale); +} + +void VoxelSystem::simulate(float deltaTime) { + +} + + + + + diff --git a/interface/src/Cube.h b/interface/src/VoxelSystem.h similarity index 62% rename from interface/src/Cube.h rename to interface/src/VoxelSystem.h index 3b3c0481ce..41d9a350c4 100644 --- a/interface/src/Cube.h +++ b/interface/src/VoxelSystem.h @@ -15,19 +15,20 @@ #include "InterfaceConfig.h" #include -class VoxelSystem { -public: - VoxelSystem(int num, - glm::vec3 box); - void simulate(float deltaTime); - void render(); -private: - struct Voxel { - glm::vec3 color; - bool hasChildren; - Voxel * children; - } *voxels; +const int NUM_CHILDREN = 8; + +struct Voxel { + glm::vec3 color; + Voxel * children[NUM_CHILDREN]; }; +class VoxelSystem { +public: + void simulate(float deltaTime); + void render(Voxel * voxel, float scale); + void init(); + int initVoxels(Voxel * root, float scale); + Voxel * root; +}; #endif diff --git a/interface/src/main.cpp b/interface/src/main.cpp index 3ac243fca1..36345a2265 100644 --- a/interface/src/main.cpp +++ b/interface/src/main.cpp @@ -42,7 +42,7 @@ #include "Texture.h" #include "Cloud.h" #include "Agent.h" -#include "Cube.h" +#include "VoxelSystem.h" #include "Lattice.h" #include "Finger.h" #include "Oscilloscope.h" @@ -104,7 +104,7 @@ Cloud cloud(0, // Particles false // Wrap ); -VoxelSystem voxels(1000, box); +VoxelSystem voxels; Lattice lattice(160,100); Finger myFinger(WIDTH, HEIGHT); @@ -314,6 +314,10 @@ void initDisplay(void) void init(void) { + voxels.init(); + int voxelsMade = voxels.initVoxels(NULL, 1.0); + std::cout << voxelsMade << " voxels made. \n"; + myHead.setRenderYaw(start_yaw); head_mouse_x = WIDTH/2; @@ -401,7 +405,7 @@ void update_pos(float frametime) if (powf(measured_yaw_rate*measured_yaw_rate + measured_pitch_rate*measured_pitch_rate, 0.5) > MIN_MOUSE_RATE) { - head_mouse_x -= measured_yaw_rate*MOUSE_SENSITIVITY; + head_mouse_x += measured_yaw_rate*MOUSE_SENSITIVITY; head_mouse_y += measured_pitch_rate*MOUSE_SENSITIVITY*(float)HEIGHT/(float)WIDTH; } head_mouse_x = max(head_mouse_x, 0); @@ -424,18 +428,18 @@ void update_pos(float frametime) */ // Update render direction (pitch/yaw) based on measured gyro rates - const int MIN_YAW_RATE = 3000; - const float YAW_SENSITIVITY = 0.03; - const int MIN_PITCH_RATE = 3000; + const int MIN_YAW_RATE = 100; + const float YAW_SENSITIVITY = 0.08; + const int MIN_PITCH_RATE = 100; const float PITCH_SENSITIVITY = 0.04; if (fabs(measured_yaw_rate) > MIN_YAW_RATE) { if (measured_yaw_rate > 0) - render_yaw_rate -= (measured_yaw_rate - MIN_YAW_RATE) * YAW_SENSITIVITY * frametime; + render_yaw_rate += (measured_yaw_rate - MIN_YAW_RATE) * YAW_SENSITIVITY * frametime; else - render_yaw_rate -= (measured_yaw_rate + MIN_YAW_RATE) * YAW_SENSITIVITY * frametime; + render_yaw_rate += (measured_yaw_rate + MIN_YAW_RATE) * YAW_SENSITIVITY * frametime; } if (fabs(measured_pitch_rate) > MIN_PITCH_RATE) { @@ -561,7 +565,7 @@ void display(void) if (!display_head) cloud.render(); // Draw voxels - voxels.render(); + //voxels.render(NULL, 10.0); // Draw field vectors if (display_field) field.render(); From 15fd9638d6ab87be404b6b363a0f11bdcfb13ca8 Mon Sep 17 00:00:00 2001 From: Philip Rosedale Date: Wed, 20 Feb 2013 21:38:42 -0800 Subject: [PATCH 2/4] remove deadhead (of self) at origin. First commit of voxels with LOD, recursive test pattern. --- interface/src/Agent.cpp | 7 ++- interface/src/VoxelSystem.cpp | 104 ++++++++++++++++++++++++---------- interface/src/VoxelSystem.h | 8 ++- interface/src/main.cpp | 28 +++++++-- 4 files changed, 108 insertions(+), 39 deletions(-) diff --git a/interface/src/Agent.cpp b/interface/src/Agent.cpp index c062f8d9d4..a200493e34 100644 --- a/interface/src/Agent.cpp +++ b/interface/src/Agent.cpp @@ -79,8 +79,11 @@ void render_agents(int renderSelf, float * myLocation) { glm::vec3 pos = agents[i].head.getPos(); glPushMatrix(); if (!agents[i].isSelf || renderSelf) { - glTranslatef(-pos.x, -pos.y, -pos.z); - agents[i].head.render(0, myLocation); + if (!((pos.x == 0.0) && (pos.y == 0.0) && (pos.z == 0.0))) { + // ZERO ZERO ZERO means we are not getting data for this head, so don't render it + glTranslatef(-pos.x, -pos.y, -pos.z); + agents[i].head.render(0, myLocation); + } } glPopMatrix(); } diff --git a/interface/src/VoxelSystem.cpp b/interface/src/VoxelSystem.cpp index fe328d89e7..f0920cd04c 100644 --- a/interface/src/VoxelSystem.cpp +++ b/interface/src/VoxelSystem.cpp @@ -15,47 +15,91 @@ void VoxelSystem::init() { // // Recursively initialize the voxel tree // -int VoxelSystem::initVoxels(Voxel * voxel, float scale) { - float childColor[3], averageColor[3]; - int averageCount = 0; +int VoxelSystem::initVoxels(Voxel * voxel, float scale, glm::vec3 * position) { + glm::vec3 averageColor(0,0,0); + int childrenCreated = 0; int newVoxels = 0; if (voxel == NULL) voxel = root; averageColor[0] = averageColor[1] = averageColor[2] = 0.0; - for (unsigned char i = 0; i < NUM_CHILDREN; i++) { - if ((scale > 0.01) && (randFloat() < 0.5)) { - voxel->children[i] = new Voxel; - newVoxels += initVoxels(voxel->children[i], scale/2.0); - for (int j = 0; j < 3; j++) averageColor[j] += childColor[j]; - averageCount++; - } - else { - voxel->children[i] = NULL; - } - } - if (averageCount == 0) { - // This is a leaf, so just pick a random color - voxel->color.x = voxel->color.y = voxel->color.z = randFloat(); + // + // First, decide whether I should be a leaf node and set/return if so + // + if ((randFloat() < 0.1) && (scale < 1.0)) + { + voxel->color.x = voxel->color.y = voxel->color.z = 0.5 + randFloat()*0.5; + for (unsigned char i = 0; i < NUM_CHILDREN; i++) voxel->children[i] = NULL; + return 0; } else { - voxel->color.x = averageColor[0]/averageCount; - voxel->color.y = averageColor[1]/averageCount; - voxel->color.z = averageColor[2]/averageCount; + // Decide whether to make kids, recurse into them + for (unsigned char i = 0; i < NUM_CHILDREN; i++) { + if ((scale > 0.01) && (randFloat() > 0.6)) + { + // Make a new child + voxel->children[i] = new Voxel; + newVoxels++; + childrenCreated++; + glm::vec3 shift(scale/4.0*((i&4)>>2), scale/4.0*((i&2)>>1), scale/4.0*(i&1)); + *position += shift; + newVoxels += initVoxels(voxel->children[i], scale/2.0, position); + *position -= shift; + averageColor += voxel->children[i]->color; + } else { + // No child made: Set pointer to null, nothing to see here. + voxel->children[i] = NULL; + } + } + if (childrenCreated > 0) { + // If there were children created, set this voxels color to the average of it's children + averageColor *= 1.0/childrenCreated; + voxel->color = averageColor; + return newVoxels; + } else { + // Tested and didn't make any children, so i've still got to be a leaf + voxel->color.x = voxel->color.y = voxel->color.z = 0.5 + randFloat()*0.5; + for (unsigned char i = 0; i < NUM_CHILDREN; i++) voxel->children[i] = NULL; + return 0; + + } } - newVoxels++; - return newVoxels; } -void VoxelSystem::render(Voxel * voxel, float scale) { - if (voxel == NULL) voxel = root; +const float RENDER_DISCARD = 0.01; + +// +// Returns the total number of voxels actually rendered +// +int VoxelSystem::render(Voxel * voxel, float scale, glm::vec3 * distance) { + // If null passed in, start at root + if (voxel == NULL) voxel = root; unsigned char i; + bool renderedChildren = false; + int vRendered = 0; + // Recursively render children for (i = 0; i < NUM_CHILDREN; i++) { - if (voxel->children[i] != NULL) { - glTranslatef(scale/2.0*((i&4)>>2), scale/2.0*((i&2)>>1), scale/2.0*(i&1)); - render(voxel->children[i], scale/2.0); - glTranslatef(-scale/2.0*((i&4)>>2), -scale/2.0*((i&2)>>1), -scale/2.0*(i&1)); + glm::vec3 shift(scale/2.0*((i&4)>>2)-scale/4.0, + scale/2.0*((i&2)>>1)-scale/4.0, + scale/2.0*(i&1)-scale/4.0); + if ((voxel->children[i] != NULL) && (scale / glm::length(*distance) > RENDER_DISCARD)) { + glTranslatef(shift.x, shift.y, shift.z); + //std::cout << "x,y,z: " << shift.x << "," << shift.y << "," << shift.z << "\n"; + *distance += shift; + vRendered += render(voxel->children[i], scale/2.0, distance); + *distance -= shift; + glTranslatef(-shift.x, -shift.y, -shift.z); + renderedChildren = true; } } - glColor4f(voxel->color.x, voxel->color.y, voxel->color.z, 0.5); - glutSolidCube(scale); + // Render this voxel if the children were not rendered + if (!renderedChildren) + { + //glColor4f(1,1,1,1); + glColor4f(voxel->color.x, voxel->color.y, voxel->color.z, 1.0); + //float bright = 1.0 - glm::length(*distance)/20.0; + //glColor3f(bright,bright,bright); + glutSolidCube(scale); + vRendered++; + } + return vRendered; } void VoxelSystem::simulate(float deltaTime) { diff --git a/interface/src/VoxelSystem.h b/interface/src/VoxelSystem.h index 41d9a350c4..8dc3e97c8c 100644 --- a/interface/src/VoxelSystem.h +++ b/interface/src/VoxelSystem.h @@ -25,10 +25,14 @@ struct Voxel { class VoxelSystem { public: void simulate(float deltaTime); - void render(Voxel * voxel, float scale); + int render(Voxel * voxel, float scale, glm::vec3 * distance); void init(); - int initVoxels(Voxel * root, float scale); + int initVoxels(Voxel * root, float scale, glm::vec3 * position); + void setVoxelsRendered(int v) {voxelsRendered = v;}; + int getVoxelsRendered() {return voxelsRendered;}; Voxel * root; +private: + int voxelsRendered; }; #endif diff --git a/interface/src/main.cpp b/interface/src/main.cpp index 8754e4d6e5..be027f6c93 100644 --- a/interface/src/main.cpp +++ b/interface/src/main.cpp @@ -228,7 +228,7 @@ void Timer(int extra) // char output[100]; sprintf(output, "%c %f,%f,%f,%s %hd", 'I', location[0], location[1], location[2], localAddressBuffer, AGENT_UDP_PORT); - std::cout << "sending " << output << " to domain server\n"; + //std::cout << "sending " << output << " to domain server\n"; int packet_size = strlen(output); agentSocket.send(DOMAIN_IP, DOMAINSERVER_PORT, output, packet_size); @@ -280,11 +280,17 @@ void display_stats(void) } drawtext(10,50,0.10, 0, 1.0, 0, (char *)pingTimes.str().c_str()); + std::stringstream voxelStats; + voxelStats << "Voxels Rendered: " << voxels.getVoxelsRendered(); + drawtext(10,70,0.10, 0, 1.0, 0, (char *)voxelStats.str().c_str()); + + /* std::stringstream angles; angles << "render_yaw: " << myHead.getRenderYaw() << ", Yaw: " << myHead.getYaw(); drawtext(10,50,0.10, 0, 1.0, 0, (char *)angles.str().c_str()); - + */ + /* char adc[200]; sprintf(adc, "location = %3.1f,%3.1f,%3.1f, angle_to(origin) = %3.1f, head yaw = %3.1f, render_yaw = %3.1f", @@ -315,7 +321,8 @@ void initDisplay(void) void init(void) { voxels.init(); - int voxelsMade = voxels.initVoxels(NULL, 1.0); + glm::vec3 position(0,0,0); + int voxelsMade = voxels.initVoxels(NULL, 10.0, &position); std::cout << voxelsMade << " voxels made. \n"; myHead.setRenderYaw(start_yaw); @@ -559,13 +566,24 @@ void display(void) glRotatef(myHead.getRenderYaw(), 0, 1, 0); glTranslatef(location[0], location[1], location[2]); + glColor3f(1,0,0); + glutSolidSphere(0.25, 15, 15); + // Draw cloud of dots glDisable( GL_POINT_SPRITE_ARB ); glDisable( GL_TEXTURE_2D ); if (!display_head) cloud.render(); // Draw voxels - //voxels.render(NULL, 10.0); + glPushMatrix(); + glTranslatef(WORLD_SIZE/2.0, WORLD_SIZE/2.0, WORLD_SIZE/2.0); + glm::vec3 distance(5.0 + location[0], 5.0 + location[1], 5.0 + location[2]); + //std::cout << "length: " << glm::length(distance) << "\n"; + int voxelsRendered = voxels.render(NULL, 10.0, &distance); + voxels.setVoxelsRendered(voxelsRendered); + //glColor4f(0,0,1,0.5); + //glutSolidCube(10.0); + glPopMatrix(); // Draw field vectors if (display_field) field.render(); @@ -573,7 +591,7 @@ void display(void) // Render heads of other agents render_agents(sendToSelf, &location[0]); - if (display_hand) myHand.render(); + if (display_hand) myHand.render(); if (!display_head) balls.render(); From 5f60bf63765a2211f4f73d2c0f19e8b3e14b0dec Mon Sep 17 00:00:00 2001 From: Philip Rosedale Date: Wed, 20 Feb 2013 21:42:10 -0800 Subject: [PATCH 3/4] recursive position vector is same as rendering. --- interface/src/VoxelSystem.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/interface/src/VoxelSystem.cpp b/interface/src/VoxelSystem.cpp index f0920cd04c..79c77ff388 100644 --- a/interface/src/VoxelSystem.cpp +++ b/interface/src/VoxelSystem.cpp @@ -38,7 +38,9 @@ int VoxelSystem::initVoxels(Voxel * voxel, float scale, glm::vec3 * position) { voxel->children[i] = new Voxel; newVoxels++; childrenCreated++; - glm::vec3 shift(scale/4.0*((i&4)>>2), scale/4.0*((i&2)>>1), scale/4.0*(i&1)); + glm::vec3 shift(scale/2.0*((i&4)>>2)-scale/4.0, + scale/2.0*((i&2)>>1)-scale/4.0, + scale/2.0*(i&1)-scale/4.0); *position += shift; newVoxels += initVoxels(voxel->children[i], scale/2.0, position); *position -= shift; From 67115ccad44e872c82014f1ab629fc675af01dae Mon Sep 17 00:00:00 2001 From: Philip Rosedale Date: Thu, 21 Feb 2013 11:25:52 -0800 Subject: [PATCH 4/4] First commit of 'Death Star' voxel planet --- interface/src/VoxelSystem.cpp | 50 ++++++++++++++++++++++------------- 1 file changed, 32 insertions(+), 18 deletions(-) diff --git a/interface/src/VoxelSystem.cpp b/interface/src/VoxelSystem.cpp index 79c77ff388..d654f71a5e 100644 --- a/interface/src/VoxelSystem.cpp +++ b/interface/src/VoxelSystem.cpp @@ -8,6 +8,12 @@ #include "VoxelSystem.h" + +bool onSphereShell(float radius, float scale, glm::vec3 * position) { + float vRadius = glm::length(*position); + return ((vRadius + scale/2.0 > radius) && (vRadius - scale/2.0 < radius)); +} + void VoxelSystem::init() { root = new Voxel; } @@ -21,42 +27,48 @@ int VoxelSystem::initVoxels(Voxel * voxel, float scale, glm::vec3 * position) { int newVoxels = 0; if (voxel == NULL) voxel = root; averageColor[0] = averageColor[1] = averageColor[2] = 0.0; + + const float RADIUS = 3.9; + // - // First, decide whether I should be a leaf node and set/return if so + // First, randomly decide whether to stop here without recursing for children // - if ((randFloat() < 0.1) && (scale < 1.0)) + if (onSphereShell(RADIUS, scale, position) && (scale < 0.25) && (randFloat() < 0.01)) { - voxel->color.x = voxel->color.y = voxel->color.z = 0.5 + randFloat()*0.5; + voxel->color.x = 0.1; + voxel->color.y = 0.5 + randFloat()*0.5; + voxel->color.z = 0.1; for (unsigned char i = 0; i < NUM_CHILDREN; i++) voxel->children[i] = NULL; return 0; } else { // Decide whether to make kids, recurse into them for (unsigned char i = 0; i < NUM_CHILDREN; i++) { - if ((scale > 0.01) && (randFloat() > 0.6)) - { - // Make a new child - voxel->children[i] = new Voxel; - newVoxels++; - childrenCreated++; + if (scale > 0.01) { glm::vec3 shift(scale/2.0*((i&4)>>2)-scale/4.0, scale/2.0*((i&2)>>1)-scale/4.0, scale/2.0*(i&1)-scale/4.0); *position += shift; - newVoxels += initVoxels(voxel->children[i], scale/2.0, position); + // Test to see whether the child is also on edge of sphere + if (onSphereShell(RADIUS, scale/2.0, position)) { + voxel->children[i] = new Voxel; + newVoxels++; + childrenCreated++; + newVoxels += initVoxels(voxel->children[i], scale/2.0, position); + averageColor += voxel->children[i]->color; + } else voxel->children[i] = NULL; *position -= shift; - averageColor += voxel->children[i]->color; } else { // No child made: Set pointer to null, nothing to see here. voxel->children[i] = NULL; } } if (childrenCreated > 0) { - // If there were children created, set this voxels color to the average of it's children + // If there were children created, the color of this voxel node is average of children averageColor *= 1.0/childrenCreated; voxel->color = averageColor; return newVoxels; } else { - // Tested and didn't make any children, so i've still got to be a leaf + // Tested and didn't make any children, so choose my color as a leaf, return voxel->color.x = voxel->color.y = voxel->color.z = 0.5 + randFloat()*0.5; for (unsigned char i = 0; i < NUM_CHILDREN; i++) voxel->children[i] = NULL; return 0; @@ -65,7 +77,12 @@ int VoxelSystem::initVoxels(Voxel * voxel, float scale, glm::vec3 * position) { } } -const float RENDER_DISCARD = 0.01; +// +// The Render Discard is the ratio of the size of the voxel to the distance from the camera +// at which the voxel will no longer be shown. Smaller = show more detail. +// + +const float RENDER_DISCARD = 0.04; //0.01; // // Returns the total number of voxels actually rendered @@ -83,7 +100,6 @@ int VoxelSystem::render(Voxel * voxel, float scale, glm::vec3 * distance) { scale/2.0*(i&1)-scale/4.0); if ((voxel->children[i] != NULL) && (scale / glm::length(*distance) > RENDER_DISCARD)) { glTranslatef(shift.x, shift.y, shift.z); - //std::cout << "x,y,z: " << shift.x << "," << shift.y << "," << shift.z << "\n"; *distance += shift; vRendered += render(voxel->children[i], scale/2.0, distance); *distance -= shift; @@ -94,10 +110,8 @@ int VoxelSystem::render(Voxel * voxel, float scale, glm::vec3 * distance) { // Render this voxel if the children were not rendered if (!renderedChildren) { - //glColor4f(1,1,1,1); + // This is the place where we need to copy this data to a VBO to make this FAST glColor4f(voxel->color.x, voxel->color.y, voxel->color.z, 1.0); - //float bright = 1.0 - glm::length(*distance)/20.0; - //glColor3f(bright,bright,bright); glutSolidCube(scale); vRendered++; }