1 /****************************************************************************/
2 /* This file is part of FreeFEM.                                            */
3 /*                                                                          */
4 /* FreeFEM is free software: you can redistribute it and/or modify          */
5 /* it under the terms of the GNU Lesser General Public License as           */
6 /* published by the Free Software Foundation, either version 3 of           */
7 /* the License, or (at your option) any later version.                      */
8 /*                                                                          */
9 /* FreeFEM is distributed in the hope that it will be useful,               */
10 /* but WITHOUT ANY WARRANTY; without even the implied warranty of           */
11 /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            */
12 /* GNU Lesser General Public License for more details.                      */
13 /*                                                                          */
14 /* You should have received a copy of the GNU Lesser General Public License */
15 /* along with FreeFEM. If not, see <http://www.gnu.org/licenses/>.          */
16 /****************************************************************************/
17 /* SUMMARY : ...                                                            */
18 /* LICENSE : LGPLv3                                                         */
19 /* ORG     : LJLL Universite Pierre et Marie Curie, Paris, FRANCE           */
20 /* AUTHORS : Pascal Frey                                                    */
21 /* E-MAIL  : pascal.frey@sorbonne-universite.fr                             */
22 
23 #ifdef __cplusplus
24 extern "C" {
25 #endif
26 
27 #include "medit.h"
28 #include "extern.h"
29 #include "sproto.h"
30 
Azimuth(pCamera c)31 double Azimuth(pCamera c) {
32   double dd, azim, cosazim, sinazim;
33 
34   dd = sqrt((double)c->speed[0] * c->speed[0] + (double)c->speed[2] * c->speed[2]);
35   cosazim = c->speed[2] / dd;
36   sinazim = c->speed[0] / dd;
37   azim = atan2(sinazim, cosazim) * RTOD;
38   return (azim);
39 }
40 
Elevation(pCamera c)41 double Elevation(pCamera c) {
42   double elev;
43 
44   elev = sqrt((double)c->speed[0] * c->speed[0] + (double)c->speed[2] * c->speed[2]);
45   elev = atan2(c->speed[1], elev) * RTOD;
46   return (elev);
47 }
48 
49 /* compute new sun position */
updateSun(pScene sc,pCamera c)50 void updateSun(pScene sc, pCamera c) {
51   double dd;
52   GLfloat axe[3], sunf[4];
53   GLdouble speed[3], sunp[4], matrix[16];
54 
55   axe[0] = c->speed[2];
56   axe[1] = 0.0f;
57   axe[2] = -c->speed[0];
58   dd = sqrt(axe[0] * axe[0] + axe[2] * axe[2]);
59   if (dd != 0.0f) {
60     axe[0] /= dd;
61     axe[2] /= dd;
62   }
63 
64   speed[0] = c->speed[0];
65   speed[1] = c->speed[1];
66   speed[2] = c->speed[2];
67 
68   glPushMatrix( );
69   glLoadIdentity( );
70   glRotatef(-30.0f, axe[0], axe[1], axe[2]);
71   glGetDoublev(GL_MODELVIEW_MATRIX, matrix);
72   glPopMatrix( );
73   transformPointd(sunp, speed, matrix);
74   sunf[0] = -sc->dmax * sunp[0];
75   sunf[1] = -sc->dmax * sunp[1];
76   sunf[2] = -sc->dmax * sunp[2];
77   sunf[3] = 0.0;
78 
79   glLightfv(GL_LIGHT0, GL_POSITION, sunf);
80 
81   if (ddebug) {
82     printf("    speed  %g %g %g\n", c->speed[0], c->speed[1], c->speed[2]);
83     printf("    axe    %g %g %g\n", axe[0], axe[1], axe[2]);
84     printf("    sunpos %g %g %g\n", sunp[0], sunp[1], sunp[2]);
85   }
86 }
87 
updateCamera(pScene sc,pCamera c,double azim,double elev)88 void updateCamera(pScene sc, pCamera c, double azim, double elev) {
89   double d, lazim, lelev;
90 
91   /* compute speed vector */
92   if (elev > 89.0f)
93     elev = 89.0;
94   else if (elev < -89.0f)
95     elev = -89.0;
96 
97   lazim = azim * DTOR;
98   lelev = elev * DTOR;
99   c->speed[0] = sin(lazim) * cos(lelev);
100   c->speed[1] = sin(lelev);
101   c->speed[2] = cos(lazim) * cos(lelev);
102 
103   d = (double)c->speed[0] * sc->par.sunpos[0] + c->speed[1] * sc->par.sunpos[1] +
104       c->speed[2] * sc->par.sunpos[2];
105   d = d / sqrt((double)sc->par.sunpos[0] * sc->par.sunpos[0] +
106                sc->par.sunpos[1] * sc->par.sunpos[1] + sc->par.sunpos[2] * sc->par.sunpos[2]);
107   d = acos(d);
108   if (fabs(d) > 0.10 * sc->persp->fovy * DTOR) updateSun(sc, c);
109 }
110 
initCamera(pScene sc,int up)111 pCamera initCamera(pScene sc, int up) {
112   pCamera c;
113   pMesh mesh;
114   double dd;
115 
116   if (ddebug) printf("    initCamera dmax %g\n", sc->dmax);
117 
118   if (sc->camera) {
119     c = sc->camera;
120   } else {
121     c = (pCamera)M_calloc(1, sizeof(struct camera), "camera");
122     if (!c) {
123       printf("  ## unable to allocate memory / camera\n");
124       exit(1);
125     }
126   }
127 
128   /* adjust coeffs */
129   mesh = cv.mesh[sc->idmesh];
130   c->eye[0] = c->eye[1] = 0.0;
131   c->eye[2] = sc->dmax;
132 
133   c->vecup = up;
134 
135   c->speed[0] = 0.0;
136   c->speed[1] = 0.0;
137   c->speed[2] = c->eye[2];
138   dd = -1.0 / sqrt(c->speed[2] * c->speed[2]);
139   c->speed[2] *= dd;
140   c->spmod = 0.01 * sc->dmax;
141   c->altinc = 0.01 * (mesh->ymax - mesh->ymin);
142 
143   /* set sun position */
144   updateSun(sc, c);
145 
146   if (ddebug) {
147     double look[3];
148 
149     look[0] = c->eye[0] + sc->dmax * c->speed[0];
150     look[1] = c->eye[1] + sc->dmax * c->speed[1];
151     look[2] = c->eye[2] + sc->dmax * c->speed[2];
152     printf("    eye   %g %g %g\n", c->eye[0], c->eye[1], c->eye[2]);
153     printf("    speed %g %g %g\n", c->speed[0], c->speed[1], c->speed[2]);
154     printf("    look  %g %g %g\n", look[0], look[1], look[2]);
155   }
156 
157   return (c);
158 }
159 
160 #ifdef __cplusplus
161 }
162 #endif
163