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 // vec.template.h file to make changes.
27 
28 #ifndef PXR_BASE_GF_VEC3F_H
29 #define PXR_BASE_GF_VEC3F_H
30 
31 /// \file gf/vec3f.h
32 /// \ingroup group_gf_LinearAlgebra
33 
34 #include "pxr/pxr.h"
35 #include "pxr/base/tf/diagnostic.h"
36 #include "pxr/base/gf/api.h"
37 #include "pxr/base/gf/limits.h"
38 #include "pxr/base/gf/traits.h"
39 #include "pxr/base/gf/math.h"
40 
41 #include <boost/functional/hash.hpp>
42 
43 #include <cstddef>
44 #include <cmath>
45 
46 #include <iosfwd>
47 
48 PXR_NAMESPACE_OPEN_SCOPE
49 
50 class GfVec3f;
51 
52 template <>
53 struct GfIsGfVec<class GfVec3f> { static const bool value = true; };
54 
55 /// \class GfVec3f
56 /// \ingroup group_gf_LinearAlgebra
57 ///
58 /// Basic type for a vector of 3 float components.
59 ///
60 /// Represents a vector of 3 components of type \c float.
61 /// It is intended to be fast and simple.
62 ///
63 class GfVec3f
64 {
65 public:
66     /// Scalar element type and dimension.
67     typedef float ScalarType;
68     static const size_t dimension = 3;
69 
70     /// Default constructor does no initialization.
71     GfVec3f() = default;
72 
73     /// Initialize all elements to a single value.
74     constexpr explicit GfVec3f(float value)
75         : _data{ value, value, value }
76     {
77     }
78 
79     /// Initialize all elements with explicit arguments.
80     constexpr GfVec3f(float s0, float s1, float s2)
81         : _data{ s0, s1, s2 }
82     {
83     }
84 
85     /// Construct with pointer to values.
86     template <class Scl>
87     constexpr explicit GfVec3f(Scl const *p)
88         : _data{ p[0], p[1], p[2] }
89     {
90     }
91 
92     /// Construct from GfVec3d.
93     explicit GfVec3f(class GfVec3d const &other);
94 
95     /// Implicitly convert from GfVec3h.
96     GfVec3f(class GfVec3h const &other);
97 
98     /// Implicitly convert from GfVec3i.
99     GfVec3f(class GfVec3i const &other);
100 
101     /// Create a unit vector along the X-axis.
102     static GfVec3f XAxis() {
103         GfVec3f result(0);
104         result[0] = 1;
105         return result;
106     }
107     /// Create a unit vector along the Y-axis.
108     static GfVec3f YAxis() {
109         GfVec3f result(0);
110         result[1] = 1;
111         return result;
112     }
113     /// Create a unit vector along the Z-axis.
114     static GfVec3f ZAxis() {
115         GfVec3f result(0);
116         result[2] = 1;
117         return result;
118     }
119 
120     /// Create a unit vector along the i-th axis, zero-based.  Return the zero
121     /// vector if \p i is greater than or equal to 3.
122     static GfVec3f Axis(size_t i) {
123         GfVec3f result(0);
124         if (i < 3)
125             result[i] = 1;
126         return result;
127     }
128 
129     /// Set all elements with passed arguments.
130     GfVec3f &Set(float s0, float s1, float s2) {
131         _data[0] = s0;
132         _data[1] = s1;
133         _data[2] = s2;
134         return *this;
135     }
136 
137     /// Set all elements with a pointer to data.
138     GfVec3f &Set(float const *a) {
139         return Set(a[0], a[1], a[2]);
140     }
141 
142     /// Direct data access.
143     float const *data() const { return _data; }
144     float *data() { return _data; }
145     float const *GetArray() const { return data(); }
146 
147     /// Indexing.
148     float const &operator[](size_t i) const { return _data[i]; }
149     float &operator[](size_t i) { return _data[i]; }
150 
151     /// Hash.
152     friend inline size_t hash_value(GfVec3f const &vec) {
153         size_t h = 0;
154         boost::hash_combine(h, vec[0]);
155         boost::hash_combine(h, vec[1]);
156         boost::hash_combine(h, vec[2]);
157         return h;
158     }
159 
160     /// Equality comparison.
161     bool operator==(GfVec3f const &other) const {
162         return _data[0] == other[0] &&
163                _data[1] == other[1] &&
164                _data[2] == other[2];
165     }
166     bool operator!=(GfVec3f const &other) const {
167         return !(*this == other);
168     }
169 
170     // TODO Add inequality for other vec types...
171     /// Equality comparison.
172     GF_API
173     bool operator==(class GfVec3d const &other) const;
174     /// Equality comparison.
175     GF_API
176     bool operator==(class GfVec3h const &other) const;
177     /// Equality comparison.
178     GF_API
179     bool operator==(class GfVec3i const &other) const;
180 
181     /// Create a vec with negated elements.
182     GfVec3f operator-() const {
183         return GfVec3f(-_data[0], -_data[1], -_data[2]);
184     }
185 
186     /// Addition.
187     GfVec3f &operator+=(GfVec3f const &other) {
188         _data[0] += other[0];
189         _data[1] += other[1];
190         _data[2] += other[2];
191         return *this;
192     }
193     friend GfVec3f operator+(GfVec3f const &l, GfVec3f const &r) {
194         return GfVec3f(l) += r;
195     }
196 
197     /// Subtraction.
198     GfVec3f &operator-=(GfVec3f const &other) {
199         _data[0] -= other[0];
200         _data[1] -= other[1];
201         _data[2] -= other[2];
202         return *this;
203     }
204     friend GfVec3f operator-(GfVec3f const &l, GfVec3f const &r) {
205         return GfVec3f(l) -= r;
206     }
207 
208     /// Multiplication by scalar.
209     GfVec3f &operator*=(double s) {
210         _data[0] *= s;
211         _data[1] *= s;
212         _data[2] *= s;
213         return *this;
214     }
215     GfVec3f operator*(double s) const {
216         return GfVec3f(*this) *= s;
217     }
218     friend GfVec3f operator*(double s, GfVec3f const &v) {
219         return v * s;
220     }
221 
222         /// Division by scalar.
223     // TODO should divide by the scalar type.
224     GfVec3f &operator/=(double s) {
225         // TODO This should not multiply by 1/s, it should do the division.
226         // Doing the division is more numerically stable when s is close to
227         // zero.
228         return *this *= (1.0 / s);
229     }
230     GfVec3f operator/(double s) const {
231         return *this * (1.0 / s);
232     }
233 
234     /// See GfDot().
235     float operator*(GfVec3f const &v) const {
236         return _data[0] * v[0] + _data[1] * v[1] + _data[2] * v[2];
237     }
238 
239     /// Returns the projection of \p this onto \p v. That is:
240     /// \code
241     /// v * (*this * v)
242     /// \endcode
243     GfVec3f GetProjection(GfVec3f const &v) const {
244         return v * (*this * v);
245     }
246 
247     /// Returns the orthogonal complement of \p this->GetProjection(b).
248     /// That is:
249     /// \code
250     ///  *this - this->GetProjection(b)
251     /// \endcode
252     GfVec3f GetComplement(GfVec3f const &b) const {
253         return *this - this->GetProjection(b);
254     }
255 
256     /// Squared length.
257     float GetLengthSq() const {
258         return *this * *this;
259     }
260 
261     /// Length
262     float GetLength() const {
263         // TODO should use GfSqrt.
264         return sqrt(GetLengthSq());
265     }
266 
267     /// Normalizes the vector in place to unit length, returning the
268     /// length before normalization. If the length of the vector is
269     /// smaller than \p eps, then the vector is set to vector/\c eps.
270     /// The original length of the vector is returned. See also GfNormalize().
271     ///
272     /// \todo This was fixed for bug 67777. This is a gcc64 optimizer bug.
273     /// By tickling the code, it no longer tries to write into
274     /// an illegal memory address (in the code section of memory).
275     float Normalize(float eps = GF_MIN_VECTOR_LENGTH) {
276         // TODO this seems suspect...  suggest dividing by length so long as
277         // length is not zero.
278         float length = GetLength();
279         *this /= (length > eps) ? length : eps;
280         return length;
281     }
282 
283     GfVec3f GetNormalized(float eps = GF_MIN_VECTOR_LENGTH) const {
284         GfVec3f normalized(*this);
285         normalized.Normalize(eps);
286         return normalized;
287     }
288 
289     /// Orthogonalize and optionally normalize a set of basis vectors. This
290     /// uses an iterative method that is very stable even when the vectors are
291     /// far from orthogonal (close to colinear).  The number of iterations and
292     /// thus the computation time does increase as the vectors become close to
293     /// colinear, however. Returns a bool specifying whether the solution
294     /// converged after a number of iterations.  If it did not converge, the
295     /// returned vectors will be as close as possible to orthogonal within the
296     /// iteration limit. Colinear vectors will be unaltered, and the method
297     /// will return false.
298     GF_API
299     static bool OrthogonalizeBasis(
300         GfVec3f *tx, GfVec3f *ty, GfVec3f *tz,
301         const bool normalize,
302         double eps = GF_MIN_ORTHO_TOLERANCE);
303 
304     /// Sets \c v1 and \c v2 to unit vectors such that v1, v2 and *this are
305     /// mutually orthogonal.  If the length L of *this is smaller than \c eps,
306     /// then v1 and v2 will have magnitude L/eps.  As a result, the function
307     /// delivers a continuous result as *this shrinks in length.
308     GF_API
309     void BuildOrthonormalFrame(GfVec3f *v1, GfVec3f *v2,
310                     float eps = GF_MIN_VECTOR_LENGTH) const;
311 
312 
313 private:
314     float _data[3];
315 };
316 
317 /// Output a GfVec3f.
318 /// \ingroup group_gf_DebuggingOutput
319 GF_API std::ostream& operator<<(std::ostream &, GfVec3f const &);
320 
321 
322 PXR_NAMESPACE_CLOSE_SCOPE
323 
324 #include "pxr/base/gf/vec3d.h"
325 #include "pxr/base/gf/vec3h.h"
326 #include "pxr/base/gf/vec3i.h"
327 
328 PXR_NAMESPACE_OPEN_SCOPE
329 
330 inline
331 GfVec3f::GfVec3f(class GfVec3d const &other)
332 {
333     _data[0] = other[0];
334     _data[1] = other[1];
335     _data[2] = other[2];
336 }
337 inline
338 GfVec3f::GfVec3f(class GfVec3h const &other)
339 {
340     _data[0] = other[0];
341     _data[1] = other[1];
342     _data[2] = other[2];
343 }
344 inline
345 GfVec3f::GfVec3f(class GfVec3i const &other)
346 {
347     _data[0] = other[0];
348     _data[1] = other[1];
349     _data[2] = other[2];
350 }
351 
352 /// Returns component-wise multiplication of vectors \p v1 and \p v2.
353 inline GfVec3f
354 GfCompMult(GfVec3f const &v1, GfVec3f const &v2) {
355     return GfVec3f(
356         v1[0] * v2[0],
357         v1[1] * v2[1],
358         v1[2] * v2[2]
359         );
360 }
361 
362 /// Returns component-wise quotient of vectors \p v1 and \p v2.
363 inline GfVec3f
364 GfCompDiv(GfVec3f const &v1, GfVec3f const &v2) {
365     return GfVec3f(
366         v1[0] / v2[0],
367         v1[1] / v2[1],
368         v1[2] / v2[2]
369         );
370 }
371 
372 /// Returns the dot (inner) product of two vectors.
373 inline float
374 GfDot(GfVec3f const &v1, GfVec3f const &v2) {
375     return v1 * v2;
376 }
377 
378 
379 /// Returns the geometric length of \c v.
380 inline float
381 GfGetLength(GfVec3f const &v)
382 {
383     return v.GetLength();
384 }
385 
386 /// Normalizes \c *v in place to unit length, returning the length before
387 /// normalization. If the length of \c *v is smaller than \p eps then \c *v is
388 /// set to \c *v/eps.  The original length of \c *v is returned.
389 inline float
390 GfNormalize(GfVec3f *v, float eps = GF_MIN_VECTOR_LENGTH)
391 {
392     return v->Normalize(eps);
393 }
394 
395 /// Returns a normalized (unit-length) vector with the same direction as \p v.
396 /// If the length of this vector is smaller than \p eps, the vector divided by
397 /// \p eps is returned.
398 inline GfVec3f
399 GfGetNormalized(GfVec3f const &v, float eps = GF_MIN_VECTOR_LENGTH)
400 {
401     return v.GetNormalized(eps);
402 }
403 
404 /// Returns the projection of \p a onto \p b. That is:
405 /// \code
406 /// b * (a * b)
407 /// \endcode
408 inline GfVec3f
409 GfGetProjection(GfVec3f const &a, GfVec3f const &b)
410 {
411     return a.GetProjection(b);
412 }
413 
414 /// Returns the orthogonal complement of \p a.GetProjection(b). That is:
415 /// \code
416 ///  a - a.GetProjection(b)
417 /// \endcode
418 inline GfVec3f
419 GfGetComplement(GfVec3f const &a, GfVec3f const &b)
420 {
421     return a.GetComplement(b);
422 }
423 
424 /// Tests for equality within a given tolerance, returning \c true if the
425 /// length of the difference vector is less than or equal to \p tolerance.
426 inline bool
427 GfIsClose(GfVec3f const &v1, GfVec3f const &v2, double tolerance)
428 {
429     GfVec3f delta = v1 - v2;
430     return delta.GetLengthSq() <= tolerance * tolerance;
431 }
432 
433 
434 GF_API bool
435 GfOrthogonalizeBasis(GfVec3f *tx, GfVec3f *ty, GfVec3f *tz,
436                      bool normalize, double eps = GF_MIN_ORTHO_TOLERANCE);
437 
438 GF_API void
439 GfBuildOrthonormalFrame(GfVec3f const &v0,
440                         GfVec3f* v1,
441                         GfVec3f* v2,
442                         float eps = GF_MIN_VECTOR_LENGTH);
443 
444 /// Returns the cross product of \p v1 and \p v2.
445 inline GfVec3f
446 GfCross(GfVec3f const &v1, GfVec3f const &v2)
447 {
448     return GfVec3f(
449         v1[1] * v2[2] - v1[2] * v2[1],
450         v1[2] * v2[0] - v1[0] * v2[2],
451         v1[0] * v2[1] - v1[1] * v2[0]);
452 }
453 
454 /// Returns the cross product of \p v1 and \p v2.
455 /// \see GfCross()
456 inline GfVec3f
457 operator^(GfVec3f const &v1, GfVec3f const &v2)
458 {
459     return GfCross(v1, v2);
460 }
461 
462 /// Spherical linear interpolation in three dimensions.
463 GF_API GfVec3f
464 GfSlerp(double alpha, GfVec3f const &v0, GfVec3f const &v1);
465 
466 
467 
468 PXR_NAMESPACE_CLOSE_SCOPE
469 
470 #endif // PXR_BASE_GF_VEC3F_H
471