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
77 //
88
99 #include "VoxelSystem.h"
10+#include <AgentList.h>
1011
11−const float MAX_Y_AXIS = 2.0;
12−const float MAX_X_AXIS = 20.0;
13−const float MAX_Z_AXIS = 20.0;
12+const int MAX_VOXELS_PER_SYSTEM = 500000;
1413
1514 const int VERTICES_PER_VOXEL = 8;
1615 const int VERTEX_POINTS_PER_VOXEL = 3 * VERTICES_PER_VOXEL;
1716 const int COLOR_VALUES_PER_VOXEL = 3 * VERTICES_PER_VOXEL;
1817 const int INDICES_PER_VOXEL = 3 * 12;
1918
20−GLfloat identityVertices[] = { -1, -1, 1,
21− 1, -1, 1,
22− 1, -1, -1,
23− -1, -1, -1,
24− 1, 1, 1,
25− -1, 1, 1,
26− -1, 1, -1,
27− 1, 1, -1 };
19+const float CUBE_WIDTH = 0.025f;
20+
21+float identityVertices[] = { -1, -1, 1,
22+ 1, -1, 1,
23+ 1, -1, -1,
24+ -1, -1, -1,
25+ 1, 1, 1,
26+ -1, 1, 1,
27+ -1, 1, -1,
28+ 1, 1, -1 };
2829
2930 GLubyte identityIndices[] = { 0,1,2, 0,2,3,
3031 0,4,1, 0,4,5,
@@ -33,73 +34,71 @@ GLubyte identityIndices[] = { 0,1,2, 0,2,3, · 2 unmodified lines
3334 2,3,6, 2,6,7,
3435 4,5,6, 4,6,7 };
3536
36−
37−bool onSphereShell(float radius, float scale, glm::vec3 * position) {
38− float vRadius = glm::length(*position);
39− return ((vRadius + scale/2.0 > radius) && (vRadius - scale/2.0 < radius));
37+VoxelSystem::VoxelSystem() {
38+ voxelsRendered = 0;
4039 }
4140
42−void VoxelSystem::init() {
43− root = new Voxel;
41+VoxelSystem::~VoxelSystem() {
42+ delete[] verticesArray;
43+ delete[] colorsArray;
4444 }
4545
46−float randomFloat(float maximumValue) {
47− return ((float) rand() / ((float) RAND_MAX / maximumValue));
48−}
46+void VoxelSystem::parseData(void *data, int size) {
47+ // ignore the first char, it's a V to tell us that this is voxel data
48+ char *voxelDataPtr = (char *) data + 1;
4949
50−void VoxelSystem::init(int numberOfRandomVoxels) {
51− // create the arrays needed to pass to glDrawElements later
52− // position / color are random for now
53−
54− voxelsRendered = numberOfRandomVoxels;
55−
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];
50+ float *position = new float[3];
51+ char *color = new char[3];
52+
53+ // get pointers to position of last append of data
54+ GLfloat *parseVerticesPtr = lastAddPointer;
55+ GLubyte *parseColorsPtr = colorsArray + (lastAddPointer - verticesArray);
6456
65− // new seed based on time now so voxels are different each time
66− srand((unsigned)time(0));
57+ int voxelsInData = 0;
6758
68− for (int n = 0; n < numberOfRandomVoxels; n++) {
69− // pick a random point for the center of the cube
70− const float DEATH_STAR_RADIUS = 4.0;
71− const float MAX_CUBE = 0.05;
72− float azimuth = randFloat()*2*PI;
73− float altitude = randFloat()*PI - PI/2;
74− float radius = DEATH_STAR_RADIUS;
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− );
59+ // pull voxels out of the received data and put them into our internal memory structure
60+ while ((voxelDataPtr - (char *) data) < size) {
61+
62+ memcpy(position, voxelDataPtr, 3 * sizeof(float));
63+ voxelDataPtr += 3 * sizeof(float);
64+ memcpy(color, voxelDataPtr, 3);
65+ voxelDataPtr += 3;
8366
84− // fill the vertices array, and scale the voxels
85− GLfloat *currentVerticesPos = verticesArray + (n * VERTEX_POINTS_PER_VOXEL);
8667 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);
8869 }
8970
90− // fill the colors array
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;
71+ parseVerticesPtr += VERTEX_POINTS_PER_VOXEL;
9672
97− for (int c = 0; c < VERTICES_PER_VOXEL; c++) {
98− currentColorPos[0 + (c * 3)] = voxelR;
99− currentColorPos[1 + (c * 3)] = voxelG;
100− currentColorPos[2 + (c * 3)] = voxelB;
73+ for (int c = 0; c < COLOR_VALUES_PER_VOXEL; c++) {
74+ parseColorsPtr[c] = color[c % 3];
10175 }
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+
87+VoxelSystem* 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+}
10291
92+void 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++) {
103102 // fill the indices array
104103 int voxelIndexOffset = n * INDICES_PER_VOXEL;
105104 GLuint *currentIndicesPos = indicesArray + voxelIndexOffset;
@@ -114,135 +113,51 @@ void VoxelSystem::init(int numberOfRandomVoxels) { · 8 unmodified lines
114113 // VBO for the verticesArray
115114 glGenBuffers(1, &vboVerticesID);
116115 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);
118117
119118 // VBO for colorsArray
120119 glGenBuffers(1, &vboColorsID);
121120 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);
123122
124123 // VBO for the indicesArray
125124 glGenBuffers(1, &vboIndicesID);
126125 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vboIndicesID);
127− glBufferData(GL_ELEMENT_ARRAY_BUFFER, numberOfRandomVoxels * INDICES_PER_VOXEL * sizeof(GLuint), indicesArray, GL_STATIC_DRAW);
128−
129− // delete the verticesArray, indicesArray
130− delete[] verticesArray;
126+ glBufferData(GL_ELEMENT_ARRAY_BUFFER, INDICES_PER_VOXEL * sizeof(GLuint) * MAX_VOXELS_PER_SYSTEM, indicesArray, GL_STATIC_DRAW);
127+
128+ // delete the indices array that is no longer needed
131129 delete[] indicesArray;
132− delete[] colorsArray;
133130 }
134131
135−//
136−// Recursively initialize the voxel tree
137−//
138−int 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;
132+void VoxelSystem::render() {
133+ // check if there are new voxels to draw
134+ int vertexValuesToDraw = lastAddPointer - lastDrawPointer;
146135
147− //
148− // First, randomly decide whether to stop here without recursing for children
149− //
150− if (onSphereShell(RADIUS, scale, position) && (scale < 0.25) && (randFloat() < 0.01))
151− {
152− voxel->color.x = 0.1;
153− voxel->color.y = 0.5 + randFloat()*0.5;
154− voxel->color.z = 0.1;
155− for (unsigned char i = 0; i < NUM_CHILDREN; i++) voxel->children[i] = NULL;
156− return 0;
157− } else {
158− // Decide whether to make kids, recurse into them
159− for (unsigned char i = 0; i < NUM_CHILDREN; i++) {
160− if (scale > 0.01) {
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−
199−const float RENDER_DISCARD = 0.04; //0.01;
200−
201−//
202−// Returns the total number of voxels actually rendered
203−//
204−int 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++;
136+ if (vertexValuesToDraw > 0) {
137+ // calculate the offset into each VBO, in vertex point values
138+ int vertexBufferOffset = lastDrawPointer - verticesArray;
139+
140+ // bind the vertices VBO, copy in new data
141+ glBindBuffer(GL_ARRAY_BUFFER, vboVerticesID);
142+ glBufferSubData(GL_ARRAY_BUFFER, vertexBufferOffset * sizeof(float), vertexValuesToDraw * sizeof(float), lastDrawPointer);
143+
144+ // bind the colors VBO, copy in new data
145+ glBindBuffer(GL_ARRAY_BUFFER, vboColorsID);
146+ glBufferSubData(GL_ARRAY_BUFFER, vertexBufferOffset * sizeof(GLubyte), vertexValuesToDraw * sizeof(GLubyte), (colorsArray + (lastDrawPointer - verticesArray)));
147+
148+ // increment the lastDrawPointer to the lastAddPointer value used for this draw
149+ lastDrawPointer += vertexValuesToDraw;
231150 }
232− return vRendered;
233−}
234151
235−void VoxelSystem::render() {
152+ // tell OpenGL where to find vertex and color information
236153 glEnableClientState(GL_VERTEX_ARRAY);
237154 glEnableClientState(GL_COLOR_ARRAY);
238155
239− glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vboIndicesID);
240−
241156 glBindBuffer(GL_ARRAY_BUFFER, vboVerticesID);
242157 glVertexPointer(3, GL_FLOAT, 0, 0);
243158
244159 glBindBuffer(GL_ARRAY_BUFFER, vboColorsID);
245− glColorPointer(3, GL_FLOAT, 0, 0);
160+ glColorPointer(3, GL_UNSIGNED_BYTE, 0, 0);
246161
247162 glNormal3f(0, 1, 0);
248163