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