ImathShear.h 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689
  1. //
  2. // SPDX-License-Identifier: BSD-3-Clause
  3. // Copyright Contributors to the OpenEXR Project.
  4. //
  5. //
  6. // A representation of a shear transformation
  7. //
  8. #ifndef INCLUDED_IMATHSHEAR_H
  9. #define INCLUDED_IMATHSHEAR_H
  10. #include "ImathExport.h"
  11. #include "ImathNamespace.h"
  12. #include "ImathMath.h"
  13. #include "ImathVec.h"
  14. #include <iostream>
  15. IMATH_INTERNAL_NAMESPACE_HEADER_ENTER
  16. ///
  17. /// Shear6 class template.
  18. ///
  19. /// A shear matrix is technically defined as having a single nonzero
  20. /// off-diagonal element; more generally, a shear transformation is
  21. /// defined by those off-diagonal elements, so in 3D, that means there
  22. /// are 6 possible elements/coefficients:
  23. ///
  24. /// | X' | | 1 YX ZX 0 | | X |
  25. /// | Y' | | XY 1 ZY 0 | | Y |
  26. /// | Z' | = | XZ YZ 1 0 | = | Z |
  27. /// | 1 | | 0 0 0 1 | | 1 |
  28. ///
  29. /// X' = X + YX * Y + ZX * Z
  30. /// Y' = YX * X + Y + ZY * Z
  31. /// Z` = XZ * X + YZ * Y + Z
  32. ///
  33. /// See
  34. /// https://www.cs.drexel.edu/~david/Classes/CS430/Lectures/L-04_3DTransformations.6.pdf
  35. ///
  36. /// Those variable elements correspond to the 6 values in a Shear6.
  37. /// So, looking at those equations, "Shear YX", for example, means
  38. /// that for any point transformed by that matrix, its X values will
  39. /// have some of their Y values added. If you're talking
  40. /// about "Axis A has values from Axis B added to it", there are 6
  41. /// permutations for A and B (XY, XZ, YX, YZ, ZX, ZY).
  42. ///
  43. /// Not that Maya has only three values, which represent the
  44. /// lower/upper (depending on column/row major) triangle of the
  45. /// matrix. Houdini is the same as Maya (see
  46. /// https://www.sidefx.com/docs/houdini/props/obj.html) in this
  47. /// respect.
  48. ///
  49. /// There's another way to look at it. A general affine transformation
  50. /// in 3D has 12 degrees of freedom - 12 "available" elements in the
  51. /// 4x4 matrix since a single row/column must be (0,0,0,1). If you
  52. /// add up the degrees of freedom from Maya:
  53. ///
  54. /// - 3 translation
  55. /// - 3 rotation
  56. /// - 3 scale
  57. /// - 3 shear
  58. ///
  59. /// You obviously get the full 12. So technically, the Shear6 option
  60. /// of having all 6 shear options is overkill; Imath/Shear6 has 15
  61. /// values for a 12-degree-of-freedom transformation. This means that
  62. /// any nonzero values in those last 3 shear coefficients can be
  63. /// represented in those standard 12 degrees of freedom. Here's a
  64. /// python example of how to do that:
  65. ///
  66. ///
  67. /// >>> import imath
  68. /// >>> M = imath.M44f()
  69. /// >>> s = imath.V3f()
  70. /// >>> h = imath.V3f()
  71. /// >>> r = imath.V3f()
  72. /// >>> t = imath.V3f()
  73. /// # Use Shear.YX (index 3), which is an "extra" shear value
  74. /// >>> M.setShear((0,0,0,1,0,0))
  75. /// M44f((1, 1, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 0, 0, 1))
  76. /// >>> M.extractSHRT(s, h, r, t)
  77. /// 1
  78. /// >>> s
  79. /// V3f(1.41421354, 0.707106769, 1)
  80. /// >>> h
  81. /// V3f(1, 0, 0)
  82. /// >>> r
  83. /// V3f(0, -0, 0.785398185)
  84. /// >>> t
  85. /// V3f(0, 0, 0)
  86. ///
  87. /// That shows how to decompose a transform matrix with one of those
  88. /// "extra" shear coefficients into those standard 12 degrees of
  89. /// freedom. But it's not necessarily intuitive; in this case, a
  90. /// single non-zero shear coefficient resulted in a transform that has
  91. /// non-uniform scale, a single "standard" shear value, and some
  92. /// rotation.
  93. ///
  94. /// So, it would seem that any transform with those extra shear
  95. /// values set could be translated into Maya to produce the exact same
  96. /// transformation matrix; but doing this is probably pretty
  97. /// undesirable, since the result would have some surprising values on
  98. /// the other transformation attributes, despite being technically
  99. /// correct.
  100. ///
  101. /// This usage of "degrees of freedom" is a bit hand-wavey here;
  102. /// having a total of 12 inputs into the construction of a standard
  103. /// transformation matrix doesn't necessarily mean that the matrix has
  104. /// 12 true degrees of freedom, but the standard
  105. /// translation/rotation/scale/shear matrices have the right
  106. /// construction to ensure that.
  107. ///
  108. template <class T> class IMATH_EXPORT_TEMPLATE_TYPE Shear6
  109. {
  110. public:
  111. /// @{
  112. /// @name Direct access to members
  113. T xy, xz, yz, yx, zx, zy;
  114. /// @}
  115. /// Element access
  116. IMATH_HOSTDEVICE IMATH_CONSTEXPR14 T& operator[] (int i);
  117. /// Element access
  118. IMATH_HOSTDEVICE constexpr const T& operator[] (int i) const;
  119. /// @{
  120. /// @name Constructors and Assignment
  121. /// Initialize to 0
  122. IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Shear6();
  123. /// Initialize to the given XY, XZ, YZ values
  124. IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Shear6 (T XY, T XZ, T YZ);
  125. /// Initialize to the given XY, XZ, YZ values held in (v.x, v.y, v.z)
  126. IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Shear6 (const Vec3<T>& v);
  127. /// Initialize to the given XY, XZ, YZ values held in (v.x, v.y, v.z)
  128. template <class S>
  129. IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Shear6 (const Vec3<S>& v);
  130. /// Initialize to the given (XY XZ YZ YX ZX ZY) values
  131. IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Shear6 (T XY,
  132. T XZ,
  133. T YZ,
  134. T YX,
  135. T ZX,
  136. T ZY);
  137. /// Copy constructor
  138. IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Shear6 (const Shear6& h);
  139. /// Construct from a Shear6 object of another base type
  140. template <class S> IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Shear6 (const Shear6<S>& h);
  141. /// Assignment
  142. IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Shear6& operator= (const Shear6& h);
  143. /// Assignment from vector
  144. template <class S>
  145. IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Shear6& operator= (const Vec3<S>& v);
  146. /// Destructor
  147. ~Shear6() = default;
  148. /// @}
  149. /// @{
  150. /// @name Compatibility with Sb
  151. /// Set the value
  152. template <class S> IMATH_HOSTDEVICE void setValue (S XY, S XZ, S YZ, S YX, S ZX, S ZY);
  153. /// Set the value
  154. template <class S> IMATH_HOSTDEVICE void setValue (const Shear6<S>& h);
  155. /// Return the values
  156. template <class S>
  157. IMATH_HOSTDEVICE void getValue (S& XY, S& XZ, S& YZ, S& YX, S& ZX, S& ZY) const;
  158. /// Return the value in `h`
  159. template <class S> IMATH_HOSTDEVICE void getValue (Shear6<S>& h) const;
  160. /// Return a raw pointer to the array of values
  161. IMATH_HOSTDEVICE T* getValue();
  162. /// Return a raw pointer to the array of values
  163. IMATH_HOSTDEVICE const T* getValue() const;
  164. /// @}
  165. /// @{
  166. /// @name Arithmetic and Comparison
  167. /// Equality
  168. template <class S> IMATH_HOSTDEVICE constexpr bool operator== (const Shear6<S>& h) const;
  169. /// Inequality
  170. template <class S> IMATH_HOSTDEVICE constexpr bool operator!= (const Shear6<S>& h) const;
  171. /// Compare two shears and test if they are "approximately equal":
  172. /// @return True if the coefficients of this and h are the same with
  173. /// an absolute error of no more than e, i.e., for all i
  174. /// abs (this[i] - h[i]) <= e
  175. IMATH_HOSTDEVICE IMATH_CONSTEXPR14 bool equalWithAbsError (const Shear6<T>& h, T e) const;
  176. /// Compare two shears and test if they are "approximately equal":
  177. /// @return True if the coefficients of this and h are the same with
  178. /// a relative error of no more than e, i.e., for all i
  179. /// abs (this[i] - h[i]) <= e * abs (this[i])
  180. IMATH_HOSTDEVICE IMATH_CONSTEXPR14 bool equalWithRelError (const Shear6<T>& h, T e) const;
  181. /// Component-wise addition
  182. IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Shear6& operator+= (const Shear6& h);
  183. /// Component-wise addition
  184. IMATH_HOSTDEVICE constexpr Shear6 operator+ (const Shear6& h) const;
  185. /// Component-wise subtraction
  186. IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Shear6& operator-= (const Shear6& h);
  187. /// Component-wise subtraction
  188. IMATH_HOSTDEVICE constexpr Shear6 operator- (const Shear6& h) const;
  189. /// Component-wise multiplication by -1
  190. IMATH_HOSTDEVICE constexpr Shear6 operator-() const;
  191. /// Component-wise multiplication by -1
  192. IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Shear6& negate();
  193. /// Component-wise multiplication
  194. IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Shear6& operator*= (const Shear6& h);
  195. /// Scalar multiplication
  196. IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Shear6& operator*= (T a);
  197. /// Component-wise multiplication
  198. IMATH_HOSTDEVICE constexpr Shear6 operator* (const Shear6& h) const;
  199. /// Scalar multiplication
  200. IMATH_HOSTDEVICE constexpr Shear6 operator* (T a) const;
  201. /// Component-wise division
  202. IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Shear6& operator/= (const Shear6& h);
  203. /// Scalar division
  204. IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Shear6& operator/= (T a);
  205. /// Component-wise division
  206. IMATH_HOSTDEVICE constexpr Shear6 operator/ (const Shear6& h) const;
  207. /// Scalar division
  208. IMATH_HOSTDEVICE constexpr Shear6 operator/ (T a) const;
  209. /// @}
  210. /// @{
  211. /// @name Numerical Limits
  212. /// Largest possible negative value
  213. IMATH_HOSTDEVICE constexpr static T baseTypeLowest() IMATH_NOEXCEPT { return std::numeric_limits<T>::lowest(); }
  214. /// Largest possible positive value
  215. IMATH_HOSTDEVICE constexpr static T baseTypeMax() IMATH_NOEXCEPT { return std::numeric_limits<T>::max(); }
  216. /// Smallest possible positive value
  217. IMATH_HOSTDEVICE constexpr static T baseTypeSmallest() IMATH_NOEXCEPT { return std::numeric_limits<T>::min(); }
  218. /// Smallest possible e for which 1+e != 1
  219. IMATH_HOSTDEVICE constexpr static T baseTypeEpsilon() IMATH_NOEXCEPT { return std::numeric_limits<T>::epsilon(); }
  220. /// @}
  221. /// Return the number of dimensions, i.e. 6
  222. IMATH_HOSTDEVICE constexpr static unsigned int dimensions() { return 6; }
  223. /// The base type: In templates that accept a parameter `V` (could
  224. /// be a Color4), you can refer to `T` as `V::BaseType`
  225. typedef T BaseType;
  226. };
  227. /// Stream output, as "(xy xz yz yx zx zy)"
  228. template <class T> std::ostream& operator<< (std::ostream& s, const Shear6<T>& h);
  229. /// Reverse multiplication: scalar * Shear6<T>
  230. template <class S, class T>
  231. IMATH_HOSTDEVICE constexpr Shear6<T> operator* (S a, const Shear6<T>& h);
  232. /// 3D shear of type float
  233. typedef Vec3<float> Shear3f;
  234. /// 3D shear of type double
  235. typedef Vec3<double> Shear3d;
  236. /// Shear6 of type float
  237. typedef Shear6<float> Shear6f;
  238. /// Shear6 of type double
  239. typedef Shear6<double> Shear6d;
  240. //-----------------------
  241. // Implementation of Shear6
  242. //-----------------------
  243. template <class T>
  244. IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline T&
  245. Shear6<T>::operator[] (int i)
  246. {
  247. return (&xy)[i]; // NOSONAR - suppress SonarCloud bug report.
  248. }
  249. template <class T>
  250. IMATH_HOSTDEVICE constexpr inline const T&
  251. Shear6<T>::operator[] (int i) const
  252. {
  253. return (&xy)[i]; // NOSONAR - suppress SonarCloud bug report.
  254. }
  255. template <class T> IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline Shear6<T>::Shear6()
  256. {
  257. xy = xz = yz = yx = zx = zy = 0;
  258. }
  259. template <class T> IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline Shear6<T>::Shear6 (T XY, T XZ, T YZ)
  260. {
  261. xy = XY;
  262. xz = XZ;
  263. yz = YZ;
  264. yx = 0;
  265. zx = 0;
  266. zy = 0;
  267. }
  268. template <class T> IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline Shear6<T>::Shear6 (const Vec3<T>& v)
  269. {
  270. xy = v.x;
  271. xz = v.y;
  272. yz = v.z;
  273. yx = 0;
  274. zx = 0;
  275. zy = 0;
  276. }
  277. template <class T>
  278. template <class S>
  279. IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline Shear6<T>::Shear6 (const Vec3<S>& v)
  280. {
  281. xy = T (v.x);
  282. xz = T (v.y);
  283. yz = T (v.z);
  284. yx = 0;
  285. zx = 0;
  286. zy = 0;
  287. }
  288. template <class T> IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline Shear6<T>::Shear6 (T XY, T XZ, T YZ, T YX, T ZX, T ZY)
  289. {
  290. xy = XY;
  291. xz = XZ;
  292. yz = YZ;
  293. yx = YX;
  294. zx = ZX;
  295. zy = ZY;
  296. }
  297. template <class T> IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline Shear6<T>::Shear6 (const Shear6& h)
  298. {
  299. xy = h.xy;
  300. xz = h.xz;
  301. yz = h.yz;
  302. yx = h.yx;
  303. zx = h.zx;
  304. zy = h.zy;
  305. }
  306. template <class T>
  307. template <class S>
  308. IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline Shear6<T>::Shear6 (const Shear6<S>& h)
  309. {
  310. xy = T (h.xy);
  311. xz = T (h.xz);
  312. yz = T (h.yz);
  313. yx = T (h.yx);
  314. zx = T (h.zx);
  315. zy = T (h.zy);
  316. }
  317. template <class T>
  318. IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline const Shear6<T>&
  319. Shear6<T>::operator= (const Shear6& h)
  320. {
  321. xy = h.xy;
  322. xz = h.xz;
  323. yz = h.yz;
  324. yx = h.yx;
  325. zx = h.zx;
  326. zy = h.zy;
  327. return *this;
  328. }
  329. template <class T>
  330. template <class S>
  331. IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline const Shear6<T>&
  332. Shear6<T>::operator= (const Vec3<S>& v)
  333. {
  334. xy = T (v.x);
  335. xz = T (v.y);
  336. yz = T (v.z);
  337. yx = 0;
  338. zx = 0;
  339. zy = 0;
  340. return *this;
  341. }
  342. template <class T>
  343. template <class S>
  344. IMATH_HOSTDEVICE inline void
  345. Shear6<T>::setValue (S XY, S XZ, S YZ, S YX, S ZX, S ZY)
  346. {
  347. xy = T (XY);
  348. xz = T (XZ);
  349. yz = T (YZ);
  350. yx = T (YX);
  351. zx = T (ZX);
  352. zy = T (ZY);
  353. }
  354. template <class T>
  355. template <class S>
  356. IMATH_HOSTDEVICE inline void
  357. Shear6<T>::setValue (const Shear6<S>& h)
  358. {
  359. xy = T (h.xy);
  360. xz = T (h.xz);
  361. yz = T (h.yz);
  362. yx = T (h.yx);
  363. zx = T (h.zx);
  364. zy = T (h.zy);
  365. }
  366. template <class T>
  367. template <class S>
  368. IMATH_HOSTDEVICE inline void
  369. Shear6<T>::getValue (S& XY, S& XZ, S& YZ, S& YX, S& ZX, S& ZY) const
  370. {
  371. XY = S (xy);
  372. XZ = S (xz);
  373. YZ = S (yz);
  374. YX = S (yx);
  375. ZX = S (zx);
  376. ZY = S (zy);
  377. }
  378. template <class T>
  379. template <class S>
  380. IMATH_HOSTDEVICE inline void
  381. Shear6<T>::getValue (Shear6<S>& h) const
  382. {
  383. h.xy = S (xy);
  384. h.xz = S (xz);
  385. h.yz = S (yz);
  386. h.yx = S (yx);
  387. h.zx = S (zx);
  388. h.zy = S (zy);
  389. }
  390. template <class T>
  391. IMATH_HOSTDEVICE inline T*
  392. Shear6<T>::getValue()
  393. {
  394. return (T*) &xy;
  395. }
  396. template <class T>
  397. IMATH_HOSTDEVICE inline const T*
  398. Shear6<T>::getValue() const
  399. {
  400. return (const T*) &xy;
  401. }
  402. template <class T>
  403. template <class S>
  404. IMATH_HOSTDEVICE constexpr inline bool
  405. Shear6<T>::operator== (const Shear6<S>& h) const
  406. {
  407. return xy == h.xy && xz == h.xz && yz == h.yz && yx == h.yx && zx == h.zx && zy == h.zy;
  408. }
  409. template <class T>
  410. template <class S>
  411. IMATH_HOSTDEVICE constexpr inline bool
  412. Shear6<T>::operator!= (const Shear6<S>& h) const
  413. {
  414. return xy != h.xy || xz != h.xz || yz != h.yz || yx != h.yx || zx != h.zx || zy != h.zy;
  415. }
  416. template <class T>
  417. IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline bool
  418. Shear6<T>::equalWithAbsError (const Shear6<T>& h, T e) const
  419. {
  420. for (int i = 0; i < 6; i++)
  421. if (!IMATH_INTERNAL_NAMESPACE::equalWithAbsError ((*this)[i], h[i], e))
  422. return false;
  423. return true;
  424. }
  425. template <class T>
  426. IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline bool
  427. Shear6<T>::equalWithRelError (const Shear6<T>& h, T e) const
  428. {
  429. for (int i = 0; i < 6; i++)
  430. if (!IMATH_INTERNAL_NAMESPACE::equalWithRelError ((*this)[i], h[i], e))
  431. return false;
  432. return true;
  433. }
  434. template <class T>
  435. IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline const Shear6<T>&
  436. Shear6<T>::operator+= (const Shear6& h)
  437. {
  438. xy += h.xy;
  439. xz += h.xz;
  440. yz += h.yz;
  441. yx += h.yx;
  442. zx += h.zx;
  443. zy += h.zy;
  444. return *this;
  445. }
  446. template <class T>
  447. IMATH_HOSTDEVICE constexpr inline Shear6<T>
  448. Shear6<T>::operator+ (const Shear6& h) const
  449. {
  450. return Shear6 (xy + h.xy, xz + h.xz, yz + h.yz, yx + h.yx, zx + h.zx, zy + h.zy);
  451. }
  452. template <class T>
  453. IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline const Shear6<T>&
  454. Shear6<T>::operator-= (const Shear6& h)
  455. {
  456. xy -= h.xy;
  457. xz -= h.xz;
  458. yz -= h.yz;
  459. yx -= h.yx;
  460. zx -= h.zx;
  461. zy -= h.zy;
  462. return *this;
  463. }
  464. template <class T>
  465. IMATH_HOSTDEVICE constexpr inline Shear6<T>
  466. Shear6<T>::operator- (const Shear6& h) const
  467. {
  468. return Shear6 (xy - h.xy, xz - h.xz, yz - h.yz, yx - h.yx, zx - h.zx, zy - h.zy);
  469. }
  470. template <class T>
  471. IMATH_HOSTDEVICE constexpr inline Shear6<T>
  472. Shear6<T>::operator-() const
  473. {
  474. return Shear6 (-xy, -xz, -yz, -yx, -zx, -zy);
  475. }
  476. template <class T>
  477. IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline const Shear6<T>&
  478. Shear6<T>::negate()
  479. {
  480. xy = -xy;
  481. xz = -xz;
  482. yz = -yz;
  483. yx = -yx;
  484. zx = -zx;
  485. zy = -zy;
  486. return *this;
  487. }
  488. template <class T>
  489. IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline const Shear6<T>&
  490. Shear6<T>::operator*= (const Shear6& h)
  491. {
  492. xy *= h.xy;
  493. xz *= h.xz;
  494. yz *= h.yz;
  495. yx *= h.yx;
  496. zx *= h.zx;
  497. zy *= h.zy;
  498. return *this;
  499. }
  500. template <class T>
  501. IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline const Shear6<T>&
  502. Shear6<T>::operator*= (T a)
  503. {
  504. xy *= a;
  505. xz *= a;
  506. yz *= a;
  507. yx *= a;
  508. zx *= a;
  509. zy *= a;
  510. return *this;
  511. }
  512. template <class T>
  513. IMATH_HOSTDEVICE constexpr inline Shear6<T>
  514. Shear6<T>::operator* (const Shear6& h) const
  515. {
  516. return Shear6 (xy * h.xy, xz * h.xz, yz * h.yz, yx * h.yx, zx * h.zx, zy * h.zy);
  517. }
  518. template <class T>
  519. IMATH_HOSTDEVICE constexpr inline Shear6<T>
  520. Shear6<T>::operator* (T a) const
  521. {
  522. return Shear6 (xy * a, xz * a, yz * a, yx * a, zx * a, zy * a);
  523. }
  524. template <class T>
  525. IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline const Shear6<T>&
  526. Shear6<T>::operator/= (const Shear6& h)
  527. {
  528. xy /= h.xy;
  529. xz /= h.xz;
  530. yz /= h.yz;
  531. yx /= h.yx;
  532. zx /= h.zx;
  533. zy /= h.zy;
  534. return *this;
  535. }
  536. template <class T>
  537. IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline const Shear6<T>&
  538. Shear6<T>::operator/= (T a)
  539. {
  540. xy /= a;
  541. xz /= a;
  542. yz /= a;
  543. yx /= a;
  544. zx /= a;
  545. zy /= a;
  546. return *this;
  547. }
  548. template <class T>
  549. IMATH_HOSTDEVICE constexpr inline Shear6<T>
  550. Shear6<T>::operator/ (const Shear6& h) const
  551. {
  552. return Shear6 (xy / h.xy, xz / h.xz, yz / h.yz, yx / h.yx, zx / h.zx, zy / h.zy);
  553. }
  554. template <class T>
  555. IMATH_HOSTDEVICE constexpr inline Shear6<T>
  556. Shear6<T>::operator/ (T a) const
  557. {
  558. return Shear6 (xy / a, xz / a, yz / a, yx / a, zx / a, zy / a);
  559. }
  560. //-----------------------------
  561. // Stream output implementation
  562. //-----------------------------
  563. template <class T>
  564. std::ostream&
  565. operator<< (std::ostream& s, const Shear6<T>& h)
  566. {
  567. return s << '(' << h.xy << ' ' << h.xz << ' ' << h.yz << h.yx << ' ' << h.zx << ' ' << h.zy
  568. << ')';
  569. }
  570. //-----------------------------------------
  571. // Implementation of reverse multiplication
  572. //-----------------------------------------
  573. template <class S, class T>
  574. IMATH_HOSTDEVICE constexpr inline Shear6<T>
  575. operator* (S a, const Shear6<T>& h)
  576. {
  577. return Shear6<T> (a * h.xy, a * h.xz, a * h.yz, a * h.yx, a * h.zx, a * h.zy);
  578. }
  579. IMATH_INTERNAL_NAMESPACE_HEADER_EXIT
  580. #endif // INCLUDED_IMATHSHEAR_H