GRASS GIS 7 Programmer's Manual  7.9.dev(2021)-e5379bbd7
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  */
29 int 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 */
46  GS_ready_draw();
48  GS_done_draw();
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  */
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  */
96 int 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 
130 void 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  */
156 int Nviz_set_viewpoint_height(double height)
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 
180 void 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  */
236 int 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 */
259 int 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 */
269 void 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 */
285 void 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 */
320 void 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 GS_set_viewdir(float *)
Set viewdir.
Definition: gs2.c:2823
void GS_ready_draw(void)
Definition: gs2.c:2488
void Nviz_get_viewpoint_position(double *x_pos, double *y_pos)
Definition: change_view.c:130
void GS_set_viewport(int, int, int, int)
Set viewport.
Definition: gs2.c:2981
void GS_init_rotation(void)
Reset scene rotation.
Definition: gs2.c:2909
int GS_look_here(int, int)
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_rotation(double, double, double, double)
Set rotation params.
Definition: gs2.c:2887
int Nviz_resize_window(int width, int height)
GL canvas resized.
Definition: change_view.c:29
#define M_PI
Definition: gis.h:134
int Nviz_update_ranges(nv_data *dc)
Update ranges.
Definition: change_view.c:60
void Nviz_init_rotation(void)
Stop scene rotation.
Definition: change_view.c:302
#define x
void GS_get_from(float *)
Get viewpoint &#39;from&#39; position.
Definition: gs2.c:2725
int Nviz_set_viewpoint_persp(int persp)
Change viewpoint perspective (field of view)
Definition: change_view.c:197
void Nviz_flythrough(nv_data *data, float *fly_info, int *scale, int lateral)
Fly through the scene.
Definition: change_view.c:320
void GS_unset_rotation(void)
Stop scene rotation.
Definition: gs2.c:2901
void GS_moveto_real(float *)
Move position to (real)
Definition: gs2.c:2647
void GS_alldraw_wire(void)
Draw all wires.
Definition: gs2.c:1919
int Nviz_change_exag(nv_data *data, double exag)
Change z-exag value.
Definition: change_view.c:236
void Nviz_set_rotation(double angle, double x, double y, double z)
Set rotation parameters.
Definition: change_view.c:285
float zrange
Definition: nviz.h:104
void GS_get_zrange_nz(float *, float *)
Get Z extents for all loaded surfaces.
Definition: gs2.c:2357
void Nviz_get_modelview(double *modelMatrix)
Get current modelview matrix.
Definition: change_view.c:269
#define RANGE
Definition: nviz.h:58
float xyrange
Definition: nviz.h:104
void GS_set_twist(int)
Set viewpoint twist value.
Definition: gs2.c:2877
void GS_get_from_real(float *)
Get viewpoint &#39;from&#39; real coordinates.
Definition: gs2.c:2739
void Nviz_get_viewpoint_height(double *height)
Definition: change_view.c:180
void GS_done_draw(void)
Draw done, swap buffers.
Definition: gs2.c:2501
#define Z
Definition: ogsf.h:139
int Nviz_set_viewpoint_twist(int twist)
Change viewpoint twist.
Definition: change_view.c:218
float GS_global_exag(void)
Get global z-exag value.
Definition: gs2.c:1999
#define GSD_BACK
Definition: ogsf.h:102
#define Y
Definition: ogsf.h:138
int Nviz_look_here(double sx, double sy)
Change focused point.
Definition: change_view.c:259
int Nviz_set_viewpoint_position(double x_pos, double y_pos)
Change position of view.
Definition: change_view.c:96
void GS_get_viewdir(float *)
Get viewdir.
Definition: gs2.c:2809
Definition: nviz.h:101
void GS_moveto(float *)
Move viewpoint.
Definition: gs2.c:2617
#define RANGE_OFFSET
Definition: nviz.h:59
#define X
Definition: ogsf.h:137
int GS_get_longdim(float *)
Get largest dimension.
Definition: gs2.c:140
void Nviz_unset_rotation(void)
Stop scene rotation.
Definition: change_view.c:294
void GS_set_global_exag(float)
Set global z-exag value.
Definition: gs2.c:1977
void GS_set_draw(int)
Sets which buffer to draw to.
Definition: gs2.c:2462
int G_debug(int, const char *,...) __attribute__((format(printf
void GS_set_fov(int)
Set field of view.
Definition: gs2.c:2843