123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360 |
- /*!
- \file lib/ogsf/gsd_cplane.c
- \brief OGSF library - manipulating surfaces (lower level functions)
- GRASS OpenGL gsurf OGSF Library
- (C) 1999-2008 by the GRASS Development Team
- This program is free software under the
- GNU General Public License (>=v2).
- Read the file COPYING that comes with GRASS
- for details.
- \author Bill Brown USACERL, GMSL/University of Illinois (January 1993)
- \author Doxygenized by Martin Landa <landa.martin gmail.com> (May 2008)
- */
- #include <grass/ogsf.h>
- #include "rowcol.h"
- static void init_cplane(void);
- static float Cp_pt[4], Cp_norm[MAX_CPLANES][4];
- static float Cp_trans[MAX_CPLANES][3], Cp_rot[MAX_CPLANES][3];
- static int Cp_ison[MAX_CPLANES]; /* also need isdef? */
- static void init_cplane(void)
- {
- int i;
- gs_get_datacenter(Cp_pt);
- gs_get_data_avg_zmax(&(Cp_pt[Z]));
- for (i = 0; i < MAX_CPLANES; i++) {
- Cp_ison[i] = 0;
- Cp_norm[i][X] = 1.0;
- Cp_norm[i][Y] = Cp_norm[i][Z] = 0.0;
- Cp_norm[i][W] = 1.;
- Cp_rot[i][X] = Cp_trans[i][X] = 0.0;
- Cp_rot[i][Y] = Cp_trans[i][Y] = 0.0;
- Cp_rot[i][Z] = Cp_trans[i][Z] = 0.0;
- }
- return;
- }
- /*!
- \brief Define cplace
- \param num
- \param pt
- \param norm
- */
- void gsd_def_cplane(int num, float *pt, float *norm)
- {
- float sx, sy, sz, ppt[3];
- double params[4];
- float zmin, zmax;
- GS_get_scale(&sx, &sy, &sz, 1);
- /* Something's still wrong with the zexag - DONT USE TILT */
- GS_get_zrange(&zmin, &zmax, 0);
- ppt[0] = (pt[0] + Cp_pt[0]) * sx;
- ppt[1] = (pt[1] + Cp_pt[1]) * sy;
- ppt[2] = (pt[2] + Cp_pt[2] - zmin) * sz;
- params[0] = norm[0] * sx;
- params[1] = norm[1] * sy;
- params[2] = norm[2] * sz;
- GS_dv3norm(params);
- params[3] = -ppt[0] * params[0] - ppt[1] * params[1] - ppt[2] * params[2];
- gsd_def_clipplane(num, params);
- return;
- }
- /*!
- \brief Update cplaces
- Called when viewing matrix changes
- */
- void gsd_update_cplanes(void)
- {
- int i;
- for (i = 0; i < MAX_CPLANES; i++) {
- if (Cp_ison[i]) {
- gsd_def_cplane(i, Cp_trans[i], Cp_norm[i]);
- }
- }
- return;
- }
- /*!
- \brief ADD
- \param num
- */
- void gsd_cplane_on(int num)
- {
- static int first = 1;
- if (first) {
- first = 0;
- init_cplane();
- gsd_def_cplane(num, Cp_trans[num], Cp_norm[num]);
- }
- gsd_set_clipplane(num, 1);
- Cp_ison[num] = 1;
- return;
- }
- /*!
- \brief Turn off clip plane
- \param num cplane id
- */
- void gsd_cplane_off(int num)
- {
- gsd_set_clipplane(num, 0);
- Cp_ison[num] = 0;
- return;
- }
- /*!
- \brief Get cplane state
- <i>onstate</i> MUST be big enough to hold MAX_CPLANES ints
- \param onstate
- */
- void gsd_get_cplanes_state(int *onstate)
- {
- int i;
- for (i = 0; i < MAX_CPLANES; i++) {
- onstate[i] = Cp_ison[i];
- }
- return;
- }
- /*!
- \brief Get cplaces
- Planes MUST be big enough to hold MAX_CPLANES Point4s
- \param places surface coordinates, normal pointing away from visible side
- \return ADD
- */
- int gsd_get_cplanes(Point4 * planes)
- {
- int i, ons;
- Point3 thru;
- for (ons = i = 0; i < MAX_CPLANES; i++) {
- if (Cp_ison[i]) {
- thru[X] = Cp_pt[X] + Cp_trans[ons][X];
- thru[Y] = Cp_pt[Y] + Cp_trans[ons][Y];
- thru[Z] = Cp_pt[Z] + Cp_trans[ons][Z];
- planes[ons][X] = -Cp_norm[ons][X];
- planes[ons][Y] = -Cp_norm[ons][Y];
- planes[ons][Z] = -Cp_norm[ons][Z];
- planes[ons][W] = -(DOT3(planes[ons], thru));
- ons++;
- }
- }
- return (ons);
- }
- /*!
- \brief ADD
- \param num
- */
- void gsd_update_cpnorm(int num)
- {
- float v[1][4];
- v[0][X] = v[0][W] = 1.0;
- v[0][Y] = v[0][Z] = 0.0;
- P_pushmatrix();
- P_rot(Cp_rot[num][Z], 'z');
- P_rot(Cp_rot[num][Y], 'y');
- P_rot(Cp_rot[num][X], 'x');
- P_transform(1, v, &Cp_norm[num]);
- P_popmatrix();
- return;
- }
- /*!
- \brief ADD
- \param num
- \param rx,ry,rz
- */
- void gsd_cplane_setrot(int num, float rx, float ry, float rz)
- {
- Cp_rot[num][X] = rx;
- Cp_rot[num][Y] = ry;
- Cp_rot[num][Z] = rz;
- gsd_update_cpnorm(num);
- gsd_def_cplane(num, Cp_trans[num], Cp_norm[num]);
- return;
- }
- /*!
- \brief ADD
- \param num
- \param tx,ty,tz
- */
- void gsd_cplane_settrans(int num, float tx, float ty, float tz)
- {
- Cp_trans[num][X] = tx;
- Cp_trans[num][Y] = ty;
- Cp_trans[num][Z] = tz;
- gsd_def_cplane(num, Cp_trans[num], Cp_norm[num]);
- return;
- }
- /*!
- \brief ADD
- \param surf1 first surface (geosurf)
- \param surf2 second surface (geosurf) [unused]
- \param cpnum
- */
- void gsd_draw_cplane_fence(geosurf * surf1, geosurf * surf2, int cpnum)
- {
- int was_on;
- float len, dir[3], bgn[2], end[2], px, py, fencenorm[3];
- /* temporarily turn this plane off */
- if ((was_on = Cp_ison[cpnum])) {
- gsd_set_clipplane(cpnum, 0);
- }
- /* line on surface (asuming NO TILT) is (-A,B)->(A,-B),
- extended thru Cp_pt */
- dir[X] = -Cp_norm[cpnum][Y];
- dir[Y] = Cp_norm[cpnum][X];
- dir[Z] = 0.0;
- GS_v3norm(dir);
- px = Cp_trans[cpnum][X] + Cp_pt[X];
- py = Cp_trans[cpnum][Y] + Cp_pt[Y];
- /* TODO: make line from point & direction, clip to region */
- /* for now, to test: */
- bgn[X] = px;
- bgn[Y] = py;
- end[X] = px;
- end[Y] = 3 * VROW2Y(surf1, 0);
- len = GS_P2distance(bgn, end) - 1;
- bgn[X] = px + len * dir[X];
- bgn[Y] = py + len * dir[Y];
- end[X] = px - len * dir[X];
- end[Y] = py - len * dir[Y];
- fencenorm[X] = -Cp_norm[cpnum][X];
- fencenorm[Y] = -Cp_norm[cpnum][Y];
- fencenorm[Z] = -Cp_norm[cpnum][Z];
- gsd_wall(bgn, end, fencenorm);
- /* turn this plane back on */
- if (was_on) {
- gsd_set_clipplane(cpnum, 1);
- }
- return;
- }
- /*!
- \brief Draw cplane
- \param num
- */
- void gsd_draw_cplane(int num)
- {
- float size, cpv[3];
- int i;
- float scalez;
- unsigned long colr;
- /* turn off all clipping planes */
- for (i = 0; i < MAX_CPLANES; i++) {
- if (Cp_ison[i]) {
- gsd_set_clipplane(i, 0);
- }
- }
- GS_get_longdim(&size);
- size /= 2.;
- cpv[X] = 0.0;
- gsd_blend(1);
- gsd_zwritemask(0x0);
- gsd_pushmatrix();
- gsd_do_scale(1);
- gsd_translate(Cp_pt[X] + Cp_trans[num][X],
- Cp_pt[Y] + Cp_trans[num][Y], Cp_pt[Z] + Cp_trans[num][Z]);
- gsd_rot(Cp_rot[num][Z], 'z');
- gsd_rot(Cp_rot[num][Y], 'y');
- gsd_rot(Cp_rot[num][X], 'x');
- if ((scalez = GS_global_exag())) {
- gsd_scale(1.0, 1.0, 1. / scalez);
- }
- colr = (GS_default_draw_color() | 0xff000000) & 0x33ffffff;
- gsd_color_func(colr);
- gsd_bgnpolygon();
- cpv[Y] = size;
- cpv[Z] = size;
- gsd_vert_func(cpv);
- cpv[Y] = -size;
- gsd_vert_func(cpv);
- cpv[Z] = -size;
- gsd_vert_func(cpv);
- cpv[Y] = size;
- gsd_vert_func(cpv);
- gsd_endpolygon();
- gsd_popmatrix();
- gsd_blend(0);
- gsd_zwritemask(0xffffffff);
- /* turn on clipping planes */
- for (i = 0; i < MAX_CPLANES; i++) {
- if (Cp_ison[i]) {
- gsd_set_clipplane(i, 1);
- }
- }
- return;
- }
|