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