123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437 |
- /*!
- \file gsd_label.c
- \brief OGSF library - objects management (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 (October 1993)
- \author Doxygenized by Martin Landa <landa.martin gmail.com> (May 2008)
- */
- #include <stdlib.h>
- #include <string.h>
- #include <grass/gis.h>
- #include <grass/ogsf_proto.h>
- #include <grass/gstypes.h>
- #include "gsget.h"
- #include "math.h"
- #include "rowcol.h"
- static void init_stuff(void);
- /*!
- \brief vertices for octohedron
- */
- float Octo[6][3] = {
- {1.0, 0.0, 0.0},
- {0.0, 1.0, 0.0},
- {0.0, 0.0, 1.0},
- {-1.0, 0.0, 0.0},
- {0.0, -1.0, 0.0},
- {0.0, 0.0, -1.0}
- };
- #define ONORM .57445626
- /*!
- \brief normals for flat-shaded octohedron
- */
- float OctoN[8][3] = {
- {ONORM, ONORM, ONORM},
- {-ONORM, ONORM, ONORM},
- {ONORM, -ONORM, ONORM},
- {-ONORM, -ONORM, ONORM},
- {ONORM, ONORM, -ONORM},
- {-ONORM, ONORM, -ONORM},
- {ONORM, -ONORM, -ONORM},
- {-ONORM, -ONORM, -ONORM},
- };
- /*!
- ???? not sure if any of these are needed for correct lighting.
- float CubeNormals[6][3] = {
- {ONORM, 0, 0},
- {-ONORM, 0, 0},
- {0, ONORM, 0},
- {0, -ONORM, 0},
- {0, 0, ONORM},
- {0, 0, -ONORM}
- };
- */
- float CubeNormals[3][3] = {
- {0, -ONORM, 0},
- {0, 0, ONORM},
- {ONORM, 0, 0}
- };
- float CubeVertices[8][3] = {
- {-1.0, -1.0, -1.0},
- {1.0, -1.0, -1.0},
- {1.0, 1.0, -1.0},
- {-1.0, 1.0, -1.0},
- {-1.0, -1.0, 1.0},
- {1.0, -1.0, 1.0},
- {1.0, 1.0, 1.0},
- {-1.0, 1.0, 1.0}
- };
- float origin[3] = { 0.0, 0.0, 0.0 };
- #define UP_NORM Octo[2]
- #define DOWN_NORM Octo[5]
- #define ORIGIN origin
- /*!
- \brief vertices & normals for octagon in xy plane
- */
- float ogverts[8][3];
- /*!
- \brief vertices for octagon in xy plane, z=1
- */
- float ogvertsplus[8][3];
- float Pi;
- static void init_stuff(void)
- {
- float cos45;
- int i;
- static int first = 1;
- if (first) {
- first = 0;
- cos45 = cos(atan(1.0));
- for (i = 0; i < 8; i++) {
- ogverts[i][Z] = 0.0;
- ogvertsplus[i][Z] = 1.0;
- }
- ogverts[0][X] = ogvertsplus[0][X] = 1.0;
- ogverts[0][Y] = ogvertsplus[0][Y] = 0.0;
- ogverts[1][X] = ogvertsplus[1][X] = cos45;
- ogverts[1][Y] = ogvertsplus[1][Y] = cos45;
- ogverts[2][X] = ogvertsplus[2][X] = 0.0;
- ogverts[2][Y] = ogvertsplus[2][Y] = 1.0;
- ogverts[3][X] = ogvertsplus[3][X] = -cos45;
- ogverts[3][Y] = ogvertsplus[3][Y] = cos45;
- ogverts[4][X] = ogvertsplus[4][X] = -1.0;
- ogverts[4][Y] = ogvertsplus[4][Y] = 0.0;
- ogverts[5][X] = ogvertsplus[5][X] = -cos45;
- ogverts[5][Y] = ogvertsplus[5][Y] = -cos45;
- ogverts[6][X] = ogvertsplus[6][X] = 0.0;
- ogverts[6][Y] = ogvertsplus[6][Y] = -1.0;
- ogverts[7][X] = ogvertsplus[7][X] = cos45;
- ogverts[7][Y] = ogvertsplus[7][Y] = -cos45;
- Pi = 4.0 * atan(1.0);
- }
- return;
- }
- /*!
- \brief ADD
- \param center center point
- \param colr color value
- \param siz size value
- */
- void gsd_plus(float *center, int colr, float siz)
- {
- float v1[3], v2[3];
- gsd_color_func(colr);
- siz *= .5;
- v1[Z] = v2[Z] = center[Z];
- v1[X] = v2[X] = center[X];
- v1[Y] = center[Y] - siz;
- v2[Y] = center[Y] + siz;
- gsd_bgnline();
- gsd_vert_func(v1);
- gsd_vert_func(v2);
- gsd_endline();
- v1[Y] = v2[Y] = center[Y];
- v1[X] = center[X] - siz;
- v2[X] = center[X] + siz;
- gsd_bgnline();
- gsd_vert_func(v1);
- gsd_vert_func(v2);
- gsd_endline();
- return;
- }
- /*!
- \brief Line on surface, fix z-values
- \todo remove fudge, instead fudge the Z buffer
- \param gs surface (geosurf)
- \param v1 first point
- \param v2 second point
- */
- void gsd_line_onsurf(geosurf * gs, float *v1, float *v2)
- {
- int i, np;
- Point3 *pts;
- float fudge;
- pts = gsdrape_get_segments(gs, v1, v2, &np);
- if (pts) {
- fudge = FUDGE(gs);
- gsd_bgnline();
- for (i = 0; i < np; i++) {
- /* ACS */
- /* reverting back, as it broke displaying X symbol and query line */
- pts[i][Z] += fudge;
- /*pts[i][Z] *= fudge;*/
- gsd_vert_func(pts[i]);
- }
- gsd_endline();
- /* fix Z values? */
- v1[Z] = pts[0][Z];
- v2[Z] = pts[np - 1][Z];
- }
- return;
- }
- /*!
- \brief Multiline on surface, fix z-values
- \todo remove fudge, instead fudge the Z buffer
- Like above, except only draws first n points of line, or np,
- whichever is less. Returns number of points used. Fills
- pt with last pt drawn.
- \param gs surface (geosurf)
- \param v1 first point
- \param v2 second point
- \param pt
- \param n number of segments
- \param number of vertices
- */
- int gsd_nline_onsurf(geosurf * gs, float *v1, float *v2, float *pt, int n)
- {
- int i, np, pdraw;
- Point3 *pts;
- float fudge;
- pts = gsdrape_get_segments(gs, v1, v2, &np);
- if (pts) {
- pdraw = n < np ? n : np;
- fudge = FUDGE(gs);
- gsd_bgnline();
- for (i = 0; i < pdraw; i++) {
- pts[i][Z] += fudge;
- gsd_vert_func(pts[i]);
- }
- gsd_endline();
- pt[X] = pts[i - 1][X];
- pt[Y] = pts[i - 1][Y];
- /* fix Z values? */
- v1[Z] = pts[0][Z];
- v2[Z] = pts[np - 1][Z];
- return (i);
- }
- return (0);
- }
- /*!
- \brief Draw X symbol
- Note gs: NULL if flat
- \param gs surface (geosurf)
- \param center
- \param colr color value
- \param siz size value
- */
- void gsd_x(geosurf * gs, float *center, int colr, float siz)
- {
- float v1[3], v2[3];
- gsd_color_func(colr);
- siz *= .5;
- v1[Z] = v2[Z] = center[Z];
- v1[X] = center[X] - siz;
- v2[X] = center[X] + siz;
- v1[Y] = center[Y] - siz;
- v2[Y] = center[Y] + siz;
- if (gs) {
- gsd_line_onsurf(gs, v1, v2);
- }
- else {
- gsd_bgnline();
- gsd_vert_func(v1);
- gsd_vert_func(v2);
- gsd_endline();
- }
- v1[X] = center[X] - siz;
- v2[X] = center[X] + siz;
- v1[Y] = center[Y] + siz;
- v2[Y] = center[Y] - siz;
- if (gs) {
- gsd_line_onsurf(gs, v1, v2);
- }
- else {
- gsd_bgnline();
- gsd_vert_func(v1);
- gsd_vert_func(v2);
- gsd_endline();
- }
- return;
- }
- /*!
- \brief Draw diamond symbol
- \param center center point
- \param colr color value
- \param size size value
- */
- void gsd_diamond(float *center, unsigned long colr, float siz)
- {
- int preshade;
- /* seems right, but isn't
- siz *= .5;
- */
- gsd_pushmatrix();
- gsd_translate(center[X], center[Y], center[Z]);
- gsd_scale(siz, siz, siz);
- preshade = gsd_getshademodel();
- gsd_shademodel(0); /* want flat shading */
- gsd_bgnpolygon();
- gsd_litvert_func(OctoN[0], colr, Octo[0]);
- gsd_litvert_func(OctoN[0], colr, Octo[1]);
- gsd_litvert_func(OctoN[0], colr, Octo[2]);
- gsd_endpolygon();
- gsd_bgnpolygon();
- gsd_litvert_func(OctoN[1], colr, Octo[2]);
- gsd_litvert_func(OctoN[1], colr, Octo[1]);
- gsd_litvert_func(OctoN[1], colr, Octo[3]);
- gsd_endpolygon();
- gsd_bgnpolygon();
- gsd_litvert_func(OctoN[2], colr, Octo[2]);
- gsd_litvert_func(OctoN[2], colr, Octo[4]);
- gsd_litvert_func(OctoN[2], colr, Octo[0]);
- gsd_endpolygon();
- gsd_bgnpolygon();
- gsd_litvert_func(OctoN[3], colr, Octo[2]);
- gsd_litvert_func(OctoN[3], colr, Octo[3]);
- gsd_litvert_func(OctoN[3], colr, Octo[4]);
- gsd_endpolygon();
- gsd_bgnpolygon();
- gsd_litvert_func(OctoN[4], colr, Octo[0]);
- gsd_litvert_func(OctoN[4], colr, Octo[5]);
- gsd_litvert_func(OctoN[4], colr, Octo[1]);
- gsd_endpolygon();
- gsd_bgnpolygon();
- gsd_litvert_func(OctoN[5], colr, Octo[1]);
- gsd_litvert_func(OctoN[5], colr, Octo[5]);
- gsd_litvert_func(OctoN[5], colr, Octo[3]);
- gsd_endpolygon();
- gsd_bgnpolygon();
- gsd_litvert_func(OctoN[6], colr, Octo[5]);
- gsd_litvert_func(OctoN[6], colr, Octo[0]);
- gsd_litvert_func(OctoN[6], colr, Octo[4]);
- gsd_endpolygon();
- gsd_bgnpolygon();
- gsd_litvert_func(OctoN[7], colr, Octo[5]);
- gsd_litvert_func(OctoN[7], colr, Octo[4]);
- gsd_litvert_func(OctoN[7], colr, Octo[3]);
- gsd_endpolygon();
- #ifdef OCT_SHADED
- {
- gsd_bgntmesh();
- gsd_litvert_func(Octo[0], colr, Octo[0]);
- gsd_litvert_func(Octo[1], colr, Octo[1]);
- gsd_swaptmesh();
- gsd_litvert_func(Octo[2], colr, Octo[2]);
- gsd_swaptmesh();
- gsd_litvert_func(Octo[4], colr, Octo[4]);
- gsd_swaptmesh();
- gsd_litvert_func(Octo[5], colr, Octo[5]);
- gsd_swaptmesh();
- gsd_litvert_func(Octo[1], colr, Octo[1]);
- gsd_litvert_func(Octo[3], colr, Octo[3]);
- gsd_litvert_func(Octo[2], colr, Octo[2]);
- gsd_swaptmesh();
- gsd_litvert_func(Octo[4], colr, Octo[4]);
- gsd_swaptmesh();
- gsd_litvert_func(Octo[5], colr, Octo[5]);
- gsd_swaptmesh();
- gsd_litvert_func(Octo[1], colr, Octo[1]);
- gsd_endtmesh();
- }
- #endif
- gsd_popmatrix();
- gsd_shademodel(preshade);
- return;
- }
- /*!
- \brief Draw cube
- Added by Hamish Bowman Nov 2005
- \param center center point
- \param colr color value
- \param siz size value
- */
- void gsd_cube(float *center, unsigned long colr, float siz)
- {
- int preshade;
- /* see gsd_diamond() "seems right, but isn't" */
- siz *= .5;
- gsd_pushmatrix();
- gsd_translate(center[X], center[Y], center[Z]);
- gsd_scale(siz, siz, siz);
- preshade = gsd_getshademodel();
- gsd_shademodel(0); /* want flat shading */
- /* N wall: */
- gsd_bgnpolygon();
- gsd_litvert_func(CubeNormals[0], colr, CubeVertices[2]);
- gsd_litvert_func(CubeNormals[0], colr, CubeVertices[3]);
- gsd_litvert_func(CubeNormals[0], colr, CubeVertices[7]);
- gsd_litvert_func(CubeNormals[0], colr, CubeVertices[6]);
- gsd_endpolygon();
- /* S wall: */
- gsd_bgnpolygon();
- gsd_litvert_func(CubeNormals[0], colr, CubeVertices[1]);
- gsd_litvert_func(CubeNormals[0], colr, CubeVertices[5]);
- gsd_litvert_func(CubeNormals[0], colr, CubeVertices[4]);
- gsd_litvert_func(CubeNormals[0], colr, CubeVertices[0]);
- gsd_endpolygon();
- /* E wall: */
- gsd_bgnpolygon();
- gsd_litvert_func(CubeNormals[1], colr, CubeVertices[2]);
- gsd_litvert_func(CubeNormals[1], colr, CubeVertices[6]);
- gsd_litvert_func(CubeNormals[1], colr, CubeVertices[5]);
- gsd_litvert_func(CubeNormals[1], colr, CubeVertices[1]);
- gsd_endpolygon();
- /* W wall: */
- gsd_bgnpolygon();
- gsd_litvert_func(CubeNormals[1], colr, CubeVertices[0]);
- gsd_litvert_func(CubeNormals[1], colr, CubeVertices[4]);
- gsd_litvert_func(CubeNormals[1], colr, CubeVertices[7]);
- gsd_litvert_func(CubeNormals[1], colr, CubeVertices[3]);
- gsd_endpolygon();
- /* lower wall: */
- gsd_bgnpolygon();
- gsd_litvert_func(CubeNormals[2], colr, CubeVertices[0]);
- gsd_litvert_func(CubeNormals[2], colr, CubeVertices[1]);
- gsd_litvert_func(CubeNormals[2], colr, CubeVertices[2]);
- gsd_litvert_func(CubeNormals[2], colr, CubeVertices[3]);
- gsd_endpolygon();
- /* top wall: */
- gsd_bgnpolygon();
- gsd_litvert_func(CubeNormals[2], colr, CubeVertices[4]);
- gsd_litvert_func(CubeNormals[2], colr, CubeVertices[5]);
- gsd_litvert_func(CubeNormals[2], colr, CubeVertices[6]);
- gsd_litvert_func(CubeNormals[2], colr, CubeVertices[7]);
- gsd_endpolygon();
- gsd_popmatrix();
- gsd_shademodel(preshade);
- return;
- }
- /*!
- \brief Draw box
- Added by Hamish Bowman Nov 2005
- \param center center point
- \param colr color value
- \param siz size value
- */
- void gsd_draw_box(float *center, unsigned long colr, float siz)
- {
- /* see gsd_diamond() "seems right, but isn't" */
- siz *= .5;
- gsd_pushmatrix();
- gsd_translate(center[X], center[Y], center[Z]);
- gsd_scale(siz, siz, siz);
- gsd_color_func(colr);
- gsd_bgnline(); /* N wall */
- gsd_vert_func(CubeVertices[2]);
- gsd_vert_func(CubeVertices[3]);
- gsd_vert_func(CubeVertices[7]);
- gsd_vert_func(CubeVertices[6]);
- gsd_vert_func(CubeVertices[2]);
- gsd_endline();
- gsd_bgnline(); /* S wall */
- gsd_vert_func(CubeVertices[1]);
- gsd_vert_func(CubeVertices[5]);
- gsd_vert_func(CubeVertices[4]);
- gsd_vert_func(CubeVertices[0]);
- gsd_vert_func(CubeVertices[1]);
- gsd_endline();
- gsd_bgnline();
- gsd_vert_func(CubeVertices[1]);
- gsd_vert_func(CubeVertices[2]);
- gsd_endline();
- gsd_bgnline();
- gsd_vert_func(CubeVertices[3]);
- gsd_vert_func(CubeVertices[0]);
- gsd_endline();
- gsd_bgnline();
- gsd_vert_func(CubeVertices[5]);
- gsd_vert_func(CubeVertices[6]);
- gsd_endline();
- gsd_bgnline();
- gsd_vert_func(CubeVertices[4]);
- gsd_vert_func(CubeVertices[7]);
- gsd_endline();
- gsd_popmatrix();
- return;
- }
- /*!
- \brief Draw sphere
- \param center center point
- \param colr color value
- \param size size value
- */
- void gsd_drawsphere(float *center, unsigned long colr, float siz)
- {
- siz *= .5; /* siz is diameter, gsd_sphere uses radius */
- gsd_color_func(colr);
- gsd_sphere(center, siz);
- return;
- }
- /*!
- \brief Draw diamond lines
- */
- void gsd_diamond_lines(void)
- {
- gsd_bgnline();
- gsd_vert_func(Octo[0]);
- gsd_vert_func(Octo[3]);
- gsd_endline();
- gsd_bgnline();
- gsd_vert_func(Octo[1]);
- gsd_vert_func(Octo[4]);
- gsd_endline();
- gsd_bgnline();
- gsd_vert_func(Octo[2]);
- gsd_vert_func(Octo[5]);
- gsd_endline();
- return;
- }
- /*!
- \brief Draw asterisk
- \param center center point
- \param colr color value
- \param siz size value
- */
- void gsd_draw_asterisk(float *center, unsigned long colr, float siz)
- {
- float angle;
- angle = 45.; /* degrees */
- gsd_pushmatrix();
- gsd_translate(center[X], center[Y], center[Z]);
- gsd_scale(siz, siz, siz);
- gsd_color_func(colr);
- gsd_diamond_lines();
- gsd_pushmatrix();
- gsd_rot(angle, 'x');
- gsd_diamond_lines();
- gsd_popmatrix();
- gsd_pushmatrix();
- gsd_rot(-angle, 'x');
- gsd_diamond_lines();
- gsd_popmatrix();
- gsd_pushmatrix();
- gsd_rot(angle, 'y');
- gsd_diamond_lines();
- gsd_popmatrix();
- gsd_pushmatrix();
- gsd_rot(-angle, 'y');
- gsd_diamond_lines();
- gsd_popmatrix();
- gsd_pushmatrix();
- gsd_rot(angle, 'z');
- gsd_diamond_lines();
- gsd_popmatrix();
- gsd_pushmatrix();
- gsd_rot(-angle, 'z');
- gsd_diamond_lines();
- gsd_popmatrix();
- gsd_popmatrix();
- return;
- }
- /*!
- \brief Draw gyro
- \param center center point
- \param colr color value
- \param siz size value
- */
- void gsd_draw_gyro(float *center, unsigned long colr, float siz)
- {
- int i;
- gsd_pushmatrix();
- gsd_translate(center[X], center[Y], center[Z]);
- gsd_scale(siz, siz, siz);
- gsd_color_func(colr);
- /* vert axis */
- gsd_bgnline();
- gsd_vert_func(Octo[2]);
- gsd_vert_func(Octo[5]);
- gsd_endline();
- /* spokes */
- gsd_pushmatrix();
- for (i = 0; i < 6; i++) {
- gsd_rot(30., 'z');
- gsd_bgnline();
- gsd_vert_func(Octo[0]);
- gsd_vert_func(Octo[3]);
- gsd_endline();
- }
- gsd_popmatrix();
- gsd_color_func(colr);
- gsd_circ(0., 0., 1.);
- gsd_pushmatrix();
- gsd_rot(90., 'x');
- gsd_circ(0., 0., 1.);
- gsd_popmatrix();
- gsd_pushmatrix();
- gsd_rot(90., 'y');
- gsd_circ(0., 0., 1.);
- gsd_popmatrix();
- gsd_popmatrix();
- return;
- }
- /*!
- \brief Draw 3d cursor
- \param pt point
- */
- void gsd_3dcursor(float *pt)
- {
- float big, vert[3];
- big = 10000.;
- gsd_bgnline();
- vert[X] = pt[X];
- vert[Y] = pt[Y];
- vert[Z] = big;
- gsd_vert_func(vert);
- vert[Z] = -big;
- gsd_vert_func(vert);
- gsd_endline();
- gsd_bgnline();
- vert[X] = pt[X];
- vert[Z] = pt[Z];
- vert[Y] = big;
- gsd_vert_func(vert);
- vert[Y] = -big;
- gsd_vert_func(vert);
- gsd_endline();
- gsd_bgnline();
- vert[Y] = pt[Y];
- vert[Z] = pt[Z];
- vert[X] = big;
- gsd_vert_func(vert);
- vert[X] = -big;
- gsd_vert_func(vert);
- gsd_endline();
- return;
- }
- /*!
- \brief ADD
- \param dir
- \param slope
- \param ascpect
- \param degrees
- */
- void dir_to_slope_aspect(float *dir, float *slope, float *aspect, int degrees)
- {
- float dx, dy, dz;
- float costheta, theta, adjacent;
- dx = dir[X];
- dy = dir[Y];
- dz = dir[Z];
- /* project vector <dx,dy,dz> onto plane of constant z containing
- * final value should be 0.0 to 3600.0 */
- if (dx == 0 && dy == 0) {
- *aspect = 0.;
- }
- else {
- if (dx == 0) {
- theta = 90.0;
- }
- else {
- costheta = dx / sqrt(dx * dx + dy * dy);
- theta = acos(costheta);
- }
- if (dy < 0) {
- theta = (2 * Pi) - theta;
- }
- *aspect = theta;
- }
- /* project vector <dx,dy,dz> onto plane of constant y containing
- * final value should be -900.0 (looking up) to 900.0 (looking down) */
- if (dz == 0) {
- theta = 0.0;
- }
- else if (dx == 0 && dy == 0) {
- theta = Pi / 2.;
- }
- else {
- adjacent = sqrt(dx * dx + dy * dy);
- costheta = adjacent / sqrt(adjacent * adjacent + dz * dz);
- theta = acos(costheta);
- }
- if (dz > 0) {
- theta = -theta;
- }
- *slope = theta;
- if (degrees) {
- *aspect = *aspect * (180. / Pi);
- *slope = *slope * (180. / Pi);
- }
- return;
- }
- /*!
- \brief Draw North Arrow takes OpenGL coords and size
- \param pos2
- \param len
- \param fontbase
- \param arw_clr north arrow color
- \param text_clr text color
- \return 1
- */
- /*TODO: Store arrow somewhere to enable it's removal/change.
- Add option to specify north text and font. */
- int gsd_north_arrow(float *pos2, float len, GLuint fontbase,
- unsigned long arw_clr, unsigned long text_clr)
- {
- const char *txt;
- float v[4][3];
- float base[3][3];
- float Ntop[] = { 0.0, 0.0, 1.0 };
- base[0][Z] = base[1][Z] = base[2][Z] = pos2[Z];
- v[0][Z] = v[1][Z] = v[2][Z] = v[3][Z] = pos2[Z];
- base[0][X] = pos2[X] - len / 16.;
- base[1][X] = pos2[X] + len / 16.;
- base[0][Y] = base[1][Y] = pos2[Y] - len / 2.;
- base[2][X] = pos2[X];
- base[2][Y] = pos2[Y] + .45 * len;
- v[0][X] = v[2][X] = pos2[X];
- v[1][X] = pos2[X] + len / 8.;
- v[3][X] = pos2[X] - len / 8.;
- v[0][Y] = pos2[Y] + .2 * len;
- v[1][Y] = v[3][Y] = pos2[Y] + .1 * len;
- v[2][Y] = pos2[Y] + .5 * len;
- /* make sure we are drawing in front buffer */
- GS_set_draw(GSD_FRONT);
- gsd_pushmatrix();
- gsd_do_scale(1);
- glNormal3fv(Ntop);
- gsd_color_func(arw_clr);
- gsd_bgnpolygon();
- glVertex3fv(base[0]);
- glVertex3fv(base[1]);
- glVertex3fv(base[2]);
- gsd_endpolygon();
- gsd_bgnpolygon();
- glVertex3fv(v[0]);
- glVertex3fv(v[1]);
- glVertex3fv(v[2]);
- glVertex3fv(v[0]);
- gsd_endpolygon();
- gsd_bgnpolygon();
- glVertex3fv(v[0]);
- glVertex3fv(v[2]);
- glVertex3fv(v[3]);
- glVertex3fv(v[0]);
- gsd_endpolygon();
- /* draw N for North */
- /* Need to pick a nice generic font */
- /* TODO -- project text position off arrow
- * bottom along azimuth
- */
- gsd_color_func(text_clr);
- txt = "North";
- /* adjust position of N text */
- base[0][X] -= gsd_get_txtwidth(txt, 18) - 20.;
- base[0][Y] -= gsd_get_txtheight(18) - 20.;
- glRasterPos3fv(base[0]);
- glListBase(fontbase);
- glCallLists(strlen(txt), GL_UNSIGNED_BYTE, (const GLvoid *)txt);
- GS_done_draw();
- gsd_popmatrix();
- gsd_flush();
- return (1);
- }
- /*!
- \brief ADD
- siz is height, sz is global exag to correct for.
- If onsurf in non-null, z component of dir is dropped and
- line-on-suf is used, resulting in length of arrow being proportional
- to slope
- \param center center point
- \param colr color value
- \param siz size value
- \param dir
- \param sz
- \param onsurf surface (geosurf)
- \return 1 no surface given
- \return 0 on surface
- */
- int gsd_arrow(float *center, unsigned long colr, float siz, float *dir,
- float sz, geosurf * onsurf)
- {
- float slope, aspect;
- float tmp[3];
- static int first = 1;
- if (first) {
- init_stuff();
- first = 0;
- }
- dir[Z] /= sz;
- GS_v3norm(dir);
- if (NULL != onsurf) {
- float base[3], tip[3], len;
- base[X] = center[X];
- base[Y] = center[Y];
- /* project dir to surface, after zexag */
- len = GS_P2distance(ORIGIN, dir); /* in case dir isn't normalized */
- tip[X] = center[X] + dir[X] * len * siz;
- tip[Y] = center[Y] + dir[Y] * len * siz;
- return gsd_arrow_onsurf(base, tip, colr, 2, onsurf);
- }
- dir_to_slope_aspect(dir, &slope, &aspect, 1);
- gsd_pushmatrix();
- gsd_translate(center[X], center[Y], center[Z]);
- gsd_scale(1.0, 1.0, 1.0 / sz);
- gsd_rot(aspect + 90, 'z');
- gsd_rot(slope + 90., 'x');
- gsd_scale(siz, siz, siz);
- gsd_color_func(colr);
- tmp[X] = 0.2;
- tmp[Y] = 0.0;
- tmp[Z] = 0.65;
- gsd_bgnline();
- gsd_vert_func(ORIGIN);
- gsd_vert_func(UP_NORM);
- gsd_endline();
- gsd_bgnline();
- gsd_vert_func(tmp);
- gsd_vert_func(UP_NORM);
- tmp[X] = -0.2;
- gsd_vert_func(tmp);
- gsd_endline();
- gsd_popmatrix();
- return (1);
- }
- /*!
- \brief Draw north arrow on surface
- \param base
- \param tip
- \param colr
- \param wid
- \param gs surface (geosurf)
- \return 0
- */
- int gsd_arrow_onsurf(float *base, float *tip, unsigned long colr, int wid,
- geosurf * gs)
- {
- static int first = 1;
- if (first) {
- init_stuff();
- first = 0;
- }
- gsd_linewidth(wid);
- gsd_color_func(colr);
- G_debug(3, "gsd_arrow_onsurf");
- G_debug(3, " %f %f -> %f %f", base[X], base[Y], tip[X], tip[Y]);
- gsd_line_onsurf(gs, base, tip);
- #ifdef DO_SPHERE_BASE
- {
- GS_v3dir(tip, base, dir0);
- GS_v3mag(dir0, &len);
- gsd_disc(base[X], base[Y], len / 10.);
- }
- #endif
- #ifdef ARROW_READY
- {
- base[Z] = tip[Z] = 0.0;
- GS_v3dir(tip, base, dir0);
- G_debug(3, " dir0: %f %f %f", dir0[X], dir0[Y], dir0[Z]);
- /* rotate this direction 90 degrees */
- GS_v3cross(dir0, UP_NORM, dir2);
- GS_v3mag(dir0, &len);
- GS_v3eq(dir1, dir0);
- G_debug(3, " len: %f", len);
- G_debug(3, " a-dir1: %f %f %f", dir1[X], dir1[Y], dir1[Z]);
- G_debug(3, " a-dir2: %f %f %f", dir2[X], dir2[Y], dir2[Z]);
- dim1 = len * .7;
- dim2 = len * .2;
- GS_v3mult(dir1, dim1);
- GS_v3mult(dir2, dim2);
- G_debug(3, " b-dir1: %f %f %f", dir1[X], dir1[Y], dir1[Z]);
- G_debug(3, " b-dir2: %f %f %f", dir2[X], dir2[Y], dir2[Z]);
- GS_v3eq(tmp, base);
- GS_v3add(tmp, dir1);
- GS_v3add(tmp, dir2);
- G_debug(3, " %f %f -> ", tmp[X], tmp[Y]);
- gsd_line_onsurf(gs, tmp, tip);
- GS_v3cross(dir0, DOWN_NORM, dir2);
- GS_v3mult(dir2, dim2);
- GS_v3eq(tmp, base);
- G_debug(3, " dir1: %f %f %f", dir1[X], dir1[Y], dir1[Z]);
- G_debug(3, " dir2: %f %f %f", dir2[X], dir2[Y], dir2[Z]);
- GS_v3add(tmp, dir1);
- GS_v3add(tmp, dir2);
- G_debug(3, " %f %f", tmp[X], tmp[Y]);
- gsd_line_onsurf(gs, tip, tmp);
- }
- #endif
- return (0);
- }
- /*!
- \brief Draw 3d north arrow
- \param center center point
- \param colr color value
- \param siz1 height
- \param siz2 is diameter
- \param dir
- \param sz
- */
- void gsd_3darrow(float *center, unsigned long colr, float siz1, float siz2,
- float *dir, float sz)
- {
- float slope, aspect;
- int preshade;
- static int first = 1;
- static int list;
- static int debugint = 1;
- dir[Z] /= sz;
- GS_v3norm(dir);
- dir_to_slope_aspect(dir, &slope, &aspect, 1);
- if (debugint > 100) {
- G_debug(3, "gsd_3darrow()");
- G_debug(3, " pt: %f,%f,%f dir: %f,%f,%f slope: %f aspect: %f",
- center[X], center[Y], center[Z], dir[X], dir[Y], dir[Z],
- slope, aspect);
- debugint = 1;
- }
- debugint++;
- preshade = gsd_getshademodel();
- /*
- gsd_shademodel(0);
- want flat shading? */
- gsd_pushmatrix();
- gsd_translate(center[X], center[Y], center[Z]);
- gsd_scale(1.0, 1.0, 1.0 / sz);
- gsd_rot(aspect + 90, 'z');
- gsd_rot(slope + 90., 'x');
- gsd_scale(siz2, siz2, siz1);
- gsd_color_func(colr);
- if (first) {
- /* combine these into an object */
- first = 0;
- list = gsd_makelist();
- gsd_bgnlist(list, 1);
- gsd_backface(1);
- gsd_pushmatrix();
- gsd_scale(.10, .10, .75); /* narrow cyl */
- primitive_cylinder(colr, 0);
- gsd_popmatrix();
- gsd_pushmatrix();
- gsd_translate(0.0, 0.0, .60);
- gsd_scale(0.3, 0.3, 0.4); /* cone */
- primitive_cone(colr);
- gsd_popmatrix();
- gsd_backface(0);
- gsd_endlist();
- }
- else {
- gsd_calllist(list);
- }
- gsd_popmatrix();
- gsd_shademodel(preshade);
- return;
- }
- /*!
- \brief Draw Scalebar takes OpenGL coords and size
- Adapted from gsd_north_arrow Hamish Bowman Dec 2006
- \param pos2
- \param fontbase font-base
- \param bar_clr barscale color
- \param text_clr text color
- \return 1
- */
- int gsd_scalebar(float *pos2, float len, GLuint fontbase,
- unsigned long bar_clr, unsigned long text_clr)
- {
- char txt[100];
- float base[4][3];
- float Ntop[] = { 0.0, 0.0, 1.0 };
- base[0][Z] = base[1][Z] = base[2][Z] = base[3][Z] = pos2[Z];
- /* simple 1:8 rectangle *//* bump to X/20. for a 1:10 narrower bar? */
- base[0][X] = base[1][X] = pos2[X] - len / 2.;
- base[2][X] = base[3][X] = pos2[X] + len / 2.;
- base[0][Y] = base[3][Y] = pos2[Y] - len / 16.;
- base[1][Y] = base[2][Y] = pos2[Y] + len / 16.;
- /* make sure we are drawing in front buffer */
- GS_set_draw(GSD_FRONT);
- gsd_pushmatrix();
- gsd_do_scale(1); /* get map scale factor */
- glNormal3fv(Ntop);
- gsd_color_func(bar_clr);
- gsd_bgnpolygon();
- glVertex3fv(base[0]);
- glVertex3fv(base[1]);
- glVertex3fv(base[2]);
- glVertex3fv(base[3]);
- glVertex3fv(base[0]);
- gsd_endpolygon();
- /* draw units */
- /* Need to pick a nice generic font */
- /* TODO -- project text position off bar bottom along azimuth */
- gsd_color_func(text_clr);
- /* format text in a nice way */
- if (strcmp("meters", G_database_unit_name(TRUE)) == 0) {
- if (len > 2500)
- sprintf(txt, "%g km", len / 1000);
- else
- sprintf(txt, "%g meters", len);
- }
- else if (strcmp("feet", G_database_unit_name(TRUE)) == 0) {
- if (len > 5280)
- sprintf(txt, "%g miles", len / 5280);
- else if (len == 5280)
- sprintf(txt, "1 mile");
- else
- sprintf(txt, "%g feet", len);
- }
- else {
- sprintf(txt, "%g %s", len, G_database_unit_name(TRUE));
- }
- /* adjust position of text (In map units?!) */
- base[0][X] -= gsd_get_txtwidth(txt, 18) - 20.;
- base[0][Y] -= gsd_get_txtheight(18) - 20.;
- glRasterPos3fv(base[0]);
- glListBase(fontbase);
- glCallLists(strlen(txt), GL_BYTE, (GLubyte *) txt);
- GS_done_draw();
- gsd_popmatrix();
- gsd_flush();
- return (1);
- }
- /*!
- \brief Primitives only called after transforms
- Center is actually center at base of 8 sided cone
- \param col color value
- */
- void primitive_cone(unsigned long col)
- {
- float tip[3];
- static int first = 1;
- if (first) {
- init_stuff();
- first = 0;
- }
- tip[X] = tip[Y] = 0.0;
- tip[Z] = 1.0;
- gsd_bgntfan();
- gsd_litvert_func2(UP_NORM, col, tip);
- gsd_litvert_func2(ogverts[0], col, ogverts[0]);
- gsd_litvert_func2(ogverts[1], col, ogverts[1]);
- gsd_litvert_func2(ogverts[2], col, ogverts[2]);
- gsd_litvert_func2(ogverts[3], col, ogverts[3]);
- gsd_litvert_func2(ogverts[4], col, ogverts[4]);
- gsd_litvert_func2(ogverts[5], col, ogverts[5]);
- gsd_litvert_func2(ogverts[6], col, ogverts[6]);
- gsd_litvert_func2(ogverts[7], col, ogverts[7]);
- gsd_litvert_func2(ogverts[0], col, ogverts[0]);
- gsd_endtfan();
- return;
- }
- /*!
- \brief Primitives only called after transforms
- Center is actually center at base of 8 sided cylinder
- \param col color value
- \param caps
- */
- void primitive_cylinder(unsigned long col, int caps)
- {
- static int first = 1;
- if (first) {
- init_stuff();
- first = 0;
- }
- gsd_bgnqstrip();
- gsd_litvert_func2(ogverts[0], col, ogvertsplus[0]);
- gsd_litvert_func2(ogverts[0], col, ogverts[0]);
- gsd_litvert_func2(ogverts[1], col, ogvertsplus[1]);
- gsd_litvert_func2(ogverts[1], col, ogverts[1]);
- gsd_litvert_func2(ogverts[2], col, ogvertsplus[2]);
- gsd_litvert_func2(ogverts[2], col, ogverts[2]);
- gsd_litvert_func2(ogverts[3], col, ogvertsplus[3]);
- gsd_litvert_func2(ogverts[3], col, ogverts[3]);
- gsd_litvert_func2(ogverts[4], col, ogvertsplus[4]);
- gsd_litvert_func2(ogverts[4], col, ogverts[4]);
- gsd_litvert_func2(ogverts[5], col, ogvertsplus[5]);
- gsd_litvert_func2(ogverts[5], col, ogverts[5]);
- gsd_litvert_func2(ogverts[6], col, ogvertsplus[6]);
- gsd_litvert_func2(ogverts[6], col, ogverts[6]);
- gsd_litvert_func2(ogverts[7], col, ogvertsplus[7]);
- gsd_litvert_func2(ogverts[7], col, ogverts[7]);
- gsd_litvert_func2(ogverts[0], col, ogvertsplus[0]);
- gsd_litvert_func2(ogverts[0], col, ogverts[0]);
- gsd_endqstrip();
- if (caps) {
- /* draw top */
- gsd_bgntfan();
- gsd_litvert_func2(UP_NORM, col, UP_NORM);
- gsd_litvert_func2(UP_NORM, col, ogvertsplus[0]);
- gsd_litvert_func2(UP_NORM, col, ogvertsplus[1]);
- gsd_litvert_func2(UP_NORM, col, ogvertsplus[2]);
- gsd_litvert_func2(UP_NORM, col, ogvertsplus[3]);
- gsd_litvert_func2(UP_NORM, col, ogvertsplus[4]);
- gsd_litvert_func2(UP_NORM, col, ogvertsplus[5]);
- gsd_litvert_func2(UP_NORM, col, ogvertsplus[6]);
- gsd_litvert_func2(UP_NORM, col, ogvertsplus[7]);
- gsd_litvert_func2(UP_NORM, col, ogvertsplus[0]);
- gsd_endtfan();
- /* draw bottom */
- gsd_bgntfan();
- gsd_litvert_func2(DOWN_NORM, col, ORIGIN);
- gsd_litvert_func2(DOWN_NORM, col, ogverts[0]);
- gsd_litvert_func2(DOWN_NORM, col, ogverts[1]);
- gsd_litvert_func2(DOWN_NORM, col, ogverts[2]);
- gsd_litvert_func2(DOWN_NORM, col, ogverts[3]);
- gsd_litvert_func2(DOWN_NORM, col, ogverts[4]);
- gsd_litvert_func2(DOWN_NORM, col, ogverts[5]);
- gsd_litvert_func2(DOWN_NORM, col, ogverts[6]);
- gsd_litvert_func2(DOWN_NORM, col, ogverts[7]);
- gsd_litvert_func2(DOWN_NORM, col, ogverts[0]);
- gsd_endtfan();
- }
- return;
- }
- /*** ACS_MODIFY_BEGIN - sites_attribute management ********************************/
- /*
- Draws boxes that are used for histograms by gpd_obj function in gpd.c
- for site_attribute management
- */
- /*!
- \brief Vertices for box
- */
- float Box[8][3] =
- { {1.0, 1.0, -1.0}, {-1.0, 1.0, -1.0}, {-1.0, 1.0, 1.0}, {1.0, 1.0, 1.0},
- {1.0, -1.0, -1.0}, {-1.0, -1.0, -1.0}, {-1.0, -1.0, 1.0}, {1.0, -1.0, 1.0}
- };
- float BoxN[6][3] =
- { {0, 0, -ONORM}, {0, 0, ONORM}, {0, ONORM, 0}, {0, -ONORM, 0}, {ONORM, 0,
- 0},
- {-ONORM, 0, 0} };
- /*!
- \brief Draw box
- Warning siz is an array (we need it for scale only Z in histograms)
- \param center center point
- \param colr color value
- \param siz size value
- */
- void gsd_box(float *center, int colr, float *siz)
- {
- int preshade;
- gsd_pushmatrix();
- gsd_translate(center[X], center[Y], center[Z] + siz[2]);
- gsd_scale(siz[0], siz[1], siz[2]);
- preshade = gsd_getshademodel();
- gsd_shademodel(0); /* want flat shading */
- /* Top */
- gsd_bgnpolygon();
- gsd_litvert_func(BoxN[2], colr, Box[0]);
- gsd_litvert_func(BoxN[2], colr, Box[1]);
- gsd_litvert_func(BoxN[2], colr, Box[2]);
- gsd_litvert_func(BoxN[2], colr, Box[3]);
- gsd_endpolygon();
- /* Bottom */
- gsd_bgnpolygon();
- gsd_litvert_func(BoxN[3], colr, Box[7]);
- gsd_litvert_func(BoxN[3], colr, Box[6]);
- gsd_litvert_func(BoxN[3], colr, Box[5]);
- gsd_litvert_func(BoxN[3], colr, Box[4]);
- gsd_endpolygon();
- /* Right */
- gsd_bgnpolygon();
- gsd_litvert_func(BoxN[4], colr, Box[0]);
- gsd_litvert_func(BoxN[4], colr, Box[3]);
- gsd_litvert_func(BoxN[4], colr, Box[7]);
- gsd_litvert_func(BoxN[4], colr, Box[4]);
- gsd_endpolygon();
- /* Left */
- gsd_bgnpolygon();
- gsd_litvert_func(BoxN[5], colr, Box[1]);
- gsd_litvert_func(BoxN[5], colr, Box[5]);
- gsd_litvert_func(BoxN[5], colr, Box[6]);
- gsd_litvert_func(BoxN[5], colr, Box[2]);
- gsd_endpolygon();
- /* Front */
- gsd_bgnpolygon();
- gsd_litvert_func(BoxN[0], colr, Box[0]);
- gsd_litvert_func(BoxN[0], colr, Box[4]);
- gsd_litvert_func(BoxN[0], colr, Box[5]);
- gsd_litvert_func(BoxN[0], colr, Box[1]);
- gsd_endpolygon();
- /* Back */
- gsd_bgnpolygon();
- gsd_litvert_func(BoxN[1], colr, Box[3]);
- gsd_litvert_func(BoxN[1], colr, Box[2]);
- gsd_litvert_func(BoxN[1], colr, Box[6]);
- gsd_litvert_func(BoxN[1], colr, Box[7]);
- gsd_endpolygon();
- gsd_popmatrix();
- gsd_shademodel(preshade);
- return;
- }
- /*** ACS_MODIFY_END - sites_attribute management ********************************/
|