dclib-numeric.h 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867
  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. #ifndef DCLIB_NUMERIC_H
  34. #define DCLIB_NUMERIC_H 1
  35. #include "dclib-types.h"
  36. #include "dclib-debug.h"
  37. #include <math.h>
  38. //
  39. ///////////////////////////////////////////////////////////////////////////////
  40. /////////////// float vector ///////////////
  41. ///////////////////////////////////////////////////////////////////////////////
  42. // [[float3]]
  43. typedef struct float3
  44. {
  45. union
  46. {
  47. u32 u[3];
  48. float v[3];
  49. struct
  50. {
  51. float x;
  52. float y;
  53. float z;
  54. }
  55. __attribute__ ((packed));
  56. }
  57. __attribute__ ((packed));
  58. }
  59. __attribute__ ((packed)) float3;
  60. ///////////////////////////////////////////////////////////////////////////////
  61. ///////////////////////////////////////////////////////////////////////////////
  62. // [[float3List_t]]
  63. typedef struct float3List_t
  64. {
  65. float3 *list; // list of data
  66. uint *sort; // NULL or 'size' alloced elements
  67. uint used; // used elements of 'list'
  68. uint size; // alloced elements of 'list'
  69. } float3List_t;
  70. //-----------------------------------------------------------------------------
  71. void InitializeF3L
  72. (
  73. float3List_t *f3l, // valid data
  74. uint bin_search // >0: enable binary search
  75. // and allocate 'bin_search' elements
  76. );
  77. void ResetF3L ( float3List_t * f3l );
  78. float3 * AppendF3L ( float3List_t * f3l );
  79. uint FindInsertFloatF3L ( float3List_t * f3l, float3 *val, bool fast );
  80. float3 * GrowF3L ( float3List_t * f3l, uint n );
  81. //
  82. ///////////////////////////////////////////////////////////////////////////////
  83. /////////////// double vector ///////////////
  84. ///////////////////////////////////////////////////////////////////////////////
  85. // [[double3]]
  86. typedef struct double3
  87. {
  88. union
  89. {
  90. u64 u[3];
  91. double v[3];
  92. struct
  93. {
  94. double x;
  95. double y;
  96. double z;
  97. };
  98. };
  99. } double3;
  100. ///////////////////////////////////////////////////////////////////////////////
  101. ///////////////////////////////////////////////////////////////////////////////
  102. // [[double3List_t]]
  103. typedef struct double3List_t
  104. {
  105. double3 *list; // list of data
  106. uint used; // used elements of 'list'
  107. uint size; // alloced elements of 'list'
  108. } double3List_t;
  109. //-----------------------------------------------------------------------------
  110. void InitializeD3L ( double3List_t * d3l );
  111. void ResetD3L ( double3List_t * d3l );
  112. double3 * AppendD3L ( double3List_t * d3l );
  113. uint FindInsertFloatD3L ( double3List_t * d3l, double3 *val, bool fast );
  114. double3 * GrowD3L ( double3List_t * d3l, uint n );
  115. //
  116. ///////////////////////////////////////////////////////////////////////////////
  117. /////////////// 2D vector macros ///////////////
  118. ///////////////////////////////////////////////////////////////////////////////
  119. #define SideOfLine(ax,ay,bx,by,px,py) \
  120. ( ((bx)-(ax)) * ((py)-(ay)) - ((by)-(ay)) * ((px)-(ax)) )
  121. #define SideOfLineXY(a,b,p) \
  122. ( ((b).x-(a).x) * ((p).y-(a).y) - ((b).y-(a).y) * ((p).x-(a).x) )
  123. #define SideOfLineXZ(a,b,p) \
  124. ( ((b).x-(a).x) * ((p).z-(a).z) - ((b).z-(a).z) * ((p).x-(a).x) )
  125. #define SideOfLineYZ(a,b,p) \
  126. ( ((b).y-(a).y) * ((p).z-(a).z) - ((b).z-(a).z) * ((p).y-(a).y) )
  127. //
  128. ///////////////////////////////////////////////////////////////////////////////
  129. /////////////// 3D vector macros ///////////////
  130. ///////////////////////////////////////////////////////////////////////////////
  131. #define NULL_EPSILON 1e-9 // 'fabs(value) < NULL_EPSILON' is 0.0
  132. #define MIN_DEGREE 1e-4 // 'fabs(value) < MIN_DEGREE' is 0.0
  133. #define Assign3(d,s) do { (d).x = (s).x; (d).y = (s).y; (d).z = (s).z; } while (0)
  134. #define IsNull3(d) ( (d).x == 0.0 && (d).y == 0.0 && (d).z == 0.0 )
  135. #define IsNull3e(d,e) ( fabs((d).x) < (e) \
  136. && fabs((d).y) < (e) \
  137. && fabs((d).z) < (e) )
  138. #define IsOne3(d) ( (d).x == 1.0 && (d).y == 1.0 && (d).z == 1.0 )
  139. #define IsOne3e(d,e) ( fabs((d).x-1.0) < (e) \
  140. && fabs((d).y-1.0) < (e) \
  141. && fabs((d).z-1.0) < (e) )
  142. #define IsVal3(d,v) ( (d).x == (v) && (d).y == (v) && (d).z == (v) )
  143. #define IsVal3e(d,v,e) ( fabs( (d).x - (v) ) < (e) \
  144. && fabs( (d).y - (v) ) < (e) \
  145. && fabs( (d).z - (v) ) < (e) )
  146. #define IsEQ3(a,b) ( (a).x == (b).x && (a).y == (b).y && (a).z == (b).z )
  147. #define IsEQ3e(a,b,e) ( fabs( (a).x - (b).x ) < (e) \
  148. && fabs( (a).y - (b).y ) < (e) \
  149. && fabs( (a).z - (b).z ) < (e) )
  150. #define Add3(d,a,b) do { (d).x = (a).x + (b).x; \
  151. (d).y = (a).y + (b).y; \
  152. (d).z = (a).z + (b).z; \
  153. } while (0)
  154. #define Sub3(d,a,b) do { (d).x = (a).x - (b).x; \
  155. (d).y = (a).y - (b).y; \
  156. (d).z = (a).z - (b).z; \
  157. } while (0)
  158. #define Neg3(v) do { (v).x = -(v).x; (v).y = -(v).y; (v).z = -(v).z; } while (0)
  159. #define Div3f(d,a,f) do { (d).x = (a).x / (f); \
  160. (d).y = (a).y / (f); \
  161. (d).z = (a).z / (f); \
  162. } while (0)
  163. #define Mult3f(d,a,f) do { (d).x = (a).x * (f); \
  164. (d).y = (a).y * (f); \
  165. (d).z = (a).z * (f); \
  166. } while (0)
  167. #define LengthSqare3(d) ( (d).x*(d).x + (d).y*(d).y + (d).z*(d).z )
  168. #define Length3(d) sqrt( (d).x*(d).x + (d).y*(d).y + (d).z*(d).z )
  169. #define DotProd3(a,b) ( (a).x*(b).x + (a).y*(b).y + (a).z*(b).z )
  170. #define CrossProd3(d,a,b) do { (d).x = (a).y*(b).z - (a).z*(b).y; \
  171. (d).y = (a).z*(b).x - (a).x*(b).z; \
  172. (d).z = (a).x*(b).y - (a).y*(b).x; \
  173. } while (0)
  174. #define CrossProd3x(d,a,b) do { typeof((d).x) xx = (a).y*(b).z - (a).z*(b).y; \
  175. typeof((d).y) yy = (a).z*(b).x - (a).x*(b).z; \
  176. (d).z = (a).x*(b).y - (a).y*(b).x; \
  177. (d).x = xx; (d).y = yy; \
  178. } while (0)
  179. #define Unit3(v) do { double l = Length3(v); \
  180. if (l) { (v).x /= l; (v).y /= l; (v).z /= l; }} while (0)
  181. #define Unit3f(v,f) do { double l = Length3(v); \
  182. if (l) { l = (f)/l; \
  183. (v).x *= l; (v).y *= l; (v).z *= l; }} while (0)
  184. #define MinMax3p(min,max,a,b,c) do { \
  185. if (a<b) { min = a < c ? a : c; max = b > c ? b : c; } \
  186. else { min = b < c ? b : c; max = a > c ? a : c; } } while (0)
  187. //
  188. ///////////////////////////////////////////////////////////////////////////////
  189. /////////////// check numbers ///////////////
  190. ///////////////////////////////////////////////////////////////////////////////
  191. static inline bool IsNormalF ( float f )
  192. {
  193. return isfinite(f);
  194. // const int fpclass = fpclassify(f);
  195. // return fpclass == FP_NORMAL || fpclass == FP_ZERO;
  196. }
  197. static inline bool IsNormalD ( double d )
  198. {
  199. return isfinite(d);
  200. // const int fpclass = fpclassify(d);
  201. // return fpclass == FP_NORMAL || fpclass == FP_ZERO;
  202. }
  203. bool IsNormalF3 ( float *f3 );
  204. bool IsNormalF3be ( float *f3 ); // big endian!
  205. bool IsNormalD3 ( double *d3 );
  206. bool IsEqualD3 ( const double3 *a, const double3 *b,
  207. double null_epsilon, double diff_epsilon );
  208. //--- new functions
  209. bool IsSameF ( float a, float b, int bit_diff );
  210. bool IsSameD ( double a, double b, int bit_diff );
  211. bool IsSameF3 ( const float *a, const float *b, int bit_diff );
  212. bool IsSameD3 ( const double *a, const double *b, int bit_diff );
  213. //--- radiant and gegree
  214. #define rad2deg(n) ( (n)*(180.0/M_PI) )
  215. #define deg2rad(n) ( (n)*(M_PI/180.0) )
  216. //
  217. ///////////////////////////////////////////////////////////////////////////////
  218. /////////////// 2D vector functions ///////////////
  219. ///////////////////////////////////////////////////////////////////////////////
  220. uint PointsInConvexPolygonF
  221. (
  222. // return, how many points are inside the polygon
  223. float *pts, // points: pointer to a array with '2*n_pts' elements
  224. uint n_pts, // Number of (x,y) pairs in 'pts'
  225. float *pol, // polygon: pointer to a array with '2*n_pol' elements
  226. uint n_pol, // number of (x,y) pairs in 'pol'
  227. bool all, // false: count the numbers of points inside
  228. // true: return '1' for all points inside and otherwise '0'
  229. int *r_dir // If not NULL then return:
  230. // -1: polygon is defined counterclockwise
  231. // 0: unknown
  232. // +1: polygon is defined clockwise
  233. // If at least one point is inside, the result is known.
  234. );
  235. //-----------------------------------------------------------------------------
  236. uint PointsInConvexPolygonD
  237. (
  238. // return, how many points are inside the polygon
  239. double *pts, // points: pointer to a array with '2*n_pts' elements
  240. uint n_pts, // Number of (x,y) pairs in 'pts'
  241. double *pol, // polygon: pointer to a array with '2*n_pol' elements
  242. uint n_pol, // number of (x,y) pairs in 'pol'
  243. bool all, // false: count the numbers of points inside
  244. // true: return '1' for all points inside and otherwise '0'
  245. int *r_dir // If not NULL then return:
  246. // -1: polygon is defined counterclockwise
  247. // 0: unknown
  248. // +1: polygon is defined clockwise
  249. // If at least one point is inside, the result is known.
  250. );
  251. //
  252. ///////////////////////////////////////////////////////////////////////////////
  253. /////////////// float34 ///////////////
  254. ///////////////////////////////////////////////////////////////////////////////
  255. // [[float34]]
  256. typedef struct float34 // transformation matrix
  257. {
  258. union
  259. {
  260. float v[12];
  261. float m[3][4];
  262. struct
  263. {
  264. float x[4];
  265. float y[4];
  266. float z[4];
  267. }
  268. __attribute__ ((packed));
  269. }
  270. __attribute__ ((packed));
  271. }
  272. __attribute__ ((packed)) float34;
  273. //-----------------------------------------------------------------------------
  274. void ClearFloat34 ( float34 *f34 );
  275. void SetupFloat34 ( float34 *f34 );
  276. void SetupMatrixF34
  277. (
  278. float34 *mat, // data to setup
  279. float3 *scale, // NULL or scaling vector
  280. float3 *rotate, // NULL or rotation vector in *radiant*
  281. float3 *translate // NULL or translation vector
  282. );
  283. void CalcInverseMatrixF34
  284. (
  285. float34 *i, // store inverse matrix here
  286. const float34 *t // transformation matrix
  287. );
  288. void MultiplyF34
  289. (
  290. float34 *dest, // valid, store result here, may be 'src1' or 'src2'
  291. const float34 *src1, // first valid source, if NULL use dest
  292. const float34 *src2 // second valid source, if NULL use dest
  293. );
  294. //
  295. ///////////////////////////////////////////////////////////////////////////////
  296. /////////////// double34 ///////////////
  297. ///////////////////////////////////////////////////////////////////////////////
  298. // [[double34]]
  299. typedef struct double34 // transformation matrix
  300. {
  301. union
  302. {
  303. double v[12];
  304. double m[3][4];
  305. struct
  306. {
  307. double x[4];
  308. double y[4];
  309. double z[4];
  310. }
  311. __attribute__ ((packed));
  312. }
  313. __attribute__ ((packed));
  314. }
  315. __attribute__ ((packed)) double34;
  316. //-----------------------------------------------------------------------------
  317. void ClearDouble34 ( double34 *d34 );
  318. void SetupDouble34 ( double34 *d34 );
  319. void SetupMatrixD34
  320. (
  321. double34 *mat, // data to setup
  322. double3 *scale, // NULL or scaling vector
  323. double3 *rotate, // NULL or rotation vector in *radiant*
  324. double3 *translate // NULL or translation vector
  325. );
  326. void CalcInverseMatrixD34
  327. (
  328. double34 *i, // store inverse matrix here
  329. const double34 *t // transformation matrix
  330. );
  331. void MultiplyD34
  332. (
  333. double34 *dest, // valid, store result here, may be 'src1' or 'src2'
  334. const double34 *src1, // first valid source, if NULL use dest
  335. const double34 *src2 // second valid source, if NULL use dest
  336. );
  337. //-----------------------------------------------------------------------------
  338. void CopyF34toD34
  339. (
  340. double34 *dest, // destination matrix
  341. const float34 *src // source matrix
  342. );
  343. void CopyD34toF34
  344. (
  345. float34 *dest, // destination matrix
  346. const double34 *src // source matrix
  347. );
  348. //-----------------------------------------------------------------------------
  349. static inline float3 TransformF3D34 ( const double34 *d34, const float3 *val )
  350. {
  351. DASSERT(d34);
  352. DASSERT(val);
  353. const double *m = d34->v;
  354. float3 res;
  355. res.x = m[ 0] * val->x + m[ 1] * val->y + m[ 2] * val->z + m[ 3];
  356. res.y = m[4+0] * val->x + m[4+1] * val->y + m[4+2] * val->z + m[4+3];
  357. res.z = m[8+0] * val->x + m[8+1] * val->y + m[8+2] * val->z + m[8+3];
  358. return res;
  359. }
  360. static inline double3 TransformD3D34 ( const double34 *d34, const double3 *val )
  361. {
  362. DASSERT(d34);
  363. DASSERT(val);
  364. const double *m = d34->v;
  365. double3 res;
  366. res.x = m[ 0] * val->x + m[ 1] * val->y + m[ 2] * val->z + m[ 3];
  367. res.y = m[4+0] * val->x + m[4+1] * val->y + m[4+2] * val->z + m[4+3];
  368. res.z = m[8+0] * val->x + m[8+1] * val->y + m[8+2] * val->z + m[8+3];
  369. return res;
  370. }
  371. static inline float3 TransformF3F34 ( const float34 *d34, const float3 *val )
  372. {
  373. DASSERT(d34);
  374. DASSERT(val);
  375. const float *m = d34->v;
  376. float3 res;
  377. res.x = m[ 0] * val->x + m[ 1] * val->y + m[ 2] * val->z + m[ 3];
  378. res.y = m[4+0] * val->x + m[4+1] * val->y + m[4+2] * val->z + m[4+3];
  379. res.z = m[8+0] * val->x + m[8+1] * val->y + m[8+2] * val->z + m[8+3];
  380. return res;
  381. }
  382. static inline double3 TransformD3F34 ( const float34 *d34, const double3 *val )
  383. {
  384. DASSERT(d34);
  385. DASSERT(val);
  386. const float *m = d34->v;
  387. double3 res;
  388. res.x = m[ 0] * val->x + m[ 1] * val->y + m[ 2] * val->z + m[ 3];
  389. res.y = m[4+0] * val->x + m[4+1] * val->y + m[4+2] * val->z + m[4+3];
  390. res.z = m[8+0] * val->x + m[8+1] * val->y + m[8+2] * val->z + m[8+3];
  391. return res;
  392. }
  393. //
  394. ///////////////////////////////////////////////////////////////////////////////
  395. /////////////// MatrixD_t ///////////////
  396. ///////////////////////////////////////////////////////////////////////////////
  397. // [[MatrixD_t]]
  398. typedef struct MatrixD_t
  399. {
  400. //--- status
  401. bool valid; // false: data structure needs initialization
  402. bool norm_valid; // false: normed values are invalid
  403. bool tmatrix_valid; // false: transformation matrix is invalid
  404. bool imatrix_valid; // false: inverse matrix is invalid
  405. uint sequence_number; // Used for tracking. It is incremented
  406. // on every new calculation by CalcNormMatrixD()
  407. //--- matrix usage status
  408. u8 use_matrix; // 0: matrix not needed for transformation
  409. // 1: matrix needed for transformation
  410. // 2: matrix is the only valid reference
  411. //--- status, only valid, if 'norm_valid'
  412. u8 scale_enabled; // scaling is enabled: 1=x, 2=y, 4=z
  413. u8 rotate_enabled; // rotation is enabled: 1=x, 2=y, 4=z
  414. u8 translate_enabled; // translation is enabled: 1=x, 2=y, 4=z
  415. u8 transform_enabled; // 'OR' result of the 3 enabled values above
  416. // OR 'use_matrix<<3'
  417. //--- base values: clear 'norm_valid' and '*matrix_valid' on change
  418. double3 scale; // scale vector
  419. double3 scale_origin; // origin for scaling
  420. double3 shift; // shift vector
  421. double3 rotate_deg; // rotation in degree and radiant.
  422. double3 rotate_rad; // both values are used as sum.
  423. double3 rotate_origin[3]; // origin for rotation
  424. double3 translate; // translation vector
  425. //--- normed values, calculated by CalcNormMatrixD()
  426. double3 norm_scale; // scale vector
  427. double3 norm_rotate_deg; // rotation vector in degree
  428. double3 norm_rotate_rad; // rotation vector in radiant
  429. double3 norm_translate; // translation vector
  430. double3 norm_pos2d; // recommended positions for 2d transformations
  431. //--- matrices, calculated by CalcMatrixD()
  432. double34 trans_matrix; // transformation matrix
  433. double34 inv_matrix; // inverse transformation matrix
  434. }
  435. MatrixD_t;
  436. //-----------------------------------------------------------------------------
  437. // statistics
  438. extern u64 N_MatrixD_forward; // total number of forward transformations
  439. extern u64 N_MatrixD_inverse; // total number of inverse transformations
  440. //-----------------------------------------------------------------------------
  441. void InitializeMatrixD ( MatrixD_t * mat );
  442. void CopyMatrixD
  443. (
  444. MatrixD_t *dest, // valid destination
  445. const
  446. MatrixD_t *src // NULL or source
  447. );
  448. void TermAssignMatrixD
  449. (
  450. // called after dirext matrix manipulations
  451. MatrixD_t * mat // valid data structure
  452. );
  453. //-----------------------------------------------------------------------------
  454. MatrixD_t * SetScaleMatrixD
  455. (
  456. MatrixD_t * mat, // valid data structure
  457. double3 * scale, // NULL: clear scale, not NULL: set scale
  458. double3 * origin // not NULL: Origin for scaling
  459. );
  460. MatrixD_t * SetShiftMatrixD
  461. (
  462. MatrixD_t * mat, // valid data structure
  463. double3 * shift // NULL: clear Shift, not NULL: set Shift
  464. );
  465. MatrixD_t * SetScaleShiftMatrixD
  466. (
  467. MatrixD_t * mat, // valid data structure
  468. uint xyz, // 0..2: x/y/z coordinate to set
  469. double old1, // old value of first point
  470. double new1, // new value of first point
  471. double old2, // old value of second point
  472. double new2 // new value of second point
  473. );
  474. MatrixD_t * SetRotateMatrixD
  475. (
  476. MatrixD_t * mat, // valid data structure
  477. uint xyz, // 0..2: x/y/z coordinate to set
  478. double degree, // angle in degree
  479. double radiant, // angle in radiant
  480. double3 * origin // not NULL: Origin for the rotation
  481. );
  482. MatrixD_t * SetTranslateMatrixD
  483. (
  484. MatrixD_t * mat, // valid data structure
  485. double3 * translate // NULL: clear translate, not NULL: set translate
  486. );
  487. MatrixD_t * SetMatrixD
  488. (
  489. MatrixD_t * mat, // valid data structure
  490. const
  491. double34 * src // NULL or matrix to set
  492. );
  493. //-----------------------------------------------------------------------------
  494. MatrixD_t * SetAScaleMatrixD
  495. (
  496. // calculate the matrix as rotation around a specified axis
  497. MatrixD_t * mat, // valid data structure
  498. double scale, // scale factor
  499. double3 * dir // NULL or scaling direction as vector
  500. );
  501. MatrixD_t * SetARotateMatrixD
  502. (
  503. // calculate the matrix as rotation around a specified axis
  504. MatrixD_t * mat, // valid data structure
  505. double degree, // angle in degree
  506. double radiant, // angle in radiant, add to degree with factor
  507. double3 * pt1, // point #1 to define the axis; if NULL use (0,0,0)
  508. double3 * pt2 // point #2 to define the axis; if NULL use (0,0,0)
  509. );
  510. //-----------------------------------------------------------------------------
  511. MatrixD_t * CheckStatusMatrixD
  512. (
  513. MatrixD_t * mat // valid data structure
  514. );
  515. MatrixD_t * CalcNormMatrixD
  516. (
  517. MatrixD_t * mat // valid data structure
  518. );
  519. MatrixD_t * CalcTransMatrixD
  520. (
  521. MatrixD_t * mat, // valid data structure
  522. bool always // false: calc transformation matrix only
  523. // if needed for transformation
  524. // true: ignore 'rotate_enabled'
  525. );
  526. MatrixD_t * CalcMatrixD
  527. (
  528. MatrixD_t * mat, // valid data structure
  529. bool always // false: calc both matrices only
  530. // if needed for transformation
  531. // true: calc matrices always
  532. );
  533. MatrixD_t * MultiplyMatrixD
  534. (
  535. MatrixD_t *dest, // valid, store result here, may be 'src1' or 'src2'
  536. MatrixD_t *src1, // first valid source, if NULL use dest
  537. MatrixD_t *src2, // second valid source, if NULL use dest
  538. uint inverse_mode // bit field:
  539. // 1: use inverse matrix of src1
  540. // 2: use inverse matrix of src2
  541. );
  542. MatrixD_t * CalcVectorsMatrixD
  543. (
  544. MatrixD_t * mat, // valid data structure
  545. bool always // false: calc vectors only if matrix is valid
  546. // true: calc matrix if invalid & vectors always
  547. );
  548. static inline bool TransformationEnabledMatrixD ( MatrixD_t * mat )
  549. {
  550. return CalcNormMatrixD(mat)->transform_enabled != 0;
  551. }
  552. //-----------------------------------------------------------------------------
  553. double3 TransformD3MatrixD
  554. (
  555. MatrixD_t * mat, // valid data structure
  556. const
  557. double3 * val // value to transform
  558. );
  559. double3 InvTransformD3MatrixD
  560. (
  561. MatrixD_t * mat, // valid data structure
  562. const
  563. double3 * val // value to transform
  564. );
  565. void TransformD3NMatrixD
  566. (
  567. MatrixD_t * mat, // valid data structure
  568. double3 * val, // value array to transform
  569. int n, // number of 3D vectors in 'val'
  570. uint off // if n>1: offset from one to next 'val' vector
  571. );
  572. void InvTransformD3NMatrixD
  573. (
  574. MatrixD_t * mat, // valid data structure
  575. double3 * val, // value array to transform
  576. int n, // number of 3D vectors in 'val'
  577. uint off // if n>1: offset from one to next 'val' vector
  578. );
  579. //-----------------------------------------------------------------------------
  580. float3 TransformF3MatrixD
  581. (
  582. MatrixD_t * mat, // valid data structure
  583. const
  584. float3 * val // value to transform
  585. );
  586. float3 InvTransformF3MatrixD
  587. (
  588. MatrixD_t * mat, // valid data structure
  589. const
  590. float3 * val // value to transform
  591. );
  592. void TransformF3NMatrixD
  593. (
  594. MatrixD_t * mat, // valid data structure
  595. float3 * val, // value array to transform
  596. int n, // number of 3D vectors in 'val'
  597. uint off // if n>1: offset from one to next 'val' vector
  598. );
  599. void InvTransformF3NMatrixD
  600. (
  601. MatrixD_t * mat, // valid data structure
  602. float3 * val, // value array to transform
  603. int n, // number of 3D vectors in 'val'
  604. uint off // if n>1: offset from one to next 'val' vector
  605. );
  606. //-----------------------------------------------------------------------------
  607. double3 BaseTransformD3MatrixD
  608. (
  609. // transform using the base parameters
  610. MatrixD_t * mat, // valid data structure
  611. const
  612. double3 * val // value to transform
  613. );
  614. double3 NormTransformD3MatrixD
  615. (
  616. // transform using the norm parameters
  617. MatrixD_t * mat, // valid data structure
  618. const
  619. double3 * val // value to transform
  620. );
  621. double3 TransformHelperD3MatrixD
  622. (
  623. // transform using vectors
  624. double3 *scale, // NULL or scale vector
  625. double3 *scale_origin, // NULL or origin for scaling
  626. double3 *shift, // NULL or shift vector
  627. double3 *rotate_deg, // NULL or rotation in degree
  628. double3 *xrot_origin, // NULL or origin for x-rotation
  629. double3 *yrot_origin, // NULL or origin for y-rotation
  630. double3 *zrot_origin, // NULL or origin for z-rotation
  631. double3 *translate, // NULL or translation vector
  632. const
  633. double3 * val // value to transform
  634. );
  635. //-----------------------------------------------------------------------------
  636. void PrintMatrixD
  637. (
  638. FILE * f, // file to print to
  639. uint indent, // indention
  640. ccp eol, // not NULL: print as 'end of line'
  641. MatrixD_t * mat, // valid data structure
  642. uint create, // bitfield for setup:
  643. // 1: create normals if invalid
  644. // 2: create transform matrix if invalid
  645. // 4: create inverse matrix if invalid
  646. uint print // bitfield print selection:
  647. // 1: print base vectors
  648. // 2: print normalized values, if valid
  649. // 4: print transformation matrix, if valid
  650. // 8: print inverse matrix, if valid
  651. // 0x10: print also header, if only 1 section is print
  652. // 0x20: print all, don't suppress NULL vectors
  653. // 0x40: print an additional EOL behind each section
  654. );
  655. //
  656. ///////////////////////////////////////////////////////////////////////////////
  657. /////////////// CRC16 ///////////////
  658. ///////////////////////////////////////////////////////////////////////////////
  659. #define CRC16_CCITT_POLYNOM 0x1021
  660. void CreateCRC16Table ( u16 table[0x100], u16 polynom );
  661. const u16 * GetCRC16Table ( u16 polynom );
  662. u16 CalcCRC16 ( cvp data, uint data_size, u16 polynom, u16 preset );
  663. static inline u16 CalcCRC16CCITT ( cvp data, uint data_size )
  664. { return CalcCRC16(data,data_size,CRC16_CCITT_POLYNOM,0); }
  665. //
  666. ///////////////////////////////////////////////////////////////////////////////
  667. /////////////// misc ///////////////
  668. ///////////////////////////////////////////////////////////////////////////////
  669. static inline int float2int ( float f ) { return (int) truncf(f+0.5); }
  670. static inline int double2int ( double d ) { return (int) trunc (d+0.5); }
  671. static inline s64 float2int64 ( float f ) { return (s64) truncf(f+0.5); }
  672. static inline s64 double2int64 ( double d ) { return (s64) trunc (d+0.5); }
  673. ///////////////////////////////////////////////////////////////////////////////
  674. u64 MulDivU64 ( u64 factor1, u64 factor2, u64 divisor );
  675. s64 MulDivS64 ( s64 factor1, s64 factor2, s64 divisor );
  676. ///////////////////////////////////////////////////////////////////////////////
  677. // all values are multiple of 26*26*100 = 67600 = 0x00010810
  678. #define GOOD_MAX_NICE4_5 67600 // 1 * 67600
  679. #define GOOD_MAX_NICE4_6 946400 // 14 * 67600
  680. #define GOOD_MAX_NICE4_7 9937200 // 147 * 67600
  681. #define GOOD_MAX_NICE4_8 99980400 // 1479 * 67600
  682. #define GOOD_MAX_NICE4_9 999939200 // 14792 * 67600
  683. #define GOOD_MAX_NICE4 4294966000 // 63535 * 67600 = 0xfffffaf0 = -1296
  684. ccp PrintNiceID4 ( uint nice_gid );
  685. char * ScanNiceID4 ( int * res, ccp arg );
  686. ///////////////////////////////////////////////////////////////////////////////
  687. // all values are multiple of 26*26*1000 = 676000 = 0x000a50a0
  688. #define GOOD_MAX_NICE5_6 676000 // 1 * 676000
  689. #define GOOD_MAX_NICE5_7 9464000 // 14 * 676000
  690. #define GOOD_MAX_NICE5_8 99372000 // 147 * 676000
  691. #define GOOD_MAX_NICE5_9 999804000 // 1479 * 676000
  692. #define GOOD_MAX_NICE5 4294628000 // 6353 * 676000 = 0xfffad2a0 = -339296
  693. ccp PrintNiceID5 ( uint nice_gid );
  694. char * ScanNiceID5 ( int * res, ccp arg );
  695. ///////////////////////////////////////////////////////////////////////////////
  696. // all values are multiple of 26*26*26*1000 = 17576000 = 0x010c3040
  697. #define GOOD_MAX_NICE6_8 87880000 // 5 * 17576000
  698. #define GOOD_MAX_NICE6_9 984256000 // 56 * 17576000
  699. #define GOOD_MAX_NICE6 4288544000 // 244 * 17576000 = 0xff9dfd00 = -6423296
  700. ccp PrintNiceID6 ( uint nice_gid );
  701. char * ScanNiceID6 ( int * res, ccp arg );
  702. //
  703. ///////////////////////////////////////////////////////////////////////////////
  704. /////////////// E N D ///////////////
  705. ///////////////////////////////////////////////////////////////////////////////
  706. #endif // DCLIB_NUMERIC_H