/*! \brief Set current scale \param doexag use z-exaggeration */ void gsd_do_scale(int doexag) { float sx, sy, sz; float min, max; GS_get_scale(&sx, &sy, &sz, doexag); gsd_scale(sx, sy, sz); GS_get_zrange(&min, &max, 0); gsd_translate(0.0, 0.0, -min); return; }
/*! \brief Convert model to real coordinates \param point[in,out] 3d point (x,y,z) */ void gsd_model2real(Point3 point) { float sx, sy, sz; float min, max, n, s, w, e; GS_get_region(&n, &s, &w, &e); GS_get_scale(&sx, &sy, &sz, 1); GS_get_zrange(&min, &max, 0); point[X] = (sx ? point[X] / sx : 0.0) + w; point[Y] = (sy ? point[Y] / sy : 0.0) + s; point[Z] = (sz ? point[Z] / sz : 0.0) + min; return; }
/*! \brief Convert real to model coordinates \param point[in,out] 3d point (Point3) */ void gsd_real2model(Point3 point) { float sx, sy, sz; float min, max, n, s, w, e; GS_get_region(&n, &s, &w, &e); GS_get_scale(&sx, &sy, &sz, 1); GS_get_zrange(&min, &max, 0); point[X] = (point[X] - w) * sx; point[Y] = (point[Y] - s) * sy; point[Z] = (point[Z] - min) * sz; return; }
/*! \brief Convert surface to model coordinates \param point 3d point (Point3) */ void gsd_surf2model(Point3 point) { float min, max, sx, sy, sz; /* need to undo z scaling & translate */ GS_get_scale(&sx, &sy, &sz, 1); GS_get_zrange(&min, &max, 0); point[Z] = (sz ? (point[Z] - min) * sz : 0.0); /* need to unscale x & y */ point[X] = (sx ? point[X] * sx : 0.0); point[Y] = (sy ? point[Y] * sy : 0.0); return; }
/*! \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 Convert model to surface coordinates \param gs surface (geosurf) \param point 3d point (Point3) */ void gsd_model2surf(geosurf * gs, Point3 point) { float min, max, sx, sy, sz; /* so far, only one geographic "region" allowed, so origin of surface is same as origin of model space, but will need to provide translations here to make up the difference, so not using gs yet */ if (gs) { /* need to undo z scaling & translate */ GS_get_scale(&sx, &sy, &sz, 1); GS_get_zrange(&min, &max, 0); point[Z] = (sz ? point[Z] / sz : 0.0) + min; /* need to unscale x & y */ point[X] = (sx ? point[X] / sx : 0.0); point[Y] = (sy ? point[Y] / sy : 0.0); } 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); } }