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