/src/FreeImage/Source/OpenEXR/Imath/ImathFrame.h

https://bitbucket.org/cabalistic/ogredeps/ · C++ Header · 190 lines · 82 code · 31 blank · 77 comment · 14 complexity · 213e85c3f02101c2776adf477d245fc8 MD5 · raw file

  1. ///////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
  4. // Digital Ltd. LLC
  5. //
  6. // All rights reserved.
  7. //
  8. // Redistribution and use in source and binary forms, with or without
  9. // modification, are permitted provided that the following conditions are
  10. // met:
  11. // * Redistributions of source code must retain the above copyright
  12. // notice, this list of conditions and the following disclaimer.
  13. // * Redistributions in binary form must reproduce the above
  14. // copyright notice, this list of conditions and the following disclaimer
  15. // in the documentation and/or other materials provided with the
  16. // distribution.
  17. // * Neither the name of Industrial Light & Magic nor the names of
  18. // its contributors may be used to endorse or promote products derived
  19. // from this software without specific prior written permission.
  20. //
  21. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  22. // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  23. // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  24. // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  25. // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  26. // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  27. // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  28. // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  29. // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  30. // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  31. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  32. //
  33. ///////////////////////////////////////////////////////////////////////////
  34. #ifndef INCLUDED_IMATHFRAME_H
  35. #define INCLUDED_IMATHFRAME_H
  36. namespace Imath {
  37. template<class T> class Vec3;
  38. template<class T> class Matrix44;
  39. //
  40. // These methods compute a set of reference frames, defined by their
  41. // transformation matrix, along a curve. It is designed so that the
  42. // array of points and the array of matrices used to fetch these routines
  43. // don't need to be ordered as the curve.
  44. //
  45. // A typical usage would be :
  46. //
  47. // m[0] = Imath::firstFrame( p[0], p[1], p[2] );
  48. // for( int i = 1; i < n - 1; i++ )
  49. // {
  50. // m[i] = Imath::nextFrame( m[i-1], p[i-1], p[i], t[i-1], t[i] );
  51. // }
  52. // m[n-1] = Imath::lastFrame( m[n-2], p[n-2], p[n-1] );
  53. //
  54. // See Graphics Gems I for the underlying algorithm.
  55. //
  56. template<class T> Matrix44<T> firstFrame( const Vec3<T>&, // First point
  57. const Vec3<T>&, // Second point
  58. const Vec3<T>& ); // Third point
  59. template<class T> Matrix44<T> nextFrame( const Matrix44<T>&, // Previous matrix
  60. const Vec3<T>&, // Previous point
  61. const Vec3<T>&, // Current point
  62. Vec3<T>&, // Previous tangent
  63. Vec3<T>& ); // Current tangent
  64. template<class T> Matrix44<T> lastFrame( const Matrix44<T>&, // Previous matrix
  65. const Vec3<T>&, // Previous point
  66. const Vec3<T>& ); // Last point
  67. //
  68. // firstFrame - Compute the first reference frame along a curve.
  69. //
  70. // This function returns the transformation matrix to the reference frame
  71. // defined by the three points 'pi', 'pj' and 'pk'. Note that if the two
  72. // vectors <pi,pj> and <pi,pk> are colinears, an arbitrary twist value will
  73. // be choosen.
  74. //
  75. // Throw 'NullVecExc' if 'pi' and 'pj' are equals.
  76. //
  77. template<class T> Matrix44<T> firstFrame
  78. (
  79. const Vec3<T>& pi, // First point
  80. const Vec3<T>& pj, // Second point
  81. const Vec3<T>& pk ) // Third point
  82. {
  83. Vec3<T> t = pj - pi; t.normalizeExc();
  84. Vec3<T> n = t.cross( pk - pi ); n.normalize();
  85. if( n.length() == 0.0f )
  86. {
  87. int i = fabs( t[0] ) < fabs( t[1] ) ? 0 : 1;
  88. if( fabs( t[2] ) < fabs( t[i] )) i = 2;
  89. Vec3<T> v( 0.0, 0.0, 0.0 ); v[i] = 1.0;
  90. n = t.cross( v ); n.normalize();
  91. }
  92. Vec3<T> b = t.cross( n );
  93. Matrix44<T> M;
  94. M[0][0] = t[0]; M[0][1] = t[1]; M[0][2] = t[2]; M[0][3] = 0.0,
  95. M[1][0] = n[0]; M[1][1] = n[1]; M[1][2] = n[2]; M[1][3] = 0.0,
  96. M[2][0] = b[0]; M[2][1] = b[1]; M[2][2] = b[2]; M[2][3] = 0.0,
  97. M[3][0] = pi[0]; M[3][1] = pi[1]; M[3][2] = pi[2]; M[3][3] = 1.0;
  98. return M;
  99. }
  100. //
  101. // nextFrame - Compute the next reference frame along a curve.
  102. //
  103. // This function returns the transformation matrix to the next reference
  104. // frame defined by the previously computed transformation matrix and the
  105. // new point and tangent vector along the curve.
  106. //
  107. template<class T> Matrix44<T> nextFrame
  108. (
  109. const Matrix44<T>& Mi, // Previous matrix
  110. const Vec3<T>& pi, // Previous point
  111. const Vec3<T>& pj, // Current point
  112. Vec3<T>& ti, // Previous tangent vector
  113. Vec3<T>& tj ) // Current tangent vector
  114. {
  115. Vec3<T> a(0.0, 0.0, 0.0); // Rotation axis.
  116. T r = 0.0; // Rotation angle.
  117. if( ti.length() != 0.0 && tj.length() != 0.0 )
  118. {
  119. ti.normalize(); tj.normalize();
  120. T dot = ti.dot( tj );
  121. //
  122. // This is *really* necessary :
  123. //
  124. if( dot > 1.0 ) dot = 1.0;
  125. else if( dot < -1.0 ) dot = -1.0;
  126. r = acosf( dot );
  127. a = ti.cross( tj );
  128. }
  129. if( a.length() != 0.0 && r != 0.0 )
  130. {
  131. Matrix44<T> R; R.setAxisAngle( a, r );
  132. Matrix44<T> Tj; Tj.translate( pj );
  133. Matrix44<T> Ti; Ti.translate( -pi );
  134. return Mi * Ti * R * Tj;
  135. }
  136. else
  137. {
  138. Matrix44<T> Tr; Tr.translate( pj - pi );
  139. return Mi * Tr;
  140. }
  141. }
  142. //
  143. // lastFrame - Compute the last reference frame along a curve.
  144. //
  145. // This function returns the transformation matrix to the last reference
  146. // frame defined by the previously computed transformation matrix and the
  147. // last point along the curve.
  148. //
  149. template<class T> Matrix44<T> lastFrame
  150. (
  151. const Matrix44<T>& Mi, // Previous matrix
  152. const Vec3<T>& pi, // Previous point
  153. const Vec3<T>& pj ) // Last point
  154. {
  155. Matrix44<T> Tr; Tr.translate( pj - pi );
  156. return Mi * Tr;
  157. }
  158. } // namespace Imath
  159. #endif