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