|
GRASS Programmer's Manual
6.5.svn(2012)-r51648
|
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 }