GRASS Programmer's Manual  6.5.svn(2012)-r51648
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines
change_view.c
Go to the documentation of this file.
00001 
00015 #include <math.h>
00016 
00017 #include <grass/glocale.h>
00018 #include <grass/nviz.h>
00019 
00029 int Nviz_resize_window(int width, int height)
00030 {
00031     int ret;
00032 
00033     ret = 1;
00034 
00035     if (width < 1 || height < 1) {
00036         width = 20;
00037         height = 20;
00038         ret = 0;
00039     }
00040 
00041     G_debug(1, "Nviz_resize_window(): width = %d height = %d", width, height);
00042     GS_set_viewport(0, width, 0, height);
00043 
00044     /*   GS_clear(0x0000FF); causes red flash - debug only */
00045     GS_set_draw(GSD_BACK);
00046     GS_ready_draw();
00047     GS_alldraw_wire();
00048     GS_done_draw();
00049 
00050     return ret;
00051 }
00052 
00060 int Nviz_update_ranges(nv_data * dc)
00061 {
00062     float zmin, zmax, exag;
00063 
00064     GS_get_longdim(&(dc->xyrange));
00065 
00066     dc->zrange = 0.;
00067 
00068     /* Zrange is based on a minimum of Longdim */
00069     if (GS_global_exag()) {
00070         exag = GS_global_exag();
00071         dc->zrange = dc->xyrange / exag;
00072     }
00073     else {
00074         exag = 1.0;
00075     }
00076 
00077     GS_get_zrange_nz(&zmin, &zmax);     /* actual */
00078 
00079     zmax = zmin + (3. * dc->xyrange / exag);
00080     zmin = zmin - (2. * dc->xyrange / exag);
00081 
00082     if ((zmax - zmin) > dc->zrange)
00083         dc->zrange = zmax - zmin;
00084 
00085     return 1;
00086 }
00087 
00096 int Nviz_set_viewpoint_position(double x_pos, double y_pos)
00097 {
00098     float xpos, ypos, from[3];
00099     float tempx, tempy;
00100 
00101     xpos = x_pos;
00102     xpos = (xpos < 0) ? 0 : (xpos > 1.0) ? 1.0 : xpos;
00103     ypos = 1.0 - y_pos;
00104     ypos = (ypos < 0) ? 0 : (ypos > 1.0) ? 1.0 : ypos;
00105 
00106     if (x_pos < 0.0 || x_pos > 1.0 || y_pos < 0.0 || y_pos > 1.0) {
00107         G_debug(3, "Invalid view position coordinates, using %f,%f",
00108                   xpos, 1.0 - ypos);
00109     }
00110 
00111     G_debug(1, "Nviz_set_viewpoint_position(): x = %f y = %f", x_pos, y_pos);
00112     GS_get_from(from);
00113 
00114     tempx = xpos * RANGE - RANGE_OFFSET;
00115     tempy = ypos * RANGE - RANGE_OFFSET;
00116 
00117     if ((from[X] != tempx) || (from[Y] != tempy)) {
00118 
00119         from[X] = tempx;
00120         from[Y] = tempy;
00121 
00122         GS_moveto(from);
00123 
00124         /* Nviz_draw_quick(data); */
00125     }
00126 
00127     return 1;
00128 }
00129 
00130 void Nviz_get_viewpoint_position(double *x_pos, double *y_pos)
00131 {
00132     float from[3];
00133     double xpos, ypos;
00134 
00135     GS_get_from(from);
00136     xpos = (from[X] + RANGE_OFFSET) / RANGE;
00137     ypos = (from[Y] + RANGE_OFFSET) / RANGE;
00138     *x_pos = xpos;
00139     *x_pos = (*x_pos < 0) ? 0 : (*x_pos > 1.0) ? 1.0 : *x_pos;
00140     *y_pos = 1.0 - ypos;
00141     *y_pos = (*y_pos < 0) ? 0 : (*y_pos > 1.0) ? 1.0 : *y_pos;
00142 
00143     if (xpos < 0.0 || xpos > 1.0 || ypos < 0.0 || ypos > 1.0) {
00144         G_debug(3, "Invalid view position coordinates, using %f,%f",
00145                   *x_pos, 1.0 - *y_pos);
00146     }
00147 }
00148 
00157 int Nviz_set_viewpoint_height(double height)
00158 {
00159     float from[3];
00160 
00161     G_debug(1, "Nviz_set_viewpoint_height(): value = %f", height);
00162 
00163     GS_get_from_real(from);
00164 
00165     if (height != from[Z]) {
00166         from[Z] = height;
00167 
00168         GS_moveto_real(from);
00169 
00170         /*
00171            normalize (from);
00172            GS_setlight_position(1, from[X], from[Y], from[Z], 0);
00173          */
00174 
00175         /* Nviz_draw_quick(data); */
00176     }
00177 
00178     return 1;
00179 }
00180 
00181 void Nviz_get_viewpoint_height(double *height)
00182 {
00183     float from[3];
00184 
00185     G_debug(1, "Nviz_get_viewpoint_height():");
00186 
00187     GS_get_from_real(from);
00188 
00189     *height = from[Z];
00190 }
00199 int Nviz_set_viewpoint_persp(int persp)
00200 {
00201     int fov;
00202 
00203     G_debug(1, "Nviz_set_viewpoint_persp(): value = %d", persp);
00204 
00205     fov = (int)(10 * persp);
00206     GS_set_fov(fov);
00207 
00208     /* Nviz_draw_quick(data); */
00209 
00210     return 1;
00211 }
00212 
00221 int Nviz_set_viewpoint_twist(int twist)
00222 {
00223     G_debug(1, "Nviz_set_viewpoint_twist(): value = %d", twist);
00224     GS_set_twist(10 * twist);
00225 
00226     /* Nviz_draw_quick(data); */
00227 
00228     return 1;
00229 }
00230 
00239 int Nviz_change_exag(nv_data * data, double exag)
00240 {
00241     double temp;
00242 
00243     G_debug(1, "Nviz_change_exag(): value = %f", exag);
00244     temp = GS_global_exag();
00245 
00246     if (exag != temp) {
00247         GS_set_global_exag(exag);
00248         Nviz_update_ranges(data);
00249 
00250         /* Nviz_draw_quick(data); */
00251     }
00252 
00253     return 1;
00254 }
00262 int Nviz_look_here(double sx, double sy)
00263 {
00264      G_debug(1, "Nviz_look_here(): screen coordinates = %f %f", sx, sy); 
00265      GS_look_here(sx, sy);
00266      return 1;
00267 }
00268 
00272 void Nviz_get_modelview(double *modelMatrix)
00273 {
00274     glGetDoublev(GL_MODELVIEW_MATRIX, modelMatrix);
00275 }
00276 
00288 void Nviz_set_rotation(double angle, double x, double y, double z)
00289 {
00290     G_debug(3, "Nviz_set_rotation(): angle = %f, x = %f, y = %f, z = %f", angle, x, y, z); 
00291     GS_set_rotation(angle, x, y, z);
00292 }
00293 
00297 void Nviz_unset_rotation(void)
00298 {
00299     GS_unset_rotation();
00300 }
00301 
00305 void Nviz_init_rotation(void)
00306 {
00307     GS_init_rotation();
00308 }
00309 
00322 void Nviz_flythrough(nv_data *data, float *fly_info, int *scale, int lateral)
00323 {
00324     float dir[3], from[4], cur_from[4], cur_dir[4];
00325     float speed, h, p, sh, ch, sp, cp;
00326     float diff_x, diff_y, diff_z;
00327     float quasi_zero;
00328 
00329     quasi_zero = 0.0001;
00330 
00331     GS_get_from(cur_from);
00332     GS_get_viewdir(cur_dir);
00333 
00334     p = asin(cur_dir[Z]);
00335     h = atan2(- cur_dir[X], - cur_dir[Y]);
00336 
00337     speed = scale[0] * fly_info[0];
00338 
00339     h += scale[1] * fly_info[1]; /* change heading */
00340     if (!lateral)   /* in case of "lateral" doesn't change pitch */
00341         p -= scale[1] * fly_info[2];
00342 
00343     h = fmod(h + M_PI, 2 * M_PI) - M_PI;
00344 
00345     sh = sin(h);
00346     ch = cos(h);
00347     sp = sin(p);
00348     cp = cos(p);
00349 
00350     dir[X] = -sh * cp;
00351     dir[Y] = -ch * cp;
00352     dir[Z] = sp;
00353 
00354     if (lateral) {
00355         from[X] = cur_from[X] + speed * dir[Y];
00356         from[Y] = cur_from[Y] - speed * dir[X];
00357         from[Z] = cur_from[Z] + scale[0] * fly_info[2];
00358     }
00359     else {
00360         from[X] = cur_from[X] + speed * dir[X];
00361         from[Y] = cur_from[Y] + speed * dir[Y];
00362         /* not sure how this should behave (change Z coord or not ?)*/
00363         from[Z] = cur_from[Z]; /* + speed * dir[Z]*/
00364     }
00365 
00366     diff_x = fabs(cur_dir[X] - dir[X]);
00367     diff_y = fabs(cur_dir[Y] - dir[Y]);
00368     diff_z = fabs(cur_dir[Z] - dir[Z]);
00369 
00370     if (    /* something has changed */
00371         (diff_x > quasi_zero) || (diff_y > quasi_zero) ||
00372         (diff_z > quasi_zero) || (cur_from[X] != from[X]) ||
00373         (cur_from[Y] != from[Y]) || (cur_from[Z] != from[Z])
00374     ) {
00375     GS_moveto(from);
00376     GS_set_viewdir(dir);        /* calls gsd_set_view */
00377     }
00378 }