omath.c 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397
  1. // Copyright 2013, Fredrik Hultin.
  2. // Copyright 2013, Jakob Bornecrantz.
  3. // SPDX-License-Identifier: BSL-1.0
  4. /*
  5. * OpenHMD - Free and Open Source API and drivers for immersive technology.
  6. */
  7. /* Math Code Implementation */
  8. #include <string.h>
  9. #include "openhmdi.h"
  10. // vector
  11. float ovec3f_get_length(const vec3f* me)
  12. {
  13. return sqrtf(POW2(me->x) + POW2(me->y) + POW2(me->z));
  14. }
  15. void ovec3f_normalize_me(vec3f* me)
  16. {
  17. if(me->x == 0 && me->y == 0 && me->z == 0)
  18. return;
  19. float len = ovec3f_get_length(me);
  20. me->x /= len;
  21. me->y /= len;
  22. me->z /= len;
  23. }
  24. void ovec3f_subtract(const vec3f* a, const vec3f* b, vec3f* out)
  25. {
  26. for(int i = 0; i < 3; i++)
  27. out->arr[i] = a->arr[i] - b->arr[i];
  28. }
  29. float ovec3f_get_dot(const vec3f* me, const vec3f* vec)
  30. {
  31. return me->x * vec->x + me->y * vec->y + me->z * vec->z;
  32. }
  33. float ovec3f_get_angle(const vec3f* me, const vec3f* vec)
  34. {
  35. float dot = ovec3f_get_dot(me, vec);
  36. float lengths = ovec3f_get_length(me) * ovec3f_get_length(vec);
  37. if(lengths == 0)
  38. return 0;
  39. return acosf(dot / lengths);
  40. }
  41. // quaternion
  42. void oquatf_init_axis(quatf* me, const vec3f* vec, float angle)
  43. {
  44. vec3f norm = *vec;
  45. ovec3f_normalize_me(&norm);
  46. me->x = norm.x * sinf(angle / 2.0f);
  47. me->y = norm.y * sinf(angle / 2.0f);
  48. me->z = norm.z * sinf(angle / 2.0f);
  49. me->w = cosf(angle / 2.0f);
  50. }
  51. void oquatf_get_rotated(const quatf* me, const vec3f* vec, vec3f* out_vec)
  52. {
  53. quatf q = {{vec->x * me->w + vec->z * me->y - vec->y * me->z,
  54. vec->y * me->w + vec->x * me->z - vec->z * me->x,
  55. vec->z * me->w + vec->y * me->x - vec->x * me->y,
  56. vec->x * me->x + vec->y * me->y + vec->z * me->z}};
  57. out_vec->x = me->w * q.x + me->x * q.w + me->y * q.z - me->z * q.y;
  58. out_vec->y = me->w * q.y + me->y * q.w + me->z * q.x - me->x * q.z;
  59. out_vec->z = me->w * q.z + me->z * q.w + me->x * q.y - me->y * q.x;
  60. }
  61. void oquatf_mult(const quatf* me, const quatf* q, quatf* out_q)
  62. {
  63. out_q->x = me->w * q->x + me->x * q->w + me->y * q->z - me->z * q->y;
  64. out_q->y = me->w * q->y - me->x * q->z + me->y * q->w + me->z * q->x;
  65. out_q->z = me->w * q->z + me->x * q->y - me->y * q->x + me->z * q->w;
  66. out_q->w = me->w * q->w - me->x * q->x - me->y * q->y - me->z * q->z;
  67. }
  68. void oquatf_mult_me(quatf* me, const quatf* q)
  69. {
  70. quatf tmp = *me;
  71. oquatf_mult(&tmp, q, me);
  72. }
  73. void oquatf_normalize_me(quatf* me)
  74. {
  75. float len = oquatf_get_length(me);
  76. me->x /= len;
  77. me->y /= len;
  78. me->z /= len;
  79. me->w /= len;
  80. }
  81. float oquatf_get_length(const quatf* me)
  82. {
  83. return sqrtf(me->x * me->x + me->y * me->y + me->z * me->z + me->w * me->w);
  84. }
  85. float oquatf_get_dot(const quatf* me, const quatf* q)
  86. {
  87. return me->x * q->x + me->y * q->y + me->z * q->z + me->w * q->w;
  88. }
  89. void oquatf_inverse(quatf* me)
  90. {
  91. float dot = oquatf_get_dot(me, me);
  92. // conjugate
  93. for(int i = 0; i < 3; i++)
  94. me->arr[i] = -me->arr[i];
  95. for(int i = 0; i < 4; i++)
  96. me->arr[i] /= dot;
  97. }
  98. void oquatf_diff(const quatf* me, const quatf* q, quatf* out_q)
  99. {
  100. quatf inv = *me;
  101. oquatf_inverse(&inv);
  102. oquatf_mult(&inv, q, out_q);
  103. }
  104. void oquatf_slerp (float fT, const quatf* rkP, const quatf* rkQ, bool shortestPath, quatf* out_q)
  105. {
  106. float fCos = oquatf_get_dot(rkP, rkQ);
  107. quatf rkT;
  108. // Do we need to invert rotation?
  109. if (fCos < 0.0f && shortestPath)
  110. {
  111. fCos = -fCos;
  112. rkT = *rkQ;
  113. oquatf_inverse(&rkT);
  114. }
  115. else
  116. {
  117. rkT = *rkQ;
  118. }
  119. if (fabsf(fCos) < 1 - 0.001f)
  120. {
  121. // Standard case (slerp)
  122. float fSin = sqrtf(1 - (fCos*fCos));
  123. float fAngle = atan2f(fSin, fCos);
  124. float fInvSin = 1.0f / fSin;
  125. float fCoeff0 = sin((1.0f - fT) * fAngle) * fInvSin;
  126. float fCoeff1 = sin(fT * fAngle) * fInvSin;
  127. out_q->x = fCoeff0 * rkP->x + fCoeff1 * rkT.x;
  128. out_q->y = fCoeff0 * rkP->y + fCoeff1 * rkT.y;
  129. out_q->z = fCoeff0 * rkP->z + fCoeff1 * rkT.z;
  130. out_q->w = fCoeff0 * rkP->w + fCoeff1 * rkT.w;
  131. //return fCoeff0 * rkP + fCoeff1 * rkT;
  132. }
  133. else
  134. {
  135. // There are two situations:
  136. // 1. "rkP" and "rkQ" are very close (fCos ~= +1), so we can do a linear
  137. // interpolation safely.
  138. // 2. "rkP" and "rkQ" are almost inverse of each other (fCos ~= -1), there
  139. // are an infinite number of possibilities interpolation. but we haven't
  140. // have method to fix this case, so just use linear interpolation here.
  141. //Quaternion t = (1.0f - fT) * rkP + fT * rkT;
  142. out_q->x = (1.0f - fT) * rkP->x + fT * rkT.x;
  143. out_q->y = (1.0f - fT) * rkP->y + fT * rkT.y;
  144. out_q->z = (1.0f - fT) * rkP->z + fT * rkT.z;
  145. out_q->w = (1.0f - fT) * rkP->w + fT * rkT.w;
  146. oquatf_normalize_me(out_q);
  147. // taking the complement requires renormalisation
  148. //t.normalise();
  149. //return t;
  150. }
  151. }
  152. void oquatf_get_mat4x4(const quatf* me, const vec3f* point, float mat[4][4])
  153. {
  154. mat[0][0] = 1 - 2 * me->y * me->y - 2 * me->z * me->z;
  155. mat[0][1] = 2 * me->x * me->y - 2 * me->w * me->z;
  156. mat[0][2] = 2 * me->x * me->z + 2 * me->w * me->y;
  157. mat[0][3] = point->x;
  158. mat[1][0] = 2 * me->x * me->y + 2 * me->w * me->z;
  159. mat[1][1] = 1 - 2 * me->x * me->x - 2 * me->z * me->z;
  160. mat[1][2] = 2 * me->y * me->z - 2 * me->w * me->x;
  161. mat[1][3] = point->y;
  162. mat[2][0] = 2 * me->x * me->z - 2 * me->w * me->y;
  163. mat[2][1] = 2 * me->y * me->z + 2 * me->w * me->x;
  164. mat[2][2] = 1 - 2 * me->x * me->x - 2 * me->y * me->y;
  165. mat[2][3] = point->z;
  166. mat[3][0] = 0;
  167. mat[3][1] = 0;
  168. mat[3][2] = 0;
  169. mat[3][3] = 1;
  170. }
  171. // matrix
  172. void omat4x4f_init_ident(mat4x4f* me)
  173. {
  174. memset(me, 0, sizeof(*me));
  175. me->m[0][0] = 1.0f;
  176. me->m[1][1] = 1.0f;
  177. me->m[2][2] = 1.0f;
  178. me->m[3][3] = 1.0f;
  179. }
  180. void omat4x4f_init_perspective(mat4x4f* me, float fovy_rad, float aspect, float znear, float zfar)
  181. {
  182. float sine, cotangent, delta, half_fov;
  183. half_fov = fovy_rad / 2.0f;
  184. delta = zfar - znear;
  185. sine = sinf(half_fov);
  186. if ((delta == 0.0f) || (sine == 0.0f) || (aspect == 0.0f)) {
  187. omat4x4f_init_ident(me);
  188. return;
  189. }
  190. cotangent = cosf(half_fov) / sine;
  191. me->m[0][0] = cotangent / aspect;
  192. me->m[0][1] = 0;
  193. me->m[0][2] = 0;
  194. me->m[0][3] = 0;
  195. me->m[1][0] = 0;
  196. me->m[1][1] = cotangent;
  197. me->m[1][2] = 0;
  198. me->m[1][3] = 0;
  199. me->m[2][0] = 0;
  200. me->m[2][1] = 0;
  201. me->m[2][2] = -(zfar + znear) / delta;
  202. me->m[2][3] = -2.0f * znear * zfar / delta;
  203. me->m[3][0] = 0;
  204. me->m[3][1] = 0;
  205. me->m[3][2] = -1.0f;
  206. me->m[3][3] = 0;
  207. }
  208. void omat4x4f_init_frustum(mat4x4f* me, float left, float right, float bottom, float top, float znear, float zfar)
  209. {
  210. omat4x4f_init_ident(me);
  211. float delta_x = right - left;
  212. float delta_y = top - bottom;
  213. float delta_z = zfar - znear;
  214. if ((delta_x == 0.0f) || (delta_y == 0.0f) || (delta_z == 0.0f)) {
  215. /* can't divide by zero, so just give back identity */
  216. return;
  217. }
  218. me->m[0][0] = 2.0f * znear / delta_x;
  219. me->m[0][1] = 0;
  220. me->m[0][2] = (right + left) / delta_x;
  221. me->m[0][3] = 0;
  222. me->m[1][0] = 0;
  223. me->m[1][1] = 2.0f * znear / delta_y;
  224. me->m[1][2] = (top + bottom) / delta_y;
  225. me->m[1][3] = 0;
  226. me->m[2][0] = 0;
  227. me->m[2][1] = 0;
  228. me->m[2][2] = -(zfar + znear) / delta_z;
  229. me->m[2][3] = -2.0f * zfar * znear / delta_z;
  230. me->m[3][0] = 0;
  231. me->m[3][1] = 0;
  232. me->m[3][2] = -1.0f;
  233. me->m[3][3] = 0;
  234. }
  235. void omat4x4f_init_look_at(mat4x4f* me, const quatf* rot, const vec3f* eye)
  236. {
  237. quatf q;
  238. vec3f p;
  239. q.x = -rot->x;
  240. q.y = -rot->y;
  241. q.z = -rot->z;
  242. q.w = rot->w;
  243. p.x = -eye->x;
  244. p.y = -eye->y;
  245. p.z = -eye->z;
  246. me->m[0][0] = 1 - 2 * q.y * q.y - 2 * q.z * q.z;
  247. me->m[0][1] = 2 * q.x * q.y - 2 * q.w * q.z;
  248. me->m[0][2] = 2 * q.x * q.z + 2 * q.w * q.y;
  249. me->m[0][3] = p.x * me->m[0][0] + p.y * me->m[0][1] + p.z * me->m[0][2];
  250. me->m[1][0] = 2 * q.x * q.y + 2 * q.w * q.z;
  251. me->m[1][1] = 1 - 2 * q.x * q.x - 2 * q.z * q.z;
  252. me->m[1][2] = 2 * q.y * q.z - 2 * q.w * q.x;
  253. me->m[1][3] = p.x * me->m[1][0] + p.y * me->m[1][1] + p.z * me->m[1][2];
  254. me->m[2][0] = 2 * q.x * q.z - 2 * q.w * q.y;
  255. me->m[2][1] = 2 * q.y * q.z + 2 * q.w * q.x;
  256. me->m[2][2] = 1 - 2 * q.x * q.x - 2 * q.y * q.y;
  257. me->m[2][3] = p.x * me->m[2][0] + p.y * me->m[2][1] + p.z * me->m[2][2];
  258. me->m[3][0] = 0;
  259. me->m[3][1] = 0;
  260. me->m[3][2] = 0;
  261. me->m[3][3] = 1;
  262. }
  263. void omat4x4f_init_translate(mat4x4f* me, float x, float y, float z)
  264. {
  265. omat4x4f_init_ident(me);
  266. me->m[0][3] = x;
  267. me->m[1][3] = y;
  268. me->m[2][3] = z;
  269. }
  270. void omat4x4f_transpose(const mat4x4f* m, mat4x4f* o)
  271. {
  272. o->m[0][0] = m->m[0][0];
  273. o->m[1][0] = m->m[0][1];
  274. o->m[2][0] = m->m[0][2];
  275. o->m[3][0] = m->m[0][3];
  276. o->m[0][1] = m->m[1][0];
  277. o->m[1][1] = m->m[1][1];
  278. o->m[2][1] = m->m[1][2];
  279. o->m[3][1] = m->m[1][3];
  280. o->m[0][2] = m->m[2][0];
  281. o->m[1][2] = m->m[2][1];
  282. o->m[2][2] = m->m[2][2];
  283. o->m[3][2] = m->m[2][3];
  284. o->m[0][3] = m->m[3][0];
  285. o->m[1][3] = m->m[3][1];
  286. o->m[2][3] = m->m[3][2];
  287. o->m[3][3] = m->m[3][3];
  288. }
  289. void omat4x4f_mult(const mat4x4f* l, const mat4x4f* r, mat4x4f *o)
  290. {
  291. for(int i = 0; i < 4; i++){
  292. float a0 = l->m[i][0], a1 = l->m[i][1], a2 = l->m[i][2], a3 = l->m[i][3];
  293. o->m[i][0] = a0 * r->m[0][0] + a1 * r->m[1][0] + a2 * r->m[2][0] + a3 * r->m[3][0];
  294. o->m[i][1] = a0 * r->m[0][1] + a1 * r->m[1][1] + a2 * r->m[2][1] + a3 * r->m[3][1];
  295. o->m[i][2] = a0 * r->m[0][2] + a1 * r->m[1][2] + a2 * r->m[2][2] + a3 * r->m[3][2];
  296. o->m[i][3] = a0 * r->m[0][3] + a1 * r->m[1][3] + a2 * r->m[2][3] + a3 * r->m[3][3];
  297. }
  298. }
  299. // filter queue
  300. void ofq_init(filter_queue* me, int size)
  301. {
  302. memset(me, 0, sizeof(filter_queue));
  303. me->size = size;
  304. }
  305. void ofq_add(filter_queue* me, const vec3f* vec)
  306. {
  307. me->elems[me->at] = *vec;
  308. me->at = ((me->at + 1) % me->size);
  309. }
  310. void ofq_get_mean(const filter_queue* me, vec3f* vec)
  311. {
  312. vec->x = vec->y = vec->z = 0;
  313. for(int i = 0; i < me->size; i++){
  314. vec->x += me->elems[i].x;
  315. vec->y += me->elems[i].y;
  316. vec->z += me->elems[i].z;
  317. }
  318. vec->x /= (float)me->size;
  319. vec->y /= (float)me->size;
  320. vec->z /= (float)me->size;
  321. }