tsTransform.cpp 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. //-----------------------------------------------------------------------------
  2. // Copyright (c) 2012 GarageGames, LLC
  3. //
  4. // Permission is hereby granted, free of charge, to any person obtaining a copy
  5. // of this software and associated documentation files (the "Software"), to
  6. // deal in the Software without restriction, including without limitation the
  7. // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  8. // sell copies of the Software, and to permit persons to whom the Software is
  9. // furnished to do so, subject to the following conditions:
  10. //
  11. // The above copyright notice and this permission notice shall be included in
  12. // all copies or substantial portions of the Software.
  13. //
  14. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  19. // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  20. // IN THE SOFTWARE.
  21. //-----------------------------------------------------------------------------
  22. #include "ts/tsTransform.h"
  23. #include "core/stream/stream.h"
  24. void Quat16::identity()
  25. {
  26. x = y = z = 0;
  27. w = MAX_VAL;
  28. }
  29. QuatF Quat16::getQuatF() const
  30. {
  31. return QuatF ( F32(x) / F32(MAX_VAL),
  32. F32(y) / F32(MAX_VAL),
  33. F32(z) / F32(MAX_VAL),
  34. F32(w) / F32(MAX_VAL) );
  35. }
  36. QuatF & Quat16::getQuatF( QuatF * q ) const
  37. {
  38. q->x = F32( x ) / F32(MAX_VAL);
  39. q->y = F32( y ) / F32(MAX_VAL);
  40. q->z = F32( z ) / F32(MAX_VAL);
  41. q->w = F32( w ) / F32(MAX_VAL);
  42. return *q;
  43. }
  44. void Quat16::set( const QuatF & q )
  45. {
  46. x = (S16)(q.x * F32(MAX_VAL));
  47. y = (S16)(q.y * F32(MAX_VAL));
  48. z = (S16)(q.z * F32(MAX_VAL));
  49. w = (S16)(q.w * F32(MAX_VAL));
  50. }
  51. S32 Quat16::operator==( const Quat16 & q ) const
  52. {
  53. return( x == q.x && y == q.y && z == q.z && w == q.w );
  54. }
  55. void Quat16::read(Stream * s)
  56. {
  57. s->read(&x);
  58. s->read(&y);
  59. s->read(&z);
  60. s->read(&w);
  61. }
  62. void Quat16::write(Stream * s)
  63. {
  64. s->write(x);
  65. s->write(y);
  66. s->write(z);
  67. s->write(w);
  68. }
  69. QuatF & TSTransform::interpolate( const QuatF & q1, const QuatF & q2, F32 interp, QuatF * q )
  70. {
  71. F32 Dot;
  72. F32 Dist2;
  73. F32 OneOverL;
  74. F32 x1,y1,z1,w1;
  75. F32 x2,y2,z2,w2;
  76. //
  77. // This is a linear interpolation with a fast renormalization.
  78. //
  79. x1 = q1.x;
  80. y1 = q1.y;
  81. z1 = q1.z;
  82. w1 = q1.w;
  83. x2 = q2.x;
  84. y2 = q2.y;
  85. z2 = q2.z;
  86. w2 = q2.w;
  87. // Determine if quats are further than 90 degrees
  88. Dot = x1*x2 + y1*y2 + z1*z2 + w1*w2;
  89. // If dot is negative flip one of the quaterions
  90. if( Dot < 0.0f )
  91. {
  92. x1 = -x1;
  93. y1 = -y1;
  94. z1 = -z1;
  95. w1 = -w1;
  96. }
  97. // Compute interpolated values
  98. x1 = x1 + interp*(x2 - x1);
  99. y1 = y1 + interp*(y2 - y1);
  100. z1 = z1 + interp*(z2 - z1);
  101. w1 = w1 + interp*(w2 - w1);
  102. // Get squared distance of new quaternion
  103. Dist2 = x1*x1 + y1*y1 + z1*z1 + w1*w1;
  104. // Use home-baked polynomial to compute 1/sqrt(Dist2)
  105. // since we know the range is 0.707 >= Dist2 <= 1.0
  106. // we'll split in half.
  107. if( Dist2<0.857f )
  108. OneOverL = (((0.699368f)*Dist2) + -1.819985f)*Dist2 + 2.126369f; //0.0000792
  109. else
  110. OneOverL = (((0.454012f)*Dist2) + -1.403517f)*Dist2 + 1.949542f; //0.0000373
  111. // Renormalize
  112. q->x = x1*OneOverL;
  113. q->y = y1*OneOverL;
  114. q->z = z1*OneOverL;
  115. q->w = w1*OneOverL;
  116. return *q;
  117. }
  118. void TSTransform::applyScale(F32 scale, MatrixF * mat)
  119. {
  120. mat->scale(Point3F(scale,scale,scale));
  121. }
  122. void TSTransform::applyScale(const Point3F & scale, MatrixF * mat)
  123. {
  124. mat->scale(scale);
  125. }
  126. void TSTransform::applyScale(const TSScale & scale, MatrixF * mat)
  127. {
  128. MatrixF mat2;
  129. TSTransform::setMatrix(scale.mRotate,&mat2);
  130. MatrixF mat3(mat2);
  131. mat3.inverse();
  132. mat2.scale(scale.mScale);
  133. mat2.mul(mat3);
  134. mat->mul(mat2);
  135. }