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

Revision 983, 13.5 KB checked in by gumbau, 18 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, 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                                                      &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, 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
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, 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
212void 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
220void 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     
232void 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
295void 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
377void 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
433void 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}
Note: See TracBrowser for help on using the repository browser.