gsd_objs.c 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437
  1. /*!
  2. \file gsd_label.c
  3. \brief OGSF library - objects management (lower level functions)
  4. GRASS OpenGL gsurf OGSF Library
  5. (C) 1999-2008 by the GRASS Development Team
  6. This program is free software under the
  7. GNU General Public License (>=v2).
  8. Read the file COPYING that comes with GRASS
  9. for details.
  10. \author Bill Brown USACERL (October 1993)
  11. \author Doxygenized by Martin Landa <landa.martin gmail.com> (May 2008)
  12. */
  13. #include <stdlib.h>
  14. #include <string.h>
  15. #include <grass/gis.h>
  16. #include <grass/ogsf_proto.h>
  17. #include <grass/gstypes.h>
  18. #include "gsget.h"
  19. #include "math.h"
  20. #include "rowcol.h"
  21. static void init_stuff(void);
  22. /*!
  23. \brief vertices for octohedron
  24. */
  25. float Octo[6][3] = {
  26. {1.0, 0.0, 0.0},
  27. {0.0, 1.0, 0.0},
  28. {0.0, 0.0, 1.0},
  29. {-1.0, 0.0, 0.0},
  30. {0.0, -1.0, 0.0},
  31. {0.0, 0.0, -1.0}
  32. };
  33. #define ONORM .57445626
  34. /*!
  35. \brief normals for flat-shaded octohedron
  36. */
  37. float OctoN[8][3] = {
  38. {ONORM, ONORM, ONORM},
  39. {-ONORM, ONORM, ONORM},
  40. {ONORM, -ONORM, ONORM},
  41. {-ONORM, -ONORM, ONORM},
  42. {ONORM, ONORM, -ONORM},
  43. {-ONORM, ONORM, -ONORM},
  44. {ONORM, -ONORM, -ONORM},
  45. {-ONORM, -ONORM, -ONORM},
  46. };
  47. /*!
  48. ???? not sure if any of these are needed for correct lighting.
  49. float CubeNormals[6][3] = {
  50. {ONORM, 0, 0},
  51. {-ONORM, 0, 0},
  52. {0, ONORM, 0},
  53. {0, -ONORM, 0},
  54. {0, 0, ONORM},
  55. {0, 0, -ONORM}
  56. };
  57. */
  58. float CubeNormals[3][3] = {
  59. {0, -ONORM, 0},
  60. {0, 0, ONORM},
  61. {ONORM, 0, 0}
  62. };
  63. float CubeVertices[8][3] = {
  64. {-1.0, -1.0, -1.0},
  65. {1.0, -1.0, -1.0},
  66. {1.0, 1.0, -1.0},
  67. {-1.0, 1.0, -1.0},
  68. {-1.0, -1.0, 1.0},
  69. {1.0, -1.0, 1.0},
  70. {1.0, 1.0, 1.0},
  71. {-1.0, 1.0, 1.0}
  72. };
  73. float origin[3] = { 0.0, 0.0, 0.0 };
  74. #define UP_NORM Octo[2]
  75. #define DOWN_NORM Octo[5]
  76. #define ORIGIN origin
  77. /*!
  78. \brief vertices & normals for octagon in xy plane
  79. */
  80. float ogverts[8][3];
  81. /*!
  82. \brief vertices for octagon in xy plane, z=1
  83. */
  84. float ogvertsplus[8][3];
  85. float Pi;
  86. static void init_stuff(void)
  87. {
  88. float cos45;
  89. int i;
  90. static int first = 1;
  91. if (first) {
  92. first = 0;
  93. cos45 = cos(atan(1.0));
  94. for (i = 0; i < 8; i++) {
  95. ogverts[i][Z] = 0.0;
  96. ogvertsplus[i][Z] = 1.0;
  97. }
  98. ogverts[0][X] = ogvertsplus[0][X] = 1.0;
  99. ogverts[0][Y] = ogvertsplus[0][Y] = 0.0;
  100. ogverts[1][X] = ogvertsplus[1][X] = cos45;
  101. ogverts[1][Y] = ogvertsplus[1][Y] = cos45;
  102. ogverts[2][X] = ogvertsplus[2][X] = 0.0;
  103. ogverts[2][Y] = ogvertsplus[2][Y] = 1.0;
  104. ogverts[3][X] = ogvertsplus[3][X] = -cos45;
  105. ogverts[3][Y] = ogvertsplus[3][Y] = cos45;
  106. ogverts[4][X] = ogvertsplus[4][X] = -1.0;
  107. ogverts[4][Y] = ogvertsplus[4][Y] = 0.0;
  108. ogverts[5][X] = ogvertsplus[5][X] = -cos45;
  109. ogverts[5][Y] = ogvertsplus[5][Y] = -cos45;
  110. ogverts[6][X] = ogvertsplus[6][X] = 0.0;
  111. ogverts[6][Y] = ogvertsplus[6][Y] = -1.0;
  112. ogverts[7][X] = ogvertsplus[7][X] = cos45;
  113. ogverts[7][Y] = ogvertsplus[7][Y] = -cos45;
  114. Pi = 4.0 * atan(1.0);
  115. }
  116. return;
  117. }
  118. /*!
  119. \brief ADD
  120. \param center center point
  121. \param colr color value
  122. \param siz size value
  123. */
  124. void gsd_plus(float *center, int colr, float siz)
  125. {
  126. float v1[3], v2[3];
  127. gsd_color_func(colr);
  128. siz *= .5;
  129. v1[Z] = v2[Z] = center[Z];
  130. v1[X] = v2[X] = center[X];
  131. v1[Y] = center[Y] - siz;
  132. v2[Y] = center[Y] + siz;
  133. gsd_bgnline();
  134. gsd_vert_func(v1);
  135. gsd_vert_func(v2);
  136. gsd_endline();
  137. v1[Y] = v2[Y] = center[Y];
  138. v1[X] = center[X] - siz;
  139. v2[X] = center[X] + siz;
  140. gsd_bgnline();
  141. gsd_vert_func(v1);
  142. gsd_vert_func(v2);
  143. gsd_endline();
  144. return;
  145. }
  146. /*!
  147. \brief Line on surface, fix z-values
  148. \todo remove fudge, instead fudge the Z buffer
  149. \param gs surface (geosurf)
  150. \param v1 first point
  151. \param v2 second point
  152. */
  153. void gsd_line_onsurf(geosurf * gs, float *v1, float *v2)
  154. {
  155. int i, np;
  156. Point3 *pts;
  157. float fudge;
  158. pts = gsdrape_get_segments(gs, v1, v2, &np);
  159. if (pts) {
  160. fudge = FUDGE(gs);
  161. gsd_bgnline();
  162. for (i = 0; i < np; i++) {
  163. /* ACS */
  164. /* reverting back, as it broke displaying X symbol and query line */
  165. pts[i][Z] += fudge;
  166. /*pts[i][Z] *= fudge;*/
  167. gsd_vert_func(pts[i]);
  168. }
  169. gsd_endline();
  170. /* fix Z values? */
  171. v1[Z] = pts[0][Z];
  172. v2[Z] = pts[np - 1][Z];
  173. }
  174. return;
  175. }
  176. /*!
  177. \brief Multiline on surface, fix z-values
  178. \todo remove fudge, instead fudge the Z buffer
  179. Like above, except only draws first n points of line, or np,
  180. whichever is less. Returns number of points used. Fills
  181. pt with last pt drawn.
  182. \param gs surface (geosurf)
  183. \param v1 first point
  184. \param v2 second point
  185. \param pt
  186. \param n number of segments
  187. \param number of vertices
  188. */
  189. int gsd_nline_onsurf(geosurf * gs, float *v1, float *v2, float *pt, int n)
  190. {
  191. int i, np, pdraw;
  192. Point3 *pts;
  193. float fudge;
  194. pts = gsdrape_get_segments(gs, v1, v2, &np);
  195. if (pts) {
  196. pdraw = n < np ? n : np;
  197. fudge = FUDGE(gs);
  198. gsd_bgnline();
  199. for (i = 0; i < pdraw; i++) {
  200. pts[i][Z] += fudge;
  201. gsd_vert_func(pts[i]);
  202. }
  203. gsd_endline();
  204. pt[X] = pts[i - 1][X];
  205. pt[Y] = pts[i - 1][Y];
  206. /* fix Z values? */
  207. v1[Z] = pts[0][Z];
  208. v2[Z] = pts[np - 1][Z];
  209. return (i);
  210. }
  211. return (0);
  212. }
  213. /*!
  214. \brief Draw X symbol
  215. Note gs: NULL if flat
  216. \param gs surface (geosurf)
  217. \param center
  218. \param colr color value
  219. \param siz size value
  220. */
  221. void gsd_x(geosurf * gs, float *center, int colr, float siz)
  222. {
  223. float v1[3], v2[3];
  224. gsd_color_func(colr);
  225. siz *= .5;
  226. v1[Z] = v2[Z] = center[Z];
  227. v1[X] = center[X] - siz;
  228. v2[X] = center[X] + siz;
  229. v1[Y] = center[Y] - siz;
  230. v2[Y] = center[Y] + siz;
  231. if (gs) {
  232. gsd_line_onsurf(gs, v1, v2);
  233. }
  234. else {
  235. gsd_bgnline();
  236. gsd_vert_func(v1);
  237. gsd_vert_func(v2);
  238. gsd_endline();
  239. }
  240. v1[X] = center[X] - siz;
  241. v2[X] = center[X] + siz;
  242. v1[Y] = center[Y] + siz;
  243. v2[Y] = center[Y] - siz;
  244. if (gs) {
  245. gsd_line_onsurf(gs, v1, v2);
  246. }
  247. else {
  248. gsd_bgnline();
  249. gsd_vert_func(v1);
  250. gsd_vert_func(v2);
  251. gsd_endline();
  252. }
  253. return;
  254. }
  255. /*!
  256. \brief Draw diamond symbol
  257. \param center center point
  258. \param colr color value
  259. \param size size value
  260. */
  261. void gsd_diamond(float *center, unsigned long colr, float siz)
  262. {
  263. int preshade;
  264. /* seems right, but isn't
  265. siz *= .5;
  266. */
  267. gsd_pushmatrix();
  268. gsd_translate(center[X], center[Y], center[Z]);
  269. gsd_scale(siz, siz, siz);
  270. preshade = gsd_getshademodel();
  271. gsd_shademodel(0); /* want flat shading */
  272. gsd_bgnpolygon();
  273. gsd_litvert_func(OctoN[0], colr, Octo[0]);
  274. gsd_litvert_func(OctoN[0], colr, Octo[1]);
  275. gsd_litvert_func(OctoN[0], colr, Octo[2]);
  276. gsd_endpolygon();
  277. gsd_bgnpolygon();
  278. gsd_litvert_func(OctoN[1], colr, Octo[2]);
  279. gsd_litvert_func(OctoN[1], colr, Octo[1]);
  280. gsd_litvert_func(OctoN[1], colr, Octo[3]);
  281. gsd_endpolygon();
  282. gsd_bgnpolygon();
  283. gsd_litvert_func(OctoN[2], colr, Octo[2]);
  284. gsd_litvert_func(OctoN[2], colr, Octo[4]);
  285. gsd_litvert_func(OctoN[2], colr, Octo[0]);
  286. gsd_endpolygon();
  287. gsd_bgnpolygon();
  288. gsd_litvert_func(OctoN[3], colr, Octo[2]);
  289. gsd_litvert_func(OctoN[3], colr, Octo[3]);
  290. gsd_litvert_func(OctoN[3], colr, Octo[4]);
  291. gsd_endpolygon();
  292. gsd_bgnpolygon();
  293. gsd_litvert_func(OctoN[4], colr, Octo[0]);
  294. gsd_litvert_func(OctoN[4], colr, Octo[5]);
  295. gsd_litvert_func(OctoN[4], colr, Octo[1]);
  296. gsd_endpolygon();
  297. gsd_bgnpolygon();
  298. gsd_litvert_func(OctoN[5], colr, Octo[1]);
  299. gsd_litvert_func(OctoN[5], colr, Octo[5]);
  300. gsd_litvert_func(OctoN[5], colr, Octo[3]);
  301. gsd_endpolygon();
  302. gsd_bgnpolygon();
  303. gsd_litvert_func(OctoN[6], colr, Octo[5]);
  304. gsd_litvert_func(OctoN[6], colr, Octo[0]);
  305. gsd_litvert_func(OctoN[6], colr, Octo[4]);
  306. gsd_endpolygon();
  307. gsd_bgnpolygon();
  308. gsd_litvert_func(OctoN[7], colr, Octo[5]);
  309. gsd_litvert_func(OctoN[7], colr, Octo[4]);
  310. gsd_litvert_func(OctoN[7], colr, Octo[3]);
  311. gsd_endpolygon();
  312. #ifdef OCT_SHADED
  313. {
  314. gsd_bgntmesh();
  315. gsd_litvert_func(Octo[0], colr, Octo[0]);
  316. gsd_litvert_func(Octo[1], colr, Octo[1]);
  317. gsd_swaptmesh();
  318. gsd_litvert_func(Octo[2], colr, Octo[2]);
  319. gsd_swaptmesh();
  320. gsd_litvert_func(Octo[4], colr, Octo[4]);
  321. gsd_swaptmesh();
  322. gsd_litvert_func(Octo[5], colr, Octo[5]);
  323. gsd_swaptmesh();
  324. gsd_litvert_func(Octo[1], colr, Octo[1]);
  325. gsd_litvert_func(Octo[3], colr, Octo[3]);
  326. gsd_litvert_func(Octo[2], colr, Octo[2]);
  327. gsd_swaptmesh();
  328. gsd_litvert_func(Octo[4], colr, Octo[4]);
  329. gsd_swaptmesh();
  330. gsd_litvert_func(Octo[5], colr, Octo[5]);
  331. gsd_swaptmesh();
  332. gsd_litvert_func(Octo[1], colr, Octo[1]);
  333. gsd_endtmesh();
  334. }
  335. #endif
  336. gsd_popmatrix();
  337. gsd_shademodel(preshade);
  338. return;
  339. }
  340. /*!
  341. \brief Draw cube
  342. Added by Hamish Bowman Nov 2005
  343. \param center center point
  344. \param colr color value
  345. \param siz size value
  346. */
  347. void gsd_cube(float *center, unsigned long colr, float siz)
  348. {
  349. int preshade;
  350. /* see gsd_diamond() "seems right, but isn't" */
  351. siz *= .5;
  352. gsd_pushmatrix();
  353. gsd_translate(center[X], center[Y], center[Z]);
  354. gsd_scale(siz, siz, siz);
  355. preshade = gsd_getshademodel();
  356. gsd_shademodel(0); /* want flat shading */
  357. /* N wall: */
  358. gsd_bgnpolygon();
  359. gsd_litvert_func(CubeNormals[0], colr, CubeVertices[2]);
  360. gsd_litvert_func(CubeNormals[0], colr, CubeVertices[3]);
  361. gsd_litvert_func(CubeNormals[0], colr, CubeVertices[7]);
  362. gsd_litvert_func(CubeNormals[0], colr, CubeVertices[6]);
  363. gsd_endpolygon();
  364. /* S wall: */
  365. gsd_bgnpolygon();
  366. gsd_litvert_func(CubeNormals[0], colr, CubeVertices[1]);
  367. gsd_litvert_func(CubeNormals[0], colr, CubeVertices[5]);
  368. gsd_litvert_func(CubeNormals[0], colr, CubeVertices[4]);
  369. gsd_litvert_func(CubeNormals[0], colr, CubeVertices[0]);
  370. gsd_endpolygon();
  371. /* E wall: */
  372. gsd_bgnpolygon();
  373. gsd_litvert_func(CubeNormals[1], colr, CubeVertices[2]);
  374. gsd_litvert_func(CubeNormals[1], colr, CubeVertices[6]);
  375. gsd_litvert_func(CubeNormals[1], colr, CubeVertices[5]);
  376. gsd_litvert_func(CubeNormals[1], colr, CubeVertices[1]);
  377. gsd_endpolygon();
  378. /* W wall: */
  379. gsd_bgnpolygon();
  380. gsd_litvert_func(CubeNormals[1], colr, CubeVertices[0]);
  381. gsd_litvert_func(CubeNormals[1], colr, CubeVertices[4]);
  382. gsd_litvert_func(CubeNormals[1], colr, CubeVertices[7]);
  383. gsd_litvert_func(CubeNormals[1], colr, CubeVertices[3]);
  384. gsd_endpolygon();
  385. /* lower wall: */
  386. gsd_bgnpolygon();
  387. gsd_litvert_func(CubeNormals[2], colr, CubeVertices[0]);
  388. gsd_litvert_func(CubeNormals[2], colr, CubeVertices[1]);
  389. gsd_litvert_func(CubeNormals[2], colr, CubeVertices[2]);
  390. gsd_litvert_func(CubeNormals[2], colr, CubeVertices[3]);
  391. gsd_endpolygon();
  392. /* top wall: */
  393. gsd_bgnpolygon();
  394. gsd_litvert_func(CubeNormals[2], colr, CubeVertices[4]);
  395. gsd_litvert_func(CubeNormals[2], colr, CubeVertices[5]);
  396. gsd_litvert_func(CubeNormals[2], colr, CubeVertices[6]);
  397. gsd_litvert_func(CubeNormals[2], colr, CubeVertices[7]);
  398. gsd_endpolygon();
  399. gsd_popmatrix();
  400. gsd_shademodel(preshade);
  401. return;
  402. }
  403. /*!
  404. \brief Draw box
  405. Added by Hamish Bowman Nov 2005
  406. \param center center point
  407. \param colr color value
  408. \param siz size value
  409. */
  410. void gsd_draw_box(float *center, unsigned long colr, float siz)
  411. {
  412. /* see gsd_diamond() "seems right, but isn't" */
  413. siz *= .5;
  414. gsd_pushmatrix();
  415. gsd_translate(center[X], center[Y], center[Z]);
  416. gsd_scale(siz, siz, siz);
  417. gsd_color_func(colr);
  418. gsd_bgnline(); /* N wall */
  419. gsd_vert_func(CubeVertices[2]);
  420. gsd_vert_func(CubeVertices[3]);
  421. gsd_vert_func(CubeVertices[7]);
  422. gsd_vert_func(CubeVertices[6]);
  423. gsd_vert_func(CubeVertices[2]);
  424. gsd_endline();
  425. gsd_bgnline(); /* S wall */
  426. gsd_vert_func(CubeVertices[1]);
  427. gsd_vert_func(CubeVertices[5]);
  428. gsd_vert_func(CubeVertices[4]);
  429. gsd_vert_func(CubeVertices[0]);
  430. gsd_vert_func(CubeVertices[1]);
  431. gsd_endline();
  432. gsd_bgnline();
  433. gsd_vert_func(CubeVertices[1]);
  434. gsd_vert_func(CubeVertices[2]);
  435. gsd_endline();
  436. gsd_bgnline();
  437. gsd_vert_func(CubeVertices[3]);
  438. gsd_vert_func(CubeVertices[0]);
  439. gsd_endline();
  440. gsd_bgnline();
  441. gsd_vert_func(CubeVertices[5]);
  442. gsd_vert_func(CubeVertices[6]);
  443. gsd_endline();
  444. gsd_bgnline();
  445. gsd_vert_func(CubeVertices[4]);
  446. gsd_vert_func(CubeVertices[7]);
  447. gsd_endline();
  448. gsd_popmatrix();
  449. return;
  450. }
  451. /*!
  452. \brief Draw sphere
  453. \param center center point
  454. \param colr color value
  455. \param size size value
  456. */
  457. void gsd_drawsphere(float *center, unsigned long colr, float siz)
  458. {
  459. siz *= .5; /* siz is diameter, gsd_sphere uses radius */
  460. gsd_color_func(colr);
  461. gsd_sphere(center, siz);
  462. return;
  463. }
  464. /*!
  465. \brief Draw diamond lines
  466. */
  467. void gsd_diamond_lines(void)
  468. {
  469. gsd_bgnline();
  470. gsd_vert_func(Octo[0]);
  471. gsd_vert_func(Octo[3]);
  472. gsd_endline();
  473. gsd_bgnline();
  474. gsd_vert_func(Octo[1]);
  475. gsd_vert_func(Octo[4]);
  476. gsd_endline();
  477. gsd_bgnline();
  478. gsd_vert_func(Octo[2]);
  479. gsd_vert_func(Octo[5]);
  480. gsd_endline();
  481. return;
  482. }
  483. /*!
  484. \brief Draw asterisk
  485. \param center center point
  486. \param colr color value
  487. \param siz size value
  488. */
  489. void gsd_draw_asterisk(float *center, unsigned long colr, float siz)
  490. {
  491. float angle;
  492. angle = 45.; /* degrees */
  493. gsd_pushmatrix();
  494. gsd_translate(center[X], center[Y], center[Z]);
  495. gsd_scale(siz, siz, siz);
  496. gsd_color_func(colr);
  497. gsd_diamond_lines();
  498. gsd_pushmatrix();
  499. gsd_rot(angle, 'x');
  500. gsd_diamond_lines();
  501. gsd_popmatrix();
  502. gsd_pushmatrix();
  503. gsd_rot(-angle, 'x');
  504. gsd_diamond_lines();
  505. gsd_popmatrix();
  506. gsd_pushmatrix();
  507. gsd_rot(angle, 'y');
  508. gsd_diamond_lines();
  509. gsd_popmatrix();
  510. gsd_pushmatrix();
  511. gsd_rot(-angle, 'y');
  512. gsd_diamond_lines();
  513. gsd_popmatrix();
  514. gsd_pushmatrix();
  515. gsd_rot(angle, 'z');
  516. gsd_diamond_lines();
  517. gsd_popmatrix();
  518. gsd_pushmatrix();
  519. gsd_rot(-angle, 'z');
  520. gsd_diamond_lines();
  521. gsd_popmatrix();
  522. gsd_popmatrix();
  523. return;
  524. }
  525. /*!
  526. \brief Draw gyro
  527. \param center center point
  528. \param colr color value
  529. \param siz size value
  530. */
  531. void gsd_draw_gyro(float *center, unsigned long colr, float siz)
  532. {
  533. int i;
  534. gsd_pushmatrix();
  535. gsd_translate(center[X], center[Y], center[Z]);
  536. gsd_scale(siz, siz, siz);
  537. gsd_color_func(colr);
  538. /* vert axis */
  539. gsd_bgnline();
  540. gsd_vert_func(Octo[2]);
  541. gsd_vert_func(Octo[5]);
  542. gsd_endline();
  543. /* spokes */
  544. gsd_pushmatrix();
  545. for (i = 0; i < 6; i++) {
  546. gsd_rot(30., 'z');
  547. gsd_bgnline();
  548. gsd_vert_func(Octo[0]);
  549. gsd_vert_func(Octo[3]);
  550. gsd_endline();
  551. }
  552. gsd_popmatrix();
  553. gsd_color_func(colr);
  554. gsd_circ(0., 0., 1.);
  555. gsd_pushmatrix();
  556. gsd_rot(90., 'x');
  557. gsd_circ(0., 0., 1.);
  558. gsd_popmatrix();
  559. gsd_pushmatrix();
  560. gsd_rot(90., 'y');
  561. gsd_circ(0., 0., 1.);
  562. gsd_popmatrix();
  563. gsd_popmatrix();
  564. return;
  565. }
  566. /*!
  567. \brief Draw 3d cursor
  568. \param pt point
  569. */
  570. void gsd_3dcursor(float *pt)
  571. {
  572. float big, vert[3];
  573. big = 10000.;
  574. gsd_bgnline();
  575. vert[X] = pt[X];
  576. vert[Y] = pt[Y];
  577. vert[Z] = big;
  578. gsd_vert_func(vert);
  579. vert[Z] = -big;
  580. gsd_vert_func(vert);
  581. gsd_endline();
  582. gsd_bgnline();
  583. vert[X] = pt[X];
  584. vert[Z] = pt[Z];
  585. vert[Y] = big;
  586. gsd_vert_func(vert);
  587. vert[Y] = -big;
  588. gsd_vert_func(vert);
  589. gsd_endline();
  590. gsd_bgnline();
  591. vert[Y] = pt[Y];
  592. vert[Z] = pt[Z];
  593. vert[X] = big;
  594. gsd_vert_func(vert);
  595. vert[X] = -big;
  596. gsd_vert_func(vert);
  597. gsd_endline();
  598. return;
  599. }
  600. /*!
  601. \brief ADD
  602. \param dir
  603. \param slope
  604. \param ascpect
  605. \param degrees
  606. */
  607. void dir_to_slope_aspect(float *dir, float *slope, float *aspect, int degrees)
  608. {
  609. float dx, dy, dz;
  610. float costheta, theta, adjacent;
  611. dx = dir[X];
  612. dy = dir[Y];
  613. dz = dir[Z];
  614. /* project vector <dx,dy,dz> onto plane of constant z containing
  615. * final value should be 0.0 to 3600.0 */
  616. if (dx == 0 && dy == 0) {
  617. *aspect = 0.;
  618. }
  619. else {
  620. if (dx == 0) {
  621. theta = 90.0;
  622. }
  623. else {
  624. costheta = dx / sqrt(dx * dx + dy * dy);
  625. theta = acos(costheta);
  626. }
  627. if (dy < 0) {
  628. theta = (2 * Pi) - theta;
  629. }
  630. *aspect = theta;
  631. }
  632. /* project vector <dx,dy,dz> onto plane of constant y containing
  633. * final value should be -900.0 (looking up) to 900.0 (looking down) */
  634. if (dz == 0) {
  635. theta = 0.0;
  636. }
  637. else if (dx == 0 && dy == 0) {
  638. theta = Pi / 2.;
  639. }
  640. else {
  641. adjacent = sqrt(dx * dx + dy * dy);
  642. costheta = adjacent / sqrt(adjacent * adjacent + dz * dz);
  643. theta = acos(costheta);
  644. }
  645. if (dz > 0) {
  646. theta = -theta;
  647. }
  648. *slope = theta;
  649. if (degrees) {
  650. *aspect = *aspect * (180. / Pi);
  651. *slope = *slope * (180. / Pi);
  652. }
  653. return;
  654. }
  655. /*!
  656. \brief Draw North Arrow takes OpenGL coords and size
  657. \param pos2
  658. \param len
  659. \param fontbase
  660. \param arw_clr north arrow color
  661. \param text_clr text color
  662. \return 1
  663. */
  664. /*TODO: Store arrow somewhere to enable it's removal/change.
  665. Add option to specify north text and font. */
  666. int gsd_north_arrow(float *pos2, float len, GLuint fontbase,
  667. unsigned long arw_clr, unsigned long text_clr)
  668. {
  669. const char *txt;
  670. float v[4][3];
  671. float base[3][3];
  672. float Ntop[] = { 0.0, 0.0, 1.0 };
  673. base[0][Z] = base[1][Z] = base[2][Z] = pos2[Z];
  674. v[0][Z] = v[1][Z] = v[2][Z] = v[3][Z] = pos2[Z];
  675. base[0][X] = pos2[X] - len / 16.;
  676. base[1][X] = pos2[X] + len / 16.;
  677. base[0][Y] = base[1][Y] = pos2[Y] - len / 2.;
  678. base[2][X] = pos2[X];
  679. base[2][Y] = pos2[Y] + .45 * len;
  680. v[0][X] = v[2][X] = pos2[X];
  681. v[1][X] = pos2[X] + len / 8.;
  682. v[3][X] = pos2[X] - len / 8.;
  683. v[0][Y] = pos2[Y] + .2 * len;
  684. v[1][Y] = v[3][Y] = pos2[Y] + .1 * len;
  685. v[2][Y] = pos2[Y] + .5 * len;
  686. /* make sure we are drawing in front buffer */
  687. GS_set_draw(GSD_FRONT);
  688. gsd_pushmatrix();
  689. gsd_do_scale(1);
  690. glNormal3fv(Ntop);
  691. gsd_color_func(arw_clr);
  692. gsd_bgnpolygon();
  693. glVertex3fv(base[0]);
  694. glVertex3fv(base[1]);
  695. glVertex3fv(base[2]);
  696. gsd_endpolygon();
  697. gsd_bgnpolygon();
  698. glVertex3fv(v[0]);
  699. glVertex3fv(v[1]);
  700. glVertex3fv(v[2]);
  701. glVertex3fv(v[0]);
  702. gsd_endpolygon();
  703. gsd_bgnpolygon();
  704. glVertex3fv(v[0]);
  705. glVertex3fv(v[2]);
  706. glVertex3fv(v[3]);
  707. glVertex3fv(v[0]);
  708. gsd_endpolygon();
  709. /* draw N for North */
  710. /* Need to pick a nice generic font */
  711. /* TODO -- project text position off arrow
  712. * bottom along azimuth
  713. */
  714. gsd_color_func(text_clr);
  715. txt = "North";
  716. /* adjust position of N text */
  717. base[0][X] -= gsd_get_txtwidth(txt, 18) - 20.;
  718. base[0][Y] -= gsd_get_txtheight(18) - 20.;
  719. glRasterPos3fv(base[0]);
  720. glListBase(fontbase);
  721. glCallLists(strlen(txt), GL_UNSIGNED_BYTE, (const GLvoid *)txt);
  722. GS_done_draw();
  723. gsd_popmatrix();
  724. gsd_flush();
  725. return (1);
  726. }
  727. /*!
  728. \brief ADD
  729. siz is height, sz is global exag to correct for.
  730. If onsurf in non-null, z component of dir is dropped and
  731. line-on-suf is used, resulting in length of arrow being proportional
  732. to slope
  733. \param center center point
  734. \param colr color value
  735. \param siz size value
  736. \param dir
  737. \param sz
  738. \param onsurf surface (geosurf)
  739. \return 1 no surface given
  740. \return 0 on surface
  741. */
  742. int gsd_arrow(float *center, unsigned long colr, float siz, float *dir,
  743. float sz, geosurf * onsurf)
  744. {
  745. float slope, aspect;
  746. float tmp[3];
  747. static int first = 1;
  748. if (first) {
  749. init_stuff();
  750. first = 0;
  751. }
  752. dir[Z] /= sz;
  753. GS_v3norm(dir);
  754. if (NULL != onsurf) {
  755. float base[3], tip[3], len;
  756. base[X] = center[X];
  757. base[Y] = center[Y];
  758. /* project dir to surface, after zexag */
  759. len = GS_P2distance(ORIGIN, dir); /* in case dir isn't normalized */
  760. tip[X] = center[X] + dir[X] * len * siz;
  761. tip[Y] = center[Y] + dir[Y] * len * siz;
  762. return gsd_arrow_onsurf(base, tip, colr, 2, onsurf);
  763. }
  764. dir_to_slope_aspect(dir, &slope, &aspect, 1);
  765. gsd_pushmatrix();
  766. gsd_translate(center[X], center[Y], center[Z]);
  767. gsd_scale(1.0, 1.0, 1.0 / sz);
  768. gsd_rot(aspect + 90, 'z');
  769. gsd_rot(slope + 90., 'x');
  770. gsd_scale(siz, siz, siz);
  771. gsd_color_func(colr);
  772. tmp[X] = 0.2;
  773. tmp[Y] = 0.0;
  774. tmp[Z] = 0.65;
  775. gsd_bgnline();
  776. gsd_vert_func(ORIGIN);
  777. gsd_vert_func(UP_NORM);
  778. gsd_endline();
  779. gsd_bgnline();
  780. gsd_vert_func(tmp);
  781. gsd_vert_func(UP_NORM);
  782. tmp[X] = -0.2;
  783. gsd_vert_func(tmp);
  784. gsd_endline();
  785. gsd_popmatrix();
  786. return (1);
  787. }
  788. /*!
  789. \brief Draw north arrow on surface
  790. \param base
  791. \param tip
  792. \param colr
  793. \param wid
  794. \param gs surface (geosurf)
  795. \return 0
  796. */
  797. int gsd_arrow_onsurf(float *base, float *tip, unsigned long colr, int wid,
  798. geosurf * gs)
  799. {
  800. static int first = 1;
  801. if (first) {
  802. init_stuff();
  803. first = 0;
  804. }
  805. gsd_linewidth(wid);
  806. gsd_color_func(colr);
  807. G_debug(3, "gsd_arrow_onsurf");
  808. G_debug(3, " %f %f -> %f %f", base[X], base[Y], tip[X], tip[Y]);
  809. gsd_line_onsurf(gs, base, tip);
  810. #ifdef DO_SPHERE_BASE
  811. {
  812. GS_v3dir(tip, base, dir0);
  813. GS_v3mag(dir0, &len);
  814. gsd_disc(base[X], base[Y], len / 10.);
  815. }
  816. #endif
  817. #ifdef ARROW_READY
  818. {
  819. base[Z] = tip[Z] = 0.0;
  820. GS_v3dir(tip, base, dir0);
  821. G_debug(3, " dir0: %f %f %f", dir0[X], dir0[Y], dir0[Z]);
  822. /* rotate this direction 90 degrees */
  823. GS_v3cross(dir0, UP_NORM, dir2);
  824. GS_v3mag(dir0, &len);
  825. GS_v3eq(dir1, dir0);
  826. G_debug(3, " len: %f", len);
  827. G_debug(3, " a-dir1: %f %f %f", dir1[X], dir1[Y], dir1[Z]);
  828. G_debug(3, " a-dir2: %f %f %f", dir2[X], dir2[Y], dir2[Z]);
  829. dim1 = len * .7;
  830. dim2 = len * .2;
  831. GS_v3mult(dir1, dim1);
  832. GS_v3mult(dir2, dim2);
  833. G_debug(3, " b-dir1: %f %f %f", dir1[X], dir1[Y], dir1[Z]);
  834. G_debug(3, " b-dir2: %f %f %f", dir2[X], dir2[Y], dir2[Z]);
  835. GS_v3eq(tmp, base);
  836. GS_v3add(tmp, dir1);
  837. GS_v3add(tmp, dir2);
  838. G_debug(3, " %f %f -> ", tmp[X], tmp[Y]);
  839. gsd_line_onsurf(gs, tmp, tip);
  840. GS_v3cross(dir0, DOWN_NORM, dir2);
  841. GS_v3mult(dir2, dim2);
  842. GS_v3eq(tmp, base);
  843. G_debug(3, " dir1: %f %f %f", dir1[X], dir1[Y], dir1[Z]);
  844. G_debug(3, " dir2: %f %f %f", dir2[X], dir2[Y], dir2[Z]);
  845. GS_v3add(tmp, dir1);
  846. GS_v3add(tmp, dir2);
  847. G_debug(3, " %f %f", tmp[X], tmp[Y]);
  848. gsd_line_onsurf(gs, tip, tmp);
  849. }
  850. #endif
  851. return (0);
  852. }
  853. /*!
  854. \brief Draw 3d north arrow
  855. \param center center point
  856. \param colr color value
  857. \param siz1 height
  858. \param siz2 is diameter
  859. \param dir
  860. \param sz
  861. */
  862. void gsd_3darrow(float *center, unsigned long colr, float siz1, float siz2,
  863. float *dir, float sz)
  864. {
  865. float slope, aspect;
  866. int preshade;
  867. static int first = 1;
  868. static int list;
  869. static int debugint = 1;
  870. dir[Z] /= sz;
  871. GS_v3norm(dir);
  872. dir_to_slope_aspect(dir, &slope, &aspect, 1);
  873. if (debugint > 100) {
  874. G_debug(3, "gsd_3darrow()");
  875. G_debug(3, " pt: %f,%f,%f dir: %f,%f,%f slope: %f aspect: %f",
  876. center[X], center[Y], center[Z], dir[X], dir[Y], dir[Z],
  877. slope, aspect);
  878. debugint = 1;
  879. }
  880. debugint++;
  881. preshade = gsd_getshademodel();
  882. /*
  883. gsd_shademodel(0);
  884. want flat shading? */
  885. gsd_pushmatrix();
  886. gsd_translate(center[X], center[Y], center[Z]);
  887. gsd_scale(1.0, 1.0, 1.0 / sz);
  888. gsd_rot(aspect + 90, 'z');
  889. gsd_rot(slope + 90., 'x');
  890. gsd_scale(siz2, siz2, siz1);
  891. gsd_color_func(colr);
  892. if (first) {
  893. /* combine these into an object */
  894. first = 0;
  895. list = gsd_makelist();
  896. gsd_bgnlist(list, 1);
  897. gsd_backface(1);
  898. gsd_pushmatrix();
  899. gsd_scale(.10, .10, .75); /* narrow cyl */
  900. primitive_cylinder(colr, 0);
  901. gsd_popmatrix();
  902. gsd_pushmatrix();
  903. gsd_translate(0.0, 0.0, .60);
  904. gsd_scale(0.3, 0.3, 0.4); /* cone */
  905. primitive_cone(colr);
  906. gsd_popmatrix();
  907. gsd_backface(0);
  908. gsd_endlist();
  909. }
  910. else {
  911. gsd_calllist(list);
  912. }
  913. gsd_popmatrix();
  914. gsd_shademodel(preshade);
  915. return;
  916. }
  917. /*!
  918. \brief Draw Scalebar takes OpenGL coords and size
  919. Adapted from gsd_north_arrow Hamish Bowman Dec 2006
  920. \param pos2
  921. \param fontbase font-base
  922. \param bar_clr barscale color
  923. \param text_clr text color
  924. \return 1
  925. */
  926. int gsd_scalebar(float *pos2, float len, GLuint fontbase,
  927. unsigned long bar_clr, unsigned long text_clr)
  928. {
  929. char txt[100];
  930. float base[4][3];
  931. float Ntop[] = { 0.0, 0.0, 1.0 };
  932. base[0][Z] = base[1][Z] = base[2][Z] = base[3][Z] = pos2[Z];
  933. /* simple 1:8 rectangle *//* bump to X/20. for a 1:10 narrower bar? */
  934. base[0][X] = base[1][X] = pos2[X] - len / 2.;
  935. base[2][X] = base[3][X] = pos2[X] + len / 2.;
  936. base[0][Y] = base[3][Y] = pos2[Y] - len / 16.;
  937. base[1][Y] = base[2][Y] = pos2[Y] + len / 16.;
  938. /* make sure we are drawing in front buffer */
  939. GS_set_draw(GSD_FRONT);
  940. gsd_pushmatrix();
  941. gsd_do_scale(1); /* get map scale factor */
  942. glNormal3fv(Ntop);
  943. gsd_color_func(bar_clr);
  944. gsd_bgnpolygon();
  945. glVertex3fv(base[0]);
  946. glVertex3fv(base[1]);
  947. glVertex3fv(base[2]);
  948. glVertex3fv(base[3]);
  949. glVertex3fv(base[0]);
  950. gsd_endpolygon();
  951. /* draw units */
  952. /* Need to pick a nice generic font */
  953. /* TODO -- project text position off bar bottom along azimuth */
  954. gsd_color_func(text_clr);
  955. /* format text in a nice way */
  956. if (strcmp("meters", G_database_unit_name(TRUE)) == 0) {
  957. if (len > 2500)
  958. sprintf(txt, "%g km", len / 1000);
  959. else
  960. sprintf(txt, "%g meters", len);
  961. }
  962. else if (strcmp("feet", G_database_unit_name(TRUE)) == 0) {
  963. if (len > 5280)
  964. sprintf(txt, "%g miles", len / 5280);
  965. else if (len == 5280)
  966. sprintf(txt, "1 mile");
  967. else
  968. sprintf(txt, "%g feet", len);
  969. }
  970. else {
  971. sprintf(txt, "%g %s", len, G_database_unit_name(TRUE));
  972. }
  973. /* adjust position of text (In map units?!) */
  974. base[0][X] -= gsd_get_txtwidth(txt, 18) - 20.;
  975. base[0][Y] -= gsd_get_txtheight(18) - 20.;
  976. glRasterPos3fv(base[0]);
  977. glListBase(fontbase);
  978. glCallLists(strlen(txt), GL_BYTE, (GLubyte *) txt);
  979. GS_done_draw();
  980. gsd_popmatrix();
  981. gsd_flush();
  982. return (1);
  983. }
  984. /*!
  985. \brief Primitives only called after transforms
  986. Center is actually center at base of 8 sided cone
  987. \param col color value
  988. */
  989. void primitive_cone(unsigned long col)
  990. {
  991. float tip[3];
  992. static int first = 1;
  993. if (first) {
  994. init_stuff();
  995. first = 0;
  996. }
  997. tip[X] = tip[Y] = 0.0;
  998. tip[Z] = 1.0;
  999. gsd_bgntfan();
  1000. gsd_litvert_func2(UP_NORM, col, tip);
  1001. gsd_litvert_func2(ogverts[0], col, ogverts[0]);
  1002. gsd_litvert_func2(ogverts[1], col, ogverts[1]);
  1003. gsd_litvert_func2(ogverts[2], col, ogverts[2]);
  1004. gsd_litvert_func2(ogverts[3], col, ogverts[3]);
  1005. gsd_litvert_func2(ogverts[4], col, ogverts[4]);
  1006. gsd_litvert_func2(ogverts[5], col, ogverts[5]);
  1007. gsd_litvert_func2(ogverts[6], col, ogverts[6]);
  1008. gsd_litvert_func2(ogverts[7], col, ogverts[7]);
  1009. gsd_litvert_func2(ogverts[0], col, ogverts[0]);
  1010. gsd_endtfan();
  1011. return;
  1012. }
  1013. /*!
  1014. \brief Primitives only called after transforms
  1015. Center is actually center at base of 8 sided cylinder
  1016. \param col color value
  1017. \param caps
  1018. */
  1019. void primitive_cylinder(unsigned long col, int caps)
  1020. {
  1021. static int first = 1;
  1022. if (first) {
  1023. init_stuff();
  1024. first = 0;
  1025. }
  1026. gsd_bgnqstrip();
  1027. gsd_litvert_func2(ogverts[0], col, ogvertsplus[0]);
  1028. gsd_litvert_func2(ogverts[0], col, ogverts[0]);
  1029. gsd_litvert_func2(ogverts[1], col, ogvertsplus[1]);
  1030. gsd_litvert_func2(ogverts[1], col, ogverts[1]);
  1031. gsd_litvert_func2(ogverts[2], col, ogvertsplus[2]);
  1032. gsd_litvert_func2(ogverts[2], col, ogverts[2]);
  1033. gsd_litvert_func2(ogverts[3], col, ogvertsplus[3]);
  1034. gsd_litvert_func2(ogverts[3], col, ogverts[3]);
  1035. gsd_litvert_func2(ogverts[4], col, ogvertsplus[4]);
  1036. gsd_litvert_func2(ogverts[4], col, ogverts[4]);
  1037. gsd_litvert_func2(ogverts[5], col, ogvertsplus[5]);
  1038. gsd_litvert_func2(ogverts[5], col, ogverts[5]);
  1039. gsd_litvert_func2(ogverts[6], col, ogvertsplus[6]);
  1040. gsd_litvert_func2(ogverts[6], col, ogverts[6]);
  1041. gsd_litvert_func2(ogverts[7], col, ogvertsplus[7]);
  1042. gsd_litvert_func2(ogverts[7], col, ogverts[7]);
  1043. gsd_litvert_func2(ogverts[0], col, ogvertsplus[0]);
  1044. gsd_litvert_func2(ogverts[0], col, ogverts[0]);
  1045. gsd_endqstrip();
  1046. if (caps) {
  1047. /* draw top */
  1048. gsd_bgntfan();
  1049. gsd_litvert_func2(UP_NORM, col, UP_NORM);
  1050. gsd_litvert_func2(UP_NORM, col, ogvertsplus[0]);
  1051. gsd_litvert_func2(UP_NORM, col, ogvertsplus[1]);
  1052. gsd_litvert_func2(UP_NORM, col, ogvertsplus[2]);
  1053. gsd_litvert_func2(UP_NORM, col, ogvertsplus[3]);
  1054. gsd_litvert_func2(UP_NORM, col, ogvertsplus[4]);
  1055. gsd_litvert_func2(UP_NORM, col, ogvertsplus[5]);
  1056. gsd_litvert_func2(UP_NORM, col, ogvertsplus[6]);
  1057. gsd_litvert_func2(UP_NORM, col, ogvertsplus[7]);
  1058. gsd_litvert_func2(UP_NORM, col, ogvertsplus[0]);
  1059. gsd_endtfan();
  1060. /* draw bottom */
  1061. gsd_bgntfan();
  1062. gsd_litvert_func2(DOWN_NORM, col, ORIGIN);
  1063. gsd_litvert_func2(DOWN_NORM, col, ogverts[0]);
  1064. gsd_litvert_func2(DOWN_NORM, col, ogverts[1]);
  1065. gsd_litvert_func2(DOWN_NORM, col, ogverts[2]);
  1066. gsd_litvert_func2(DOWN_NORM, col, ogverts[3]);
  1067. gsd_litvert_func2(DOWN_NORM, col, ogverts[4]);
  1068. gsd_litvert_func2(DOWN_NORM, col, ogverts[5]);
  1069. gsd_litvert_func2(DOWN_NORM, col, ogverts[6]);
  1070. gsd_litvert_func2(DOWN_NORM, col, ogverts[7]);
  1071. gsd_litvert_func2(DOWN_NORM, col, ogverts[0]);
  1072. gsd_endtfan();
  1073. }
  1074. return;
  1075. }
  1076. /*** ACS_MODIFY_BEGIN - sites_attribute management ********************************/
  1077. /*
  1078. Draws boxes that are used for histograms by gpd_obj function in gpd.c
  1079. for site_attribute management
  1080. */
  1081. /*!
  1082. \brief Vertices for box
  1083. */
  1084. float Box[8][3] =
  1085. { {1.0, 1.0, -1.0}, {-1.0, 1.0, -1.0}, {-1.0, 1.0, 1.0}, {1.0, 1.0, 1.0},
  1086. {1.0, -1.0, -1.0}, {-1.0, -1.0, -1.0}, {-1.0, -1.0, 1.0}, {1.0, -1.0, 1.0}
  1087. };
  1088. float BoxN[6][3] =
  1089. { {0, 0, -ONORM}, {0, 0, ONORM}, {0, ONORM, 0}, {0, -ONORM, 0}, {ONORM, 0,
  1090. 0},
  1091. {-ONORM, 0, 0} };
  1092. /*!
  1093. \brief Draw box
  1094. Warning siz is an array (we need it for scale only Z in histograms)
  1095. \param center center point
  1096. \param colr color value
  1097. \param siz size value
  1098. */
  1099. void gsd_box(float *center, int colr, float *siz)
  1100. {
  1101. int preshade;
  1102. gsd_pushmatrix();
  1103. gsd_translate(center[X], center[Y], center[Z] + siz[2]);
  1104. gsd_scale(siz[0], siz[1], siz[2]);
  1105. preshade = gsd_getshademodel();
  1106. gsd_shademodel(0); /* want flat shading */
  1107. /* Top */
  1108. gsd_bgnpolygon();
  1109. gsd_litvert_func(BoxN[2], colr, Box[0]);
  1110. gsd_litvert_func(BoxN[2], colr, Box[1]);
  1111. gsd_litvert_func(BoxN[2], colr, Box[2]);
  1112. gsd_litvert_func(BoxN[2], colr, Box[3]);
  1113. gsd_endpolygon();
  1114. /* Bottom */
  1115. gsd_bgnpolygon();
  1116. gsd_litvert_func(BoxN[3], colr, Box[7]);
  1117. gsd_litvert_func(BoxN[3], colr, Box[6]);
  1118. gsd_litvert_func(BoxN[3], colr, Box[5]);
  1119. gsd_litvert_func(BoxN[3], colr, Box[4]);
  1120. gsd_endpolygon();
  1121. /* Right */
  1122. gsd_bgnpolygon();
  1123. gsd_litvert_func(BoxN[4], colr, Box[0]);
  1124. gsd_litvert_func(BoxN[4], colr, Box[3]);
  1125. gsd_litvert_func(BoxN[4], colr, Box[7]);
  1126. gsd_litvert_func(BoxN[4], colr, Box[4]);
  1127. gsd_endpolygon();
  1128. /* Left */
  1129. gsd_bgnpolygon();
  1130. gsd_litvert_func(BoxN[5], colr, Box[1]);
  1131. gsd_litvert_func(BoxN[5], colr, Box[5]);
  1132. gsd_litvert_func(BoxN[5], colr, Box[6]);
  1133. gsd_litvert_func(BoxN[5], colr, Box[2]);
  1134. gsd_endpolygon();
  1135. /* Front */
  1136. gsd_bgnpolygon();
  1137. gsd_litvert_func(BoxN[0], colr, Box[0]);
  1138. gsd_litvert_func(BoxN[0], colr, Box[4]);
  1139. gsd_litvert_func(BoxN[0], colr, Box[5]);
  1140. gsd_litvert_func(BoxN[0], colr, Box[1]);
  1141. gsd_endpolygon();
  1142. /* Back */
  1143. gsd_bgnpolygon();
  1144. gsd_litvert_func(BoxN[1], colr, Box[3]);
  1145. gsd_litvert_func(BoxN[1], colr, Box[2]);
  1146. gsd_litvert_func(BoxN[1], colr, Box[6]);
  1147. gsd_litvert_func(BoxN[1], colr, Box[7]);
  1148. gsd_endpolygon();
  1149. gsd_popmatrix();
  1150. gsd_shademodel(preshade);
  1151. return;
  1152. }
  1153. /*** ACS_MODIFY_END - sites_attribute management ********************************/