c3dlas.h 37 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120
  1. #ifndef __c3dlas_h__
  2. #define __c3dlas_h__
  3. #include <stdlib.h> // rand() et al.
  4. #include <stdint.h>
  5. #include <math.h> // fmin/fmax
  6. #undef I // because of some bullshit in <complex.h>
  7. //#define C3DLAS_USE_SIMD 1
  8. #define _0000b 0x00
  9. #define _0001b 0x01
  10. #define _0010b 0x02
  11. #define _0011b 0x03
  12. #define _0100b 0x04
  13. #define _0101b 0x05
  14. #define _0110b 0x06
  15. #define _0111b 0x07
  16. #define _1000b 0x08
  17. #define _1001b 0x09
  18. #define _1010b 0x0a
  19. #define _1011b 0x0b
  20. #define _1100b 0x0c
  21. #define _1101b 0x0d
  22. #define _1110b 0x0e
  23. #define _1111b 0x0f
  24. #define F_PI ((float)3.1415926535897932384626433832795028841971693993751)
  25. #define D_PI ((double)3.1415926535897932384626433832795028841971693993751)
  26. #define F_2PI ((float)6.2831853071795864769252867665590057683943387987502)
  27. #define D_2PI ((double)6.2831853071795864769252867665590057683943387987502)
  28. #define F_1_PI ((float)0.3183098861837906715377675267450287240689192914809)
  29. #define D_1_PI ((double)0.3183098861837906715377675267450287240689192914809)
  30. #define F_PI_2 ((float)1.5707963267948966192313216916397514420985846996875)
  31. #define D_PI_2 ((double)1.5707963267948966192313216916397514420985846996875)
  32. #define F_3PI_2 ((float)4.7123889803846898576939650749192543262957540990626)
  33. #define D_3PI_2 ((double)4.7123889803846898576939650749192543262957540990626)
  34. #define F_GOLDEN ((float)1.61803398874989484820458683436563811772030917980576f)
  35. #define D_GOLDEN ((double)1.61803398874989484820458683436563811772030917980576)
  36. #define RAD2DEG (57.29577951308232087679815481410517033240547246656432154916024386)
  37. #define DEG2RAD (0.0174532925199432957692369076848861271344287188854172545609719144)
  38. #ifndef FLT_CMP_EPSILON
  39. #define FLT_CMP_EPSILON 0.000001
  40. #endif
  41. #ifndef DBL_CMP_EPSILON
  42. #define DBL_CMP_EPSILON 0.00000000000001
  43. #endif
  44. #define FLT_CMP_EPSILON_SQ (FLT_CMP_EPSILON * FLT_CMP_EPSILON)
  45. #define DBL_CMP_EPSILON_SQ (DBL_CMP_EPSILON_SQ * DBL_CMP_EPSILON_SQ)
  46. #define C3DLAS_COPLANAR (0)
  47. #define C3DLAS_FRONT (1)
  48. #define C3DLAS_BACK (2)
  49. #define C3DLAS_INTERSECT (3)
  50. #define C3DLAS_DISJOINT (4)
  51. #define C3DLAS_PARALLEL (5)
  52. #ifndef C3DLAS_fprintf
  53. #define C3DLAS_fprintf fprintf
  54. #endif
  55. #ifndef C3DLAS_errprintf
  56. #define C3DLAS_errprintf(...) fprintf(stderr, __VA_ARGS__)
  57. #endif
  58. // set externally if desired
  59. // #define C3DLAS_SEGFAULT_ON_NO_MATRIX_INVERSE 0
  60. static const char* c3dlas_EnumString(int e) {
  61. switch(e) {
  62. case 0: return "C3DLAS_COPLANAR";
  63. case 1: return "C3DLAS_FRONT";
  64. case 2: return "C3DLAS_BACK";
  65. case 3: return "C3DLAS_INTERSECT";
  66. case 4: return "C3DLAS_DISJOINT";
  67. case 5: return "C3DLAS_PARALLEL";
  68. default: return "Unknown Code";
  69. }
  70. }
  71. #ifndef MAX
  72. #define MAX(a,b) ({ \
  73. __typeof__ (a) _a = (a); \
  74. __typeof__ (b) _b = (b); \
  75. _a > _b ? _a : _b; \
  76. })
  77. #endif
  78. #ifndef MIN
  79. #define MIN(a,b) ({ \
  80. __typeof__ (a) _a = (a); \
  81. __typeof__ (b) _b = (b); \
  82. _a < _b ? _a : _b; \
  83. })
  84. #endif
  85. // suffix, type, float
  86. // type
  87. #define C3DLAS_VECTOR_TYPE_LIST(X, ...) \
  88. X(, float, float, __VA_ARGS__) \
  89. X(d, double, double, __VA_ARGS__) \
  90. X(i, int, double, __VA_ARGS__) \
  91. X(l, long, double, __VA_ARGS__) \
  92. // suffix, type, float
  93. // type
  94. #define C3DLAS_VECTOR_LIST(X, ...) \
  95. X(2, 2, float, float, 2, FLT __VA_OPT__(,) __VA_ARGS__) \
  96. X(3, 3, float, float, 3, FLT __VA_OPT__(,) __VA_ARGS__) \
  97. X(4, 4, float, float, 4, FLT __VA_OPT__(,) __VA_ARGS__) \
  98. X(2, 2d, double, double, 2d, DBL __VA_OPT__(,) __VA_ARGS__) \
  99. X(3, 3d, double, double, 3d, DBL __VA_OPT__(,) __VA_ARGS__) \
  100. X(4, 4d, double, double, 4d, DBL __VA_OPT__(,) __VA_ARGS__) \
  101. X(2, 2i, int, double, 2d, DBL __VA_OPT__(,) __VA_ARGS__) \
  102. X(3, 3i, int, double, 3d, DBL __VA_OPT__(,) __VA_ARGS__) \
  103. X(4, 4i, int, double, 4d, DBL __VA_OPT__(,) __VA_ARGS__) \
  104. X(2, 2l, long, double, 2d, DBL __VA_OPT__(,) __VA_ARGS__) \
  105. X(3, 3l, long, double, 3d, DBL __VA_OPT__(,) __VA_ARGS__) \
  106. X(4, 4l, long, double, 4d, DBL __VA_OPT__(,) __VA_ARGS__) \
  107. #define C3DLAS_GEN_HELPER(sz, suf, ty, ft, sufft, pref, name, ...) Vector##suf: name##suf,
  108. #define X(suf, t, ...) \
  109. typedef struct Vector2 ## suf { \
  110. /* cartesian polar */ \
  111. union { t x, rho; }; \
  112. union { t y, theta; }; \
  113. } Vector2 ## suf;
  114. C3DLAS_VECTOR_TYPE_LIST(X)
  115. #undef X
  116. // The spherical coordinates use the "mathematical" conventions as opposed to the "physics" conventions
  117. // This is because of the struct layout convenience for overlapping with 2D polar coordinates.
  118. #define X(suf, t, ...) \
  119. typedef struct Vector3 ## suf { \
  120. /* cartesian spherical color */ \
  121. union { t x, rho, r; }; /* rho is the radius */ \
  122. union { t y, theta, g; }; /* rotation in the X-Y plane, with positive x axis being 0, and pi/2 being positive y axis */ \
  123. union { t z, phi, b; }; /* rotation in the plane passing through the Z axis, with 0 being the positive z axis */ \
  124. } Vector3 ## suf;
  125. C3DLAS_VECTOR_TYPE_LIST(X)
  126. #undef X
  127. #define X(suf, t, ...) \
  128. typedef struct Vector4 ## suf { \
  129. /* cartesian spherical color quaternion basis */ \
  130. union { t x, rho, r, i; }; /* rho = the radius */ \
  131. union { t y, theta, g, j; }; /* theta = rotation in the X-Y plane */ \
  132. union { t z, phi, b, k; }; /* phi = rotation in the plane passing through the Z axis */ \
  133. union { t w, a, real; }; /* real is last for memory alignment with 4d cartesian vectors */ \
  134. } Vector4 ## suf;
  135. C3DLAS_VECTOR_TYPE_LIST(X)
  136. #undef X
  137. // Best quaternion site on the internet so far: http://www.songho.ca/math/quaternion/quaternion.html
  138. typedef struct Vector4 Quaternion;
  139. typedef struct Vector4d Quaterniond;
  140. // Rays, but also infinite lines (mathematical lines) because there is no practical
  141. // difference besides whether you conside the ray to be one-sided or not.
  142. typedef struct {
  143. Vector3 o; // origin
  144. Vector3 d; // normalized direction
  145. } Ray3;
  146. typedef struct {
  147. Vector2 o; // origin
  148. Vector2 d; // normalized direction
  149. } Ray2;
  150. // Line *segments*
  151. typedef struct {
  152. Vector2 start, end;
  153. } Line2;
  154. typedef struct {
  155. union { Vector3 start, a; };
  156. union { Vector3 end, b; };
  157. } Line3;
  158. // Polygons are 2-dimensional by definition
  159. typedef struct Polygon {
  160. Vector2* points;
  161. long pointAlloc;
  162. long pointCount;
  163. Vector2 centroid;
  164. float maxRadiusSq; // squared distance from the centroid to the furthest point
  165. } Polygon;
  166. typedef struct BezierSplineSegment3 {
  167. Vector3 e, c; // end and control
  168. struct BezierSplineSegment3* next;
  169. } BezierSplineSegment3;
  170. typedef struct {
  171. int length;
  172. unsigned char isLoop;
  173. BezierSplineSegment3* segments;
  174. } BezierSpline3;
  175. typedef struct BezierSplineSegment2 {
  176. Vector2 e, c; // end and control
  177. struct BezierSplineSegment2* next;
  178. } BezierSplineSegment2;
  179. typedef struct {
  180. int length;
  181. unsigned char isLoop;
  182. BezierSplineSegment2* segments;
  183. } BezierSpline2;
  184. typedef struct {
  185. Vector3 n; // normal
  186. float d; // distance along normal from the origin
  187. } Plane;
  188. typedef struct {
  189. Vector3 n; // normal
  190. Vector3 p; // an arbitrary point on the plane
  191. } PlaneP;
  192. typedef struct {
  193. Vector3 center;
  194. float r;
  195. } Sphere;
  196. typedef struct {
  197. Vector3 a, b; // the two centroids
  198. float r; // radius
  199. } Capsule;
  200. typedef struct {
  201. Plane planes[6]; // near, far, sides[4]
  202. Vector3 points[8]; // near then far
  203. } Frustum;
  204. typedef struct {
  205. Vector2i v[4]; // in a loop
  206. } Quad2i;
  207. typedef struct {
  208. Vector2 v[4]; // in a loop
  209. } Quad2;
  210. typedef struct { // does not have to be coplanar
  211. Vector3 v[4]; // in a loop
  212. } Quad3;
  213. typedef struct {
  214. Vector2 c1, c2; // opposite corners
  215. } Rect2;
  216. /* Column-major, for OpenGL compatibility:
  217. _ _
  218. | 0 4 8 12 |
  219. | 1 5 9 13 |
  220. | 2 6 10 14 |
  221. |_ 3 7 11 15 _|
  222. */
  223. typedef struct {
  224. float m[16];
  225. } Matrix;
  226. typedef struct MatrixStack {
  227. short size;
  228. short top;
  229. Matrix* stack;
  230. } MatrixStack;
  231. // Symmetric matrix
  232. /* Column-major, for OpenGL compatibility:
  233. _ _
  234. | 0 1 3 6 |
  235. | 2 4 7 |
  236. | 5 8 |
  237. |_ 9 _|
  238. ==
  239. _ _
  240. | 0 1 3 6 |
  241. | 1 2 4 7 |
  242. | 3 4 5 8 |
  243. |_ 6 7 8 9 _|
  244. */
  245. typedef struct {
  246. float m[10];
  247. } MatrixSym;
  248. // 3x3 matrix
  249. /* Column-major, for OpenGL compatibility:
  250. _ _
  251. | 0 3 6 |
  252. | 1 4 7 |
  253. |_ 2 5 8 _|
  254. */
  255. typedef struct {
  256. float m[9];
  257. } Matrix3;
  258. // 2x2 matrix
  259. /* Column-major, for OpenGL compatibility:
  260. _ _
  261. | 0 2 |
  262. |_ 1 3 _|
  263. */
  264. typedef struct {
  265. float m[4];
  266. } Matrix2;
  267. // axis-aligned bounding box
  268. #define X(sz, suf, t, ...) \
  269. typedef struct AABB ## suf { \
  270. Vector ## suf min, max; \
  271. } AABB ## suf;
  272. C3DLAS_VECTOR_LIST(X)
  273. #undef X
  274. typedef struct {
  275. uint64_t state, stream;
  276. } PCG;
  277. extern const Matrix IDENT_MATRIX;
  278. extern const Matrix3 IDENT_MATRIX3;
  279. // utilities
  280. uint32_t bitReverse32(uint32_t x);
  281. uint32_t reverseBits(uint32_t n, int len);
  282. // returns a random number in (-1, 1) uninclusive
  283. float pcg_f(uint64_t* state, uint64_t stream);
  284. // returns a random number in [0, UINT32_MAX] inclusive
  285. uint32_t pcg_u32(uint64_t* state, uint64_t stream);
  286. float frandPCG(float low, float high, PCG* pcg);
  287. #ifndef C3DLAS_NO_LIBC_RAND
  288. static inline float frand(float low, float high) {
  289. return low + ((high - low) * ((float)rand() / (float)RAND_MAX));
  290. }
  291. static inline float frandNorm(void) {
  292. return ((float)rand() / (float)RAND_MAX);
  293. }
  294. static inline float frandNorm2(void) {
  295. return ((float)rand() / (float)RAND_MAX) * 2.0 - 1.0;
  296. }
  297. static inline double drand(double low, double high) {
  298. return low + ((high - low) * ((double)rand() / (double)RAND_MAX));
  299. }
  300. static inline double drandNorm(void) {
  301. return ((double)rand() / (double)RAND_MAX);
  302. }
  303. #endif
  304. static inline float fclamp(float val, float min, float max) {
  305. return fminf(max, fmaxf(min, val));
  306. }
  307. static inline double dclamp(double val, double min, double max) {
  308. return fmin(max, fmax(min, val));
  309. }
  310. static inline float fclampNorm(float val) {
  311. return fclamp(val, 0.0f, 1.0f);
  312. }
  313. static inline double dclampNorm(double val) {
  314. return dclamp(val, 0.0, 1.0);
  315. }
  316. static inline int iclamp(int val, int min, int max) {
  317. return MIN(max, MAX(min, val));
  318. }
  319. static inline long lclamp(long val, long min, long max) {
  320. return MIN(max, MAX(min, val));
  321. }
  322. static inline float flerp(float a, float b, float t) {
  323. return a + ((b - a) * t);
  324. }
  325. static inline double dlerp(double a, double b, double t) {
  326. return a + ((b - a) * t);
  327. }
  328. static inline float flerp2D(float xx, float xy, float yx, float yy, float xt, float yt) {
  329. float a = xx + ((xy - xx) * yt);
  330. float b = yx + ((yy - yx) * yt);
  331. return a + ((b - a) * xt);
  332. }
  333. static inline double dlerp2D(double xx, double xy, double yx, double yy, double xt, double yt) {
  334. double a = xx + ((xy - xx) * yt);
  335. double b = yx + ((yy - yx) * yt);
  336. return a + ((b - a) * xt);
  337. }
  338. static inline float fsmootherstep(float a, float b, float t) {
  339. if(t < 0.f) return a;
  340. if(t > 1.f) return b;
  341. return (b - a) * ((t * (t * 6.0f - 15.0f) + 10.0f) * t * t * t) + a;
  342. }
  343. static inline double dsmootherstep(double a, double b, double t) {
  344. if(t < 0.0) return a;
  345. if(t > 1.0) return b;
  346. return (b - a) * ((t * (t * 6.0 - 15.0) + 10.0) * t * t * t) + a;
  347. }
  348. // Returns an arbitrary unit vector perpendicular to the input
  349. // The input vector does not need to be normalized
  350. void vPerp2p(Vector2* n, Vector2* out);
  351. Vector2 vPerp2(Vector2 n);
  352. void vPerp3p(Vector3* n, Vector3* out);
  353. Vector3 vPerp3(Vector3 n);
  354. //
  355. // Vectors
  356. //
  357. #define X(sz, suf, ty, ft, sufft, ...) \
  358. int vEq##suf(const Vector##suf a, const Vector##suf b); \
  359. int vEq##suf##p(const Vector##suf* a, const Vector##suf* b); \
  360. \
  361. int vEqEp##suf(const Vector##suf a, const Vector##suf b, ft epsilon); \
  362. int vEqEp##suf##p(const Vector##suf* a, const Vector##suf* b, ft epsilon); \
  363. \
  364. int vEqExact##suf(const Vector##suf a, const Vector##suf b); \
  365. int vEqExact##suf##p(const Vector##suf* a, const Vector##suf* b); \
  366. \
  367. Vector##suf vAdd##suf(const Vector##suf a, const Vector##suf b); \
  368. void vAdd##suf##p(const Vector##suf* a, const Vector##suf* b, Vector##suf* out); \
  369. \
  370. Vector##suf vSub##suf(const Vector##suf from, const Vector##suf what); \
  371. void vSub##suf##p(const Vector##suf* from, const Vector##suf* what, Vector##suf* out); \
  372. \
  373. Vector##suf vMul##suf(const Vector##suf a, const Vector##suf b); \
  374. void vMul##suf##p(const Vector##suf* a, const Vector##suf* b, Vector##suf* out); \
  375. \
  376. Vector##suf vDiv##suf(const Vector##suf top, const Vector##suf bot); \
  377. void vDiv##suf##p(const Vector##suf* top, const Vector##suf* bot, Vector##suf* out); \
  378. \
  379. Vector##sufft vScale##suf(const Vector##suf v, ft scalar); \
  380. void vScale##suf##p(const Vector##suf* v, ft scalar, Vector##sufft* out); \
  381. \
  382. Vector##suf vMin##suf(const Vector##suf a, const Vector##suf b); \
  383. void vMin##suf##p(const Vector##suf* a, const Vector##suf* b, Vector##suf* out); \
  384. \
  385. Vector##suf vMax##suf(const Vector##suf a, const Vector##suf b); \
  386. void vMax##suf##p(const Vector##suf* a, const Vector##suf* b, Vector##suf* out); \
  387. \
  388. Vector##suf vClamp##suf(const Vector##suf in, const Vector##suf min, const Vector##suf max); \
  389. void vClamp##suf##p(const Vector##suf* in, const Vector##suf* min, const Vector##suf* max, Vector##suf* out); \
  390. \
  391. int vMinComp##suf(const Vector##suf a); \
  392. int vMinComp##suf##p(const Vector##suf* a); \
  393. \
  394. int vMaxComp##suf(const Vector##suf a); \
  395. int vMaxComp##suf##p(const Vector##suf* a); \
  396. \
  397. ft vDot##suf(const Vector##suf a, const Vector##suf b); \
  398. ft vDot##suf##p(const Vector##suf* a, const Vector##suf* b); \
  399. \
  400. Vector##sufft vAvg##suf(const Vector##suf a, const Vector##suf b); \
  401. void vAvg##suf##p(const Vector##suf* a, const Vector##suf* b, Vector##sufft* out); \
  402. \
  403. ft vDist##suf(const Vector##suf a, const Vector##suf b); \
  404. ft vDist##suf##p(const Vector##suf* a, const Vector##suf* b); \
  405. \
  406. ft vDistSq##suf(const Vector##suf a, const Vector##suf b); \
  407. ft vDistSq##suf##p(const Vector##suf* a, const Vector##suf* b); \
  408. \
  409. Vector##sufft vNorm##suf(const Vector##suf v); \
  410. void vNorm##suf##p(const Vector##suf* v, Vector##sufft* out); \
  411. \
  412. Vector##sufft vUnit##suf(const Vector##suf v); \
  413. void vUnit##suf##p(const Vector##suf* v, Vector##sufft* out); \
  414. \
  415. ft vLen##suf(const Vector##suf v); \
  416. ft vLen##suf##p(const Vector##suf* v); \
  417. ft vMag##suf(const Vector##suf v); \
  418. ft vMag##suf##p(const Vector##suf* v); \
  419. \
  420. ft vLenSq##suf(const Vector##suf v); \
  421. ft vLenSq##suf##p(const Vector##suf* v); \
  422. \
  423. ft vInvLen##suf(const Vector##suf v); \
  424. ft vInvLen##suf##p(const Vector##suf* v); \
  425. \
  426. Vector##suf vAbs##suf(const Vector##suf v); \
  427. void vAbs##suf##p(const Vector##suf* v, Vector##suf* out); \
  428. \
  429. Vector##sufft vRecip##suf(const Vector##suf v); \
  430. void vRecip##suf##p(const Vector##suf* v, Vector##sufft* out); \
  431. Vector##sufft vInv##suf(const Vector##suf v); \
  432. void vInv##suf##p(const Vector##suf* v, Vector##sufft* out); \
  433. \
  434. Vector##suf vNeg##suf(const Vector##suf v); \
  435. void vNeg##suf##p(const Vector##suf* v, Vector##suf* out); \
  436. \
  437. Vector##suf vSign##suf(const Vector##suf v); \
  438. void vSign##suf##p(const Vector##suf* v, Vector##suf* out); \
  439. \
  440. Vector##suf vStep##suf(const Vector##suf edge, const Vector##suf v); \
  441. void vStep##suf##p(const Vector##suf* edge, const Vector##suf* v, Vector##suf* out); \
  442. \
  443. Vector##sufft vLerp##suf(const Vector##suf a, const Vector##suf b, ft t); \
  444. void vLerp##suf##p(const Vector##suf* a, const Vector##suf* b, ft t, Vector##sufft* out); \
  445. \
  446. C3DLAS_VECTOR_LIST(X)
  447. #undef X
  448. #ifndef C3DLAS_NO_SHORT_TYPENAMES
  449. #include "short_macros.h"
  450. #endif
  451. #ifndef C3DLAS_NO_GENERIC_FNS
  452. #include "generic_vectors.h"
  453. #endif
  454. // Swap two vectors
  455. void vSwap2ip(Vector2i* a, Vector2i* b);
  456. void vSwap2p(Vector2* a, Vector2* b);
  457. void vSwap3p(Vector3* a, Vector3* b);
  458. void vSwap4p(Vector4* a, Vector4* b);
  459. // Vector addition
  460. // Vector subtraction. diff = from - what
  461. // Scalar muliplication
  462. //Vector2 vScale2(Vector2 v, float scalar);
  463. //Vector3 vScale3(Vector3 v, float scalar);
  464. //void vScale2ip(Vector2i* v, float scalar, Vector2i* out);
  465. //void vScale2p(Vector2* v, float scalar, Vector2* out);
  466. //void vScale3p(Vector3* v, float scalar, Vector3* out);
  467. // Component-wise vector muliplication
  468. // Cross product: out = a x b
  469. Vector3 vCross3(Vector3 a, Vector3 b);
  470. void vCross3p(Vector3* a, Vector3* b, Vector3* out);
  471. float vCross2(Vector2 a, Vector2 b);
  472. float vCross2p(Vector2* a, Vector2* b);
  473. // Scalar triple product: a . (b x c)
  474. float vScalarTriple3(Vector3 a, Vector3 b, Vector3 c);
  475. float vScalarTriple3p(Vector3* a, Vector3* b, Vector3* c);
  476. // Linear interpolation between two vectors
  477. // Vector Inverse. Returns FLT/DBL_MAX on div/0. Integer functions return double vectors
  478. // Vector magnitude (length)
  479. double vMag2i(const Vector2i v);
  480. float vMag2(const Vector2 v);
  481. float vMag3(const Vector3 v);
  482. float vMag4(const Vector4 v);
  483. double vMag2ip(const Vector2i* v);
  484. float vMag2p(const Vector2* v);
  485. float vMag3p(const Vector3* v);
  486. float vMag4p(const Vector4* v);
  487. // Squared distance from one point to another
  488. Vector4i vFloor4(const Vector4 v);
  489. Vector3i vFloor3(const Vector3 v);
  490. Vector2i vFloor2(const Vector2 v);
  491. Vector4i vCeil4(const Vector4 v);
  492. Vector3i vCeil3(const Vector3 v);
  493. Vector2i vCeil2(const Vector2 v);
  494. Vector4l vFloor4d(const Vector4d v);
  495. Vector3l vFloor3d(const Vector3d v);
  496. Vector2l vFloor2d(const Vector2d v);
  497. Vector4l vCeil4d(const Vector4d v);
  498. Vector3l vCeil3d(const Vector3d v);
  499. Vector2l vCeil2d(const Vector2d v);
  500. Vector2 vModPositive2(Vector2 v, Vector2 m);
  501. Vector3 vModPositive3(Vector3 v, Vector3 m);
  502. Vector4 vModPositive4(Vector4 v, Vector4 m);
  503. Vector2 vClamp2f(Vector2 in, float min, float max);
  504. Vector3 vClamp3f(Vector3 in, float min, float max);
  505. // Cartesian to Spherical
  506. Vector3 vC2S3(Vector3 cart);
  507. // Spherical to Cartesian
  508. Vector3 vS2C3(Vector3 s);
  509. // Distance from a point to a line segment
  510. float vDistPointLine2(Vector2 p, Line2 ls);
  511. float vDistPointLine3(Vector3 p, Line3 ls);
  512. float distPoint2Triangle2(Vector2 a, Vector2 tri[3]);
  513. // Also returns the normalized distance along the line to the closest point
  514. float vDistTPointLine2(Vector2 p, Line2 ls, float* T);
  515. float vDistTPointLine3(Vector3 p, Line3 ls, float* T);
  516. int intersectLine2Line2(Line2 a, Line2 b);
  517. int intersectRect2Rect2(Quad2 a, Quad2 b);
  518. float projPointLine2(Vector2 p, Line2 ls);
  519. float distLineLine3(Line3* a, Line3* b);
  520. Line2 shortestLineFromLineToLine2(Line2* a, Line2* b); // same algorithm as the above, but returns the points instead of their distance
  521. Line3 shortestLineFromLineToLine(Line3* a, Line3* b); // same algorithm as the above, but returns the points instead of their distance
  522. float distLine2Line2(Line2 a, Line2 b);
  523. // Quad *must* be a rectangle, and the vertices must be ordered in a loop
  524. float distLine2Rect2(Line2 a, Quad2 q);
  525. float distPoint2Rect2(Vector2 a, Quad2 q);
  526. float distLine2Triangle2(Line2 a, Vector2 tri[3]);
  527. float distTPointRay3(Vector3 p, Ray3 r, float* T);
  528. float dist2TPointRay3(Vector3 p, Ray3 r, float* T);
  529. int vInsidePolygon(Vector2 p, Polygon* poly);
  530. // Returns the distance from p to the closest point on the polygon.
  531. // Interior distances are negative
  532. float vDistPolygon(Vector2 p, Polygon* poly);
  533. void polyCalcCentroid(Polygon* poly);
  534. void polyCalcRadiusSq(Polygon* poly) ;
  535. void vProject3p(Vector3* what, Vector3* onto, Vector3* out); // slower; onto may not be normalized
  536. void vProjectNorm3p(Vector3* what, Vector3* onto, Vector3* out); // faster; onto must be normalized
  537. void vPointAvg3p(Vector3* a, Vector3* b, Vector3* out);
  538. void vRandomPCG3p(Vector3* end1, Vector3* end2, PCG* pcg, Vector3* out);
  539. Vector3 vRandomPCG3(Vector3 end1, Vector3 end2, PCG* pcg);
  540. void vRandomNormPCG3p(PCG* pcg, Vector3* out);
  541. Vector3 vRandomNormPCG3(PCG* pcg);
  542. void vRandomPCG2p(Vector2* end1, Vector2* end2, PCG* pcg, Vector2* out);
  543. Vector2 vRandomPCG2(Vector2 end1, Vector2 end2, PCG* pcg);
  544. void vRandomNormPCG2p(PCG* pcg, Vector2* out);
  545. Vector2 vRandomNormPCG2(PCG* pcg);
  546. void vRandom3p(Vector3* end1, Vector3* end2, Vector3* out);
  547. Vector3 vRandom3(Vector3 end1, Vector3 end2);
  548. void vRandomNorm3p(Vector3* out);
  549. // http://geomalgorithms.com/a07-_distance.html
  550. // _PARALLEL with no output on parallel lines
  551. // _INTERSECT with one point of output on intersection
  552. // _DISJOINT with two outputs otherwise
  553. int shortestLineFromRayToRay3p(Ray3* r1, Ray3* r2, Vector3* pOut);
  554. // reflects the distance from v to pivot across pivot.
  555. // out, pivot, and v will form a straight line with pivot exactly in the middle.
  556. void vReflectAcross3p(Vector3* v, Vector3* pivot, Vector3* out);
  557. Vector3 vReflectAcross3(Vector3 v, Vector3 pivot);
  558. void vTriFaceNormal3p(Vector3* a, Vector3* b, Vector3* c, Vector3* out); // returns a normalized face normal for the given triangle
  559. Vector3 vTriFaceNormal3(Vector3 a, Vector3 b, Vector3 c);
  560. void vpTriFaceNormal3p(Vector3* tri, Vector3* out); // returns a normalized face normal for the given triangle
  561. Vector3 vTriFaceNormalArea3(Vector3 a, Vector3 b, Vector3 c, float* area); // also provides that triangle's area as a side product
  562. void vProjectOntoPlane3p(Vector3* v, Plane* p, Vector3* out);
  563. void vProjectOntoPlaneNormalized3p(Vector3* v, Plane* p, Vector3* out);
  564. void planeFromPointNormal(Vector3* p, Vector3* norm, Plane* out);
  565. void planeFromTriangle3p(Vector3* v1, Vector3* v2, Vector3* v3, Plane* out); // calculates a plane form a triangle
  566. void planeCopy3p(Plane* in, Plane* out); // copy a plane
  567. void planeInverse3p(Plane* in, Plane* out); // flips the plane's direction
  568. int planeClassifyPoint3p(Plane* p, Vector3* pt); // classifies a point by which side of the plane it's on, default espilon
  569. int planeClassifyPointEps3p(Plane* p, Vector3* pt, float epsilon); // classifies a point by which side of the plane it's on, custom espilon
  570. // closest distance from an arbitrary point to the plane
  571. float planePointDist3p(Plane* pl, Vector3* p);
  572. // signed closest distance from an arbitrary point to the plane
  573. float planePointDistSigned3p(Plane* pl, Vector3* p);
  574. // C3DLAS_INTERSECT, _COPLANAR or _DISJOINT
  575. int planeLineFindIntersect3p(Plane* pl, Vector3* la, Vector3* lb, Vector3* out);
  576. // Assumes full proper intersection.
  577. // C3DLAS_INTERSECT
  578. int planeLineFindIntersectFast3p(Plane* pl, Vector3* la, Vector3* lb, Vector3* out);
  579. // C3DLAS_INTERSECT, _PARALLEL or _DISJOINT
  580. // negative values of idist are "behind" ray->o
  581. int intersectPlaneRay3p(Plane* pl, Ray3* ray, Vector3* ipoint, float* idist);
  582. // https://en.wikipedia.org/wiki/M%C3%B6ller%E2%80%93Trumbore_intersection_algorithm
  583. // returns _INTERSECT or _DISJOINT
  584. int rayTriangleIntersect(
  585. Vector3* a, Vector3* b, Vector3* c, // triangle
  586. Vector3* ray_origin, Vector3* ray_dir, // ray
  587. float* u, float* v, float* t // barycentric out coords, t of intersection point along ray
  588. );
  589. Vector3 triangleClosestPoint(
  590. Vector3* a, Vector3* b, Vector3* c, // triangle
  591. Vector3* p, // test point
  592. float* out_u, float* out_v // barycentric out coords of closest point
  593. );
  594. Vector3 triangleClosestPoint_Reference(
  595. Vector3* a, Vector3* b, Vector3* c, // triangle
  596. Vector3* p, // test point
  597. float* out_u, float* out_v // barycentric out coords of closest point
  598. );
  599. Vector3 baryCoords2(Vector2 p, Vector2 a, Vector2 b, Vector2 c);
  600. // C3DLAS_COPLANAR, _INTERSECT, or _DISJOINT
  601. int triPlaneTestIntersect3p(Vector3* pTri, Plane* pl);
  602. // C3DLAS_COPLANAR, _INTERSECT, or _DISJOINT
  603. int triPlaneClip3p(
  604. Vector3* pTri,
  605. Plane* pl,
  606. Vector3* aboveOut,
  607. Vector3* belowOut,
  608. int* aboveCnt,
  609. int* belowCnt
  610. );
  611. // C3DLAS_COPLANAR, _PARALLEL, _INTERSECT, or _DISJOINT
  612. // aboveCnt and belowCnt are always set.
  613. int linePlaneClip3p(
  614. Vector3* la,
  615. Vector3* lb,
  616. Plane* pl,
  617. Vector3* aboveOut,
  618. Vector3* belowOut,
  619. int* aboveCnt,
  620. int* belowCnt
  621. );
  622. // _INTERSECT, or _DISJOINT
  623. int intersectQuadPoint2(vec2 p, vec2 q[4]);
  624. struct intersectQuadPoint2_precalc {
  625. vec2 ab, ac, db, dc;
  626. vec2 a, d;
  627. float invden_a, invden_d;
  628. };
  629. void intersectQuadPoint2_precalc(vec2 q[4], struct intersectQuadPoint2_precalc* pc);
  630. int intersectQuadPoint2_withprecalc(vec2 p, struct intersectQuadPoint2_precalc* pc);
  631. void frustumCenter(Frustum* f, Vector3* out);
  632. void frustumBoundingSphere(Frustum* f, Sphere* out);
  633. void quadCenterp3p(Vector3* a, Vector3* b, Vector3* c, Vector3* d, Vector3* out);
  634. void frustumFromMatrix(Matrix* m, Frustum* out);
  635. void frustumFromMatrixVK(Matrix* m, Frustum* out);
  636. void frustumFromMatrixVK_ZUP(Matrix* m, Frustum* out);
  637. void frustumFromMatrixVK_RDepth(Matrix* m, Frustum* out);
  638. void frustumFromMatrixVK_ZUP_RDepth(Matrix* m, Frustum* out);
  639. void frustumInnerBoundingSphere(Frustum* f, Sphere* out);
  640. void frustumOuterBoundingSphere(Frustum* f, Sphere* out);
  641. // reflects the distance from v to pivot across pivot.
  642. // out, pivot, and v will form a straight line with pivot exactly in the middle.
  643. void vReflectAcross2p(Vector2* v, Vector2* pivot, Vector2* out);
  644. // degenerate cases may not give desired results. GIGO.
  645. void vRoundAway2p(const Vector2* in, const Vector2* center, Vector2i* out);
  646. void vRoundToward2p(const Vector2* in, const Vector2* center, Vector2i* out);
  647. // returns the *signed* area of a triangle. useful for determining winding
  648. // positive values mean a clockwise triangle
  649. float triArea2p(Vector2* a, Vector2* b, Vector2* c);
  650. // determines if a point is inside a triangle
  651. int triPointInside2p(Vector2* p, Vector2* a, Vector2* b, Vector2* c);
  652. void mIdent3(Matrix3* m);
  653. // out cannot overlap with a or b
  654. // with restrict and -O2, this vectorizes nicely.
  655. void mFastMul3(Matrix3* restrict a, Matrix3* restrict b, Matrix3* restrict out);
  656. void mMul3(Matrix3* a, Matrix3* out);
  657. float mDeterminate3(Matrix3* m);
  658. void mInverse3(Matrix3* m, Matrix3* out);
  659. void mScalarMul3(Matrix3* m, float scalar, Matrix3* out);
  660. Vector3 vMatrix3Mul(Vector3 v, Matrix3* restrict m);
  661. void mTranspose3(Matrix3* m, Matrix3* out);
  662. float mTrace3(Matrix3* m); // sum of the diagonal elements
  663. float pvDist3p(Plane* p, Vector3* v);
  664. void vMatrixMul3p(Vector3* in, Matrix* m, Vector3* out); // multiply a vector by a matrix
  665. void vMatrixMulf3p(float x, float y, float z, Matrix* m, Vector3* out); // multiply a vector by a matrix
  666. Vector3 vMatrixMul3(Vector3 in, Matrix* m);
  667. Vector4 vMatrixMul4(Vector4 in, Matrix* m);
  668. Vector3 vMatrixMulProjectedMagic3(Vector3 in, Matrix* m);
  669. // These are 3d spatial operations
  670. void mIdent(Matrix* m); // set m to the identity matrix
  671. void mCopy(Matrix* in, Matrix* out);
  672. void mFastMul(Matrix* a, Matrix* b, Matrix* out); // a and b cannot also be out. mostly internal use.
  673. void mMul(Matrix* a, Matrix* out); // makes a copy of out before multiplying over it
  674. void mTransv(Vector3* v, Matrix* out); // translation
  675. void mTrans3f(float x, float y, float z, Matrix* out); // translation
  676. void mScalev(Vector3* v, Matrix* out);
  677. void mScale3f(float x, float y, float z, Matrix* out);
  678. void mRotv(Vector3* v, float theta, Matrix* out); // rotate about a vector
  679. //void mRotq(Vector3* v, float theta, Matrix* out); // rotate by a Quaternion
  680. void mRot3f(float x, float y, float z, float theta, Matrix* out); // rotate about a vector
  681. void mRotX(float theta, Matrix* out); //
  682. void mRotY(float theta, Matrix* out); // rotate about axes
  683. void mRotZ(float theta, Matrix* out); //
  684. void mTranspose(Matrix* in, Matrix* out);
  685. void mTransposeFast(Matrix* in, Matrix* out); // in cannot be out
  686. float mDeterminate(Matrix* m);
  687. int mInverse(Matrix* in, Matrix* out); // returns 0 on success, 1 if there is no inverse; out remains unchanged
  688. float mTrace(Matrix* m); // sum of the diagonal elements
  689. // removes translation, scale and perspective
  690. void mRotationOnly(Matrix* in, Matrix* out);
  691. // simple component-wise mathematical operations
  692. void mAdd(Matrix* a, Matrix* b, Matrix* out);
  693. void mScalarMul(Matrix* a, float f, Matrix* out);
  694. void mDecompose(Matrix* mat, Vector3* trans, Quaternion* rot, Vector3* scale);
  695. void mRecompose(Vector3* trans, Quaternion* rot, Vector3* scale, Matrix* out);
  696. // analogous to glFrustum
  697. // no div/0 checking here for right == left etc. just don't be an idiot.
  698. void mFrustum(float left, float right, float top, float bottom, float near, float far, Matrix* out);
  699. // analogous to gluPerspective
  700. // same div/0 warnings apply. if you get an FP exception you deserve it.
  701. // https://www.opengl.org/archives/resources/faq/technical/transformations.htm
  702. // https://www.opengl.org/sdk/docs/man2/xhtml/gluPerspective.xml
  703. void mPerspective(float fov, float aspect, float near, float far, Matrix* out);
  704. // analogous to gluPerspective
  705. // same div/0 warnings apply. if you get an FP exception you deserve it.
  706. void mPerspectiveVK(float fov, float aspect, float near, float far, Matrix* out);
  707. void mPerspectiveVK_ZUp(float fov, float aspect, float near, float far, Matrix* out);
  708. // extract the near and far planes from a prespective matrix
  709. void mPerspExtractNF(Matrix* m, double* near, double* far);
  710. // set the near and far planes for an existing prespective matrix
  711. void mPerspSetNF(Matrix* m, float near, float far);
  712. void mPerspSetNFVK(Matrix* m, float near, float far);
  713. void mPerspSetNF_ZUp(Matrix* m, float near, float far);
  714. void mPerspSetNF_ZUp_RDepth(Matrix* m, float near, float far);
  715. void mPerspSetNFVK_ZUp(Matrix* m, float near, float far);
  716. void mPerspSetNFVK_ZUp_RDepth(Matrix* m, float near, float far);
  717. // orthographic projection. use this for a "2D" look.
  718. // same div/0 warnings.
  719. void mOrtho(float left, float right, float top, float bottom, float near, float far, Matrix* out);
  720. // orthographic projection. use this for a "2D" look.
  721. void mOrthoVK(float left, float right, float top, float bottom, float near, float far, Matrix* out);
  722. // calculates a cubical orthographic matrix with a side length of 2*r
  723. void mOrthoFromRadius(float r, Matrix* out);
  724. // calculates a cubical orthographic matrix with a side length of 2*r
  725. void mOrthoFromRadiusVK(float r, Matrix* out);
  726. // calculates an orthographic matrix that encloses the sphere, looking from eyePos
  727. void mOrthoFromSphere(Sphere s, Vector3 eyePos, Vector3 up, Matrix* out);
  728. // calculates an orthographic matrix that encloses the sphere, looking from eyePos
  729. void mOrthoFromSphereVK(Sphere s, Vector3 eyePos, Vector3 up, Matrix* out);
  730. // extract the planes from an orthographic projection matrix.
  731. void mOrthoExtractPlanes(Matrix* m, float* left, float* right, float* top, float* bottom, float* near, float* far);
  732. // extract the planes from an orthographic projection matrix.
  733. void mOrthoExtractPlanesVK(Matrix* m, float* left, float* right, float* top, float* bottom, float* near, float* far);
  734. void mOrthoSetNF(Matrix* m, float near, float far);
  735. void mOrthoSetNFVK(Matrix* m, float near, float far);
  736. // analgous to gluLookAt
  737. // up is not required to be orthogonal to anything, so long as it's not parallel to anything
  738. // http://www.songho.ca/opengl/gl_camera.html#lookat
  739. void mLookAt(Vector3 eye, Vector3 center, Vector3 up, Matrix* out);
  740. void mLookDir(Vector3 eye, Vector3 dir, Vector3 up, Matrix* out);
  741. void mPrint(Matrix* m, void* arg);
  742. // matrix stack functions
  743. // make sure you allocate enough. when it's out, it's out. no surprise mallocs later on. (yet)
  744. void msAlloc(int size, MatrixStack* ms);
  745. void msFree(MatrixStack* ms);
  746. int msPush(MatrixStack* ms);
  747. void msPop(MatrixStack* ms);
  748. Matrix* msGetTop(MatrixStack* ms);
  749. void msPrintAll(MatrixStack* ms, void* f);
  750. // these are all wrappers around the functions listed above
  751. void msIdent(MatrixStack* ms); // set to the identity matrix
  752. void msCopy(Matrix* in, MatrixStack* ms);
  753. void msMul(Matrix* a, MatrixStack* ms); // makes a copy of out before multiplying over it
  754. void msTransv(Vector3* v, MatrixStack* ms); // translation
  755. void msTrans3f(float x, float y, float z, MatrixStack* ms); // translation
  756. void msScalev(Vector3* v, MatrixStack* ms);
  757. void msScale3f(float x, float y, float z, MatrixStack* ms);
  758. void msRotv(Vector3* v, float theta, MatrixStack* ms); // rotate about a vector
  759. void msRot3f(float x, float y, float z, float theta, MatrixStack* ms); // rotate about a vector
  760. void msFrustum(float left, float right, float top, float bottom, float near, float far, MatrixStack* ms);
  761. void msPerspective(double fov, float aspect, float near, float far, MatrixStack* ms);
  762. void msOrtho(float left, float right, float top, float bottom, float near, float far, MatrixStack* ms);
  763. void msLookAt(Vector3* eye, Vector3* center, Vector3* up, MatrixStack* ms);
  764. // cubic Bezier curves
  765. void evalBezier3p(Vector3* e1, Vector3* e2, Vector3* c1, Vector3* c2, float t, Vector3* out);
  766. void evalBezierTangent3p(Vector3* e1, Vector3* e2, Vector3* c1, Vector3* c2, float t, Vector3* out); // tangent vector; not normalized
  767. void evalBezierNorm3p(Vector3* e1, Vector3* e2, Vector3* c1, Vector3* c2, float t, Vector3* out); // normal vector; not normalized
  768. float evalBezier1D(float e1, float e2, float c1, float c2, float t);
  769. float evalBezier1D_dt(float e1, float e2, float c1, float c2, float t); // first derivative with respect to t
  770. float evalBezier1D_ddt(float e1, float e2, float c1, float c2, float t); // second derivative with respect to t
  771. // quadratic Bezier curves
  772. float evalQBezier1D(float e1, float e2, float c1, float t);
  773. void evalQBezier2D3p(Vector2* e1, Vector2* e2, Vector2* c1, float t, Vector2* out);
  774. void evalQBezier3p(Vector3* e1, Vector3* e2, Vector3* c1, float t, Vector3* out);
  775. ///// bounding box functions
  776. // 3D versions
  777. int boxDisjoint3p(const AABB3* a, const AABB3* b);
  778. int boxOverlaps3p(const AABB3* a, const AABB3* b);
  779. int boxContainsPoint3p(const AABB3* b, const Vector3* p);
  780. bool boxContainsPoint3(AABB3 b, Vector3 p);
  781. AABB3 boxUnion(AABB3 a, AABB3 b);
  782. Vector3 boxCenter3(const AABB3 b); // calculates the center of the box
  783. void boxCenter3p(const AABB3* b, Vector3* out); // calculates the center of the box
  784. Vector2 boxSize2(const AABB2 b); // calculates the size of the box
  785. Vector3 boxSize3(const AABB3 b); // calculates the size of the box
  786. void boxSize2p(const AABB2* b, Vector2* out); // calculates the size of the box
  787. void boxSize3p(const AABB3* b, Vector3* out); // calculates the size of the box
  788. void boxExpandTo3p(AABB3* b, Vector3* p);
  789. void boxExpandTo3(AABB3* b, Vector3 p);
  790. int boxClipRay(AABB3* b, Ray3 r, Line3* out); // returns _INTERSECT or _DISJOINT
  791. void makeRay3p(Vector3* origin, Vector3* direction, Ray3* out);
  792. int boxRayIntersectFast3p(const AABB3* b, const Ray3* r);
  793. int boxRayIntersect3p(const AABB3* b, const Ray3* r, Vector3* ipoint, float* idist);
  794. int intersectBoxLine3p(const AABB3* b, const Line3* l, Vector3* ipoint, float* idist);
  795. int intersectBoxLine3(AABB3 b, Line3 l, Vector3* ipoint, float* idist);
  796. // 2D versions
  797. int boxDisjoint2p(const AABB2* a, const AABB2* b);
  798. int boxOverlaps2p(const AABB2* a, const AABB2* b);
  799. int boxContainsPoint2p(const AABB2* b, const Vector2* p);
  800. void boxCenter2p(const AABB2* b, Vector2* out); // calcuates the center of the box
  801. void boxSize2p(const AABB2* b, Vector2* out); // calculates the size of the box
  802. void boxQuadrant2p(const AABB2* in, char ix, char iy, AABB2* out);
  803. // 2D integer versions
  804. int boxDisjoint2ip(const AABB2i* a, const AABB2i* b);
  805. int boxOverlaps2ip(const AABB2i* a, const AABB2i* b);
  806. int boxContainsPoint2ip(const AABB2i* b, const Vector2i* p);
  807. void boxCenter2ip(const AABB2i* b, Vector2* out); // calcuates the center of the box
  808. void boxSize2ip(const AABB2i* b, Vector2* out); // calculates the size of the box
  809. void boxQuadrant2ip(const AABB2i* in, char ix, char iy, AABB2i* out);
  810. // find the center of a quad
  811. void quadCenter2p(const Quad2* in, Vector2* out);
  812. void quadRoundOutward2p(const Quad2* in, Quad2i* out);
  813. void quadRoundInward2p(const Quad2* in, Quad2i* out);
  814. float evalCatmullRom1D(float t, float a, float b, float c, float d);
  815. Vector2 evalCatmullRom2D(float t, Vector2 a, Vector2 b, Vector2 c, Vector2 d);
  816. Vector3 evalCatmullRom3D(float t, Vector3 a, Vector3 b, Vector3 c, Vector3 d);
  817. float evalCatmullRom1D_dt(float t, float a, float b, float c, float d);
  818. Vector2 evalCatmullRom2D_dt(float t, Vector2 a, Vector2 b, Vector2 c, Vector2 d);
  819. Vector3 evalCatmullRom3D_dt(float t, Vector3 a, Vector3 b, Vector3 c, Vector3 d);
  820. float evalCatmullRom1D_both(float t, float a, float b, float c, float d, float* dt);
  821. Vector2 evalCatmullRom2D_both(float t, Vector2 a, Vector2 b, Vector2 c, Vector2 d, Vector2* dt);
  822. Vector3 evalCatmullRom3D_both(float t, Vector3 a, Vector3 b, Vector3 c, Vector3 d, Vector3* dt);
  823. float evalCubicHermite1D(float t, float p0, float p1, float m0, float m1);
  824. Vector2 evalCubicHermite2D(float t, Vector2 p0, Vector2 p1, Vector2 m0, Vector2 m1);
  825. Vector3 evalCubicHermite3D(float t, Vector3 p0, Vector3 p1, Vector3 m0, Vector3 m1);
  826. Quaternion qFromRTheta(Vector3 r, float theta);
  827. void qToRTheta(Quaternion q, Vector3* r, float* theta);
  828. Quaternion qAdd(Quaternion l, Quaternion r);
  829. Quaternion qSub(Quaternion l, Quaternion r);
  830. Quaternion qScale(Quaternion q, float s);
  831. Quaternion qMul(Quaternion l, Quaternion r);
  832. Quaternion qDiv(Quaternion n, Quaternion d);
  833. Quaternion qRot(Quaternion l, Quaternion r);
  834. Vector3 qRot3(Vector3 a, Quaternion r);
  835. Vector2 qRot2(Vector2 a, Quaternion r);
  836. Quaternion qConj(Quaternion q);
  837. Quaternion qInv(Quaternion q);
  838. Quaternion qNorm(Quaternion q);
  839. Quaternion qSlerp(Quaternion a, Quaternion b, float t);
  840. Quaternion qNlerp(Quaternion a, Quaternion b, float t);
  841. float qAngleBetween(Quaternion a, Quaternion b);
  842. // these appear to all mean the same thing for quaternions.
  843. float qMod(Quaternion q);
  844. float qMag(Quaternion q);
  845. float qLen(Quaternion q);
  846. Quaternion qFromBasis(Vector3 bx, Vector3 by, Vector3 bz);
  847. // Applies the full conjugate multiplication qvq*
  848. void qNonUnitToMatrix(Quaternion q, Matrix* out);
  849. // faster
  850. void qUnitToMatrix3(Quaternion q, Matrix3* out);
  851. void qUnitToMatrix(Quaternion q, Matrix* out);
  852. //
  853. // Algorithms
  854. //
  855. // calls the output fn once for every cell that the line crosses, in no particular order.
  856. // return a non-zero value from the output fn to stop iteration
  857. // returns 0 if all cells were scanned, 1 if the user stopped iteration early.
  858. int rasterizeLine2d(Vector2 pa, Vector2 pb, float cellSize, int (*found)(void* userData, int64_t x, int64_t y), void* userData);
  859. // conservative overestimation; the ends are square, not conformed to the radius
  860. int rasterizeFatLine2d(Vector2 pa, Vector2 pb, float width, float cellSize, int (*found)(void* userData, int64_t x, int64_t y), void* userData);
  861. #endif // __c3dlas_h__