GRASS 8 Programmer's Manual 8.6.0dev(2026)-8843f13794
Loading...
Searching...
No Matches
gsd_views.c
Go to the documentation of this file.
1/*!
2 \file lib/ogsf/gsd_views.c
3
4 \brief OGSF library - manipulating views (lower level functions)
5
6 GRASS OpenGL gsurf OGSF Library
7
8 SPDX-FileCopyrightText: 1999-2008 GRASS Development Team
9 SPDX-License-Identifier: GPL-2.0-or-later
10
11 \author Bill Brown USACERL (January 1993)
12 \author Doxygenized by Martin Landa <landa.martin gmail.com> (May 2008)
13 */
14
15#include <grass/config.h>
16
17#if defined(OPENGL_X11) || defined(OPENGL_WINDOWS)
18#include <GL/gl.h>
19#include <GL/glu.h>
20#elif defined(OPENGL_AQUA)
21#include <OpenGL/gl.h>
22#include <OpenGL/glu.h>
23#endif
24
25#include <grass/ogsf.h>
26#include "math.h"
27
28/*!
29 \brief ADD
30
31 \param vect
32 \param sx, sy screen coordinates
33
34 \return 1
35 */
36int gsd_get_los(float (*vect)[3], short sx, short sy)
37{
38 double fx, fy, fz, tx, ty, tz;
40 GLint viewport[4];
41
44
45 gsd_do_scale(1);
50
51 /* OGLXXX XXX I think this is backwards gluProject(XXX); */
52 /* WAS: mapw(Vobj, sx, sy, &fx, &fy, &fz, &tx, &ty, &tz); */
54 viewport, &fx, &fy, &fz);
56 viewport, &tx, &ty, &tz);
57 vect[FROM][X] = fx;
58 vect[FROM][Y] = fy;
59 vect[FROM][Z] = fz;
60 vect[TO][X] = tx;
61 vect[TO][Y] = ty;
62 vect[TO][Z] = tz;
63
64 /* DEBUG - should just be a dot */
65 /* OGLXXX frontbuffer: other possibilities include GSD_BOTH */
68 gsd_do_scale(1);
70 gsd_color_func(0x8888FF);
71
72 /* OGLXXX for multiple, independent line segments: use GL_LINES */
74 glVertex3fv(vect[FROM]);
75 glVertex3fv(vect[TO]);
76 glEnd();
77
80
81 /* OGLXXX frontbuffer: other possibilities include GSD_BOTH */
83
84 return (1);
85}
86
87#if 0
88/*!
89 \brief Set view
90
91 Establishes viewing & projection matrices
92
93 \param gv view (geoview)
94 \param dp display (geodisplay)
95 */
97{
98 double up[3];
99 GLint mm;
100
101 /* will expand when need to check for in focus, ortho, etc. */
102
104 gsd_get_zup(gv, up);
105
106 gd->aspect = GS_get_aspect();
107
111 gluPerspective((double).1 * (gv->fov), (double)gd->aspect,
112 (double)gd->nearclip, (double)gd->farclip);
113
115
117
118 /* update twist parm */
119 glRotatef((float)(gv->twist / 10.), 0.0, 0.0, 1.0);
120
121 /* OGLXXX lookat: replace UPx with vector */
122 gluLookAt((double)gv->from_to[FROM][X], (double)gv->from_to[FROM][Y],
123 (double)gv->from_to[FROM][Z], (double)gv->from_to[TO][X],
124 (double)gv->from_to[TO][Y], (double)gv->from_to[TO][Z],
125 (double)up[X], (double)up[Y], (double)up[Z]);
126
127 /* have to redefine clipping planes when view changes */
128
130
131 return;
132}
133#endif
134/*!
135 \brief Set view
136
137 Establishes viewing & projection matrices
138
139 \param gv view (geoview)
140 \param gd display (geodisplay)
141 */
143{
144 double up[3];
145 float pos[3];
146 int i;
148 GLint mm;
149
150 /* will expand when need to check for in focus, ortho, etc. */
151
153 gsd_get_zup(gv, up);
154
155 gd->aspect = GS_get_aspect();
156
160 gluPerspective((double).1 * (gv->fov), (double)gd->aspect,
161 (double)gd->nearclip, (double)gd->farclip);
162
164
166
167 /* update twist parm */
168 glRotatef((float)(gv->twist / 10.), 0.0, 0.0, 1.0);
169
170 /* OGLXXX lookat: replace UPx with vector */
171 gluLookAt((double)gv->from_to[FROM][X], (double)gv->from_to[FROM][Y],
172 (double)gv->from_to[FROM][Z], (double)gv->from_to[TO][X],
173 (double)gv->from_to[TO][Y], (double)gv->from_to[TO][Z],
174 (double)up[X], (double)up[Y], (double)up[Z]);
175
176 /* rotate to get rotation matrix and then save it */
177 if (gv->rotate.do_rot) {
178
179 glPushMatrix();
180 glLoadMatrixd(gv->rotate.rotMatrix);
181
182 glRotated(gv->rotate.rot_angle, gv->rotate.rot_axes[0],
183 gv->rotate.rot_axes[1], gv->rotate.rot_axes[2]);
185
186 for (i = 0; i < 16; i++) {
187 gv->rotate.rotMatrix[i] = modelMatrix[i];
188 }
189
190 glPopMatrix();
191 }
192
194 gsd_surf2model(pos);
195 /* translate rotation center to view center, rotate and translate back */
196 glTranslatef(pos[0], pos[1], pos[2]);
197 glMultMatrixd(gv->rotate.rotMatrix);
198 glTranslatef(-pos[0], -pos[1], -pos[2]);
199
200 /* have to redefine clipping planes when view changes */
201
203
204 return;
205}
206
207/*!
208 \brief Check focus
209
210 \param gv view (geoview)
211 */
213{
214 float zmax, zmin;
215
216 GS_get_zrange(&zmin, &zmax, 0);
217
218 if (gv->infocus) {
219 GS_v3eq(gv->from_to[TO], gv->real_to);
220 gv->from_to[TO][Z] -= zmin;
221 GS_v3mult(gv->from_to[TO], gv->scale);
222 gv->from_to[TO][Z] *= gv->vert_exag;
223
224 GS_v3normalize(gv->from_to[FROM], gv->from_to[TO]);
225 }
226
227 return;
228}
229
230/*!
231 \brief Get z-up vector (z-direction)
232
233 \param gv view (geoview)
234 \param up up vector
235 */
236void gsd_get_zup(geoview *gv, double *up)
237{
238 float alpha;
239 float zup[3], fup[3];
240
241 /* neg alpha OK since sin(-x) = -sin(x) */
242 alpha = (2.0 * atan(1.0)) - acos(gv->from_to[FROM][Z] - gv->from_to[TO][Z]);
243
244 zup[X] = gv->from_to[TO][X];
245 zup[Y] = gv->from_to[TO][Y];
246
247 if (sin(alpha)) {
248 zup[Z] = gv->from_to[TO][Z] + 1 / sin(alpha);
249 }
250 else {
251 zup[Z] = gv->from_to[FROM][Z] + 1.0;
252 }
253
254 GS_v3dir(gv->from_to[FROM], zup, fup);
255
256 up[X] = fup[X];
257 up[Y] = fup[Y];
258 up[Z] = fup[Z];
259
260 return;
261}
262
263/*!
264 \brief ADD
265
266 \param gv view (geoview)
267
268 \return ?
269 */
271{
272 float fr_to[2][4];
273 float look_theta, pi;
274 float alpha, beta;
275 float zup[3], yup[3], zupmag, yupmag;
276
277 pi = 4.0 * atan(1.0);
278
279 /* *************************************************************** */
280 /* This block of code is used to keep pos z in the up direction,
281 * correcting for SGI system default which is pos y in the up
282 * direction. Involves finding up vectors for both y up and
283 * z up, then determining angle between them. LatLon mode uses y as
284 * up direction instead of z, so no correction necessary. Next rewrite,
285 * we should use y as up for all drawing.
286 */
287 GS_v3eq(fr_to[FROM], gv->from_to[FROM]);
288 GS_v3eq(fr_to[TO], gv->from_to[TO]);
289
290 /* neg alpha OK since sin(-x) = -sin(x) */
291 alpha = pi / 2.0 - acos(fr_to[FROM][Z] - fr_to[TO][Z]);
292
293 zup[X] = fr_to[TO][X];
294 zup[Y] = fr_to[TO][Y];
295
296 if (sin(alpha)) {
297 zup[Z] = fr_to[TO][Z] + 1 / sin(alpha);
298 }
299 else {
300 zup[Z] = fr_to[FROM][Z] + 1.0;
301 }
302
304
305 yup[X] = fr_to[TO][X];
306 yup[Z] = fr_to[TO][Z];
307
308 /* neg beta OK since sin(-x) = -sin(x) */
309 beta = pi / 2.0 - acos(fr_to[TO][Y] - fr_to[FROM][Y]);
310
311 if (sin(beta)) {
312 yup[Y] = fr_to[TO][Y] - 1 / sin(beta);
313 }
314 else {
315 yup[Y] = fr_to[FROM][Y] + 1.0;
316 }
317
319
320 look_theta = (1800.0 / pi) *
321 acos(((zup[X] - fr_to[FROM][X]) * (yup[X] - fr_to[FROM][X]) +
322 (zup[Y] - fr_to[FROM][Y]) * (yup[Y] - fr_to[FROM][Y]) +
323 (zup[Z] - fr_to[FROM][Z]) * (yup[Z] - fr_to[FROM][Z])) /
324 (zupmag * yupmag));
325
326 if (fr_to[TO][X] - fr_to[FROM][X] < 0.0) {
328 }
329
330 if (fr_to[TO][Z] - fr_to[FROM][Z] < 0.0) {
331 /* looking down */
332 if (fr_to[TO][Y] - fr_to[FROM][Y] < 0.0) {
333 look_theta = 1800 - look_theta;
334 }
335 }
336 else {
337 /* looking up */
338 if (fr_to[TO][Y] - fr_to[FROM][Y] > 0.0) {
339 look_theta = 1800 - look_theta;
340 }
341 }
342
343 return ((int)(gv->twist + 1800 + look_theta));
344}
345
346/*!
347 \brief Set current scale
348
349 \param doexag use z-exaggeration
350 */
352{
353 float sx, sy, sz;
354 float min, max;
355
356 GS_get_scale(&sx, &sy, &sz, doexag);
357 gsd_scale(sx, sy, sz);
358 GS_get_zrange(&min, &max, 0);
359 gsd_translate(0.0, 0.0, -min);
360
361 return;
362}
363
364/*!
365 \brief Convert real to model coordinates
366
367 \param[in,out] point 3d point (Point3)
368 */
370{
371 float sx, sy, sz;
372 float min, max, n, s, w, e;
373
374 GS_get_region(&n, &s, &w, &e);
375 GS_get_scale(&sx, &sy, &sz, 1);
376 GS_get_zrange(&min, &max, 0);
377 point[X] = (point[X] - w) * sx;
378 point[Y] = (point[Y] - s) * sy;
379 point[Z] = (point[Z] - min) * sz;
380
381 return;
382}
383
384/*!
385 \brief Convert model to real coordinates
386
387 \param[in,out] point 3d point (x,y,z)
388 */
390{
391 float sx, sy, sz;
392 float min, max, n, s, w, e;
393
394 GS_get_region(&n, &s, &w, &e);
395 GS_get_scale(&sx, &sy, &sz, 1);
396 GS_get_zrange(&min, &max, 0);
397 point[X] = (sx ? point[X] / sx : 0.0) + w;
398 point[Y] = (sy ? point[Y] / sy : 0.0) + s;
399 point[Z] = (sz ? point[Z] / sz : 0.0) + min;
400
401 return;
402}
403
404/*!
405 \brief Convert model to surface coordinates
406
407 \param gs surface (geosurf)
408 \param point 3d point (Point3)
409 */
411{
412 float min, max, sx, sy, sz;
413
414 /* so far, only one geographic "region" allowed, so origin of
415 surface is same as origin of model space, but will need to provide
416 translations here to make up the difference, so not using gs yet */
417
418 if (gs) {
419 /* need to undo z scaling & translate */
420 GS_get_scale(&sx, &sy, &sz, 1);
421 GS_get_zrange(&min, &max, 0);
422
423 point[Z] = (sz ? point[Z] / sz : 0.0) + min;
424
425 /* need to unscale x & y */
426 point[X] = (sx ? point[X] / sx : 0.0);
427 point[Y] = (sy ? point[Y] / sy : 0.0);
428 }
429
430 return;
431}
432
433/*!
434 \brief Convert surface to model coordinates
435
436 \param point 3d point (Point3)
437 */
439{
440 float min, max, sx, sy, sz;
441
442 /* need to undo z scaling & translate */
443 GS_get_scale(&sx, &sy, &sz, 1);
444 GS_get_zrange(&min, &max, 0);
445
446 point[Z] = (sz ? (point[Z] - min) * sz : 0.0f);
447
448 /* need to unscale x & y */
449 point[X] = (sx ? point[X] * sx : 0.0f);
450 point[Y] = (sy ? point[Y] * sy : 0.0f);
451
452 return;
453}
454
455/*!
456 \brief Convert surface to real coordinates
457
458 \param gs surface (geosurf)
459 \param[in,out] point 3d point (Point3)
460 */
462{
463 if (gs) {
464 point[X] += gs->ox;
465 point[Y] += gs->oy;
466 }
467
468 return;
469}
470
471/*!
472 \brief Convert real to surface coordinates
473
474 \param gs surface (geosurf)
475 \param[in,out] point 3d point (Point3)
476 */
478{
479 if (gs) {
480 point[X] -= gs->ox;
481 point[Y] -= gs->oy;
482 }
483
484 return;
485}
void GS_v3mult(float *, float)
Multiple vectors.
Definition gs_util.c:225
int GS_get_region(float *, float *, float *, float *)
Get 2D region extent.
Definition gs2.c:152
void GS_set_draw(int)
Sets which buffer to draw to.
Definition gs2.c:2458
void gsd_scale(float, float, float)
Multiply the current matrix by a general scaling matrix.
Definition gsd_prim.c:521
double GS_get_aspect(void)
Get aspect value.
Definition gs2.c:3446
int GS_get_zrange(float *, float *, int)
Get z-extent for all loaded surfaces.
Definition gs2.c:2684
int GS_v3normalize(float *, float *)
Change v2 so that v1v2 is a unit vector.
Definition gs_util.c:317
int gs_get_datacenter(float *)
Get data center point.
Definition gs.c:1226
void GS_v3eq(float *, float *)
Copy vector values.
Definition gs_util.c:174
void gsd_color_func(unsigned int)
Set current color.
Definition gsd_prim.c:694
void gsd_translate(float, float, float)
Multiply the current matrix by a translation matrix.
Definition gsd_prim.c:535
void GS_ready_draw(void)
Definition gs2.c:2484
void gsd_linewidth(short)
Set width of rasterized lines.
Definition gsd_prim.c:263
void GS_get_scale(float *, float *, float *, int)
Get axis scale.
Definition gs2.c:3235
int GS_v3dir(float *, float *, float *)
Get a normalized direction from v1 to v2, store in v3.
Definition gs_util.c:347
float GS_distance(float *, float *)
Calculate distance.
Definition gs_util.c:137
void gsd_update_cplanes(void)
Update cplaces.
Definition gsd_cplane.c:82
#define min(x, y)
Definition draw2.c:29
#define max(x, y)
Definition draw2.c:30
void gsd_real2model(Point3 point)
Convert real to model coordinates.
Definition gsd_views.c:369
void gsd_surf2real(geosurf *gs, Point3 point)
Convert surface to real coordinates.
Definition gsd_views.c:461
void gsd_check_focus(geoview *gv)
Check focus.
Definition gsd_views.c:212
int gsd_zup_twist(geoview *gv)
ADD.
Definition gsd_views.c:270
int gsd_get_los(float(*vect)[3], short sx, short sy)
ADD.
Definition gsd_views.c:36
void gsd_real2surf(geosurf *gs, Point3 point)
Convert real to surface coordinates.
Definition gsd_views.c:477
void gsd_surf2model(Point3 point)
Convert surface to model coordinates.
Definition gsd_views.c:438
void gsd_model2real(Point3 point)
Convert model to real coordinates.
Definition gsd_views.c:389
void gsd_model2surf(geosurf *gs, Point3 point)
Convert model to surface coordinates.
Definition gsd_views.c:410
void gsd_do_scale(int doexag)
Set current scale.
Definition gsd_views.c:351
void gsd_get_zup(geoview *gv, double *up)
Get z-up vector (z-direction)
Definition gsd_views.c:236
void gsd_set_view(geoview *gv, geodisplay *gd)
Set view.
Definition gsd_views.c:142
OGSF header file (structures)
#define X
Definition ogsf.h:141
float Point3[3]
Definition ogsf.h:206
#define Z
Definition ogsf.h:143
#define GSD_FRONT
Definition ogsf.h:105
#define Y
Definition ogsf.h:142
#define GSD_BACK
Definition ogsf.h:106
#define FROM
Definition ogsf.h:145
#define TO
Definition ogsf.h:146
Definition ogsf.h:267