gs2.c 63 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495
  1. /*!
  2. \file lib/ogsf/gs2.c
  3. \brief OGSF library - loading and manipulating surfaces (higher level functions)
  4. GRASS OpenGL gsurf OGSF Library
  5. Plans for handling color maps:
  6. NOW:
  7. if able to load as unsigned char, make lookup table containing palette
  8. otherwise, load directly as packed color, set lookup = NULL
  9. MAYBE LATER:
  10. if able to load as POSITIVE short, make lookup table containing palette
  11. - may want to calculate savings first (ie, numcells > 32768)
  12. (not exactly, it's Friday & time to go home - figure it later)
  13. otherwise, load directly as packed color, set lookup = NULL
  14. MESSY! - need to fix up!
  15. (C) 1999-2008 by the GRASS Development Team
  16. This program is free software under the
  17. GNU General Public License (>=v2).
  18. Read the file COPYING that comes with GRASS
  19. for details.
  20. \author Bill Brown USACERL (1993)
  21. \author Pierre de Mouveaux <p_de_mouveaux hotmail.com> (updated October 1999)
  22. \author Doxygenized by Martin Landa <landa.martin gmail.com> (May 2008)
  23. */
  24. #include <stdlib.h>
  25. #include <string.h>
  26. #include <math.h>
  27. #include <grass/config.h>
  28. #if defined(OPENGL_X11) || defined(OPENGL_WINDOWS)
  29. #include <GL/gl.h>
  30. #include <GL/glu.h>
  31. #elif defined(OPENGL_AQUA)
  32. #include <OpenGL/gl.h>
  33. #include <OpenGL/glu.h>
  34. #endif
  35. #include <grass/gis.h>
  36. #include <grass/raster.h>
  37. #include <grass/ogsf.h>
  38. #include <grass/glocale.h>
  39. #include "gsget.h"
  40. #include "rowcol.h"
  41. #include "rgbpack.h"
  42. /* Hack to make NVIZ2.2 query functions.("What's Here" and "Look at")
  43. * to work.
  44. * Uses gs_los_intersect1() instead of gs_los_intersect().
  45. * Pierre de Mouveaux - 31 oct. 1999. p_de_mouveaux@hotmail.com.
  46. */
  47. #define NVIZ_HACK 1
  48. int gsd_getViewport(GLint *, GLint *);
  49. /* array of surface ids */
  50. static int Surf_ID[MAX_SURFS];
  51. static int Next_surf = 0;
  52. static int SDref_surf = 0;
  53. /* attributes array */
  54. static float Default_const[MAX_ATTS];
  55. static float Default_nulls[MAX_ATTS];
  56. /* largest dimension */
  57. static float Longdim;
  58. /* N, S, W, E */
  59. static float Region[4];
  60. static geoview Gv;
  61. static geodisplay Gd;
  62. static struct Cell_head wind;
  63. static int Buffermode;
  64. static int Numlights = 0;
  65. static int Resetlight = 1;
  66. static int Modelshowing = 0;
  67. void void_func(void)
  68. {
  69. return;
  70. }
  71. /*!
  72. \brief Initialize OGSF library
  73. Get region settings - wind
  74. Set Region (NSWE array) and compute scale
  75. */
  76. void GS_libinit(void)
  77. {
  78. static int first = 1;
  79. G_get_set_window(&wind);
  80. Region[0] = wind.north;
  81. Region[1] = wind.south;
  82. Region[2] = wind.west;
  83. Region[3] = wind.east;
  84. /* scale largest dimension to GS_UNIT_SIZE */
  85. if ((wind.east - wind.west) > (wind.north - wind.south)) {
  86. Longdim = (wind.east - wind.west);
  87. }
  88. else {
  89. Longdim = (wind.north - wind.south);
  90. }
  91. Gv.scale = GS_UNIT_SIZE / Longdim;
  92. G_debug(1, "GS_libinit(): n=%f s=%f w=%f e=%f scale=%f first=%d",
  93. Region[0], Region[1], Region[2], Region[3], Gv.scale, first);
  94. Cxl_func = void_func;
  95. if (first) {
  96. gs_init();
  97. }
  98. first = 0;
  99. return;
  100. }
  101. /*!
  102. \brief Get largest dimension
  103. \param[out] dim dimension
  104. \return 1
  105. */
  106. int GS_get_longdim(float *dim)
  107. {
  108. *dim = Longdim;
  109. G_debug(3, "GS_get_longdim(): dim=%g", *dim);
  110. return (1);
  111. }
  112. /*!
  113. \brief Get 2D region extent
  114. \param[out] n,s,w,e extent values
  115. \return 1
  116. */
  117. int GS_get_region(float *n, float *s, float *w, float *e)
  118. {
  119. *n = Region[0];
  120. *s = Region[1];
  121. *w = Region[2];
  122. *e = Region[3];
  123. return (1);
  124. }
  125. /*!
  126. \brief Set default attributes for map objects
  127. \param defs attributes array (dim MAX_ATTS)
  128. \param null_defs null attributes array (dim MAX_ATTS)
  129. */
  130. void GS_set_att_defaults(float *defs, float *null_defs)
  131. {
  132. int i;
  133. G_debug(3, "GS_set_att_defaults");
  134. for (i = 0; i < MAX_ATTS; i++) {
  135. Default_const[i] = defs[i];
  136. Default_nulls[i] = null_defs[i];
  137. }
  138. return;
  139. }
  140. /*!
  141. Check if surface exists
  142. \param id surface id
  143. \return 0 not found
  144. \return 1 found
  145. */
  146. int GS_surf_exists(int id)
  147. {
  148. int i, found = 0;
  149. G_debug(3, "GS_surf_exists(): id=%d", id);
  150. if (NULL == gs_get_surf(id)) {
  151. return (0);
  152. }
  153. for (i = 0; i < Next_surf && !found; i++) {
  154. if (Surf_ID[i] == id) {
  155. found = 1;
  156. }
  157. }
  158. return (found);
  159. }
  160. /*!
  161. \brief Add new surface
  162. Note that origin has 1/2 cell added to represent center of cells
  163. because library assumes that east - west = (cols - 1) * ew_res,
  164. since left and right columns are on the edges.
  165. \return surface id
  166. \return -1 on error (MAX_SURFS exceded)
  167. */
  168. int GS_new_surface(void)
  169. {
  170. geosurf *ns;
  171. G_debug(3, "GS_new_surface():");
  172. if (Next_surf < MAX_SURFS) {
  173. ns = gs_get_new_surface();
  174. gs_init_surf(ns, wind.west + wind.ew_res / 2.,
  175. wind.south + wind.ns_res / 2., wind.rows, wind.cols,
  176. wind.ew_res, wind.ns_res);
  177. gs_set_defaults(ns, Default_const, Default_nulls);
  178. /* make default shine current */
  179. gs_set_att_src(ns, ATT_SHINE, CONST_ATT);
  180. Surf_ID[Next_surf] = ns->gsurf_id;
  181. ++Next_surf;
  182. G_debug(3, " id=%d", ns->gsurf_id);
  183. return (ns->gsurf_id);
  184. }
  185. return (-1);
  186. }
  187. void GS_set_light_reset(int i)
  188. {
  189. Resetlight = i;
  190. if (i)
  191. Numlights = 0;
  192. }
  193. int GS_get_light_reset(void)
  194. {
  195. return Resetlight;
  196. }
  197. /*!
  198. \brief Add new model light
  199. \return light model id
  200. \return -1 on error (MAX_LIGHTS exceded)
  201. */
  202. int GS_new_light(void)
  203. {
  204. int i;
  205. if (GS_get_light_reset()) {
  206. GS_set_light_reset(0);
  207. for (i = 0; i < MAX_LIGHTS; i++) {
  208. Gv.lights[i].position[X] = Gv.lights[i].position[Y] = 0.0;
  209. Gv.lights[i].position[Z] = 1.0;
  210. Gv.lights[i].position[W] = 0.0; /* infinite */
  211. Gv.lights[i].color[0] = Gv.lights[i].color[1] =
  212. Gv.lights[i].color[2] = 1.0;
  213. Gv.lights[i].ambient[0] = Gv.lights[i].ambient[1] =
  214. Gv.lights[i].ambient[2] = 0.2;
  215. Gv.lights[i].shine = 32.0;
  216. }
  217. gsd_init_lightmodel();
  218. }
  219. if (Numlights < MAX_LIGHTS) {
  220. gsd_deflight(Numlights + 1, &(Gv.lights[Numlights]));
  221. gsd_switchlight(Numlights + 1, 1);
  222. return ++Numlights;
  223. }
  224. return -1;
  225. }
  226. /*!
  227. \brief Set light position
  228. \bug I think lights array doesnt match sgi_light array
  229. \param num light id (starts with 1)
  230. \param xpos,ypos,zpos coordinates (model)
  231. \param local local coordinate (for viewport)
  232. */
  233. void GS_setlight_position(int num, float xpos, float ypos, float zpos,
  234. int local)
  235. {
  236. if (num) {
  237. num -= 1;
  238. if (num < Numlights) {
  239. Gv.lights[num].position[X] = xpos;
  240. Gv.lights[num].position[Y] = ypos;
  241. Gv.lights[num].position[Z] = zpos;
  242. Gv.lights[num].position[W] = (float)local;
  243. gsd_deflight(num + 1, &(Gv.lights[num]));
  244. }
  245. }
  246. return;
  247. }
  248. /*!
  249. \brief Get light position
  250. \param num light id (starts at 1)
  251. \param[out] xpos,ypos,zpos coordinates
  252. \param[out] local ?
  253. */
  254. void GS_getlight_position(int num, float *xpos, float *ypos, float *zpos,
  255. int *local)
  256. {
  257. if (num) {
  258. num -= 1;
  259. if (num < Numlights) {
  260. *xpos = Gv.lights[num].position[X];
  261. *ypos = Gv.lights[num].position[Y];
  262. *zpos = Gv.lights[num].position[Z];
  263. *local = (int)Gv.lights[num].position[W];
  264. }
  265. }
  266. return;
  267. }
  268. /*!
  269. \brief Set light color
  270. \param num light id (starts at 1)
  271. \param red,green,blue color values (from 0.0 to 1.0)
  272. */
  273. void GS_setlight_color(int num, float red, float green, float blue)
  274. {
  275. if (num) {
  276. num -= 1;
  277. if (num < Numlights) {
  278. Gv.lights[num].color[0] = red;
  279. Gv.lights[num].color[1] = green;
  280. Gv.lights[num].color[2] = blue;
  281. gsd_deflight(num + 1, &(Gv.lights[num]));
  282. }
  283. }
  284. return;
  285. }
  286. /*!
  287. \brief Get light color
  288. \param num light id (starts at 1)
  289. \param[out] red,green,blue color values
  290. */
  291. void GS_getlight_color(int num, float *red, float *green, float *blue)
  292. {
  293. if (num) {
  294. num -= 1;
  295. if (num < Numlights) {
  296. *red = Gv.lights[num].color[0];
  297. *green = Gv.lights[num].color[1];
  298. *blue = Gv.lights[num].color[2];
  299. }
  300. }
  301. return;
  302. }
  303. /*!
  304. \brief Set light ambient
  305. Red, green, blue from 0.0 to 1.0
  306. \param num light id (starts at 1)
  307. \param red,green,blue color values
  308. */
  309. void GS_setlight_ambient(int num, float red, float green, float blue)
  310. {
  311. if (num) {
  312. num -= 1;
  313. if (num < Numlights) {
  314. Gv.lights[num].ambient[0] = red;
  315. Gv.lights[num].ambient[1] = green;
  316. Gv.lights[num].ambient[2] = blue;
  317. gsd_deflight(num + 1, &(Gv.lights[num]));
  318. }
  319. }
  320. return;
  321. }
  322. /*!
  323. \brief Get light ambient
  324. \param num light id (starts at 1)
  325. \param[out] red,green,blue color values
  326. */
  327. void GS_getlight_ambient(int num, float *red, float *green, float *blue)
  328. {
  329. if (num) {
  330. num -= 1;
  331. if (num < Numlights) {
  332. *red = Gv.lights[num].ambient[0];
  333. *green = Gv.lights[num].ambient[1];
  334. *blue = Gv.lights[num].ambient[2];
  335. }
  336. }
  337. return;
  338. }
  339. /*!
  340. \brief Switch off all lights
  341. */
  342. void GS_lights_off(void)
  343. {
  344. int i;
  345. for (i = 0; i < Numlights; i++) {
  346. gsd_switchlight(i + 1, 0);
  347. }
  348. return;
  349. }
  350. /*!
  351. \brief Switch on all lights
  352. */
  353. void GS_lights_on(void)
  354. {
  355. int i;
  356. for (i = 0; i < Numlights; i++) {
  357. gsd_switchlight(i + 1, 1);
  358. }
  359. return;
  360. }
  361. /*!
  362. \brief Switch on/off light
  363. \param num light id (starts at 1)
  364. \param on non-zero for 'on' otherwise 'off'
  365. */
  366. void GS_switchlight(int num, int on)
  367. {
  368. if (num) {
  369. num -= 1;
  370. if (num < Numlights) {
  371. gsd_switchlight(num + 1, on);
  372. }
  373. }
  374. return;
  375. }
  376. /*!
  377. \brief Check if transparency is set
  378. \return 0 transparency not set
  379. \return 1 transparency is set
  380. */
  381. int GS_transp_is_set(void)
  382. {
  383. return (gs_att_is_set(NULL, ATT_TRANSP) || (FC_GREY == gsd_getfc()));
  384. }
  385. /*!
  386. \brief Retrieves coordinates for lighting model position, at center of view
  387. \param pos[out] coordinates
  388. */
  389. void GS_get_modelposition1(float pos[])
  390. {
  391. /* TODO: Still needs work to handle other cases */
  392. /* this is a quick hack to get lighting adjustments debugged */
  393. /*
  394. GS_v3dir(Gv.from_to[FROM], Gv.from_to[TO], center);
  395. GS_v3mult(center, 1000);
  396. GS_v3add(center, Gv.from_to[FROM]);
  397. */
  398. gs_get_datacenter(pos);
  399. gs_get_data_avg_zmax(&(pos[Z]));
  400. G_debug(1, "GS_get_modelposition1(): model position: %f %f %f",
  401. pos[X], pos[Y], pos[Z]);
  402. return;
  403. }
  404. /*!
  405. \brief Retrieves coordinates for lighting model position, at center of view
  406. Position at nearclip * 2: tried nearclip + siz, but since need to
  407. know position to calculate size, have two dependent variables
  408. (nearclip * 2) from eye.
  409. \param siz[out] size
  410. \param pos[out] coordinates (X, Y, Z)
  411. */
  412. void GS_get_modelposition(float *siz, float *pos)
  413. {
  414. float dist, near_h, dir[3];
  415. dist = 2. * Gd.nearclip;
  416. near_h = 2.0 * tan(4.0 * atan(1.) * Gv.fov / 3600.) * dist;
  417. *siz = near_h / 8.0;
  418. /* prevent clipping - would only happen if fov > ~127 degrees, at
  419. fov = 2.0 * atan(2.0) */
  420. if (*siz > Gd.nearclip) {
  421. *siz = Gd.nearclip;
  422. }
  423. GS_v3dir(Gv.from_to[FROM], Gv.from_to[TO], dir);
  424. pos[X] = Gv.from_to[FROM][X] + dir[X] * dist;
  425. pos[Y] = Gv.from_to[FROM][Y] + dir[Y] * dist;
  426. pos[Z] = Gv.from_to[FROM][Z] + dir[Z] * dist;
  427. return;
  428. }
  429. /*!
  430. \brief Set decoration, north arrow ??
  431. \todo scale used to calculate len of arrow still needs work
  432. needs go function that returns center / eye distance
  433. gsd_get_los function is not working correctly ??
  434. \param pt point value in true world coordinates (?)
  435. \param id surface id
  436. \param[out] pos2 output coordinates
  437. */
  438. void GS_set_Narrow(int *pt, int id, float *pos2)
  439. {
  440. geosurf *gs;
  441. float x, y, z;
  442. GLdouble modelMatrix[16], projMatrix[16];
  443. GLint viewport[4];
  444. if (GS_get_selected_point_on_surface(pt[X], pt[Y], &id, &x, &y, &z)) {
  445. gs = gs_get_surf(id);
  446. if (gs) {
  447. z = gs->zmax;
  448. pos2[X] = (float)x - gs->ox + gs->x_trans;
  449. pos2[Y] = (float)y - gs->oy + gs->y_trans;
  450. pos2[Z] = (float)z + gs->z_trans;
  451. return;
  452. }
  453. }
  454. else {
  455. gs = gs_get_surf(id);
  456. /* Need to get model matrix, etc
  457. * to run gluUnProject
  458. */
  459. gsd_pushmatrix();
  460. gsd_do_scale(1);
  461. glGetDoublev(GL_MODELVIEW_MATRIX, modelMatrix);
  462. glGetDoublev(GL_PROJECTION_MATRIX, projMatrix);
  463. glGetIntegerv(GL_VIEWPORT, viewport);
  464. if (gs) {
  465. GLdouble out_near[3], out_far[3];
  466. GLdouble factor;
  467. GLdouble out[3];
  468. z = (float)gs->zmax + gs->z_trans;
  469. gluUnProject((GLdouble) pt[X], (GLdouble) pt[Y], (GLdouble) 0.,
  470. modelMatrix, projMatrix, viewport,
  471. &out_near[X], &out_near[Y], &out_near[Z]);
  472. gluUnProject((GLdouble) pt[X], (GLdouble) pt[Y], (GLdouble) 1.,
  473. modelMatrix, projMatrix, viewport,
  474. &out_far[X], &out_far[Y], &out_far[Z]);
  475. glPopMatrix();
  476. factor = (out_near[Z] - z) / (out_near[Z] - out_far[Z]);
  477. out[X] = out_near[X] - ((out_near[X] - out_far[X]) * factor);
  478. out[Y] = out_near[Y] - ((out_near[Y] - out_far[Y]) * factor);
  479. out[Z] = z;
  480. pos2[X] = (float)out[X];
  481. pos2[Y] = (float)out[Y];
  482. pos2[Z] = (float)out[Z];
  483. return;
  484. }
  485. }
  486. return;
  487. }
  488. /*!
  489. \brief Draw place marker
  490. Used to display query point for raster queries.
  491. \param id surface id
  492. \param pt point, X, Y value in true world coordinates
  493. */
  494. void GS_draw_X(int id, float *pt)
  495. {
  496. geosurf *gs;
  497. Point3 pos;
  498. float siz;
  499. gvstyle style;
  500. if ((gs = gs_get_surf(id))) {
  501. GS_get_longdim(&siz);
  502. style.size = siz / 200.;
  503. pos[X] = pt[X] - gs->ox;
  504. pos[Y] = pt[Y] - gs->oy;
  505. _viewcell_tri_interp(gs, pos);
  506. gsd_pushmatrix();
  507. gsd_do_scale(1);
  508. gsd_translate(gs->x_trans, gs->y_trans, gs->z_trans);
  509. gsd_linewidth(1);
  510. if (CONST_ATT == gs_get_att_src(gs, ATT_TOPO)) {
  511. pos[Z] = gs->att[ATT_TOPO].constant;
  512. gs = NULL; /* tells gpd_obj to use given Z val */
  513. }
  514. style.color = Gd.bgcol;
  515. style.symbol = ST_GYRO;
  516. gpd_obj(gs, &style, pos);
  517. gsd_flush();
  518. gsd_popmatrix();
  519. }
  520. return;
  521. }
  522. /*!
  523. \brief Draw line on surface
  524. \param id surface id
  525. \param x1,y1,x2,y2 line nodes
  526. */
  527. void GS_draw_line_onsurf(int id, float x1, float y1, float x2, float y2)
  528. {
  529. float p1[2], p2[2];
  530. geosurf *gs;
  531. if ((gs = gs_get_surf(id))) {
  532. p1[X] = x1 - gs->ox;
  533. p1[Y] = y1 - gs->oy;
  534. p2[X] = x2 - gs->ox;
  535. p2[Y] = y2 - gs->oy;
  536. gsd_pushmatrix();
  537. gsd_do_scale(1);
  538. gsd_translate(gs->x_trans, gs->y_trans, gs->z_trans);
  539. gsd_linewidth(1);
  540. gsd_color_func(GS_default_draw_color());
  541. gsd_line_onsurf(gs, p1, p2);
  542. gsd_popmatrix();
  543. gsd_flush();
  544. }
  545. return;
  546. }
  547. /*!
  548. \brief Draw multiline on surface
  549. Like above but limits points in line to n or points found in segment,
  550. whichever is smaller.
  551. \param id surface id
  552. \param x1,y1,x2,y2 line nodes
  553. \return number of points used
  554. */
  555. int GS_draw_nline_onsurf(int id, float x1, float y1, float x2, float y2,
  556. float *lasp, int n)
  557. {
  558. float p1[2], p2[2];
  559. geosurf *gs;
  560. int ret = 0;
  561. if ((gs = gs_get_surf(id))) {
  562. p1[X] = x1 - gs->ox;
  563. p1[Y] = y1 - gs->oy;
  564. p2[X] = x2 - gs->ox;
  565. p2[Y] = y2 - gs->oy;
  566. gsd_pushmatrix();
  567. gsd_do_scale(1);
  568. gsd_translate(gs->x_trans, gs->y_trans, gs->z_trans);
  569. gsd_linewidth(1);
  570. gsd_color_func(GS_default_draw_color());
  571. ret = gsd_nline_onsurf(gs, p1, p2, lasp, n);
  572. gsd_surf2real(gs, lasp);
  573. gsd_popmatrix();
  574. gsd_flush();
  575. }
  576. return (ret);
  577. }
  578. /*!
  579. \brief Draw flow-line on surace
  580. This is slow - should be moved to gs_ but GS_ good for testing
  581. and useful for app programmer
  582. \param id surface id
  583. \param x,y coordinates of flow-line
  584. */
  585. void GS_draw_flowline_at_xy(int id, float x, float y)
  586. {
  587. geosurf *gs;
  588. float nv[3], pdir[2], mult;
  589. float p1[2], p2[2], next[2];
  590. int i = 0;
  591. if ((gs = gs_get_surf(id))) {
  592. p1[X] = x;
  593. p1[Y] = y;
  594. /* multiply by 1.5 resolutions to ensure a crossing ? */
  595. mult = .1 * (VXRES(gs) > VYRES(gs) ? VXRES(gs) : VYRES(gs));
  596. GS_coordpair_repeats(p1, p1, 50);
  597. while (1 == GS_get_norm_at_xy(id, p1[X], p1[Y], nv)) {
  598. if (nv[Z] == 1.0) {
  599. if (pdir[X] == 0.0 && pdir[Y] == 0.0) {
  600. break;
  601. }
  602. p2[X] = p1[X] + (pdir[X] * mult);
  603. p2[Y] = p1[Y] + (pdir[Y] * mult);
  604. }
  605. else {
  606. /* use previous direction */
  607. GS_v2norm(nv);
  608. p2[X] = p1[X] + (nv[X] * mult);
  609. p2[Y] = p1[Y] + (nv[Y] * mult);
  610. pdir[X] = nv[X];
  611. pdir[Y] = nv[Y];
  612. }
  613. if (i > 2000) {
  614. break;
  615. }
  616. if (GS_coordpair_repeats(p1, p2, 0)) {
  617. break;
  618. }
  619. /* Think about this: */
  620. /* degenerate line means edge or level edge ? */
  621. /* next is filled with last point drawn */
  622. if (2 > GS_draw_nline_onsurf(id, p1[X], p1[Y],
  623. p2[X], p2[Y], next, 3)) {
  624. break;
  625. }
  626. p1[X] = next[X];
  627. p1[Y] = next[Y];
  628. }
  629. G_debug(3, "GS_draw_flowline_at_xy(): dir: %f %f", nv[X], nv[Y]);
  630. }
  631. return;
  632. }
  633. /*!
  634. \brief Draw fringe around data (surface) at selected corners
  635. \param id surface id
  636. \param clr color
  637. \param elev elevation value
  638. \param where nw/ne/sw/se edges - 0 (turn off) 1 (turn on)
  639. */
  640. void GS_draw_fringe(int id, unsigned long clr, float elev, int *where)
  641. {
  642. geosurf *gs;
  643. G_debug(3, "GS_draw_fringe(): id: %d clr: %ld elev %f edges: %d %d %d %d",
  644. id, clr, elev, where[0], where[1], where[2], where[3]);
  645. if ((gs = gs_get_surf(id)))
  646. gsd_display_fringe(gs, clr, elev, where);
  647. }
  648. /*!
  649. \brief Draw legend
  650. \todo add legend from list option
  651. make font loading more flexible
  652. \param name legend name
  653. \param fontbase font-base
  654. \param size ?
  655. \param flags legend flags
  656. \param range values range
  657. \param pt ?
  658. */
  659. int GS_draw_legend(const char *name, GLuint fontbase, int size, int *flags,
  660. float *range, int *pt)
  661. {
  662. int list_no;
  663. list_no = gsd_put_legend(name, fontbase, size, flags, range, pt);
  664. return (list_no);
  665. }
  666. /*!
  667. \brief Draw pre-defined list
  668. Uses glFlush() to ensure all drawing is complete
  669. before returning
  670. \param list_id list id
  671. */
  672. void GS_draw_list(GLuint list_id)
  673. {
  674. gsd_calllist(list_id);
  675. glFlush();
  676. return;
  677. }
  678. /*!
  679. \brief Draw all glLists
  680. Uses glFlush() to ensure all drawing is complete
  681. before returning
  682. */
  683. void GS_draw_all_list(void)
  684. {
  685. gsd_calllists(0); /* not sure if 0 is right - MN */
  686. glFlush();
  687. return;
  688. }
  689. /*!
  690. \brief Delete pre-defined list
  691. \param list_id list id
  692. */
  693. void GS_delete_list(GLuint list_id)
  694. {
  695. gsd_deletelist(list_id, 1);
  696. return;
  697. }
  698. /*!
  699. \brief Draw lighting model
  700. */
  701. void GS_draw_lighting_model1(void)
  702. {
  703. static float center[3];
  704. float tcenter[3];
  705. if (!Modelshowing) {
  706. GS_get_modelposition1(center);
  707. }
  708. GS_v3eq(tcenter, center);
  709. gsd_zwritemask(0x0);
  710. gsd_backface(1);
  711. gsd_colormode(CM_AD);
  712. gsd_shademodel(DM_GOURAUD);
  713. gsd_pushmatrix();
  714. gsd_do_scale(1);
  715. if (Gv.vert_exag) {
  716. tcenter[Z] *= Gv.vert_exag;
  717. gsd_scale(1.0, 1.0, 1. / Gv.vert_exag);
  718. }
  719. gsd_drawsphere(tcenter, 0xDDDDDD, (float)(Longdim / 10.));
  720. gsd_popmatrix();
  721. Modelshowing = 1;
  722. gsd_backface(0);
  723. gsd_zwritemask(0xffffffff);
  724. return;
  725. }
  726. /*!
  727. \brief Draw lighting model
  728. Just turn off any cutting planes and draw it just outside near
  729. clipping plane, since lighting is infinite now
  730. */
  731. void GS_draw_lighting_model(void)
  732. {
  733. static float center[3], size;
  734. float tcenter[3], tsize;
  735. int i, wason[MAX_CPLANES];
  736. gsd_get_cplanes_state(wason);
  737. for (i = 0; i < MAX_CPLANES; i++) {
  738. if (wason[i]) {
  739. gsd_cplane_off(i);
  740. }
  741. }
  742. if (!Modelshowing) {
  743. GS_get_modelposition(&size, center);
  744. }
  745. GS_v3eq(tcenter, center);
  746. tsize = size;
  747. gsd_zwritemask(0x0);
  748. gsd_backface(1);
  749. gsd_colormode(CM_DIFFUSE);
  750. gsd_shademodel(DM_GOURAUD);
  751. gsd_pushmatrix();
  752. gsd_drawsphere(tcenter, 0xDDDDDD, tsize);
  753. gsd_popmatrix();
  754. Modelshowing = 1;
  755. gsd_backface(0);
  756. gsd_zwritemask(0xffffffff);
  757. for (i = 0; i < MAX_CPLANES; i++) {
  758. if (wason[i]) {
  759. gsd_cplane_on(i);
  760. }
  761. }
  762. gsd_flush();
  763. return;
  764. }
  765. /*!
  766. \brief Update current mask
  767. May be called to update total mask for a surface at convenient times
  768. instead of waiting until ready to redraw surface
  769. \param id surface id
  770. \return ?
  771. */
  772. int GS_update_curmask(int id)
  773. {
  774. geosurf *gs;
  775. gs = gs_get_surf(id);
  776. return (gs_update_curmask(gs));
  777. }
  778. /*!
  779. \brief Check if point is masked ?
  780. \param id surface id
  781. \param pt point
  782. \return 1 masked
  783. \return 0 not masked
  784. \return -1 on error, invalid surface id
  785. */
  786. int GS_is_masked(int id, float *pt)
  787. {
  788. geosurf *gs;
  789. Point3 tmp;
  790. if ((gs = gs_get_surf(id))) {
  791. tmp[X] = pt[X] - gs->ox;
  792. tmp[Y] = pt[Y] - gs->oy;
  793. return (gs_point_is_masked(gs, tmp));
  794. }
  795. return (-1);
  796. }
  797. /*!
  798. \brief Unset Scaled Difference surface
  799. */
  800. void GS_unset_SDsurf(void)
  801. {
  802. gsdiff_set_SDref(NULL);
  803. SDref_surf = 0;
  804. return;
  805. }
  806. /*!
  807. \brief Set surface as Scaled Difference surface
  808. \param id surface id
  809. \return 1 on success
  810. \return 0 on error, invalid surface id
  811. */
  812. int GS_set_SDsurf(int id)
  813. {
  814. geosurf *gs;
  815. if ((gs = gs_get_surf(id))) {
  816. gsdiff_set_SDref(gs);
  817. SDref_surf = id;
  818. return (1);
  819. }
  820. return (0);
  821. }
  822. /*!
  823. \brief Set ?
  824. \param scale scale value
  825. \return 1
  826. */
  827. int GS_set_SDscale(float scale)
  828. {
  829. gsdiff_set_SDscale(scale);
  830. return (1);
  831. }
  832. /*!
  833. \brief Get ?
  834. \param[out] id ?
  835. \return 1 on success
  836. \return 0 on error
  837. */
  838. int GS_get_SDsurf(int *id)
  839. {
  840. geosurf *gs;
  841. if ((gs = gsdiff_get_SDref())) {
  842. *id = SDref_surf;
  843. return (1);
  844. }
  845. return (0);
  846. }
  847. /*!
  848. \brief Get ?
  849. \param[out] scale value
  850. \return 1
  851. */
  852. int GS_get_SDscale(float *scale)
  853. {
  854. *scale = gsdiff_get_SDscale();
  855. return (1);
  856. }
  857. /*!
  858. \brief Update normals
  859. \param id surface id
  860. \return ?
  861. */
  862. int GS_update_normals(int id)
  863. {
  864. geosurf *gs;
  865. gs = gs_get_surf(id);
  866. return (gs_calc_normals(gs));
  867. }
  868. /*!
  869. \brief Get attributes
  870. \param id surface id
  871. \param att
  872. \param[out] set
  873. \param[out] constant
  874. \param[out] mapname
  875. \return 1 on success
  876. \return -1 on error (invalid surface id)
  877. */
  878. int GS_get_att(int id, int att, int *set, float *constant, char *mapname)
  879. {
  880. int src;
  881. geosurf *gs;
  882. gs = gs_get_surf(id);
  883. if (gs) {
  884. if (-1 != (src = gs_get_att_src(gs, att))) {
  885. *set = src;
  886. if (src == CONST_ATT) {
  887. *constant = gs->att[att].constant;
  888. }
  889. else if (src == MAP_ATT) {
  890. strcpy(mapname, gsds_get_name(gs->att[att].hdata));
  891. }
  892. return (1);
  893. }
  894. return (-1);
  895. }
  896. return (-1);
  897. }
  898. /*!
  899. \brief Get surface category on given position
  900. Prints "no data" or a description (i.e., "coniferous forest") to
  901. <i>catstr</i>. Usually call after GS_get_selected_point_on_surface().
  902. Define <i>att</i> as MAP_ATT
  903. \todo Allocate catstr using G_store()
  904. \param id surface id
  905. \param att attribute id (MAP_ATT)
  906. \param catstr cat string (must be allocated, dim?)
  907. \param x,y real coordinates
  908. \return -1 if no category info or point outside of window
  909. \return 1 on success
  910. */
  911. int GS_get_cat_at_xy(int id, int att, char *catstr, float x, float y)
  912. {
  913. int offset, drow, dcol, vrow, vcol;
  914. float ftmp, pt[3];
  915. typbuff *buff;
  916. geosurf *gs;
  917. *catstr = '\0';
  918. gs = gs_get_surf(id);
  919. if (NULL == gs) {
  920. return -1;
  921. }
  922. pt[X] = x;
  923. pt[Y] = y;
  924. gsd_real2surf(gs, pt);
  925. if (gs_point_is_masked(gs, pt)) {
  926. return -1;
  927. }
  928. if (!in_vregion(gs, pt)) {
  929. return -1;
  930. }
  931. if (MAP_ATT != gs_get_att_src(gs, att)) {
  932. sprintf(catstr, _("no category info"));
  933. return -1;
  934. }
  935. buff = gs_get_att_typbuff(gs, att, 0);
  936. vrow = Y2VROW(gs, pt[Y]);
  937. vcol = X2VCOL(gs, pt[X]);
  938. drow = VROW2DROW(gs, vrow);
  939. dcol = VCOL2DCOL(gs, vcol);
  940. offset = DRC2OFF(gs, drow, dcol);
  941. if (GET_MAPATT(buff, offset, ftmp)) {
  942. return
  943. (Gs_get_cat_label(gsds_get_name(gs->att[att].hdata),
  944. drow, dcol, catstr));
  945. }
  946. sprintf(catstr, _("no data"));
  947. return 1;
  948. }
  949. /*!
  950. \brief Get surface normal at x,y (real coordinates)
  951. Usually call after GS_get_selected_point_on_surface()
  952. \param id surface id
  953. \param x,y real coordinates
  954. \param[out] nv surface normal
  955. \return -1 if point outside of window or masked
  956. \return 1 on success
  957. */
  958. int GS_get_norm_at_xy(int id, float x, float y, float *nv)
  959. {
  960. int offset, drow, dcol, vrow, vcol;
  961. float pt[3];
  962. geosurf *gs;
  963. gs = gs_get_surf(id);
  964. if (NULL == gs) {
  965. return (-1);
  966. }
  967. if (gs->norm_needupdate) {
  968. gs_calc_normals(gs);
  969. }
  970. pt[X] = x;
  971. pt[Y] = y;
  972. gsd_real2surf(gs, pt);
  973. if (gs_point_is_masked(gs, pt)) {
  974. return (-1);
  975. }
  976. if (!in_vregion(gs, pt)) {
  977. return (-1);
  978. }
  979. vrow = Y2VROW(gs, pt[Y]);
  980. vcol = X2VCOL(gs, pt[X]);
  981. drow = VROW2DROW(gs, vrow);
  982. dcol = VCOL2DCOL(gs, vcol);
  983. offset = DRC2OFF(gs, drow, dcol);
  984. if (gs->norms) {
  985. FNORM(gs->norms[offset], nv);
  986. }
  987. else {
  988. /* otherwise must be a constant */
  989. nv[0] = 0.0;
  990. nv[1] = 0.0;
  991. nv[2] = 1.0;
  992. }
  993. return (1);
  994. }
  995. /*!
  996. \brief Get RGB color at given point
  997. Colors are translated to rgb and returned as Rxxx Gxxx Bxxx Usually
  998. call after GS_get_selected_point_on_surface().
  999. Prints NULL or the value (i.e., "921.5") to valstr
  1000. \param id surface id
  1001. \param att attribute id
  1002. \param[out] valstr value string (allocated, dim?)
  1003. \param x,y real coordinates
  1004. \return -1 if point outside of window or masked
  1005. \return 1 on success
  1006. */
  1007. int GS_get_val_at_xy(int id, int att, char *valstr, float x, float y)
  1008. {
  1009. int offset, drow, dcol, vrow, vcol;
  1010. float ftmp, pt[3];
  1011. typbuff *buff;
  1012. geosurf *gs;
  1013. *valstr = '\0';
  1014. gs = gs_get_surf(id);
  1015. if (NULL == gs) {
  1016. return -1;
  1017. }
  1018. pt[X] = x;
  1019. pt[Y] = y;
  1020. gsd_real2surf(gs, pt);
  1021. if (gs_point_is_masked(gs, pt)) {
  1022. return -1;
  1023. }
  1024. if (!in_vregion(gs, pt)) {
  1025. return (-1);
  1026. }
  1027. if (CONST_ATT == gs_get_att_src(gs, att)) {
  1028. if (att == ATT_COLOR) {
  1029. int r, g, b, i;
  1030. i = gs->att[att].constant;
  1031. sprintf(valstr, "R%d G%d B%d",
  1032. INT_TO_RED(i, r), INT_TO_GRN(i, g), INT_TO_BLU(i, b));
  1033. }
  1034. else {
  1035. sprintf(valstr, "%f", gs->att[att].constant);
  1036. }
  1037. return 1;
  1038. }
  1039. else if (MAP_ATT != gs_get_att_src(gs, att)) {
  1040. return -1;
  1041. }
  1042. buff = gs_get_att_typbuff(gs, att, 0);
  1043. vrow = Y2VROW(gs, pt[Y]);
  1044. vcol = X2VCOL(gs, pt[X]);
  1045. drow = VROW2DROW(gs, vrow);
  1046. dcol = VCOL2DCOL(gs, vcol);
  1047. offset = DRC2OFF(gs, drow, dcol);
  1048. if (GET_MAPATT(buff, offset, ftmp)) {
  1049. if (att == ATT_COLOR) {
  1050. int r, g, b, i;
  1051. i = gs_mapcolor(gs_get_att_typbuff(gs, ATT_COLOR, 0),
  1052. &(gs->att[ATT_COLOR]), offset);
  1053. sprintf(valstr, "R%d G%d B%d",
  1054. INT_TO_RED(i, r), INT_TO_GRN(i, g), INT_TO_BLU(i, b));
  1055. }
  1056. else {
  1057. sprintf(valstr, "%f", ftmp);
  1058. }
  1059. return (1);
  1060. }
  1061. sprintf(valstr, "NULL");
  1062. return (1);
  1063. }
  1064. /*!
  1065. \brief Unset attribute
  1066. \param id surface id
  1067. \param att attribute id
  1068. \return ?
  1069. */
  1070. int GS_unset_att(int id, int att)
  1071. {
  1072. geosurf *gs;
  1073. gs = gs_get_surf(id);
  1074. gs->mask_needupdate = 1;
  1075. return (gs_set_att_src(gs, att, NOTSET_ATT));
  1076. }
  1077. /*!
  1078. \brief Set attribute constant
  1079. \param id surface id
  1080. \param att attribute id
  1081. \param constant value
  1082. \return ?
  1083. */
  1084. int GS_set_att_const(int id, int att, float constant)
  1085. {
  1086. geosurf *gs;
  1087. int ret;
  1088. gs = gs_get_surf(id);
  1089. ret = (gs_set_att_const(gs, att, constant));
  1090. Gs_update_attrange(gs, att);
  1091. return (ret);
  1092. }
  1093. /*!
  1094. \brief Set mask mode
  1095. Mask attribute special: constant is set to indicate invert or no
  1096. \param id surface id
  1097. \param mode id
  1098. \return mode id
  1099. \return -1 on error (invalid surface id)
  1100. */
  1101. int GS_set_maskmode(int id, int mode)
  1102. {
  1103. geosurf *gs;
  1104. gs = gs_get_surf(id);
  1105. if (gs) {
  1106. gs->att[ATT_MASK].constant = mode;
  1107. gs->mask_needupdate = 1;
  1108. return (mode);
  1109. }
  1110. return (-1);
  1111. }
  1112. /*!
  1113. \brief Get mask mode
  1114. \param id surface id
  1115. \param[out] mode id
  1116. \return 1 on success
  1117. \return -1 on error (invalid surface id)
  1118. */
  1119. int GS_get_maskmode(int id, int *mode)
  1120. {
  1121. geosurf *gs;
  1122. gs = gs_get_surf(id);
  1123. if (gs) {
  1124. *mode = gs->att[ATT_MASK].constant;
  1125. return (1);
  1126. }
  1127. return (-1);
  1128. }
  1129. /*!
  1130. \brief Set client data
  1131. \param id surface id
  1132. \param clientd pointer to client data struct
  1133. \return 1 on success
  1134. \return -1 on error (invalid surface id)
  1135. */
  1136. int GS_Set_ClientData(int id, void *clientd)
  1137. {
  1138. geosurf *gs;
  1139. gs = gs_get_surf(id);
  1140. if (gs) {
  1141. gs->clientdata = clientd;
  1142. return (1);
  1143. }
  1144. return (-1);
  1145. }
  1146. /*!
  1147. \brief Get client data
  1148. \param id surface id
  1149. \return pointer to client data
  1150. \return NULL on error
  1151. */
  1152. void *GS_Get_ClientData(int id)
  1153. {
  1154. geosurf *gs;
  1155. gs = gs_get_surf(id);
  1156. if (gs) {
  1157. return (gs->clientdata);
  1158. }
  1159. return (NULL);
  1160. }
  1161. /*!
  1162. \brief Get number of surfaces
  1163. \return number of surfaces
  1164. */
  1165. int GS_num_surfs(void)
  1166. {
  1167. return (gs_num_surfaces());
  1168. }
  1169. /*!
  1170. \brief Get surface list
  1171. Must be freed when not neeed!
  1172. \param[out] numsurf number of available surfaces
  1173. \return pointer to surface array
  1174. \return NULL on error
  1175. */
  1176. int *GS_get_surf_list(int *numsurfs)
  1177. {
  1178. int i, *ret;
  1179. *numsurfs = Next_surf;
  1180. if (Next_surf) {
  1181. ret = (int *)G_malloc(Next_surf * sizeof(int));
  1182. for (i = 0; i < Next_surf; i++) {
  1183. ret[i] = Surf_ID[i];
  1184. }
  1185. return (ret);
  1186. }
  1187. return (NULL);
  1188. }
  1189. /*!
  1190. \brief Delete surface
  1191. \param id surface id
  1192. \return 1 on success
  1193. \return -1 on error
  1194. */
  1195. int GS_delete_surface(int id)
  1196. {
  1197. int i, j, found;
  1198. found = FALSE;
  1199. G_debug(1, "GS_delete_surface(): id=%d", id);
  1200. if (GS_surf_exists(id)) {
  1201. gs_delete_surf(id);
  1202. for (i = 0; i < Next_surf && !found; i++) {
  1203. if (Surf_ID[i] == id) {
  1204. found = TRUE;
  1205. for (j = i; j < Next_surf; j++) {
  1206. Surf_ID[j] = Surf_ID[j + 1];
  1207. }
  1208. }
  1209. }
  1210. gv_update_drapesurfs();
  1211. if (found) {
  1212. --Next_surf;
  1213. return 1;
  1214. }
  1215. }
  1216. return -1;
  1217. }
  1218. /*!
  1219. \brief Load raster map as attribute
  1220. \param id surface id
  1221. \param filename filename
  1222. \param att attribute descriptor
  1223. \return -1 on error (invalid surface id)
  1224. \return ?
  1225. */
  1226. int GS_load_att_map(int id, const char *filename, int att)
  1227. {
  1228. geosurf *gs;
  1229. unsigned int changed;
  1230. unsigned int atty;
  1231. const char *mapset;
  1232. struct Cell_head rast_head;
  1233. int reuse, begin, hdata, ret, neg, has_null;
  1234. typbuff *tbuff;
  1235. G_debug(3, "GS_load_att_map(): map=%s", filename);
  1236. reuse = ret = neg = has_null = 0;
  1237. gs = gs_get_surf(id);
  1238. if (NULL == gs) {
  1239. return -1;
  1240. }
  1241. gs->mask_needupdate = (ATT_MASK == att || ATT_TOPO == att ||
  1242. (gs->nz_topo && ATT_TOPO == att) ||
  1243. (gs->nz_color && ATT_COLOR == att));
  1244. gs_set_att_src(gs, att, MAP_ATT);
  1245. /* Check against maps already loaded in memory */
  1246. /* if to be color attribute:
  1247. - if packed color for another surface, OK to reuse
  1248. - if unchanged, ok to reuse IF it's of type char (will have lookup)
  1249. */
  1250. begin = hdata = 1;
  1251. /* Get MAPSET to ensure names are fully qualified */
  1252. mapset = G_find_raster2(filename, "");
  1253. if (mapset == NULL) {
  1254. /* Check for valid filename */
  1255. G_warning("Raster map <%s> not found", filename);
  1256. return -1;
  1257. }
  1258. /* Check to see if map is in Region */
  1259. Rast_get_cellhd(filename, mapset, &rast_head);
  1260. if (rast_head.north <= wind.south ||
  1261. rast_head.south >= wind.north ||
  1262. rast_head.east <= wind.west || rast_head.west >= wind.east) {
  1263. G_warning(_("Raster map <%s> is outside of current region. Load failed."),
  1264. G_fully_qualified_name(filename, mapset));
  1265. }
  1266. while (!reuse && (0 < hdata)) {
  1267. changed = CF_COLOR_PACKED;
  1268. atty = ATTY_FLOAT | ATTY_CHAR | ATTY_INT | ATTY_SHORT | ATTY_MASK;
  1269. if (0 < (hdata = gsds_findh(filename, &changed, &atty, begin))) {
  1270. G_debug(3, "GS_load_att_map(): %s already has data handle %d.CF=%x",
  1271. filename, hdata, changed);
  1272. /* handle found */
  1273. if (ATT_COLOR == att) {
  1274. if ((changed == CF_COLOR_PACKED) ||
  1275. (!changed && atty == ATTY_CHAR)) {
  1276. reuse = 1;
  1277. }
  1278. }
  1279. else if (atty == ATTY_MASK && att != ATT_MASK) {
  1280. reuse = 0;
  1281. /* should also free mask data & share new - but need backward
  1282. reference? */
  1283. }
  1284. else if (!changed) {
  1285. reuse = 1;
  1286. }
  1287. }
  1288. begin = 0;
  1289. }
  1290. if (reuse) {
  1291. gs->att[att].hdata = hdata;
  1292. gs_set_att_type(gs, att, atty); /* ?? */
  1293. /* free lookup & set to NULL! */
  1294. if (atty == ATTY_INT) {
  1295. if (gs->att[att].lookup) {
  1296. free(gs->att[att].lookup);
  1297. gs->att[att].lookup = NULL;
  1298. }
  1299. }
  1300. /* TODO: FIX THIS stuff with lookup sharing! */
  1301. G_debug(3, "GS_load_att_map(): %s is being reused. hdata=%d",
  1302. filename, hdata);
  1303. }
  1304. else {
  1305. G_debug(3, "GS_load_att_map(): %s not loaded in correct form - loading now",
  1306. filename);
  1307. /* not loaded - need to get new dataset handle */
  1308. gs->att[att].hdata = gsds_newh(filename);
  1309. tbuff = gs_get_att_typbuff(gs, att, 1);
  1310. /* TODO: Provide mechanism for loading certain attributes at
  1311. specified sizes, allow scaling or capping, or scale non-zero */
  1312. if (ATT_MASK == att) {
  1313. atty = ATTY_MASK;
  1314. }
  1315. else {
  1316. atty = Gs_numtype(filename, &neg);
  1317. }
  1318. #ifdef MAYBE_LATER
  1319. if (att == ATT_COLOR && atty == ATTY_SHORT) {
  1320. atty = (neg ? ATTY_INT : ATTY_SHORT);
  1321. }
  1322. #endif
  1323. if (att == ATT_COLOR && atty == ATTY_SHORT) {
  1324. atty = ATTY_INT;
  1325. }
  1326. if (0 == gs_malloc_att_buff(gs, att, ATTY_NULL)) {
  1327. G_fatal_error(_("GS_load_att_map(): Out of memory. Unable to load map"));
  1328. }
  1329. switch (atty) {
  1330. case ATTY_MASK:
  1331. if (0 == gs_malloc_att_buff(gs, att, ATTY_MASK)) {
  1332. G_fatal_error(_("GS_load_att_map(): Out of memory. Unable to load map"));
  1333. }
  1334. ret = Gs_loadmap_as_bitmap(&wind, filename, tbuff->bm);
  1335. break;
  1336. case ATTY_CHAR:
  1337. if (0 == gs_malloc_att_buff(gs, att, ATTY_CHAR)) {
  1338. G_fatal_error(_("GS_load_att_map(): Out of memory. Unable to load map"));
  1339. }
  1340. ret = Gs_loadmap_as_char(&wind, filename, tbuff->cb,
  1341. tbuff->nm, &has_null);
  1342. break;
  1343. case ATTY_SHORT:
  1344. if (0 == gs_malloc_att_buff(gs, att, ATTY_SHORT)) {
  1345. G_fatal_error(_("GS_load_att_map(): Out of memory. Unable to load map"));
  1346. }
  1347. ret = Gs_loadmap_as_short(&wind, filename, tbuff->sb,
  1348. tbuff->nm, &has_null);
  1349. break;
  1350. case ATTY_FLOAT:
  1351. if (0 == gs_malloc_att_buff(gs, att, ATTY_FLOAT)) {
  1352. G_fatal_error(_("GS_load_att_map(): Out of memory. Unable to load map"));
  1353. }
  1354. ret = Gs_loadmap_as_float(&wind, filename, tbuff->fb,
  1355. tbuff->nm, &has_null);
  1356. break;
  1357. case ATTY_INT:
  1358. default:
  1359. if (0 == gs_malloc_att_buff(gs, att, ATTY_INT)) {
  1360. G_fatal_error(_("GS_load_att_map(): Out of memory. Unable to load map"));
  1361. }
  1362. ret = Gs_loadmap_as_int(&wind, filename, tbuff->ib,
  1363. tbuff->nm, &has_null);
  1364. break;
  1365. } /* Done with switch */
  1366. if (ret == -1) {
  1367. gsds_free_data_buff(gs->att[att].hdata, ATTY_NULL);
  1368. return -1;
  1369. }
  1370. G_debug(4, " has_null=%d", has_null);
  1371. if (!has_null) {
  1372. gsds_free_data_buff(gs->att[att].hdata, ATTY_NULL);
  1373. }
  1374. else {
  1375. gs_update_curmask(gs);
  1376. }
  1377. } /* end if not reuse */
  1378. if (ATT_COLOR == att) {
  1379. #ifdef MAYBE_LATER
  1380. if (ATTY_INT == atty) {
  1381. Gs_pack_colors(filename, tbuff->ib, gs->rows, gs->cols);
  1382. gsds_set_changed(gs->att[att].hdata, CF_COLOR_PACKED);
  1383. gs->att[att].lookup = NULL;
  1384. }
  1385. else {
  1386. gs_malloc_lookup(gs, att);
  1387. Gs_build_lookup(filename, gs->att[att].lookup);
  1388. }
  1389. #else
  1390. if (ATTY_CHAR == atty) {
  1391. if (!gs->att[att].lookup) {
  1392. /* might already exist if reusing */
  1393. gs_malloc_lookup(gs, att);
  1394. Gs_build_256lookup(filename, gs->att[att].lookup);
  1395. }
  1396. }
  1397. else if (ATTY_FLOAT == atty) {
  1398. if (!reuse) {
  1399. if (0 == gs_malloc_att_buff(gs, att, ATTY_INT)) {
  1400. G_fatal_error(_("GS_load_att_map(): Out of memory. Unable to load map"));
  1401. }
  1402. Gs_pack_colors_float(filename, tbuff->fb, tbuff->ib,
  1403. gs->rows, gs->cols);
  1404. gsds_set_changed(gs->att[att].hdata, CF_COLOR_PACKED);
  1405. gsds_free_data_buff(gs->att[att].hdata, ATTY_FLOAT);
  1406. gs->att[att].lookup = NULL;
  1407. }
  1408. }
  1409. else {
  1410. if (!reuse) {
  1411. Gs_pack_colors(filename, tbuff->ib, gs->rows, gs->cols);
  1412. gsds_set_changed(gs->att[att].hdata, CF_COLOR_PACKED);
  1413. gs->att[att].lookup = NULL;
  1414. }
  1415. }
  1416. #endif
  1417. }
  1418. if (ATT_TOPO == att) {
  1419. gs_init_normbuff(gs);
  1420. /* S_DIFF: should also check here to see if this surface is a
  1421. reference surface for scaled differences, if so update references
  1422. to it */
  1423. }
  1424. if (ret < 0) {
  1425. G_warning(_("Loading failed"));
  1426. }
  1427. if (-1 == Gs_update_attrange(gs, att)) {
  1428. G_warning(_("Error finding range"));
  1429. }
  1430. return ret;
  1431. }
  1432. /*!
  1433. \brief Draw surface
  1434. \param id surface id
  1435. */
  1436. void GS_draw_surf(int id)
  1437. {
  1438. geosurf *gs;
  1439. G_debug(3, "GS_draw_surf(): id=%d", id);
  1440. gs = gs_get_surf(id);
  1441. if (gs) {
  1442. gsd_shademodel(gs->draw_mode & DM_GOURAUD);
  1443. if (gs->draw_mode & DM_POLY) {
  1444. gsd_surf(gs);
  1445. }
  1446. if (gs->draw_mode & DM_WIRE) {
  1447. gsd_wire_surf(gs);
  1448. }
  1449. /* TODO: write wire/poly draw routines */
  1450. if (gs->draw_mode & DM_WIRE_POLY) {
  1451. gsd_surf(gs);
  1452. gsd_wire_surf(gs);
  1453. }
  1454. }
  1455. return;
  1456. }
  1457. /*!
  1458. \brief Draw surface wire
  1459. Overrides draw_mode for fast display
  1460. \param id surface id
  1461. */
  1462. void GS_draw_wire(int id)
  1463. {
  1464. geosurf *gs;
  1465. G_debug(3, "GS_draw_wire(): id=%d", id);
  1466. gs = gs_get_surf(id);
  1467. if (gs) {
  1468. gsd_wire_surf(gs);
  1469. }
  1470. return;
  1471. }
  1472. /*!
  1473. \brief Draw all wires
  1474. Overrides draw_mode for fast display
  1475. */
  1476. void GS_alldraw_wire(void)
  1477. {
  1478. geosurf *gs;
  1479. int i;
  1480. for (i = 0; i < Next_surf; i++) {
  1481. if ((gs = gs_get_surf(Surf_ID[i]))) {
  1482. gsd_wire_surf(gs);
  1483. }
  1484. }
  1485. return;
  1486. }
  1487. /*!
  1488. \brief Draw all surfaces
  1489. */
  1490. void GS_alldraw_surf(void)
  1491. {
  1492. int i;
  1493. for (i = 0; i < Next_surf; i++) {
  1494. GS_draw_surf(Surf_ID[i]);
  1495. }
  1496. return;
  1497. }
  1498. /*!
  1499. \brief Set Z exag for surface
  1500. \param id surface id
  1501. \param exag z-exag value
  1502. */
  1503. void GS_set_exag(int id, float exag)
  1504. {
  1505. geosurf *gs;
  1506. G_debug(3, "GS_set_exag");
  1507. gs = gs_get_surf(id);
  1508. if (gs) {
  1509. if (gs->z_exag != exag) {
  1510. gs->norm_needupdate = 1;
  1511. }
  1512. gs->z_exag = exag;
  1513. }
  1514. return;
  1515. }
  1516. /*!
  1517. \brief Set global z-exag value
  1518. \param exag exag value to be set up
  1519. */
  1520. void GS_set_global_exag(float exag)
  1521. {
  1522. G_debug(3, "GS_set_global_exag");
  1523. Gv.vert_exag = exag;
  1524. /* GL_NORMALIZE */
  1525. /* Only need to update norms gs_norms.c
  1526. * if exag is used in norm equation which
  1527. * it is not! If GL_NORMALIZE is disabled
  1528. * will need to include.
  1529. gs_setall_norm_needupdate();
  1530. */
  1531. return;
  1532. }
  1533. /*!
  1534. \brief Get global z-exag value
  1535. \return value
  1536. */
  1537. float GS_global_exag(void)
  1538. {
  1539. G_debug(3, "GS_global_exag(): %g", Gv.vert_exag);
  1540. return (Gv.vert_exag);
  1541. }
  1542. /*!
  1543. \brief Set wire color
  1544. \todo error-handling
  1545. \param id surface id
  1546. \param colr color value
  1547. */
  1548. void GS_set_wire_color(int id, int colr)
  1549. {
  1550. geosurf *gs;
  1551. G_debug(3, "GS_set_wire_color");
  1552. gs = gs_get_surf(id);
  1553. if (gs) {
  1554. gs->wire_color = colr;
  1555. }
  1556. return;
  1557. }
  1558. /*!
  1559. \brief Get wire color
  1560. \param id surface id
  1561. \param[out] colr color value
  1562. \return 1 on success
  1563. \return -1 on error
  1564. */
  1565. int GS_get_wire_color(int id, int *colr)
  1566. {
  1567. geosurf *gs;
  1568. gs = gs_get_surf(id);
  1569. if (gs) {
  1570. *colr = gs->wire_color;
  1571. return (1);
  1572. }
  1573. return (-1);
  1574. }
  1575. /*!
  1576. \brief Set all draw-modes
  1577. \param mode mode id
  1578. \return 0 on success
  1579. \return -1 on error
  1580. */
  1581. int GS_setall_drawmode(int mode)
  1582. {
  1583. int i;
  1584. for (i = 0; i < Next_surf; i++) {
  1585. if (0 != GS_set_drawmode(Surf_ID[i], mode)) {
  1586. return (-1);
  1587. }
  1588. }
  1589. return (0);
  1590. }
  1591. /*!
  1592. \brief Set draw mode
  1593. \param id surface id
  1594. \param mode mode type(s)
  1595. \return 0 on success
  1596. \return -1 on error (invalid surface id)
  1597. */
  1598. int GS_set_drawmode(int id, int mode)
  1599. {
  1600. geosurf *gs;
  1601. G_debug(3, "GS_set_drawmode(): id=%d mode=%d", id, mode);
  1602. gs = gs_get_surf(id);
  1603. if (gs) {
  1604. gs->draw_mode = mode;
  1605. return (0);
  1606. }
  1607. return (-1);
  1608. }
  1609. /*!
  1610. \brief Get draw mode
  1611. \param id surface id
  1612. \param[out] mode mode id
  1613. \return 1 on success
  1614. \return -1 on error (invalid surface id)
  1615. */
  1616. int GS_get_drawmode(int id, int *mode)
  1617. {
  1618. geosurf *gs;
  1619. gs = gs_get_surf(id);
  1620. if (gs) {
  1621. *mode = gs->draw_mode;
  1622. return (1);
  1623. }
  1624. return (-1);
  1625. }
  1626. /*!
  1627. \brief Set no-zero ?
  1628. \param id surface id
  1629. \param att attribute id
  1630. \param mode mode id
  1631. */
  1632. void GS_set_nozero(int id, int att, int mode)
  1633. {
  1634. geosurf *gs;
  1635. G_debug(3, "GS_set_nozero");
  1636. gs = gs_get_surf(id);
  1637. if (gs) {
  1638. if (att == ATT_TOPO) {
  1639. gs->nz_topo = mode;
  1640. gs->mask_needupdate = 1;
  1641. }
  1642. if (att == ATT_COLOR) {
  1643. gs->nz_color = mode;
  1644. gs->mask_needupdate = 1;
  1645. }
  1646. }
  1647. return;
  1648. }
  1649. /*!
  1650. \brief Get no-zero ?
  1651. \param id surface id
  1652. \param att attribute id
  1653. \param[out] mode mode id
  1654. \return -1 on error (invalid surface id)
  1655. \return 1 on success
  1656. */
  1657. int GS_get_nozero(int id, int att, int *mode)
  1658. {
  1659. geosurf *gs;
  1660. G_debug(3, "GS_set_nozero");
  1661. gs = gs_get_surf(id);
  1662. if (gs) {
  1663. if (att == ATT_TOPO) {
  1664. *mode = gs->nz_topo;
  1665. }
  1666. else if (att == ATT_COLOR) {
  1667. *mode = gs->nz_color;
  1668. }
  1669. else {
  1670. return (-1);
  1671. }
  1672. return (1);
  1673. }
  1674. return (-1);
  1675. }
  1676. /*!
  1677. \brief Set all draw resolutions
  1678. \param xres,yres x/y resolution value
  1679. \param xwire,ywire x/y wire value
  1680. \return 0 on success
  1681. \return -1 on error
  1682. */
  1683. int GS_setall_drawres(int xres, int yres, int xwire, int ywire)
  1684. {
  1685. int i;
  1686. for (i = 0; i < Next_surf; i++) {
  1687. if (0 != GS_set_drawres(Surf_ID[i], xres, yres, xwire, ywire)) {
  1688. return (-1);
  1689. }
  1690. }
  1691. return (0);
  1692. }
  1693. /*!
  1694. \brief Set draw resolution for surface
  1695. \param id surface id
  1696. \param xres,yres x/y resolution value
  1697. \param xwire,ywire x/y wire value
  1698. \return -1 on error
  1699. \return 0 on success
  1700. */
  1701. int GS_set_drawres(int id, int xres, int yres, int xwire, int ywire)
  1702. {
  1703. geosurf *gs;
  1704. G_debug(3, "GS_set_drawres() id=%d xyres=%d/%d xywire=%d/%d",
  1705. id, xres, yres, xwire, ywire);
  1706. if (xres < 1 || yres < 1 || xwire < 1 || ywire < 1) {
  1707. return (-1);
  1708. }
  1709. gs = gs_get_surf(id);
  1710. if (gs) {
  1711. if (gs->x_mod != xres || gs->y_mod != yres) {
  1712. gs->norm_needupdate = 1;
  1713. }
  1714. gs->x_mod = xres;
  1715. gs->y_mod = yres;
  1716. gs->x_modw = xwire;
  1717. gs->y_modw = ywire;
  1718. }
  1719. return (0);
  1720. }
  1721. /*!
  1722. \brief Get draw resolution of surface
  1723. \param id surface id
  1724. \param[out] xres,yres x/y resolution value
  1725. \param[out] xwire,ywire x/y wire value
  1726. */
  1727. void GS_get_drawres(int id, int *xres, int *yres, int *xwire, int *ywire)
  1728. {
  1729. geosurf *gs;
  1730. G_debug(3, "GS_get_drawres");
  1731. gs = gs_get_surf(id);
  1732. if (gs) {
  1733. *xres = gs->x_mod;
  1734. *yres = gs->y_mod;
  1735. *xwire = gs->x_modw;
  1736. *ywire = gs->y_modw;
  1737. }
  1738. return;
  1739. }
  1740. /*!
  1741. \brief Get dimension of surface
  1742. \param id surface id
  1743. \param[out] rows,cols number of rows/cols
  1744. */
  1745. void GS_get_dims(int id, int *rows, int *cols)
  1746. {
  1747. geosurf *gs;
  1748. gs = gs_get_surf(id);
  1749. if (gs) {
  1750. *rows = gs->rows;
  1751. *cols = gs->cols;
  1752. }
  1753. return;
  1754. }
  1755. /*!
  1756. \brief Get exag-value guess
  1757. Use no_zero range because if zero IS data, then range won't be that
  1758. much off (it's just a GUESS, after all), but if zero is NO data, could
  1759. drastically affect guess
  1760. \param id surface id
  1761. \param[out] exag exag value
  1762. \return 1 on success
  1763. \return -1 on error
  1764. */
  1765. int GS_get_exag_guess(int id, float *exag)
  1766. {
  1767. geosurf *gs;
  1768. float guess;
  1769. gs = gs_get_surf(id);
  1770. guess = 1.0;
  1771. /* if gs is type const return guess = 1.0 */
  1772. if (CONST_ATT == gs_get_att_src(gs, ATT_TOPO)) {
  1773. *exag = guess;
  1774. return (1);
  1775. }
  1776. if (gs) {
  1777. if (gs->zrange_nz == 0.0) {
  1778. *exag = 0.0;
  1779. return (1);
  1780. }
  1781. G_debug(3, "GS_get_exag_guess(): %f %f", gs->zrange_nz, Longdim);
  1782. while (gs->zrange_nz * guess / Longdim >= .25) {
  1783. guess *= .1;
  1784. G_debug(3, "GS_get_exag_guess(): %f", guess);
  1785. }
  1786. while (gs->zrange_nz * guess / Longdim < .025) {
  1787. guess *= 10.;
  1788. G_debug(3, "GS_get_exag_guess(): %f", guess);
  1789. }
  1790. *exag = guess;
  1791. return (1);
  1792. }
  1793. return (-1);
  1794. }
  1795. /*!
  1796. \brief Get Z extents for all loaded surfaces
  1797. Treating zeros as "no data"
  1798. \param[out] min min value
  1799. \param[out] max max value
  1800. */
  1801. void GS_get_zrange_nz(float *min, float *max)
  1802. {
  1803. int i, first = 1;
  1804. geosurf *gs;
  1805. for (i = 0; i < Next_surf; i++) {
  1806. if ((gs = gs_get_surf(Surf_ID[i]))) {
  1807. if (first) {
  1808. first = 0;
  1809. *min = gs->zmin_nz;
  1810. *max = gs->zmax_nz;
  1811. }
  1812. if (gs->zmin_nz < *min) {
  1813. *min = gs->zmin_nz;
  1814. }
  1815. if (gs->zmax_nz > *max) {
  1816. *max = gs->zmax_nz;
  1817. }
  1818. }
  1819. }
  1820. G_debug(3, "GS_get_zrange_nz(): min=%g max=%g", *min, *max);
  1821. return;
  1822. }
  1823. /*!
  1824. \brief Set translation (surface position)
  1825. \param id surface id
  1826. \param xtrans,ytrans,ztrans translation values
  1827. */
  1828. void GS_set_trans(int id, float xtrans, float ytrans, float ztrans)
  1829. {
  1830. geosurf *gs;
  1831. gs = gs_get_surf(id);
  1832. if (gs) {
  1833. gs->x_trans = xtrans;
  1834. gs->y_trans = ytrans;
  1835. gs->z_trans = ztrans;
  1836. }
  1837. G_debug(3, "GS_set_trans(): id=%d, x=%f, y=%f, z=%f",
  1838. id, xtrans, ytrans, ztrans);
  1839. return;
  1840. }
  1841. /*!
  1842. \brief Get translation values (surface position)
  1843. \param id surface id
  1844. \param[out] xtrans,ytrans,ztrans trans values
  1845. */
  1846. void GS_get_trans(int id, float *xtrans, float *ytrans, float *ztrans)
  1847. {
  1848. geosurf *gs;
  1849. gs = gs_get_surf(id);
  1850. if (gs) {
  1851. *xtrans = gs->x_trans;
  1852. *ytrans = gs->y_trans;
  1853. *ztrans = gs->z_trans;
  1854. }
  1855. G_debug(3, "GS_get_trans: id=%d, x=%f, y=%f, z=%f",
  1856. id, *xtrans, *ytrans, *ztrans);
  1857. return;
  1858. }
  1859. /*!
  1860. \brief Get default draw color
  1861. \return color value
  1862. */
  1863. unsigned int GS_default_draw_color(void)
  1864. {
  1865. G_debug(3, "GS_default_draw_color");
  1866. return ((unsigned int)Gd.bgcol);
  1867. }
  1868. /*!
  1869. \brief Get background color
  1870. \return color value
  1871. */
  1872. unsigned int GS_background_color(void)
  1873. {
  1874. return ((unsigned int)Gd.bgcol);
  1875. }
  1876. /*!
  1877. \brief Sets which buffer to draw to
  1878. \param where GSD_BOTH, GSD_FRONT, GSD_BACK
  1879. */
  1880. void GS_set_draw(int where)
  1881. {
  1882. Buffermode = where;
  1883. switch (where) {
  1884. case GSD_BOTH:
  1885. gsd_bothbuffers();
  1886. break;
  1887. case GSD_FRONT:
  1888. gsd_frontbuffer();
  1889. break;
  1890. case GSD_BACK:
  1891. default:
  1892. gsd_backbuffer();
  1893. break;
  1894. }
  1895. return;
  1896. }
  1897. /*
  1898. \brief Ready to draw
  1899. */
  1900. void GS_ready_draw(void)
  1901. {
  1902. G_debug(3, "GS_ready_draw");
  1903. gsd_set_view(&Gv, &Gd);
  1904. return;
  1905. }
  1906. /*!
  1907. \brief Draw done, swap buffers
  1908. */
  1909. void GS_done_draw(void)
  1910. {
  1911. G_debug(3, "GS_done_draw");
  1912. if (GSD_BACK == Buffermode) {
  1913. gsd_swapbuffers();
  1914. }
  1915. gsd_flush();
  1916. return;
  1917. }
  1918. /*!
  1919. \brief Set focus
  1920. \param realto real coordinates to
  1921. */
  1922. void GS_set_focus(float *realto)
  1923. {
  1924. G_debug(3, "GS_set_focus(): %f,%f,%f", realto[0], realto[1], realto[2]);
  1925. Gv.infocus = 1;
  1926. GS_v3eq(Gv.real_to, realto);
  1927. gsd_set_view(&Gv, &Gd);
  1928. return;
  1929. }
  1930. /*!
  1931. \brief Set real focus
  1932. \param realto real coordinates to
  1933. */
  1934. void GS_set_focus_real(float *realto)
  1935. {
  1936. G_get_set_window(&wind);
  1937. realto[X] = realto[X] - wind.west - (wind.ew_res / 2.);
  1938. realto[Y] = realto[Y] - wind.south - (wind.ns_res / 2.);
  1939. Gv.infocus = 1;
  1940. GS_v3eq(Gv.real_to, realto);
  1941. gsd_set_view(&Gv, &Gd);
  1942. return;
  1943. }
  1944. /*!
  1945. \brief Get focus
  1946. OK to call with NULL argument if just want to check state
  1947. \param realto real coordinates to
  1948. \return ?
  1949. */
  1950. int GS_get_focus(float *realto)
  1951. {
  1952. G_debug(3, "GS_get_focus");
  1953. if (Gv.infocus) {
  1954. if (realto) {
  1955. GS_v3eq(realto, Gv.real_to);
  1956. }
  1957. }
  1958. return (Gv.infocus);
  1959. }
  1960. /*!
  1961. \brief Set focus to map center
  1962. \param id surface id
  1963. */
  1964. void GS_set_focus_center_map(int id)
  1965. {
  1966. float center[3];
  1967. geosurf *gs;
  1968. G_debug(3, "GS_set_focus_center_map");
  1969. gs = gs_get_surf(id);
  1970. if (gs) {
  1971. center[X] = (gs->xmax - gs->xmin) / 2.;
  1972. center[Y] = (gs->ymax - gs->ymin) / 2.;
  1973. center[Z] = (gs->zmax_nz + gs->zmin_nz) / 2.;
  1974. /* not yet working
  1975. buff = gs_get_att_typbuff(gs, ATT_TOPO, 0);
  1976. offset = gs->rows*gs->cols/2 + gs->cols/2;
  1977. if (buff)
  1978. {
  1979. if (GET_MAPATT(buff, offset, tmp))
  1980. {
  1981. center[Z] = tmp;
  1982. }
  1983. }
  1984. */
  1985. GS_set_focus(center);
  1986. }
  1987. }
  1988. /*!
  1989. \brief Move viewpoint
  1990. \param pt 'from' model coordinates
  1991. */
  1992. void GS_moveto(float *pt)
  1993. {
  1994. float ft[3];
  1995. G_debug(3, "GS_moveto(): %f,%f,%f", pt[0], pt[1], pt[2]);
  1996. if (Gv.infocus) {
  1997. GS_v3eq(Gv.from_to[FROM], pt);
  1998. /*
  1999. GS_v3eq(Gv.from_to[TO], Gv.real_to);
  2000. */
  2001. GS_v3normalize(Gv.from_to[FROM], Gv.from_to[TO]);
  2002. /* update inclination, look_dir if we're keeping these */
  2003. }
  2004. else {
  2005. GS_v3eq(ft, Gv.from_to[TO]);
  2006. GS_v3sub(ft, Gv.from_to[FROM]);
  2007. GS_v3eq(Gv.from_to[FROM], pt);
  2008. GS_v3eq(Gv.from_to[TO], pt);
  2009. GS_v3add(Gv.from_to[TO], ft);
  2010. }
  2011. return;
  2012. }
  2013. /*!
  2014. \brief Move position to (real)
  2015. \param pt point real coordinates
  2016. */
  2017. void GS_moveto_real(float *pt)
  2018. {
  2019. gsd_real2model(pt);
  2020. GS_moveto(pt);
  2021. return;
  2022. }
  2023. /*!
  2024. \brief Get z-extent for a single surface
  2025. \param id surface id
  2026. \param[out] min min z-value
  2027. \param[out] max max z-value
  2028. \param[out] mid middle z-value
  2029. \return -1 on error (invalid surface id)
  2030. \return ?
  2031. */
  2032. int GS_get_zextents(int id, float *min, float *max, float *mid)
  2033. {
  2034. geosurf *gs;
  2035. if (NULL == (gs = gs_get_surf(id))) {
  2036. return (-1);
  2037. }
  2038. G_debug(3, "GS_get_zextents(): id=%d", id);
  2039. return (gs_get_zextents(gs, min, max, mid));
  2040. }
  2041. /*!
  2042. \brief Get z-extent for all loaded surfaces
  2043. \param[out] min min z-value
  2044. \param[out] max max z-value
  2045. \param doexag use z-exaggeration
  2046. \return 1 on success
  2047. \return -1 on error
  2048. */
  2049. int GS_get_zrange(float *min, float *max, int doexag)
  2050. {
  2051. int ret_surf, ret_vol;
  2052. float surf_min, surf_max;
  2053. float vol_min, vol_max;
  2054. ret_surf = gs_get_zrange(&surf_min, &surf_max);
  2055. ret_vol = gvl_get_zrange(&vol_min, &vol_max);
  2056. if (ret_surf > 0 && ret_vol > 0) {
  2057. *min = (surf_min < vol_min) ? surf_min : vol_min;
  2058. *max = (surf_max < vol_max) ? surf_max : vol_max;
  2059. }
  2060. else if (ret_surf > 0) {
  2061. *min = surf_min;
  2062. *max = surf_max;
  2063. }
  2064. else if (ret_vol > 0) {
  2065. *min = vol_min;
  2066. *max = vol_max;
  2067. }
  2068. if (doexag) {
  2069. *min *= Gv.vert_exag;
  2070. *max *= Gv.vert_exag;
  2071. }
  2072. G_debug(3, "GS_get_zrange(): min=%g max=%g", *min, *max);
  2073. return ((ret_surf > 0 || ret_vol > 0) ? (1) : (-1));
  2074. }
  2075. /*!
  2076. \brief Get viewpoint 'from' position
  2077. \param[out] fr from model coordinates
  2078. */
  2079. void GS_get_from(float *fr)
  2080. {
  2081. GS_v3eq(fr, Gv.from_to[FROM]);
  2082. G_debug(3, "GS_get_from(): %f,%f,%f", fr[0], fr[1], fr[2]);
  2083. return;
  2084. }
  2085. /*!
  2086. \brief Get viewpoint 'from' real coordinates
  2087. \param[out] fr 'from' real coordinates
  2088. */
  2089. void GS_get_from_real(float *fr)
  2090. {
  2091. GS_v3eq(fr, Gv.from_to[FROM]);
  2092. gsd_model2real(fr);
  2093. return;
  2094. }
  2095. /*!
  2096. \brief Get 'to' real coordinates
  2097. \param[out] to 'to' real coordinates
  2098. */
  2099. void GS_get_to_real(float *to)
  2100. {
  2101. float realto[3];
  2102. G_get_set_window(&wind);
  2103. GS_get_focus(realto);
  2104. to[X] = realto[X] + wind.west + (wind.ew_res / 2.);
  2105. to[Y] = realto[Y] + wind.south + (wind.ns_res / 2.);
  2106. to[Z] = realto[Z];
  2107. return;
  2108. }
  2109. /*!
  2110. \brief Get zoom setup
  2111. \param[out] a,b,c,d current viewport settings
  2112. \param[out] maxx,maxy max viewport size
  2113. */
  2114. void GS_zoom_setup(int *a, int *b, int *c, int *d, int *maxx, int *maxy)
  2115. {
  2116. GLint tmp[4];
  2117. GLint num[2];
  2118. gsd_getViewport(tmp, num);
  2119. *a = tmp[0];
  2120. *b = tmp[1];
  2121. *c = tmp[2];
  2122. *d = tmp[3];
  2123. *maxx = num[0];
  2124. *maxy = num[1];
  2125. return;
  2126. }
  2127. /*!
  2128. \brief Get 'to' model coordinates
  2129. \todo need set_to? - just use viewdir?
  2130. \param[out] to 'to' model coordinates
  2131. */
  2132. void GS_get_to(float *to)
  2133. {
  2134. G_debug(3, "GS_get_to");
  2135. GS_v3eq(to, Gv.from_to[TO]);
  2136. return;
  2137. }
  2138. /*!
  2139. \brief Get viewdir
  2140. \param[out] dir viewdir value
  2141. */
  2142. void GS_get_viewdir(float *dir)
  2143. {
  2144. GS_v3dir(Gv.from_to[FROM], Gv.from_to[TO], dir);
  2145. return;
  2146. }
  2147. /*!
  2148. \brief Set viewdir
  2149. Automatically turns off focus
  2150. \param dir viewdir value
  2151. */
  2152. void GS_set_viewdir(float *dir)
  2153. {
  2154. float tmp[3];
  2155. GS_v3eq(tmp, dir);
  2156. GS_v3norm(tmp);
  2157. GS_v3eq(Gv.from_to[TO], Gv.from_to[FROM]);
  2158. GS_v3add(Gv.from_to[TO], tmp);
  2159. GS_set_nofocus();
  2160. gsd_set_view(&Gv, &Gd);
  2161. return;
  2162. }
  2163. /*!
  2164. \brief Set field of view
  2165. \param fov fov value
  2166. */
  2167. void GS_set_fov(int fov)
  2168. {
  2169. Gv.fov = fov;
  2170. return;
  2171. }
  2172. /*!
  2173. \brief Get fied of view
  2174. \return field of view, in 10ths of degrees
  2175. */
  2176. int GS_get_fov(void)
  2177. {
  2178. return (Gv.fov);
  2179. }
  2180. /*!
  2181. \brief Get twist value
  2182. 10ths of degrees off twelve o'clock
  2183. */
  2184. int GS_get_twist(void)
  2185. {
  2186. return (Gv.twist);
  2187. }
  2188. /*!
  2189. \brief Set viewpoint twist value
  2190. 10ths of degrees off twelve o'clock
  2191. \param t tenths of degrees clockwise from 12:00.
  2192. */
  2193. void GS_set_twist(int t)
  2194. {
  2195. Gv.twist = t;
  2196. return;
  2197. }
  2198. /*!
  2199. \brief Set rotation params
  2200. */
  2201. void GS_set_rotation(double angle, double x, double y, double z)
  2202. {
  2203. Gv.rotate.rot_angle = angle;
  2204. Gv.rotate.rot_axes[0] = x;
  2205. Gv.rotate.rot_axes[1] = y;
  2206. Gv.rotate.rot_axes[2] = z;
  2207. Gv.rotate.do_rot = 1;
  2208. return;
  2209. }
  2210. /*!
  2211. \brief Stop scene rotation
  2212. */
  2213. void GS_unset_rotation(void)
  2214. {
  2215. Gv.rotate.do_rot = 0;
  2216. }
  2217. /*!
  2218. \brief Reset scene rotation
  2219. */
  2220. void GS_init_rotation(void)
  2221. {
  2222. int i;
  2223. for (i = 0; i < 16; i++) {
  2224. if (i == 0 || i == 5 || i == 10 || i == 15)
  2225. Gv.rotate.rotMatrix[i] = 1.0;
  2226. else
  2227. Gv.rotate.rotMatrix[i] = 0.0;
  2228. }
  2229. Gv.rotate.rot_angle = 0.0;
  2230. Gv.rotate.rot_axes[0] = 0.0;
  2231. Gv.rotate.rot_axes[1] = 0.0;
  2232. Gv.rotate.rot_axes[2] = 0.0;
  2233. Gv.rotate.do_rot = 0;
  2234. }
  2235. /*!
  2236. * \brief Get rotation matrix
  2237. */
  2238. void GS_get_rotation_matrix(double *matrix)
  2239. {
  2240. int i;
  2241. for (i = 0; i < 16; i++) {
  2242. matrix[i] = Gv.rotate.rotMatrix[i];
  2243. }
  2244. }
  2245. /*!
  2246. * \brief Set rotation matrix
  2247. */
  2248. void GS_set_rotation_matrix(double *matrix)
  2249. {
  2250. int i;
  2251. for (i = 0; i < 16; i++) {
  2252. Gv.rotate.rotMatrix[i] = matrix[i];
  2253. }
  2254. }
  2255. /*!
  2256. \brief Unset focus
  2257. */
  2258. void GS_set_nofocus(void)
  2259. {
  2260. G_debug(3, "GS_set_nofocus");
  2261. Gv.infocus = 0;
  2262. return;
  2263. }
  2264. /*!
  2265. \brief Set focus
  2266. Make sure that the center of view is set
  2267. */
  2268. void GS_set_infocus(void)
  2269. {
  2270. G_debug(3, "GS_set_infocus");
  2271. Gv.infocus = 1;
  2272. return;
  2273. }
  2274. /*!
  2275. \brief Set viewport
  2276. \param left,right,bottom,top viewport extent values
  2277. */
  2278. void GS_set_viewport(int left, int right, int bottom, int top)
  2279. {
  2280. G_debug(3, "GS_set_viewport(): left=%d, right=%d, "
  2281. "bottom=%d, top=%d", left, right, bottom, top);
  2282. gsd_viewport(left, right, bottom, top);
  2283. return;
  2284. }
  2285. /*!
  2286. \brief Send screen coords sx and sy, lib traces through surfaces; sets
  2287. new center to point of nearest intersection.
  2288. If no intersection, uses line of sight with length of current view
  2289. ray (eye to center) to set new center.
  2290. Reset center of view to screen coordinates sx, sy.
  2291. \param sx,sy screen coordinates
  2292. \return 1 on success
  2293. \return 0 on error (invalid surface id)
  2294. */
  2295. int GS_look_here(int sx, int sy)
  2296. {
  2297. float x, y, z, len, los[2][3];
  2298. Point3 realto, dir;
  2299. int id;
  2300. geosurf *gs;
  2301. if (GS_get_selected_point_on_surface(sx, sy, &id, &x, &y, &z)) {
  2302. gs = gs_get_surf(id);
  2303. if (gs) {
  2304. realto[X] = x - gs->ox + gs->x_trans;
  2305. realto[Y] = y - gs->oy + gs->y_trans;
  2306. realto[Z] = z + gs->z_trans;
  2307. GS_set_focus(realto);
  2308. return (1);
  2309. }
  2310. }
  2311. else {
  2312. if (gsd_get_los(los, (short)sx, (short)sy)) {
  2313. len = GS_distance(Gv.from_to[FROM], Gv.real_to);
  2314. GS_v3dir(los[FROM], los[TO], dir);
  2315. GS_v3mult(dir, len);
  2316. realto[X] = Gv.from_to[FROM][X] + dir[X];
  2317. realto[Y] = Gv.from_to[FROM][Y] + dir[Y];
  2318. realto[Z] = Gv.from_to[FROM][Z] + dir[Z];
  2319. GS_set_focus(realto);
  2320. return (1);
  2321. }
  2322. }
  2323. return (0);
  2324. }
  2325. /*!
  2326. \brief Get selected point of surface
  2327. Given screen coordinates sx and sy, find closest intersection of
  2328. view ray with surfaces and return coordinates of intersection in x, y,
  2329. z, and identifier of surface in id.
  2330. \param sx,sy screen coordinates
  2331. \param[out] id surface id
  2332. \param[out] x,y,z point on surface (model coordinates?)
  2333. \returns 0 if no intersections found
  2334. \return number of intersections
  2335. */
  2336. int GS_get_selected_point_on_surface(int sx, int sy, int *id, float *x,
  2337. float *y, float *z)
  2338. {
  2339. float los[2][3], find_dist[MAX_SURFS], closest;
  2340. Point3 point, tmp, finds[MAX_SURFS];
  2341. int surfs[MAX_SURFS], i, iclose, numhits = 0;
  2342. geosurf *gs;
  2343. /* returns surface-world coords */
  2344. gsd_get_los(los, (short)sx, (short)sy);
  2345. if (!gs_setlos_enterdata(los)) {
  2346. G_debug(3, "gs_setlos_enterdata(los): returns false");
  2347. return (0);
  2348. }
  2349. for (i = 0; i < Next_surf; i++) {
  2350. G_debug(3, "id=%d", i);
  2351. gs = gs_get_surf(Surf_ID[i]);
  2352. /* los_intersect expects surf-world coords (xy transl, no scaling) */
  2353. #if NVIZ_HACK
  2354. if (gs_los_intersect1(Surf_ID[i], los, point)) {
  2355. #else
  2356. if (gs_los_intersect(Surf_ID[i], los, point)) {
  2357. #endif
  2358. if (!gs_point_is_masked(gs, point)) {
  2359. GS_v3eq(tmp, point);
  2360. tmp[X] += gs->x_trans;
  2361. tmp[Y] += gs->y_trans;
  2362. tmp[Z] += gs->z_trans;
  2363. find_dist[numhits] = GS_distance(los[FROM], tmp);
  2364. gsd_surf2real(gs, point);
  2365. GS_v3eq(finds[numhits], point);
  2366. surfs[numhits] = Surf_ID[i];
  2367. numhits++;
  2368. }
  2369. }
  2370. }
  2371. for (i = iclose = 0; i < numhits; i++) {
  2372. closest = find_dist[iclose];
  2373. if (find_dist[i] < closest) {
  2374. iclose = i;
  2375. }
  2376. }
  2377. if (numhits) {
  2378. *x = finds[iclose][X];
  2379. *y = finds[iclose][Y];
  2380. *z = finds[iclose][Z];
  2381. *id = surfs[iclose];
  2382. }
  2383. G_debug(3, "NumHits %d, next %d", numhits, Next_surf);
  2384. return (numhits);
  2385. }
  2386. /*!
  2387. \brief Set cplace rotation
  2388. \param num cplace id
  2389. \param dx,dy,dz rotation values
  2390. */
  2391. void GS_set_cplane_rot(int num, float dx, float dy, float dz)
  2392. {
  2393. gsd_cplane_setrot(num, dx, dy, dz);
  2394. return;
  2395. }
  2396. /*!
  2397. \brief Set cplace trans
  2398. \param num cplace id
  2399. \param dx,dy,dz rotation values
  2400. */
  2401. void GS_set_cplane_trans(int num, float dx, float dy, float dz)
  2402. {
  2403. gsd_cplane_settrans(num, dx, dy, dz);
  2404. return;
  2405. }
  2406. /*!
  2407. \brief Draw cplace
  2408. \param num cplace id
  2409. */
  2410. void GS_draw_cplane(int num)
  2411. {
  2412. geosurf *gsurfs[MAX_SURFS];
  2413. int nsurfs;
  2414. nsurfs = gs_num_surfaces();
  2415. if (2 == nsurfs) {
  2416. /* testing */
  2417. gs_getall_surfaces(gsurfs);
  2418. gsd_draw_cplane_fence(gsurfs[0], gsurfs[1], num);
  2419. }
  2420. else {
  2421. gsd_draw_cplane(num);
  2422. }
  2423. return;
  2424. }
  2425. /*!
  2426. \brief Draw cplace fence ?
  2427. \param hs1,hs2
  2428. \param num cplane id
  2429. \return 0 on error
  2430. \return 1 on success
  2431. */
  2432. int GS_draw_cplane_fence(int hs1, int hs2, int num)
  2433. {
  2434. geosurf *gs1, *gs2;
  2435. if (NULL == (gs1 = gs_get_surf(hs1))) {
  2436. return (0);
  2437. }
  2438. if (NULL == (gs2 = gs_get_surf(hs2))) {
  2439. return (0);
  2440. }
  2441. gsd_draw_cplane_fence(gs1, gs2, num);
  2442. return (1);
  2443. }
  2444. /*!
  2445. \brief Draw all cplace fences ?
  2446. */
  2447. void GS_alldraw_cplane_fences(void)
  2448. {
  2449. int onstate[MAX_CPLANES], i;
  2450. gsd_get_cplanes_state(onstate);
  2451. for (i = 0; i < MAX_CPLANES; i++) {
  2452. if (onstate[i]) {
  2453. GS_draw_cplane_fence(Surf_ID[0], Surf_ID[1], i);
  2454. }
  2455. }
  2456. return;
  2457. }
  2458. /*!
  2459. \brief Set cplace
  2460. \param num cplane id
  2461. */
  2462. void GS_set_cplane(int num)
  2463. {
  2464. gsd_cplane_on(num);
  2465. return;
  2466. }
  2467. /*!
  2468. \brief Unset clip place (turn off)
  2469. \param num cplane id
  2470. */
  2471. void GS_unset_cplane(int num)
  2472. {
  2473. gsd_cplane_off(num);
  2474. return;
  2475. }
  2476. /*!
  2477. \brief Get axis scale
  2478. \param sx,sy,sz x/y/z scale values
  2479. \param doexag use vertical exaggeration
  2480. */
  2481. void GS_get_scale(float *sx, float *sy, float *sz, int doexag)
  2482. {
  2483. float zexag;
  2484. zexag = doexag ? Gv.vert_exag : 1.;
  2485. *sx = *sy = Gv.scale;
  2486. *sz = Gv.scale * zexag;
  2487. return;
  2488. }
  2489. /*!
  2490. \brief Set fence color
  2491. \param mode mode id
  2492. */
  2493. void GS_set_fencecolor(int mode)
  2494. {
  2495. gsd_setfc(mode);
  2496. return;
  2497. }
  2498. /*!
  2499. \brief Get fence color
  2500. \return color value
  2501. */
  2502. int GS_get_fencecolor(void)
  2503. {
  2504. return gsd_getfc();
  2505. }
  2506. /*!
  2507. \brief Measure distance "as the ball rolls" between two points on
  2508. surface
  2509. \param hs surface id
  2510. \param x1,y1,x2,y2 two points on surface
  2511. \param[out] dist measured distance
  2512. \param use_exag use exag. surface
  2513. \return 0 on error or if one or more points is not in region
  2514. \return distance following terrain
  2515. */
  2516. int GS_get_distance_alongsurf(int hs, float x1, float y1, float x2, float y2,
  2517. float *dist, int use_exag)
  2518. {
  2519. geosurf *gs;
  2520. float p1[2], p2[2];
  2521. gs = gs_get_surf(hs);
  2522. if (gs == NULL) {
  2523. return 0;
  2524. }
  2525. p1[X] = x1;
  2526. p1[Y] = y1;
  2527. p2[X] = x2;
  2528. p2[Y] = y2;
  2529. gsd_real2surf(gs, p1);
  2530. gsd_real2surf(gs, p2);
  2531. G_debug(3, "GS_get_distance_alongsurf(): hs=%d p1=%f,%f p2=%f,%f",
  2532. hs, x1, y1, x2, y2);
  2533. return gs_distance_onsurf(gs, p1, p2, dist, use_exag);
  2534. }
  2535. /*!
  2536. \brief Save 3d view
  2537. \param vname view file name
  2538. \param surfid surface id
  2539. \return ?
  2540. */
  2541. int GS_save_3dview(const char *vname, int surfid)
  2542. {
  2543. return (Gs_save_3dview(vname, &Gv, &Gd, &wind, gs_get_surf(surfid)));
  2544. }
  2545. /*!
  2546. \brief Load 3d view
  2547. \param vname view file name
  2548. \param surfid surface id
  2549. \return ?
  2550. */
  2551. int GS_load_3dview(const char *vname, int surfid)
  2552. {
  2553. return (Gs_load_3dview(vname, &Gv, &Gd, &wind, gs_get_surf(surfid)));
  2554. /* what to do about lights - I guess, delete all &
  2555. create any that exist in 3dview file */
  2556. }
  2557. /************************************************************************
  2558. * Following routines use Graphics Library
  2559. ************************************************************************/
  2560. /*!
  2561. \brief Init viewpoint
  2562. \todo allow setting center?
  2563. */
  2564. void GS_init_view(void)
  2565. {
  2566. static int first = 1;
  2567. G_debug(3, "GS_init_view");
  2568. if (first) {
  2569. first = 0;
  2570. glMatrixMode(GL_MODELVIEW);
  2571. /* OGLXXX doublebuffer: use GLX_DOUBLEBUFFER in attriblist */
  2572. /* glxChooseVisual(*dpy, screen, *attriblist); */
  2573. /* OGLXXX
  2574. * ZMIN not needed -- always 0.
  2575. * ZMAX not needed -- always 1.
  2576. * getgdesc other posiblilties:
  2577. * glxGetConfig();
  2578. * glxGetCurrentContext();
  2579. * glxGetCurrentDrawable();
  2580. * GLint gdtmp;
  2581. * getgdesc other posiblilties:
  2582. * glxGetConfig();
  2583. * glxGetCurrentContext();
  2584. * glxGetCurrentDrawable();
  2585. * GLint gdtmp;
  2586. * glDepthRange params must be scaled to [0, 1]
  2587. */
  2588. glDepthRange(0.0, 1.0);
  2589. glEnable(GL_DEPTH_TEST);
  2590. glDepthFunc(GL_LEQUAL);
  2591. /* } */
  2592. /* replace these with something meaningful */
  2593. Gv.fov = 450;
  2594. Gv.twist = 0;
  2595. GS_init_rotation();
  2596. Gv.from_to[FROM][X] = Gv.from_to[FROM][Y] =
  2597. Gv.from_to[FROM][Z] = GS_UNIT_SIZE / 2.;
  2598. Gv.from_to[TO][X] = GS_UNIT_SIZE / 2.;
  2599. Gv.from_to[TO][Y] = GS_UNIT_SIZE / 2.;
  2600. Gv.from_to[TO][Z] = 0.;
  2601. Gv.from_to[TO][W] = Gv.from_to[FROM][W] = 1.;
  2602. Gv.real_to[W] = 1.;
  2603. Gv.vert_exag = 1.;
  2604. GS_v3eq(Gv.real_to, Gv.from_to[TO]);
  2605. GS_v3normalize(Gv.from_to[FROM], Gv.from_to[TO]);
  2606. /*
  2607. Gd.nearclip = 50;
  2608. Gd.farclip = 10000.;
  2609. */
  2610. Gd.nearclip = 10.;
  2611. Gd.farclip = 10000.;
  2612. Gd.aspect = (float)GS_get_aspect();
  2613. GS_set_focus(Gv.real_to);
  2614. }
  2615. return;
  2616. }
  2617. /*!
  2618. \brief Clear view
  2619. \param col color value
  2620. */
  2621. void GS_clear(int col)
  2622. {
  2623. G_debug(3, "GS_clear");
  2624. col = col | 0xFF000000;
  2625. /* OGLXXX
  2626. * change glClearDepth parameter to be in [0, 1]
  2627. * ZMAX not needed -- always 1.
  2628. * getgdesc other posiblilties:
  2629. * glxGetConfig();
  2630. * glxGetCurrentContext();
  2631. * glxGetCurrentDrawable();
  2632. * GLint gdtmp;
  2633. */
  2634. glClearDepth(1.0);
  2635. glClearColor(((float)((col) & 0xff)) / 255.,
  2636. (float)((col) >> 8 & 0xff) / 255.,
  2637. (float)((col) >> 16 & 0xff) / 255.,
  2638. (float)((col) >> 24 & 0xff) / 255.);
  2639. glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
  2640. Gd.bgcol = col;
  2641. Modelshowing = 0;
  2642. gsd_flush();
  2643. return;
  2644. }
  2645. /*!
  2646. \brief Get aspect value
  2647. \return aspect value
  2648. */
  2649. double GS_get_aspect(void)
  2650. {
  2651. int left, right, bottom, top;
  2652. GLint tmp[4];
  2653. /* OGLXXX
  2654. * get GL_VIEWPORT:
  2655. * You can probably do better than this.
  2656. */
  2657. glGetIntegerv(GL_VIEWPORT, tmp);
  2658. left = tmp[0];
  2659. right = tmp[0] + tmp[2] - 1;
  2660. bottom = tmp[1];
  2661. top = tmp[1] + tmp[3] - 1;
  2662. G_debug(3, "GS_get_aspect(): left=%d, right=%d, top=%d, bottom=%d",
  2663. left, right, top, bottom);
  2664. return ((double)(right - left) / (top - bottom));
  2665. }
  2666. /*!
  2667. \brief Check for transparency
  2668. Disabled.
  2669. \return 1
  2670. */
  2671. int GS_has_transparency(void)
  2672. {
  2673. /* OGLXXX
  2674. * getgdesc other posiblilties:
  2675. * glxGetConfig();
  2676. * glxGetCurrentContext();
  2677. * glxGetCurrentDrawable();
  2678. * GLint gdtmp;
  2679. * blending is ALWAYS supported.
  2680. * This function returns whether it is enabled.
  2681. * return((glGetIntegerv(GL_BLEND, &gdtmp), gdtmp));
  2682. */
  2683. return (1);
  2684. }