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