1
0

quat.h 1.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657
  1. /*
  2. * Copyright (c), Recep Aslantas.
  3. *
  4. * MIT License (MIT), http://opensource.org/licenses/MIT
  5. * Full license can be found in the LICENSE file
  6. */
  7. #ifndef cglm_quat_neon_h
  8. #define cglm_quat_neon_h
  9. #if defined(CGLM_NEON_FP)
  10. #include "../../common.h"
  11. #include "../intrin.h"
  12. CGLM_INLINE
  13. void
  14. glm_quat_mul_neon(versor p, versor q, versor dest) {
  15. /*
  16. + (a1 b2 + b1 a2 + c1 d2 − d1 c2)i
  17. + (a1 c2 − b1 d2 + c1 a2 + d1 b2)j
  18. + (a1 d2 + b1 c2 − c1 b2 + d1 a2)k
  19. a1 a2 − b1 b2 − c1 c2 − d1 d2
  20. */
  21. glmm_128 xp, xq, xqr, r, x, y, z, s2, s3;
  22. glmm_128 s1 = glmm_float32x4_SIGNMASK_NPPN;
  23. float32x2_t qh, ql;
  24. xp = glmm_load(p); /* 3 2 1 0 */
  25. xq = glmm_load(q);
  26. r = vmulq_f32(glmm_splat_w(xp), xq);
  27. x = glmm_splat_x(xp);
  28. y = glmm_splat_y(xp);
  29. z = glmm_splat_z(xp);
  30. ql = vget_high_f32(s1);
  31. s3 = vcombine_f32(ql, ql);
  32. s2 = vzipq_f32(s3, s3).val[0];
  33. xqr = vrev64q_f32(xq);
  34. qh = vget_high_f32(xqr);
  35. ql = vget_low_f32(xqr);
  36. r = glmm_fmadd(glmm_xor(x, s3), vcombine_f32(qh, ql), r);
  37. r = glmm_fmadd(glmm_xor(y, s2), vcombine_f32(vget_high_f32(xq),
  38. vget_low_f32(xq)), r);
  39. r = glmm_fmadd(glmm_xor(z, s1), vcombine_f32(ql, qh), r);
  40. glmm_store(dest, r);
  41. }
  42. #endif
  43. #endif /* cglm_quat_neon_h */