gsd_objs.c 33 KB

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