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