GRASS GIS 8 Programmer's Manual  8.5.0dev(2024)-847944e18e
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  */
30 int 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 */
47  GS_ready_draw();
49  GS_done_draw();
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  */
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  */
97 int 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 
131 void 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  */
157 int Nviz_set_viewpoint_height(double height)
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 
181 void 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  */
238 int 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  */
262 int 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  */
272 void 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  */
288 void 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  */
324 void 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, const char *,...) __attribute__((format(printf
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:3002
void GS_set_rotation(double, double, double, double)
Set rotation params.
Definition: gs2.c:2882
void GS_set_fov(int)
Set field of view.
Definition: gs2.c:2838
void GS_get_viewdir(float *)
Get viewdir.
Definition: gs2.c:2804
void GS_set_draw(int)
Sets which buffer to draw to.
Definition: gs2.c:2459
void GS_get_from(float *)
Get viewpoint 'from' position.
Definition: gs2.c:2721
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_get_longdim(float *)
Get largest dimension.
Definition: gs2.c:140
void GS_get_from_real(float *)
Get viewpoint 'from' real coordinates.
Definition: gs2.c:2735
void GS_set_twist(int)
Set viewpoint twist value.
Definition: gs2.c:2872
void GS_set_viewdir(float *)
Set viewdir.
Definition: gs2.c:2818
void GS_get_zrange_nz(float *, float *)
Get Z extents for all loaded surfaces.
Definition: gs2.c:2355
void GS_moveto(float *)
Move viewpoint.
Definition: gs2.c:2613
void GS_unset_rotation(void)
Stop scene rotation.
Definition: gs2.c:2896
void GS_ready_draw(void)
Definition: gs2.c:2485
void GS_set_global_exag(float)
Set global z-exag value.
Definition: gs2.c:1975
void GS_moveto_real(float *)
Move position to (real)
Definition: gs2.c:2643
void GS_done_draw(void)
Draw done, swap buffers.
Definition: gs2.c:2498
void GS_set_viewport(int, int, int, int)
Set viewport.
Definition: gs2.c:2976
float GS_global_exag(void)
Get global z-exag value.
Definition: gs2.c:1997
#define UNUSED
A macro for an attribute, if attached to a variable, indicating that the variable is not used.
Definition: gis.h:47
#define M_PI
Definition: gis.h:158
#define RANGE_OFFSET
Definition: nviz.h:59
#define RANGE
Definition: nviz.h:58
#define X
Definition: ogsf.h:140
#define Z
Definition: ogsf.h:142
#define Y
Definition: ogsf.h:141
#define GSD_BACK
Definition: ogsf.h:105
Definition: nviz.h:97
float xyrange
Definition: nviz.h:99
float zrange
Definition: nviz.h:99
#define x