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