dclib-vector.c 65 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583
  1. /***************************************************************************
  2. * *
  3. * _____ ____ *
  4. * | __ \ / __ \ _ _ _____ *
  5. * | | \ \ / / \_\ | | | | _ \ *
  6. * | | \ \| | | | | | |_| | *
  7. * | | | || | | | | | ___/ *
  8. * | | / /| | __ | | | | _ \ *
  9. * | |__/ / \ \__/ / | |___| | |_| | *
  10. * |_____/ \____/ |_____|_|_____/ *
  11. * *
  12. * Wiimms source code library *
  13. * *
  14. ***************************************************************************
  15. * *
  16. * Copyright (c) 2012-2022 by Dirk Clemens <wiimm@wiimm.de> *
  17. * *
  18. ***************************************************************************
  19. * *
  20. * This library is free software; you can redistribute it and/or modify *
  21. * it under the terms of the GNU General Public License as published by *
  22. * the Free Software Foundation; either version 2 of the License, or *
  23. * (at your option) any later version. *
  24. * *
  25. * This library is distributed in the hope that it will be useful, *
  26. * but WITHOUT ANY WARRANTY; without even the implied warranty of *
  27. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
  28. * GNU General Public License for more details. *
  29. * *
  30. * See file gpl-2.0.txt or http://www.gnu.org/licenses/gpl-2.0.txt *
  31. * *
  32. ***************************************************************************/
  33. #define _GNU_SOURCE 1
  34. #include <string.h>
  35. #include "dclib-basics.h"
  36. #include "dclib-numeric.h"
  37. #include "dclib-debug.h"
  38. //
  39. ///////////////////////////////////////////////////////////////////////////////
  40. /////////////// float3 list support ///////////////
  41. ///////////////////////////////////////////////////////////////////////////////
  42. void InitializeF3L
  43. (
  44. float3List_t *f3l, // valid data
  45. uint bin_search // >0: enable binary search
  46. // and allocate 'bin_search' elements
  47. )
  48. {
  49. DASSERT(f3l);
  50. memset(f3l,0,sizeof(*f3l));
  51. if (bin_search)
  52. {
  53. f3l->size = bin_search;
  54. f3l->list = MALLOC( f3l->size * sizeof(*f3l->list) );
  55. f3l->sort = MALLOC( f3l->size * sizeof(*f3l->sort) );
  56. }
  57. }
  58. ///////////////////////////////////////////////////////////////////////////////
  59. void ResetF3L ( float3List_t * f3l )
  60. {
  61. DASSERT(f3l);
  62. FREE(f3l->list);
  63. FREE(f3l->sort);
  64. memset(f3l,0,sizeof(*f3l));
  65. }
  66. ///////////////////////////////////////////////////////////////////////////////
  67. float3 * AppendF3L ( float3List_t * f3l )
  68. {
  69. DASSERT( f3l );
  70. DASSERT( f3l->used <= f3l->size );
  71. DASSERT( !f3l->list == !f3l->size );
  72. if ( f3l->used == f3l->size )
  73. {
  74. f3l->size = 3*f3l->size/2 + 100;
  75. f3l->list = REALLOC( f3l->list, f3l->size * sizeof(*f3l->list) );
  76. if (f3l->sort)
  77. f3l->sort = REALLOC( f3l->sort, f3l->size * sizeof(*f3l->sort) );
  78. }
  79. DASSERT( f3l->list );
  80. DASSERT( f3l->used < f3l->size );
  81. if (f3l->sort)
  82. f3l->sort[f3l->used] = 0;
  83. float3 * item = f3l->list + f3l->used++;
  84. item->x = item->y = item->z = 0.0;
  85. return item;
  86. }
  87. ///////////////////////////////////////////////////////////////////////////////
  88. uint FindInsertFloatF3L ( float3List_t * f3l, float3 *val, bool fast )
  89. {
  90. DASSERT( f3l );
  91. DASSERT( f3l->used <= f3l->size );
  92. DASSERT( !f3l->list == !f3l->size );
  93. DASSERT( val );
  94. int beg = 0;
  95. if (!fast)
  96. {
  97. if (f3l->sort)
  98. {
  99. int end = f3l->used - 1;
  100. while ( beg <= end )
  101. {
  102. uint idx = (beg+end)/2;
  103. DASSERT( idx >= 0 && idx < f3l->used );
  104. DASSERT_MSG( f3l->sort[idx] < f3l->used,
  105. "idx=%d, sort-idx=%d, used=%u, size=%u\n",
  106. idx, f3l->sort[idx], f3l->used, f3l->size );
  107. int stat = memcmp( val,f3l->list + f3l->sort[idx], sizeof(*val) );
  108. if ( stat < 0 )
  109. end = idx - 1 ;
  110. else if ( stat > 0 )
  111. beg = idx + 1;
  112. else
  113. return f3l->sort[idx];
  114. }
  115. }
  116. else
  117. {
  118. float3 *ptr = f3l->list;
  119. float3 *end = ptr + f3l->used;
  120. for ( ; ptr < end; ptr++ )
  121. if (!memcmp(val,ptr,sizeof(*val)))
  122. return ptr - f3l->list;
  123. }
  124. }
  125. else if (f3l->sort)
  126. {
  127. // 'sort' not needed
  128. BINGO; // don't remove this line!
  129. FREE(f3l->sort);
  130. f3l->sort = 0;
  131. }
  132. float3 *res = AppendF3L(f3l);
  133. DASSERT(res);
  134. memcpy(res,val,sizeof(*res));
  135. const uint idx = f3l->used - 1;
  136. DASSERT( idx < f3l->used );
  137. if (f3l->sort)
  138. {
  139. DASSERT( beg >= 0 && beg <= idx );
  140. uint *dest = f3l->sort + beg;
  141. memmove( dest+1, dest, (idx-beg)*sizeof(*f3l->sort) );
  142. *dest = idx;
  143. #if HAVE_PRINT0
  144. if ( f3l->used < 10 )
  145. {
  146. uint i;
  147. for ( i = 0; i < f3l->used; i++ )
  148. {
  149. float3 *f = f3l->list + f3l->sort[i];
  150. PRINT("INS %2u: %2u -> %08x %08x %08x %11.5f %11.5f %11.5f\n",
  151. i, f3l->sort[i],
  152. be32(&f->x), be32(&f->y), be32(&f->z),
  153. f->x, f->y, f->z );
  154. }
  155. PRINT("---\n");
  156. }
  157. #endif
  158. }
  159. return idx;
  160. }
  161. ///////////////////////////////////////////////////////////////////////////////
  162. float3 * GrowF3L ( float3List_t * f3l, uint n )
  163. {
  164. DASSERT( f3l );
  165. DASSERT( f3l->used <= f3l->size );
  166. DASSERT( !f3l->list == !f3l->size );
  167. const uint new_used = f3l->used + n;
  168. if ( new_used > f3l->size || !f3l->size )
  169. {
  170. f3l->size = new_used ? new_used : 10;
  171. f3l->list = REALLOC( f3l->list, f3l->size * sizeof(*f3l->list)) ;
  172. }
  173. DASSERT( f3l->list );
  174. DASSERT( f3l->used + n <= f3l->size );
  175. float3 * result = f3l->list + f3l->used;
  176. f3l->used = new_used;
  177. return result;
  178. }
  179. //
  180. ///////////////////////////////////////////////////////////////////////////////
  181. /////////////// double3 list support ///////////////
  182. ///////////////////////////////////////////////////////////////////////////////
  183. void InitializeD3L ( double3List_t * d3l )
  184. {
  185. DASSERT(d3l);
  186. memset(d3l,0,sizeof(*d3l));
  187. }
  188. ///////////////////////////////////////////////////////////////////////////////
  189. void ResetD3L ( double3List_t * d3l )
  190. {
  191. DASSERT(d3l);
  192. FREE(d3l->list);
  193. memset(d3l,0,sizeof(*d3l));
  194. }
  195. ///////////////////////////////////////////////////////////////////////////////
  196. double3 * AppendD3L ( double3List_t * d3l )
  197. {
  198. DASSERT( d3l );
  199. DASSERT( d3l->used <= d3l->size );
  200. DASSERT( !d3l->list == !d3l->size );
  201. if ( d3l->used == d3l->size )
  202. {
  203. d3l->size = 3*d3l->size/2 + 100;
  204. d3l->list = REALLOC( d3l->list, d3l->size * sizeof(*d3l->list)) ;
  205. }
  206. DASSERT( d3l->list );
  207. DASSERT( d3l->used < d3l->size );
  208. double3 * item = d3l->list + d3l->used++;
  209. item->x = item->y = item->z = 0.0;
  210. return item;
  211. }
  212. ///////////////////////////////////////////////////////////////////////////////
  213. uint FindInsertFloatD3L ( double3List_t * d3l, double3 *val, bool fast )
  214. {
  215. DASSERT( d3l );
  216. DASSERT( d3l->used <= d3l->size );
  217. DASSERT( !d3l->list == !d3l->size );
  218. DASSERT( val );
  219. // first: reduce precision
  220. double3 temp;
  221. temp.x = double2float(val->x);
  222. temp.y = double2float(val->y);
  223. temp.z = double2float(val->z);
  224. if (!fast)
  225. {
  226. double3 *ptr = d3l->list;
  227. double3 *end = ptr + d3l->used;
  228. for ( ; ptr < end; ptr++ )
  229. if (!memcmp(&temp,ptr,sizeof(temp)))
  230. return ptr - d3l->list;
  231. }
  232. double3 *res = AppendD3L(d3l);
  233. DASSERT(res);
  234. memcpy(res,&temp,sizeof(*res));
  235. return d3l->used - 1;
  236. }
  237. ///////////////////////////////////////////////////////////////////////////////
  238. double3 * GrowD3L ( double3List_t * d3l, uint n )
  239. {
  240. DASSERT( d3l );
  241. DASSERT( d3l->used <= d3l->size );
  242. DASSERT( !d3l->list == !d3l->size );
  243. const uint new_used = d3l->used + n;
  244. if ( new_used > d3l->size || !d3l->size )
  245. {
  246. d3l->size = new_used ? new_used : 10;
  247. d3l->list = REALLOC( d3l->list, d3l->size * sizeof(*d3l->list)) ;
  248. }
  249. DASSERT( d3l->list );
  250. DASSERT( d3l->used + n <= d3l->size );
  251. double3 * result = d3l->list + d3l->used;
  252. d3l->used = new_used;
  253. return result;
  254. }
  255. //
  256. ///////////////////////////////////////////////////////////////////////////////
  257. /////////////// check numbers ///////////////
  258. ///////////////////////////////////////////////////////////////////////////////
  259. bool IsNormalF3 ( float *f3 )
  260. {
  261. DASSERT(f3);
  262. const int fpclass = fpclassify(*f3++);
  263. if ( fpclass == FP_NORMAL || fpclass == FP_ZERO )
  264. {
  265. const int fpclass = fpclassify(*f3++);
  266. if ( fpclass == FP_NORMAL || fpclass == FP_ZERO )
  267. {
  268. const int fpclass = fpclassify(*f3);
  269. return fpclass == FP_NORMAL || fpclass == FP_ZERO;
  270. }
  271. }
  272. return false;
  273. }
  274. ///////////////////////////////////////////////////////////////////////////////
  275. bool IsNormalF3be ( float *f3 )
  276. {
  277. DASSERT(f3);
  278. const int fpclass = fpclassify(bef4(f3));
  279. if ( fpclass == FP_NORMAL || fpclass == FP_ZERO )
  280. {
  281. const int fpclass = fpclassify(bef4(++f3));
  282. if ( fpclass == FP_NORMAL || fpclass == FP_ZERO )
  283. {
  284. const int fpclass = fpclassify(bef4(++f3));
  285. return fpclass == FP_NORMAL || fpclass == FP_ZERO;
  286. }
  287. }
  288. return false;
  289. }
  290. ///////////////////////////////////////////////////////////////////////////////
  291. bool IsNormalD3 ( double *d3 )
  292. {
  293. DASSERT(d3);
  294. const int fpclass = fpclassify(*d3++);
  295. if ( fpclass == FP_NORMAL || fpclass == FP_ZERO )
  296. {
  297. const int fpclass = fpclassify(*d3++);
  298. if ( fpclass == FP_NORMAL || fpclass == FP_ZERO )
  299. {
  300. const int fpclass = fpclassify(*d3);
  301. return fpclass == FP_NORMAL || fpclass == FP_ZERO;
  302. }
  303. }
  304. return false;
  305. }
  306. ///////////////////////////////////////////////////////////////////////////////
  307. bool IsEqualD3 ( const double3 *a, const double3 *b,
  308. double null_epsilon, double diff_epsilon )
  309. {
  310. DASSERT(a);
  311. DASSERT(b);
  312. DASSERT( null_epsilon > 0.0 );
  313. DASSERT( diff_epsilon > 0.0 );
  314. double diff;
  315. diff = fabs( a->x - b->x );
  316. if ( diff > null_epsilon )
  317. {
  318. const double abs_a = fabs(a->x);
  319. const double abs_b = fabs(b->x);
  320. if ( diff > ( abs_a > abs_b ? abs_a : abs_b ) * diff_epsilon )
  321. return false;
  322. }
  323. diff = fabs( a->y - b->y );
  324. if ( diff > null_epsilon )
  325. {
  326. const double abs_a = fabs(a->y);
  327. const double abs_b = fabs(b->y);
  328. if ( diff > ( abs_a > abs_b ? abs_a : abs_b ) * diff_epsilon )
  329. return false;
  330. }
  331. diff = fabs( a->z - b->z );
  332. if ( diff > null_epsilon )
  333. {
  334. const double abs_a = fabs(a->z);
  335. const double abs_b = fabs(b->z);
  336. if ( diff > ( abs_a > abs_b ? abs_a : abs_b ) * diff_epsilon )
  337. return false;
  338. }
  339. return true;
  340. }
  341. ///////////////////////////////////////////////////////////////////////////////
  342. bool IsSameF ( float a, float b, int bit_diff )
  343. {
  344. float delta = ldexpf( fabsf(a-b), 23-bit_diff );
  345. return IsNormalF(delta) && delta <= fabsf(a) && delta <= fabsf(b);
  346. }
  347. bool IsSameD ( double a, double b, int bit_diff )
  348. {
  349. double delta = ldexp( fabs(a-b), 52-bit_diff );
  350. return IsNormalD(delta) && delta <= fabs(a) && delta <= fabs(b);
  351. }
  352. bool IsSameF3 ( const float *a, const float *b, int bit_diff )
  353. {
  354. return IsSameF(a[0],b[0],bit_diff)
  355. && IsSameF(a[1],b[1],bit_diff)
  356. && IsSameF(a[2],b[2],bit_diff);
  357. }
  358. bool IsSameD3 ( const double *a, const double *b, int bit_diff )
  359. {
  360. return IsSameD(a[0],b[0],bit_diff)
  361. && IsSameD(a[1],b[1],bit_diff)
  362. && IsSameD(a[2],b[2],bit_diff);
  363. }
  364. //
  365. ///////////////////////////////////////////////////////////////////////////////
  366. /////////////// 2D vector functions ///////////////
  367. ///////////////////////////////////////////////////////////////////////////////
  368. uint PointsInConvexPolygonF
  369. (
  370. // return, how many points are inside the polygon
  371. float *pts, // points: pointer to a array with '2*n_pts' elements
  372. uint n_pts, // Number of (x,y) pairs in 'pts'
  373. float *pol, // polygon: pointer to a array with '2*n_pol' elements
  374. uint n_pol, // number of (x,y) pairs in 'pol'
  375. bool all, // false: count the numbers of points inside
  376. // true: return '1' for all points inside and otherwise '0'
  377. int *r_dir // If not NULL then return:
  378. // -1: polygon is defined counterclockwise
  379. // 0: unknown
  380. // +1: polygon is defined clockwise
  381. // If at least one point is inside, the result is known.
  382. )
  383. {
  384. if ( !n_pts || n_pol < 3 )
  385. return 0;
  386. DASSERT(pts);
  387. DASSERT(pol);
  388. int pol_dir = 0;
  389. uint count = 0;
  390. for(;;)
  391. {
  392. float *a = pol + 2*(n_pol-1);
  393. float *b = pol;
  394. int dir = pol_dir;
  395. uint i = n_pol;
  396. for(;;)
  397. {
  398. const double dstat = SideOfLine(a[0],a[1],b[0],b[1],pts[0],pts[1]);
  399. const int new_dir = dstat > 0.0 ? -1 : dstat < 0;
  400. noPRINT("STAT: %2d %2d %2d %4g\n", pol_dir, dir, new_dir, dstat );
  401. if (!dir)
  402. dir = new_dir;
  403. else if ( new_dir && dir != new_dir )
  404. {
  405. if (!all)
  406. break;
  407. if (r_dir)
  408. *r_dir = pol_dir;
  409. return 0;
  410. }
  411. if ( --i > 0 )
  412. {
  413. a = b;
  414. b += 2;
  415. continue;
  416. }
  417. if (!pol_dir)
  418. pol_dir = dir;
  419. count++;
  420. break;
  421. }
  422. if ( --n_pts > 0 )
  423. {
  424. pts += 2;
  425. continue;
  426. }
  427. if (r_dir)
  428. *r_dir = pol_dir;
  429. noPRINT("DIR: %2d\n",pol_dir);
  430. return all ? 1 : count;
  431. }
  432. }
  433. ///////////////////////////////////////////////////////////////////////////////
  434. uint PointsInConvexPolygonD
  435. (
  436. // return, how many points are inside the polygon
  437. double *pts, // points: pointer to a array with '2*n_pts' elements
  438. uint n_pts, // Number of (x,y) pairs in 'pts'
  439. double *pol, // polygon: pointer to a array with '2*n_pol' elements
  440. uint n_pol, // number of (x,y) pairs in 'pol'
  441. bool all, // false: count the numbers of points inside
  442. // true: return '1' for all points inside and otherwise '0'
  443. int *r_dir // If not NULL then return:
  444. // -1: polygon is defined counterclockwise
  445. // 0: unknown
  446. // +1: polygon is defined clockwise
  447. // If at least one point is inside, the result is known.
  448. )
  449. {
  450. if ( !n_pts || n_pol < 3 )
  451. return 0;
  452. DASSERT(pts);
  453. DASSERT(pol);
  454. int pol_dir = 0;
  455. uint count = 0;
  456. for(;;)
  457. {
  458. double *a = pol + 2*(n_pol-1);
  459. double *b = pol;
  460. int dir = pol_dir;
  461. uint i = n_pol;
  462. for(;;)
  463. {
  464. const double dstat = SideOfLine(a[0],a[1],b[0],b[1],pts[0],pts[1]);
  465. const int new_dir = dstat > 0.0 ? -1 : dstat < 0;
  466. noPRINT("STAT: %2d %2d %2d %4g\n", pol_dir, dir, new_dir, dstat );
  467. if (!dir)
  468. dir = new_dir;
  469. else if ( new_dir && dir != new_dir )
  470. {
  471. if (!all)
  472. break;
  473. if (r_dir)
  474. *r_dir = pol_dir;
  475. return 0;
  476. }
  477. if ( --i > 0 )
  478. {
  479. a = b;
  480. b += 2;
  481. continue;
  482. }
  483. if (!pol_dir)
  484. pol_dir = dir;
  485. count++;
  486. break;
  487. }
  488. if ( --n_pts > 0 )
  489. {
  490. pts += 2;
  491. continue;
  492. }
  493. if (r_dir)
  494. *r_dir = pol_dir;
  495. noPRINT("DIR: %2d\n",pol_dir);
  496. return all ? 1 : count;
  497. }
  498. }
  499. //
  500. ///////////////////////////////////////////////////////////////////////////////
  501. /////////////// float34 ///////////////
  502. ///////////////////////////////////////////////////////////////////////////////
  503. void ClearFloat34 ( float34 *f34 )
  504. {
  505. DASSERT(f34);
  506. float *d = f34->v;
  507. uint n;
  508. for ( n = 0; n < 12; n++ )
  509. *d++ = 0.0;
  510. }
  511. ///////////////////////////////////////////////////////////////////////////////
  512. void SetupFloat34 ( float34 *f34 )
  513. {
  514. DASSERT(f34);
  515. float *d = f34->v;
  516. uint n;
  517. for ( n = 0; n < 12; n++ )
  518. *d++ = 0.0;
  519. f34->m[0][0] = f34->m[1][1] = f34->m[2][2] = 1.0;
  520. }
  521. ///////////////////////////////////////////////////////////////////////////////
  522. void SetupMatrixF34
  523. (
  524. float34 *mat, // data to setup
  525. float3 *scale, // NULL or scaling vector
  526. float3 *rotate, // NULL or rotation vector in *radiant*
  527. float3 *translate // NULL or translation vector
  528. )
  529. {
  530. // This function use 'scale', 'rotate' and 'translate' to calculate the
  531. // transformation matrix. The calculations have been verified against
  532. // original MDL files of Nintendo. The rotation is done in right-handed
  533. // rotation with Euler angles (in degree) and x-y-z convention:
  534. // => http://en.wikipedia.org/wiki/Matrix_rotation#General_rotations
  535. DASSERT(mat);
  536. float *t = mat->v;
  537. //--- setup scale
  538. float3 myscale;
  539. if (scale)
  540. {
  541. myscale.x = fabs(scale->x) < NULL_EPSILON ? 1.0 : scale->x;
  542. myscale.y = fabs(scale->y) < NULL_EPSILON ? 1.0 : scale->y;
  543. myscale.z = fabs(scale->z) < NULL_EPSILON ? 1.0 : scale->z;
  544. }
  545. else
  546. myscale.x = myscale.y = myscale.z = 1.0;
  547. //--- calc translation matrix by scale and rotation
  548. if (rotate)
  549. {
  550. // be sure, that null values are exact
  551. const double sin_x = fabs(rotate->x) < NULL_EPSILON ? 0.0 : sin( rotate->x );
  552. const double cos_x = fabs(rotate->x) < NULL_EPSILON ? 1.0 : cos( rotate->x );
  553. const double sin_y = fabs(rotate->y) < NULL_EPSILON ? 0.0 : sin( rotate->y );
  554. const double cos_y = fabs(rotate->y) < NULL_EPSILON ? 1.0 : cos( rotate->y );
  555. const double sin_z = fabs(rotate->z) < NULL_EPSILON ? 0.0 : sin( rotate->z );
  556. const double cos_z = fabs(rotate->z) < NULL_EPSILON ? 1.0 : cos( rotate->z );
  557. t[ 0] = myscale.x * ( cos_y * cos_z );
  558. t[ 1] = myscale.y * ( - cos_x * sin_z + sin_x * sin_y * cos_z );
  559. t[ 2] = myscale.z * ( sin_x * sin_z + cos_x * sin_y * cos_z );
  560. t[4+0] = myscale.x * ( cos_y * sin_z );
  561. t[4+1] = myscale.y * ( cos_x * cos_z + sin_x * sin_y * sin_z );
  562. t[4+2] = myscale.z * ( - sin_x * cos_z + cos_x * sin_y * sin_z );
  563. t[8+0] = myscale.x * ( - sin_y );
  564. t[8+1] = myscale.y * ( sin_x * cos_y );
  565. t[8+2] = myscale.z * ( cos_x * cos_y );
  566. }
  567. else
  568. {
  569. t[ 0] = myscale.x;
  570. t[4+1] = myscale.y;
  571. t[8+2] = myscale.z;
  572. t[ 1] = 0.0;
  573. t[ 2] = 0.0;
  574. t[4+0] = 0.0;
  575. t[4+2] = 0.0;
  576. t[8+0] = 0.0;
  577. t[8+1] = 0.0;
  578. }
  579. //--- assign translation
  580. if (translate)
  581. {
  582. t[ 3] = translate->x;
  583. t[4+3] = translate->y;
  584. t[8+3] = translate->z;
  585. }
  586. else
  587. {
  588. t[ 3] = 0.0;
  589. t[4+3] = 0.0;
  590. t[8+3] = 0.0;
  591. }
  592. }
  593. ///////////////////////////////////////////////////////////////////////////////
  594. void CalcInverseMatrixF34
  595. (
  596. float34 *i, // store inverse matrix here
  597. const float34 *t // transformation matrix
  598. )
  599. {
  600. DASSERT(i);
  601. DASSERT(t);
  602. //--- calc inverse matrix
  603. const double det = t->v[ 0] * t->v[4+1] * t->v[8+2]
  604. + t->v[ 1] * t->v[4+2] * t->v[8+0]
  605. + t->v[ 2] * t->v[4+0] * t->v[8+1]
  606. - t->v[ 2] * t->v[4+1] * t->v[8+0]
  607. - t->v[ 1] * t->v[4+0] * t->v[8+2]
  608. - t->v[ 0] * t->v[4+2] * t->v[8+1];
  609. if ( fabs(det) < NULL_EPSILON )
  610. {
  611. // this should never happen => initialize inv_matrix with 0.0
  612. ClearFloat34(i);
  613. }
  614. else
  615. {
  616. const double det1 = 1.0 / det; // multplication is faster than division
  617. i->v[ 0] = ( t->v[4+1] * t->v[8+2] - t->v[4+2] * t->v[8+1] ) * det1;
  618. i->v[ 1] = ( t->v[ 2] * t->v[8+1] - t->v[ 1] * t->v[8+2] ) * det1;
  619. i->v[ 2] = ( t->v[ 1] * t->v[4+2] - t->v[ 2] * t->v[4+1] ) * det1;
  620. i->v[4+0] = ( t->v[4+2] * t->v[8+0] - t->v[4+0] * t->v[8+2] ) * det1;
  621. i->v[4+1] = ( t->v[ 0] * t->v[8+2] - t->v[ 2] * t->v[8+0] ) * det1;
  622. i->v[4+2] = ( t->v[ 2] * t->v[4+0] - t->v[ 0] * t->v[4+2] ) * det1;
  623. i->v[8+0] = ( t->v[4+0] * t->v[8+1] - t->v[4+1] * t->v[8+0] ) * det1;
  624. i->v[8+1] = ( t->v[ 1] * t->v[8+0] - t->v[ 0] * t->v[8+1] ) * det1;
  625. i->v[8+2] = ( t->v[ 0] * t->v[4+1] - t->v[ 1] * t->v[4+0] ) * det1;
  626. }
  627. //--- calc inverse translation
  628. i->v[ 3] = - t->v[ 3] * i->v[ 0]
  629. - t->v[4+3] * i->v[ 1]
  630. - t->v[8+3] * i->v[ 2];
  631. i->v[4+3] = - t->v[ 3] * i->v[4+0]
  632. - t->v[4+3] * i->v[4+1]
  633. - t->v[8+3] * i->v[4+2];
  634. i->v[8+3] = - t->v[ 3] * i->v[8+0]
  635. - t->v[4+3] * i->v[8+1]
  636. - t->v[8+3] * i->v[8+2];
  637. }
  638. ///////////////////////////////////////////////////////////////////////////////
  639. void MultiplyF34
  640. (
  641. float34 *dest, // valid, store result here, may be 'src1' or 'src2'
  642. const float34 *src1, // first valid source, if NULL use dest
  643. const float34 *src2 // second valid source, if NULL use dest
  644. )
  645. {
  646. DASSERT(dest);
  647. if ( dest == src1 || dest == src2 || !src1 || !src2 )
  648. {
  649. float34 temp;
  650. MultiplyF34( &temp, src1 ? src1 : dest, src2 ? src2 : dest );
  651. *dest = temp;
  652. return;
  653. }
  654. DASSERT( src1 && src1 != dest );
  655. DASSERT( src2 && src2 != dest );
  656. float *res = dest->v;
  657. const float *a = src1->v;
  658. const float *b = src2->v;
  659. res[0+0] = a[0+0]*b[0+0] + a[4+0]*b[0+1] + a[8+0]*b[0+2];
  660. res[0+1] = a[0+1]*b[0+0] + a[4+1]*b[0+1] + a[8+1]*b[0+2];
  661. res[0+2] = a[0+2]*b[0+0] + a[4+2]*b[0+1] + a[8+2]*b[0+2];
  662. res[0+3] = a[0+3]*b[0+0] + a[4+3]*b[0+1] + a[8+3]*b[0+2] + b[0+3];
  663. res[4+0] = a[0+0]*b[4+0] + a[4+0]*b[4+1] + a[8+0]*b[4+2];
  664. res[4+1] = a[0+1]*b[4+0] + a[4+1]*b[4+1] + a[8+1]*b[4+2];
  665. res[4+2] = a[0+2]*b[4+0] + a[4+2]*b[4+1] + a[8+2]*b[4+2];
  666. res[4+3] = a[0+3]*b[4+0] + a[4+3]*b[4+1] + a[8+3]*b[4+2] + b[4+3];
  667. res[8+0] = a[0+0]*b[8+0] + a[4+0]*b[8+1] + a[8+0]*b[8+2];
  668. res[8+1] = a[0+1]*b[8+0] + a[4+1]*b[8+1] + a[8+1]*b[8+2];
  669. res[8+2] = a[0+2]*b[8+0] + a[4+2]*b[8+1] + a[8+2]*b[8+2];
  670. res[8+3] = a[0+3]*b[8+0] + a[4+3]*b[8+1] + a[8+3]*b[8+2] + b[8+3];
  671. }
  672. //
  673. ///////////////////////////////////////////////////////////////////////////////
  674. /////////////// double34 ///////////////
  675. ///////////////////////////////////////////////////////////////////////////////
  676. void ClearDouble34 ( double34 *d34 )
  677. {
  678. DASSERT(d34);
  679. double *d = d34->v;
  680. uint n;
  681. for ( n = 0; n < 12; n++ )
  682. *d++ = 0.0;
  683. }
  684. ///////////////////////////////////////////////////////////////////////////////
  685. void SetupDouble34 ( double34 *d34 )
  686. {
  687. DASSERT(d34);
  688. double *d = d34->v;
  689. uint n;
  690. for ( n = 0; n < 12; n++ )
  691. *d++ = 0.0;
  692. d34->m[0][0] = d34->m[1][1] = d34->m[2][2] = 1.0;
  693. }
  694. ///////////////////////////////////////////////////////////////////////////////
  695. void SetupMatrixD34
  696. (
  697. double34 *mat, // data to setup
  698. double3 *scale, // NULL or scaling vector
  699. double3 *rotate, // NULL or rotation vector in *radiant*
  700. double3 *translate // NULL or translation vector
  701. )
  702. {
  703. // This function use 'scale', 'rotate' and 'translate' to calculate the
  704. // transformation matrix. The calculations have been verified against
  705. // original MDL files of Nintendo. The rotation is done in right-handed
  706. // rotation with Euler angles (in degree) and x-y-z convention:
  707. // => http://en.wikipedia.org/wiki/Matrix_rotation#General_rotations
  708. DASSERT(mat);
  709. double *t = mat->v;
  710. //--- setup scale
  711. double3 myscale;
  712. if (scale)
  713. {
  714. myscale.x = fabs(scale->x) < NULL_EPSILON ? 1.0 : scale->x;
  715. myscale.y = fabs(scale->y) < NULL_EPSILON ? 1.0 : scale->y;
  716. myscale.z = fabs(scale->z) < NULL_EPSILON ? 1.0 : scale->z;
  717. }
  718. else
  719. myscale.x = myscale.y = myscale.z = 1.0;
  720. //--- calc translation matrix by scale and rotation
  721. if (rotate)
  722. {
  723. // be sure, that null values are exact
  724. const double sin_x = fabs(rotate->x) < NULL_EPSILON ? 0.0 : sin( rotate->x );
  725. const double cos_x = fabs(rotate->x) < NULL_EPSILON ? 1.0 : cos( rotate->x );
  726. const double sin_y = fabs(rotate->y) < NULL_EPSILON ? 0.0 : sin( rotate->y );
  727. const double cos_y = fabs(rotate->y) < NULL_EPSILON ? 1.0 : cos( rotate->y );
  728. const double sin_z = fabs(rotate->z) < NULL_EPSILON ? 0.0 : sin( rotate->z );
  729. const double cos_z = fabs(rotate->z) < NULL_EPSILON ? 1.0 : cos( rotate->z );
  730. t[ 0] = myscale.x * ( cos_y * cos_z );
  731. t[ 1] = myscale.y * ( - cos_x * sin_z + sin_x * sin_y * cos_z );
  732. t[ 2] = myscale.z * ( sin_x * sin_z + cos_x * sin_y * cos_z );
  733. t[4+0] = myscale.x * ( cos_y * sin_z );
  734. t[4+1] = myscale.y * ( cos_x * cos_z + sin_x * sin_y * sin_z );
  735. t[4+2] = myscale.z * ( - sin_x * cos_z + cos_x * sin_y * sin_z );
  736. t[8+0] = myscale.x * ( - sin_y );
  737. t[8+1] = myscale.y * ( sin_x * cos_y );
  738. t[8+2] = myscale.z * ( cos_x * cos_y );
  739. }
  740. else
  741. {
  742. t[ 0] = myscale.x;
  743. t[4+1] = myscale.y;
  744. t[8+2] = myscale.z;
  745. t[ 1] = 0.0;
  746. t[ 2] = 0.0;
  747. t[4+0] = 0.0;
  748. t[4+2] = 0.0;
  749. t[8+0] = 0.0;
  750. t[8+1] = 0.0;
  751. }
  752. //--- assign translation
  753. if (translate)
  754. {
  755. t[ 3] = translate->x;
  756. t[4+3] = translate->y;
  757. t[8+3] = translate->z;
  758. }
  759. else
  760. {
  761. t[ 3] = 0.0;
  762. t[4+3] = 0.0;
  763. t[8+3] = 0.0;
  764. }
  765. }
  766. ///////////////////////////////////////////////////////////////////////////////
  767. void CalcInverseMatrixD34
  768. (
  769. double34 *i, // store inverse matrix here
  770. const double34 *t // transformation matrix
  771. )
  772. {
  773. DASSERT(i);
  774. DASSERT(t);
  775. //--- calc inverse matrix
  776. const double det = t->v[ 0] * t->v[4+1] * t->v[8+2]
  777. + t->v[ 1] * t->v[4+2] * t->v[8+0]
  778. + t->v[ 2] * t->v[4+0] * t->v[8+1]
  779. - t->v[ 2] * t->v[4+1] * t->v[8+0]
  780. - t->v[ 1] * t->v[4+0] * t->v[8+2]
  781. - t->v[ 0] * t->v[4+2] * t->v[8+1];
  782. if ( fabs(det) < NULL_EPSILON )
  783. {
  784. // this should never happen => initialize inv_matrix with 0.0
  785. ClearDouble34(i);
  786. }
  787. else
  788. {
  789. const double det1 = 1.0 / det; // multplication is faster than division
  790. i->v[ 0] = ( t->v[4+1] * t->v[8+2] - t->v[4+2] * t->v[8+1] ) * det1;
  791. i->v[ 1] = ( t->v[ 2] * t->v[8+1] - t->v[ 1] * t->v[8+2] ) * det1;
  792. i->v[ 2] = ( t->v[ 1] * t->v[4+2] - t->v[ 2] * t->v[4+1] ) * det1;
  793. i->v[4+0] = ( t->v[4+2] * t->v[8+0] - t->v[4+0] * t->v[8+2] ) * det1;
  794. i->v[4+1] = ( t->v[ 0] * t->v[8+2] - t->v[ 2] * t->v[8+0] ) * det1;
  795. i->v[4+2] = ( t->v[ 2] * t->v[4+0] - t->v[ 0] * t->v[4+2] ) * det1;
  796. i->v[8+0] = ( t->v[4+0] * t->v[8+1] - t->v[4+1] * t->v[8+0] ) * det1;
  797. i->v[8+1] = ( t->v[ 1] * t->v[8+0] - t->v[ 0] * t->v[8+1] ) * det1;
  798. i->v[8+2] = ( t->v[ 0] * t->v[4+1] - t->v[ 1] * t->v[4+0] ) * det1;
  799. }
  800. //--- calc inverse translation
  801. i->v[ 3] = - t->v[ 3] * i->v[ 0]
  802. - t->v[4+3] * i->v[ 1]
  803. - t->v[8+3] * i->v[ 2];
  804. i->v[4+3] = - t->v[ 3] * i->v[4+0]
  805. - t->v[4+3] * i->v[4+1]
  806. - t->v[8+3] * i->v[4+2];
  807. i->v[8+3] = - t->v[ 3] * i->v[8+0]
  808. - t->v[4+3] * i->v[8+1]
  809. - t->v[8+3] * i->v[8+2];
  810. }
  811. ///////////////////////////////////////////////////////////////////////////////
  812. void MultiplyD34
  813. (
  814. double34 *dest, // valid, store result here, may be 'src1' or 'src2'
  815. const double34 *src1, // first valid source, if NULL use dest
  816. const double34 *src2 // second valid source, if NULL use dest
  817. )
  818. {
  819. DASSERT(dest);
  820. if ( dest == src1 || dest == src2 || !src1 || !src2 )
  821. {
  822. double34 temp;
  823. MultiplyD34( &temp, src1 ? src1 : dest, src2 ? src2 : dest );
  824. *dest = temp;
  825. return;
  826. }
  827. DASSERT( src1 && src1 != dest );
  828. DASSERT( src2 && src2 != dest );
  829. double *res = dest->v;
  830. const double *a = src1->v;
  831. const double *b = src2->v;
  832. res[0+0] = a[0+0]*b[0+0] + a[4+0]*b[0+1] + a[8+0]*b[0+2];
  833. res[0+1] = a[0+1]*b[0+0] + a[4+1]*b[0+1] + a[8+1]*b[0+2];
  834. res[0+2] = a[0+2]*b[0+0] + a[4+2]*b[0+1] + a[8+2]*b[0+2];
  835. res[0+3] = a[0+3]*b[0+0] + a[4+3]*b[0+1] + a[8+3]*b[0+2] + b[0+3];
  836. res[4+0] = a[0+0]*b[4+0] + a[4+0]*b[4+1] + a[8+0]*b[4+2];
  837. res[4+1] = a[0+1]*b[4+0] + a[4+1]*b[4+1] + a[8+1]*b[4+2];
  838. res[4+2] = a[0+2]*b[4+0] + a[4+2]*b[4+1] + a[8+2]*b[4+2];
  839. res[4+3] = a[0+3]*b[4+0] + a[4+3]*b[4+1] + a[8+3]*b[4+2] + b[4+3];
  840. res[8+0] = a[0+0]*b[8+0] + a[4+0]*b[8+1] + a[8+0]*b[8+2];
  841. res[8+1] = a[0+1]*b[8+0] + a[4+1]*b[8+1] + a[8+1]*b[8+2];
  842. res[8+2] = a[0+2]*b[8+0] + a[4+2]*b[8+1] + a[8+2]*b[8+2];
  843. res[8+3] = a[0+3]*b[8+0] + a[4+3]*b[8+1] + a[8+3]*b[8+2] + b[8+3];
  844. }
  845. ///////////////////////////////////////////////////////////////////////////////
  846. ///////////////////////////////////////////////////////////////////////////////
  847. void CopyF34toD34
  848. (
  849. double34 *dest, // destination matrix
  850. const float34 *src // source matrix
  851. )
  852. {
  853. DASSERT(dest);
  854. DASSERT(src);
  855. double *d = dest->v;
  856. const float *s = src->v;
  857. uint n;
  858. for ( n = 0; n < 12; n++ )
  859. *d++ = *s++;
  860. }
  861. ///////////////////////////////////////////////////////////////////////////////
  862. void CopyD34toF34
  863. (
  864. float34 *dest, // destination matrix
  865. const double34 *src // source matrix
  866. )
  867. {
  868. DASSERT(dest);
  869. DASSERT(src);
  870. float *d = dest->v;
  871. const double *s = src->v;
  872. uint n;
  873. for ( n = 0; n < 12; n++ )
  874. *d++ = *s++;
  875. }
  876. //
  877. ///////////////////////////////////////////////////////////////////////////////
  878. /////////////// MatrixD_t: setup ///////////////
  879. ///////////////////////////////////////////////////////////////////////////////
  880. // statistics
  881. u64 N_MatrixD_forward = 0; // total number of forward transformations
  882. u64 N_MatrixD_inverse = 0; // total number of inverse transformations
  883. ///////////////////////////////////////////////////////////////////////////////
  884. void InitializeMatrixD ( MatrixD_t * mat )
  885. {
  886. DASSERT(mat);
  887. // const uint seqnum = mat->valid ? mat->sequence_number : 0;
  888. memset(mat,0,sizeof(*mat));
  889. // mat->sequence_number = seqnum;
  890. mat->scale.x = mat->scale.y = mat->scale.z = 1.0;
  891. mat->scale_origin.x = mat->scale_origin.y = mat->scale_origin.z = 0.0;
  892. mat->shift = mat->scale_origin;
  893. mat->rotate_deg = mat->scale_origin;
  894. mat->rotate_rad = mat->scale_origin;
  895. mat->translate = mat->scale_origin;
  896. double *d = (double*)mat->rotate_origin;
  897. uint n;
  898. for ( n = 0; n < 9; n++ )
  899. *d++ = 0.0;
  900. mat->valid = true;
  901. }
  902. ///////////////////////////////////////////////////////////////////////////////
  903. void CopyMatrixD
  904. (
  905. MatrixD_t *dest, // valid destination
  906. const
  907. MatrixD_t *src // NULL or source
  908. )
  909. {
  910. DASSERT(dest);
  911. if ( src && src->valid )
  912. {
  913. const uint seqnum = dest->sequence_number;
  914. *dest = *src;
  915. dest->sequence_number = seqnum+1;
  916. }
  917. else
  918. InitializeMatrixD(dest);
  919. }
  920. ///////////////////////////////////////////////////////////////////////////////
  921. ///////////////////////////////////////////////////////////////////////////////
  922. MatrixD_t * SetScaleMatrixD
  923. (
  924. MatrixD_t * mat, // valid data structure
  925. double3 * scale, // NULL: clear scale, not NULL: set scale
  926. double3 * origin // not NULL: Origin for scaling
  927. )
  928. {
  929. DASSERT(mat);
  930. if (!mat->valid)
  931. InitializeMatrixD(mat);
  932. mat->norm_valid = mat->tmatrix_valid = mat->imatrix_valid = false;
  933. if (scale)
  934. mat->scale = *scale;
  935. else
  936. {
  937. mat->scale.x = mat->scale.y = mat->scale.z = 1.0;
  938. origin = 0;
  939. }
  940. if (origin)
  941. mat->scale_origin = *origin;
  942. else
  943. mat->scale_origin.x = mat->scale_origin.y = mat->scale_origin.z = 0.0;
  944. return mat;
  945. }
  946. ///////////////////////////////////////////////////////////////////////////////
  947. MatrixD_t * SetShiftMatrixD
  948. (
  949. MatrixD_t * mat, // valid data structure
  950. double3 * shift // NULL: clear Shift, not NULL: set Shift
  951. )
  952. {
  953. DASSERT(mat);
  954. if (!mat->valid)
  955. InitializeMatrixD(mat);
  956. mat->norm_valid = mat->tmatrix_valid = mat->imatrix_valid = false;
  957. if (shift)
  958. mat->shift = *shift;
  959. else
  960. mat->shift.x = mat->shift.y = mat->shift.z = 0.0;
  961. return mat;
  962. }
  963. ///////////////////////////////////////////////////////////////////////////////
  964. MatrixD_t * SetScaleShiftMatrixD
  965. (
  966. MatrixD_t * mat, // valid data structure
  967. uint xyz, // 0..2: x/y/z coordinate to set
  968. double old1, // old value of first point
  969. double new1, // new value of first point
  970. double old2, // old value of second point
  971. double new2 // new value of second point
  972. )
  973. {
  974. DASSERT(mat);
  975. if (!mat->valid)
  976. InitializeMatrixD(mat);
  977. if ( fabs(old1-old2) >= NULL_EPSILON ) // ignore othwerwise
  978. {
  979. mat->norm_valid = mat->tmatrix_valid = mat->imatrix_valid = false;
  980. const double scale = ( new2 - new1 ) / ( old2 - old1 );
  981. mat->scale.v[xyz] = scale;
  982. mat->scale_origin.v[xyz] = 0.0;
  983. // new = old * scale + shift
  984. mat->shift.v[xyz] = new1 - old1 * scale;
  985. }
  986. return mat;
  987. }
  988. ///////////////////////////////////////////////////////////////////////////////
  989. MatrixD_t * SetRotateMatrixD
  990. (
  991. MatrixD_t * mat, // valid data structure
  992. uint xyz, // 0..2: x/y/z coordinate to set
  993. double degree, // angle in degree
  994. double radiant, // angle in radiant
  995. double3 * origin // not NULL: Origin for the rotation
  996. )
  997. {
  998. DASSERT(mat);
  999. DASSERT(xyz<3);
  1000. if (!mat->valid)
  1001. InitializeMatrixD(mat);
  1002. mat->norm_valid = mat->tmatrix_valid = mat->imatrix_valid = false;
  1003. mat->rotate_deg.v[xyz] = degree;
  1004. mat->rotate_rad.v[xyz] = radiant;
  1005. if (origin)
  1006. mat->rotate_origin[xyz] = *origin;
  1007. else
  1008. {
  1009. origin = mat->rotate_origin + xyz;
  1010. origin->x = origin->y = origin->z = 0.0;
  1011. }
  1012. return mat;
  1013. }
  1014. ///////////////////////////////////////////////////////////////////////////////
  1015. MatrixD_t * SetTranslateMatrixD
  1016. (
  1017. MatrixD_t * mat, // valid data structure
  1018. double3 * translate // NULL: clear translate, not NULL: set translate
  1019. )
  1020. {
  1021. DASSERT(mat);
  1022. if (!mat->valid)
  1023. InitializeMatrixD(mat);
  1024. mat->norm_valid = mat->tmatrix_valid = mat->imatrix_valid = false;
  1025. if (translate)
  1026. mat->translate = *translate;
  1027. else
  1028. mat->translate.x = mat->translate.y = mat->translate.z = 0.0;
  1029. return mat;
  1030. }
  1031. ///////////////////////////////////////////////////////////////////////////////
  1032. ///////////////////////////////////////////////////////////////////////////////
  1033. MatrixD_t * CheckStatusMatrixD
  1034. (
  1035. MatrixD_t * mat // valid data structure
  1036. )
  1037. {
  1038. DASSERT(mat);
  1039. if (mat->tmatrix_valid)
  1040. {
  1041. double *t = mat->trans_matrix.v;
  1042. //--- check rotation (only disabled for all axis)
  1043. if ( mat->rotate_enabled & 1
  1044. && fabs( t[4+2] ) < NULL_EPSILON
  1045. && fabs( t[8+1] ) < NULL_EPSILON
  1046. )
  1047. {
  1048. mat->rotate_enabled &= ~1;
  1049. t[4+2] = 0.0;
  1050. t[8+1] = 0.0;
  1051. }
  1052. if ( mat->rotate_enabled & 2
  1053. && fabs( t[ 2] ) < NULL_EPSILON
  1054. && fabs( t[8+0] ) < NULL_EPSILON
  1055. )
  1056. {
  1057. mat->rotate_enabled &= ~2;
  1058. t[ 2] = 0.0;
  1059. t[8+0] = 0.0;
  1060. }
  1061. if ( mat->rotate_enabled & 4
  1062. && fabs( t[ 1] ) < NULL_EPSILON
  1063. && fabs( t[4+0] ) < NULL_EPSILON
  1064. )
  1065. {
  1066. mat->rotate_enabled &= ~4;
  1067. t[ 1] = 0.0;
  1068. t[4+0] = 0.0;
  1069. }
  1070. //--- check scaling (don't touch scale if roating is enabled)
  1071. if ( mat->scale_enabled & 1
  1072. && !( mat->rotate_enabled & ~1 )
  1073. && fabs( t[ 0] - 1.0 ) < NULL_EPSILON )
  1074. {
  1075. t[ 0] = 1.0;
  1076. mat->scale_enabled &= ~1;
  1077. }
  1078. if ( mat->scale_enabled & 2
  1079. && !( mat->rotate_enabled & ~2 )
  1080. && fabs( t[4+1] - 1.0 ) < NULL_EPSILON )
  1081. {
  1082. t[4+1] = 1.0;
  1083. mat->scale_enabled &= ~2;
  1084. }
  1085. if ( mat->scale_enabled & 4
  1086. && !( mat->rotate_enabled & ~4 )
  1087. && fabs( t[8+2] - 1.0 ) < NULL_EPSILON )
  1088. {
  1089. t[8+2] = 1.0;
  1090. mat->scale_enabled &= ~4;
  1091. }
  1092. //--- check transformation
  1093. if ( mat->translate_enabled & 1 && fabs( t[ 3] ) < NULL_EPSILON )
  1094. {
  1095. t[ 3] = 0.0;
  1096. mat->translate_enabled &= ~1;
  1097. }
  1098. if ( mat->translate_enabled & 2 && fabs( t[4+3] ) < NULL_EPSILON )
  1099. {
  1100. t[4+3] = 0.0;
  1101. mat->translate_enabled &= ~2;
  1102. }
  1103. if ( mat->translate_enabled & 4 && fabs( t[8+3] ) < NULL_EPSILON )
  1104. {
  1105. t[8+3] = 0.0;
  1106. mat->translate_enabled &= ~4;
  1107. }
  1108. mat->transform_enabled = mat->scale_enabled
  1109. | mat->rotate_enabled
  1110. | mat->translate_enabled
  1111. | mat->use_matrix << 3;
  1112. }
  1113. return mat;
  1114. }
  1115. //
  1116. ///////////////////////////////////////////////////////////////////////////////
  1117. /////////////// MatrixD_t: specials ///////////////
  1118. ///////////////////////////////////////////////////////////////////////////////
  1119. void TermAssignMatrixD
  1120. (
  1121. // called after dirext matrix manipulations
  1122. MatrixD_t * mat // valid data structure
  1123. )
  1124. {
  1125. DASSERT(mat);
  1126. mat->valid = true;
  1127. mat->norm_valid = false;
  1128. mat->tmatrix_valid = true;
  1129. mat->imatrix_valid = false;
  1130. mat->use_matrix = 2;
  1131. mat->scale_enabled = 7;
  1132. mat->rotate_enabled = 7;
  1133. mat->translate_enabled = 7;
  1134. mat->sequence_number++;
  1135. double34 *m = &mat->trans_matrix;
  1136. mat->norm_scale.x = m->x[0];
  1137. mat->norm_scale.y = m->y[1];
  1138. mat->norm_scale.z = m->z[2];
  1139. mat->norm_translate.x = m->x[3];
  1140. mat->norm_translate.y = m->y[3];
  1141. mat->norm_translate.z = m->z[3];
  1142. CheckStatusMatrixD(mat);
  1143. if (!mat->rotate_enabled)
  1144. {
  1145. mat->use_matrix = 0;
  1146. mat->norm_valid = true;
  1147. mat->norm_rotate_deg.x = 0;
  1148. mat->norm_rotate_deg.y = 0;
  1149. mat->norm_rotate_deg.z = 0;
  1150. mat->norm_rotate_rad = mat->norm_rotate_deg;
  1151. mat->scale = mat->norm_scale;
  1152. mat->translate = mat->norm_translate;
  1153. }
  1154. }
  1155. ///////////////////////////////////////////////////////////////////////////////
  1156. MatrixD_t * SetMatrixD
  1157. (
  1158. MatrixD_t * mat, // valid data structure
  1159. const
  1160. double34 * src // NULL or matrix to set
  1161. )
  1162. {
  1163. DASSERT(mat);
  1164. InitializeMatrixD(mat);
  1165. if (src)
  1166. {
  1167. mat->trans_matrix = *src;
  1168. TermAssignMatrixD(mat);
  1169. }
  1170. return mat;
  1171. }
  1172. ///////////////////////////////////////////////////////////////////////////////
  1173. MatrixD_t * SetAScaleMatrixD
  1174. (
  1175. // calculate the matrix as rotation around a specified axis
  1176. MatrixD_t * mat, // valid data structure
  1177. double scale, // scale factor
  1178. double3 * dir // NULL or scaling direction as vector
  1179. )
  1180. {
  1181. DASSERT(mat);
  1182. InitializeMatrixD(mat);
  1183. if (dir)
  1184. {
  1185. const double hrot = atan2(dir->x,dir->z);
  1186. const double hlen = sqrt( dir->x*dir->x + dir->z*dir->z );
  1187. const double vrot = -atan2(dir->y,hlen);
  1188. PRINT("HROT: %6.4f %7.2f / %11.3f\n",hrot,hrot*180.0/M_PI,hlen);
  1189. PRINT("VROT: %6.4f %7.2f\n",vrot,vrot*180.0/M_PI);
  1190. MatrixD_t mrot;
  1191. InitializeMatrixD(&mrot);
  1192. mrot.rotate_rad.x = vrot;
  1193. mrot.rotate_rad.y = hrot;
  1194. CalcMatrixD(&mrot,true);
  1195. DASSERT(mrot.imatrix_valid);
  1196. SetMatrixD(mat,&mrot.inv_matrix);
  1197. double3 scale3;
  1198. scale3.x = scale3.y = 0;
  1199. scale3.z = scale;
  1200. SetScaleMatrixD(&mrot,&scale3,0);
  1201. MultiplyMatrixD(mat,0,&mrot,0);
  1202. TermAssignMatrixD(mat);
  1203. }
  1204. //--- terminate
  1205. return mat;
  1206. }
  1207. ///////////////////////////////////////////////////////////////////////////////
  1208. MatrixD_t * SetARotateMatrixD
  1209. (
  1210. // calculate the matrix as rotation around a specified axis
  1211. MatrixD_t * mat, // valid data structure
  1212. double degree, // angle in degree
  1213. double radiant, // angle in radiant, add to degree with factor
  1214. double3 * pt1, // point #1 to define the axis; if NULL use (0,0,0)
  1215. double3 * pt2 // point #2 to define the axis; if NULL use (0,0,0)
  1216. )
  1217. {
  1218. DASSERT(mat);
  1219. InitializeMatrixD(mat);
  1220. double3 dir, base;
  1221. if (pt1)
  1222. base = *pt1;
  1223. else
  1224. base.x = base.y = base.z = 0.0;
  1225. if (pt2)
  1226. Sub3(dir,*pt2,base);
  1227. else
  1228. {
  1229. dir.x = -base.x;
  1230. dir.y = -base.y;
  1231. dir.z = -base.z;
  1232. }
  1233. #if 1
  1234. radiant += degree * (M_PI/180.0);
  1235. const double len = Length3(dir);
  1236. if ( len >= NULL_EPSILON )
  1237. #else
  1238. radiant = fmod( degree * (M_PI/180.0) + radiant + M_PI, 2*M_PI) - M_PI;
  1239. const double len = Length3(dir);
  1240. if ( len >= NULL_EPSILON && fabs(radiant) >= NULL_EPSILON )
  1241. #endif
  1242. {
  1243. dir.x /= len;
  1244. dir.y /= len;
  1245. dir.z /= len;
  1246. const double sin0 = sin(radiant);
  1247. const double cos0 = cos(radiant);
  1248. const double cos1 = 1.0 - cos0;
  1249. double *t = mat->trans_matrix.v;
  1250. t[ 0] = dir.x * dir.x * cos1 + cos0;
  1251. t[ 1] = dir.x * dir.y * cos1 - dir.z * sin0;
  1252. t[ 2] = dir.x * dir.z * cos1 + dir.y * sin0;
  1253. t[4+0] = dir.y * dir.x * cos1 + dir.z * sin0;
  1254. t[4+1] = dir.y * dir.y * cos1 + cos0;
  1255. t[4+2] = dir.y * dir.z * cos1 - dir.x * sin0;
  1256. t[8+0] = dir.z * dir.x * cos1 - dir.y * sin0;
  1257. t[8+1] = dir.z * dir.y * cos1 + dir.x * sin0;
  1258. t[8+2] = dir.z * dir.z * cos1 + cos0;
  1259. double3 delta = TransformD3D34(&mat->trans_matrix,&base);
  1260. t[ 3] = base.x - delta.x;
  1261. t[4+3] = base.y - delta.y;
  1262. t[8+3] = base.z - delta.z;
  1263. TermAssignMatrixD(mat);
  1264. }
  1265. //--- terminate
  1266. return mat;
  1267. }
  1268. //
  1269. ///////////////////////////////////////////////////////////////////////////////
  1270. /////////////// MatrixD_t: calc ///////////////
  1271. ///////////////////////////////////////////////////////////////////////////////
  1272. MatrixD_t * CalcNormMatrixD
  1273. (
  1274. MatrixD_t * mat // valid data structure
  1275. )
  1276. {
  1277. DASSERT(mat);
  1278. if (!mat->valid)
  1279. InitializeMatrixD(mat);
  1280. if ( mat->norm_valid || mat->tmatrix_valid )
  1281. return mat;
  1282. mat->sequence_number++;
  1283. mat->norm_valid = true;
  1284. mat->scale_enabled = mat->rotate_enabled = mat->translate_enabled = 0;
  1285. //--- scale & shift
  1286. double3 trans;
  1287. uint xyz;
  1288. for ( xyz = 0; xyz < 3; xyz++ )
  1289. {
  1290. double scale = mat->scale.v[xyz];
  1291. if ( fabs(scale) < NULL_EPSILON || fabs(scale-1.0) < NULL_EPSILON )
  1292. mat->scale.v[xyz] = scale = 1.0;
  1293. else
  1294. mat->scale_enabled |= 1 << xyz;
  1295. mat->norm_scale.v[xyz] = scale;
  1296. trans.v[xyz] = mat->shift.v[xyz]
  1297. + ( 1.0 - scale ) * mat->scale_origin.v[xyz];
  1298. }
  1299. //--- rotate
  1300. mat->norm_pos2d.x = mat->norm_pos2d.y = mat->norm_pos2d.z = 0;
  1301. for ( xyz = 0; xyz < 3; xyz++ )
  1302. {
  1303. double deg = fmod( mat->rotate_deg.v[xyz]
  1304. + mat->rotate_rad.v[xyz] * (180.0/M_PI)
  1305. + 180.0, 360.0 ) - 180.0;
  1306. if ( fabs(deg) < MIN_DEGREE )
  1307. {
  1308. mat->norm_rotate_deg.v[xyz] = 0.0;
  1309. mat->norm_rotate_rad.v[xyz] = 0.0;
  1310. }
  1311. else
  1312. {
  1313. mat->rotate_enabled |= 1 << xyz;
  1314. mat->norm_rotate_deg.v[xyz] = deg;
  1315. double rad = deg * (M_PI/180.0);
  1316. mat->norm_rotate_rad.v[xyz] = rad;
  1317. // translate = rot_origin + rotated(translate-rot_origin)
  1318. Sub3(trans,trans,mat->rotate_origin[xyz]);
  1319. const uint a = (xyz+2) % 3;
  1320. const uint b = (xyz+1) % 3;
  1321. rad += atan2(trans.v[a],trans.v[b]);
  1322. const double len = sqrt(trans.v[a]*trans.v[a]+trans.v[b]*trans.v[b]);
  1323. trans.v[a] = sin(rad) * len;
  1324. trans.v[b] = cos(rad) * len;
  1325. Add3(trans,trans,mat->rotate_origin[xyz]);
  1326. mat->norm_pos2d.v[a] += mat->rotate_origin[xyz].v[a];
  1327. mat->norm_pos2d.v[b] += mat->rotate_origin[xyz].v[b];
  1328. }
  1329. }
  1330. if ( (mat->rotate_enabled|1) == 7 ) mat->norm_pos2d.x /= 2;
  1331. if ( (mat->rotate_enabled|2) == 7 ) mat->norm_pos2d.y /= 2;
  1332. if ( (mat->rotate_enabled|4) == 7 ) mat->norm_pos2d.z /= 2;
  1333. //--- translate
  1334. mat->translate_enabled = false;
  1335. for ( xyz = 0; xyz < 3; xyz++ )
  1336. {
  1337. const double temp = trans.v[xyz] + mat->translate.v[xyz];
  1338. if ( fabs(temp) < NULL_EPSILON )
  1339. mat->norm_translate.v[xyz] = 0.0;
  1340. else
  1341. {
  1342. mat->norm_translate.v[xyz] = temp;
  1343. mat->translate_enabled |= 1 << xyz;
  1344. }
  1345. }
  1346. //--- status
  1347. if ( mat->use_matrix < 2 )
  1348. {
  1349. mat->use_matrix = mat->rotate_enabled ? 1 : 0;
  1350. mat->tmatrix_valid = mat->imatrix_valid = false;
  1351. }
  1352. mat->transform_enabled = mat->scale_enabled
  1353. | mat->rotate_enabled
  1354. | mat->translate_enabled
  1355. | mat->use_matrix << 3;
  1356. TRACE("%%%%%%%%%% CalcNormMatrixD(%p) => %u|%u|%u = %02x %%%%%%%%%%\n",
  1357. mat, mat->scale_enabled, mat->rotate_enabled,
  1358. mat->translate_enabled, mat->transform_enabled );
  1359. return mat;
  1360. }
  1361. ///////////////////////////////////////////////////////////////////////////////
  1362. MatrixD_t * CalcTransMatrixD
  1363. (
  1364. MatrixD_t * mat, // valid data structure
  1365. bool always // false: calc transformation matrix only
  1366. // if needed for transformation
  1367. // true: calc matrix always
  1368. // if 'tmatrix_valid', the matrix is never calculated
  1369. )
  1370. {
  1371. DASSERT(mat);
  1372. CalcNormMatrixD(mat);
  1373. if ( mat->tmatrix_valid || !always && !mat->use_matrix )
  1374. return mat;
  1375. TRACE("%%%%%%%%%% CalcTransMatrixD(%p,%d) => %u|%u|%u = %02x %%%%%%%%%%\n",
  1376. mat, always, mat->scale_enabled, mat->rotate_enabled,
  1377. mat->translate_enabled, mat->transform_enabled );
  1378. DASSERT(mat->use_matrix<2);
  1379. SetupMatrixD34( &mat->trans_matrix,
  1380. &mat->norm_scale,
  1381. &mat->norm_rotate_rad,
  1382. &mat->norm_translate );
  1383. mat->tmatrix_valid = true;
  1384. mat->imatrix_valid = false;
  1385. CheckStatusMatrixD(mat);
  1386. return mat;
  1387. }
  1388. ///////////////////////////////////////////////////////////////////////////////
  1389. MatrixD_t * CalcMatrixD
  1390. (
  1391. MatrixD_t * mat, // valid data structure
  1392. bool always // false: calc both matrices only
  1393. // if needed for transformation
  1394. // true: calc matrices always
  1395. )
  1396. {
  1397. DASSERT(mat);
  1398. if ( mat->imatrix_valid || !always && !mat->use_matrix )
  1399. return mat;
  1400. CalcTransMatrixD(mat,true);
  1401. TRACE("%%%%%%%%%% CalcMatrixD (%p,%d) => %u|%u|%u = %02x %%%%%%%%%%\n",
  1402. mat, always, mat->scale_enabled, mat->rotate_enabled,
  1403. mat->translate_enabled, mat->transform_enabled );
  1404. CalcInverseMatrixD34(&mat->inv_matrix,&mat->trans_matrix);
  1405. mat->imatrix_valid = true;
  1406. return mat;
  1407. }
  1408. ///////////////////////////////////////////////////////////////////////////////
  1409. MatrixD_t * MultiplyMatrixD
  1410. (
  1411. MatrixD_t *dest, // valid, store result here, may be 'src1' or 'src2'
  1412. MatrixD_t *src1, // first valid source, if NULL use dest
  1413. MatrixD_t *src2, // second valid source, if NULL use dest
  1414. uint inverse_mode // bit field:
  1415. // 1: use inverse matrix of src1
  1416. // 2: use inverse matrix of src2
  1417. )
  1418. {
  1419. DASSERT(dest);
  1420. if ( dest == src1 || dest == src2 || !src1 || !src2 )
  1421. {
  1422. MatrixD_t temp;
  1423. MultiplyMatrixD( &temp, src1 ? src1 : dest, src2 ? src2 : dest, inverse_mode );
  1424. *dest = temp;
  1425. return dest;
  1426. }
  1427. DASSERT( src1 && src1 != dest );
  1428. DASSERT( src2 && src2 != dest );
  1429. CalcMatrixD(src1,true);
  1430. CalcMatrixD(src2,true);
  1431. InitializeMatrixD(dest);
  1432. MultiplyD34( &dest->trans_matrix,
  1433. inverse_mode & 1 ? &src1->inv_matrix : &src1->trans_matrix,
  1434. inverse_mode & 2 ? &src2->inv_matrix : &src2->trans_matrix );
  1435. //--- setup normals, simply assumption
  1436. dest->norm_scale.x = dest->trans_matrix.m[0][0];
  1437. dest->norm_scale.y = dest->trans_matrix.m[1][1];
  1438. dest->norm_scale.z = dest->trans_matrix.m[2][2];
  1439. dest->norm_rotate_deg.x = src1->norm_rotate_deg.x + src2->norm_rotate_deg.x;
  1440. dest->norm_rotate_deg.y = src1->norm_rotate_deg.y + src2->norm_rotate_deg.y;
  1441. dest->norm_rotate_deg.z = src1->norm_rotate_deg.z + src2->norm_rotate_deg.z;
  1442. Mult3f(dest->norm_rotate_rad,dest->norm_rotate_deg,M_PI/180.0);
  1443. dest->norm_translate.x = dest->trans_matrix.m[0][3];
  1444. dest->norm_translate.y = dest->trans_matrix.m[1][3];
  1445. dest->norm_translate.z = dest->trans_matrix.m[2][3];
  1446. //--- setup base values
  1447. dest->scale = dest->norm_scale;
  1448. dest->rotate_deg = dest->norm_rotate_deg;
  1449. dest->translate = dest->norm_translate;
  1450. //--- terminate
  1451. TermAssignMatrixD(dest);
  1452. return dest;
  1453. }
  1454. ///////////////////////////////////////////////////////////////////////////////
  1455. MatrixD_t * CalcVectorsMatrixD
  1456. (
  1457. MatrixD_t * mat, // valid data structure
  1458. bool always // false: calc vectors only if matrix is valid
  1459. // true: calc matrix if invalid & vectors always
  1460. )
  1461. {
  1462. DASSERT(mat);
  1463. // search: Decomposing a rotation matrix
  1464. if ( !always && !mat->tmatrix_valid )
  1465. return mat;
  1466. CalcMatrixD(mat,false);
  1467. // [[2do]] ??? calculate scale
  1468. //mat->norm_scale.x = 1.0;
  1469. //mat->norm_scale.y = 1.0;
  1470. //mat->norm_scale.z = 1.0;
  1471. double (*m)[4] = mat->trans_matrix.m;
  1472. // [[2do]] ??? works only for scale == 1 ==>
  1473. mat->norm_rotate_rad.x = atan2( m[2][1], m[2][2] );
  1474. mat->norm_rotate_rad.y = atan2( -m[2][0], sqrt( m[2][1]*m[2][1] + m[2][2]*m[2][2] ) );
  1475. mat->norm_rotate_rad.z = atan2( m[1][0], m[0][0] );
  1476. mat->norm_rotate_deg.x = rad2deg(mat->norm_rotate_rad.x);
  1477. mat->norm_rotate_deg.y = rad2deg(mat->norm_rotate_rad.y);
  1478. mat->norm_rotate_deg.z = rad2deg(mat->norm_rotate_rad.z);
  1479. mat->norm_translate.x = m[0][3];
  1480. mat->norm_translate.y = m[1][3];
  1481. mat->norm_translate.z = m[2][3];
  1482. return mat;
  1483. }
  1484. //
  1485. ///////////////////////////////////////////////////////////////////////////////
  1486. /////////////// MatrixD_t: double transform ///////////////
  1487. ///////////////////////////////////////////////////////////////////////////////
  1488. double3 TransformD3MatrixD
  1489. (
  1490. MatrixD_t * mat, // valid data structure
  1491. const
  1492. double3 * val // value to transform
  1493. )
  1494. {
  1495. DASSERT(mat);
  1496. DASSERT(val);
  1497. N_MatrixD_forward++;
  1498. if ( !mat->norm_valid && !mat->tmatrix_valid )
  1499. CalcNormMatrixD(mat);
  1500. if (mat->use_matrix)
  1501. {
  1502. if (!mat->tmatrix_valid)
  1503. CalcTransMatrixD(mat,true);
  1504. return TransformD3D34(&mat->trans_matrix,val);
  1505. }
  1506. double3 res;
  1507. res.x = val->x * mat->norm_scale.x + mat->norm_translate.x;
  1508. res.y = val->y * mat->norm_scale.y + mat->norm_translate.y;
  1509. res.z = val->z * mat->norm_scale.z + mat->norm_translate.z;
  1510. return res;
  1511. }
  1512. ///////////////////////////////////////////////////////////////////////////////
  1513. double3 InvTransformD3MatrixD
  1514. (
  1515. MatrixD_t * mat, // valid data structure
  1516. const
  1517. double3 * val // value to transform
  1518. )
  1519. {
  1520. DASSERT(mat);
  1521. DASSERT(val);
  1522. N_MatrixD_inverse++;
  1523. if ( !mat->norm_valid && !mat->tmatrix_valid )
  1524. CalcNormMatrixD(mat);
  1525. if (mat->use_matrix)
  1526. {
  1527. if (!mat->imatrix_valid)
  1528. CalcMatrixD(mat,true);
  1529. return TransformD3D34(&mat->inv_matrix,val);
  1530. }
  1531. double3 res;
  1532. res.x = ( val->x - mat->norm_translate.x ) / mat->norm_scale.x;
  1533. res.y = ( val->y - mat->norm_translate.y ) / mat->norm_scale.y;
  1534. res.z = ( val->z - mat->norm_translate.z ) / mat->norm_scale.z;
  1535. return res;
  1536. }
  1537. ///////////////////////////////////////////////////////////////////////////////
  1538. ///////////////////////////////////////////////////////////////////////////////
  1539. void TransformD3NMatrixD
  1540. (
  1541. MatrixD_t * mat, // valid data structure
  1542. double3 * val, // value array to transform
  1543. int n, // number of 3D vectors in 'val'
  1544. uint off // if n>1: offset from one to next 'val' vector
  1545. )
  1546. {
  1547. DASSERT(mat);
  1548. DASSERT(val);
  1549. DASSERT( n <= 1 || off >= sizeof(*val) );
  1550. N_MatrixD_forward += n;
  1551. if ( !mat->norm_valid && !mat->tmatrix_valid )
  1552. CalcNormMatrixD(mat);
  1553. if (mat->use_matrix)
  1554. {
  1555. if (!mat->tmatrix_valid)
  1556. CalcTransMatrixD(mat,true);
  1557. while ( n-- > 0 )
  1558. {
  1559. *val = TransformD3D34(&mat->trans_matrix,val);
  1560. val = (double3*)( (u8*)val + off );
  1561. }
  1562. }
  1563. else if (mat->transform_enabled)
  1564. {
  1565. while ( n-- > 0 )
  1566. {
  1567. val->x = val->x * mat->norm_scale.x + mat->norm_translate.x;
  1568. val->y = val->y * mat->norm_scale.y + mat->norm_translate.y;
  1569. val->z = val->z * mat->norm_scale.z + mat->norm_translate.z;
  1570. val = (double3*)( (u8*)val + off );
  1571. }
  1572. }
  1573. }
  1574. ///////////////////////////////////////////////////////////////////////////////
  1575. void InvTransformD3NMatrixD
  1576. (
  1577. MatrixD_t * mat, // valid data structure
  1578. double3 * val, // value array to transform
  1579. int n, // number of 3D vectors in 'val'
  1580. uint off // if n>1: offset from one to next 'val' vector
  1581. )
  1582. {
  1583. DASSERT(mat);
  1584. DASSERT(val);
  1585. DASSERT( n <= 1 || off >= sizeof(*val) );
  1586. N_MatrixD_inverse += n;
  1587. if ( !mat->norm_valid && !mat->tmatrix_valid )
  1588. CalcNormMatrixD(mat);
  1589. if (mat->use_matrix)
  1590. {
  1591. if (!mat->imatrix_valid)
  1592. CalcMatrixD(mat,true);
  1593. while ( n-- > 0 )
  1594. {
  1595. *val = TransformD3D34(&mat->inv_matrix,val);
  1596. val = (double3*)( (u8*)val + off );
  1597. }
  1598. }
  1599. else if (mat->transform_enabled)
  1600. {
  1601. double3 f; // multiplication is faster than division
  1602. f.x = 1.0 / mat->norm_scale.x;
  1603. f.y = 1.0 / mat->norm_scale.y;
  1604. f.z = 1.0 / mat->norm_scale.z;
  1605. while ( n-- > 0 )
  1606. {
  1607. val->x = ( val->x - mat->norm_translate.x ) * f.x;
  1608. val->y = ( val->y - mat->norm_translate.y ) * f.y;
  1609. val->z = ( val->z - mat->norm_translate.z ) * f.z;
  1610. val = (double3*)( (u8*)val + off );
  1611. }
  1612. }
  1613. }
  1614. //
  1615. ///////////////////////////////////////////////////////////////////////////////
  1616. /////////////// MatrixD_t: float transform ///////////////
  1617. ///////////////////////////////////////////////////////////////////////////////
  1618. float3 TransformF3MatrixD
  1619. (
  1620. MatrixD_t * mat, // valid data structure
  1621. const
  1622. float3 * val // value to transform
  1623. )
  1624. {
  1625. DASSERT(mat);
  1626. DASSERT(val);
  1627. N_MatrixD_forward++;
  1628. if ( !mat->norm_valid && !mat->tmatrix_valid )
  1629. CalcNormMatrixD(mat);
  1630. if (mat->use_matrix)
  1631. {
  1632. if (!mat->tmatrix_valid)
  1633. CalcTransMatrixD(mat,true);
  1634. return TransformF3D34(&mat->trans_matrix,val);
  1635. }
  1636. float3 res;
  1637. res.x = val->x * mat->norm_scale.x + mat->norm_translate.x;
  1638. res.y = val->y * mat->norm_scale.y + mat->norm_translate.y;
  1639. res.z = val->z * mat->norm_scale.z + mat->norm_translate.z;
  1640. return res;
  1641. }
  1642. ///////////////////////////////////////////////////////////////////////////////
  1643. float3 InvTransformF3MatrixD
  1644. (
  1645. MatrixD_t * mat, // valid data structure
  1646. const
  1647. float3 * val // value to transform
  1648. )
  1649. {
  1650. DASSERT(mat);
  1651. DASSERT(val);
  1652. N_MatrixD_inverse++;
  1653. if ( !mat->norm_valid && !mat->tmatrix_valid )
  1654. CalcNormMatrixD(mat);
  1655. if (mat->use_matrix)
  1656. {
  1657. if (!mat->imatrix_valid)
  1658. CalcMatrixD(mat,true);
  1659. return TransformF3D34(&mat->inv_matrix,val);
  1660. }
  1661. float3 res;
  1662. res.x = ( val->x - mat->norm_translate.x ) / mat->norm_scale.x;
  1663. res.y = ( val->y - mat->norm_translate.y ) / mat->norm_scale.y;
  1664. res.z = ( val->z - mat->norm_translate.z ) / mat->norm_scale.z;
  1665. return res;
  1666. }
  1667. ///////////////////////////////////////////////////////////////////////////////
  1668. ///////////////////////////////////////////////////////////////////////////////
  1669. void TransformF3NMatrixD
  1670. (
  1671. MatrixD_t * mat, // valid data structure
  1672. float3 * val, // value array to transform
  1673. int n, // number of 3D vectors in 'val'
  1674. uint off // if n>1: offset from one to next 'val' vector
  1675. )
  1676. {
  1677. DASSERT(mat);
  1678. DASSERT(val);
  1679. DASSERT_MSG( n <= 1 || off >= sizeof(*val), "n=%u,off=%u\n",n,off );
  1680. N_MatrixD_forward += n;
  1681. if ( !mat->norm_valid && !mat->tmatrix_valid )
  1682. CalcNormMatrixD(mat);
  1683. if (mat->use_matrix)
  1684. {
  1685. if (!mat->tmatrix_valid)
  1686. CalcTransMatrixD(mat,true);
  1687. while ( n-- > 0 )
  1688. {
  1689. *val = TransformF3D34(&mat->trans_matrix,val);
  1690. val = (float3*)( (u8*)val + off );
  1691. }
  1692. }
  1693. else if (mat->transform_enabled)
  1694. {
  1695. while ( n-- > 0 )
  1696. {
  1697. val->x = val->x * mat->norm_scale.x + mat->norm_translate.x;
  1698. val->y = val->y * mat->norm_scale.y + mat->norm_translate.y;
  1699. val->z = val->z * mat->norm_scale.z + mat->norm_translate.z;
  1700. val = (float3*)( (u8*)val + off );
  1701. }
  1702. }
  1703. }
  1704. ///////////////////////////////////////////////////////////////////////////////
  1705. void InvTransformF3NMatrixD
  1706. (
  1707. MatrixD_t * mat, // valid data structure
  1708. float3 * val, // value array to transform
  1709. int n, // number of 3D vectors in 'val'
  1710. uint off // if n>1: offset from one to next 'val' vector
  1711. )
  1712. {
  1713. DASSERT(mat);
  1714. DASSERT(val);
  1715. DASSERT( n <= 1 || off >= sizeof(*val) );
  1716. N_MatrixD_inverse += n;
  1717. if ( !mat->norm_valid && !mat->tmatrix_valid )
  1718. CalcNormMatrixD(mat);
  1719. if (mat->use_matrix)
  1720. {
  1721. if (!mat->imatrix_valid)
  1722. CalcMatrixD(mat,true);
  1723. while ( n-- > 0 )
  1724. {
  1725. *val = TransformF3D34(&mat->inv_matrix,val);
  1726. val = (float3*)( (u8*)val + off );
  1727. }
  1728. }
  1729. else if (mat->transform_enabled)
  1730. {
  1731. double3 f; // multiplication is faster than division
  1732. f.x = 1.0 / mat->norm_scale.x;
  1733. f.y = 1.0 / mat->norm_scale.y;
  1734. f.z = 1.0 / mat->norm_scale.z;
  1735. while ( n-- > 0 )
  1736. {
  1737. val->x = ( val->x - mat->norm_translate.x ) * f.x;
  1738. val->y = ( val->y - mat->norm_translate.y ) * f.y;
  1739. val->z = ( val->z - mat->norm_translate.z ) * f.z;
  1740. val = (float3*)( (u8*)val + off );
  1741. }
  1742. }
  1743. }
  1744. //
  1745. ///////////////////////////////////////////////////////////////////////////////
  1746. /////////////// MatrixD_t: direct transform ///////////////
  1747. ///////////////////////////////////////////////////////////////////////////////
  1748. double3 BaseTransformD3MatrixD
  1749. (
  1750. // transform using the base parameters
  1751. MatrixD_t * mat, // valid data structure
  1752. const
  1753. double3 * val // value to transform
  1754. )
  1755. {
  1756. DASSERT(mat);
  1757. DASSERT(val);
  1758. if (!mat->valid)
  1759. InitializeMatrixD(mat);
  1760. if ( mat->use_matrix > 1 )
  1761. return TransformD3MatrixD(mat,val);
  1762. double3 rot = mat->rotate_rad;
  1763. Mult3f(rot,rot,180.0/M_PI);
  1764. Add3(rot,rot,mat->rotate_deg);
  1765. return TransformHelperD3MatrixD
  1766. ( &mat->scale,
  1767. &mat->scale_origin,
  1768. &mat->shift,
  1769. &rot,
  1770. mat->rotate_origin+0,
  1771. mat->rotate_origin+1,
  1772. mat->rotate_origin+2,
  1773. &mat->translate,
  1774. val
  1775. );
  1776. }
  1777. ///////////////////////////////////////////////////////////////////////////////
  1778. double3 NormTransformD3MatrixD
  1779. (
  1780. // transform using the norm parameters
  1781. MatrixD_t * mat, // valid data structure
  1782. const
  1783. double3 * val // value to transform
  1784. )
  1785. {
  1786. DASSERT(mat);
  1787. DASSERT(val);
  1788. if ( !mat->norm_valid && !mat->tmatrix_valid )
  1789. CalcNormMatrixD(mat);
  1790. if ( mat->use_matrix > 1 )
  1791. return TransformD3MatrixD(mat,val);
  1792. return TransformHelperD3MatrixD
  1793. ( &mat->norm_scale,
  1794. 0,
  1795. 0,
  1796. &mat->norm_rotate_deg,
  1797. 0,
  1798. 0,
  1799. 0,
  1800. &mat->norm_translate,
  1801. val
  1802. );
  1803. }
  1804. ///////////////////////////////////////////////////////////////////////////////
  1805. double3 TransformHelperD3MatrixD
  1806. (
  1807. // transform using vectors
  1808. double3 *scale, // NULL or scale vector
  1809. double3 *scale_origin, // NULL or origin for scaling
  1810. double3 *shift, // NULL or shift vector
  1811. double3 *rotate_deg, // NULL or rotation in degree
  1812. double3 *xrot_origin, // NULL or origin for x-rotation
  1813. double3 *yrot_origin, // NULL or origin for y-rotation
  1814. double3 *zrot_origin, // NULL or origin for z-rotation
  1815. double3 *translate, // NULL or translation vector
  1816. const
  1817. double3 * val // value to transform
  1818. )
  1819. {
  1820. DASSERT(val);
  1821. double3 res; //, null3 = { 0.0, 0.0, 0.0 };
  1822. //--- scale
  1823. if (!scale)
  1824. res = *val;
  1825. else if (scale_origin)
  1826. {
  1827. res.x = ( val->x - scale_origin->x ) * scale->x + scale_origin->x;
  1828. res.y = ( val->y - scale_origin->y ) * scale->y + scale_origin->y;
  1829. res.z = ( val->z - scale_origin->z ) * scale->z + scale_origin->z;
  1830. }
  1831. else
  1832. {
  1833. res.x = val->x * scale->x;
  1834. res.y = val->y * scale->y;
  1835. res.z = val->z * scale->z;
  1836. }
  1837. //--- shift
  1838. if (shift)
  1839. {
  1840. res.x += shift->x;
  1841. res.y += shift->y;
  1842. res.z += shift->z;
  1843. }
  1844. //--- rotate
  1845. if (rotate_deg)
  1846. {
  1847. uint xyz;
  1848. for ( xyz = 0; xyz < 3; xyz++ )
  1849. {
  1850. const double deg = fmod(rotate_deg->v[xyz]+180.0,360.0) - 180.0;
  1851. if ( fabs(deg) >= MIN_DEGREE )
  1852. {
  1853. uint a = xyz + 2; if ( a >= 3 ) a -= 3;
  1854. uint b = xyz + 1; if ( b >= 3 ) b -= 3;
  1855. double rad = deg * (M_PI/180.0);
  1856. if (xrot_origin)
  1857. {
  1858. const double da = res.v[a] - xrot_origin->v[a];
  1859. const double db = res.v[b] - xrot_origin->v[b];
  1860. rad += atan2(da,db);
  1861. const double len = sqrt(da*da+db*db);
  1862. res.v[a] = sin(rad) * len + xrot_origin->v[a];
  1863. res.v[b] = cos(rad) * len + xrot_origin->v[b];
  1864. }
  1865. else
  1866. {
  1867. rad += atan2(res.v[a],res.v[b]);
  1868. const double len = sqrt(res.v[a]*res.v[a]+res.v[b]*res.v[b]);
  1869. res.v[a] = sin(rad) * len;
  1870. res.v[b] = cos(rad) * len;
  1871. }
  1872. }
  1873. xrot_origin = yrot_origin;
  1874. yrot_origin = zrot_origin;
  1875. }
  1876. }
  1877. //--- translate
  1878. if (translate)
  1879. {
  1880. res.x += translate->x;
  1881. res.y += translate->y;
  1882. res.z += translate->z;
  1883. }
  1884. return res;
  1885. }
  1886. //
  1887. ///////////////////////////////////////////////////////////////////////////////
  1888. /////////////// MatrixD_t: printing ///////////////
  1889. ///////////////////////////////////////////////////////////////////////////////
  1890. static ccp print_matrix_stat
  1891. ( MatrixD_t * mat, char * buf, uint bufsize, bool for_inverse )
  1892. {
  1893. DASSERT(buf);
  1894. DASSERT(bufsize>10);
  1895. char *dest = buf, *bufend = buf + bufsize;
  1896. if (mat->scale_enabled)
  1897. dest = StringCopyE(dest,bufend,"+scale");
  1898. if (mat->rotate_enabled)
  1899. dest = StringCopyE(dest,bufend,"+rotate");
  1900. if (mat->translate_enabled)
  1901. dest = StringCopyE(dest,bufend,"+translate");
  1902. if ( mat->use_matrix > 1 && !for_inverse )
  1903. dest = StringCopyE(dest,bufend,",source");
  1904. else if (mat->use_matrix)
  1905. dest = StringCopyE(dest,bufend,",required");
  1906. if ( dest == buf )
  1907. StringCopyE(dest,bufend,"+no transformation");
  1908. return buf+1;
  1909. }
  1910. ///////////////////////////////////////////////////////////////////////////////
  1911. void PrintMatrixD
  1912. (
  1913. FILE * f, // file to print to
  1914. uint indent, // indention
  1915. ccp eol, // not NULL: print as 'end of line'
  1916. MatrixD_t * mat, // valid data structure
  1917. uint create, // bitfield for setup:
  1918. // 1: create normals if invalid
  1919. // 2: create transform matrix if invalid
  1920. // 4: create inverse matrix if invalid
  1921. uint print // bitfield print selection:
  1922. // 1: print base vectors
  1923. // 2: print normalized values, if valid
  1924. // 4: print transformation matrix, if valid
  1925. // 8: print inverse matrix, if valid
  1926. // 0x10: print also header, if only 1 section is print
  1927. // 0x20: print all, don't suppress NULL vectors
  1928. // 0x40: print an additional EOL behind each section
  1929. )
  1930. {
  1931. DASSERT(f);
  1932. DASSERT(mat);
  1933. //--- setup
  1934. indent = NormalizeIndent(indent);
  1935. if (!eol)
  1936. eol = "\n";
  1937. ccp sep = print & 0x40 ? eol : "";
  1938. if ( create & 4 )
  1939. CalcMatrixD(mat,true);
  1940. else if ( create & 2 )
  1941. CalcTransMatrixD(mat,true);
  1942. else if ( create & 1 )
  1943. CalcNormMatrixD(mat);
  1944. else if (!mat->valid)
  1945. InitializeMatrixD(mat);
  1946. if (!mat->norm_valid)
  1947. print &= ~2;
  1948. if (!mat->tmatrix_valid)
  1949. print &= ~4;
  1950. else if (mat->use_matrix>1)
  1951. print &= ~1;
  1952. if (!mat->imatrix_valid)
  1953. print &= ~8;
  1954. const uint print_all = print & 0x20;
  1955. uint print_head = print & 0x10;
  1956. print &= 0x0f;
  1957. if ( print != 1 && print != 2 && print != 4 && print != 8 )
  1958. print_head = 1;
  1959. //--- print base vectors
  1960. if ( print & 1 )
  1961. {
  1962. if (print_head)
  1963. fprintf(f,"%*sBase Vectors:%s", indent,"", eol );
  1964. if ( print_all || !IsOne3(mat->scale) )
  1965. fprintf(f,"%*s Scale: %11.3f %11.3f %11.3f%s",
  1966. indent,"",
  1967. mat->scale.x, mat->scale.y, mat->scale.z,
  1968. eol );
  1969. if ( print_all || !IsNull3(mat->scale_origin) )
  1970. fprintf(f,"%*s Origin: %11.3f %11.3f %11.3f%s",
  1971. indent,"",
  1972. mat->scale_origin.x, mat->scale_origin.y, mat->scale_origin.z,
  1973. eol );
  1974. if ( print_all || !IsNull3(mat->shift) )
  1975. fprintf(f,"%*s Shift: %11.3f %11.3f %11.3f%s",
  1976. indent,"",
  1977. mat->shift.x, mat->shift.y, mat->shift.z,
  1978. eol );
  1979. bool print_rot = false;
  1980. if ( print_all || !IsNull3(mat->rotate_deg) )
  1981. {
  1982. print_rot = true;
  1983. fprintf(f,"%*s Rotate/deg: %11.3f %11.3f %11.3f%s",
  1984. indent,"",
  1985. mat->rotate_deg.x, mat->rotate_deg.y, mat->rotate_deg.z,
  1986. eol );
  1987. }
  1988. if ( print_all || !IsNull3(mat->rotate_rad) )
  1989. {
  1990. print_rot = true;
  1991. fprintf(f,"%*s Rotate/rad: %11.3f %11.3f %11.3f%s",
  1992. indent,"",
  1993. mat->rotate_rad.x, mat->rotate_rad.y, mat->rotate_rad.z,
  1994. eol );
  1995. }
  1996. if (print_rot)
  1997. {
  1998. double3 *d = mat->rotate_origin;
  1999. uint xyz;
  2000. for ( xyz = 0; xyz < 3; xyz++, d++ )
  2001. if ( print_all || !IsNull3(*d) )
  2002. fprintf(f,"%*s %c-origin: %11.3f %11.3f %11.3f%s",
  2003. indent,"", 'x'+xyz,
  2004. d->x, d->y, d->z,
  2005. eol );
  2006. }
  2007. if ( print_all || !IsNull3(mat->translate) )
  2008. fprintf(f,"%*s Translate: %11.3f %11.3f %11.3f%s",
  2009. indent,"",
  2010. mat->translate.x, mat->translate.y, mat->translate.z,
  2011. eol );
  2012. fputs(sep,f);
  2013. }
  2014. //--- print normalized vectors
  2015. if ( print & 2 )
  2016. {
  2017. if (print_head)
  2018. fprintf(f,"%*sNormalized Vectors (seq=%u):%s",
  2019. indent,"", mat->sequence_number, eol );
  2020. fprintf(f,
  2021. "%*s Scale: %11.3f %11.3f %11.3f [%c%c%c]%s"
  2022. "%*s Rotate/deg: %11.3f %11.3f %11.3f [%c%c%c]%s"
  2023. #if TEST0
  2024. "%*s Rotate/rad: %11.3f %11.3f %11.3f%s"
  2025. #endif
  2026. "%*s Translate: %11.3f %11.3f %11.3f [%c%c%c]%s",
  2027. indent,"",
  2028. mat->norm_scale.x, mat->norm_scale.y, mat->norm_scale.z,
  2029. mat->scale_enabled & 1 ? 'x' : '-',
  2030. mat->scale_enabled & 2 ? 'y' : '-',
  2031. mat->scale_enabled & 4 ? 'z' : '-',
  2032. eol,
  2033. indent,"",
  2034. mat->norm_rotate_deg.x, mat->norm_rotate_deg.y, mat->norm_rotate_deg.z,
  2035. mat->rotate_enabled & 1 ? 'x' : '-',
  2036. mat->rotate_enabled & 2 ? 'y' : '-',
  2037. mat->rotate_enabled & 4 ? 'z' : '-',
  2038. eol,
  2039. #if TEST0
  2040. indent,"",
  2041. mat->norm_rotate_rad.x, mat->norm_rotate_rad.y, mat->norm_rotate_rad.z,
  2042. eol,
  2043. #endif
  2044. indent,"",
  2045. mat->norm_translate.x, mat->norm_translate.y, mat->norm_translate.z,
  2046. mat->translate_enabled & 1 ? 'x' : '-',
  2047. mat->translate_enabled & 2 ? 'y' : '-',
  2048. mat->translate_enabled & 4 ? 'z' : '-',
  2049. eol );
  2050. if ( print_all || !IsNull3(mat->norm_pos2d) )
  2051. fprintf(f,"%*s 2D tf-base: %11.3f %11.3f %11.3f (for 2D transform)%s",
  2052. indent,"",
  2053. mat->norm_pos2d.x, mat->norm_pos2d.y, mat->norm_pos2d.z,
  2054. eol );
  2055. fputs(sep,f);
  2056. }
  2057. //--- print transformation matrix
  2058. char buf[50];
  2059. if ( print & 4 )
  2060. {
  2061. if (print_head)
  2062. fprintf(f,"%*sTransformation Matrix (%s):%s",
  2063. indent,"", print_matrix_stat(mat,buf,sizeof(buf),false), eol );
  2064. fprintf(f,
  2065. "%*s x' = %11.3f * x + %11.3f * y + %11.3f * z + %11.3f%s"
  2066. "%*s y' = %11.3f * x + %11.3f * y + %11.3f * z + %11.3f%s"
  2067. "%*s z' = %11.3f * x + %11.3f * y + %11.3f * z + %11.3f%s"
  2068. "%s",
  2069. indent,"",
  2070. mat->trans_matrix.x[0],
  2071. mat->trans_matrix.x[1],
  2072. mat->trans_matrix.x[2],
  2073. mat->trans_matrix.x[3],
  2074. eol,
  2075. indent,"",
  2076. mat->trans_matrix.y[0],
  2077. mat->trans_matrix.y[1],
  2078. mat->trans_matrix.y[2],
  2079. mat->trans_matrix.y[3],
  2080. eol,
  2081. indent,"",
  2082. mat->trans_matrix.z[0],
  2083. mat->trans_matrix.z[1],
  2084. mat->trans_matrix.z[2],
  2085. mat->trans_matrix.z[3],
  2086. eol, sep );
  2087. }
  2088. //--- print inverse matrix
  2089. if ( print & 8 )
  2090. {
  2091. if (print_head)
  2092. fprintf(f,"%*sInverse Matrix (%s):%s",
  2093. indent,"", print_matrix_stat(mat,buf,sizeof(buf),true), eol );
  2094. fprintf(f,
  2095. "%*s x' = %11.3f * x + %11.3f * y + %11.3f * z + %11.3f%s"
  2096. "%*s y' = %11.3f * x + %11.3f * y + %11.3f * z + %11.3f%s"
  2097. "%*s z' = %11.3f * x + %11.3f * y + %11.3f * z + %11.3f%s"
  2098. "%s",
  2099. indent,"",
  2100. mat->inv_matrix.x[0],
  2101. mat->inv_matrix.x[1],
  2102. mat->inv_matrix.x[2],
  2103. mat->inv_matrix.x[3],
  2104. eol,
  2105. indent,"",
  2106. mat->inv_matrix.y[0],
  2107. mat->inv_matrix.y[1],
  2108. mat->inv_matrix.y[2],
  2109. mat->inv_matrix.y[3],
  2110. eol,
  2111. indent,"",
  2112. mat->inv_matrix.z[0],
  2113. mat->inv_matrix.z[1],
  2114. mat->inv_matrix.z[2],
  2115. mat->inv_matrix.z[3],
  2116. eol, sep );
  2117. }
  2118. }
  2119. //
  2120. ///////////////////////////////////////////////////////////////////////////////
  2121. /////////////// END ///////////////
  2122. ///////////////////////////////////////////////////////////////////////////////