c3dlas.h 35 KB

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