c3dlas.h 37 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104
  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. // Quad *must* be a rectangle, and the vertices must be ordered in a loop
  523. float distLine2Rect2(Line2 a, Quad2 q);
  524. float distPoint2Rect2(Vector2 a, Quad2 q);
  525. float distLine2Triangle2(Line2 a, Vector2 tri[3]);
  526. float distTPointRay3(Vector3 p, Ray3 r, float* T);
  527. float dist2TPointRay3(Vector3 p, Ray3 r, float* T);
  528. int vInsidePolygon(Vector2 p, Polygon* poly);
  529. // Returns the distance from p to the closest point on the polygon.
  530. // Interior distances are negative
  531. float vDistPolygon(Vector2 p, Polygon* poly);
  532. void polyCalcCentroid(Polygon* poly);
  533. void polyCalcRadiusSq(Polygon* poly) ;
  534. void vProject3p(Vector3* what, Vector3* onto, Vector3* out); // slower; onto may not be normalized
  535. void vProjectNorm3p(Vector3* what, Vector3* onto, Vector3* out); // faster; onto must be normalized
  536. void vPointAvg3p(Vector3* a, Vector3* b, Vector3* out);
  537. void vRandomPCG3p(Vector3* end1, Vector3* end2, PCG* pcg, Vector3* out);
  538. Vector3 vRandomPCG3(Vector3 end1, Vector3 end2, PCG* pcg);
  539. void vRandomNormPCG3p(PCG* pcg, Vector3* out);
  540. Vector3 vRandomNormPCG3(PCG* pcg);
  541. void vRandomPCG2p(Vector2* end1, Vector2* end2, PCG* pcg, Vector2* out);
  542. Vector2 vRandomPCG2(Vector2 end1, Vector2 end2, PCG* pcg);
  543. void vRandomNormPCG2p(PCG* pcg, Vector2* out);
  544. Vector2 vRandomNormPCG2(PCG* pcg);
  545. void vRandom3p(Vector3* end1, Vector3* end2, Vector3* out);
  546. Vector3 vRandom3(Vector3 end1, Vector3 end2);
  547. void vRandomNorm3p(Vector3* out);
  548. // http://geomalgorithms.com/a07-_distance.html
  549. // _PARALLEL with no output on parallel lines
  550. // _INTERSECT with one point of output on intersection
  551. // _DISJOINT with two outputs otherwise
  552. int shortestLineFromRayToRay3p(Ray3* r1, Ray3* r2, Vector3* pOut);
  553. // reflects the distance from v to pivot across pivot.
  554. // out, pivot, and v will form a straight line with pivot exactly in the middle.
  555. void vReflectAcross3p(Vector3* v, Vector3* pivot, Vector3* out);
  556. Vector3 vReflectAcross3(Vector3 v, Vector3 pivot);
  557. void vTriFaceNormal3p(Vector3* a, Vector3* b, Vector3* c, Vector3* out); // returns a normalized face normal for the given triangle
  558. Vector3 vTriFaceNormal3(Vector3 a, Vector3 b, Vector3 c);
  559. void vpTriFaceNormal3p(Vector3* tri, Vector3* out); // returns a normalized face normal for the given triangle
  560. Vector3 vTriFaceNormalArea3(Vector3 a, Vector3 b, Vector3 c, float* area); // also provides that triangle's area as a side product
  561. void vProjectOntoPlane3p(Vector3* v, Plane* p, Vector3* out);
  562. void vProjectOntoPlaneNormalized3p(Vector3* v, Plane* p, Vector3* out);
  563. void planeFromPointNormal(Vector3* p, Vector3* norm, Plane* out);
  564. void planeFromTriangle3p(Vector3* v1, Vector3* v2, Vector3* v3, Plane* out); // calculates a plane form a triangle
  565. void planeCopy3p(Plane* in, Plane* out); // copy a plane
  566. void planeInverse3p(Plane* in, Plane* out); // flips the plane's direction
  567. int planeClassifyPoint3p(Plane* p, Vector3* pt); // classifies a point by which side of the plane it's on, default espilon
  568. int planeClassifyPointEps3p(Plane* p, Vector3* pt, float epsilon); // classifies a point by which side of the plane it's on, custom espilon
  569. // closest distance from an arbitrary point to the plane
  570. float planePointDist3p(Plane* pl, Vector3* p);
  571. // signed closest distance from an arbitrary point to the plane
  572. float planePointDistSigned3p(Plane* pl, Vector3* p);
  573. // C3DLAS_INTERSECT, _COPLANAR or _DISJOINT
  574. int planeLineFindIntersect3p(Plane* pl, Vector3* la, Vector3* lb, Vector3* out);
  575. // Assumes full proper intersection.
  576. // C3DLAS_INTERSECT
  577. int planeLineFindIntersectFast3p(Plane* pl, Vector3* la, Vector3* lb, Vector3* out);
  578. // C3DLAS_INTERSECT, _PARALLEL or _DISJOINT
  579. // negative values of idist are "behind" ray->o
  580. int intersectPlaneRay3p(Plane* pl, Ray3* ray, Vector3* ipoint, float* idist);
  581. // https://en.wikipedia.org/wiki/M%C3%B6ller%E2%80%93Trumbore_intersection_algorithm
  582. // returns _INTERSECT or _DISJOINT
  583. int rayTriangleIntersect(
  584. Vector3* a, Vector3* b, Vector3* c, // triangle
  585. Vector3* ray_origin, Vector3* ray_dir, // ray
  586. float* u, float* v, float* t // barycentric out coords, t of intersection point along ray
  587. );
  588. Vector3 triangleClosestPoint(
  589. Vector3* a, Vector3* b, Vector3* c, // triangle
  590. Vector3* p, // test point
  591. float* out_u, float* out_v // barycentric out coords of closest point
  592. );
  593. Vector3 triangleClosestPoint_Reference(
  594. Vector3* a, Vector3* b, Vector3* c, // triangle
  595. Vector3* p, // test point
  596. float* out_u, float* out_v // barycentric out coords of closest point
  597. );
  598. // C3DLAS_COPLANAR, _INTERSECT, or _DISJOINT
  599. int triPlaneTestIntersect3p(Vector3* pTri, Plane* pl);
  600. // C3DLAS_COPLANAR, _INTERSECT, or _DISJOINT
  601. int triPlaneClip3p(
  602. Vector3* pTri,
  603. Plane* pl,
  604. Vector3* aboveOut,
  605. Vector3* belowOut,
  606. int* aboveCnt,
  607. int* belowCnt
  608. );
  609. // C3DLAS_COPLANAR, _PARALLEL, _INTERSECT, or _DISJOINT
  610. // aboveCnt and belowCnt are always set.
  611. int linePlaneClip3p(
  612. Vector3* la,
  613. Vector3* lb,
  614. Plane* pl,
  615. Vector3* aboveOut,
  616. Vector3* belowOut,
  617. int* aboveCnt,
  618. int* belowCnt
  619. );
  620. void frustumCenter(Frustum* f, Vector3* out);
  621. void frustumBoundingSphere(Frustum* f, Sphere* out);
  622. void quadCenterp3p(Vector3* a, Vector3* b, Vector3* c, Vector3* d, Vector3* out);
  623. void frustumFromMatrix(Matrix* m, Frustum* out);
  624. void frustumFromMatrixVK(Matrix* m, Frustum* out);
  625. void frustumFromMatrixVK_ZUP(Matrix* m, Frustum* out);
  626. void frustumFromMatrixVK_RDepth(Matrix* m, Frustum* out);
  627. void frustumFromMatrixVK_ZUP_RDepth(Matrix* m, Frustum* out);
  628. void frustumInnerBoundingSphere(Frustum* f, Sphere* out);
  629. void frustumOuterBoundingSphere(Frustum* f, Sphere* out);
  630. // reflects the distance from v to pivot across pivot.
  631. // out, pivot, and v will form a straight line with pivot exactly in the middle.
  632. void vReflectAcross2p(Vector2* v, Vector2* pivot, Vector2* out);
  633. // degenerate cases may not give desired results. GIGO.
  634. void vRoundAway2p(const Vector2* in, const Vector2* center, Vector2i* out);
  635. void vRoundToward2p(const Vector2* in, const Vector2* center, Vector2i* out);
  636. // returns the *signed* area of a triangle. useful for determining winding
  637. // positive values mean a clockwise triangle
  638. float triArea2p(Vector2* a, Vector2* b, Vector2* c);
  639. // determines if a point is inside a triangle
  640. int triPointInside2p(Vector2* p, Vector2* a, Vector2* b, Vector2* c);
  641. void mIdent3(Matrix3* m);
  642. // out cannot overlap with a or b
  643. // with restrict and -O2, this vectorizes nicely.
  644. void mFastMul3(Matrix3* restrict a, Matrix3* restrict b, Matrix3* restrict out);
  645. void mMul3(Matrix3* a, Matrix3* out);
  646. float mDeterminate3(Matrix3* m);
  647. void mInverse3(Matrix3* m, Matrix3* out);
  648. void mScalarMul3(Matrix3* m, float scalar, Matrix3* out);
  649. Vector3 vMatrix3Mul(Vector3 v, Matrix3* restrict m);
  650. void mTranspose3(Matrix3* m, Matrix3* out);
  651. float mTrace3(Matrix3* m); // sum of the diagonal elements
  652. float pvDist3p(Plane* p, Vector3* v);
  653. void vMatrixMul3p(Vector3* in, Matrix* m, Vector3* out); // multiply a vector by a matrix
  654. void vMatrixMulf3p(float x, float y, float z, Matrix* m, Vector3* out); // multiply a vector by a matrix
  655. Vector3 vMatrixMul3(Vector3 in, Matrix* m);
  656. Vector4 vMatrixMul4(Vector4 in, Matrix* m);
  657. Vector3 vMatrixMulProjectedMagic3(Vector3 in, Matrix* m);
  658. // These are 3d spatial operations
  659. void mIdent(Matrix* m); // set m to the identity matrix
  660. void mCopy(Matrix* in, Matrix* out);
  661. void mFastMul(Matrix* a, Matrix* b, Matrix* out); // a and b cannot also be out. mostly internal use.
  662. void mMul(Matrix* a, Matrix* out); // makes a copy of out before multiplying over it
  663. void mTransv(Vector3* v, Matrix* out); // translation
  664. void mTrans3f(float x, float y, float z, Matrix* out); // translation
  665. void mScalev(Vector3* v, Matrix* out);
  666. void mScale3f(float x, float y, float z, Matrix* out);
  667. void mRotv(Vector3* v, float theta, Matrix* out); // rotate about a vector
  668. //void mRotq(Vector3* v, float theta, Matrix* out); // rotate by a Quaternion
  669. void mRot3f(float x, float y, float z, float theta, Matrix* out); // rotate about a vector
  670. void mRotX(float theta, Matrix* out); //
  671. void mRotY(float theta, Matrix* out); // rotate about axes
  672. void mRotZ(float theta, Matrix* out); //
  673. void mTranspose(Matrix* in, Matrix* out);
  674. void mTransposeFast(Matrix* in, Matrix* out); // in cannot be out
  675. float mDeterminate(Matrix* m);
  676. int mInverse(Matrix* in, Matrix* out); // returns 0 on success, 1 if there is no inverse; out remains unchanged
  677. float mTrace(Matrix* m); // sum of the diagonal elements
  678. // removes translation, scale and perspective
  679. void mRotationOnly(Matrix* in, Matrix* out);
  680. // simple component-wise mathematical operations
  681. void mAdd(Matrix* a, Matrix* b, Matrix* out);
  682. void mScalarMul(Matrix* a, float f, Matrix* out);
  683. void mDecompose(Matrix* mat, Vector3* trans, Quaternion* rot, Vector3* scale);
  684. void mRecompose(Vector3* trans, Quaternion* rot, Vector3* scale, Matrix* out);
  685. // analogous to glFrustum
  686. // no div/0 checking here for right == left etc. just don't be an idiot.
  687. void mFrustum(float left, float right, float top, float bottom, float near, float far, Matrix* out);
  688. // analogous to gluPerspective
  689. // same div/0 warnings apply. if you get an FP exception you deserve it.
  690. // https://www.opengl.org/archives/resources/faq/technical/transformations.htm
  691. // https://www.opengl.org/sdk/docs/man2/xhtml/gluPerspective.xml
  692. void mPerspective(float fov, float aspect, float near, float far, Matrix* out);
  693. // analogous to gluPerspective
  694. // same div/0 warnings apply. if you get an FP exception you deserve it.
  695. void mPerspectiveVK(float fov, float aspect, float near, float far, Matrix* out);
  696. void mPerspectiveVK_ZUp(float fov, float aspect, float near, float far, Matrix* out);
  697. // extract the near and far planes from a prespective matrix
  698. void mPerspExtractNF(Matrix* m, double* near, double* far);
  699. // set the near and far planes for an existing prespective matrix
  700. void mPerspSetNF(Matrix* m, float near, float far);
  701. void mPerspSetNFVK(Matrix* m, float near, float far);
  702. void mPerspSetNF_ZUp(Matrix* m, float near, float far);
  703. void mPerspSetNF_ZUp_RDepth(Matrix* m, float near, float far);
  704. void mPerspSetNFVK_ZUp(Matrix* m, float near, float far);
  705. void mPerspSetNFVK_ZUp_RDepth(Matrix* m, float near, float far);
  706. // orthographic projection. use this for a "2D" look.
  707. // same div/0 warnings.
  708. void mOrtho(float left, float right, float top, float bottom, float near, float far, Matrix* out);
  709. // orthographic projection. use this for a "2D" look.
  710. void mOrthoVK(float left, float right, float top, float bottom, float near, float far, Matrix* out);
  711. // calculates a cubical orthographic matrix with a side length of 2*r
  712. void mOrthoFromRadius(float r, Matrix* out);
  713. // calculates a cubical orthographic matrix with a side length of 2*r
  714. void mOrthoFromRadiusVK(float r, Matrix* out);
  715. // calculates an orthographic matrix that encloses the sphere, looking from eyePos
  716. void mOrthoFromSphere(Sphere s, Vector3 eyePos, Vector3 up, Matrix* out);
  717. // calculates an orthographic matrix that encloses the sphere, looking from eyePos
  718. void mOrthoFromSphereVK(Sphere s, Vector3 eyePos, Vector3 up, Matrix* out);
  719. // extract the planes from an orthographic projection matrix.
  720. void mOrthoExtractPlanes(Matrix* m, float* left, float* right, float* top, float* bottom, float* near, float* far);
  721. // extract the planes from an orthographic projection matrix.
  722. void mOrthoExtractPlanesVK(Matrix* m, float* left, float* right, float* top, float* bottom, float* near, float* far);
  723. void mOrthoSetNF(Matrix* m, float near, float far);
  724. void mOrthoSetNFVK(Matrix* m, float near, float far);
  725. // analgous to gluLookAt
  726. // up is not required to be orthogonal to anything, so long as it's not parallel to anything
  727. // http://www.songho.ca/opengl/gl_camera.html#lookat
  728. void mLookAt(Vector3 eye, Vector3 center, Vector3 up, Matrix* out);
  729. void mLookDir(Vector3 eye, Vector3 dir, Vector3 up, Matrix* out);
  730. void mPrint(Matrix* m, void* arg);
  731. // matrix stack functions
  732. // make sure you allocate enough. when it's out, it's out. no surprise mallocs later on. (yet)
  733. void msAlloc(int size, MatrixStack* ms);
  734. void msFree(MatrixStack* ms);
  735. int msPush(MatrixStack* ms);
  736. void msPop(MatrixStack* ms);
  737. Matrix* msGetTop(MatrixStack* ms);
  738. void msPrintAll(MatrixStack* ms, void* f);
  739. // these are all wrappers around the functions listed above
  740. void msIdent(MatrixStack* ms); // set to the identity matrix
  741. void msCopy(Matrix* in, MatrixStack* ms);
  742. void msMul(Matrix* a, MatrixStack* ms); // makes a copy of out before multiplying over it
  743. void msTransv(Vector3* v, MatrixStack* ms); // translation
  744. void msTrans3f(float x, float y, float z, MatrixStack* ms); // translation
  745. void msScalev(Vector3* v, MatrixStack* ms);
  746. void msScale3f(float x, float y, float z, MatrixStack* ms);
  747. void msRotv(Vector3* v, float theta, MatrixStack* ms); // rotate about a vector
  748. void msRot3f(float x, float y, float z, float theta, MatrixStack* ms); // rotate about a vector
  749. void msFrustum(float left, float right, float top, float bottom, float near, float far, MatrixStack* ms);
  750. void msPerspective(double fov, float aspect, float near, float far, MatrixStack* ms);
  751. void msOrtho(float left, float right, float top, float bottom, float near, float far, MatrixStack* ms);
  752. void msLookAt(Vector3* eye, Vector3* center, Vector3* up, MatrixStack* ms);
  753. // cubic Bezier curves
  754. void evalBezier3p(Vector3* e1, Vector3* e2, Vector3* c1, Vector3* c2, float t, Vector3* out);
  755. void evalBezierTangent3p(Vector3* e1, Vector3* e2, Vector3* c1, Vector3* c2, float t, Vector3* out); // tangent vector; not normalized
  756. void evalBezierNorm3p(Vector3* e1, Vector3* e2, Vector3* c1, Vector3* c2, float t, Vector3* out); // normal vector; not normalized
  757. float evalBezier1D(float e1, float e2, float c1, float c2, float t);
  758. float evalBezier1D_dt(float e1, float e2, float c1, float c2, float t); // first derivative with respect to t
  759. float evalBezier1D_ddt(float e1, float e2, float c1, float c2, float t); // second derivative with respect to t
  760. // quadratic Bezier curves
  761. float evalQBezier1D(float e1, float e2, float c1, float t);
  762. void evalQBezier2D3p(Vector2* e1, Vector2* e2, Vector2* c1, float t, Vector2* out);
  763. void evalQBezier3p(Vector3* e1, Vector3* e2, Vector3* c1, float t, Vector3* out);
  764. ///// bounding box functions
  765. // 3D versions
  766. int boxDisjoint3p(const AABB3* a, const AABB3* b);
  767. int boxOverlaps3p(const AABB3* a, const AABB3* b);
  768. int boxContainsPoint3p(const AABB3* b, const Vector3* p);
  769. bool boxContainsPoint3(AABB3 b, Vector3 p);
  770. AABB3 boxUnion(AABB3 a, AABB3 b);
  771. Vector3 boxCenter3(const AABB3 b); // calculates the center of the box
  772. void boxCenter3p(const AABB3* b, Vector3* out); // calculates the center of the box
  773. Vector2 boxSize2(const AABB2 b); // calculates the size of the box
  774. Vector3 boxSize3(const AABB3 b); // calculates the size of the box
  775. void boxSize2p(const AABB2* b, Vector2* out); // calculates the size of the box
  776. void boxSize3p(const AABB3* b, Vector3* out); // calculates the size of the box
  777. void boxExpandTo3p(AABB3* b, Vector3* p);
  778. void boxExpandTo3(AABB3* b, Vector3 p);
  779. int boxClipRay(AABB3* b, Ray3 r, Line3* out); // returns _INTERSECT or _DISJOINT
  780. void makeRay3p(Vector3* origin, Vector3* direction, Ray3* out);
  781. int boxRayIntersectFast3p(const AABB3* b, const Ray3* r);
  782. int boxRayIntersect3p(const AABB3* b, const Ray3* r, Vector3* ipoint, float* idist);
  783. int intersectBoxLine3p(const AABB3* b, const Line3* l, Vector3* ipoint, float* idist);
  784. int intersectBoxLine3(AABB3 b, Line3 l, Vector3* ipoint, float* idist);
  785. // 2D versions
  786. int boxDisjoint2p(const AABB2* a, const AABB2* b);
  787. int boxOverlaps2p(const AABB2* a, const AABB2* b);
  788. int boxContainsPoint2p(const AABB2* b, const Vector2* p);
  789. void boxCenter2p(const AABB2* b, Vector2* out); // calcuates the center of the box
  790. void boxSize2p(const AABB2* b, Vector2* out); // calculates the size of the box
  791. void boxQuadrant2p(const AABB2* in, char ix, char iy, AABB2* out);
  792. // 2D integer versions
  793. int boxDisjoint2ip(const AABB2i* a, const AABB2i* b);
  794. int boxOverlaps2ip(const AABB2i* a, const AABB2i* b);
  795. int boxContainsPoint2ip(const AABB2i* b, const Vector2i* p);
  796. void boxCenter2ip(const AABB2i* b, Vector2* out); // calcuates the center of the box
  797. void boxSize2ip(const AABB2i* b, Vector2* out); // calculates the size of the box
  798. void boxQuadrant2ip(const AABB2i* in, char ix, char iy, AABB2i* out);
  799. // find the center of a quad
  800. void quadCenter2p(const Quad2* in, Vector2* out);
  801. void quadRoundOutward2p(const Quad2* in, Quad2i* out);
  802. void quadRoundInward2p(const Quad2* in, Quad2i* out);
  803. float evalCatmullRom1D(float t, float a, float b, float c, float d);
  804. Vector2 evalCatmullRom2D(float t, Vector2 a, Vector2 b, Vector2 c, Vector2 d);
  805. Vector3 evalCatmullRom3D(float t, Vector3 a, Vector3 b, Vector3 c, Vector3 d);
  806. float evalCatmullRom1D_dt(float t, float a, float b, float c, float d);
  807. Vector2 evalCatmullRom2D_dt(float t, Vector2 a, Vector2 b, Vector2 c, Vector2 d);
  808. Vector3 evalCatmullRom3D_dt(float t, Vector3 a, Vector3 b, Vector3 c, Vector3 d);
  809. float evalCatmullRom1D_both(float t, float a, float b, float c, float d, float* dt);
  810. Vector2 evalCatmullRom2D_both(float t, Vector2 a, Vector2 b, Vector2 c, Vector2 d, Vector2* dt);
  811. Vector3 evalCatmullRom3D_both(float t, Vector3 a, Vector3 b, Vector3 c, Vector3 d, Vector3* dt);
  812. float evalCubicHermite1D(float t, float p0, float p1, float m0, float m1);
  813. Vector2 evalCubicHermite2D(float t, Vector2 p0, Vector2 p1, Vector2 m0, Vector2 m1);
  814. Vector3 evalCubicHermite3D(float t, Vector3 p0, Vector3 p1, Vector3 m0, Vector3 m1);
  815. Quaternion qFromRTheta(Vector3 r, float theta);
  816. void qToRTheta(Quaternion q, Vector3* r, float* theta);
  817. Quaternion qAdd(Quaternion l, Quaternion r);
  818. Quaternion qSub(Quaternion l, Quaternion r);
  819. Quaternion qScale(Quaternion q, float s);
  820. Quaternion qMul(Quaternion l, Quaternion r);
  821. Quaternion qDiv(Quaternion n, Quaternion d);
  822. Quaternion qRot(Quaternion l, Quaternion r);
  823. Vector3 qRot3(Vector3 a, Quaternion r);
  824. Vector2 qRot2(Vector2 a, Quaternion r);
  825. Quaternion qConj(Quaternion q);
  826. Quaternion qInv(Quaternion q);
  827. Quaternion qNorm(Quaternion q);
  828. Quaternion qSlerp(Quaternion a, Quaternion b, float t);
  829. Quaternion qNlerp(Quaternion a, Quaternion b, float t);
  830. float qAngleBetween(Quaternion a, Quaternion b);
  831. // these appear to all mean the same thing for quaternions.
  832. float qMod(Quaternion q);
  833. float qMag(Quaternion q);
  834. float qLen(Quaternion q);
  835. Quaternion qFromBasis(Vector3 bx, Vector3 by, Vector3 bz);
  836. // Applies the full conjugate multiplication qvq*
  837. void qNonUnitToMatrix(Quaternion q, Matrix* out);
  838. // faster
  839. void qUnitToMatrix3(Quaternion q, Matrix3* out);
  840. void qUnitToMatrix(Quaternion q, Matrix* out);
  841. //
  842. // Algorithms
  843. //
  844. // calls the output fn once for every cell that the line crosses, in no particular order.
  845. // return a non-zero value from the output fn to stop iteration
  846. // returns 0 if all cells were scanned, 1 if the user stopped iteration early.
  847. int rasterizeLine2d(Vector2 pa, Vector2 pb, float cellSize, int (*found)(void* userData, int64_t x, int64_t y), void* userData);
  848. // conservative overestimation; the ends are square, not conformed to the radius
  849. int rasterizeFatLine2d(Vector2 pa, Vector2 pb, float width, float cellSize, int (*found)(void* userData, int64_t x, int64_t y), void* userData);
  850. #endif // __c3dlas_h__