HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
ImathFrame.h
Go to the documentation of this file.
1 //
2 // SPDX-License-Identifier: BSD-3-Clause
3 // Copyright Contributors to the OpenEXR Project.
4 //
5 
6 //
7 // Functions for computing reference frames.
8 //
9 
10 #ifndef INCLUDED_IMATHFRAME_H
11 #define INCLUDED_IMATHFRAME_H
12 
13 #include "ImathNamespace.h"
14 
15 IMATH_INTERNAL_NAMESPACE_HEADER_ENTER
16 
17 /// @cond Doxygen_Suppress
18 template <class T> class Vec3;
19 template <class T> class Matrix44;
20 /// @endcond
21 
22 ///
23 /// @{
24 /// @name Functions for computing reference frames
25 ///
26 /// These methods compute a set of reference frames, defined by their
27 /// transformation matrix, along a curve. It is designed so that the
28 /// array of points and the array of matrices used to fetch these
29 /// routines don't need to be ordered as the curve.
30 ///
31 /// A typical usage would be :
32 ///
33 /// m[0] = IMATH_INTERNAL_NAMESPACE::firstFrame( p[0], p[1], p[2] );
34 /// for( int i = 1; i < n - 1; i++ )
35 /// {
36 /// m[i] = IMATH_INTERNAL_NAMESPACE::nextFrame( m[i-1], p[i-1], p[i], t[i-1], t[i] );
37 /// }
38 /// m[n-1] = IMATH_INTERNAL_NAMESPACE::lastFrame( m[n-2], p[n-2], p[n-1] );
39 ///
40 /// See Graphics Gems I for the underlying algorithm.
41 
42 
43 template <class T>
44 Matrix44<T> constexpr firstFrame (const Vec3<T>&, // First point
45  const Vec3<T>&, // Second point
46  const Vec3<T>&) IMATH_NOEXCEPT; // Third point
47 
48 template <class T>
49 Matrix44<T> constexpr nextFrame (const Matrix44<T>&, // Previous matrix
50  const Vec3<T>&, // Previous point
51  const Vec3<T>&, // Current point
52  Vec3<T>&, // Previous tangent
53  Vec3<T>&) IMATH_NOEXCEPT; // Current tangent
54 
55 template <class T>
56 Matrix44<T> constexpr lastFrame (const Matrix44<T>&, // Previous matrix
57  const Vec3<T>&, // Previous point
58  const Vec3<T>&) IMATH_NOEXCEPT; // Last point
59 
60 ///
61 /// Compute the first reference frame along a curve.
62 ///
63 /// This function returns the transformation matrix to the reference
64 /// frame defined by the three points `pi`, `pj` and `pk`. Note that
65 /// if the two vectors <`pi`,`pj`> and <`pi`,`pk`> are colinears, an
66 /// arbitrary twist value will be choosen.
67 ///
68 /// Throw `std::domain_error` if `pi` and `pj` are equal.
69 ///
70 /// @param pi
71 /// First point
72 /// @param pj
73 /// Second point
74 /// @param pk
75 /// Third point
76 ///
77 template <class T>
78 Matrix44<T> constexpr firstFrame (const Vec3<T>& pi, // first point
79  const Vec3<T>& pj, // secont point
80  const Vec3<T>& pk) IMATH_NOEXCEPT // third point
81 {
82  Vec3<T> t = pj - pi;
83  t.normalizeExc();
84 
85  Vec3<T> n = t.cross (pk - pi);
86  n.normalize();
87  if (n.length() == 0.0f)
88  {
89  int i = fabs (t[0]) < fabs (t[1]) ? 0 : 1;
90  if (fabs (t[2]) < fabs (t[i]))
91  i = 2;
92 
93  Vec3<T> v (0.0, 0.0, 0.0);
94  v[i] = 1.0;
95  n = t.cross (v);
96  n.normalize();
97  }
98 
99  Vec3<T> b = t.cross (n);
100 
101  Matrix44<T> M;
102 
103  M[0][0] = t[0];
104  M[0][1] = t[1];
105  M[0][2] = t[2];
106  M[0][3] = 0.0, M[1][0] = n[0];
107  M[1][1] = n[1];
108  M[1][2] = n[2];
109  M[1][3] = 0.0, M[2][0] = b[0];
110  M[2][1] = b[1];
111  M[2][2] = b[2];
112  M[2][3] = 0.0, M[3][0] = pi[0];
113  M[3][1] = pi[1];
114  M[3][2] = pi[2];
115  M[3][3] = 1.0;
116 
117  return M;
118 }
119 
120 ///
121 /// Compute the next reference frame along a curve.
122 ///
123 /// This function returns the transformation matrix to the next reference
124 /// frame defined by the previously computed transformation matrix and the
125 /// new point and tangent vector along the curve.
126 ///
127 /// @param Mi
128 /// The previous matrix
129 /// @param pi
130 /// The previous point
131 /// @param pj
132 /// The current point
133 /// @param ti
134 /// The previous tangent vector
135 /// @param tj
136 /// The current tangent vector
137 
138 template <class T>
139 Matrix44<T> constexpr nextFrame (const Matrix44<T>& Mi, // Previous matrix
140  const Vec3<T>& pi, // Previous point
141  const Vec3<T>& pj, // Current point
142  Vec3<T>& ti, // Previous tangent vector
143  Vec3<T>& tj) IMATH_NOEXCEPT // Current tangent vector
144 {
145  Vec3<T> a (0.0, 0.0, 0.0); /// Rotation axis.
146  T r = 0.0; // Rotation angle.
147 
148  if (ti.length() != 0.0 && tj.length() != 0.0)
149  {
150  ti.normalize();
151  tj.normalize();
152  T dot = ti.dot (tj);
153 
154  //
155  // This is *really* necessary :
156  //
157 
158  if (dot > 1.0)
159  dot = 1.0;
160  else if (dot < -1.0)
161  dot = -1.0;
162 
163  r = acosf (dot);
164  a = ti.cross (tj);
165  }
166 
167  if (a.length() != 0.0 && r != 0.0)
168  {
169  Matrix44<T> R;
170  R.setAxisAngle (a, r);
171  Matrix44<T> Tj;
172  Tj.translate (pj);
173  Matrix44<T> Ti;
174  Ti.translate (-pi);
175 
176  return Mi * Ti * R * Tj;
177  }
178  else
179  {
180  Matrix44<T> Tr;
181  Tr.translate (pj - pi);
182 
183  return Mi * Tr;
184  }
185 }
186 
187 ///
188 /// Compute the last reference frame along a curve.
189 ///
190 /// This function returns the transformation matrix to the last reference
191 /// frame defined by the previously computed transformation matrix and the
192 /// last point along the curve.
193 ///
194 /// @param Mi
195 /// The previous matrix
196 /// @param pi
197 /// The previous point
198 /// @param pj
199 /// The last point
200 
201 template <class T>
202 Matrix44<T> constexpr lastFrame (const Matrix44<T>& Mi, // Previous matrix
203  const Vec3<T>& pi, // Previous point
204  const Vec3<T>& pj) IMATH_NOEXCEPT // Last point
205 {
206  Matrix44<T> Tr;
207  Tr.translate (pj - pi);
208 
209  return Mi * Tr;
210 }
211 
212 /// @}
213 
214 IMATH_INTERNAL_NAMESPACE_HEADER_EXIT
215 
216 #endif // INCLUDED_IMATHFRAME_H
SYS_API float acosf(float x)
#define IMATH_NOEXCEPT
Definition: ImathConfig.h:72
Definition: ImathVec.h:32
*get result *(waiting if necessary)*A common idiom is to fire a bunch of sub tasks at the and then *wait for them to all complete We provide a helper class
Definition: thread.h:623
IMATH_HOSTDEVICE T length() const IMATH_NOEXCEPT
Return the Euclidean norm.
Definition: ImathVec.h:1734
const GLdouble * v
Definition: glcorearb.h:837
GLboolean GLboolean GLboolean GLboolean a
Definition: glcorearb.h:1222
GLdouble n
Definition: glcorearb.h:2008
Matrix44< T > constexpr nextFrame(const Matrix44< T > &, const Vec3< T > &, const Vec3< T > &, Vec3< T > &, Vec3< T > &) IMATH_NOEXCEPT
Definition: ImathFrame.h:139
Matrix44< T > constexpr lastFrame(const Matrix44< T > &, const Vec3< T > &, const Vec3< T > &) IMATH_NOEXCEPT
Definition: ImathFrame.h:202
fpreal64 dot(const CE_VectorT< T > &a, const CE_VectorT< T > &b)
Definition: CE_Vector.h:140
const Vec3 & normalizeExc()
Normalize in place. If length()==0, throw an exception.
Definition: ImathVec.h:1775
IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Matrix44 & translate(const Vec3< S > &t) IMATH_NOEXCEPT
GLboolean GLboolean GLboolean b
Definition: glcorearb.h:1222
GLdouble t
Definition: glad.h:2397
Matrix44< T > constexpr firstFrame(const Vec3< T > &, const Vec3< T > &, const Vec3< T > &) IMATH_NOEXCEPT
Definition: ImathFrame.h:78
__hostdev__ constexpr T pi()
Pi constant taken from Boost to match old behaviour.
Definition: NanoVDB.h:976
IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Matrix44 & setAxisAngle(const Vec3< S > &ax, S ang) IMATH_NOEXCEPT
GLboolean r
Definition: glcorearb.h:1222
IMATH_HOSTDEVICE constexpr Vec3 cross(const Vec3 &v) const IMATH_NOEXCEPT
Right-handed cross product.
Definition: ImathVec.h:1556
IMATH_HOSTDEVICE const Vec3 & normalize() IMATH_NOEXCEPT
Normalize in place. If length()==0, return a null vector.
Definition: ImathVec.h:1753