gsd_cplane.c 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360
  1. /*!
  2. \file lib/ogsf/gsd_cplane.c
  3. \brief OGSF library - manipulating surfaces (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, GMSL/University of Illinois (January 1993)
  11. \author Doxygenized by Martin Landa <landa.martin gmail.com> (May 2008)
  12. */
  13. #include <grass/ogsf.h>
  14. #include "rowcol.h"
  15. static void init_cplane(void);
  16. static float Cp_pt[4], Cp_norm[MAX_CPLANES][4];
  17. static float Cp_trans[MAX_CPLANES][3], Cp_rot[MAX_CPLANES][3];
  18. static int Cp_ison[MAX_CPLANES]; /* also need isdef? */
  19. static void init_cplane(void)
  20. {
  21. int i;
  22. gs_get_datacenter(Cp_pt);
  23. gs_get_data_avg_zmax(&(Cp_pt[Z]));
  24. for (i = 0; i < MAX_CPLANES; i++) {
  25. Cp_ison[i] = 0;
  26. Cp_norm[i][X] = 1.0;
  27. Cp_norm[i][Y] = Cp_norm[i][Z] = 0.0;
  28. Cp_norm[i][W] = 1.;
  29. Cp_rot[i][X] = Cp_trans[i][X] = 0.0;
  30. Cp_rot[i][Y] = Cp_trans[i][Y] = 0.0;
  31. Cp_rot[i][Z] = Cp_trans[i][Z] = 0.0;
  32. }
  33. return;
  34. }
  35. /*!
  36. \brief Define cplace
  37. \param num
  38. \param pt
  39. \param norm
  40. */
  41. void gsd_def_cplane(int num, float *pt, float *norm)
  42. {
  43. float sx, sy, sz, ppt[3];
  44. double params[4];
  45. float zmin, zmax;
  46. GS_get_scale(&sx, &sy, &sz, 1);
  47. /* Something's still wrong with the zexag - DONT USE TILT */
  48. GS_get_zrange(&zmin, &zmax, 0);
  49. ppt[0] = (pt[0] + Cp_pt[0]) * sx;
  50. ppt[1] = (pt[1] + Cp_pt[1]) * sy;
  51. ppt[2] = (pt[2] + Cp_pt[2] - zmin) * sz;
  52. params[0] = norm[0] * sx;
  53. params[1] = norm[1] * sy;
  54. params[2] = norm[2] * sz;
  55. GS_dv3norm(params);
  56. params[3] = -ppt[0] * params[0] - ppt[1] * params[1] - ppt[2] * params[2];
  57. gsd_def_clipplane(num, params);
  58. return;
  59. }
  60. /*!
  61. \brief Update cplaces
  62. Called when viewing matrix changes
  63. */
  64. void gsd_update_cplanes(void)
  65. {
  66. int i;
  67. for (i = 0; i < MAX_CPLANES; i++) {
  68. if (Cp_ison[i]) {
  69. gsd_def_cplane(i, Cp_trans[i], Cp_norm[i]);
  70. }
  71. }
  72. return;
  73. }
  74. /*!
  75. \brief ADD
  76. \param num
  77. */
  78. void gsd_cplane_on(int num)
  79. {
  80. static int first = 1;
  81. if (first) {
  82. first = 0;
  83. init_cplane();
  84. gsd_def_cplane(num, Cp_trans[num], Cp_norm[num]);
  85. }
  86. gsd_set_clipplane(num, 1);
  87. Cp_ison[num] = 1;
  88. return;
  89. }
  90. /*!
  91. \brief Turn off clip plane
  92. \param num cplane id
  93. */
  94. void gsd_cplane_off(int num)
  95. {
  96. gsd_set_clipplane(num, 0);
  97. Cp_ison[num] = 0;
  98. return;
  99. }
  100. /*!
  101. \brief Get cplane state
  102. <i>onstate</i> MUST be big enough to hold MAX_CPLANES ints
  103. \param onstate
  104. */
  105. void gsd_get_cplanes_state(int *onstate)
  106. {
  107. int i;
  108. for (i = 0; i < MAX_CPLANES; i++) {
  109. onstate[i] = Cp_ison[i];
  110. }
  111. return;
  112. }
  113. /*!
  114. \brief Get cplaces
  115. Planes MUST be big enough to hold MAX_CPLANES Point4s
  116. \param places surface coordinates, normal pointing away from visible side
  117. \return ADD
  118. */
  119. int gsd_get_cplanes(Point4 * planes)
  120. {
  121. int i, ons;
  122. Point3 thru;
  123. for (ons = i = 0; i < MAX_CPLANES; i++) {
  124. if (Cp_ison[i]) {
  125. thru[X] = Cp_pt[X] + Cp_trans[ons][X];
  126. thru[Y] = Cp_pt[Y] + Cp_trans[ons][Y];
  127. thru[Z] = Cp_pt[Z] + Cp_trans[ons][Z];
  128. planes[ons][X] = -Cp_norm[ons][X];
  129. planes[ons][Y] = -Cp_norm[ons][Y];
  130. planes[ons][Z] = -Cp_norm[ons][Z];
  131. planes[ons][W] = -(DOT3(planes[ons], thru));
  132. ons++;
  133. }
  134. }
  135. return (ons);
  136. }
  137. /*!
  138. \brief ADD
  139. \param num
  140. */
  141. void gsd_update_cpnorm(int num)
  142. {
  143. float v[1][4];
  144. v[0][X] = v[0][W] = 1.0;
  145. v[0][Y] = v[0][Z] = 0.0;
  146. P_pushmatrix();
  147. P_rot(Cp_rot[num][Z], 'z');
  148. P_rot(Cp_rot[num][Y], 'y');
  149. P_rot(Cp_rot[num][X], 'x');
  150. P_transform(1, v, &Cp_norm[num]);
  151. P_popmatrix();
  152. return;
  153. }
  154. /*!
  155. \brief ADD
  156. \param num
  157. \param rx,ry,rz
  158. */
  159. void gsd_cplane_setrot(int num, float rx, float ry, float rz)
  160. {
  161. Cp_rot[num][X] = rx;
  162. Cp_rot[num][Y] = ry;
  163. Cp_rot[num][Z] = rz;
  164. gsd_update_cpnorm(num);
  165. gsd_def_cplane(num, Cp_trans[num], Cp_norm[num]);
  166. return;
  167. }
  168. /*!
  169. \brief ADD
  170. \param num
  171. \param tx,ty,tz
  172. */
  173. void gsd_cplane_settrans(int num, float tx, float ty, float tz)
  174. {
  175. Cp_trans[num][X] = tx;
  176. Cp_trans[num][Y] = ty;
  177. Cp_trans[num][Z] = tz;
  178. gsd_def_cplane(num, Cp_trans[num], Cp_norm[num]);
  179. return;
  180. }
  181. /*!
  182. \brief ADD
  183. \param surf1 first surface (geosurf)
  184. \param surf2 second surface (geosurf) [unused]
  185. \param cpnum
  186. */
  187. void gsd_draw_cplane_fence(geosurf * surf1, geosurf * surf2, int cpnum)
  188. {
  189. int was_on;
  190. float len, dir[3], bgn[2], end[2], px, py, fencenorm[3];
  191. /* temporarily turn this plane off */
  192. if ((was_on = Cp_ison[cpnum])) {
  193. gsd_set_clipplane(cpnum, 0);
  194. }
  195. /* line on surface (asuming NO TILT) is (-A,B)->(A,-B),
  196. extended thru Cp_pt */
  197. dir[X] = -Cp_norm[cpnum][Y];
  198. dir[Y] = Cp_norm[cpnum][X];
  199. dir[Z] = 0.0;
  200. GS_v3norm(dir);
  201. px = Cp_trans[cpnum][X] + Cp_pt[X];
  202. py = Cp_trans[cpnum][Y] + Cp_pt[Y];
  203. /* TODO: make line from point & direction, clip to region */
  204. /* for now, to test: */
  205. bgn[X] = px;
  206. bgn[Y] = py;
  207. end[X] = px;
  208. end[Y] = 3 * VROW2Y(surf1, 0);
  209. len = GS_P2distance(bgn, end) - 1;
  210. bgn[X] = px + len * dir[X];
  211. bgn[Y] = py + len * dir[Y];
  212. end[X] = px - len * dir[X];
  213. end[Y] = py - len * dir[Y];
  214. fencenorm[X] = -Cp_norm[cpnum][X];
  215. fencenorm[Y] = -Cp_norm[cpnum][Y];
  216. fencenorm[Z] = -Cp_norm[cpnum][Z];
  217. gsd_wall(bgn, end, fencenorm);
  218. /* turn this plane back on */
  219. if (was_on) {
  220. gsd_set_clipplane(cpnum, 1);
  221. }
  222. return;
  223. }
  224. /*!
  225. \brief Draw cplane
  226. \param num
  227. */
  228. void gsd_draw_cplane(int num)
  229. {
  230. float size, cpv[3];
  231. int i;
  232. float scalez;
  233. unsigned long colr;
  234. /* turn off all clipping planes */
  235. for (i = 0; i < MAX_CPLANES; i++) {
  236. if (Cp_ison[i]) {
  237. gsd_set_clipplane(i, 0);
  238. }
  239. }
  240. GS_get_longdim(&size);
  241. size /= 2.;
  242. cpv[X] = 0.0;
  243. gsd_blend(1);
  244. gsd_zwritemask(0x0);
  245. gsd_pushmatrix();
  246. gsd_do_scale(1);
  247. gsd_translate(Cp_pt[X] + Cp_trans[num][X],
  248. Cp_pt[Y] + Cp_trans[num][Y], Cp_pt[Z] + Cp_trans[num][Z]);
  249. gsd_rot(Cp_rot[num][Z], 'z');
  250. gsd_rot(Cp_rot[num][Y], 'y');
  251. gsd_rot(Cp_rot[num][X], 'x');
  252. if ((scalez = GS_global_exag())) {
  253. gsd_scale(1.0, 1.0, 1. / scalez);
  254. }
  255. colr = (GS_default_draw_color() | 0xff000000) & 0x33ffffff;
  256. gsd_color_func(colr);
  257. gsd_bgnpolygon();
  258. cpv[Y] = size;
  259. cpv[Z] = size;
  260. gsd_vert_func(cpv);
  261. cpv[Y] = -size;
  262. gsd_vert_func(cpv);
  263. cpv[Z] = -size;
  264. gsd_vert_func(cpv);
  265. cpv[Y] = size;
  266. gsd_vert_func(cpv);
  267. gsd_endpolygon();
  268. gsd_popmatrix();
  269. gsd_blend(0);
  270. gsd_zwritemask(0xffffffff);
  271. /* turn on clipping planes */
  272. for (i = 0; i < MAX_CPLANES; i++) {
  273. if (Cp_ison[i]) {
  274. gsd_set_clipplane(i, 1);
  275. }
  276. }
  277. return;
  278. }