1 | #include <stdio.h> |
---|
2 | #include <stdlib.h> |
---|
3 | #include <math.h> |
---|
4 | |
---|
5 | #include "../include/camera.h" |
---|
6 | #include "../include/global.h" |
---|
7 | |
---|
8 | using namespace VMI; |
---|
9 | |
---|
10 | /* Make it not a power of two to avoid cache thrashing on the chip */ |
---|
11 | #define CACHE_SIZE 240 |
---|
12 | #define Pi (GLdouble)3.141592653589793238462643383279502884197 |
---|
13 | |
---|
14 | //#define DRAW_DEBUG // just for debugging not necessary |
---|
15 | |
---|
16 | Camera *VMI::loadCameras(GLdouble radius, char* filename, GLuint *numCameras) {
|
---|
17 | FILE *fp;
|
---|
18 | Camera *cameras;
|
---|
19 | GLuint num, i;
|
---|
20 | GLfloat eyeX, eyeY, eyeZ,
|
---|
21 | centerX, centerY, centerZ,
|
---|
22 | upX, upY, upZ, weight, max = 0.0f, min = 0.0f, normal;
|
---|
23 | float u[3], v[3]/*, n[3]*/;
|
---|
24 |
|
---|
25 | if((fp= fopen(filename, "rt"))== NULL) {
|
---|
26 | printf("Can't open file %s\n", filename);
|
---|
27 | exit(1);
|
---|
28 | }
|
---|
29 |
|
---|
30 | printf("Reading file %s\n", filename);
|
---|
31 |
|
---|
32 | fscanf (fp, "%d\n", &num);
|
---|
33 | printf("%d\n", num);
|
---|
34 |
|
---|
35 | cameras = (Camera *)malloc(sizeof(Camera) * num);
|
---|
36 | if (cameras == NULL) {
|
---|
37 | fprintf(stderr, "Error allocating memory\n");
|
---|
38 | exit(1);
|
---|
39 | }
|
---|
40 |
|
---|
41 | num = 0;
|
---|
42 |
|
---|
43 | while (!feof(fp)) {
|
---|
44 |
|
---|
45 | fscanf(fp, "%f %f %f %f %f %f %f %f %f %f\n", &eyeX, &eyeY, &eyeZ,
|
---|
46 | ¢erX, ¢erY, ¢erZ,
|
---|
47 | &upX, &upY, &upZ,
|
---|
48 | &weight);
|
---|
49 |
|
---|
50 | /*printf("%d -> %f %f %f %f %f %f %f %f %f %f\n",num,
|
---|
51 | eyeX, eyeY, eyeZ,
|
---|
52 | centerX, centerY, centerZ,
|
---|
53 | upX, upY, upZ, weight);*/
|
---|
54 | if (eyeX > max) max = eyeX;
|
---|
55 | if (eyeY > max) max = eyeY;
|
---|
56 | if (eyeZ > max) max = eyeZ;
|
---|
57 |
|
---|
58 | if (eyeX < min) min = eyeX;
|
---|
59 | if (eyeY < min) min = eyeY;
|
---|
60 | if (eyeZ < min) min = eyeZ;
|
---|
61 |
|
---|
62 | cameras[num].eyeX = radius * eyeX;
|
---|
63 | cameras[num].eyeY = radius * eyeY;
|
---|
64 | cameras[num].eyeZ = radius * eyeZ;
|
---|
65 |
|
---|
66 | cameras[num].centerX = centerX;
|
---|
67 | cameras[num].centerY = centerY;
|
---|
68 | cameras[num].centerZ = centerZ;
|
---|
69 | cameras[num].upX = upX;
|
---|
70 | cameras[num].upY = upY;
|
---|
71 | cameras[num].upZ = upZ;
|
---|
72 | cameras[num].weight = weight;
|
---|
73 | num++;
|
---|
74 | }
|
---|
75 |
|
---|
76 | //printf("%f %f\n", min, max);
|
---|
77 | // This normalization currently only works if center is vector (0,0,0)
|
---|
78 | normal = ABS(max);
|
---|
79 |
|
---|
80 | if (ABS(min) > normal) normal = ABS(min);
|
---|
81 |
|
---|
82 | for (i=0; i<num; i++) {
|
---|
83 |
|
---|
84 | cameras[i].eyeX /= normal;
|
---|
85 | cameras[i].eyeY /= normal;
|
---|
86 | cameras[i].eyeZ /= normal;
|
---|
87 |
|
---|
88 | u[0] = cameras[i].eyeX;
|
---|
89 | u[1] = cameras[i].eyeY;
|
---|
90 | u[2] = cameras[i].eyeZ;
|
---|
91 |
|
---|
92 | // Compute camera Up vector
|
---|
93 | if ((cameras[i].eyeY == 0.0f) && (cameras[i].eyeX == 0.0f)) {
|
---|
94 | v[0] = 1.0f;
|
---|
95 | v[1] = 0.0f;
|
---|
96 | v[2] = 0.0f;
|
---|
97 | } else {
|
---|
98 | v[0] = -cameras[i].eyeY;
|
---|
99 | v[1] = cameras[i].eyeX;
|
---|
100 | v[2] = 0.0f;
|
---|
101 | }
|
---|
102 |
|
---|
103 | //glmCross(u, v, n);
|
---|
104 |
|
---|
105 | cameras[i].upX = v[0];
|
---|
106 | cameras[i].upY = v[1];
|
---|
107 | cameras[i].upZ = v[2];
|
---|
108 | }
|
---|
109 |
|
---|
110 | fclose(fp);
|
---|
111 | printf("File read.\n");
|
---|
112 |
|
---|
113 | *numCameras = num;
|
---|
114 |
|
---|
115 | printCameras(cameras, *numCameras);
|
---|
116 |
|
---|
117 | return cameras;
|
---|
118 | }
|
---|
119 |
|
---|
120 | void VMI::saveCameras(char* filename, Camera *cameras, GLuint numCameras) {
|
---|
121 | FILE *fp;
|
---|
122 | GLuint i;
|
---|
123 |
|
---|
124 | if((fp= fopen(filename, "wt"))== NULL) {
|
---|
125 | printf("Can't open file %s\n", filename);
|
---|
126 | exit(1);
|
---|
127 | }
|
---|
128 |
|
---|
129 | printf("Writing file %s\n", filename);
|
---|
130 |
|
---|
131 | fprintf(fp, "%d\n", numCameras);
|
---|
132 | //printf("%d\n", num);
|
---|
133 |
|
---|
134 | for(i=0; i<numCameras; i++) {
|
---|
135 |
|
---|
136 | fprintf(fp, "%f %f %f %f %f %f %f %f %f %f\n",
|
---|
137 | cameras[i].eyeX, cameras[i].eyeY, cameras[i].eyeZ,
|
---|
138 | cameras[i].centerX, cameras[i].centerY, cameras[i].centerZ,
|
---|
139 | cameras[i].upX, cameras[i].upY, cameras[i].upZ, cameras[i].weight);
|
---|
140 | }
|
---|
141 |
|
---|
142 | fclose(fp);
|
---|
143 | printf("File written.\n");
|
---|
144 | } |
---|
145 | |
---|
146 | void VMI::copyToCameras(Camera *cameras, int numVertices, GLdouble vertices[][3]) { |
---|
147 | int i; |
---|
148 | |
---|
149 | for (i = 0; i < numVertices; i++) { |
---|
150 | cameras[i].eyeX = vertices[i][0]; |
---|
151 | cameras[i].eyeY = vertices[i][1]; |
---|
152 | cameras[i].eyeZ = vertices[i][2]; |
---|
153 | cameras[i].centerX = 0.0; |
---|
154 | cameras[i].centerY = 0.0; |
---|
155 | cameras[i].centerZ = 0.0; |
---|
156 | cameras[i].upX = 0.0; |
---|
157 | cameras[i].upY = 1.0; |
---|
158 | cameras[i].upZ = 0.0; |
---|
159 | cameras[i].weight = 1.0; |
---|
160 | |
---|
161 | /* |
---|
162 | if (cameras[i].eyeY != 0.0f) { |
---|
163 | cameras[i].upY = 0.0; |
---|
164 | cameras[i].upZ = 1.0; |
---|
165 | } else { |
---|
166 | cameras[i].upY = 1.0; |
---|
167 | cameras[i].upZ = 0.0; |
---|
168 | }*/ |
---|
169 | } |
---|
170 | } |
---|
171 | |
---|
172 | Camera *VMI::setCameras(GLdouble radius, GLuint type, GLuint *numCameras) { |
---|
173 | Camera *cameras = NULL; |
---|
174 | |
---|
175 | switch (type) { |
---|
176 | case OCTAHEDRON: |
---|
177 | cameras = (Camera *)malloc(sizeof(Camera) * type); |
---|
178 | if (cameras == NULL) { |
---|
179 | fprintf(stderr, "Error allocating memory\n"); |
---|
180 | exit(1); |
---|
181 | } |
---|
182 | *numCameras = type; |
---|
183 | drawOctahedron(cameras, radius); |
---|
184 | break; |
---|
185 | case ICOSAHEDRON: |
---|
186 | cameras = (Camera *)malloc(sizeof(Camera) * type); |
---|
187 | if (cameras == NULL) { |
---|
188 | fprintf(stderr, "Error allocating memory\n"); |
---|
189 | exit(1); |
---|
190 | } |
---|
191 | *numCameras = type; |
---|
192 | drawIcosahedron(cameras, radius); |
---|
193 | break; |
---|
194 | case DODECAHEDRON: |
---|
195 | cameras = (Camera *)malloc(sizeof(Camera) * type); |
---|
196 | if (cameras == NULL) { |
---|
197 | fprintf(stderr, "Error allocating memory\n"); |
---|
198 | exit(1); |
---|
199 | } |
---|
200 | *numCameras = type; |
---|
201 | drawDodecahedron(cameras, radius); |
---|
202 | break; |
---|
203 | default: |
---|
204 | printf("Error cameras not defined\n"); |
---|
205 | exit(1); |
---|
206 | break; |
---|
207 | } |
---|
208 | |
---|
209 | return cameras; |
---|
210 | } |
---|
211 | |
---|
212 | void VMI::setCameraWeights(Camera *cameras, GLuint numCameras, GLdouble *weights) { |
---|
213 | GLuint i; |
---|
214 | |
---|
215 | for (i = 0; i<numCameras; i++) { |
---|
216 | cameras[i].weight = weights[i]; |
---|
217 | } |
---|
218 | } |
---|
219 | |
---|
220 | void VMI::printCameras(Camera *cameras, GLuint numCameras) { |
---|
221 | GLuint i; |
---|
222 | |
---|
223 | printf("\n"); |
---|
224 | for (i = 0; i<numCameras; i++) { |
---|
225 | printf("Camera %d Eye (%f, %f, %f)\n", i , cameras[i].eyeX, cameras[i].eyeY, cameras[i].eyeZ); |
---|
226 | printf(" Center(%f, %f, %f)\n", cameras[i].centerX, cameras[i].centerY, cameras[i].centerZ); |
---|
227 | printf(" Up (%f, %f, %f)\n", cameras[i].upX, cameras[i].upY, cameras[i].upZ); |
---|
228 | printf(" Weight: %f\n", cameras[i].weight); |
---|
229 | } |
---|
230 | } |
---|
231 | |
---|
232 | void VMI::drawSphere(Camera *cameras, GLdouble radius, int slices, int stacks) { |
---|
233 | GLdouble sintemp1; |
---|
234 | GLdouble costemp1; |
---|
235 | GLdouble sinCache1a[CACHE_SIZE]; |
---|
236 | GLdouble cosCache1a[CACHE_SIZE]; |
---|
237 | GLdouble sinCache1b[CACHE_SIZE]; |
---|
238 | GLdouble cosCache1b[CACHE_SIZE]; |
---|
239 | GLdouble vertices[CACHE_SIZE][3]; |
---|
240 | GLdouble angle; |
---|
241 | int i, j, n = 0; |
---|
242 | |
---|
243 | if (slices >= CACHE_SIZE) slices = CACHE_SIZE-1; |
---|
244 | if (stacks >= CACHE_SIZE) stacks = CACHE_SIZE-1; |
---|
245 | if (slices < 2 || stacks < 1 || radius < 0.0) { |
---|
246 | printf("Error\n"); |
---|
247 | return; |
---|
248 | } |
---|
249 | |
---|
250 | for (i = 0; i < slices; i++) { |
---|
251 | angle = 2 * Pi * i / slices; |
---|
252 | sinCache1a[i] = sin(angle); |
---|
253 | cosCache1a[i] = cos(angle); |
---|
254 | } |
---|
255 | |
---|
256 | for (j = 0; j <= stacks; j++) { |
---|
257 | angle = Pi * j / stacks; |
---|
258 | sinCache1b[j] = radius * sin(angle); |
---|
259 | cosCache1b[j] = radius * cos(angle); |
---|
260 | } |
---|
261 | |
---|
262 | // Make sure it comes to a point |
---|
263 | sinCache1b[0] = 0; |
---|
264 | sinCache1b[stacks] = 0; |
---|
265 | |
---|
266 | sinCache1a[slices] = sinCache1a[0]; |
---|
267 | cosCache1a[slices] = cosCache1a[0]; |
---|
268 | #ifdef DRAW_DEBUG |
---|
269 | glBegin(GL_POINTS); |
---|
270 | #endif |
---|
271 | for (j = 0; j <= stacks; j++) { |
---|
272 | sintemp1 = sinCache1b[j]; |
---|
273 | costemp1 = cosCache1b[j]; |
---|
274 | |
---|
275 | for (i = 0; i < slices; i++) { |
---|
276 | |
---|
277 | vertices[n][0]= sintemp1 * sinCache1a[i]; |
---|
278 | vertices[n][1]= sintemp1 * cosCache1a[i]; |
---|
279 | vertices[n][2]= costemp1; |
---|
280 | #ifdef DRAW_DEBUG |
---|
281 | glVertex3fv(vertices[n]); |
---|
282 | #endif |
---|
283 | n++; |
---|
284 | } |
---|
285 | } |
---|
286 | #ifdef DRAW_DEBUG |
---|
287 | glEnd(); |
---|
288 | #endif |
---|
289 | |
---|
290 | copyToCameras(cameras, n, vertices); |
---|
291 | } |
---|
292 | |
---|
293 | /////////////////////////////////////////////////////////////////////////////// |
---|
294 | |
---|
295 | void VMI::drawDodecahedron(Camera *cameras,GLdouble r) // any radius in which the polyhedron is inscribed |
---|
296 | { |
---|
297 | GLdouble vertices[20][3]; // 20 vertices with x, y, z coordinate |
---|
298 | GLdouble phiaa = 52.62263590; // the two phi angles needed for generation |
---|
299 | GLdouble phibb = 10.81231754; |
---|
300 | GLdouble phia = Pi*phiaa/180.0; // 4 sets of five points each |
---|
301 | GLdouble phib = Pi*phibb/180.0; |
---|
302 | GLdouble phic = Pi*(-phibb)/180.0; |
---|
303 | GLdouble phid = Pi*(-phiaa)/180.0; |
---|
304 | GLdouble the72 = Pi*72.0/180; |
---|
305 | GLdouble theb = the72/2.0; // pairs of layers offset 36 degrees |
---|
306 | GLdouble the = 0.0; |
---|
307 | int i; |
---|
308 | #ifdef DRAW_DEBUG |
---|
309 | int tindex[12][5] = { |
---|
310 | {0,1,2,3,4}, |
---|
311 | |
---|
312 | {0,1,6,10,5}, |
---|
313 | {1,2,7,11,6}, |
---|
314 | {2,3,8,12,7}, |
---|
315 | {3,4,9,13,8}, |
---|
316 | {4,0,5,14,9}, |
---|
317 | |
---|
318 | {15,16,11,6,10}, |
---|
319 | {16,17,12,7,11}, |
---|
320 | {17,18,13,8,12}, |
---|
321 | {18,19,14,9,13}, |
---|
322 | {19,15,10,5,14} }; |
---|
323 | #endif |
---|
324 | |
---|
325 | if (r < 0.0f) return; |
---|
326 | |
---|
327 | for(i=0; i<5; i++) |
---|
328 | { |
---|
329 | vertices[i][0]=r*cos(the)*cos(phia); |
---|
330 | vertices[i][1]=r*sin(the)*cos(phia); |
---|
331 | vertices[i][2]=r*sin(phia); |
---|
332 | the = the+the72; |
---|
333 | } |
---|
334 | the=0.0; |
---|
335 | for(i=5; i<10; i++) |
---|
336 | { |
---|
337 | vertices[i][0]=r*cos(the)*cos(phib); |
---|
338 | vertices[i][1]=r*sin(the)*cos(phib); |
---|
339 | vertices[i][2]=r*sin(phib); |
---|
340 | the = the+the72; |
---|
341 | } |
---|
342 | the = theb; |
---|
343 | for(i=10; i<15; i++) |
---|
344 | { |
---|
345 | vertices[i][0]=r*cos(the)*cos(phic); |
---|
346 | vertices[i][1]=r*sin(the)*cos(phic); |
---|
347 | vertices[i][2]=r*sin(phic); |
---|
348 | the = the+the72; |
---|
349 | } |
---|
350 | the=theb; |
---|
351 | for(i=15; i<20; i++) |
---|
352 | { |
---|
353 | vertices[i][0]=r*cos(the)*cos(phid); |
---|
354 | vertices[i][1]=r*sin(the)*cos(phid); |
---|
355 | vertices[i][2]=r*sin(phid); |
---|
356 | the = the+the72; |
---|
357 | } |
---|
358 | |
---|
359 | // map vertices to 12 faces |
---|
360 | #ifdef DRAW_DEBUG |
---|
361 | |
---|
362 | for (i=0; i<12; i++) { |
---|
363 | glBegin(GL_POINTS); |
---|
364 | glVertex3fv(&vertices[tindex[i][0]][0]); |
---|
365 | glVertex3fv(&vertices[tindex[i][1]][0]); |
---|
366 | glVertex3fv(&vertices[tindex[i][2]][0]); |
---|
367 | glVertex3fv(&vertices[tindex[i][3]][0]); |
---|
368 | glVertex3fv(&vertices[tindex[i][4]][0]); |
---|
369 | glEnd(); |
---|
370 | } |
---|
371 | #endif |
---|
372 | copyToCameras(cameras, 20, vertices); |
---|
373 | } |
---|
374 | |
---|
375 | /////////////////////////////////////////////////////////////////////////////// |
---|
376 | |
---|
377 | void VMI::drawOctahedron(Camera *cameras, GLdouble r) // any radius in which the polyhedron is inscribed |
---|
378 | { |
---|
379 | GLdouble vertices[6][3]; // 6 vertices with x, y, z coordinate |
---|
380 | GLdouble phiaa = 0.0; // the phi needed for generation |
---|
381 | GLdouble phia = Pi*phiaa/180.0; // 1 set of four points |
---|
382 | GLdouble the90 = Pi*90.0/180; |
---|
383 | GLdouble the = 0.0; |
---|
384 | int i; |
---|
385 | #ifdef DRAW_DEBUG |
---|
386 | int tindex[8][3] = { |
---|
387 | {0,1,2}, |
---|
388 | {0,2,3}, |
---|
389 | {0,3,4}, |
---|
390 | {0,4,1}, |
---|
391 | {5,1,2}, |
---|
392 | {5,2,3}, |
---|
393 | {5,3,4}, |
---|
394 | {5,4,1} }; |
---|
395 | #endif |
---|
396 | |
---|
397 | if (r < 0.0f) return; |
---|
398 | |
---|
399 | vertices[0][0]=0.0; |
---|
400 | vertices[0][1]=0.0; |
---|
401 | vertices[0][2]=r; |
---|
402 | |
---|
403 | vertices[5][0]=0.0; |
---|
404 | vertices[5][1]=0.0; |
---|
405 | vertices[5][2]=-r; |
---|
406 | |
---|
407 | |
---|
408 | for(i=1; i<5; i++) |
---|
409 | { |
---|
410 | vertices[i][0]=r*cos(the)*cos(phia); |
---|
411 | vertices[i][1]=r*sin(the)*cos(phia); |
---|
412 | vertices[i][2]=r*sin(phia); |
---|
413 | the = the+the90; |
---|
414 | } |
---|
415 | |
---|
416 | // map vertices to 8 faces |
---|
417 | #ifdef DRAW_DEBUG |
---|
418 | |
---|
419 | for (i=0; i<8; i++) { |
---|
420 | glBegin(GL_POINTS); |
---|
421 | glVertex3fv(&vertices[tindex[i][0]][0]); |
---|
422 | glVertex3fv(&vertices[tindex[i][1]][0]); |
---|
423 | glVertex3fv(&vertices[tindex[i][2]][0]); |
---|
424 | glEnd(); |
---|
425 | } |
---|
426 | #endif |
---|
427 | |
---|
428 | copyToCameras(cameras, 6, vertices); |
---|
429 | } |
---|
430 | |
---|
431 | /////////////////////////////////////////////////////////////////////////////// |
---|
432 | |
---|
433 | void VMI::drawIcosahedron(Camera *cameras, GLdouble r) // any radius in which the polyhedron is inscribed |
---|
434 | { |
---|
435 | GLdouble vertices[12][3]; // 12 vertices with x, y, z coordinates |
---|
436 | GLdouble phiaa = 26.56505; // phi needed for generation |
---|
437 | GLdouble phia = Pi*phiaa/180.0; // 2 sets of four points |
---|
438 | GLdouble theb = Pi*36.0/180.0; // offset second set 36 degrees |
---|
439 | GLdouble the72 = Pi*72.0/180; // step 72 degrees |
---|
440 | GLdouble the = 0.0; |
---|
441 | int i; |
---|
442 | #ifdef DRAW_DEBUG |
---|
443 | int tindex[20][3] = { |
---|
444 | {0,1,2}, |
---|
445 | {0,2,3}, |
---|
446 | {0,3,4}, |
---|
447 | {0,4,5}, |
---|
448 | {0,5,1}, |
---|
449 | {11,6,7}, |
---|
450 | {11,7,8}, |
---|
451 | {11,8,9}, |
---|
452 | {11,9,10}, |
---|
453 | {11,10,6}, |
---|
454 | {1,2,6}, |
---|
455 | {2,3,7}, |
---|
456 | {3,4,8}, |
---|
457 | {4,5,9}, |
---|
458 | {5,1,10}, |
---|
459 | {6,7,2}, |
---|
460 | {7,8,3}, |
---|
461 | {8,9,4}, |
---|
462 | {9,10,5}, |
---|
463 | {10,6,1} }; |
---|
464 | #endif |
---|
465 | |
---|
466 | if (r < 0.0f) return; |
---|
467 | |
---|
468 | vertices[0][0]=0.0; |
---|
469 | vertices[0][1]=0.0; |
---|
470 | vertices[0][2]=r; |
---|
471 | |
---|
472 | vertices[11][0]=0.0; |
---|
473 | vertices[11][1]=0.0; |
---|
474 | vertices[11][2]=-r; |
---|
475 | |
---|
476 | for(i=1; i<6; i++) |
---|
477 | { |
---|
478 | vertices[i][0]=r*cos(the)*cos(phia); |
---|
479 | vertices[i][1]=r*sin(the)*cos(phia); |
---|
480 | vertices[i][2]=r*sin(phia); |
---|
481 | the = the+the72; |
---|
482 | } |
---|
483 | the=theb; |
---|
484 | for(i=6; i<11; i++) |
---|
485 | { |
---|
486 | vertices[i][0]=r*cos(the)*cos(-phia); |
---|
487 | vertices[i][1]=r*sin(the)*cos(-phia); |
---|
488 | vertices[i][2]=r*sin(-phia); |
---|
489 | the = the+the72; |
---|
490 | } |
---|
491 | |
---|
492 | // map vertices to 20 faces |
---|
493 | #ifdef DRAW_DEBUG |
---|
494 | |
---|
495 | for (i=0; i<20; i++) { |
---|
496 | |
---|
497 | glBegin(GL_POINTS ); |
---|
498 | glVertex3fv(&vertices[tindex[i][0]][0]); |
---|
499 | glVertex3fv(&vertices[tindex[i][1]][0]); |
---|
500 | glVertex3fv(&vertices[tindex[i][2]][0]); |
---|
501 | glEnd(); |
---|
502 | } |
---|
503 | |
---|
504 | #endif |
---|
505 | |
---|
506 | copyToCameras(cameras, 12, vertices); |
---|
507 | } |
---|