/*! \brief Get all segments \param gs surface (geosurf) \param bgn begin point \param end end point \param num \return pointer to Point3 struct */ Point3 *gsdrape_get_allsegments(geosurf * gs, float *bgn, float *end, int *num) { gsdrape_set_surface(gs); if (!seg_intersect_vregion(gs, bgn, end)) { *num = 0; return (NULL); } if (bgn[X] == end[X] && bgn[Y] == end[Y]) { float f[3], l[3]; interp_first_last(gs, bgn, end, f, l); GS_v3eq(I3d[0], f); GS_v3eq(I3d[1], l); *num = 2; return (I3d); } if (CONST_ATT == gs_get_att_src(gs, ATT_TOPO)) { Flat = 1; } else { Flat = 0; } return (_gsdrape_get_segments(gs, bgn, end, num)); }
/*! \brief ADD \param gs surface (geosurf) \param bgn begin point (x,y) \param end end point (x,y) \param num \return pointer to Point3 struct */ Point3 *gsdrape_get_segments(geosurf * gs, float *bgn, float *end, int *num) { gsdrape_set_surface(gs); if (!seg_intersect_vregion(gs, bgn, end)) { *num = 0; return (NULL); } if (CONST_ATT == gs_get_att_src(gs, ATT_TOPO)) { /* will probably want a force_drape option to get all intersects */ I3d[0][X] = bgn[X]; I3d[0][Y] = bgn[Y]; I3d[0][Z] = gs->att[ATT_TOPO].constant; I3d[1][X] = end[X]; I3d[1][Y] = end[Y]; I3d[1][Z] = gs->att[ATT_TOPO].constant; *num = 2; return (I3d); } if (bgn[X] == end[X] && bgn[Y] == end[Y]) { float f[3], l[3]; interp_first_last(gs, bgn, end, f, l); GS_v3eq(I3d[0], f); GS_v3eq(I3d[1], l); /* CHANGE (*num = 1) to reflect degenerate line ? */ *num = 2; return (I3d); } Flat = 0; return (_gsdrape_get_segments(gs, bgn, end, num)); }
/*! \brief Check focus \param gv view (geoview) */ void gsd_check_focus(geoview * gv) { float zmax, zmin; GS_get_zrange(&zmin, &zmax, 0); if (gv->infocus) { GS_v3eq(gv->from_to[TO], gv->real_to); gv->from_to[TO][Z] -= zmin; GS_v3mult(gv->from_to[TO], gv->scale); gv->from_to[TO][Z] *= gv->vert_exag; GS_v3normalize(gv->from_to[FROM], gv->from_to[TO]); } return; }
/*! \brief Save 3dview \param vname view name \param gv pointer to geoview struct \param gd pointer to geodisplay struct \param w current window \param defsurf default geosurf struct \return -1 on error \return ? */ int Gs_save_3dview(const char *vname, geoview * gv, geodisplay * gd, struct Cell_head *w, geosurf * defsurf) { const char *mapset; struct G_3dview v; float zmax, zmin; GS_get_zrange(&zmin, &zmax, 0); G_get_3dview_defaults(&v, w); mapset = G_mapset(); if (mapset != NULL) { if (defsurf) { if (defsurf->draw_mode & DM_WIRE_POLY) { v.display_type = 3; } else if (defsurf->draw_mode & DM_WIRE || defsurf->draw_mode & DM_COL_WIRE) { v.display_type = 1; } else if (defsurf->draw_mode & DM_POLY) { v.display_type = 2; } v.mesh_freq = defsurf->x_modw; /* mesh resolution */ v.poly_freq = defsurf->x_mod; /* poly resolution */ v.dozero = !(defsurf->nz_topo); v.colorgrid = (defsurf->draw_mode & DM_COL_WIRE) ? 1 : 0; v.shading = (defsurf->draw_mode & DM_GOURAUD) ? 1 : 0; } if (gv->infocus) { GS_v3eq(v.from_to[TO], gv->real_to); v.from_to[TO][Z] -= zmin; GS_v3mult(v.from_to[TO], gv->scale); v.from_to[TO][Z] *= gv->vert_exag; } else { GS_v3eq(v.from_to[TO], gv->from_to[TO]); } gsd_model2real(v.from_to[TO]); GS_v3eq(v.from_to[FROM], gv->from_to[FROM]); gsd_model2real(v.from_to[FROM]); v.exag = gv->vert_exag; v.fov = gv->fov / 10.; v.twist = gv->twist; v.fringe = 0; /* not implemented here */ v.lightson = 1; /* always true, curently */ if (gv->lights[0].position[W] == 1) { /* local */ v.lightpos[X] = gv->lights[0].position[X]; v.lightpos[Y] = gv->lights[0].position[Y]; v.lightpos[Z] = gv->lights[0].position[Z]; gsd_model2real(v.lightpos); v.lightpos[W] = 1.0; /* local */ } else { v.lightpos[X] = gv->lights[0].position[X]; v.lightpos[Y] = gv->lights[0].position[Y]; v.lightpos[Z] = gv->lights[0].position[Z]; v.lightpos[W] = 0.0; /* inf */ } v.lightcol[0] = gv->lights[0].color[0]; v.lightcol[1] = gv->lights[0].color[1]; v.lightcol[2] = gv->lights[0].color[2]; v.ambient = (gv->lights[0].ambient[0] + gv->lights[0].ambient[1] + gv->lights[0].ambient[2]) / 3.; v.shine = gv->lights[0].shine; v.surfonly = 0; /* N/A - now uses constant color */ strcpy((v.pgm_id), "Nvision-ALPHA!"); return (G_put_3dview(vname, mapset, &v, w)); } else { return (-1); } }
/*! \brief ADD \param gv view (geoview) \return ? */ int gsd_zup_twist(geoview * gv) { float fr_to[2][4]; float look_theta, pi; float alpha, beta; float zup[3], yup[3], zupmag, yupmag; pi = 4.0 * atan(1.0); /* *************************************************************** */ /* This block of code is used to keep pos z in the up direction, * correcting for SGI system default which is pos y in the up * direction. Involves finding up vectors for both y up and * z up, then determining angle between them. LatLon mode uses y as * up direction instead of z, so no correction necessary. Next rewrite, * we should use y as up for all drawing. */ GS_v3eq(fr_to[FROM], gv->from_to[FROM]); GS_v3eq(fr_to[TO], gv->from_to[TO]); /* neg alpha OK since sin(-x) = -sin(x) */ alpha = pi / 2.0 - acos(fr_to[FROM][Z] - fr_to[TO][Z]); zup[X] = fr_to[TO][X]; zup[Y] = fr_to[TO][Y]; if (sin(alpha)) { zup[Z] = fr_to[TO][Z] + 1 / sin(alpha); } else { zup[Z] = fr_to[FROM][Z] + 1.0; } zupmag = GS_distance(fr_to[FROM], zup); yup[X] = fr_to[TO][X]; yup[Z] = fr_to[TO][Z]; /* neg beta OK since sin(-x) = -sin(x) */ beta = pi / 2.0 - acos(fr_to[TO][Y] - fr_to[FROM][Y]); if (sin(beta)) { yup[Y] = fr_to[TO][Y] - 1 / sin(beta); } else { yup[Y] = fr_to[FROM][Y] + 1.0; } yupmag = GS_distance(fr_to[FROM], yup); look_theta = (1800.0 / pi) * acos(((zup[X] - fr_to[FROM][X]) * (yup[X] - fr_to[FROM][X]) + (zup[Y] - fr_to[FROM][Y]) * (yup[Y] - fr_to[FROM][Y]) + (zup[Z] - fr_to[FROM][Z]) * (yup[Z] - fr_to[FROM][Z])) / (zupmag * yupmag)); if (fr_to[TO][X] - fr_to[FROM][X] < 0.0) { look_theta = -look_theta; } if (fr_to[TO][Z] - fr_to[FROM][Z] < 0.0) { /* looking down */ if (fr_to[TO][Y] - fr_to[FROM][Y] < 0.0) { look_theta = 1800 - look_theta; } } else { /* looking up */ if (fr_to[TO][Y] - fr_to[FROM][Y] > 0.0) { look_theta = 1800 - look_theta; } } return ((int)(gv->twist + 1800 + look_theta)); }
/*! \brief ADD Do normal transforms before calling Note gs: NULL if 3d obj or const elev surface \todo add size1, size2 & dir1, dir2 (eg azimuth, elevation) variables \param gs surface (geosurf) \param size \param marker \param pt 3d point (Point3) */ void gpd_obj(geosurf * gs, int color, float size, int marker, Point3 pt) { float sz, lpt[3]; float siz[3]; gsd_color_func(color); sz = GS_global_exag(); GS_v3eq(lpt, pt); /* CHANGING Z OF POINT PASSED, so use copy */ switch (marker) { /* ACS_MODIFY_BEGIN site_attr management ************************************** */ case ST_HISTOGRAM: gsd_colormode(CM_DIFFUSE); gsd_pushmatrix(); if (sz) { lpt[Z] *= sz; gsd_scale(1.0, 1.0, 1. / sz); } siz[0] = _cur_size_; siz[1] = _cur_size_; siz[2] = size; gsd_box(lpt, color, siz); gsd_popmatrix(); gsd_colormode(CM_COLOR); break; /* ACS_MODIFY_END site_attr management ************************************** */ case ST_DIAMOND: /* gsd_colormode(CM_AD); */ gsd_colormode(CM_DIFFUSE); gsd_pushmatrix(); if (sz) { lpt[Z] *= sz; gsd_scale(1.0, 1.0, 1. / sz); } gsd_diamond(lpt, color, size); gsd_popmatrix(); gsd_colormode(CM_COLOR); break; case ST_BOX: gsd_colormode(CM_COLOR); gsd_pushmatrix(); if (sz) { lpt[Z] *= sz; gsd_scale(1.0, 1.0, 1. / sz); } gsd_draw_box(lpt, color, size); gsd_popmatrix(); break; case ST_SPHERE: /* gsd_colormode(CM_AD); */ gsd_colormode(CM_DIFFUSE); gsd_pushmatrix(); if (sz) { lpt[Z] *= sz; gsd_scale(1.0, 1.0, 1. / sz); } gsd_sphere(lpt, size); gsd_popmatrix(); gsd_colormode(CM_COLOR); break; case ST_GYRO: gsd_colormode(CM_COLOR); gsd_pushmatrix(); if (sz) { lpt[Z] *= sz; gsd_scale(1.0, 1.0, 1. / sz); } gsd_draw_gyro(lpt, color, size); gsd_popmatrix(); break; case ST_ASTER: gsd_colormode(CM_COLOR); gsd_pushmatrix(); if (sz) { lpt[Z] *= sz; gsd_scale(1.0, 1.0, 1. / sz); } gsd_draw_asterisk(lpt, color, size); gsd_popmatrix(); break; case ST_CUBE: gsd_colormode(CM_DIFFUSE); gsd_pushmatrix(); if (sz) { lpt[Z] *= sz; gsd_scale(1.0, 1.0, 1. / sz); } gsd_cube(lpt, color, size); gsd_popmatrix(); gsd_colormode(CM_COLOR); break; default: case ST_X: gsd_colormode(CM_COLOR); gsd_x(gs, lpt, color, size); break; } return; }