GRASS 8 Programmer's Manual 8.6.0dev(2026)-5f4f7ad06c
Loading...
Searching...
No Matches
gsd_objs.c
Go to the documentation of this file.
1/*!
2 \file lib/ogsf/gsd_objs.c
3
4 \brief OGSF library - objects management (lower level functions)
5
6 GRASS OpenGL gsurf OGSF Library
7
8 (C) 1999-2008 by the GRASS Development Team
9
10 This program is free software under the
11 GNU General Public License (>=v2).
12 Read the file COPYING that comes with GRASS
13 for details.
14
15 \author Bill Brown USACERL (October 1993)
16 \author Doxygenized by Martin Landa <landa.martin gmail.com> (May 2008)
17 */
18
19#include <stdlib.h>
20#include <string.h>
21
22#include <grass/gis.h>
23#include <grass/ogsf.h>
24
25#include "gsget.h"
26#include "math.h"
27#include "rowcol.h"
28
29static void init_stuff(void);
30
31/**
32 * @brief vertices for octahedron
33 */
34float Octo[6][3] = {{1.0, 0.0, 0.0}, {0.0, 1.0, 0.0}, {0.0, 0.0, 1.0},
35 {-1.0, 0.0, 0.0}, {0.0, -1.0, 0.0}, {0.0, 0.0, -1.0}};
36
37#define ONORM .57445626
38
39/**
40 * @brief normals for flat-shaded octahedron
41 */
42float OctoN[8][3] = {
44 {-ONORM, -ONORM, ONORM}, {ONORM, ONORM, -ONORM}, {-ONORM, ONORM, -ONORM},
45 {ONORM, -ONORM, -ONORM}, {-ONORM, -ONORM, -ONORM},
46};
47
48/*!
49 ???? not sure if any of these are needed for correct lighting.
50 float CubeNormals[6][3] = {
51 {ONORM, 0, 0},
52 {-ONORM, 0, 0},
53 {0, ONORM, 0},
54 {0, -ONORM, 0},
55 {0, 0, ONORM},
56 {0, 0, -ONORM}
57 };
58 */
59
60float CubeNormals[3][3] = {{0, -ONORM, 0}, {0, 0, ONORM}, {ONORM, 0, 0}};
61
62float CubeVertices[8][3] = {
63 {-1.0, -1.0, -1.0}, {1.0, -1.0, -1.0}, {1.0, 1.0, -1.0}, {-1.0, 1.0, -1.0},
64 {-1.0, -1.0, 1.0}, {1.0, -1.0, 1.0}, {1.0, 1.0, 1.0}, {-1.0, 1.0, 1.0}};
65
66float origin[3] = {0.0, 0.0, 0.0};
67
68#define UP_NORM Octo[2]
69#define DOWN_NORM Octo[5]
70#define ORIGIN origin
71
72/**
73 * @brief vertices & normals for octagon in xy plane
74 */
75float ogverts[8][3];
76
77/**
78 * @brief vertices for octagon in xy plane, z=1
79 */
80float ogvertsplus[8][3];
81
82float Pi;
83
84static void init_stuff(void)
85{
86 float cos45;
87 int i;
88 static int first = 1;
89
90 if (first) {
91 first = 0;
92
93 cos45 = cos(atan(1.0));
94
95 for (i = 0; i < 8; i++) {
96 ogverts[i][Z] = 0.0;
97 ogvertsplus[i][Z] = 1.0;
98 }
99
100 ogverts[0][X] = ogvertsplus[0][X] = 1.0;
101 ogverts[0][Y] = ogvertsplus[0][Y] = 0.0;
102 ogverts[1][X] = ogvertsplus[1][X] = cos45;
103 ogverts[1][Y] = ogvertsplus[1][Y] = cos45;
104 ogverts[2][X] = ogvertsplus[2][X] = 0.0;
105 ogverts[2][Y] = ogvertsplus[2][Y] = 1.0;
106 ogverts[3][X] = ogvertsplus[3][X] = -cos45;
107 ogverts[3][Y] = ogvertsplus[3][Y] = cos45;
108 ogverts[4][X] = ogvertsplus[4][X] = -1.0;
109 ogverts[4][Y] = ogvertsplus[4][Y] = 0.0;
110 ogverts[5][X] = ogvertsplus[5][X] = -cos45;
111 ogverts[5][Y] = ogvertsplus[5][Y] = -cos45;
112 ogverts[6][X] = ogvertsplus[6][X] = 0.0;
113 ogverts[6][Y] = ogvertsplus[6][Y] = -1.0;
114 ogverts[7][X] = ogvertsplus[7][X] = cos45;
115 ogverts[7][Y] = ogvertsplus[7][Y] = -cos45;
116
117 Pi = 4.0 * atan(1.0);
118 }
119
120 return;
121}
122
123/**
124 * @brief Draws a plus sign symbol at the specified center location.
125 *
126 * This function renders a plus sign ('+') symbol at the given center
127 * coordinates with the specified color and size.
128 *
129 * @param center Pointer to a float array representing the (x, y, z) coordinates
130 * of the center point.
131 * @param colr Integer representing the color to use for drawing the symbol.
132 * @param siz Size of the symbol.
133 */
134void gsd_plus(float *center, int colr, float siz)
135{
136 float v1[3], v2[3];
137
139 siz *= .5;
140
141 v1[Z] = v2[Z] = center[Z];
142
143 v1[X] = v2[X] = center[X];
144 v1[Y] = center[Y] - siz;
145 v2[Y] = center[Y] + siz;
146 gsd_bgnline();
147 gsd_vert_func(v1);
148 gsd_vert_func(v2);
149 gsd_endline();
150
151 v1[Y] = v2[Y] = center[Y];
152 v1[X] = center[X] - siz;
153 v2[X] = center[X] + siz;
154 gsd_bgnline();
155 gsd_vert_func(v1);
156 gsd_vert_func(v2);
157 gsd_endline();
158
159 return;
160}
161
162/**
163 * @brief Line on surface, fix z-values
164 *
165 * @todo remove fudge, instead fudge the Z buffer
166 *
167 * @param gs surface (geosurf)
168 * @param v1 first point (X,Y)
169 * @param v2 second point (X,Y)
170 */
171void gsd_line_onsurf(geosurf *gs, float *v1, float *v2)
172{
173 int i, np;
174 Point3 *pts;
175 float fudge;
176
177 pts = gsdrape_get_segments(gs, v1, v2, &np);
178 if (pts) {
179 fudge = FUDGE(gs);
180 gsd_bgnline();
181
182 for (i = 0; i < np; i++) {
183 /* ACS */
184 /* reverting back, as it broke displaying X symbol and query line */
185 pts[i][Z] += fudge;
186 /*pts[i][Z] *= fudge; */
187 gsd_vert_func(pts[i]);
188 }
189
190 gsd_endline();
191
192 /* fix Z values? */
193 v1[Z] = pts[0][Z];
194 v2[Z] = pts[np - 1][Z];
195 }
196
197 return;
198}
199
200/**
201 * @brief Multiline on surface, fix z-values
202 *
203 * @todo remove fudge, instead fudge the Z buffer
204 *
205 * Like above, except only draws first n points of line, or np,
206 * whichever is less. Returns number of points used. Fills
207 * pt with last pt drawn.
208 *
209 * @param gs surface (geosurf)
210 * @param v1 Pointer to a float array representing the first point as a vector.
211 * @param v2 Pointer to a float array representing the second point as a vector.
212 * @param[out] pt
213 * @param[in] n number of segments
214 * @return int
215 */
216int gsd_nline_onsurf(geosurf *gs, float *v1, float *v2, float *pt, int n)
217{
218 int i, np, pdraw;
219 Point3 *pts;
220 float fudge;
221
222 pts = gsdrape_get_segments(gs, v1, v2, &np);
223
224 if (pts) {
225 pdraw = n < np ? n : np;
226 fudge = FUDGE(gs);
227 gsd_bgnline();
228
229 for (i = 0; i < pdraw; i++) {
230 pts[i][Z] += fudge;
231 gsd_vert_func(pts[i]);
232 }
233
234 gsd_endline();
235
236 pt[X] = pts[i - 1][X];
237 pt[Y] = pts[i - 1][Y];
238
239 /* fix Z values? */
240 v1[Z] = pts[0][Z];
241 v2[Z] = pts[np - 1][Z];
242
243 return (i);
244 }
245
246 return (0);
247}
248
249/**
250 * @brief Draws a X symbol at the specified center location.
251 *
252 * This function renders a x ('X') symbol at the given center
253 * coordinates with the specified color and size.
254 *
255 * Note gs: NULL if flat
256 *
257 * @param gs surface (geosurf)
258 * @param center Pointer to a float array representing the (x, y, z) coordinates
259 * of the center point.
260 * @param colr Integer representing the color to use for drawing the symbol.
261 * @param siz Size of the symbol.
262 */
263void gsd_x(geosurf *gs, float *center, int colr, float siz)
264{
265 float v1[3], v2[3];
266
268 siz *= .5;
269
270 v1[Z] = v2[Z] = center[Z];
271
272 v1[X] = center[X] - siz;
273 v2[X] = center[X] + siz;
274 v1[Y] = center[Y] - siz;
275 v2[Y] = center[Y] + siz;
276
277 if (gs) {
278 gsd_line_onsurf(gs, v1, v2);
279 }
280 else {
281 gsd_bgnline();
282 gsd_vert_func(v1);
283 gsd_vert_func(v2);
284 gsd_endline();
285 }
286
287 v1[X] = center[X] - siz;
288 v2[X] = center[X] + siz;
289 v1[Y] = center[Y] + siz;
290 v2[Y] = center[Y] - siz;
291
292 if (gs) {
293 gsd_line_onsurf(gs, v1, v2);
294 }
295 else {
296 gsd_bgnline();
297 gsd_vert_func(v1);
298 gsd_vert_func(v2);
299 gsd_endline();
300 }
301
302 return;
303}
304
305/**
306 * @brief Draws a diamond symbol at the specified center location.
307 *
308 * This function renders a diamond symbol at the given center
309 * coordinates with the specified color and size.
310 *
311 * @param center Pointer to a float array representing the (x, y, z) coordinates
312 * of the center point.
313 * @param colr Integer representing the color to use for drawing the symbol.
314 * @param siz Size of the symbol.
315 */
316void gsd_diamond(float *center, unsigned long colr, float siz)
317{
318 int preshade;
319
320 /* seems right, but isn't
321 siz *= .5;
322 */
323
326 gsd_scale(siz, siz, siz);
328 gsd_shademodel(0); /* want flat shading */
329
335
341
347
353
359
365
371
377
378#ifdef OCT_SHADED
379 {
380 gsd_bgntmesh();
399 gsd_endtmesh();
400 }
401#endif
402
405
406 return;
407}
408
409/**
410 * @brief Draws a cube symbol at the specified center location.
411 *
412 * This function renders a cube symbol at the given center
413 * coordinates with the specified color and size.
414 *
415 * Added by Hamish Bowman Nov 2005
416 *
417 * @param center Pointer to a float array representing the (x, y, z) coordinates
418 * of the center point.
419 * @param colr Integer representing the color to use for drawing the symbol.
420 * @param siz Size of the symbol.
421 */
422void gsd_cube(float *center, unsigned long colr, float siz)
423{
424 int preshade;
425
426 /* see gsd_diamond() "seems right, but isn't" */
427 siz *= .5;
428
431 gsd_scale(siz, siz, siz);
433 gsd_shademodel(0); /* want flat shading */
434
435 /* N wall: */
442
443 /* S wall: */
450
451 /* E wall: */
458
459 /* W wall: */
466
467 /* lower wall: */
474
475 /* top wall: */
482
485
486 return;
487}
488
489/**
490 * @brief Draws a box symbol at the specified center location.
491 *
492 * This function renders a box symbol at the given center
493 * coordinates with the specified color and size.
494 *
495 * Added by Hamish Bowman Nov 2005
496 *
497 * @param center Pointer to a float array representing the (x, y, z) coordinates
498 * of the center point.
499 * @param colr Integer representing the color to use for drawing the symbol.
500 * @param siz Size of the symbol.
501 */
502void gsd_draw_box(float *center, unsigned long colr, float siz)
503{
504
505 /* see gsd_diamond() "seems right, but isn't" */
506 siz *= .5;
507
510 gsd_scale(siz, siz, siz);
512
513 gsd_bgnline(); /* N wall */
519 gsd_endline();
520
521 gsd_bgnline(); /* S wall */
527 gsd_endline();
528
529 gsd_bgnline();
532 gsd_endline();
533
534 gsd_bgnline();
537 gsd_endline();
538
539 gsd_bgnline();
542 gsd_endline();
543
544 gsd_bgnline();
547 gsd_endline();
548
550
551 return;
552}
553
554/**
555 * @brief Draws a sphere at the specified center location.
556 *
557 * This function renders a sphere at the given center
558 * coordinates with the specified color and size.
559 *
560 * @param center Pointer to a float array representing the (x, y, z) coordinates
561 * of the center point.
562 * @param colr Integer representing the color to use for drawing the sphere.
563 * @param siz Size of the sphere.
564 */
565void gsd_drawsphere(float *center, unsigned long colr, float siz)
566{
567 siz *= .5; /* siz is diameter, gsd_sphere uses radius */
570
571 return;
572}
573
574/*!
575 \brief Draw diamond lines
576 */
578{
579 gsd_bgnline();
582 gsd_endline();
583
584 gsd_bgnline();
587 gsd_endline();
588
589 gsd_bgnline();
592 gsd_endline();
593
594 return;
595}
596
597/**
598 * @brief Draws an asterisk symbol at the specified center location.
599 *
600 * This function renders an asterisk symbol at the given center
601 * coordinates with the specified color and size.
602 *
603 * @param center Pointer to a float array representing the (x, y, z) coordinates
604 * of the center point.
605 * @param colr Integer representing the color to use for drawing the symbol.
606 * @param siz Size of the symbol.
607 */
608void gsd_draw_asterisk(float *center, unsigned long colr, float siz)
609{
610 float angle;
611
612 angle = 45.; /* degrees */
613
616 gsd_scale(siz, siz, siz);
618
620
622 gsd_rot(angle, 'x');
625
627 gsd_rot(-angle, 'x');
630
632 gsd_rot(angle, 'y');
635
637 gsd_rot(-angle, 'y');
640
642 gsd_rot(angle, 'z');
645
647 gsd_rot(-angle, 'z');
650
652
653 return;
654}
655
656/**
657 * @brief Draws a gyro symbol at the specified center location.
658 *
659 * This function renders a gyro symbol at the given center
660 * coordinates with the specified color and size.
661 *
662 * @param center Pointer to a float array representing the (x, y, z) coordinates
663 * of the center point.
664 * @param colr Integer representing the color to use for drawing the symbol.
665 * @param siz Size of the symbol.
666 */
667void gsd_draw_gyro(float *center, unsigned long colr, float siz)
668{
669 int i;
670
673 gsd_scale(siz, siz, siz);
675
676 /* vert axis */
677 gsd_bgnline();
680 gsd_endline();
681
682 /* spokes */
684
685 for (i = 0; i < 6; i++) {
686 gsd_rot(30., 'z');
687 gsd_bgnline();
690 gsd_endline();
691 }
692
694
696
697 gsd_circ(0., 0., 1.);
698
700 gsd_rot(90., 'x');
701 gsd_circ(0., 0., 1.);
703
705 gsd_rot(90., 'y');
706 gsd_circ(0., 0., 1.);
708
710
711 return;
712}
713
714/**
715 * @brief Draw 3d cursor
716 *
717 * @param[in] pt point
718 */
719void gsd_3dcursor(float *pt)
720{
721 float big, vert[3];
722
723 big = 10000.;
724
725 gsd_bgnline();
726 vert[X] = pt[X];
727 vert[Y] = pt[Y];
728 vert[Z] = big;
730 vert[Z] = -big;
732 gsd_endline();
733
734 gsd_bgnline();
735 vert[X] = pt[X];
736 vert[Z] = pt[Z];
737 vert[Y] = big;
739 vert[Y] = -big;
741 gsd_endline();
742
743 gsd_bgnline();
744 vert[Y] = pt[Y];
745 vert[Z] = pt[Z];
746 vert[X] = big;
748 vert[X] = -big;
750 gsd_endline();
751
752 return;
753}
754
755/**
756 * @brief Converts a direction vector to slope and aspect angles.
757 *
758 * Given a 3D direction vector, this function computes the slope and aspect
759 * angles corresponding to the vector. The aspect is the compass direction
760 * (azimuth) of the projection of the vector onto the XY plane, and the slope
761 * is the angle between the vector and the vertical axis (Z).
762 *
763 * @param[in] dir Pointer to an array of 3 floats representing the
764 * direction vector [dx, dy, dz].
765 * @param[out] slope Pointer to a float where the computed slope angle will be
766 * stored (in radians or degrees).
767 * @param[out] aspect Pointer to a float where the computed aspect angle will
768 * be stored (in radians or degrees).
769 * @param[in] degrees If non-zero, the output angles are converted to degrees;
770 * otherwise, they are in radians.
771 *
772 * The function handles edge cases where the direction vector is vertical or
773 * horizontal. Aspect is set to 0 if the vector has no horizontal component.
774 * Slope is negative for upward-pointing vectors, positive for downward.
775 */
776void dir_to_slope_aspect(float *dir, float *slope, float *aspect, int degrees)
777{
778 float dx, dy, dz;
779 float costheta, theta, adjacent;
780
781 dx = dir[X];
782 dy = dir[Y];
783 dz = dir[Z];
784
785 /* project vector <dx,dy,dz> onto plane of constant z containing
786 * final value should be 0.0 to 3600.0 */
787 if (dx == 0 && dy == 0) {
788 *aspect = 0.;
789 }
790 else {
791 if (dx == 0) {
792 theta = 90.0;
793 }
794 else {
795 costheta = dx / sqrt(dx * dx + dy * dy);
796 theta = acos(costheta);
797 }
798
799 if (dy < 0) {
800 theta = (2 * Pi) - theta;
801 }
802
803 *aspect = theta;
804 }
805
806 /* project vector <dx,dy,dz> onto plane of constant y containing
807 * final value should be -900.0 (looking up) to 900.0 (looking down) */
808 if (dz == 0) {
809 theta = 0.0;
810 }
811 else if (dx == 0 && dy == 0) {
812 theta = Pi / 2.;
813 }
814 else {
815 adjacent = sqrt(dx * dx + dy * dy);
816 costheta = adjacent / sqrt(adjacent * adjacent + dz * dz);
817 theta = acos(costheta);
818 }
819
820 if (dz > 0) {
821 theta = -theta;
822 }
823
824 *slope = theta;
825
826 if (degrees) {
827 *aspect = *aspect * (180. / Pi);
828 *slope = *slope * (180. / Pi);
829 }
830
831 return;
832}
833
834/**
835 * @brief Draw North Arrow
836 *
837 * Takes OpenGL coords and size
838 *
839 * @param pos2 Pointer to a float array representing the position as a
840 * 3D vector (X,Y,Z).
841 * @param len
842 * @param fontbase
843 * @param arw_clr north arrow color
844 * @param text_clr text color
845 *
846 * @return 1
847 *
848 * @todo Store arrow somewhere to enable it's removal/change.
849 * @todo Add option to specify north text and font.
850 */
851int gsd_north_arrow(float *pos2, float len, GLuint fontbase,
852 unsigned long arw_clr, unsigned long text_clr)
853{
854 const char *txt;
855 float v[4][3];
856 float base[3][3];
857 float Ntop[] = {0.0, 0.0, 1.0};
858
859 base[0][Z] = base[1][Z] = base[2][Z] = pos2[Z];
860 v[0][Z] = v[1][Z] = v[2][Z] = v[3][Z] = pos2[Z];
861
862 base[0][X] = pos2[X] - len / 16.;
863 base[1][X] = pos2[X] + len / 16.;
864 base[0][Y] = base[1][Y] = pos2[Y] - len / 2.;
865 base[2][X] = pos2[X];
866 base[2][Y] = pos2[Y] + .45 * len;
867
868 v[0][X] = v[2][X] = pos2[X];
869 v[1][X] = pos2[X] + len / 8.;
870 v[3][X] = pos2[X] - len / 8.;
871 v[0][Y] = pos2[Y] + .2 * len;
872 v[1][Y] = v[3][Y] = pos2[Y] + .1 * len;
873 v[2][Y] = pos2[Y] + .5 * len;
874
875 /* make sure we are drawing in front buffer */
877
879 gsd_do_scale(1);
880
883
885 glVertex3fv(base[0]);
886 glVertex3fv(base[1]);
887 glVertex3fv(base[2]);
889
891 glVertex3fv(v[0]);
892 glVertex3fv(v[1]);
893 glVertex3fv(v[2]);
894 glVertex3fv(v[0]);
896
898 glVertex3fv(v[0]);
899 glVertex3fv(v[2]);
900 glVertex3fv(v[3]);
901 glVertex3fv(v[0]);
903
904 /* draw N for North */
905 /* Need to pick a nice generic font */
906 /* TODO -- project text position off arrow
907 * bottom along azimuth
908 */
909
911 txt = "North";
912 /* adjust position of N text */
913 base[0][X] -= gsd_get_txtwidth(txt, 18) - 20.;
914 base[0][Y] -= gsd_get_txtheight(18) - 20.;
915
916 glRasterPos3fv(base[0]);
919 GS_done_draw();
920
922 gsd_flush();
923
924 return (1);
925}
926
927/**
928 * @brief Draws an arrow
929 *
930 * siz is height, sz is global exag to correct for.
931 *
932 * If onsurf in non-null, z component of dir is dropped and
933 * line-on-suf is used, resulting in length of arrow being proportional
934 * to slope.
935 *
936 * @param center Pointer to a float array representing the (x, y, z) coordinates
937 * of the center point.
938 * @param colr Integer representing the color to use for drawing the arrow.
939 * @param siz Size of the arrow.
940 * @param dir Direction of the arrow. Pointer to a float array representing the
941 * 3D vector (X,Y,Z).
942 * @param sz height, sz is global exag to correct for.
943 * @param onsurf surface (geosurf).
944 *
945 * @return 1 no surface given
946 * @return 0 on surface
947 */
948int gsd_arrow(float *center, unsigned long colr, float siz, float *dir,
949 float sz, geosurf *onsurf)
950{
951 float slope, aspect;
952 float tmp[3];
953 static int first = 1;
954
955 if (first) {
956 init_stuff();
957 first = 0;
958 }
959
960 dir[Z] /= sz;
961
962 GS_v3norm(dir);
963
964 if (NULL != onsurf) {
965 float base[3], tip[3], len;
966
967 base[X] = center[X];
968 base[Y] = center[Y];
969
970 /* project dir to surface, after zexag */
971 len = GS_P2distance(ORIGIN, dir); /* in case dir isn't normalized */
972 tip[X] = center[X] + dir[X] * len * siz;
973 tip[Y] = center[Y] + dir[Y] * len * siz;
974
975 return gsd_arrow_onsurf(base, tip, colr, 2, onsurf);
976 }
977
978 dir_to_slope_aspect(dir, &slope, &aspect, 1);
979
982 gsd_scale(1.0, 1.0, 1.0 / sz);
983 gsd_rot(aspect + 90, 'z');
984 gsd_rot(slope + 90., 'x');
985 gsd_scale(siz, siz, siz);
987
988 tmp[X] = 0.2;
989 tmp[Y] = 0.0;
990 tmp[Z] = 0.65;
991
992 gsd_bgnline();
995 gsd_endline();
996
997 gsd_bgnline();
998 gsd_vert_func(tmp);
1000 tmp[X] = -0.2;
1001 gsd_vert_func(tmp);
1002 gsd_endline();
1003
1004 gsd_popmatrix();
1005
1006 return (1);
1007}
1008
1009/**
1010 * @brief Draw north arrow on surface
1011 *
1012 * @param base Pointer to a float array representing the base as a
1013 * 2D vector (X,Y).
1014 * @param tip Pointer to a float array representing the tip as a
1015 * 2D vector (X,Y).
1016 * @param colr Integer representing the color to use for drawing the arrow.
1017 * @param wid Line width (see \ref gsd_linewidth)
1018 * @param gs surface (geosurf)
1019 *
1020 * @return 0
1021 */
1022int gsd_arrow_onsurf(float *base, float *tip, unsigned long colr, int wid,
1023 geosurf *gs)
1024{
1025 static int first = 1;
1026
1027 if (first) {
1028 init_stuff();
1029 first = 0;
1030 }
1031
1034
1035 G_debug(3, "gsd_arrow_onsurf");
1036 G_debug(3, " %f %f -> %f %f", base[X], base[Y], tip[X], tip[Y]);
1037
1038 gsd_line_onsurf(gs, base, tip);
1039
1040#ifdef DO_SPHERE_BASE
1041 {
1042 GS_v3dir(tip, base, dir0);
1043 GS_v3mag(dir0, &len);
1044 gsd_disc(base[X], base[Y], len / 10.);
1045 }
1046#endif
1047
1048#ifdef ARROW_READY
1049 {
1050 base[Z] = tip[Z] = 0.0;
1051 GS_v3dir(tip, base, dir0);
1052
1053 G_debug(3, " dir0: %f %f %f", dir0[X], dir0[Y], dir0[Z]);
1054
1055 /* rotate this direction 90 degrees */
1057 GS_v3mag(dir0, &len);
1058 GS_v3eq(dir1, dir0);
1059
1060 G_debug(3, " len: %f", len);
1061 G_debug(3, " a-dir1: %f %f %f", dir1[X], dir1[Y], dir1[Z]);
1062 G_debug(3, " a-dir2: %f %f %f", dir2[X], dir2[Y], dir2[Z]);
1063
1064 dim1 = len * .7;
1065 dim2 = len * .2;
1068
1069 G_debug(3, " b-dir1: %f %f %f", dir1[X], dir1[Y], dir1[Z]);
1070 G_debug(3, " b-dir2: %f %f %f", dir2[X], dir2[Y], dir2[Z]);
1071
1072 GS_v3eq(tmp, base);
1073 GS_v3add(tmp, dir1);
1074 GS_v3add(tmp, dir2);
1075
1076 G_debug(3, " %f %f -> ", tmp[X], tmp[Y]);
1077
1078 gsd_line_onsurf(gs, tmp, tip);
1079
1082 GS_v3eq(tmp, base);
1083
1084 G_debug(3, " dir1: %f %f %f", dir1[X], dir1[Y], dir1[Z]);
1085 G_debug(3, " dir2: %f %f %f", dir2[X], dir2[Y], dir2[Z]);
1086
1087 GS_v3add(tmp, dir1);
1088 GS_v3add(tmp, dir2);
1089
1090 G_debug(3, " %f %f", tmp[X], tmp[Y]);
1091
1092 gsd_line_onsurf(gs, tip, tmp);
1093 }
1094#endif
1095
1096 return (0);
1097}
1098
1099/**
1100 * @brief Draw 3d north arrow
1101 *
1102 * @param center Pointer to a float array representing the (x, y, z) coordinates
1103 * of the center point.
1104 * @param colr Integer representing the color to use for drawing the arrow.
1105 * @param siz1 size
1106 * @param siz2 size
1107 * @param dir Direction of the arrow. Pointer to a float array representing the
1108 * 3D vector (X,Y,Z).
1109 * @param sz height
1110 */
1111void gsd_3darrow(float *center, unsigned long colr, float siz1, float siz2,
1112 float *dir, float sz)
1113{
1114 float slope, aspect;
1115 int preshade;
1116 static int first = 1;
1117 static int list;
1118 static int debugint = 1;
1119
1120 dir[Z] /= sz;
1121
1122 GS_v3norm(dir);
1123 dir_to_slope_aspect(dir, &slope, &aspect, 1);
1124
1125 if (debugint > 100) {
1126 G_debug(3, "gsd_3darrow()");
1127 G_debug(3, " pt: %f,%f,%f dir: %f,%f,%f slope: %f aspect: %f",
1128 center[X], center[Y], center[Z], dir[X], dir[Y], dir[Z], slope,
1129 aspect);
1130 debugint = 1;
1131 }
1132 debugint++;
1133
1135
1136 /*
1137 gsd_shademodel(0);
1138 want flat shading? */
1141 gsd_scale(1.0, 1.0, 1.0 / sz);
1142 gsd_rot(aspect + 90, 'z');
1143 gsd_rot(slope + 90., 'x');
1146
1147 if (first) {
1148 /* combine these into an object */
1149 first = 0;
1150 list = gsd_makelist();
1151 gsd_bgnlist(list, 1);
1152 gsd_backface(1);
1153
1155 gsd_scale(.10, .10, .75); /* narrow cyl */
1157 gsd_popmatrix();
1158
1160 gsd_translate(0.0, 0.0, .60);
1161 gsd_scale(0.3, 0.3, 0.4); /* cone */
1163 gsd_popmatrix();
1164
1165 gsd_backface(0);
1166 gsd_endlist();
1167 }
1168 else {
1170 }
1171
1172 gsd_popmatrix();
1174
1175 return;
1176}
1177
1178/**
1179 * @brief Draw Scalebar takes OpenGL coords and size
1180 *
1181 * Adapted from gsd_north_arrow Hamish Bowman Dec 2006
1182 *
1183 * @param pos2 Pointer to a float array representing the scalebar position as a
1184 * 3D vector (X,Y,Z).
1185 * @param len
1186 * @param fontbase font-base
1187 * @param bar_clr barscale color.
1188 * Integer representing the color to use for the barscale.
1189 * @param text_clr test color.
1190 * Integer representing the color to use for the text.
1191 * @return 1
1192 */
1193int gsd_scalebar(float *pos2, float len, GLuint fontbase, unsigned long bar_clr,
1194 unsigned long text_clr)
1195{
1196 char txt[100];
1197 float base[4][3];
1198 float Ntop[] = {0.0, 0.0, 1.0};
1199
1200 base[0][Z] = base[1][Z] = base[2][Z] = base[3][Z] = pos2[Z];
1201
1202 /* simple 1:8 rectangle */ /* bump to X/20. for a 1:10 narrower bar? */
1203 base[0][X] = base[1][X] = pos2[X] - len / 2.;
1204 base[2][X] = base[3][X] = pos2[X] + len / 2.;
1205
1206 base[0][Y] = base[3][Y] = pos2[Y] - len / 16.;
1207 base[1][Y] = base[2][Y] = pos2[Y] + len / 16.;
1208
1209 /* make sure we are drawing in front buffer */
1211
1213 gsd_do_scale(1); /* get map scale factor */
1214
1216
1218
1220 glVertex3fv(base[0]);
1221 glVertex3fv(base[1]);
1222 glVertex3fv(base[2]);
1223 glVertex3fv(base[3]);
1224 glVertex3fv(base[0]);
1226
1227 /* draw units */
1228 /* Need to pick a nice generic font */
1229 /* TODO -- project text position off bar bottom along azimuth */
1230
1232
1233 /* format text in a nice way */
1234 if (strcmp("meters", G_database_unit_name(TRUE)) == 0) {
1235 if (len > 2500)
1236 snprintf(txt, sizeof(txt), "%g km", len / 1000);
1237 else
1238 snprintf(txt, sizeof(txt), "%g meters", len);
1239 }
1240 else if (strcmp("feet", G_database_unit_name(TRUE)) == 0) {
1241 if (len > 5280)
1242 snprintf(txt, sizeof(txt), "%g miles", len / 5280);
1243 else if (len == 5280)
1244 snprintf(txt, sizeof(txt), "1 mile");
1245 else
1246 snprintf(txt, sizeof(txt), "%g feet", len);
1247 }
1248 else {
1249 snprintf(txt, sizeof(txt), "%g %s", len, G_database_unit_name(TRUE));
1250 }
1251
1252 /* adjust position of text (In map units?!) */
1253 base[0][X] -= gsd_get_txtwidth(txt, 18) - 20.;
1254 base[0][Y] -= gsd_get_txtheight(18) - 20.;
1255
1256 glRasterPos3fv(base[0]);
1259 GS_done_draw();
1260
1261 gsd_popmatrix();
1262 gsd_flush();
1263
1264 return (1);
1265}
1266
1267/**
1268 * @brief Draw Scalebar (as lines)
1269 *
1270 * Adapted from gsd_scalebar A.Kratochvilova 2011
1271 *
1272 * @param pos Pointer to a float array representing the scalebar position as a
1273 * 3D vector (X,Y,Z).
1274 * @param len
1275 * @param fontbase font-base (unused)
1276 * @param bar_clr barscale color.
1277 * Integer representing the color to use for the barscale.
1278 * @param text_clr Text color (unused).
1279 * Integer representing the color to use for the text.
1280 * @return 1
1281 */
1282int gsd_scalebar_v2(float *pos, float len, GLuint fontbase UNUSED,
1283 unsigned long bar_clr, unsigned long text_clr UNUSED)
1284{
1285 float base[6][3];
1286 float Ntop[] = {0.0, 0.0, 1.0};
1287
1288 base[0][Z] = base[1][Z] = base[2][Z] = pos[Z];
1289 base[3][Z] = base[4][Z] = base[5][Z] = pos[Z];
1290
1291 /* simple scalebar: |------| */
1292 base[0][X] = base[2][X] = base[3][X] = pos[X] - len / 2.;
1293 base[1][X] = base[4][X] = base[5][X] = pos[X] + len / 2.;
1294 base[0][Y] = base[1][Y] = pos[Y];
1295 base[2][Y] = base[4][Y] = pos[Y] - len / 12;
1296 base[3][Y] = base[5][Y] = pos[Y] + len / 12;
1297
1298 /* make sure we are drawing in front buffer */
1300
1302 gsd_do_scale(1); /* get map scale factor */
1303
1305
1307
1308 gsd_linewidth(3); /* could be optional */
1309
1310 /* ------- */
1311 gsd_bgnline();
1312 gsd_vert_func(base[0]);
1313 gsd_vert_func(base[1]);
1314 gsd_endline();
1315
1316 /* |------- */
1317 gsd_bgnline();
1318 gsd_vert_func(base[2]);
1319 gsd_vert_func(base[3]);
1320 gsd_endline();
1321
1322 /* |-------| */
1323 gsd_bgnline();
1324 gsd_vert_func(base[4]);
1325 gsd_vert_func(base[5]);
1326 gsd_endline();
1327
1328 /* TODO -- draw units */
1329
1330 GS_done_draw();
1331
1332 gsd_popmatrix();
1333 gsd_flush();
1334
1335 return 1;
1336}
1337
1338/**
1339 * @brief Primitives only called after transforms
1340 *
1341 * Center is actually center at base of 8 sided cone
1342 *
1343 * @param colr Integer representing the color to use for drawing the cone.
1344 */
1345void primitive_cone(unsigned long colr)
1346{
1347 float tip[3];
1348 static int first = 1;
1349
1350 if (first) {
1351 init_stuff();
1352 first = 0;
1353 }
1354
1355 tip[X] = tip[Y] = 0.0;
1356 tip[Z] = 1.0;
1357
1358 gsd_bgntfan();
1369 gsd_endtfan();
1370
1371 return;
1372}
1373
1374/**
1375 * @brief Primitives only called after transforms
1376 *
1377 * Center is actually center at base of 8 sided cylinder
1378 *
1379 * @param colr Integer representing the color to use for drawing the cylinder.
1380 * @param caps If non zero, draw caps at the bottom and top of the cylinder.
1381 */
1382void primitive_cylinder(unsigned long colr, int caps)
1383{
1384 static int first = 1;
1385
1386 if (first) {
1387 init_stuff();
1388 first = 0;
1389 }
1390
1391 gsd_bgnqstrip();
1410 gsd_endqstrip();
1411
1412 if (caps) {
1413 /* draw top */
1414 gsd_bgntfan();
1425 gsd_endtfan();
1426
1427 /* draw bottom */
1428 gsd_bgntfan();
1439 gsd_endtfan();
1440 }
1441
1442 return;
1443}
1444
1445/*** ACS_MODIFY_BEGIN - sites_attribute management
1446 * ********************************/
1447/*
1448 Draws boxes that are used for histograms by \ref gpd_obj function in gpd.c
1449 for site_attribute management
1450 */
1451
1452/**
1453 * @brief Vertices for box
1454 */
1455float Box[8][3] = {{1.0, 1.0, -1.0}, {-1.0, 1.0, -1.0}, {-1.0, 1.0, 1.0},
1456 {1.0, 1.0, 1.0}, {1.0, -1.0, -1.0}, {-1.0, -1.0, -1.0},
1457 {-1.0, -1.0, 1.0}, {1.0, -1.0, 1.0}};
1458
1459float BoxN[6][3] = {{0, 0, -ONORM}, {0, 0, ONORM}, {0, ONORM, 0},
1460 {0, -ONORM, 0}, {ONORM, 0, 0}, {-ONORM, 0, 0}};
1461
1462/**
1463 * @brief Draws a box at the specified center location.
1464 *
1465 * This function renders a box at the given center
1466 * coordinates with the specified color and size.
1467 *
1468 * @warning siz is an array (we need it for scale only Z in histograms)
1469 *
1470 * @param center Pointer to a float array representing the (x, y, z) coordinates
1471 * of the center point.
1472 * @param colr Integer representing the color to use for drawing the symbol.
1473 * @param siz Size of the symbol.
1474 */
1475void gsd_box(float *center, int colr, float *siz)
1476{
1477 int preshade;
1478
1480 gsd_translate(center[X], center[Y], center[Z] + siz[2]);
1481 gsd_scale(siz[0], siz[1], siz[2]);
1483 gsd_shademodel(0); /* want flat shading */
1484
1485 /* Top */
1487 gsd_litvert_func(BoxN[2], colr, Box[0]);
1488 gsd_litvert_func(BoxN[2], colr, Box[1]);
1489 gsd_litvert_func(BoxN[2], colr, Box[2]);
1490 gsd_litvert_func(BoxN[2], colr, Box[3]);
1492
1493 /* Bottom */
1495 gsd_litvert_func(BoxN[3], colr, Box[7]);
1496 gsd_litvert_func(BoxN[3], colr, Box[6]);
1497 gsd_litvert_func(BoxN[3], colr, Box[5]);
1498 gsd_litvert_func(BoxN[3], colr, Box[4]);
1500
1501 /* Right */
1503 gsd_litvert_func(BoxN[4], colr, Box[0]);
1504 gsd_litvert_func(BoxN[4], colr, Box[3]);
1505 gsd_litvert_func(BoxN[4], colr, Box[7]);
1506 gsd_litvert_func(BoxN[4], colr, Box[4]);
1508
1509 /* Left */
1511 gsd_litvert_func(BoxN[5], colr, Box[1]);
1512 gsd_litvert_func(BoxN[5], colr, Box[5]);
1513 gsd_litvert_func(BoxN[5], colr, Box[6]);
1514 gsd_litvert_func(BoxN[5], colr, Box[2]);
1516
1517 /* Front */
1519 gsd_litvert_func(BoxN[0], colr, Box[0]);
1520 gsd_litvert_func(BoxN[0], colr, Box[4]);
1521 gsd_litvert_func(BoxN[0], colr, Box[5]);
1522 gsd_litvert_func(BoxN[0], colr, Box[1]);
1524
1525 /* Back */
1527 gsd_litvert_func(BoxN[1], colr, Box[3]);
1528 gsd_litvert_func(BoxN[1], colr, Box[2]);
1529 gsd_litvert_func(BoxN[1], colr, Box[6]);
1530 gsd_litvert_func(BoxN[1], colr, Box[7]);
1532
1533 gsd_popmatrix();
1535 return;
1536}
1537
1538/*** ACS_MODIFY_END - sites_attribute management
1539 * ********************************/
#define NULL
Definition ccmath.h:32
const char * G_database_unit_name(int)
Get units (localized) name for the current location.
Definition proj3.c:53
int G_debug(int, const char *,...) __attribute__((format(printf
void gsd_endlist(void)
End list.
Definition gsd_prim.c:1140
int GS_v3norm(float *)
Change v1 so that it is a unit vector (3D)
Definition gs_util.c:246
void GS_v3mult(float *, float)
Multiple vectors.
Definition gs_util.c:229
void gsd_endtfan(void)
ADD.
Definition gsd_prim.c:347
void gsd_endtmesh(void)
ADD.
Definition gsd_prim.c:307
void gsd_swaptmesh(void)
ADD.
Definition gsd_prim.c:357
void gsd_pushmatrix(void)
Push the current matrix stack.
Definition gsd_prim.c:511
void gsd_backface(int)
ADD.
Definition gsd_prim.c:254
void GS_set_draw(int)
Sets which buffer to draw to.
Definition gs2.c:2462
void gsd_scale(float, float, float)
Multiply the current matrix by a general scaling matrix.
Definition gsd_prim.c:525
void gsd_do_scale(int)
Set current scale.
Definition gsd_views.c:355
void gsd_bgnqstrip(void)
ADD.
Definition gsd_prim.c:277
void GS_v3mag(float *, float *)
Magnitude of vector.
Definition gs_util.c:418
void gsd_shademodel(int)
Set shaded model.
Definition gsd_prim.c:419
float GS_P2distance(float *, float *)
Calculate distance in plane.
Definition gs_util.c:160
void gsd_sphere(float *, float)
ADD.
Definition gsd_prim.c:207
void gsd_circ(float, float, float)
ADD.
Definition gsd_prim.c:167
void gsd_bgnpolygon(void)
Delimit the vertices of a primitive or a group of like primitives.
Definition gsd_prim.c:372
void GS_v3add(float *, float *)
Sum vectors.
Definition gs_util.c:195
void gsd_bgnlist(int, int)
ADD.
Definition gsd_prim.c:1125
int gsd_getshademodel(void)
Get shaded model.
Definition gsd_prim.c:438
int gsd_makelist(void)
ADD.
Definition gsd_prim.c:1094
void gsd_calllist(int)
ADD.
Definition gsd_prim.c:1173
void GS_v3eq(float *, float *)
Copy vector values.
Definition gs_util.c:178
int gsd_get_txtwidth(const char *, int)
Get text width.
Definition gsd_fonts.c:36
void gsd_endqstrip(void)
ADD.
Definition gsd_prim.c:287
int gsd_get_txtheight(int size)
Get text height.
Definition gsd_fonts.c:53
Point3 * gsdrape_get_segments(geosurf *, float *, float *, int *)
ADD.
Definition gsdrape.c:350
void gsd_color_func(unsigned int)
Set current color.
Definition gsd_prim.c:698
void gsd_translate(float, float, float)
Multiply the current matrix by a translation matrix.
Definition gsd_prim.c:539
void gsd_popmatrix(void)
Pop the current matrix stack.
Definition gsd_prim.c:501
void gsd_flush(void)
Mostly for flushing drawing commands across a network.
Definition gsd_prim.c:84
void GS_v3cross(float *, float *, float *)
Get the cross product v3 = v1 cross v2.
Definition gs_util.c:403
void gsd_linewidth(short)
Set width of rasterized lines.
Definition gsd_prim.c:267
void gsd_endline(void)
End line.
Definition gsd_prim.c:407
void gsd_bgntfan(void)
ADD.
Definition gsd_prim.c:337
void gsd_disc(float, float, float, float)
ADD.
Definition gsd_prim.c:187
int GS_v3dir(float *, float *, float *)
Get a normalized direction from v1 to v2, store in v3.
Definition gs_util.c:351
void gsd_bgnline(void)
Begin line.
Definition gsd_prim.c:397
void GS_done_draw(void)
Draw done, swap buffers.
Definition gs2.c:2501
void gsd_rot(float, char)
ADD.
Definition gsd_prim.c:605
void gsd_vert_func(float *)
ADD.
Definition gsd_prim.c:686
void gsd_bgntmesh(void)
ADD.
Definition gsd_prim.c:297
void gsd_litvert_func2(float *, unsigned long, float *)
ADD.
Definition gsd_prim.c:673
void gsd_endpolygon(void)
Delimit the vertices of a primitive or a group of like primitives.
Definition gsd_prim.c:387
void gsd_litvert_func(float *, unsigned long, float *)
Set the current normal vector & specify vertex.
Definition gsd_prim.c:657
#define TRUE
Definition gis.h:78
#define UNUSED
A macro for an attribute, if attached to a variable, indicating that the variable is not used.
Definition gis.h:46
float Ntop[]
Definition gsd_fringe.c:36
void gsd_3dcursor(float *pt)
Draw 3d cursor.
Definition gsd_objs.c:719
void gsd_diamond(float *center, unsigned long colr, float siz)
Draws a diamond symbol at the specified center location.
Definition gsd_objs.c:316
float Box[8][3]
Vertices for box.
Definition gsd_objs.c:1455
void gsd_draw_box(float *center, unsigned long colr, float siz)
Draws a box symbol at the specified center location.
Definition gsd_objs.c:502
#define UP_NORM
Definition gsd_objs.c:68
float CubeNormals[3][3]
Definition gsd_objs.c:60
void gsd_3darrow(float *center, unsigned long colr, float siz1, float siz2, float *dir, float sz)
Draw 3d north arrow.
Definition gsd_objs.c:1111
float CubeVertices[8][3]
Definition gsd_objs.c:62
#define DOWN_NORM
Definition gsd_objs.c:69
void gsd_line_onsurf(geosurf *gs, float *v1, float *v2)
Line on surface, fix z-values.
Definition gsd_objs.c:171
void primitive_cylinder(unsigned long colr, int caps)
Primitives only called after transforms.
Definition gsd_objs.c:1382
int gsd_arrow(float *center, unsigned long colr, float siz, float *dir, float sz, geosurf *onsurf)
Draws an arrow.
Definition gsd_objs.c:948
void gsd_x(geosurf *gs, float *center, int colr, float siz)
Draws a X symbol at the specified center location.
Definition gsd_objs.c:263
float Pi
Definition gsd_objs.c:82
#define ORIGIN
Definition gsd_objs.c:70
void gsd_drawsphere(float *center, unsigned long colr, float siz)
Draws a sphere at the specified center location.
Definition gsd_objs.c:565
int gsd_north_arrow(float *pos2, float len, GLuint fontbase, unsigned long arw_clr, unsigned long text_clr)
Draw North Arrow.
Definition gsd_objs.c:851
float BoxN[6][3]
Definition gsd_objs.c:1459
float ogverts[8][3]
vertices & normals for octagon in xy plane
Definition gsd_objs.c:75
void gsd_cube(float *center, unsigned long colr, float siz)
Draws a cube symbol at the specified center location.
Definition gsd_objs.c:422
int gsd_nline_onsurf(geosurf *gs, float *v1, float *v2, float *pt, int n)
Multiline on surface, fix z-values.
Definition gsd_objs.c:216
void gsd_diamond_lines(void)
Draw diamond lines.
Definition gsd_objs.c:577
int gsd_arrow_onsurf(float *base, float *tip, unsigned long colr, int wid, geosurf *gs)
Draw north arrow on surface.
Definition gsd_objs.c:1022
int gsd_scalebar(float *pos2, float len, GLuint fontbase, unsigned long bar_clr, unsigned long text_clr)
Draw Scalebar takes OpenGL coords and size.
Definition gsd_objs.c:1193
float OctoN[8][3]
normals for flat-shaded octahedron
Definition gsd_objs.c:42
float ogvertsplus[8][3]
vertices for octagon in xy plane, z=1
Definition gsd_objs.c:80
void dir_to_slope_aspect(float *dir, float *slope, float *aspect, int degrees)
Converts a direction vector to slope and aspect angles.
Definition gsd_objs.c:776
float Octo[6][3]
vertices for octahedron
Definition gsd_objs.c:34
int gsd_scalebar_v2(float *pos, float len, GLuint fontbase, unsigned long bar_clr, unsigned long text_clr)
Draw Scalebar (as lines)
Definition gsd_objs.c:1282
void gsd_draw_asterisk(float *center, unsigned long colr, float siz)
Draws an asterisk symbol at the specified center location.
Definition gsd_objs.c:608
void primitive_cone(unsigned long colr)
Primitives only called after transforms.
Definition gsd_objs.c:1345
#define ONORM
Definition gsd_objs.c:37
void gsd_box(float *center, int colr, float *siz)
Draws a box at the specified center location.
Definition gsd_objs.c:1475
void gsd_draw_gyro(float *center, unsigned long colr, float siz)
Draws a gyro symbol at the specified center location.
Definition gsd_objs.c:667
void gsd_plus(float *center, int colr, float siz)
Draws a plus sign symbol at the specified center location.
Definition gsd_objs.c:134
float origin[3]
Definition gsd_objs.c:66
OGSF header file (structures)
#define X
Definition ogsf.h:140
float Point3[3]
Definition ogsf.h:205
#define Z
Definition ogsf.h:142
#define GSD_FRONT
Definition ogsf.h:104
#define Y
Definition ogsf.h:141
#define FUDGE(gs)
Definition ogsf.h:179
Definition ogsf.h:266
Definition manage.h:4