source: GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/vmi/src/camera.cpp @ 2127

Revision 2127, 15.1 KB checked in by gumbau, 17 years ago (diff)
Line 
1#include <stdio.h>
2#include <stdlib.h>
3#include <math.h>
4
5#include "../include/camera.h"
6#include "../include/global.h"
7
8using 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
16Camera *VMI::loadCameras(GLdouble radius, char* filename, int *numCameras) {
17    FILE *fp;
18    Camera *cameras;
19    int 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                                                      &centerX, &centerY, &centerZ,
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
120void VMI::saveCameras(char* filename, Camera *cameras, int numCameras) {
121    FILE *fp;
122    int 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
146void 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
172Camera *VMI::setCameras(GLdouble radius, int type, int *numCameras) {
173    Camera *cameras = NULL;
174
175    switch (type) {
176    case 0:
177        cameras = (Camera *)malloc(sizeof(Camera) * OCTAHEDRON);
178        if (cameras == NULL) {
179            fprintf(stderr, "Error allocating memory\n");
180            exit(1);
181        }
182        *numCameras = OCTAHEDRON;
183        drawOctahedron(cameras, radius);
184        break;
185    case 1:
186        cameras = (Camera *)malloc(sizeof(Camera) * CUBE);
187        if (cameras == NULL) {
188            fprintf(stderr, "Error allocating memory\n");
189            exit(1);
190        }
191        *numCameras = CUBE;
192        drawCube(cameras, radius);
193        break;
194    case 2:
195        cameras = (Camera *)malloc(sizeof(Camera) * ICOSAHEDRON);
196        if (cameras == NULL) {
197            fprintf(stderr, "Error allocating memory\n");
198            exit(1);
199        }
200        *numCameras = ICOSAHEDRON;
201        drawIcosahedron(cameras, radius);
202        break;
203    case 3:
204        cameras = (Camera *)malloc(sizeof(Camera) * DODECAHEDRON);
205        if (cameras == NULL) {
206            fprintf(stderr, "Error allocating memory\n");
207            exit(1);
208        }
209        *numCameras = DODECAHEDRON;
210        drawDodecahedron(cameras, radius);
211        break;
212    default:
213        printf("Error, cameras not defined\n");
214        exit(1);
215        break;
216    }
217
218    printf("Number of cameras: %d\n", *numCameras);
219
220    return cameras;
221}
222
223void VMI::setCameraWeights(Camera *cameras, int numCameras, GLdouble *weights) {
224    int i;
225
226    for (i = 0; i<numCameras; i++) {
227       cameras[i].weight = weights[i];
228    }
229}
230
231void VMI::printCameras(Camera *cameras, int numCameras) {
232    int i;
233   
234    printf("\n");
235    for (i = 0; i<numCameras; i++) {
236        printf("Camera %d  Eye   (%f, %f, %f)\n", i , cameras[i].eyeX, cameras[i].eyeY, cameras[i].eyeZ);
237        printf("          Center(%f, %f, %f)\n", cameras[i].centerX, cameras[i].centerY, cameras[i].centerZ);
238        printf("          Up    (%f, %f, %f)\n", cameras[i].upX, cameras[i].upY, cameras[i].upZ);
239        printf("          Weight: %f\n", cameras[i].weight);
240    }
241}
242     
243void VMI::drawSphere(Camera *cameras, GLdouble radius, int slices, int stacks) {
244    GLdouble sintemp1;
245    GLdouble costemp1;
246    GLdouble sinCache1a[CACHE_SIZE];
247    GLdouble cosCache1a[CACHE_SIZE];
248    GLdouble sinCache1b[CACHE_SIZE];
249    GLdouble cosCache1b[CACHE_SIZE];
250    GLdouble vertices[CACHE_SIZE][3];
251    GLdouble angle;
252    int i, j, n = 0;
253   
254    if (slices >= CACHE_SIZE) slices = CACHE_SIZE-1;
255    if (stacks >= CACHE_SIZE) stacks = CACHE_SIZE-1;
256    if (slices < 2 || stacks < 1 || radius < 0.0) {
257        printf("Error\n");
258        return;
259    }
260   
261    for (i = 0; i < slices; i++) {
262        angle = 2 * Pi * i / slices;
263        sinCache1a[i] = sin(angle);
264        cosCache1a[i] = cos(angle);
265    }
266   
267    for (j = 0; j <= stacks; j++) {
268        angle = Pi * j / stacks;
269        sinCache1b[j] = radius * sin(angle);
270        cosCache1b[j] = radius * cos(angle);
271    }
272   
273    // Make sure it comes to a point
274    sinCache1b[0] = 0;
275    sinCache1b[stacks] = 0;
276   
277    sinCache1a[slices] = sinCache1a[0];
278    cosCache1a[slices] = cosCache1a[0];
279#ifdef DRAW_DEBUG
280    glBegin(GL_POINTS);
281#endif
282    for (j = 0; j <= stacks; j++) {
283        sintemp1 = sinCache1b[j];
284        costemp1 = cosCache1b[j];
285       
286        for (i = 0; i < slices; i++) {
287           
288            vertices[n][0]= sintemp1 * sinCache1a[i];
289            vertices[n][1]= sintemp1 * cosCache1a[i];
290            vertices[n][2]= costemp1;
291#ifdef DRAW_DEBUG
292            glVertex3fv(vertices[n]);
293#endif
294            n++;
295        }
296    }
297#ifdef DRAW_DEBUG
298    glEnd();
299#endif
300
301    copyToCameras(cameras, n, vertices);
302}
303
304///////////////////////////////////////////////////////////////////////////////
305
306void VMI::drawDodecahedron(Camera *cameras,GLdouble r) // any radius in which the polyhedron is inscribed
307{
308    GLdouble vertices[20][3]; // 20 vertices with x, y, z coordinate
309    GLdouble phiaa = 52.62263590; // the two phi angles needed for generation
310    GLdouble phibb = 10.81231754;
311    GLdouble phia = Pi*phiaa/180.0; // 4 sets of five points each
312    GLdouble phib = Pi*phibb/180.0;
313    GLdouble phic = Pi*(-phibb)/180.0;
314    GLdouble phid = Pi*(-phiaa)/180.0;
315    GLdouble the72 = Pi*72.0/180;
316    GLdouble theb = the72/2.0; // pairs of layers offset 36 degrees
317    GLdouble the = 0.0;
318    int i;
319#ifdef DRAW_DEBUG
320    int tindex[12][5] = {
321        {0,1,2,3,4},
322   
323        {0,1,6,10,5},
324        {1,2,7,11,6},
325        {2,3,8,12,7},
326        {3,4,9,13,8},
327        {4,0,5,14,9},
328   
329        {15,16,11,6,10},
330        {16,17,12,7,11},
331        {17,18,13,8,12},
332        {18,19,14,9,13},
333        {19,15,10,5,14} };
334#endif
335
336    if (r < 0.0f) return;
337
338    for(i=0; i<5; i++)
339    {
340        vertices[i][0]=r*cos(the)*cos(phia);
341        vertices[i][1]=r*sin(the)*cos(phia);
342        vertices[i][2]=r*sin(phia);
343        the = the+the72;
344    }
345    the=0.0;
346    for(i=5; i<10; i++)
347    {
348        vertices[i][0]=r*cos(the)*cos(phib);
349        vertices[i][1]=r*sin(the)*cos(phib);
350        vertices[i][2]=r*sin(phib);
351        the = the+the72;
352    }
353    the = theb;
354    for(i=10; i<15; i++)
355    {
356        vertices[i][0]=r*cos(the)*cos(phic);
357        vertices[i][1]=r*sin(the)*cos(phic);
358        vertices[i][2]=r*sin(phic);
359        the = the+the72;
360    }
361    the=theb;
362    for(i=15; i<20; i++)
363    {
364        vertices[i][0]=r*cos(the)*cos(phid);
365        vertices[i][1]=r*sin(the)*cos(phid);
366        vertices[i][2]=r*sin(phid);
367        the = the+the72;
368    }
369   
370    // map vertices to 12 faces
371#ifdef DRAW_DEBUG
372   
373    for (i=0; i<12; i++) {   
374        glBegin(GL_POINTS); 
375        glVertex3fv(&vertices[tindex[i][0]][0]);
376        glVertex3fv(&vertices[tindex[i][1]][0]);
377        glVertex3fv(&vertices[tindex[i][2]][0]);   
378        glVertex3fv(&vertices[tindex[i][3]][0]);   
379        glVertex3fv(&vertices[tindex[i][4]][0]);   
380        glEnd();
381    }
382#endif
383    copyToCameras(cameras, 20, vertices);
384}
385
386///////////////////////////////////////////////////////////////////////////////
387
388void VMI::drawOctahedron(Camera *cameras, GLdouble r) // any radius in which the polyhedron is inscribed
389{
390    GLdouble vertices[6][3]; // 6 vertices with x, y, z coordinate
391    GLdouble phiaa  = 0.0; // the phi needed for generation
392    GLdouble phia = Pi*phiaa/180.0; // 1 set of four points
393    GLdouble the90 = Pi*90.0/180;
394    GLdouble the = 0.0;
395    int i;
396#ifdef DRAW_DEBUG
397    int tindex[8][3] = {
398        {0,1,2},
399        {0,2,3},
400        {0,3,4},
401        {0,4,1},
402        {5,1,2},
403        {5,2,3},
404        {5,3,4},
405        {5,4,1} };
406#endif
407
408    if (r < 0.0f) return;
409
410    vertices[0][0]=0.0;
411    vertices[0][1]=0.0;
412    vertices[0][2]=r;
413   
414    vertices[5][0]=0.0;
415    vertices[5][1]=0.0;
416    vertices[5][2]=-r;
417   
418   
419    for(i=1; i<5; i++)
420    {
421        vertices[i][0]=r*cos(the)*cos(phia);
422        vertices[i][1]=r*sin(the)*cos(phia);
423        vertices[i][2]=r*sin(phia);
424        the = the+the90;
425    }
426   
427    // map vertices to 8 faces
428#ifdef DRAW_DEBUG
429   
430    for (i=0; i<8; i++) {   
431        glBegin(GL_POINTS);
432        glVertex3fv(&vertices[tindex[i][0]][0]);
433        glVertex3fv(&vertices[tindex[i][1]][0]);
434        glVertex3fv(&vertices[tindex[i][2]][0]);   
435        glEnd();
436    }
437#endif
438   
439    copyToCameras(cameras, 6, vertices);
440}
441
442///////////////////////////////////////////////////////////////////////////////
443
444void VMI::drawIcosahedron(Camera *cameras, GLdouble r) // any radius in which the polyhedron is inscribed
445{
446    GLdouble vertices[12][3]; // 12 vertices with x, y, z coordinates
447    GLdouble phiaa  = 26.56505; // phi needed for generation
448    GLdouble phia = Pi*phiaa/180.0; // 2 sets of four points
449    GLdouble theb = Pi*36.0/180.0;  // offset second set 36 degrees
450    GLdouble the72 = Pi*72.0/180;   // step 72 degrees
451    GLdouble the = 0.0;
452    int i;
453#ifdef DRAW_DEBUG
454    int tindex[20][3] = {
455        {0,1,2},
456        {0,2,3},
457        {0,3,4},
458        {0,4,5},
459        {0,5,1},
460        {11,6,7},
461        {11,7,8},
462        {11,8,9},
463        {11,9,10},
464        {11,10,6},
465        {1,2,6},
466        {2,3,7},
467        {3,4,8},
468        {4,5,9},
469        {5,1,10},
470        {6,7,2},
471        {7,8,3},
472        {8,9,4},
473        {9,10,5},
474        {10,6,1} };
475#endif
476   
477    if (r < 0.0f) return;
478
479    vertices[0][0]=0.0;
480    vertices[0][1]=0.0;
481    vertices[0][2]=r;
482
483    vertices[11][0]=0.0;
484    vertices[11][1]=0.0;
485    vertices[11][2]=-r;
486   
487    for(i=1; i<6; i++)
488    {
489        vertices[i][0]=r*cos(the)*cos(phia);
490        vertices[i][1]=r*sin(the)*cos(phia);
491        vertices[i][2]=r*sin(phia);
492        the = the+the72;
493    }
494    the=theb;
495    for(i=6; i<11; i++)
496    {
497        vertices[i][0]=r*cos(the)*cos(-phia);
498        vertices[i][1]=r*sin(the)*cos(-phia);
499        vertices[i][2]=r*sin(-phia);
500        the = the+the72;
501    }
502   
503    // map vertices to 20 faces
504#ifdef DRAW_DEBUG
505   
506    for (i=0; i<20; i++) {
507       
508        glBegin(GL_POINTS );
509        glVertex3fv(&vertices[tindex[i][0]][0]);
510        glVertex3fv(&vertices[tindex[i][1]][0]);
511        glVertex3fv(&vertices[tindex[i][2]][0]);   
512        glEnd();
513    }
514
515#endif
516   
517    copyToCameras(cameras, 12, vertices);
518}
519
520void VMI::drawCube(Camera *cameras, GLdouble r) // any radius in which the polyhedron is inscribed
521{
522    GLdouble vertices[8][3] = {
523        {-1, -1, 1},   // vertex v0
524        {1,  -1, 1},   // vertex v1
525        {1,  -1, -1},  // vertex v2
526        {-1, -1, -1},  // vertex v3
527        {-1, 1,  1},   // vertex v4
528        {1,  1,  1},   // vertex v5
529        {1,  1,  -1},  // vertex v6
530        {-1, 1,  -1},  // vertex v7
531    }; // 8 vertices with x, y, z coordinates
532    int i;
533#ifdef DRAW_DEBUG
534    int tindex[12][3] = {
535       
536        {0, 1, 4}, //polygon v0,v1,v4
537        {1, 5, 4}, //polygon v1,v5,v4
538        {1, 2, 5}, //polygon v1,v2,v5
539        {2, 6, 5}, //polygon v2,v6,v5
540        {2, 3, 6}, //polygon v2,v3,v6
541        {3, 7, 6}, //polygon v3,v7,v6
542        {3, 0, 7}, //polygon v3,v0,v7
543        {0, 4, 7}, //polygon v0,v4,v7
544        {4, 5, 7}, //polygon v4,v5,v7
545        {5, 6, 7}, //polygon v5,v6,v7
546        {3, 2, 0}, //polygon v3,v2,v0
547        {2, 1, 0}, //polygon v2,v1,v0
548    };
549#endif
550   
551    for(i=0; i<8; i++)
552    {
553        vertices[i][0]*=r;
554        vertices[i][1]*=r;
555        vertices[i][2]*=r;
556    }
557
558    // map vertices to 12 faces
559#ifdef DRAW_DEBUG
560   
561    for (i=0; i<12; i++) {
562       
563        glBegin(GL_POINTS );
564        glVertex3fv(&vertices[tindex[i][0]][0]);
565        glVertex3fv(&vertices[tindex[i][1]][0]);
566        glVertex3fv(&vertices[tindex[i][2]][0]);   
567        glEnd();
568    }
569
570#endif
571   
572    copyToCameras(cameras, 8, vertices);
573}
574
Note: See TracBrowser for help on using the repository browser.