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