c3dlas.h 37 KB

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