1///////////////////////////////////////////////////////////////////////////
2//
3// Copyright (c) 2004-2012, Industrial Light & Magic, a division of Lucas
4// Digital Ltd. LLC
5//
6// All rights reserved.
7//
8// Redistribution and use in source and binary forms, with or without
9// modification, are permitted provided that the following conditions are
10// met:
11// * Redistributions of source code must retain the above copyright
12// notice, this list of conditions and the following disclaimer.
13// * Redistributions in binary form must reproduce the above
14// copyright notice, this list of conditions and the following disclaimer
15// in the documentation and/or other materials provided with the
16// distribution.
17// * Neither the name of Industrial Light & Magic nor the names of
18// its contributors may be used to endorse or promote products derived
19// from this software without specific prior written permission.
20//
21// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32//
33///////////////////////////////////////////////////////////////////////////
34
35
36
37#ifndef INCLUDED_IMATHVEC_H
38#define INCLUDED_IMATHVEC_H
39
40//----------------------------------------------------
41//
42// 2D, 3D and 4D point/vector class templates
43//
44//----------------------------------------------------
45
46#include "ImathExc.h"
47#include "ImathLimits.h"
48#include "ImathMath.h"
49#include "ImathNamespace.h"
50
51#include <iostream>
52
53#if (defined _WIN32 || defined _WIN64) && defined _MSC_VER
54// suppress exception specification warnings
55#pragma warning(push)
56#pragma warning(disable:4290)
57#endif
58
59
60IMATH_INTERNAL_NAMESPACE_HEADER_ENTER
61
62template <class T> class Vec2;
63template <class T> class Vec3;
64template <class T> class Vec4;
65
66enum InfException {INF_EXCEPTION};
67
68
69template <class T> class Vec2
70{
71 public:
72
73 //-------------------
74 // Access to elements
75 //-------------------
76
77 T x, y;
78
79 T & operator [] (int i);
80 const T & operator [] (int i) const;
81
82
83 //-------------
84 // Constructors
85 //-------------
86
87 Vec2 (); // no initialization
88 explicit Vec2 (T a); // (a a)
89 Vec2 (T a, T b); // (a b)
90
91
92 //---------------------------------
93 // Copy constructors and assignment
94 //---------------------------------
95
96 Vec2 (const Vec2 &v);
97 template <class S> Vec2 (const Vec2<S> &v);
98
99 const Vec2 & operator = (const Vec2 &v);
100
101 //------------
102 // Destructor
103 //------------
104
105 ~Vec2 () = default;
106
107 //----------------------
108 // Compatibility with Sb
109 //----------------------
110
111 template <class S>
112 void setValue (S a, S b);
113
114 template <class S>
115 void setValue (const Vec2<S> &v);
116
117 template <class S>
118 void getValue (S &a, S &b) const;
119
120 template <class S>
121 void getValue (Vec2<S> &v) const;
122
123 T * getValue ();
124 const T * getValue () const;
125
126
127 //---------
128 // Equality
129 //---------
130
131 template <class S>
132 bool operator == (const Vec2<S> &v) const;
133
134 template <class S>
135 bool operator != (const Vec2<S> &v) const;
136
137
138 //-----------------------------------------------------------------------
139 // Compare two vectors and test if they are "approximately equal":
140 //
141 // equalWithAbsError (v, e)
142 //
143 // Returns true if the coefficients of this and v are the same with
144 // an absolute error of no more than e, i.e., for all i
145 //
146 // abs (this[i] - v[i]) <= e
147 //
148 // equalWithRelError (v, e)
149 //
150 // Returns true if the coefficients of this and v are the same with
151 // a relative error of no more than e, i.e., for all i
152 //
153 // abs (this[i] - v[i]) <= e * abs (this[i])
154 //-----------------------------------------------------------------------
155
156 bool equalWithAbsError (const Vec2<T> &v, T e) const;
157 bool equalWithRelError (const Vec2<T> &v, T e) const;
158
159 //------------
160 // Dot product
161 //------------
162
163 T dot (const Vec2 &v) const;
164 T operator ^ (const Vec2 &v) const;
165
166
167 //------------------------------------------------
168 // Right-handed cross product, i.e. z component of
169 // Vec3 (this->x, this->y, 0) % Vec3 (v.x, v.y, 0)
170 //------------------------------------------------
171
172 T cross (const Vec2 &v) const;
173 T operator % (const Vec2 &v) const;
174
175
176 //------------------------
177 // Component-wise addition
178 //------------------------
179
180 const Vec2 & operator += (const Vec2 &v);
181 Vec2 operator + (const Vec2 &v) const;
182
183
184 //---------------------------
185 // Component-wise subtraction
186 //---------------------------
187
188 const Vec2 & operator -= (const Vec2 &v);
189 Vec2 operator - (const Vec2 &v) const;
190
191
192 //------------------------------------
193 // Component-wise multiplication by -1
194 //------------------------------------
195
196 Vec2 operator - () const;
197 const Vec2 & negate ();
198
199
200 //------------------------------
201 // Component-wise multiplication
202 //------------------------------
203
204 const Vec2 & operator *= (const Vec2 &v);
205 const Vec2 & operator *= (T a);
206 Vec2 operator * (const Vec2 &v) const;
207 Vec2 operator * (T a) const;
208
209
210 //------------------------
211 // Component-wise division
212 //------------------------
213
214 const Vec2 & operator /= (const Vec2 &v);
215 const Vec2 & operator /= (T a);
216 Vec2 operator / (const Vec2 &v) const;
217 Vec2 operator / (T a) const;
218
219
220 //----------------------------------------------------------------
221 // Length and normalization: If v.length() is 0.0, v.normalize()
222 // and v.normalized() produce a null vector; v.normalizeExc() and
223 // v.normalizedExc() throw a NullVecExc.
224 // v.normalizeNonNull() and v.normalizedNonNull() are slightly
225 // faster than the other normalization routines, but if v.length()
226 // is 0.0, the result is undefined.
227 //----------------------------------------------------------------
228
229 T length () const;
230 T length2 () const;
231
232 const Vec2 & normalize (); // modifies *this
233 const Vec2 & normalizeExc ();
234 const Vec2 & normalizeNonNull ();
235
236 Vec2<T> normalized () const; // does not modify *this
237 Vec2<T> normalizedExc () const;
238 Vec2<T> normalizedNonNull () const;
239
240
241 //--------------------------------------------------------
242 // Number of dimensions, i.e. number of elements in a Vec2
243 //--------------------------------------------------------
244
245 static unsigned int dimensions() {return 2;}
246
247
248 //-------------------------------------------------
249 // Limitations of type T (see also class limits<T>)
250 //-------------------------------------------------
251
252 static T baseTypeMin() {return limits<T>::min();}
253 static T baseTypeMax() {return limits<T>::max();}
254 static T baseTypeSmallest() {return limits<T>::smallest();}
255 static T baseTypeEpsilon() {return limits<T>::epsilon();}
256
257
258 //--------------------------------------------------------------
259 // Base type -- in templates, which accept a parameter, V, which
260 // could be either a Vec2<T>, a Vec3<T>, or a Vec4<T> you can
261 // refer to T as V::BaseType
262 //--------------------------------------------------------------
263
264 typedef T BaseType;
265
266 private:
267
268 T lengthTiny () const;
269};
270
271
272template <class T> class Vec3
273{
274 public:
275
276 //-------------------
277 // Access to elements
278 //-------------------
279
280 T x, y, z;
281
282 T & operator [] (int i);
283 const T & operator [] (int i) const;
284
285
286 //-------------
287 // Constructors
288 //-------------
289
290 Vec3 (); // no initialization
291 explicit Vec3 (T a); // (a a a)
292 Vec3 (T a, T b, T c); // (a b c)
293
294
295 //---------------------------------
296 // Copy constructors and assignment
297 //---------------------------------
298
299 Vec3 (const Vec3 &v);
300 template <class S> Vec3 (const Vec3<S> &v);
301
302 const Vec3 & operator = (const Vec3 &v);
303
304 //-----------
305 // Destructor
306 //-----------
307
308 ~Vec3 () = default;
309
310 //---------------------------------------------------------
311 // Vec4 to Vec3 conversion, divides x, y and z by w:
312 //
313 // The one-argument conversion function divides by w even
314 // if w is zero. The result depends on how the environment
315 // handles floating-point exceptions.
316 //
317 // The two-argument version thows an InfPointExc exception
318 // if w is zero or if division by w would overflow.
319 //---------------------------------------------------------
320
321 template <class S> explicit Vec3 (const Vec4<S> &v);
322 template <class S> explicit Vec3 (const Vec4<S> &v, InfException);
323
324
325 //----------------------
326 // Compatibility with Sb
327 //----------------------
328
329 template <class S>
330 void setValue (S a, S b, S c);
331
332 template <class S>
333 void setValue (const Vec3<S> &v);
334
335 template <class S>
336 void getValue (S &a, S &b, S &c) const;
337
338 template <class S>
339 void getValue (Vec3<S> &v) const;
340
341 T * getValue();
342 const T * getValue() const;
343
344
345 //---------
346 // Equality
347 //---------
348
349 template <class S>
350 bool operator == (const Vec3<S> &v) const;
351
352 template <class S>
353 bool operator != (const Vec3<S> &v) const;
354
355 //-----------------------------------------------------------------------
356 // Compare two vectors and test if they are "approximately equal":
357 //
358 // equalWithAbsError (v, e)
359 //
360 // Returns true if the coefficients of this and v are the same with
361 // an absolute error of no more than e, i.e., for all i
362 //
363 // abs (this[i] - v[i]) <= e
364 //
365 // equalWithRelError (v, e)
366 //
367 // Returns true if the coefficients of this and v are the same with
368 // a relative error of no more than e, i.e., for all i
369 //
370 // abs (this[i] - v[i]) <= e * abs (this[i])
371 //-----------------------------------------------------------------------
372
373 bool equalWithAbsError (const Vec3<T> &v, T e) const;
374 bool equalWithRelError (const Vec3<T> &v, T e) const;
375
376 //------------
377 // Dot product
378 //------------
379
380 T dot (const Vec3 &v) const;
381 T operator ^ (const Vec3 &v) const;
382
383
384 //---------------------------
385 // Right-handed cross product
386 //---------------------------
387
388 Vec3 cross (const Vec3 &v) const;
389 const Vec3 & operator %= (const Vec3 &v);
390 Vec3 operator % (const Vec3 &v) const;
391
392
393 //------------------------
394 // Component-wise addition
395 //------------------------
396
397 const Vec3 & operator += (const Vec3 &v);
398 Vec3 operator + (const Vec3 &v) const;
399
400
401 //---------------------------
402 // Component-wise subtraction
403 //---------------------------
404
405 const Vec3 & operator -= (const Vec3 &v);
406 Vec3 operator - (const Vec3 &v) const;
407
408
409 //------------------------------------
410 // Component-wise multiplication by -1
411 //------------------------------------
412
413 Vec3 operator - () const;
414 const Vec3 & negate ();
415
416
417 //------------------------------
418 // Component-wise multiplication
419 //------------------------------
420
421 const Vec3 & operator *= (const Vec3 &v);
422 const Vec3 & operator *= (T a);
423 Vec3 operator * (const Vec3 &v) const;
424 Vec3 operator * (T a) const;
425
426
427 //------------------------
428 // Component-wise division
429 //------------------------
430
431 const Vec3 & operator /= (const Vec3 &v);
432 const Vec3 & operator /= (T a);
433 Vec3 operator / (const Vec3 &v) const;
434 Vec3 operator / (T a) const;
435
436
437 //----------------------------------------------------------------
438 // Length and normalization: If v.length() is 0.0, v.normalize()
439 // and v.normalized() produce a null vector; v.normalizeExc() and
440 // v.normalizedExc() throw a NullVecExc.
441 // v.normalizeNonNull() and v.normalizedNonNull() are slightly
442 // faster than the other normalization routines, but if v.length()
443 // is 0.0, the result is undefined.
444 //----------------------------------------------------------------
445
446 T length () const;
447 T length2 () const;
448
449 const Vec3 & normalize (); // modifies *this
450 const Vec3 & normalizeExc ();
451 const Vec3 & normalizeNonNull ();
452
453 Vec3<T> normalized () const; // does not modify *this
454 Vec3<T> normalizedExc () const;
455 Vec3<T> normalizedNonNull () const;
456
457
458 //--------------------------------------------------------
459 // Number of dimensions, i.e. number of elements in a Vec3
460 //--------------------------------------------------------
461
462 static unsigned int dimensions() {return 3;}
463
464
465 //-------------------------------------------------
466 // Limitations of type T (see also class limits<T>)
467 //-------------------------------------------------
468
469 static T baseTypeMin() {return limits<T>::min();}
470 static T baseTypeMax() {return limits<T>::max();}
471 static T baseTypeSmallest() {return limits<T>::smallest();}
472 static T baseTypeEpsilon() {return limits<T>::epsilon();}
473
474
475 //--------------------------------------------------------------
476 // Base type -- in templates, which accept a parameter, V, which
477 // could be either a Vec2<T>, a Vec3<T>, or a Vec4<T> you can
478 // refer to T as V::BaseType
479 //--------------------------------------------------------------
480
481 typedef T BaseType;
482
483 private:
484
485 T lengthTiny () const;
486};
487
488
489
490template <class T> class Vec4
491{
492 public:
493
494 //-------------------
495 // Access to elements
496 //-------------------
497
498 T x, y, z, w;
499
500 T & operator [] (int i);
501 const T & operator [] (int i) const;
502
503
504 //-------------
505 // Constructors
506 //-------------
507
508 Vec4 (); // no initialization
509 explicit Vec4 (T a); // (a a a a)
510 Vec4 (T a, T b, T c, T d); // (a b c d)
511
512
513 //---------------------------------
514 // Copy constructors and assignment
515 //---------------------------------
516
517 Vec4 (const Vec4 &v);
518 template <class S> Vec4 (const Vec4<S> &v);
519
520 const Vec4 & operator = (const Vec4 &v);
521
522 //-----------
523 // Destructor
524 //-----------
525
526 ~Vec4 () = default;
527
528 //-------------------------------------
529 // Vec3 to Vec4 conversion, sets w to 1
530 //-------------------------------------
531
532 template <class S> explicit Vec4 (const Vec3<S> &v);
533
534
535 //---------
536 // Equality
537 //---------
538
539 template <class S>
540 bool operator == (const Vec4<S> &v) const;
541
542 template <class S>
543 bool operator != (const Vec4<S> &v) const;
544
545
546 //-----------------------------------------------------------------------
547 // Compare two vectors and test if they are "approximately equal":
548 //
549 // equalWithAbsError (v, e)
550 //
551 // Returns true if the coefficients of this and v are the same with
552 // an absolute error of no more than e, i.e., for all i
553 //
554 // abs (this[i] - v[i]) <= e
555 //
556 // equalWithRelError (v, e)
557 //
558 // Returns true if the coefficients of this and v are the same with
559 // a relative error of no more than e, i.e., for all i
560 //
561 // abs (this[i] - v[i]) <= e * abs (this[i])
562 //-----------------------------------------------------------------------
563
564 bool equalWithAbsError (const Vec4<T> &v, T e) const;
565 bool equalWithRelError (const Vec4<T> &v, T e) const;
566
567
568 //------------
569 // Dot product
570 //------------
571
572 T dot (const Vec4 &v) const;
573 T operator ^ (const Vec4 &v) const;
574
575
576 //-----------------------------------
577 // Cross product is not defined in 4D
578 //-----------------------------------
579
580 //------------------------
581 // Component-wise addition
582 //------------------------
583
584 const Vec4 & operator += (const Vec4 &v);
585 Vec4 operator + (const Vec4 &v) const;
586
587
588 //---------------------------
589 // Component-wise subtraction
590 //---------------------------
591
592 const Vec4 & operator -= (const Vec4 &v);
593 Vec4 operator - (const Vec4 &v) const;
594
595
596 //------------------------------------
597 // Component-wise multiplication by -1
598 //------------------------------------
599
600 Vec4 operator - () const;
601 const Vec4 & negate ();
602
603
604 //------------------------------
605 // Component-wise multiplication
606 //------------------------------
607
608 const Vec4 & operator *= (const Vec4 &v);
609 const Vec4 & operator *= (T a);
610 Vec4 operator * (const Vec4 &v) const;
611 Vec4 operator * (T a) const;
612
613
614 //------------------------
615 // Component-wise division
616 //------------------------
617
618 const Vec4 & operator /= (const Vec4 &v);
619 const Vec4 & operator /= (T a);
620 Vec4 operator / (const Vec4 &v) const;
621 Vec4 operator / (T a) const;
622
623
624 //----------------------------------------------------------------
625 // Length and normalization: If v.length() is 0.0, v.normalize()
626 // and v.normalized() produce a null vector; v.normalizeExc() and
627 // v.normalizedExc() throw a NullVecExc.
628 // v.normalizeNonNull() and v.normalizedNonNull() are slightly
629 // faster than the other normalization routines, but if v.length()
630 // is 0.0, the result is undefined.
631 //----------------------------------------------------------------
632
633 T length () const;
634 T length2 () const;
635
636 const Vec4 & normalize (); // modifies *this
637 const Vec4 & normalizeExc ();
638 const Vec4 & normalizeNonNull ();
639
640 Vec4<T> normalized () const; // does not modify *this
641 Vec4<T> normalizedExc () const;
642 Vec4<T> normalizedNonNull () const;
643
644
645 //--------------------------------------------------------
646 // Number of dimensions, i.e. number of elements in a Vec4
647 //--------------------------------------------------------
648
649 static unsigned int dimensions() {return 4;}
650
651
652 //-------------------------------------------------
653 // Limitations of type T (see also class limits<T>)
654 //-------------------------------------------------
655
656 static T baseTypeMin() {return limits<T>::min();}
657 static T baseTypeMax() {return limits<T>::max();}
658 static T baseTypeSmallest() {return limits<T>::smallest();}
659 static T baseTypeEpsilon() {return limits<T>::epsilon();}
660
661
662 //--------------------------------------------------------------
663 // Base type -- in templates, which accept a parameter, V, which
664 // could be either a Vec2<T>, a Vec3<T>, or a Vec4<T> you can
665 // refer to T as V::BaseType
666 //--------------------------------------------------------------
667
668 typedef T BaseType;
669
670 private:
671
672 T lengthTiny () const;
673};
674
675
676//--------------
677// Stream output
678//--------------
679
680template <class T>
681std::ostream & operator << (std::ostream &s, const Vec2<T> &v);
682
683template <class T>
684std::ostream & operator << (std::ostream &s, const Vec3<T> &v);
685
686template <class T>
687std::ostream & operator << (std::ostream &s, const Vec4<T> &v);
688
689//----------------------------------------------------
690// Reverse multiplication: S * Vec2<T> and S * Vec3<T>
691//----------------------------------------------------
692
693template <class T> Vec2<T> operator * (T a, const Vec2<T> &v);
694template <class T> Vec3<T> operator * (T a, const Vec3<T> &v);
695template <class T> Vec4<T> operator * (T a, const Vec4<T> &v);
696
697
698//-------------------------
699// Typedefs for convenience
700//-------------------------
701
702typedef Vec2 <short> V2s;
703typedef Vec2 <int> V2i;
704typedef Vec2 <float> V2f;
705typedef Vec2 <double> V2d;
706typedef Vec3 <short> V3s;
707typedef Vec3 <int> V3i;
708typedef Vec3 <float> V3f;
709typedef Vec3 <double> V3d;
710typedef Vec4 <short> V4s;
711typedef Vec4 <int> V4i;
712typedef Vec4 <float> V4f;
713typedef Vec4 <double> V4d;
714
715
716//-------------------------------------------
717// Specializations for VecN<short>, VecN<int>
718//-------------------------------------------
719
720// Vec2<short>
721
722template <> short
723Vec2<short>::length () const;
724
725template <> const Vec2<short> &
726Vec2<short>::normalize ();
727
728template <> const Vec2<short> &
729Vec2<short>::normalizeExc ();
730
731template <> const Vec2<short> &
732Vec2<short>::normalizeNonNull ();
733
734template <> Vec2<short>
735Vec2<short>::normalized () const;
736
737template <> Vec2<short>
738Vec2<short>::normalizedExc () const;
739
740template <> Vec2<short>
741Vec2<short>::normalizedNonNull () const;
742
743
744// Vec2<int>
745
746template <> int
747Vec2<int>::length () const;
748
749template <> const Vec2<int> &
750Vec2<int>::normalize ();
751
752template <> const Vec2<int> &
753Vec2<int>::normalizeExc ();
754
755template <> const Vec2<int> &
756Vec2<int>::normalizeNonNull ();
757
758template <> Vec2<int>
759Vec2<int>::normalized () const;
760
761template <> Vec2<int>
762Vec2<int>::normalizedExc () const;
763
764template <> Vec2<int>
765Vec2<int>::normalizedNonNull () const;
766
767
768// Vec3<short>
769
770template <> short
771Vec3<short>::length () const;
772
773template <> const Vec3<short> &
774Vec3<short>::normalize ();
775
776template <> const Vec3<short> &
777Vec3<short>::normalizeExc ();
778
779template <> const Vec3<short> &
780Vec3<short>::normalizeNonNull ();
781
782template <> Vec3<short>
783Vec3<short>::normalized () const;
784
785template <> Vec3<short>
786Vec3<short>::normalizedExc () const;
787
788template <> Vec3<short>
789Vec3<short>::normalizedNonNull () const;
790
791
792// Vec3<int>
793
794template <> int
795Vec3<int>::length () const;
796
797template <> const Vec3<int> &
798Vec3<int>::normalize ();
799
800template <> const Vec3<int> &
801Vec3<int>::normalizeExc ();
802
803template <> const Vec3<int> &
804Vec3<int>::normalizeNonNull ();
805
806template <> Vec3<int>
807Vec3<int>::normalized () const;
808
809template <> Vec3<int>
810Vec3<int>::normalizedExc () const;
811
812template <> Vec3<int>
813Vec3<int>::normalizedNonNull () const;
814
815// Vec4<short>
816
817template <> short
818Vec4<short>::length () const;
819
820template <> const Vec4<short> &
821Vec4<short>::normalize ();
822
823template <> const Vec4<short> &
824Vec4<short>::normalizeExc ();
825
826template <> const Vec4<short> &
827Vec4<short>::normalizeNonNull ();
828
829template <> Vec4<short>
830Vec4<short>::normalized () const;
831
832template <> Vec4<short>
833Vec4<short>::normalizedExc () const;
834
835template <> Vec4<short>
836Vec4<short>::normalizedNonNull () const;
837
838
839// Vec4<int>
840
841template <> int
842Vec4<int>::length () const;
843
844template <> const Vec4<int> &
845Vec4<int>::normalize ();
846
847template <> const Vec4<int> &
848Vec4<int>::normalizeExc ();
849
850template <> const Vec4<int> &
851Vec4<int>::normalizeNonNull ();
852
853template <> Vec4<int>
854Vec4<int>::normalized () const;
855
856template <> Vec4<int>
857Vec4<int>::normalizedExc () const;
858
859template <> Vec4<int>
860Vec4<int>::normalizedNonNull () const;
861
862
863//------------------------
864// Implementation of Vec2:
865//------------------------
866
867template <class T>
868inline T &
869Vec2<T>::operator [] (int i)
870{
871 return (&x)[i]; // NOSONAR - suppress SonarCloud bug report.
872}
873
874template <class T>
875inline const T &
876Vec2<T>::operator [] (int i) const
877{
878 return (&x)[i]; // NOSONAR - suppress SonarCloud bug report.
879}
880
881template <class T>
882inline
883Vec2<T>::Vec2 ()
884{
885 // empty
886}
887
888template <class T>
889inline
890Vec2<T>::Vec2 (T a)
891{
892 x = y = a;
893}
894
895template <class T>
896inline
897Vec2<T>::Vec2 (T a, T b)
898{
899 x = a;
900 y = b;
901}
902
903template <class T>
904inline
905Vec2<T>::Vec2 (const Vec2 &v)
906{
907 x = v.x;
908 y = v.y;
909}
910
911template <class T>
912template <class S>
913inline
914Vec2<T>::Vec2 (const Vec2<S> &v)
915{
916 x = T (v.x);
917 y = T (v.y);
918}
919
920template <class T>
921inline const Vec2<T> &
922Vec2<T>::operator = (const Vec2 &v)
923{
924 x = v.x;
925 y = v.y;
926 return *this;
927}
928
929template <class T>
930template <class S>
931inline void
932Vec2<T>::setValue (S a, S b)
933{
934 x = T (a);
935 y = T (b);
936}
937
938template <class T>
939template <class S>
940inline void
941Vec2<T>::setValue (const Vec2<S> &v)
942{
943 x = T (v.x);
944 y = T (v.y);
945}
946
947template <class T>
948template <class S>
949inline void
950Vec2<T>::getValue (S &a, S &b) const
951{
952 a = S (x);
953 b = S (y);
954}
955
956template <class T>
957template <class S>
958inline void
959Vec2<T>::getValue (Vec2<S> &v) const
960{
961 v.x = S (x);
962 v.y = S (y);
963}
964
965template <class T>
966inline T *
967Vec2<T>::getValue()
968{
969 return (T *) &x;
970}
971
972template <class T>
973inline const T *
974Vec2<T>::getValue() const
975{
976 return (const T *) &x;
977}
978
979template <class T>
980template <class S>
981inline bool
982Vec2<T>::operator == (const Vec2<S> &v) const
983{
984 return x == v.x && y == v.y;
985}
986
987template <class T>
988template <class S>
989inline bool
990Vec2<T>::operator != (const Vec2<S> &v) const
991{
992 return x != v.x || y != v.y;
993}
994
995template <class T>
996bool
997Vec2<T>::equalWithAbsError (const Vec2<T> &v, T e) const
998{
999 for (int i = 0; i < 2; i++)
1000 if (!IMATH_INTERNAL_NAMESPACE::equalWithAbsError ((*this)[i], v[i], e))
1001 return false;
1002
1003 return true;
1004}
1005
1006template <class T>
1007bool
1008Vec2<T>::equalWithRelError (const Vec2<T> &v, T e) const
1009{
1010 for (int i = 0; i < 2; i++)
1011 if (!IMATH_INTERNAL_NAMESPACE::equalWithRelError ((*this)[i], v[i], e))
1012 return false;
1013
1014 return true;
1015}
1016
1017template <class T>
1018inline T
1019Vec2<T>::dot (const Vec2 &v) const
1020{
1021 return x * v.x + y * v.y;
1022}
1023
1024template <class T>
1025inline T
1026Vec2<T>::operator ^ (const Vec2 &v) const
1027{
1028 return dot (v);
1029}
1030
1031template <class T>
1032inline T
1033Vec2<T>::cross (const Vec2 &v) const
1034{
1035 return x * v.y - y * v.x;
1036
1037}
1038
1039template <class T>
1040inline T
1041Vec2<T>::operator % (const Vec2 &v) const
1042{
1043 return x * v.y - y * v.x;
1044}
1045
1046template <class T>
1047inline const Vec2<T> &
1048Vec2<T>::operator += (const Vec2 &v)
1049{
1050 x += v.x;
1051 y += v.y;
1052 return *this;
1053}
1054
1055template <class T>
1056inline Vec2<T>
1057Vec2<T>::operator + (const Vec2 &v) const
1058{
1059 return Vec2 (x + v.x, y + v.y);
1060}
1061
1062template <class T>
1063inline const Vec2<T> &
1064Vec2<T>::operator -= (const Vec2 &v)
1065{
1066 x -= v.x;
1067 y -= v.y;
1068 return *this;
1069}
1070
1071template <class T>
1072inline Vec2<T>
1073Vec2<T>::operator - (const Vec2 &v) const
1074{
1075 return Vec2 (x - v.x, y - v.y);
1076}
1077
1078template <class T>
1079inline Vec2<T>
1080Vec2<T>::operator - () const
1081{
1082 return Vec2 (-x, -y);
1083}
1084
1085template <class T>
1086inline const Vec2<T> &
1087Vec2<T>::negate ()
1088{
1089 x = -x;
1090 y = -y;
1091 return *this;
1092}
1093
1094template <class T>
1095inline const Vec2<T> &
1096Vec2<T>::operator *= (const Vec2 &v)
1097{
1098 x *= v.x;
1099 y *= v.y;
1100 return *this;
1101}
1102
1103template <class T>
1104inline const Vec2<T> &
1105Vec2<T>::operator *= (T a)
1106{
1107 x *= a;
1108 y *= a;
1109 return *this;
1110}
1111
1112template <class T>
1113inline Vec2<T>
1114Vec2<T>::operator * (const Vec2 &v) const
1115{
1116 return Vec2 (x * v.x, y * v.y);
1117}
1118
1119template <class T>
1120inline Vec2<T>
1121Vec2<T>::operator * (T a) const
1122{
1123 return Vec2 (x * a, y * a);
1124}
1125
1126template <class T>
1127inline const Vec2<T> &
1128Vec2<T>::operator /= (const Vec2 &v)
1129{
1130 x /= v.x;
1131 y /= v.y;
1132 return *this;
1133}
1134
1135template <class T>
1136inline const Vec2<T> &
1137Vec2<T>::operator /= (T a)
1138{
1139 x /= a;
1140 y /= a;
1141 return *this;
1142}
1143
1144template <class T>
1145inline Vec2<T>
1146Vec2<T>::operator / (const Vec2 &v) const
1147{
1148 return Vec2 (x / v.x, y / v.y);
1149}
1150
1151template <class T>
1152inline Vec2<T>
1153Vec2<T>::operator / (T a) const
1154{
1155 return Vec2 (x / a, y / a);
1156}
1157
1158template <class T>
1159T
1160Vec2<T>::lengthTiny () const
1161{
1162 T absX = (x >= T (0))? x: -x;
1163 T absY = (y >= T (0))? y: -y;
1164
1165 T max = absX;
1166
1167 if (max < absY)
1168 max = absY;
1169
1170 if (max == T (0))
1171 return T (0);
1172
1173 //
1174 // Do not replace the divisions by max with multiplications by 1/max.
1175 // Computing 1/max can overflow but the divisions below will always
1176 // produce results less than or equal to 1.
1177 //
1178
1179 absX /= max;
1180 absY /= max;
1181
1182 return max * Math<T>::sqrt (absX * absX + absY * absY);
1183}
1184
1185template <class T>
1186inline T
1187Vec2<T>::length () const
1188{
1189 T length2 = dot (v: *this);
1190
1191 if (length2 < T (2) * limits<T>::smallest())
1192 return lengthTiny();
1193
1194 return Math<T>::sqrt (length2);
1195}
1196
1197template <class T>
1198inline T
1199Vec2<T>::length2 () const
1200{
1201 return dot (v: *this);
1202}
1203
1204template <class T>
1205const Vec2<T> &
1206Vec2<T>::normalize ()
1207{
1208 T l = length();
1209
1210 if (l != T (0))
1211 {
1212 //
1213 // Do not replace the divisions by l with multiplications by 1/l.
1214 // Computing 1/l can overflow but the divisions below will always
1215 // produce results less than or equal to 1.
1216 //
1217
1218 x /= l;
1219 y /= l;
1220 }
1221
1222 return *this;
1223}
1224
1225template <class T>
1226const Vec2<T> &
1227Vec2<T>::normalizeExc ()
1228{
1229 T l = length();
1230
1231 if (l == T (0))
1232 throw NullVecExc ("Cannot normalize null vector.");
1233
1234 x /= l;
1235 y /= l;
1236 return *this;
1237}
1238
1239template <class T>
1240inline
1241const Vec2<T> &
1242Vec2<T>::normalizeNonNull ()
1243{
1244 T l = length();
1245 x /= l;
1246 y /= l;
1247 return *this;
1248}
1249
1250template <class T>
1251Vec2<T>
1252Vec2<T>::normalized () const
1253{
1254 T l = length();
1255
1256 if (l == T (0))
1257 return Vec2 (T (0));
1258
1259 return Vec2 (x / l, y / l);
1260}
1261
1262template <class T>
1263Vec2<T>
1264Vec2<T>::normalizedExc () const
1265{
1266 T l = length();
1267
1268 if (l == T (0))
1269 throw NullVecExc ("Cannot normalize null vector.");
1270
1271 return Vec2 (x / l, y / l);
1272}
1273
1274template <class T>
1275inline
1276Vec2<T>
1277Vec2<T>::normalizedNonNull () const
1278{
1279 T l = length();
1280 return Vec2 (x / l, y / l);
1281}
1282
1283
1284//-----------------------
1285// Implementation of Vec3
1286//-----------------------
1287
1288template <class T>
1289inline T &
1290Vec3<T>::operator [] (int i)
1291{
1292 return (&x)[i]; // NOSONAR - suppress SonarCloud bug report.
1293}
1294
1295template <class T>
1296inline const T &
1297Vec3<T>::operator [] (int i) const
1298{
1299 return (&x)[i]; // NOSONAR - suppress SonarCloud bug report.
1300}
1301
1302template <class T>
1303inline
1304Vec3<T>::Vec3 ()
1305{
1306 // empty
1307}
1308
1309template <class T>
1310inline
1311Vec3<T>::Vec3 (T a)
1312{
1313 x = y = z = a;
1314}
1315
1316template <class T>
1317inline
1318Vec3<T>::Vec3 (T a, T b, T c)
1319{
1320 x = a;
1321 y = b;
1322 z = c;
1323}
1324
1325template <class T>
1326inline
1327Vec3<T>::Vec3 (const Vec3 &v)
1328{
1329 x = v.x;
1330 y = v.y;
1331 z = v.z;
1332}
1333
1334template <class T>
1335template <class S>
1336inline
1337Vec3<T>::Vec3 (const Vec3<S> &v)
1338{
1339 x = T (v.x);
1340 y = T (v.y);
1341 z = T (v.z);
1342}
1343
1344template <class T>
1345inline const Vec3<T> &
1346Vec3<T>::operator = (const Vec3 &v)
1347{
1348 x = v.x;
1349 y = v.y;
1350 z = v.z;
1351 return *this;
1352}
1353
1354template <class T>
1355template <class S>
1356inline
1357Vec3<T>::Vec3 (const Vec4<S> &v)
1358{
1359 x = T (v.x / v.w);
1360 y = T (v.y / v.w);
1361 z = T (v.z / v.w);
1362}
1363
1364template <class T>
1365template <class S>
1366Vec3<T>::Vec3 (const Vec4<S> &v, InfException)
1367{
1368 T vx = T (v.x);
1369 T vy = T (v.y);
1370 T vz = T (v.z);
1371 T vw = T (v.w);
1372
1373 T absW = (vw >= T (0))? vw: -vw;
1374
1375 if (absW < 1)
1376 {
1377 T m = baseTypeMax() * absW;
1378
1379 if (vx <= -m || vx >= m || vy <= -m || vy >= m || vz <= -m || vz >= m)
1380 throw InfPointExc ("Cannot normalize point at infinity.");
1381 }
1382
1383 x = vx / vw;
1384 y = vy / vw;
1385 z = vz / vw;
1386}
1387
1388template <class T>
1389template <class S>
1390inline void
1391Vec3<T>::setValue (S a, S b, S c)
1392{
1393 x = T (a);
1394 y = T (b);
1395 z = T (c);
1396}
1397
1398template <class T>
1399template <class S>
1400inline void
1401Vec3<T>::setValue (const Vec3<S> &v)
1402{
1403 x = T (v.x);
1404 y = T (v.y);
1405 z = T (v.z);
1406}
1407
1408template <class T>
1409template <class S>
1410inline void
1411Vec3<T>::getValue (S &a, S &b, S &c) const
1412{
1413 a = S (x);
1414 b = S (y);
1415 c = S (z);
1416}
1417
1418template <class T>
1419template <class S>
1420inline void
1421Vec3<T>::getValue (Vec3<S> &v) const
1422{
1423 v.x = S (x);
1424 v.y = S (y);
1425 v.z = S (z);
1426}
1427
1428template <class T>
1429inline T *
1430Vec3<T>::getValue()
1431{
1432 return (T *) &x;
1433}
1434
1435template <class T>
1436inline const T *
1437Vec3<T>::getValue() const
1438{
1439 return (const T *) &x;
1440}
1441
1442template <class T>
1443template <class S>
1444inline bool
1445Vec3<T>::operator == (const Vec3<S> &v) const
1446{
1447 return x == v.x && y == v.y && z == v.z;
1448}
1449
1450template <class T>
1451template <class S>
1452inline bool
1453Vec3<T>::operator != (const Vec3<S> &v) const
1454{
1455 return x != v.x || y != v.y || z != v.z;
1456}
1457
1458template <class T>
1459bool
1460Vec3<T>::equalWithAbsError (const Vec3<T> &v, T e) const
1461{
1462 for (int i = 0; i < 3; i++)
1463 if (!IMATH_INTERNAL_NAMESPACE::equalWithAbsError ((*this)[i], v[i], e))
1464 return false;
1465
1466 return true;
1467}
1468
1469template <class T>
1470bool
1471Vec3<T>::equalWithRelError (const Vec3<T> &v, T e) const
1472{
1473 for (int i = 0; i < 3; i++)
1474 if (!IMATH_INTERNAL_NAMESPACE::equalWithRelError ((*this)[i], v[i], e))
1475 return false;
1476
1477 return true;
1478}
1479
1480template <class T>
1481inline T
1482Vec3<T>::dot (const Vec3 &v) const
1483{
1484 return x * v.x + y * v.y + z * v.z;
1485}
1486
1487template <class T>
1488inline T
1489Vec3<T>::operator ^ (const Vec3 &v) const
1490{
1491 return dot (v);
1492}
1493
1494template <class T>
1495inline Vec3<T>
1496Vec3<T>::cross (const Vec3 &v) const
1497{
1498 return Vec3 (y * v.z - z * v.y,
1499 z * v.x - x * v.z,
1500 x * v.y - y * v.x);
1501}
1502
1503template <class T>
1504inline const Vec3<T> &
1505Vec3<T>::operator %= (const Vec3 &v)
1506{
1507 T a = y * v.z - z * v.y;
1508 T b = z * v.x - x * v.z;
1509 T c = x * v.y - y * v.x;
1510 x = a;
1511 y = b;
1512 z = c;
1513 return *this;
1514}
1515
1516template <class T>
1517inline Vec3<T>
1518Vec3<T>::operator % (const Vec3 &v) const
1519{
1520 return Vec3 (y * v.z - z * v.y,
1521 z * v.x - x * v.z,
1522 x * v.y - y * v.x);
1523}
1524
1525template <class T>
1526inline const Vec3<T> &
1527Vec3<T>::operator += (const Vec3 &v)
1528{
1529 x += v.x;
1530 y += v.y;
1531 z += v.z;
1532 return *this;
1533}
1534
1535template <class T>
1536inline Vec3<T>
1537Vec3<T>::operator + (const Vec3 &v) const
1538{
1539 return Vec3 (x + v.x, y + v.y, z + v.z);
1540}
1541
1542template <class T>
1543inline const Vec3<T> &
1544Vec3<T>::operator -= (const Vec3 &v)
1545{
1546 x -= v.x;
1547 y -= v.y;
1548 z -= v.z;
1549 return *this;
1550}
1551
1552template <class T>
1553inline Vec3<T>
1554Vec3<T>::operator - (const Vec3 &v) const
1555{
1556 return Vec3 (x - v.x, y - v.y, z - v.z);
1557}
1558
1559template <class T>
1560inline Vec3<T>
1561Vec3<T>::operator - () const
1562{
1563 return Vec3 (-x, -y, -z);
1564}
1565
1566template <class T>
1567inline const Vec3<T> &
1568Vec3<T>::negate ()
1569{
1570 x = -x;
1571 y = -y;
1572 z = -z;
1573 return *this;
1574}
1575
1576template <class T>
1577inline const Vec3<T> &
1578Vec3<T>::operator *= (const Vec3 &v)
1579{
1580 x *= v.x;
1581 y *= v.y;
1582 z *= v.z;
1583 return *this;
1584}
1585
1586template <class T>
1587inline const Vec3<T> &
1588Vec3<T>::operator *= (T a)
1589{
1590 x *= a;
1591 y *= a;
1592 z *= a;
1593 return *this;
1594}
1595
1596template <class T>
1597inline Vec3<T>
1598Vec3<T>::operator * (const Vec3 &v) const
1599{
1600 return Vec3 (x * v.x, y * v.y, z * v.z);
1601}
1602
1603template <class T>
1604inline Vec3<T>
1605Vec3<T>::operator * (T a) const
1606{
1607 return Vec3 (x * a, y * a, z * a);
1608}
1609
1610template <class T>
1611inline const Vec3<T> &
1612Vec3<T>::operator /= (const Vec3 &v)
1613{
1614 x /= v.x;
1615 y /= v.y;
1616 z /= v.z;
1617 return *this;
1618}
1619
1620template <class T>
1621inline const Vec3<T> &
1622Vec3<T>::operator /= (T a)
1623{
1624 x /= a;
1625 y /= a;
1626 z /= a;
1627 return *this;
1628}
1629
1630template <class T>
1631inline Vec3<T>
1632Vec3<T>::operator / (const Vec3 &v) const
1633{
1634 return Vec3 (x / v.x, y / v.y, z / v.z);
1635}
1636
1637template <class T>
1638inline Vec3<T>
1639Vec3<T>::operator / (T a) const
1640{
1641 return Vec3 (x / a, y / a, z / a);
1642}
1643
1644template <class T>
1645T
1646Vec3<T>::lengthTiny () const
1647{
1648 T absX = (x >= T (0))? x: -x;
1649 T absY = (y >= T (0))? y: -y;
1650 T absZ = (z >= T (0))? z: -z;
1651
1652 T max = absX;
1653
1654 if (max < absY)
1655 max = absY;
1656
1657 if (max < absZ)
1658 max = absZ;
1659
1660 if (max == T (0))
1661 return T (0);
1662
1663 //
1664 // Do not replace the divisions by max with multiplications by 1/max.
1665 // Computing 1/max can overflow but the divisions below will always
1666 // produce results less than or equal to 1.
1667 //
1668
1669 absX /= max;
1670 absY /= max;
1671 absZ /= max;
1672
1673 return max * Math<T>::sqrt (absX * absX + absY * absY + absZ * absZ);
1674}
1675
1676template <class T>
1677inline T
1678Vec3<T>::length () const
1679{
1680 T length2 = dot (v: *this);
1681
1682 if (length2 < T (2) * limits<T>::smallest())
1683 return lengthTiny();
1684
1685 return Math<T>::sqrt (length2);
1686}
1687
1688template <class T>
1689inline T
1690Vec3<T>::length2 () const
1691{
1692 return dot (v: *this);
1693}
1694
1695template <class T>
1696const Vec3<T> &
1697Vec3<T>::normalize ()
1698{
1699 T l = length();
1700
1701 if (l != T (0))
1702 {
1703 //
1704 // Do not replace the divisions by l with multiplications by 1/l.
1705 // Computing 1/l can overflow but the divisions below will always
1706 // produce results less than or equal to 1.
1707 //
1708
1709 x /= l;
1710 y /= l;
1711 z /= l;
1712 }
1713
1714 return *this;
1715}
1716
1717template <class T>
1718const Vec3<T> &
1719Vec3<T>::normalizeExc ()
1720{
1721 T l = length();
1722
1723 if (l == T (0))
1724 throw NullVecExc ("Cannot normalize null vector.");
1725
1726 x /= l;
1727 y /= l;
1728 z /= l;
1729 return *this;
1730}
1731
1732template <class T>
1733inline
1734const Vec3<T> &
1735Vec3<T>::normalizeNonNull ()
1736{
1737 T l = length();
1738 x /= l;
1739 y /= l;
1740 z /= l;
1741 return *this;
1742}
1743
1744template <class T>
1745Vec3<T>
1746Vec3<T>::normalized () const
1747{
1748 T l = length();
1749
1750 if (l == T (0))
1751 return Vec3 (T (0));
1752
1753 return Vec3 (x / l, y / l, z / l);
1754}
1755
1756template <class T>
1757Vec3<T>
1758Vec3<T>::normalizedExc () const
1759{
1760 T l = length();
1761
1762 if (l == T (0))
1763 throw NullVecExc ("Cannot normalize null vector.");
1764
1765 return Vec3 (x / l, y / l, z / l);
1766}
1767
1768template <class T>
1769inline
1770Vec3<T>
1771Vec3<T>::normalizedNonNull () const
1772{
1773 T l = length();
1774 return Vec3 (x / l, y / l, z / l);
1775}
1776
1777
1778//-----------------------
1779// Implementation of Vec4
1780//-----------------------
1781
1782template <class T>
1783inline T &
1784Vec4<T>::operator [] (int i)
1785{
1786 return (&x)[i]; // NOSONAR - suppress SonarCloud bug report.
1787}
1788
1789template <class T>
1790inline const T &
1791Vec4<T>::operator [] (int i) const
1792{
1793 return (&x)[i]; // NOSONAR - suppress SonarCloud bug report.
1794}
1795
1796template <class T>
1797inline
1798Vec4<T>::Vec4 ()
1799{
1800 // empty
1801}
1802
1803template <class T>
1804inline
1805Vec4<T>::Vec4 (T a)
1806{
1807 x = y = z = w = a;
1808}
1809
1810template <class T>
1811inline
1812Vec4<T>::Vec4 (T a, T b, T c, T d)
1813{
1814 x = a;
1815 y = b;
1816 z = c;
1817 w = d;
1818}
1819
1820template <class T>
1821inline
1822Vec4<T>::Vec4 (const Vec4 &v)
1823{
1824 x = v.x;
1825 y = v.y;
1826 z = v.z;
1827 w = v.w;
1828}
1829
1830template <class T>
1831template <class S>
1832inline
1833Vec4<T>::Vec4 (const Vec4<S> &v)
1834{
1835 x = T (v.x);
1836 y = T (v.y);
1837 z = T (v.z);
1838 w = T (v.w);
1839}
1840
1841template <class T>
1842inline const Vec4<T> &
1843Vec4<T>::operator = (const Vec4 &v)
1844{
1845 x = v.x;
1846 y = v.y;
1847 z = v.z;
1848 w = v.w;
1849 return *this;
1850}
1851
1852template <class T>
1853template <class S>
1854inline
1855Vec4<T>::Vec4 (const Vec3<S> &v)
1856{
1857 x = T (v.x);
1858 y = T (v.y);
1859 z = T (v.z);
1860 w = T (1);
1861}
1862
1863template <class T>
1864template <class S>
1865inline bool
1866Vec4<T>::operator == (const Vec4<S> &v) const
1867{
1868 return x == v.x && y == v.y && z == v.z && w == v.w;
1869}
1870
1871template <class T>
1872template <class S>
1873inline bool
1874Vec4<T>::operator != (const Vec4<S> &v) const
1875{
1876 return x != v.x || y != v.y || z != v.z || w != v.w;
1877}
1878
1879template <class T>
1880bool
1881Vec4<T>::equalWithAbsError (const Vec4<T> &v, T e) const
1882{
1883 for (int i = 0; i < 4; i++)
1884 if (!IMATH_INTERNAL_NAMESPACE::equalWithAbsError ((*this)[i], v[i], e))
1885 return false;
1886
1887 return true;
1888}
1889
1890template <class T>
1891bool
1892Vec4<T>::equalWithRelError (const Vec4<T> &v, T e) const
1893{
1894 for (int i = 0; i < 4; i++)
1895 if (!IMATH_INTERNAL_NAMESPACE::equalWithRelError ((*this)[i], v[i], e))
1896 return false;
1897
1898 return true;
1899}
1900
1901template <class T>
1902inline T
1903Vec4<T>::dot (const Vec4 &v) const
1904{
1905 return x * v.x + y * v.y + z * v.z + w * v.w;
1906}
1907
1908template <class T>
1909inline T
1910Vec4<T>::operator ^ (const Vec4 &v) const
1911{
1912 return dot (v);
1913}
1914
1915
1916template <class T>
1917inline const Vec4<T> &
1918Vec4<T>::operator += (const Vec4 &v)
1919{
1920 x += v.x;
1921 y += v.y;
1922 z += v.z;
1923 w += v.w;
1924 return *this;
1925}
1926
1927template <class T>
1928inline Vec4<T>
1929Vec4<T>::operator + (const Vec4 &v) const
1930{
1931 return Vec4 (x + v.x, y + v.y, z + v.z, w + v.w);
1932}
1933
1934template <class T>
1935inline const Vec4<T> &
1936Vec4<T>::operator -= (const Vec4 &v)
1937{
1938 x -= v.x;
1939 y -= v.y;
1940 z -= v.z;
1941 w -= v.w;
1942 return *this;
1943}
1944
1945template <class T>
1946inline Vec4<T>
1947Vec4<T>::operator - (const Vec4 &v) const
1948{
1949 return Vec4 (x - v.x, y - v.y, z - v.z, w - v.w);
1950}
1951
1952template <class T>
1953inline Vec4<T>
1954Vec4<T>::operator - () const
1955{
1956 return Vec4 (-x, -y, -z, -w);
1957}
1958
1959template <class T>
1960inline const Vec4<T> &
1961Vec4<T>::negate ()
1962{
1963 x = -x;
1964 y = -y;
1965 z = -z;
1966 w = -w;
1967 return *this;
1968}
1969
1970template <class T>
1971inline const Vec4<T> &
1972Vec4<T>::operator *= (const Vec4 &v)
1973{
1974 x *= v.x;
1975 y *= v.y;
1976 z *= v.z;
1977 w *= v.w;
1978 return *this;
1979}
1980
1981template <class T>
1982inline const Vec4<T> &
1983Vec4<T>::operator *= (T a)
1984{
1985 x *= a;
1986 y *= a;
1987 z *= a;
1988 w *= a;
1989 return *this;
1990}
1991
1992template <class T>
1993inline Vec4<T>
1994Vec4<T>::operator * (const Vec4 &v) const
1995{
1996 return Vec4 (x * v.x, y * v.y, z * v.z, w * v.w);
1997}
1998
1999template <class T>
2000inline Vec4<T>
2001Vec4<T>::operator * (T a) const
2002{
2003 return Vec4 (x * a, y * a, z * a, w * a);
2004}
2005
2006template <class T>
2007inline const Vec4<T> &
2008Vec4<T>::operator /= (const Vec4 &v)
2009{
2010 x /= v.x;
2011 y /= v.y;
2012 z /= v.z;
2013 w /= v.w;
2014 return *this;
2015}
2016
2017template <class T>
2018inline const Vec4<T> &
2019Vec4<T>::operator /= (T a)
2020{
2021 x /= a;
2022 y /= a;
2023 z /= a;
2024 w /= a;
2025 return *this;
2026}
2027
2028template <class T>
2029inline Vec4<T>
2030Vec4<T>::operator / (const Vec4 &v) const
2031{
2032 return Vec4 (x / v.x, y / v.y, z / v.z, w / v.w);
2033}
2034
2035template <class T>
2036inline Vec4<T>
2037Vec4<T>::operator / (T a) const
2038{
2039 return Vec4 (x / a, y / a, z / a, w / a);
2040}
2041
2042template <class T>
2043T
2044Vec4<T>::lengthTiny () const
2045{
2046 T absX = (x >= T (0))? x: -x;
2047 T absY = (y >= T (0))? y: -y;
2048 T absZ = (z >= T (0))? z: -z;
2049 T absW = (w >= T (0))? w: -w;
2050
2051 T max = absX;
2052
2053 if (max < absY)
2054 max = absY;
2055
2056 if (max < absZ)
2057 max = absZ;
2058
2059 if (max < absW)
2060 max = absW;
2061
2062 if (max == T (0))
2063 return T (0);
2064
2065 //
2066 // Do not replace the divisions by max with multiplications by 1/max.
2067 // Computing 1/max can overflow but the divisions below will always
2068 // produce results less than or equal to 1.
2069 //
2070
2071 absX /= max;
2072 absY /= max;
2073 absZ /= max;
2074 absW /= max;
2075
2076 return max *
2077 Math<T>::sqrt (absX * absX + absY * absY + absZ * absZ + absW * absW);
2078}
2079
2080template <class T>
2081inline T
2082Vec4<T>::length () const
2083{
2084 T length2 = dot (v: *this);
2085
2086 if (length2 < T (2) * limits<T>::smallest())
2087 return lengthTiny();
2088
2089 return Math<T>::sqrt (length2);
2090}
2091
2092template <class T>
2093inline T
2094Vec4<T>::length2 () const
2095{
2096 return dot (v: *this);
2097}
2098
2099template <class T>
2100const Vec4<T> &
2101Vec4<T>::normalize ()
2102{
2103 T l = length();
2104
2105 if (l != T (0))
2106 {
2107 //
2108 // Do not replace the divisions by l with multiplications by 1/l.
2109 // Computing 1/l can overflow but the divisions below will always
2110 // produce results less than or equal to 1.
2111 //
2112
2113 x /= l;
2114 y /= l;
2115 z /= l;
2116 w /= l;
2117 }
2118
2119 return *this;
2120}
2121
2122template <class T>
2123const Vec4<T> &
2124Vec4<T>::normalizeExc ()
2125{
2126 T l = length();
2127
2128 if (l == T (0))
2129 throw NullVecExc ("Cannot normalize null vector.");
2130
2131 x /= l;
2132 y /= l;
2133 z /= l;
2134 w /= l;
2135 return *this;
2136}
2137
2138template <class T>
2139inline
2140const Vec4<T> &
2141Vec4<T>::normalizeNonNull ()
2142{
2143 T l = length();
2144 x /= l;
2145 y /= l;
2146 z /= l;
2147 w /= l;
2148 return *this;
2149}
2150
2151template <class T>
2152Vec4<T>
2153Vec4<T>::normalized () const
2154{
2155 T l = length();
2156
2157 if (l == T (0))
2158 return Vec4 (T (0));
2159
2160 return Vec4 (x / l, y / l, z / l, w / l);
2161}
2162
2163template <class T>
2164Vec4<T>
2165Vec4<T>::normalizedExc () const
2166{
2167 T l = length();
2168
2169 if (l == T (0))
2170 throw NullVecExc ("Cannot normalize null vector.");
2171
2172 return Vec4 (x / l, y / l, z / l, w / l);
2173}
2174
2175template <class T>
2176inline
2177Vec4<T>
2178Vec4<T>::normalizedNonNull () const
2179{
2180 T l = length();
2181 return Vec4 (x / l, y / l, z / l, w / l);
2182}
2183
2184//-----------------------------
2185// Stream output implementation
2186//-----------------------------
2187
2188template <class T>
2189std::ostream &
2190operator << (std::ostream &s, const Vec2<T> &v)
2191{
2192 return s << '(' << v.x << ' ' << v.y << ')';
2193}
2194
2195template <class T>
2196std::ostream &
2197operator << (std::ostream &s, const Vec3<T> &v)
2198{
2199 return s << '(' << v.x << ' ' << v.y << ' ' << v.z << ')';
2200}
2201
2202template <class T>
2203std::ostream &
2204operator << (std::ostream &s, const Vec4<T> &v)
2205{
2206 return s << '(' << v.x << ' ' << v.y << ' ' << v.z << ' ' << v.w << ')';
2207}
2208
2209
2210//-----------------------------------------
2211// Implementation of reverse multiplication
2212//-----------------------------------------
2213
2214template <class T>
2215inline Vec2<T>
2216operator * (T a, const Vec2<T> &v)
2217{
2218 return Vec2<T> (a * v.x, a * v.y);
2219}
2220
2221template <class T>
2222inline Vec3<T>
2223operator * (T a, const Vec3<T> &v)
2224{
2225 return Vec3<T> (a * v.x, a * v.y, a * v.z);
2226}
2227
2228template <class T>
2229inline Vec4<T>
2230operator * (T a, const Vec4<T> &v)
2231{
2232 return Vec4<T> (a * v.x, a * v.y, a * v.z, a * v.w);
2233}
2234
2235
2236#if (defined _WIN32 || defined _WIN64) && defined _MSC_VER
2237#pragma warning(pop)
2238#endif
2239
2240IMATH_INTERNAL_NAMESPACE_HEADER_EXIT
2241
2242#endif // INCLUDED_IMATHVEC_H
2243

source code of include/OpenEXR/ImathVec.h