GRASS GIS 8 Programmer's Manual 8.4.1(2025)-45ca3179ab
Loading...
Searching...
No Matches
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.
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.
void Nviz_init_rotation(void)
Stop scene rotation.
void Nviz_get_viewpoint_position(double *x_pos, double *y_pos)
void Nviz_get_viewpoint_height(double *height)
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.
int Nviz_set_viewpoint_twist(int twist)
Change viewpoint twist.
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)
void Nviz_set_rotation(double angle, double x, double y, double z)
Set rotation parameters.
void Nviz_unset_rotation(void)
Stop scene rotation.
int Nviz_change_exag(nv_data *data, double exag)
Change z-exag value.
void Nviz_flythrough(nv_data *data UNUSED, float *fly_info, int *scale, int lateral)
Fly through the scene.
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)