/engine/math/math_transform.c

https://github.com/r-lyeh/AVA · C · 96 lines · 67 code · 16 blank · 13 comment · 0 complexity · 15f22981c0e3d8475a406d50d4d0b7c1 MD5 · raw file

  1. #ifndef TRANSFORM_H
  2. #define TRANSFORM_H
  3. #include "math_linear.c"
  4. // ----------------------------------------------------------------------------
  5. static m_inline vec3 transform33(mat33 m, vec3 p) {
  6. float x = (m[0] * p.x) + (m[4] * p.y) + (m[ 8] * p.z);
  7. float y = (m[1] * p.x) + (m[5] * p.y) + (m[ 9] * p.z);
  8. float z = (m[2] * p.x) + (m[6] * p.y) + (m[10] * p.z);
  9. return vec3(x,y,z);
  10. }
  11. static m_inline vec4 transform444(const mat44 m, const vec4 p) {
  12. // remember w = 1 for move in space; w = 0 rotate in space;
  13. float x = m[0]*p.x + m[4]*p.y + m[ 8]*p.z + m[12]*p.w;
  14. float y = m[1]*p.x + m[5]*p.y + m[ 9]*p.z + m[13]*p.w;
  15. float z = m[2]*p.x + m[6]*p.y + m[10]*p.z + m[14]*p.w;
  16. float w = m[3]*p.x + m[7]*p.y + m[11]*p.z + m[15]*p.w;
  17. return vec4(x,y,z,w);
  18. }
  19. static m_inline vec3 transform344(const mat44 m, const vec3 p) {
  20. vec4 v = transform444(m, vec34(p, 1));
  21. return scale3(v.xyz, 1.f / v.w);
  22. }
  23. static m_inline vec3 transformq(const quat q, const vec3 v) { // !!! ok, i guess
  24. // [src] https://gamedev.stackexchange.com/questions/28395/rotating-vector3-by-a-quaternion (laurent couvidou)
  25. // Extract the vector part of the quaternion
  26. vec3 u = vec3(q.x, q.y, q.z);
  27. // Extract the scalar part of the quaternion
  28. float s = q.w;
  29. // Do the math
  30. vec3 a = scale3(u, 2 * dot3(u,v));
  31. vec3 b = scale3(v, s*s - dot3(u,u));
  32. vec3 c = scale3(cross3(u,v), 2*s);
  33. return add3(a, add3(b,c));
  34. }
  35. static m_inline vec3 transform_axis(const coord_system basis, const coord_axis to) {
  36. const float dot_table[6][6] = {
  37. {+1,-1,0,0,0,0},{-1,+1,0,0,0,0},{0,0,+1,-1,0,0},
  38. {0,0,-1,+1,0,0},{0,0,0,0,+1,-1},{0,0,0,0,-1,+1},
  39. };
  40. return vec3( dot_table[basis.x][to], dot_table[basis.y][to], dot_table[basis.z][to] );
  41. }
  42. // A vector is the difference between two points in 3D space, possessing both direction and magnitude
  43. static m_inline vec3 transform_vector (const mat44 m, const vec3 vector) {
  44. return transform344(m, vector);
  45. }
  46. // A point is a specific location within a 3D space
  47. static m_inline vec3 transform_point (const mat44 m, const vec3 p) { // return (m * vec4{point,1).xyz()/r.w;
  48. float inv = 1.0f / (m[3+4*0]*p.x + m[3+4*1]*p.y + m[3+4*2]*p.z + m[3+4*3]);
  49. return vec3(
  50. (m[0+4*0]*p.x + m[0+4*1]*p.y + m[0+4*2]*p.z + m[0+4*3]) * inv,
  51. (m[1+4*0]*p.x + m[1+4*1]*p.y + m[1+4*2]*p.z + m[1+4*3]) * inv,
  52. (m[2+4*0]*p.x + m[2+4*1]*p.y + m[2+4*2]*p.z + m[2+4*3]) * inv
  53. );
  54. }
  55. // A tangent is a unit-length vector which is parallel to a piece of geometry, such as a surface or a curve
  56. static m_inline vec3 transform_tangent (const mat44 m, const vec3 tangent) { return norm3(transform_vector(m, tangent)); }
  57. // A normal is a unit-length bivector which is perpendicular to a piece of geometry, such as a surface or a curve
  58. static m_inline vec3 transform_normal (const mat44 m, const vec3 normal) {
  59. return transform_tangent(m, normal); // ok?
  60. mat44 t; transpose44(t,m); mat44 i; invert44(i,t);
  61. return scale3(norm3(transform_vector(i, normal)), det44(m) < 0 ? -1.f : 1.f);
  62. }
  63. // A quaternion can describe both a rotation and a uniform scaling in 3D space
  64. static m_inline quat transform_quat (const mat44 m, const quat q) {
  65. vec3 s = scale3(transform_vector(m, q.xyz), det44(m) < 0 ? -1.f : 1.f);
  66. return quat(s.x,s.y,s.z,q.w);
  67. }
  68. // A matrix can describe a general transformation of homogeneous coordinates in projective space
  69. static m_inline float* transform_matrix(mat44 out, const mat44 m, const mat44 matrix) {
  70. mat44 I; invert44(I, m);
  71. multiply344(out, I, matrix, m); // m,matrix,I instead ?
  72. return out;
  73. }
  74. // Scaling factors are not a vector, they are a compact representation of a scaling matrix
  75. static m_inline vec3 transform_scaling (const mat44 m, const vec3 scaling) {
  76. mat44 s; scaling44(s, scaling.x, scaling.y, scaling.z);
  77. mat44 out; transform_matrix(out, m, s);
  78. return vec3( out[0], out[5], out[10] );
  79. }
  80. #endif