/vMath.c

https://github.com/vyasa/asteria · C · 184 lines · 114 code · 44 blank · 26 comment · 1 complexity · 687ba9213dd233c3c02739ac85e3d86f MD5 · raw file

  1. /****************************************************************************
  2. * *
  3. * This file is part of the Asteria project. *
  4. * Copyright (C) 2011 Samuel C. Payson, Akanksha Vyas *
  5. * *
  6. * Asteria is free software: you can redistribute it and/or modify it under *
  7. * the terms of the GNU General Public License as published by the Free *
  8. * Software Foundation, either version 3 of the License, or (at your *
  9. * option) any later version. *
  10. * *
  11. * Asteria is distributed in the hope that it will be useful, but WITHOUT *
  12. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
  13. * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License *
  14. * for more details. *
  15. * *
  16. * You should have received a copy of the GNU General Public License along *
  17. * with Asteria. If not, see <http://www.gnu.org/licenses/>. *
  18. * *
  19. ****************************************************************************/
  20. /* vMath.c */
  21. #include "libInclude.h"
  22. #include "vMath.h"
  23. #include <math.h>
  24. vec3 v3Cross( vec3 a, vec3 b ) {
  25. vec3_u u = { .vec = a },
  26. v = { .vec = b },
  27. ret;
  28. ret.x = ( u.y * v.z ) - ( u.z * v.y );
  29. ret.y = ( u.z * v.x ) - ( u.x * v.z );
  30. ret.z = ( u.x * v.y ) - ( u.y * v.x );
  31. return ret.vec;
  32. }
  33. GLfloat v2Dot( vec2 a, vec2 b ) {
  34. vec2_u tmp2 = { .vec = a * b };
  35. return tmp2.x + tmp2.y;
  36. }
  37. GLfloat v3Dot( vec3 a, vec3 b ) {
  38. vec3_u tmp3 = { .vec = a * b };
  39. return tmp3.x + tmp3.y + tmp3.z;
  40. }
  41. GLfloat v4Dot( vec4 a, vec4 b ) {
  42. vec4_u tmp4 = { .vec = a * b };
  43. return tmp4.x + tmp4.y + tmp4.z + tmp4.w;
  44. }
  45. vec2 v2Normalize( vec2 op ) {
  46. return v2Scale( 1.0f / sqrt( v2Dot( op, op ) ), op );
  47. }
  48. vec3 v3Normalize( vec3 op ) {
  49. return v3Scale( 1.0f / sqrt( v3Dot( op, op ) ), op );
  50. }
  51. vec4 v4Normalize( vec4 op ) {
  52. return v4Scale( 1.0f / sqrt( v4Dot( op, op ) ), op );
  53. }
  54. vec3 v3LERP( vec3 a, vec3 b, GLfloat t ) {
  55. vec3 x, y;
  56. x = v3Scale( 1.0f - t, a );
  57. y = v3Scale( t, b );
  58. return x + y;
  59. }
  60. vec3 qtRotate( vec4 q, vec3 v ) {
  61. vec4_u qTmp = { .vec = q };
  62. vec4_u vTmp = { .vec = v };
  63. vTmp.w = 0.0f;
  64. v = vTmp.vec;
  65. /* Dot product of 3D components, the scalar component of the intermediate *
  66. * quaternion. */
  67. GLfloat dot = -v3Dot( qTmp.xyz, v );
  68. /* 3D component of quaternion conjugate. */
  69. vec3 conj = v3Scale( -1.0f, qTmp.xyz );
  70. /* Vector portion of the intermediate quaternion. */
  71. vec3 intVec = v3Scale( qTmp.w, v ) + v3Cross( qTmp.xyz, v );
  72. return v3Scale( qTmp.w, intVec ) + v3Scale( dot, conj )
  73. + v3Cross( intVec, conj );
  74. }
  75. vec4 qtConjugate( vec4 op ) {
  76. vec4_u q = { .vec = op };
  77. q.w = -q.w;
  78. return -q.vec;
  79. }
  80. vec4 qtMkRot( GLfloat th, vec3 axis ) {
  81. vec3_u ax = { .vec = axis };
  82. GLfloat s;
  83. th *= M_PI / 180.0f;
  84. s = sin( th / 2.0f );
  85. return (vec4){ ax.x * s, ax.y * s, ax.z * s, cos( th / 2.0f ) };
  86. }
  87. vec4 qtMul( vec4 a, vec4 b ) {
  88. vec4_u a_u = { .vec = a },
  89. b_u = { .vec = b },
  90. res;
  91. GLfloat s;
  92. s = a_u.w * b_u.w - v3Dot( a_u.xyz, b_u.xyz );
  93. res.vec = v3Scale( b_u.w, a_u.xyz )
  94. + v3Scale( a_u.w, b_u.xyz )
  95. + v3Cross( a_u.xyz, b_u.xyz );
  96. res.w = s;
  97. return res.vec;
  98. }
  99. vec4 qtLERP( vec4 a, vec4 b, GLfloat t ) {
  100. vec4 x, y;
  101. GLfloat magCos = v4Dot( a, b );
  102. if ( magCos < 0.0f ) {
  103. a = -a;
  104. }
  105. x = v4Scale( 1.0f - t, a );
  106. y = v4Scale( t, b );
  107. return x + y;
  108. }
  109. vec4 qtSLERP( vec4 a, vec4 b, GLfloat t ) {
  110. // account for cases where sin( theta ) small
  111. // Look into different implementations / optimizations
  112. int theta;
  113. vec4 x, y;
  114. theta = acos( v4Dot( a, b ));
  115. x = v4Scale( sin( ( 1 - t ) * theta ) / sin( theta ), a);
  116. y = v4Scale( sin( t * theta ) / sin( theta ), b);
  117. return x + y;
  118. }
  119. vec4 qtNLERP( vec4 a, vec4 b , GLfloat t ) {
  120. return v4Normalize( qtLERP( a, b, t ));
  121. }
  122. const char * v2Txt( vec2 v ) {
  123. char * buf = malloc( 512 );
  124. vec2_u u = { .vec = v };
  125. snprintf( buf, 512, "{ .x = %f, .y = %f }", u.x, u.y );
  126. return buf;
  127. }
  128. const char * v3Txt( vec3 v ) {
  129. char * buf = malloc( 512 );
  130. vec3_u u = { .vec = v };
  131. snprintf( buf, 512, "{ .x = %f, .y = %f, .z = %f }", u.x, u.y, u.z );
  132. return buf;
  133. }
  134. const char * v4Txt( vec4 v ) {
  135. char * buf = malloc( 512 );
  136. vec4_u u = { .vec = v };
  137. snprintf( buf, 512, "{ .x = %f, .y = %f, .z = %f, .w = %f }",
  138. u.x, u.y, u.z, u.w );
  139. return buf;
  140. }