Coverage Report

Created: 2024-09-08 06:41

/usr/local/include/OpenEXR/ImathVec.h
Line
Count
Source (jump to first uncovered line)
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
60
IMATH_INTERNAL_NAMESPACE_HEADER_ENTER
61
62
template <class T> class Vec2;
63
template <class T> class Vec3;
64
template <class T> class Vec4;
65
66
enum InfException {INF_EXCEPTION};
67
68
69
template <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
0
    static T    baseTypeMin()   {return limits<T>::min();}
Unexecuted instantiation: Imath_2_5::Vec2<short>::baseTypeMin()
Unexecuted instantiation: Imath_2_5::Vec2<int>::baseTypeMin()
Unexecuted instantiation: Imath_2_5::Vec2<float>::baseTypeMin()
Unexecuted instantiation: Imath_2_5::Vec2<double>::baseTypeMin()
253
0
    static T    baseTypeMax()   {return limits<T>::max();}
Unexecuted instantiation: Imath_2_5::Vec2<short>::baseTypeMax()
Unexecuted instantiation: Imath_2_5::Vec2<int>::baseTypeMax()
Unexecuted instantiation: Imath_2_5::Vec2<float>::baseTypeMax()
Unexecuted instantiation: Imath_2_5::Vec2<double>::baseTypeMax()
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
272
template <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
0
    static T    baseTypeMin()   {return limits<T>::min();}
Unexecuted instantiation: Imath_2_5::Vec3<short>::baseTypeMin()
Unexecuted instantiation: Imath_2_5::Vec3<int>::baseTypeMin()
Unexecuted instantiation: Imath_2_5::Vec3<float>::baseTypeMin()
Unexecuted instantiation: Imath_2_5::Vec3<double>::baseTypeMin()
470
0
    static T    baseTypeMax()   {return limits<T>::max();}
Unexecuted instantiation: Imath_2_5::Vec3<short>::baseTypeMax()
Unexecuted instantiation: Imath_2_5::Vec3<int>::baseTypeMax()
Unexecuted instantiation: Imath_2_5::Vec3<float>::baseTypeMax()
Unexecuted instantiation: Imath_2_5::Vec3<double>::baseTypeMax()
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
490
template <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
680
template <class T>
681
std::ostream &  operator << (std::ostream &s, const Vec2<T> &v);
682
683
template <class T>
684
std::ostream &  operator << (std::ostream &s, const Vec3<T> &v);
685
686
template <class T>
687
std::ostream &  operator << (std::ostream &s, const Vec4<T> &v);
688
689
//----------------------------------------------------
690
// Reverse multiplication: S * Vec2<T> and S * Vec3<T>
691
//----------------------------------------------------
692
693
template <class T> Vec2<T>  operator * (T a, const Vec2<T> &v);
694
template <class T> Vec3<T>  operator * (T a, const Vec3<T> &v);
695
template <class T> Vec4<T>  operator * (T a, const Vec4<T> &v);
696
697
698
//-------------------------
699
// Typedefs for convenience
700
//-------------------------
701
702
typedef Vec2 <short>  V2s;
703
typedef Vec2 <int>    V2i;
704
typedef Vec2 <float>  V2f;
705
typedef Vec2 <double> V2d;
706
typedef Vec3 <short>  V3s;
707
typedef Vec3 <int>    V3i;
708
typedef Vec3 <float>  V3f;
709
typedef Vec3 <double> V3d;
710
typedef Vec4 <short>  V4s;
711
typedef Vec4 <int>    V4i;
712
typedef Vec4 <float>  V4f;
713
typedef Vec4 <double> V4d;
714
715
716
//-------------------------------------------
717
// Specializations for VecN<short>, VecN<int>
718
//-------------------------------------------
719
720
// Vec2<short>
721
722
template <> short
723
Vec2<short>::length () const;
724
725
template <> const Vec2<short> &
726
Vec2<short>::normalize ();
727
728
template <> const Vec2<short> &
729
Vec2<short>::normalizeExc ();
730
731
template <> const Vec2<short> &
732
Vec2<short>::normalizeNonNull ();
733
734
template <> Vec2<short>
735
Vec2<short>::normalized () const;
736
737
template <> Vec2<short>
738
Vec2<short>::normalizedExc () const;
739
740
template <> Vec2<short>
741
Vec2<short>::normalizedNonNull () const;
742
743
744
// Vec2<int>
745
746
template <> int
747
Vec2<int>::length () const;
748
749
template <> const Vec2<int> &
750
Vec2<int>::normalize ();
751
752
template <> const Vec2<int> &
753
Vec2<int>::normalizeExc ();
754
755
template <> const Vec2<int> &
756
Vec2<int>::normalizeNonNull ();
757
758
template <> Vec2<int>
759
Vec2<int>::normalized () const;
760
761
template <> Vec2<int>
762
Vec2<int>::normalizedExc () const;
763
764
template <> Vec2<int>
765
Vec2<int>::normalizedNonNull () const;
766
767
768
// Vec3<short>
769
770
template <> short
771
Vec3<short>::length () const;
772
773
template <> const Vec3<short> &
774
Vec3<short>::normalize ();
775
776
template <> const Vec3<short> &
777
Vec3<short>::normalizeExc ();
778
779
template <> const Vec3<short> &
780
Vec3<short>::normalizeNonNull ();
781
782
template <> Vec3<short>
783
Vec3<short>::normalized () const;
784
785
template <> Vec3<short>
786
Vec3<short>::normalizedExc () const;
787
788
template <> Vec3<short>
789
Vec3<short>::normalizedNonNull () const;
790
791
792
// Vec3<int>
793
794
template <> int
795
Vec3<int>::length () const;
796
797
template <> const Vec3<int> &
798
Vec3<int>::normalize ();
799
800
template <> const Vec3<int> &
801
Vec3<int>::normalizeExc ();
802
803
template <> const Vec3<int> &
804
Vec3<int>::normalizeNonNull ();
805
806
template <> Vec3<int>
807
Vec3<int>::normalized () const;
808
809
template <> Vec3<int>
810
Vec3<int>::normalizedExc () const;
811
812
template <> Vec3<int>
813
Vec3<int>::normalizedNonNull () const;
814
815
// Vec4<short>
816
817
template <> short
818
Vec4<short>::length () const;
819
820
template <> const Vec4<short> &
821
Vec4<short>::normalize ();
822
823
template <> const Vec4<short> &
824
Vec4<short>::normalizeExc ();
825
826
template <> const Vec4<short> &
827
Vec4<short>::normalizeNonNull ();
828
829
template <> Vec4<short>
830
Vec4<short>::normalized () const;
831
832
template <> Vec4<short>
833
Vec4<short>::normalizedExc () const;
834
835
template <> Vec4<short>
836
Vec4<short>::normalizedNonNull () const;
837
838
839
// Vec4<int>
840
841
template <> int
842
Vec4<int>::length () const;
843
844
template <> const Vec4<int> &
845
Vec4<int>::normalize ();
846
847
template <> const Vec4<int> &
848
Vec4<int>::normalizeExc ();
849
850
template <> const Vec4<int> &
851
Vec4<int>::normalizeNonNull ();
852
853
template <> Vec4<int>
854
Vec4<int>::normalized () const;
855
856
template <> Vec4<int>
857
Vec4<int>::normalizedExc () const;
858
859
template <> Vec4<int>
860
Vec4<int>::normalizedNonNull () const;
861
862
863
//------------------------
864
// Implementation of Vec2:
865
//------------------------
866
867
template <class T>
868
inline T &
869
Vec2<T>::operator [] (int i)
870
{
871
    return (&x)[i]; // NOSONAR - suppress SonarCloud bug report.
872
}
873
874
template <class T>
875
inline const T &
876
Vec2<T>::operator [] (int i) const
877
{
878
    return (&x)[i]; // NOSONAR - suppress SonarCloud bug report.
879
}
880
881
template <class T>
882
inline
883
Vec2<T>::Vec2 ()
884
{
885
    // empty
886
}
887
888
template <class T>
889
inline
890
Vec2<T>::Vec2 (T a)
891
{
892
    x = y = a;
893
}
894
895
template <class T>
896
inline
897
Vec2<T>::Vec2 (T a, T b)
898
{
899
    x = a;
900
    y = b;
901
}
902
903
template <class T>
904
inline
905
Vec2<T>::Vec2 (const Vec2 &v)
906
{
907
    x = v.x;
908
    y = v.y;
909
}
910
911
template <class T>
912
template <class S>
913
inline
914
Vec2<T>::Vec2 (const Vec2<S> &v)
915
{
916
    x = T (v.x);
917
    y = T (v.y);
918
}
919
920
template <class T>
921
inline const Vec2<T> &
922
Vec2<T>::operator = (const Vec2 &v)
923
0
{
924
0
    x = v.x;
925
0
    y = v.y;
926
0
    return *this;
927
0
}
Unexecuted instantiation: Imath_2_5::Vec2<short>::operator=(Imath_2_5::Vec2<short> const&)
Unexecuted instantiation: Imath_2_5::Vec2<int>::operator=(Imath_2_5::Vec2<int> const&)
Unexecuted instantiation: Imath_2_5::Vec2<float>::operator=(Imath_2_5::Vec2<float> const&)
Unexecuted instantiation: Imath_2_5::Vec2<double>::operator=(Imath_2_5::Vec2<double> const&)
928
929
template <class T>
930
template <class S>
931
inline void
932
Vec2<T>::setValue (S a, S b)
933
{
934
    x = T (a);
935
    y = T (b);
936
}
937
938
template <class T>
939
template <class S>
940
inline void
941
Vec2<T>::setValue (const Vec2<S> &v)
942
{
943
    x = T (v.x);
944
    y = T (v.y);
945
}
946
947
template <class T>
948
template <class S>
949
inline void
950
Vec2<T>::getValue (S &a, S &b) const
951
{
952
    a = S (x);
953
    b = S (y);
954
}
955
956
template <class T>
957
template <class S>
958
inline void
959
Vec2<T>::getValue (Vec2<S> &v) const
960
{
961
    v.x = S (x);
962
    v.y = S (y);
963
}
964
965
template <class T>
966
inline T *
967
Vec2<T>::getValue()
968
{
969
    return (T *) &x;
970
}
971
972
template <class T>
973
inline const T *
974
Vec2<T>::getValue() const
975
{
976
    return (const T *) &x;
977
}
978
979
template <class T>
980
template <class S>
981
inline bool
982
Vec2<T>::operator == (const Vec2<S> &v) const
983
{
984
    return x == v.x && y == v.y;
985
}
986
987
template <class T>
988
template <class S>
989
inline bool
990
Vec2<T>::operator != (const Vec2<S> &v) const
991
{
992
    return x != v.x || y != v.y;
993
}
994
995
template <class T>
996
bool
997
Vec2<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
1006
template <class T>
1007
bool
1008
Vec2<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
1017
template <class T>
1018
inline T
1019
Vec2<T>::dot (const Vec2 &v) const
1020
{
1021
    return x * v.x + y * v.y;
1022
}
1023
1024
template <class T>
1025
inline T
1026
Vec2<T>::operator ^ (const Vec2 &v) const
1027
{
1028
    return dot (v);
1029
}
1030
1031
template <class T>
1032
inline T
1033
Vec2<T>::cross (const Vec2 &v) const
1034
{
1035
    return x * v.y - y * v.x;
1036
1037
}
1038
1039
template <class T>
1040
inline T
1041
Vec2<T>::operator % (const Vec2 &v) const
1042
{
1043
    return x * v.y - y * v.x;
1044
}
1045
1046
template <class T>
1047
inline const Vec2<T> &
1048
Vec2<T>::operator += (const Vec2 &v)
1049
{
1050
    x += v.x;
1051
    y += v.y;
1052
    return *this;
1053
}
1054
1055
template <class T>
1056
inline Vec2<T>
1057
Vec2<T>::operator + (const Vec2 &v) const
1058
{
1059
    return Vec2 (x + v.x, y + v.y);
1060
}
1061
1062
template <class T>
1063
inline const Vec2<T> &
1064
Vec2<T>::operator -= (const Vec2 &v)
1065
{
1066
    x -= v.x;
1067
    y -= v.y;
1068
    return *this;
1069
}
1070
1071
template <class T>
1072
inline Vec2<T>
1073
Vec2<T>::operator - (const Vec2 &v) const
1074
{
1075
    return Vec2 (x - v.x, y - v.y);
1076
}
1077
1078
template <class T>
1079
inline Vec2<T>
1080
Vec2<T>::operator - () const
1081
{
1082
    return Vec2 (-x, -y);
1083
}
1084
1085
template <class T>
1086
inline const Vec2<T> &
1087
Vec2<T>::negate ()
1088
{
1089
    x = -x;
1090
    y = -y;
1091
    return *this;
1092
}
1093
1094
template <class T>
1095
inline const Vec2<T> &
1096
Vec2<T>::operator *= (const Vec2 &v)
1097
{
1098
    x *= v.x;
1099
    y *= v.y;
1100
    return *this;
1101
}
1102
1103
template <class T>
1104
inline const Vec2<T> &
1105
Vec2<T>::operator *= (T a)
1106
{
1107
    x *= a;
1108
    y *= a;
1109
    return *this;
1110
}
1111
1112
template <class T>
1113
inline Vec2<T>
1114
Vec2<T>::operator * (const Vec2 &v) const
1115
{
1116
    return Vec2 (x * v.x, y * v.y);
1117
}
1118
1119
template <class T>
1120
inline Vec2<T>
1121
Vec2<T>::operator * (T a) const
1122
{
1123
    return Vec2 (x * a, y * a);
1124
}
1125
1126
template <class T>
1127
inline const Vec2<T> &
1128
Vec2<T>::operator /= (const Vec2 &v)
1129
{
1130
    x /= v.x;
1131
    y /= v.y;
1132
    return *this;
1133
}
1134
1135
template <class T>
1136
inline const Vec2<T> &
1137
Vec2<T>::operator /= (T a)
1138
{
1139
    x /= a;
1140
    y /= a;
1141
    return *this;
1142
}
1143
1144
template <class T>
1145
inline Vec2<T>
1146
Vec2<T>::operator / (const Vec2 &v) const
1147
{
1148
    return Vec2 (x / v.x, y / v.y);
1149
}
1150
1151
template <class T>
1152
inline Vec2<T>
1153
Vec2<T>::operator / (T a) const
1154
{
1155
    return Vec2 (x / a, y / a);
1156
}
1157
1158
template <class T>
1159
T
1160
Vec2<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
1185
template <class T>
1186
inline T
1187
Vec2<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
1197
template <class T>
1198
inline T
1199
Vec2<T>::length2 () const
1200
{
1201
    return dot (*this);
1202
}
1203
1204
template <class T>
1205
const Vec2<T> &
1206
Vec2<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
1225
template <class T>
1226
const Vec2<T> &
1227
Vec2<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
1239
template <class T>
1240
inline
1241
const Vec2<T> &
1242
Vec2<T>::normalizeNonNull ()
1243
{
1244
    T l = length();
1245
    x /= l;
1246
    y /= l;
1247
    return *this;
1248
}
1249
1250
template <class T>
1251
Vec2<T>
1252
Vec2<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
1262
template <class T>
1263
Vec2<T>
1264
Vec2<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
1274
template <class T>
1275
inline
1276
Vec2<T>
1277
Vec2<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
1288
template <class T>
1289
inline T &
1290
Vec3<T>::operator [] (int i)
1291
0
{
1292
0
    return (&x)[i]; // NOSONAR - suppress SonarCloud bug report.
1293
0
}
1294
1295
template <class T>
1296
inline const T &
1297
Vec3<T>::operator [] (int i) const
1298
0
{
1299
0
    return (&x)[i]; // NOSONAR - suppress SonarCloud bug report.
1300
0
}
1301
1302
template <class T>
1303
inline
1304
Vec3<T>::Vec3 ()
1305
0
{
1306
    // empty
1307
0
}
1308
1309
template <class T>
1310
inline
1311
Vec3<T>::Vec3 (T a)
1312
0
{
1313
0
    x = y = z = a;
1314
0
}
1315
1316
template <class T>
1317
inline
1318
Vec3<T>::Vec3 (T a, T b, T c)
1319
0
{
1320
0
    x = a;
1321
0
    y = b;
1322
0
    z = c;
1323
0
}
1324
1325
template <class T>
1326
inline
1327
Vec3<T>::Vec3 (const Vec3 &v)
1328
{
1329
    x = v.x;
1330
    y = v.y;
1331
    z = v.z;
1332
}
1333
1334
template <class T>
1335
template <class S>
1336
inline
1337
Vec3<T>::Vec3 (const Vec3<S> &v)
1338
{
1339
    x = T (v.x);
1340
    y = T (v.y);
1341
    z = T (v.z);
1342
}
1343
1344
template <class T>
1345
inline const Vec3<T> &
1346
Vec3<T>::operator = (const Vec3 &v)
1347
0
{
1348
0
    x = v.x;
1349
0
    y = v.y;
1350
0
    z = v.z;
1351
0
    return *this;
1352
0
}
Unexecuted instantiation: Imath_2_5::Vec3<short>::operator=(Imath_2_5::Vec3<short> const&)
Unexecuted instantiation: Imath_2_5::Vec3<int>::operator=(Imath_2_5::Vec3<int> const&)
Unexecuted instantiation: Imath_2_5::Vec3<float>::operator=(Imath_2_5::Vec3<float> const&)
Unexecuted instantiation: Imath_2_5::Vec3<double>::operator=(Imath_2_5::Vec3<double> const&)
1353
1354
template <class T>
1355
template <class S>
1356
inline
1357
Vec3<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
1364
template <class T>
1365
template <class S>
1366
Vec3<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
1388
template <class T>
1389
template <class S>
1390
inline void
1391
Vec3<T>::setValue (S a, S b, S c)
1392
{
1393
    x = T (a);
1394
    y = T (b);
1395
    z = T (c);
1396
}
1397
1398
template <class T>
1399
template <class S>
1400
inline void
1401
Vec3<T>::setValue (const Vec3<S> &v)
1402
{
1403
    x = T (v.x);
1404
    y = T (v.y);
1405
    z = T (v.z);
1406
}
1407
1408
template <class T>
1409
template <class S>
1410
inline void
1411
Vec3<T>::getValue (S &a, S &b, S &c) const
1412
{
1413
    a = S (x);
1414
    b = S (y);
1415
    c = S (z);
1416
}
1417
1418
template <class T>
1419
template <class S>
1420
inline void
1421
Vec3<T>::getValue (Vec3<S> &v) const
1422
{
1423
    v.x = S (x);
1424
    v.y = S (y);
1425
    v.z = S (z);
1426
}
1427
1428
template <class T>
1429
inline T *
1430
Vec3<T>::getValue()
1431
{
1432
    return (T *) &x;
1433
}
1434
1435
template <class T>
1436
inline const T *
1437
Vec3<T>::getValue() const
1438
{
1439
    return (const T *) &x;
1440
}
1441
1442
template <class T>
1443
template <class S>
1444
inline bool
1445
Vec3<T>::operator == (const Vec3<S> &v) const
1446
{
1447
    return x == v.x && y == v.y && z == v.z;
1448
}
1449
1450
template <class T>
1451
template <class S>
1452
inline bool
1453
Vec3<T>::operator != (const Vec3<S> &v) const
1454
{
1455
    return x != v.x || y != v.y || z != v.z;
1456
}
1457
1458
template <class T>
1459
bool
1460
Vec3<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
1469
template <class T>
1470
bool
1471
Vec3<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
1480
template <class T>
1481
inline T
1482
Vec3<T>::dot (const Vec3 &v) const
1483
0
{
1484
0
    return x * v.x + y * v.y + z * v.z;
1485
0
}
1486
1487
template <class T>
1488
inline T
1489
Vec3<T>::operator ^ (const Vec3 &v) const
1490
{
1491
    return dot (v);
1492
}
1493
1494
template <class T>
1495
inline Vec3<T>
1496
Vec3<T>::cross (const Vec3 &v) const
1497
0
{
1498
0
    return Vec3 (y * v.z - z * v.y,
1499
0
     z * v.x - x * v.z,
1500
0
     x * v.y - y * v.x);
1501
0
}
1502
1503
template <class T>
1504
inline const Vec3<T> &
1505
Vec3<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
1516
template <class T>
1517
inline Vec3<T>
1518
Vec3<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
1525
template <class T>
1526
inline const Vec3<T> &
1527
Vec3<T>::operator += (const Vec3 &v)
1528
{
1529
    x += v.x;
1530
    y += v.y;
1531
    z += v.z;
1532
    return *this;
1533
}
1534
1535
template <class T>
1536
inline Vec3<T>
1537
Vec3<T>::operator + (const Vec3 &v) const
1538
{
1539
    return Vec3 (x + v.x, y + v.y, z + v.z);
1540
}
1541
1542
template <class T>
1543
inline const Vec3<T> &
1544
Vec3<T>::operator -= (const Vec3 &v)
1545
0
{
1546
0
    x -= v.x;
1547
0
    y -= v.y;
1548
0
    z -= v.z;
1549
0
    return *this;
1550
0
}
1551
1552
template <class T>
1553
inline Vec3<T>
1554
Vec3<T>::operator - (const Vec3 &v) const
1555
{
1556
    return Vec3 (x - v.x, y - v.y, z - v.z);
1557
}
1558
1559
template <class T>
1560
inline Vec3<T>
1561
Vec3<T>::operator - () const
1562
{
1563
    return Vec3 (-x, -y, -z);
1564
}
1565
1566
template <class T>
1567
inline const Vec3<T> &
1568
Vec3<T>::negate ()
1569
{
1570
    x = -x;
1571
    y = -y;
1572
    z = -z;
1573
    return *this;
1574
}
1575
1576
template <class T>
1577
inline const Vec3<T> &
1578
Vec3<T>::operator *= (const Vec3 &v)
1579
{
1580
    x *= v.x;
1581
    y *= v.y;
1582
    z *= v.z;
1583
    return *this;
1584
}
1585
1586
template <class T>
1587
inline const Vec3<T> &
1588
Vec3<T>::operator *= (T a)
1589
0
{
1590
0
    x *= a;
1591
0
    y *= a;
1592
0
    z *= a;
1593
0
    return *this;
1594
0
}
1595
1596
template <class T>
1597
inline Vec3<T>
1598
Vec3<T>::operator * (const Vec3 &v) const
1599
{
1600
    return Vec3 (x * v.x, y * v.y, z * v.z);
1601
}
1602
1603
template <class T>
1604
inline Vec3<T>
1605
Vec3<T>::operator * (T a) const
1606
{
1607
    return Vec3 (x * a, y * a, z * a);
1608
}
1609
1610
template <class T>
1611
inline const Vec3<T> &
1612
Vec3<T>::operator /= (const Vec3 &v)
1613
{
1614
    x /= v.x;
1615
    y /= v.y;
1616
    z /= v.z;
1617
    return *this;
1618
}
1619
1620
template <class T>
1621
inline const Vec3<T> &
1622
Vec3<T>::operator /= (T a)
1623
0
{
1624
0
    x /= a;
1625
0
    y /= a;
1626
0
    z /= a;
1627
0
    return *this;
1628
0
}
1629
1630
template <class T>
1631
inline Vec3<T>
1632
Vec3<T>::operator / (const Vec3 &v) const
1633
{
1634
    return Vec3 (x / v.x, y / v.y, z / v.z);
1635
}
1636
1637
template <class T>
1638
inline Vec3<T>
1639
Vec3<T>::operator / (T a) const
1640
{
1641
    return Vec3 (x / a, y / a, z / a);
1642
}
1643
1644
template <class T>
1645
T
1646
Vec3<T>::lengthTiny () const
1647
0
{
1648
0
    T absX = (x >= T (0))? x: -x;
1649
0
    T absY = (y >= T (0))? y: -y;
1650
0
    T absZ = (z >= T (0))? z: -z;
1651
    
1652
0
    T max = absX;
1653
1654
0
    if (max < absY)
1655
0
  max = absY;
1656
1657
0
    if (max < absZ)
1658
0
  max = absZ;
1659
1660
0
    if (max == T (0))
1661
0
  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
0
    absX /= max;
1670
0
    absY /= max;
1671
0
    absZ /= max;
1672
1673
0
    return max * Math<T>::sqrt (absX * absX + absY * absY + absZ * absZ);
1674
0
}
1675
1676
template <class T>
1677
inline T
1678
Vec3<T>::length () const
1679
0
{
1680
0
    T length2 = dot (*this);
1681
1682
0
    if (length2 < T (2) * limits<T>::smallest())
1683
0
  return lengthTiny();
1684
1685
0
    return Math<T>::sqrt (length2);
1686
0
}
1687
1688
template <class T>
1689
inline T
1690
Vec3<T>::length2 () const
1691
{
1692
    return dot (*this);
1693
}
1694
1695
template <class T>
1696
const Vec3<T> &
1697
Vec3<T>::normalize ()
1698
0
{
1699
0
    T l = length();
1700
1701
0
    if (l != T (0))
1702
0
    {
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
0
  x /= l;
1710
0
  y /= l;
1711
0
  z /= l;
1712
0
    }
1713
1714
0
    return *this;
1715
0
}
1716
1717
template <class T>
1718
const Vec3<T> &
1719
Vec3<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
1732
template <class T>
1733
inline
1734
const Vec3<T> &
1735
Vec3<T>::normalizeNonNull ()
1736
{
1737
    T l = length();
1738
    x /= l;
1739
    y /= l;
1740
    z /= l;
1741
    return *this;
1742
}
1743
1744
template <class T>
1745
Vec3<T>
1746
Vec3<T>::normalized () const
1747
0
{
1748
0
    T l = length();
1749
1750
0
    if (l == T (0))
1751
0
  return Vec3 (T (0));
1752
1753
0
    return Vec3 (x / l, y / l, z / l);
1754
0
}
1755
1756
template <class T>
1757
Vec3<T>
1758
Vec3<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
1768
template <class T>
1769
inline
1770
Vec3<T>
1771
Vec3<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
1782
template <class T>
1783
inline T &
1784
Vec4<T>::operator [] (int i)
1785
{
1786
    return (&x)[i]; // NOSONAR - suppress SonarCloud bug report.
1787
}
1788
1789
template <class T>
1790
inline const T &
1791
Vec4<T>::operator [] (int i) const
1792
{
1793
    return (&x)[i]; // NOSONAR - suppress SonarCloud bug report.
1794
}
1795
1796
template <class T>
1797
inline
1798
Vec4<T>::Vec4 ()
1799
{
1800
    // empty
1801
}
1802
1803
template <class T>
1804
inline
1805
Vec4<T>::Vec4 (T a)
1806
{
1807
    x = y = z = w = a;
1808
}
1809
1810
template <class T>
1811
inline
1812
Vec4<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
1820
template <class T>
1821
inline
1822
Vec4<T>::Vec4 (const Vec4 &v)
1823
{
1824
    x = v.x;
1825
    y = v.y;
1826
    z = v.z;
1827
    w = v.w;
1828
}
1829
1830
template <class T>
1831
template <class S>
1832
inline
1833
Vec4<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
1841
template <class T>
1842
inline const Vec4<T> &
1843
Vec4<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
1852
template <class T>
1853
template <class S>
1854
inline
1855
Vec4<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
1863
template <class T>
1864
template <class S>
1865
inline bool
1866
Vec4<T>::operator == (const Vec4<S> &v) const
1867
{
1868
    return x == v.x && y == v.y && z == v.z && w == v.w;
1869
}
1870
1871
template <class T>
1872
template <class S>
1873
inline bool
1874
Vec4<T>::operator != (const Vec4<S> &v) const
1875
{
1876
    return x != v.x || y != v.y || z != v.z || w != v.w;
1877
}
1878
1879
template <class T>
1880
bool
1881
Vec4<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
1890
template <class T>
1891
bool
1892
Vec4<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
1901
template <class T>
1902
inline T
1903
Vec4<T>::dot (const Vec4 &v) const
1904
{
1905
    return x * v.x + y * v.y + z * v.z + w * v.w;
1906
}
1907
1908
template <class T>
1909
inline T
1910
Vec4<T>::operator ^ (const Vec4 &v) const
1911
{
1912
    return dot (v);
1913
}
1914
1915
1916
template <class T>
1917
inline const Vec4<T> &
1918
Vec4<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
1927
template <class T>
1928
inline Vec4<T>
1929
Vec4<T>::operator + (const Vec4 &v) const
1930
{
1931
    return Vec4 (x + v.x, y + v.y, z + v.z, w + v.w);
1932
}
1933
1934
template <class T>
1935
inline const Vec4<T> &
1936
Vec4<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
1945
template <class T>
1946
inline Vec4<T>
1947
Vec4<T>::operator - (const Vec4 &v) const
1948
{
1949
    return Vec4 (x - v.x, y - v.y, z - v.z, w - v.w);
1950
}
1951
1952
template <class T>
1953
inline Vec4<T>
1954
Vec4<T>::operator - () const
1955
{
1956
    return Vec4 (-x, -y, -z, -w);
1957
}
1958
1959
template <class T>
1960
inline const Vec4<T> &
1961
Vec4<T>::negate ()
1962
{
1963
    x = -x;
1964
    y = -y;
1965
    z = -z;
1966
    w = -w;
1967
    return *this;
1968
}
1969
1970
template <class T>
1971
inline const Vec4<T> &
1972
Vec4<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
1981
template <class T>
1982
inline const Vec4<T> &
1983
Vec4<T>::operator *= (T a)
1984
{
1985
    x *= a;
1986
    y *= a;
1987
    z *= a;
1988
    w *= a;
1989
    return *this;
1990
}
1991
1992
template <class T>
1993
inline Vec4<T>
1994
Vec4<T>::operator * (const Vec4 &v) const
1995
{
1996
    return Vec4 (x * v.x, y * v.y, z * v.z, w * v.w);
1997
}
1998
1999
template <class T>
2000
inline Vec4<T>
2001
Vec4<T>::operator * (T a) const
2002
{
2003
    return Vec4 (x * a, y * a, z * a, w * a);
2004
}
2005
2006
template <class T>
2007
inline const Vec4<T> &
2008
Vec4<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
2017
template <class T>
2018
inline const Vec4<T> &
2019
Vec4<T>::operator /= (T a)
2020
{
2021
    x /= a;
2022
    y /= a;
2023
    z /= a;
2024
    w /= a;
2025
    return *this;
2026
}
2027
2028
template <class T>
2029
inline Vec4<T>
2030
Vec4<T>::operator / (const Vec4 &v) const
2031
{
2032
    return Vec4 (x / v.x, y / v.y, z / v.z, w / v.w);
2033
}
2034
2035
template <class T>
2036
inline Vec4<T>
2037
Vec4<T>::operator / (T a) const
2038
{
2039
    return Vec4 (x / a, y / a, z / a, w / a);
2040
}
2041
2042
template <class T>
2043
T
2044
Vec4<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
2080
template <class T>
2081
inline T
2082
Vec4<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
2092
template <class T>
2093
inline T
2094
Vec4<T>::length2 () const
2095
{
2096
    return dot (*this);
2097
}
2098
2099
template <class T>
2100
const Vec4<T> &
2101
Vec4<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
2122
template <class T>
2123
const Vec4<T> &
2124
Vec4<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
2138
template <class T>
2139
inline
2140
const Vec4<T> &
2141
Vec4<T>::normalizeNonNull ()
2142
{
2143
    T l = length();
2144
    x /= l;
2145
    y /= l;
2146
    z /= l;
2147
    w /= l;
2148
    return *this;
2149
}
2150
2151
template <class T>
2152
Vec4<T>
2153
Vec4<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
2163
template <class T>
2164
Vec4<T>
2165
Vec4<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
2175
template <class T>
2176
inline
2177
Vec4<T>
2178
Vec4<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
2188
template <class T>
2189
std::ostream &
2190
operator << (std::ostream &s, const Vec2<T> &v)
2191
{
2192
    return s << '(' << v.x << ' ' << v.y << ')';
2193
}
2194
2195
template <class T>
2196
std::ostream &
2197
operator << (std::ostream &s, const Vec3<T> &v)
2198
{
2199
    return s << '(' << v.x << ' ' << v.y << ' ' << v.z << ')';
2200
}
2201
2202
template <class T>
2203
std::ostream &
2204
operator << (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
2214
template <class T>
2215
inline Vec2<T>
2216
operator * (T a, const Vec2<T> &v)
2217
{
2218
    return Vec2<T> (a * v.x, a * v.y);
2219
}
2220
2221
template <class T>
2222
inline Vec3<T>
2223
operator * (T a, const Vec3<T> &v)
2224
0
{
2225
0
    return Vec3<T> (a * v.x, a * v.y, a * v.z);
2226
0
}
2227
2228
template <class T>
2229
inline Vec4<T>
2230
operator * (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
2240
IMATH_INTERNAL_NAMESPACE_HEADER_EXIT
2241
2242
#endif // INCLUDED_IMATHVEC_H