GRASS GIS 8 Programmer's Manual 8.3.0(2023)-exported
change_view.c
Go to the documentation of this file.
1/*!
2 \file lib/nviz/change_view.c
3
4 \brief Nviz library -- Change view settings
5
6 Based on visualization/nviz/src/change_view.c
7
8 (C) 2008, 2010 by the GRASS Development Team
9 This program is free software under the GNU General Public License
10 (>=v2). Read the file COPYING that comes with GRASS for details.
11
12 \author Updated/modified by Martin Landa <landa.martin gmail.com> (Google SoC
13 2008/2010)
14 */
15
16#include <math.h>
17
18#include <grass/glocale.h>
19#include <grass/nviz.h>
20
21/*!
22 \brief GL canvas resized
23
24 \param width window width
25 \param height window height
26
27 \return 1 on success
28 \return 0 on failure (window resized by default to 20x20 px)
29 */
30int Nviz_resize_window(int width, int height)
31{
32 int ret;
33
34 ret = 1;
35
36 if (width < 1 || height < 1) {
37 width = 20;
38 height = 20;
39 ret = 0;
40 }
41
42 G_debug(1, "Nviz_resize_window(): width = %d height = %d", width, height);
43 GS_set_viewport(0, width, 0, height);
44
45 /* GS_clear(0x0000FF); causes red flash - debug only */
46 GS_set_draw(GSD_BACK);
50
51 return ret;
52}
53
54/*!
55 \brief Update ranges
56
57 Call whenever a new surface is added, deleted, or exag changes
58
59 \return 1
60 */
61int Nviz_update_ranges(nv_data *dc)
62{
63 float zmin, zmax, exag;
64
65 GS_get_longdim(&(dc->xyrange));
66
67 dc->zrange = 0.;
68
69 /* Zrange is based on a minimum of Longdim */
70 if (GS_global_exag()) {
71 exag = GS_global_exag();
72 dc->zrange = dc->xyrange / exag;
73 }
74 else {
75 exag = 1.0;
76 }
77
78 GS_get_zrange_nz(&zmin, &zmax); /* actual */
79
80 zmax = zmin + (3. * dc->xyrange / exag);
81 zmin = zmin - (2. * dc->xyrange / exag);
82
83 if ((zmax - zmin) > dc->zrange)
84 dc->zrange = zmax - zmin;
85
86 return 1;
87}
88
89/*!
90 \brief Change position of view
91
92 \param x_pos x position (model coordinates)
93 \param y_pos y position (model coordinates)
94
95 \return 1
96 */
97int Nviz_set_viewpoint_position(double x_pos, double y_pos)
98{
99 float xpos, ypos, from[3];
100 float tempx, tempy;
101
102 xpos = x_pos;
103 xpos = (xpos < 0) ? 0 : (xpos > 1.0) ? 1.0 : xpos;
104 ypos = 1.0 - y_pos;
105 ypos = (ypos < 0) ? 0 : (ypos > 1.0) ? 1.0 : ypos;
106
107 if (x_pos < 0.0 || x_pos > 1.0 || y_pos < 0.0 || y_pos > 1.0) {
108 G_debug(3, "Invalid view position coordinates, using %f,%f", xpos,
109 1.0 - ypos);
110 }
111
112 G_debug(1, "Nviz_set_viewpoint_position(): x = %f y = %f", x_pos, y_pos);
113 GS_get_from(from);
114
115 tempx = xpos * RANGE - RANGE_OFFSET;
116 tempy = ypos * RANGE - RANGE_OFFSET;
117
118 if ((from[X] != tempx) || (from[Y] != tempy)) {
119
120 from[X] = tempx;
121 from[Y] = tempy;
122
123 GS_moveto(from);
124
125 /* Nviz_draw_quick(data); */
126 }
127
128 return 1;
129}
130
131void Nviz_get_viewpoint_position(double *x_pos, double *y_pos)
132{
133 float from[3];
134 double xpos, ypos;
135
136 GS_get_from(from);
137 xpos = (from[X] + RANGE_OFFSET) / RANGE;
138 ypos = (from[Y] + RANGE_OFFSET) / RANGE;
139 *x_pos = xpos;
140 *x_pos = (*x_pos < 0) ? 0 : (*x_pos > 1.0) ? 1.0 : *x_pos;
141 *y_pos = 1.0 - ypos;
142 *y_pos = (*y_pos < 0) ? 0 : (*y_pos > 1.0) ? 1.0 : *y_pos;
143
144 if (xpos < 0.0 || xpos > 1.0 || ypos < 0.0 || ypos > 1.0) {
145 G_debug(3, "Invalid view position coordinates, using %f,%f", *x_pos,
146 1.0 - *y_pos);
147 }
148}
149
150/*!
151 \brief Change viewpoint height
152
153 \param height height value (world coordinates)
154
155 \return 1
156 */
158{
159 float from[3];
160
161 G_debug(1, "Nviz_set_viewpoint_height(): value = %f", height);
162
163 GS_get_from_real(from);
164
165 if (height != from[Z]) {
166 from[Z] = height;
167
168 GS_moveto_real(from);
169
170 /*
171 normalize (from);
172 GS_setlight_position(1, from[X], from[Y], from[Z], 0);
173 */
174
175 /* Nviz_draw_quick(data); */
176 }
177
178 return 1;
179}
180
181void Nviz_get_viewpoint_height(double *height)
182{
183 float from[3];
184
185 G_debug(1, "Nviz_get_viewpoint_height():");
186
187 GS_get_from_real(from);
188
189 *height = from[Z];
190}
191
192/*!
193 \brief Change viewpoint perspective (field of view)
194
195 \param persp perspective value (0-100, in degrees)
196
197 \return 1
198 */
200{
201 int fov;
202
203 G_debug(1, "Nviz_set_viewpoint_persp(): value = %d", persp);
204
205 fov = (int)(10 * persp);
206 GS_set_fov(fov);
207
208 /* Nviz_draw_quick(data); */
209
210 return 1;
211}
212
213/*!
214 \brief Change viewpoint twist
215
216 \param twist persp twist value (-180-180, in degrees)
217
218 \return 1
219 */
221{
222 G_debug(1, "Nviz_set_viewpoint_twist(): value = %d", twist);
223 GS_set_twist(10 * twist);
224
225 /* Nviz_draw_quick(data); */
226
227 return 1;
228}
229
230/*!
231 \brief Change z-exag value
232
233 \param data nviz data
234 \param exag exag value
235
236 \return 1
237 */
238int Nviz_change_exag(nv_data *data, double exag)
239{
240 double temp;
241
242 G_debug(1, "Nviz_change_exag(): value = %f", exag);
243 temp = GS_global_exag();
244
245 if (exag != temp) {
246 GS_set_global_exag(exag);
247 Nviz_update_ranges(data);
248
249 /* Nviz_draw_quick(data); */
250 }
251
252 return 1;
253}
254
255/*!
256 \brief Change focused point
257
258 \param sx,sy screen coordinates
259
260 \return 1
261 */
262int Nviz_look_here(double sx, double sy)
263{
264 G_debug(1, "Nviz_look_here(): screen coordinates = %f %f", sx, sy);
265 GS_look_here(sx, sy);
266 return 1;
267}
268
269/*!
270 \brief Get current modelview matrix
271 */
272void Nviz_get_modelview(double *modelMatrix)
273{
274 glGetDoublev(GL_MODELVIEW_MATRIX, modelMatrix);
275}
276
277/*!
278 \brief Set rotation parameters
279
280 Rotate scene by given parameters related to mouse drag event
281 (difference from current state).
282 Coordinates determine the second point of rotation axis,
283 the first point is (0, 0, 0).
284
285 \param angle angle
286 \param x,y,z axis coordinate
287 */
288void Nviz_set_rotation(double angle, double x, double y, double z)
289{
290 G_debug(3, "Nviz_set_rotation(): angle = %f, x = %f, y = %f, z = %f", angle,
291 x, y, z);
292 GS_set_rotation(angle, x, y, z);
293}
294
295/*!
296 \brief Stop scene rotation
297 */
299{
301}
302
303/*!
304 \brief Stop scene rotation
305 */
307{
309}
310
311/*!
312 \brief Fly through the scene
313
314 Computes parameters needed for moving scene.
315 Changes viewpoint and viewdir.
316 Based on visualization/nviz/src/togl_flythrough.c and simplified.
317
318 \param data nviz data [unused]
319 \param fly_info values computed from mouse movement
320 \param scale rate of movement
321 \param lateral type of movement
322
323 */
324void Nviz_flythrough(nv_data *data UNUSED, float *fly_info, int *scale,
325 int lateral)
326{
327 float dir[3], from[4], cur_from[4], cur_dir[4];
328 float speed, h, p, sh, ch, sp, cp;
329 float diff_x, diff_y, diff_z;
330 float quasi_zero;
331
332 quasi_zero = 0.0001;
333
334 GS_get_from(cur_from);
335 GS_get_viewdir(cur_dir);
336
337 p = asin(cur_dir[Z]);
338 h = atan2(-cur_dir[X], -cur_dir[Y]);
339
340 speed = scale[0] * fly_info[0];
341
342 h += scale[1] * fly_info[1]; /* change heading */
343 if (!lateral) /* in case of "lateral" doesn't change pitch */
344 p -= scale[1] * fly_info[2];
345
346 h = fmod(h + M_PI, 2 * M_PI) - M_PI;
347
348 sh = sin(h);
349 ch = cos(h);
350 sp = sin(p);
351 cp = cos(p);
352
353 dir[X] = -sh * cp;
354 dir[Y] = -ch * cp;
355 dir[Z] = sp;
356
357 if (lateral) {
358 from[X] = cur_from[X] + speed * dir[Y];
359 from[Y] = cur_from[Y] - speed * dir[X];
360 from[Z] = cur_from[Z] + scale[0] * fly_info[2];
361 }
362 else {
363 from[X] = cur_from[X] + speed * dir[X];
364 from[Y] = cur_from[Y] + speed * dir[Y];
365 /* not sure how this should behave (change Z coord or not ?) */
366 from[Z] = cur_from[Z]; /* + speed * dir[Z] */
367 }
368
369 diff_x = fabs(cur_dir[X] - dir[X]);
370 diff_y = fabs(cur_dir[Y] - dir[Y]);
371 diff_z = fabs(cur_dir[Z] - dir[Z]);
372
373 if (/* something has changed */
374 (diff_x > quasi_zero) || (diff_y > quasi_zero) ||
375 (diff_z > quasi_zero) || (cur_from[X] != from[X]) ||
376 (cur_from[Y] != from[Y]) || (cur_from[Z] != from[Z])) {
377 GS_moveto(from);
378 GS_set_viewdir(dir); /* calls gsd_set_view */
379 }
380}
int Nviz_set_viewpoint_height(double height)
Change viewpoint height.
Definition: change_view.c:157
int Nviz_update_ranges(nv_data *dc)
Update ranges.
Definition: change_view.c:61
int Nviz_look_here(double sx, double sy)
Change focused point.
Definition: change_view.c:262
void Nviz_init_rotation(void)
Stop scene rotation.
Definition: change_view.c:306
void Nviz_get_viewpoint_position(double *x_pos, double *y_pos)
Definition: change_view.c:131
void Nviz_get_viewpoint_height(double *height)
Definition: change_view.c:181
int Nviz_resize_window(int width, int height)
GL canvas resized.
Definition: change_view.c:30
void Nviz_get_modelview(double *modelMatrix)
Get current modelview matrix.
Definition: change_view.c:272
int Nviz_set_viewpoint_twist(int twist)
Change viewpoint twist.
Definition: change_view.c:220
int Nviz_set_viewpoint_position(double x_pos, double y_pos)
Change position of view.
Definition: change_view.c:97
int Nviz_set_viewpoint_persp(int persp)
Change viewpoint perspective (field of view)
Definition: change_view.c:199
void Nviz_set_rotation(double angle, double x, double y, double z)
Set rotation parameters.
Definition: change_view.c:288
void Nviz_unset_rotation(void)
Stop scene rotation.
Definition: change_view.c:298
int Nviz_change_exag(nv_data *data, double exag)
Change z-exag value.
Definition: change_view.c:238
void Nviz_flythrough(nv_data *data UNUSED, float *fly_info, int *scale, int lateral)
Fly through the scene.
Definition: change_view.c:324
int G_debug(int level, const char *msg,...)
Print debugging message.
Definition: debug.c:66
void GS_set_global_exag(float exag)
Set global z-exag value.
Definition: gs2.c:1975
void GS_get_zrange_nz(float *min, float *max)
Get Z extents for all loaded surfaces.
Definition: gs2.c:2355
void GS_get_from(float *fr)
Get viewpoint 'from' position.
Definition: gs2.c:2721
void GS_get_viewdir(float *dir)
Get viewdir.
Definition: gs2.c:2804
void GS_alldraw_wire(void)
Draw all wires.
Definition: gs2.c:1917
void GS_init_rotation(void)
Reset scene rotation.
Definition: gs2.c:2904
int GS_look_here(int sx, int sy)
Send screen coords sx and sy, lib traces through surfaces; sets new center to point of nearest inters...
Definition: gs2.c:3002
void GS_set_viewdir(float *dir)
Set viewdir.
Definition: gs2.c:2818
void GS_moveto(float *pt)
Move viewpoint.
Definition: gs2.c:2613
void GS_unset_rotation(void)
Stop scene rotation.
Definition: gs2.c:2896
void GS_set_rotation(double angle, double x, double y, double z)
Set rotation params.
Definition: gs2.c:2882
void GS_ready_draw(void)
Definition: gs2.c:2485
void GS_set_draw(int where)
Sets which buffer to draw to.
Definition: gs2.c:2459
void GS_moveto_real(float *pt)
Move position to (real)
Definition: gs2.c:2643
void GS_get_from_real(float *fr)
Get viewpoint 'from' real coordinates.
Definition: gs2.c:2735
int GS_get_longdim(float *dim)
Get largest dimension.
Definition: gs2.c:140
void GS_set_viewport(int left, int right, int bottom, int top)
Set viewport.
Definition: gs2.c:2976
void GS_done_draw(void)
Draw done, swap buffers.
Definition: gs2.c:2498
void GS_set_fov(int fov)
Set field of view.
Definition: gs2.c:2838
void GS_set_twist(int t)
Set viewpoint twist value.
Definition: gs2.c:2872
float GS_global_exag(void)
Get global z-exag value.
Definition: gs2.c:1997
#define X(j)
#define x
#define Y(j)