History

Merge remote-tracking branch 'origin/master'

Philip Rosedale committed 13 years ago

Commit 5c1bd682 parents f014fcd a161ea817 files · +407 −208Browse files

Showing the changes to interface/src/VoxelSystem.cpp (1 of 17 files). Show all

Unified · Split

interface/src/VoxelSystem.cpp+87−172
@@ -7,24 +7,25 @@ · 6 unmodified lines
7//7//
8 8
9#include "VoxelSystem.h"9#include "VoxelSystem.h"
10#include <AgentList.h>
10 11
11const float MAX_Y_AXIS = 2.0;12const int MAX_VOXELS_PER_SYSTEM = 500000;
12const float MAX_X_AXIS = 20.0;
13const float MAX_Z_AXIS = 20.0;
14 13
15const int VERTICES_PER_VOXEL = 8;14const int VERTICES_PER_VOXEL = 8;
16const int VERTEX_POINTS_PER_VOXEL = 3 * VERTICES_PER_VOXEL;15const int VERTEX_POINTS_PER_VOXEL = 3 * VERTICES_PER_VOXEL;
17const int COLOR_VALUES_PER_VOXEL = 3 * VERTICES_PER_VOXEL;16const int COLOR_VALUES_PER_VOXEL = 3 * VERTICES_PER_VOXEL;
18const int INDICES_PER_VOXEL = 3 * 12;17const int INDICES_PER_VOXEL = 3 * 12;
19 18
20GLfloat identityVertices[] = { -1, -1, 1,19const float CUBE_WIDTH = 0.025f;
21 1, -1, 1,20
22 1, -1, -1,21float identityVertices[] = { -1, -1, 1,
23 -1, -1, -1,22 1, -1, 1,
24 1, 1, 1,23 1, -1, -1,
25 -1, 1, 1,24 -1, -1, -1,
26 -1, 1, -1,25 1, 1, 1,
27 1, 1, -1 };26 -1, 1, 1,
27 -1, 1, -1,
28 1, 1, -1 };
28 29
29GLubyte identityIndices[] = { 0,1,2, 0,2,3,30GLubyte identityIndices[] = { 0,1,2, 0,2,3,
30 0,4,1, 0,4,5,31 0,4,1, 0,4,5,
@@ -33,73 +34,71 @@ GLubyte identityIndices[] = { 0,1,2, 0,2,3, · 2 unmodified lines
33 2,3,6, 2,6,7,34 2,3,6, 2,6,7,
34 4,5,6, 4,6,7 };35 4,5,6, 4,6,7 };
35 36
36 37VoxelSystem::VoxelSystem() {
37bool onSphereShell(float radius, float scale, glm::vec3 * position) {38 voxelsRendered = 0;
38 float vRadius = glm::length(*position);
39 return ((vRadius + scale/2.0 > radius) && (vRadius - scale/2.0 < radius));
40}39}
41 40
42void VoxelSystem::init() {41VoxelSystem::~VoxelSystem() {
43 root = new Voxel;42 delete[] verticesArray;
43 delete[] colorsArray;
44}44}
45 45
46float randomFloat(float maximumValue) {46void VoxelSystem::parseData(void *data, int size) {
47 return ((float) rand() / ((float) RAND_MAX / maximumValue));47 // ignore the first char, it's a V to tell us that this is voxel data
48}48 char *voxelDataPtr = (char *) data + 1;
49 49
50void VoxelSystem::init(int numberOfRandomVoxels) {50 float *position = new float[3];
51 // create the arrays needed to pass to glDrawElements later51 char *color = new char[3];
52 // position / color are random for now52
53 53 // get pointers to position of last append of data
54 voxelsRendered = numberOfRandomVoxels;54 GLfloat *parseVerticesPtr = lastAddPointer;
55 55 GLubyte *parseColorsPtr = colorsArray + (lastAddPointer - verticesArray);
56 // there are 3 points for each vertices, 24 vertices in each cube
57 GLfloat *verticesArray = new GLfloat[VERTEX_POINTS_PER_VOXEL * numberOfRandomVoxels];
58
59 // we need a color for each vertex in each voxel
60 GLfloat *colorsArray = new GLfloat[COLOR_VALUES_PER_VOXEL * numberOfRandomVoxels];
61
62 // there are 12 triangles in each cube, with three indices for each triangle
63 GLuint *indicesArray = new GLuint[INDICES_PER_VOXEL * numberOfRandomVoxels];
64 56
65 // new seed based on time now so voxels are different each time57 int voxelsInData = 0;
66 srand((unsigned)time(0));
67 58
68 for (int n = 0; n < numberOfRandomVoxels; n++) { 59 // pull voxels out of the received data and put them into our internal memory structure
69 // pick a random point for the center of the cube60 while ((voxelDataPtr - (char *) data) < size) {
70 const float DEATH_STAR_RADIUS = 4.0;61
71 const float MAX_CUBE = 0.05;62 memcpy(position, voxelDataPtr, 3 * sizeof(float));
72 float azimuth = randFloat()*2*PI;63 voxelDataPtr += 3 * sizeof(float);
73 float altitude = randFloat()*PI - PI/2;64 memcpy(color, voxelDataPtr, 3);
74 float radius = DEATH_STAR_RADIUS;65 voxelDataPtr += 3;
75 float thisScale = MAX_CUBE*1/(float)(rand()%8 + 1);
76 float radius_twiddle = (DEATH_STAR_RADIUS/100)*powf(2, (float)(rand()%8));
77 radius += radius_twiddle + (randFloat()*DEATH_STAR_RADIUS/12 - DEATH_STAR_RADIUS/24);
78 glm::vec3 position = glm::vec3(
79 radius * cosf(azimuth) * cosf(altitude),
80 radius * sinf(azimuth) * cosf(altitude),
81 radius * sinf(altitude)
82 );
83 66
84 // fill the vertices array, and scale the voxels
85 GLfloat *currentVerticesPos = verticesArray + (n * VERTEX_POINTS_PER_VOXEL);
86 for (int v = 0; v < VERTEX_POINTS_PER_VOXEL; v++) {67 for (int v = 0; v < VERTEX_POINTS_PER_VOXEL; v++) {
87 currentVerticesPos[v] = position[v % 3] + (identityVertices[v] * thisScale);68 parseVerticesPtr[v] = position[v % 3] + (identityVertices[v] * CUBE_WIDTH);
88 }69 }
89 70
90 // fill the colors array71 parseVerticesPtr += VERTEX_POINTS_PER_VOXEL;
91 const float MIN_BRIGHTNESS = 0.25;
92 GLfloat *currentColorPos = colorsArray + (n * COLOR_VALUES_PER_VOXEL);
93 float voxelR = MIN_BRIGHTNESS + randomFloat(1)*(1.0 - MIN_BRIGHTNESS);
94 float voxelG = voxelR;
95 float voxelB = voxelR;
96 72
97 for (int c = 0; c < VERTICES_PER_VOXEL; c++) {73 for (int c = 0; c < COLOR_VALUES_PER_VOXEL; c++) {
98 currentColorPos[0 + (c * 3)] = voxelR;74 parseColorsPtr[c] = color[c % 3];
99 currentColorPos[1 + (c * 3)] = voxelG;
100 currentColorPos[2 + (c * 3)] = voxelB;
101 }75 }
76
77 parseColorsPtr += COLOR_VALUES_PER_VOXEL;
78
79 voxelsInData++;
80 }
81
82 // increase the lastAddPointer to the new spot, increase the number of rendered voxels
83 lastAddPointer = parseVerticesPtr;
84 voxelsRendered += voxelsInData;
85}
86
87VoxelSystem* VoxelSystem::clone() const {
88 // this still needs to be implemented, will need to be used if VoxelSystem is attached to agent
89 return NULL;
90}
102 91
92void VoxelSystem::init() {
93 // prep the data structures for incoming voxel data
94 lastDrawPointer = lastAddPointer = verticesArray = new GLfloat[VERTEX_POINTS_PER_VOXEL * MAX_VOXELS_PER_SYSTEM];
95 colorsArray = new GLubyte[COLOR_VALUES_PER_VOXEL * MAX_VOXELS_PER_SYSTEM];
96
97 GLuint *indicesArray = new GLuint[INDICES_PER_VOXEL * MAX_VOXELS_PER_SYSTEM];
98
99 // populate the indicesArray
100 // this will not change given new voxels, so we can set it all up now
101 for (int n = 0; n < MAX_VOXELS_PER_SYSTEM; n++) {
103 // fill the indices array102 // fill the indices array
104 int voxelIndexOffset = n * INDICES_PER_VOXEL;103 int voxelIndexOffset = n * INDICES_PER_VOXEL;
105 GLuint *currentIndicesPos = indicesArray + voxelIndexOffset;104 GLuint *currentIndicesPos = indicesArray + voxelIndexOffset;
@@ -114,135 +113,51 @@ void VoxelSystem::init(int numberOfRandomVoxels) { · 8 unmodified lines
114 // VBO for the verticesArray113 // VBO for the verticesArray
115 glGenBuffers(1, &vboVerticesID);114 glGenBuffers(1, &vboVerticesID);
116 glBindBuffer(GL_ARRAY_BUFFER, vboVerticesID);115 glBindBuffer(GL_ARRAY_BUFFER, vboVerticesID);
117 glBufferData(GL_ARRAY_BUFFER, VERTEX_POINTS_PER_VOXEL * sizeof(GLfloat) * numberOfRandomVoxels, verticesArray, GL_STATIC_DRAW);116 glBufferData(GL_ARRAY_BUFFER, VERTEX_POINTS_PER_VOXEL * sizeof(GLfloat) * MAX_VOXELS_PER_SYSTEM, NULL, GL_DYNAMIC_DRAW);
118 117
119 // VBO for colorsArray118 // VBO for colorsArray
120 glGenBuffers(1, &vboColorsID);119 glGenBuffers(1, &vboColorsID);
121 glBindBuffer(GL_ARRAY_BUFFER, vboColorsID);120 glBindBuffer(GL_ARRAY_BUFFER, vboColorsID);
122 glBufferData(GL_ARRAY_BUFFER, COLOR_VALUES_PER_VOXEL * sizeof(GLfloat) * numberOfRandomVoxels, colorsArray, GL_STATIC_DRAW);121 glBufferData(GL_ARRAY_BUFFER, COLOR_VALUES_PER_VOXEL * sizeof(GLubyte) * MAX_VOXELS_PER_SYSTEM, NULL, GL_DYNAMIC_DRAW);
123 122
124 // VBO for the indicesArray123 // VBO for the indicesArray
125 glGenBuffers(1, &vboIndicesID);124 glGenBuffers(1, &vboIndicesID);
126 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vboIndicesID);125 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vboIndicesID);
127 glBufferData(GL_ELEMENT_ARRAY_BUFFER, numberOfRandomVoxels * INDICES_PER_VOXEL * sizeof(GLuint), indicesArray, GL_STATIC_DRAW);126 glBufferData(GL_ELEMENT_ARRAY_BUFFER, INDICES_PER_VOXEL * sizeof(GLuint) * MAX_VOXELS_PER_SYSTEM, indicesArray, GL_STATIC_DRAW);
128 127
129 // delete the verticesArray, indicesArray128 // delete the indices array that is no longer needed
130 delete[] verticesArray;
131 delete[] indicesArray;129 delete[] indicesArray;
132 delete[] colorsArray;
133}130}
134 131
135//132void VoxelSystem::render() {
136// Recursively initialize the voxel tree133 // check if there are new voxels to draw
137//134 int vertexValuesToDraw = lastAddPointer - lastDrawPointer;
138int VoxelSystem::initVoxels(Voxel * voxel, float scale, glm::vec3 * position) {
139 glm::vec3 averageColor(0,0,0);
140 int childrenCreated = 0;
141 int newVoxels = 0;
142 if (voxel == NULL) voxel = root;
143 averageColor[0] = averageColor[1] = averageColor[2] = 0.0;
144
145 const float RADIUS = 3.9;
146 135
147 //136 if (vertexValuesToDraw > 0) {
148 // First, randomly decide whether to stop here without recursing for children 137 // calculate the offset into each VBO, in vertex point values
149 //138 int vertexBufferOffset = lastDrawPointer - verticesArray;
150 if (onSphereShell(RADIUS, scale, position) && (scale < 0.25) && (randFloat() < 0.01))139
151 {140 // bind the vertices VBO, copy in new data
152 voxel->color.x = 0.1;141 glBindBuffer(GL_ARRAY_BUFFER, vboVerticesID);
153 voxel->color.y = 0.5 + randFloat()*0.5;142 glBufferSubData(GL_ARRAY_BUFFER, vertexBufferOffset * sizeof(float), vertexValuesToDraw * sizeof(float), lastDrawPointer);
154 voxel->color.z = 0.1;143
155 for (unsigned char i = 0; i < NUM_CHILDREN; i++) voxel->children[i] = NULL;144 // bind the colors VBO, copy in new data
156 return 0;145 glBindBuffer(GL_ARRAY_BUFFER, vboColorsID);
157 } else {146 glBufferSubData(GL_ARRAY_BUFFER, vertexBufferOffset * sizeof(GLubyte), vertexValuesToDraw * sizeof(GLubyte), (colorsArray + (lastDrawPointer - verticesArray)));
158 // Decide whether to make kids, recurse into them 147
159 for (unsigned char i = 0; i < NUM_CHILDREN; i++) {148 // increment the lastDrawPointer to the lastAddPointer value used for this draw
160 if (scale > 0.01) {149 lastDrawPointer += vertexValuesToDraw;
161 glm::vec3 shift(scale/2.0*((i&4)>>2)-scale/4.0,
162 scale/2.0*((i&2)>>1)-scale/4.0,
163 scale/2.0*(i&1)-scale/4.0);
164 *position += shift;
165 // Test to see whether the child is also on edge of sphere
166 if (onSphereShell(RADIUS, scale/2.0, position)) {
167 voxel->children[i] = new Voxel;
168 newVoxels++;
169 childrenCreated++;
170 newVoxels += initVoxels(voxel->children[i], scale/2.0, position);
171 averageColor += voxel->children[i]->color;
172 } else voxel->children[i] = NULL;
173 *position -= shift;
174 } else {
175 // No child made: Set pointer to null, nothing to see here.
176 voxel->children[i] = NULL;
177 }
178 }
179 if (childrenCreated > 0) {
180 // If there were children created, the color of this voxel node is average of children
181 averageColor *= 1.0/childrenCreated;
182 voxel->color = averageColor;
183 return newVoxels;
184 } else {
185 // Tested and didn't make any children, so choose my color as a leaf, return
186 voxel->color.x = voxel->color.y = voxel->color.z = 0.5 + randFloat()*0.5;
187 for (unsigned char i = 0; i < NUM_CHILDREN; i++) voxel->children[i] = NULL;
188 return 0;
189
190 }
191 }
192}
193
194//
195// The Render Discard is the ratio of the size of the voxel to the distance from the camera
196// at which the voxel will no longer be shown. Smaller = show more detail.
197//
198
199const float RENDER_DISCARD = 0.04; //0.01;
200
201//
202// Returns the total number of voxels actually rendered
203//
204int VoxelSystem::render(Voxel * voxel, float scale, glm::vec3 * distance) {
205 // If null passed in, start at root
206 if (voxel == NULL) voxel = root;
207 unsigned char i;
208 bool renderedChildren = false;
209 int vRendered = 0;
210 // Recursively render children
211 for (i = 0; i < NUM_CHILDREN; i++) {
212 glm::vec3 shift(scale/2.0*((i&4)>>2)-scale/4.0,
213 scale/2.0*((i&2)>>1)-scale/4.0,
214 scale/2.0*(i&1)-scale/4.0);
215 if ((voxel->children[i] != NULL) && (scale / glm::length(*distance) > RENDER_DISCARD)) {
216 glTranslatef(shift.x, shift.y, shift.z);
217 *distance += shift;
218 vRendered += render(voxel->children[i], scale/2.0, distance);
219 *distance -= shift;
220 glTranslatef(-shift.x, -shift.y, -shift.z);
221 renderedChildren = true;
222 }
223 }
224 // Render this voxel if the children were not rendered
225 if (!renderedChildren)
226 {
227 // This is the place where we need to copy this data to a VBO to make this FAST
228 glColor4f(voxel->color.x, voxel->color.y, voxel->color.z, 1.0);
229 glutSolidCube(scale);
230 vRendered++;
231 }150 }
232 return vRendered;
233}
234 151
235void VoxelSystem::render() {152 // tell OpenGL where to find vertex and color information
236 glEnableClientState(GL_VERTEX_ARRAY);153 glEnableClientState(GL_VERTEX_ARRAY);
237 glEnableClientState(GL_COLOR_ARRAY);154 glEnableClientState(GL_COLOR_ARRAY);
238 155
239 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vboIndicesID);
240
241 glBindBuffer(GL_ARRAY_BUFFER, vboVerticesID);156 glBindBuffer(GL_ARRAY_BUFFER, vboVerticesID);
242 glVertexPointer(3, GL_FLOAT, 0, 0);157 glVertexPointer(3, GL_FLOAT, 0, 0);
243 158
244 glBindBuffer(GL_ARRAY_BUFFER, vboColorsID);159 glBindBuffer(GL_ARRAY_BUFFER, vboColorsID);
245 glColorPointer(3, GL_FLOAT, 0, 0);160 glColorPointer(3, GL_UNSIGNED_BYTE, 0, 0);
246 161
247 glNormal3f(0, 1, 0);162 glNormal3f(0, 1, 0);
248 163