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