1 //
2 // Copyright 2016 Pixar
3 //
4 // Licensed under the Apache License, Version 2.0 (the "Apache License")
5 // with the following modification; you may not use this file except in
6 // compliance with the Apache License and the following modification to it:
7 // Section 6. Trademarks. is deleted and replaced with:
8 //
9 // 6. Trademarks. This License does not grant permission to use the trade
10 //    names, trademarks, service marks, or product names of the Licensor
11 //    and its affiliates, except as required to comply with Section 4(c) of
12 //    the License and to reproduce the content of the NOTICE file.
13 //
14 // You may obtain a copy of the Apache License at
15 //
16 //     http://www.apache.org/licenses/LICENSE-2.0
17 //
18 // Unless required by applicable law or agreed to in writing, software
19 // distributed under the Apache License with the above modification is
20 // distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
21 // KIND, either express or implied. See the Apache License for the specific
22 // language governing permissions and limitations under the Apache License.
23 //
24 ////////////////////////////////////////////////////////////////////////
25 // This file is generated by a script.  Do not edit directly.  Edit the
26 // quat.template.h file to make changes.
27 
28 #ifndef PXR_BASE_GF_QUATD_H
29 #define PXR_BASE_GF_QUATD_H
30 
31 /// \file gf/quatd.h
32 /// \ingroup group_gf_LinearAlgebra
33 
34 #include "pxr/pxr.h"
35 #include "pxr/base/gf/api.h"
36 #include "pxr/base/gf/declare.h"
37 #include "pxr/base/gf/vec3d.h"
38 #include "pxr/base/gf/traits.h"
39 
40 #include <boost/functional/hash.hpp>
41 
42 #include <iosfwd>
43 
44 PXR_NAMESPACE_OPEN_SCOPE
45 
46 template <>
47 struct GfIsGfQuat<class GfQuatd> { static const bool value = true; };
48 
49 
50 /// Return the dot (inner) product of two quaternions.
51 double GfDot(const GfQuatd& q1, const GfQuatd& q2);
52 
53 
54 /// \class GfQuatd
55 /// \ingroup group_gf_LinearAlgebra
56 ///
57 /// Basic type: a quaternion, a complex number with a real coefficient and
58 /// three imaginary coefficients, stored as a 3-vector.
59 ///
60 class GfQuatd
61 {
62   public:
63     typedef double ScalarType;
64     typedef GfVec3d ImaginaryType;
65 
66     /// Default constructor leaves the quaternion undefined.
67     GfQuatd() {}
68 
69     /// Initialize the real coefficient to \p realVal and the imaginary
70     /// coefficients to zero.
71     ///
72     /// Since quaternions typically must be normalized, reasonable values for
73     /// \p realVal are -1, 0, or 1.  Other values are legal but are likely to
74     /// be meaningless.
75     ///
76     explicit GfQuatd (double realVal) : _imaginary(0), _real(realVal) {}
77 
78     /// Initialize the real and imaginary coefficients.
79     GfQuatd(double real, double i, double j, double k)
80         : _imaginary(i, j, k), _real(real)
81     {
82     }
83 
84     /// Initialize the real and imaginary coefficients.
85     GfQuatd(double real, const GfVec3d &imaginary)
86         : _imaginary(imaginary), _real(real)
87     {
88     }
89 
90     /// Implicitly convert from GfQuatf.
91     GF_API
92     GfQuatd(class GfQuatf const &other);
93     /// Implicitly convert from GfQuath.
94     GF_API
95     GfQuatd(class GfQuath const &other);
96 
97     /// Return the identity quaternion, with real coefficient 1 and an
98     /// imaginary coefficients all zero.
99     static GfQuatd GetIdentity() { return GfQuatd(1.0); }
100 
101     /// Return the real coefficient.
102     double GetReal() const { return _real; }
103 
104     /// Set the real coefficient.
105     void SetReal(double real) { _real = real; }
106 
107     /// Return the imaginary coefficient.
108     const GfVec3d &GetImaginary() const { return _imaginary; }
109 
110     /// Set the imaginary coefficients.
111     void SetImaginary(const GfVec3d &imaginary) {
112         _imaginary = imaginary;
113     }
114 
115     /// Set the imaginary coefficients.
116     void SetImaginary(double i, double j, double k) {
117         _imaginary.Set(i, j, k);
118     }
119 
120     /// Return geometric length of this quaternion.
121     double GetLength() const { return GfSqrt(_GetLengthSquared()); }
122 
123     /// length of this quaternion is smaller than \p eps, return the identity
124     /// quaternion.
125     GfQuatd
126     GetNormalized(double eps = GF_MIN_VECTOR_LENGTH) const {
127         GfQuatd ret(*this);
128         ret.Normalize(eps);
129         return ret;
130     }
131 
132     /// Normalizes this quaternion in place to unit length, returning the
133     /// length before normalization. If the length of this quaternion is
134     /// smaller than \p eps, this sets the quaternion to identity.
135     GF_API
136     double Normalize(double eps = GF_MIN_VECTOR_LENGTH);
137 
138     /// Return this quaternion's conjugate, which is the quaternion with the
139     /// same real coefficient and negated imaginary coefficients.
140     GfQuatd GetConjugate() const {
141         return GfQuatd(GetReal(), -GetImaginary());
142     }
143 
144     /// Return this quaternion's inverse, or reciprocal.  This is the
145     /// quaternion's conjugate divided by it's squared length.
146     GfQuatd GetInverse() const {
147         return GetConjugate() / _GetLengthSquared();
148     }
149 
150     /// Transform the GfVec3d point. If the quaternion is normalized,
151     /// the transformation is a rotation. Given a GfQuatd q, q.Transform(point)
152     /// is equivalent to:
153     ///
154     ///     (q * GfQuatd(0, point) * q.GetInverse()).GetImaginary()
155     ///
156     /// but is more efficient.
157     GF_API
158     GfVec3d Transform(const GfVec3d& point) const;
159 
160     /// Hash.
161     friend inline size_t hash_value(const GfQuatd &q) {
162         size_t h = boost::hash<ScalarType>()(q.GetReal());
163         boost::hash_combine(h, q.GetImaginary());
164         return h;
165     }
166 
167     /// Component-wise negation.
168     GfQuatd operator-() const {
169         return GfQuatd(-GetReal(), -GetImaginary());
170     }
171 
172     /// Component-wise quaternion equality test. The real and imaginary parts
173     /// must match exactly for quaternions to be considered equal.
174     bool operator==(const GfQuatd &q) const {
175         return (GetReal() == q.GetReal() &&
176                 GetImaginary() == q.GetImaginary());
177     }
178 
179     /// Component-wise quaternion inequality test. The real and imaginary
180     /// parts must match exactly for quaternions to be considered equal.
181     bool operator!=(const GfQuatd &q) const {
182         return !(*this == q);
183     }
184 
185     /// Post-multiply quaternion \p q into this quaternion.
186     GF_API
187     GfQuatd &operator *=(const GfQuatd &q);
188 
189     /// Multiply this quaternion's coefficients by \p s.
190     GfQuatd &operator *=(double s) {
191         _real *= s;
192         _imaginary *= s;
193         return *this;
194     }
195 
196     /// Divide this quaternion's coefficients by \p s.
197     GfQuatd &operator /=(double s) {
198         _real /= s;
199         _imaginary /= s;
200         return *this;
201     }
202 
203     /// Add quaternion \p q to this quaternion.
204     GfQuatd &operator +=(const GfQuatd &q) {
205         _real += q._real;
206         _imaginary += q._imaginary;
207         return *this;
208     }
209 
210     /// Component-wise unary difference operator.
211     GfQuatd &operator -=(const GfQuatd &q)  {
212         _real -= q._real;
213         _imaginary -= q._imaginary;
214         return *this;
215     }
216 
217     /// Component-wise binary sum operator.
218     friend GfQuatd
219     operator +(const GfQuatd &q1, const GfQuatd &q2) {
220         return GfQuatd(q1) += q2;
221     }
222 
223     /// Component-wise binary difference operator.
224     friend GfQuatd
225     operator -(const GfQuatd &q1, const GfQuatd &q2) {
226         return GfQuatd(q1) -= q2;
227     }
228 
229     /// Returns the product of quaternions \p q1 and \p q2.
230     friend GfQuatd
231     operator *(const GfQuatd &q1, const GfQuatd &q2) {
232         return GfQuatd(q1) *= q2;
233     }
234 
235     /// Returns the product of quaternion \p q and scalar \p s.
236     friend GfQuatd
237     operator *(const GfQuatd &q, double s) {
238         return GfQuatd(q) *= s;
239     }
240 
241     /// Returns the product of quaternion \p q and scalar \p s.
242     friend GfQuatd
243     operator *(double s, const GfQuatd &q) {
244         return GfQuatd(q) *= s;
245     }
246 
247     /// Returns the product of quaternion \p q and scalar 1 / \p s.
248     friend GfQuatd
249     operator /(const GfQuatd &q, double s) {
250         return GfQuatd(q) /= s;
251     }
252 
253   private:
254     /// Imaginary part
255     GfVec3d _imaginary;
256 
257     /// Real part
258     double _real;
259 
260     /// Returns the square of the length
261     double
262     _GetLengthSquared() const {
263         return GfDot(*this, *this);
264     }
265 };
266 
267 /// Spherically linearly interpolate between \p q0 and \p q1.
268 ///
269 /// If the interpolant \p alpha is zero, then the result is \p q0, while
270 /// \p alpha of one yields \p q1.
271 GF_API GfQuatd
272 GfSlerp(double alpha, const GfQuatd& q0, const GfQuatd& q1);
273 
274 GF_API GfQuatd
275 GfSlerp(const GfQuatd& q0, const GfQuatd& q1, double alpha);
276 
277 inline double
278 GfDot(GfQuatd const &q1, GfQuatd const &q2) {
279     return GfDot(q1.GetImaginary(), q2.GetImaginary()) +
280                  q1.GetReal()*q2.GetReal();
281 }
282 
283 /// Output a GfQuatd using the format (re, i, j, k)
284 /// \ingroup group_gf_DebuggingOutput
285 GF_API std::ostream& operator<<(std::ostream &, GfQuatd const &);
286 
287 PXR_NAMESPACE_CLOSE_SCOPE
288 
289 #endif // PXR_BASE_GF_QUATD_H
290