2 * Copyright 1993-2013 NVIDIA Corporation. All rights reserved.
4 * Please refer to the NVIDIA end user license agreement (EULA) associated
5 * with this source code for terms and conditions that govern your use of
6 * this software. Any use, reproduction, disclosure, or distribution of
7 * this software and related documentation outside the terms of the EULA
8 * is strictly prohibited.
13 // Template math library for common 3D functionality
15 // nvVector.h - 2-vector, 3-vector, and 4-vector templates and utilities
17 // This code is in part deriver from glh, a cross platform glut helper library.
18 // The copyright for glh follows this notice.
20 // Copyright (c) NVIDIA Corporation. All rights reserved.
21 ////////////////////////////////////////////////////////////////////////////////
24 Copyright (c) 2000 Cass Everitt
25 Copyright (c) 2000 NVIDIA Corporation
28 Redistribution and use in source and binary forms, with or
29 without modification, are permitted provided that the following
32 * Redistributions of source code must retain the above
33 copyright notice, this list of conditions and the following
36 * Redistributions in binary form must reproduce the above
37 copyright notice, this list of conditions and the following
38 disclaimer in the documentation and/or other materials
39 provided with the distribution.
41 * The names of contributors to this software may not be used
42 to endorse or promote products derived from this software
43 without specific prior written permission.
45 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
46 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
47 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
48 FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
49 REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
50 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
51 BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
52 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
53 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
54 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
55 ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
56 POSSIBILITY OF SUCH DAMAGE.
59 Cass Everitt - cass@r3.nu
67 template <class T> class vec2;
68 template <class T> class vec3;
69 template <class T> class vec4;
71 //////////////////////////////////////////////////////////////////////
73 // vec2 - template class for 2-tuple vector
75 //////////////////////////////////////////////////////////////////////
87 ////////////////////////////////////////////////////////
91 ////////////////////////////////////////////////////////
93 // Default/scalar constructor
94 vec2(const T &t = T())
96 for (int i = 0; i < size(); i++)
102 // Construct from array
105 for (int i = 0; i < size(); i++)
111 // Construct from explicit values
112 vec2(const T v0, const T v1)
118 explicit vec2(const vec3<T> &u)
120 for (int i = 0; i < size(); i++)
122 _array[i] = u._array[i];
126 explicit vec2(const vec4<T> &u)
128 for (int i = 0; i < size(); i++)
130 _array[i] = u._array[i];
134 const T *get_value() const
139 vec2<T> &set_value(const T *rhs)
141 for (int i = 0; i < size(); i++)
149 // indexing operators
150 T &operator [](int i)
155 const T &operator [](int i) const
160 // type-cast operators
166 operator const T *() const
171 ////////////////////////////////////////////////////////
175 ////////////////////////////////////////////////////////
177 // scalar multiply assign
178 friend vec2<T> &operator *= (vec2<T> &lhs, T d)
180 for (int i = 0; i < lhs.size(); i++)
188 // component-wise vector multiply assign
189 friend vec2<T> &operator *= (vec2<T> &lhs, const vec2<T> &rhs)
191 for (int i = 0; i < lhs.size(); i++)
193 lhs._array[i] *= rhs[i];
199 // scalar divide assign
200 friend vec2<T> &operator /= (vec2<T> &lhs, T d)
207 for (int i = 0; i < lhs.size(); i++)
215 // component-wise vector divide assign
216 friend vec2<T> &operator /= (vec2<T> &lhs, const vec2<T> &rhs)
218 for (int i = 0; i < lhs.size(); i++)
220 lhs._array[i] /= rhs._array[i];
226 // component-wise vector add assign
227 friend vec2<T> &operator += (vec2<T> &lhs, const vec2<T> &rhs)
229 for (int i = 0; i < lhs.size(); i++)
231 lhs._array[i] += rhs._array[i];
237 // component-wise vector subtract assign
238 friend vec2<T> &operator -= (vec2<T> &lhs, const vec2<T> &rhs)
240 for (int i = 0; i < lhs.size(); i++)
242 lhs._array[i] -= rhs._array[i];
249 friend vec2<T> operator - (const vec2<T> &rhs)
253 for (int i = 0; i < rhs.size(); i++)
255 rv._array[i] = -rhs._array[i];
262 friend vec2<T> operator + (const vec2<T> &lhs, const vec2<T> &rhs)
269 friend vec2<T> operator - (const vec2<T> &lhs, const vec2<T> &rhs)
276 friend vec2<T> operator * (const vec2<T> &lhs, T rhs)
283 friend vec2<T> operator * (T lhs, const vec2<T> &rhs)
289 // vector component-wise multiply
290 friend vec2<T> operator * (const vec2<T> &lhs, const vec2<T> &rhs)
297 friend vec2<T> operator / (const vec2<T> &lhs, T rhs)
303 // vector component-wise multiply
304 friend vec2<T> operator / (const vec2<T> &lhs, const vec2<T> &rhs)
310 ////////////////////////////////////////////////////////
312 // Comparison operators
314 ////////////////////////////////////////////////////////
317 friend bool operator == (const vec2<T> &lhs, const vec2<T> &rhs)
321 for (int i = 0; i < lhs.size(); i++)
323 r &= lhs._array[i] == rhs._array[i];
330 friend bool operator != (const vec2<T> &lhs, const vec2<T> &rhs)
334 for (int i = 0; i < lhs.size(); i++)
336 r &= lhs._array[i] != rhs._array[i];
342 //data intentionally left public to allow vec2.x
347 T x,y; // standard names for components
351 T s,t; // standard names for components
353 T _array[2]; // array access
357 //////////////////////////////////////////////////////////////////////
359 // vec3 - template class for 3-tuple vector
361 //////////////////////////////////////////////////////////////////////
367 typedef T value_type;
373 ////////////////////////////////////////////////////////
377 ////////////////////////////////////////////////////////
379 // Default/scalar constructor
380 vec3(const T &t = T())
382 for (int i = 0; i < size(); i++)
388 // Construct from array
391 for (int i = 0; i < size(); i++)
397 // Construct from explicit values
398 vec3(const T v0, const T v1, const T v2)
405 explicit vec3(const vec4<T> &u)
407 for (int i = 0; i < size(); i++)
409 _array[i] = u._array[i];
413 explicit vec3(const vec2<T> &u, T v0)
420 const T *get_value() const
425 vec3<T> &set_value(const T *rhs)
427 for (int i = 0; i < size(); i++)
435 // indexing operators
436 T &operator [](int i)
441 const T &operator [](int i) const
446 // type-cast operators
452 operator const T *() const
457 ////////////////////////////////////////////////////////
461 ////////////////////////////////////////////////////////
463 // scalar multiply assign
464 friend vec3<T> &operator *= (vec3<T> &lhs, T d)
466 for (int i = 0; i < lhs.size(); i++)
474 // component-wise vector multiply assign
475 friend vec3<T> &operator *= (vec3<T> &lhs, const vec3<T> &rhs)
477 for (int i = 0; i < lhs.size(); i++)
479 lhs._array[i] *= rhs[i];
485 // scalar divide assign
486 friend vec3<T> &operator /= (vec3<T> &lhs, T d)
493 for (int i = 0; i < lhs.size(); i++)
501 // component-wise vector divide assign
502 friend vec3<T> &operator /= (vec3<T> &lhs, const vec3<T> &rhs)
504 for (int i = 0; i < lhs.size(); i++)
506 lhs._array[i] /= rhs._array[i];
512 // component-wise vector add assign
513 friend vec3<T> &operator += (vec3<T> &lhs, const vec3<T> &rhs)
515 for (int i = 0; i < lhs.size(); i++)
517 lhs._array[i] += rhs._array[i];
523 // component-wise vector subtract assign
524 friend vec3<T> &operator -= (vec3<T> &lhs, const vec3<T> &rhs)
526 for (int i = 0; i < lhs.size(); i++)
528 lhs._array[i] -= rhs._array[i];
535 friend vec3<T> operator - (const vec3<T> &rhs)
539 for (int i = 0; i < rhs.size(); i++)
541 rv._array[i] = -rhs._array[i];
548 friend vec3<T> operator + (const vec3<T> &lhs, const vec3<T> &rhs)
555 friend vec3<T> operator - (const vec3<T> &lhs, const vec3<T> &rhs)
562 friend vec3<T> operator * (const vec3<T> &lhs, T rhs)
569 friend vec3<T> operator * (T lhs, const vec3<T> &rhs)
575 // vector component-wise multiply
576 friend vec3<T> operator * (const vec3<T> &lhs, const vec3<T> &rhs)
583 friend vec3<T> operator / (const vec3<T> &lhs, T rhs)
589 // vector component-wise multiply
590 friend vec3<T> operator / (const vec3<T> &lhs, const vec3<T> &rhs)
596 ////////////////////////////////////////////////////////
598 // Comparison operators
600 ////////////////////////////////////////////////////////
603 friend bool operator == (const vec3<T> &lhs, const vec3<T> &rhs)
607 for (int i = 0; i < lhs.size(); i++)
609 r &= lhs._array[i] == rhs._array[i];
616 friend bool operator != (const vec3<T> &lhs, const vec3<T> &rhs)
620 for (int i = 0; i < lhs.size(); i++)
622 r &= lhs._array[i] != rhs._array[i];
628 ////////////////////////////////////////////////////////////////////////////////
630 // dimension specific operations
632 ////////////////////////////////////////////////////////////////////////////////
635 friend vec3<T> cross(const vec3<T> &lhs, const vec3<T> &rhs)
639 r.x = lhs.y * rhs.z - lhs.z * rhs.y;
640 r.y = lhs.z * rhs.x - lhs.x * rhs.z;
641 r.z = lhs.x * rhs.y - lhs.y * rhs.x;
646 //data intentionally left public to allow vec2.x
651 T x, y, z; // standard names for components
655 T s, t, r; // standard names for components
657 T _array[3]; // array access
661 //////////////////////////////////////////////////////////////////////
663 // vec4 - template class for 4-tuple vector
665 //////////////////////////////////////////////////////////////////////
671 typedef T value_type;
677 ////////////////////////////////////////////////////////
681 ////////////////////////////////////////////////////////
683 // Default/scalar constructor
684 vec4(const T &t = T())
686 for (int i = 0; i < size(); i++)
692 // Construct from array
695 for (int i = 0; i < size(); i++)
701 // Construct from explicit values
702 vec4(const T v0, const T v1, const T v2, const T v3)
710 explicit vec4(const vec3<T> &u, T v0)
718 explicit vec4(const vec2<T> &u, T v0, T v1)
726 const T *get_value() const
731 vec4<T> &set_value(const T *rhs)
733 for (int i = 0; i < size(); i++)
741 // indexing operators
742 T &operator [](int i)
747 const T &operator [](int i) const
752 // type-cast operators
758 operator const T *() const
763 ////////////////////////////////////////////////////////
767 ////////////////////////////////////////////////////////
769 // scalar multiply assign
770 friend vec4<T> &operator *= (vec4<T> &lhs, T d)
772 for (int i = 0; i < lhs.size(); i++)
780 // component-wise vector multiply assign
781 friend vec4<T> &operator *= (vec4<T> &lhs, const vec4<T> &rhs)
783 for (int i = 0; i < lhs.size(); i++)
785 lhs._array[i] *= rhs[i];
791 // scalar divide assign
792 friend vec4<T> &operator /= (vec4<T> &lhs, T d)
799 for (int i = 0; i < lhs.size(); i++)
807 // component-wise vector divide assign
808 friend vec4<T> &operator /= (vec4<T> &lhs, const vec4<T> &rhs)
810 for (int i = 0; i < lhs.size(); i++)
812 lhs._array[i] /= rhs._array[i];
818 // component-wise vector add assign
819 friend vec4<T> &operator += (vec4<T> &lhs, const vec4<T> &rhs)
821 for (int i = 0; i < lhs.size(); i++)
823 lhs._array[i] += rhs._array[i];
829 // component-wise vector subtract assign
830 friend vec4<T> &operator -= (vec4<T> &lhs, const vec4<T> &rhs)
832 for (int i = 0; i < lhs.size(); i++)
834 lhs._array[i] -= rhs._array[i];
841 friend vec4<T> operator - (const vec4<T> &rhs)
845 for (int i = 0; i < rhs.size(); i++)
847 rv._array[i] = -rhs._array[i];
854 friend vec4<T> operator + (const vec4<T> &lhs, const vec4<T> &rhs)
861 friend vec4<T> operator - (const vec4<T> &lhs, const vec4<T> &rhs)
868 friend vec4<T> operator * (const vec4<T> &lhs, T rhs)
875 friend vec4<T> operator * (T lhs, const vec4<T> &rhs)
881 // vector component-wise multiply
882 friend vec4<T> operator * (const vec4<T> &lhs, const vec4<T> &rhs)
889 friend vec4<T> operator / (const vec4<T> &lhs, T rhs)
895 // vector component-wise multiply
896 friend vec4<T> operator / (const vec4<T> &lhs, const vec4<T> &rhs)
902 ////////////////////////////////////////////////////////
904 // Comparison operators
906 ////////////////////////////////////////////////////////
909 friend bool operator == (const vec4<T> &lhs, const vec4<T> &rhs)
913 for (int i = 0; i < lhs.size(); i++)
915 r &= lhs._array[i] == rhs._array[i];
922 friend bool operator != (const vec4<T> &lhs, const vec4<T> &rhs)
926 for (int i = 0; i < lhs.size(); i++)
928 r &= lhs._array[i] != rhs._array[i];
934 //data intentionally left public to allow vec2.x
939 T x, y, z, w; // standard names for components
943 T s, t, r, q; // standard names for components
945 T _array[4]; // array access
949 ////////////////////////////////////////////////////////////////////////////////
951 // Generic vector operations
953 ////////////////////////////////////////////////////////////////////////////////
955 // compute the dot product of two vectors
957 inline typename T::value_type dot(const T &lhs, const T &rhs)
959 typename T::value_type r = 0;
961 for (int i = 0; i < lhs.size(); i++)
963 r += lhs._array[i] * rhs._array[i];
969 // return the length of the provided vector
971 inline typename T::value_type length(const T &vec)
973 typename T::value_type r = 0;
975 for (int i = 0; i < vec.size(); i++)
977 r += vec._array[i]*vec._array[i];
980 return typename T::value_type(sqrt(r));
983 // return the squared norm
985 inline typename T::value_type square_norm(const T &vec)
987 typename T::value_type r = 0;
989 for (int i = 0; i < vec.size(); i++)
991 r += vec._array[i]*vec._array[i];
997 // return the normalized version of the vector
999 inline T normalize(const T &vec)
1001 typename T::value_type sum(0);
1004 for (int i = 0; i < vec.size(); i++)
1006 sum += vec._array[i] * vec._array[i];
1009 sum = typename T::value_type(sqrt(sum));
1012 for (int i = 0; i < vec.size(); i++)
1014 r._array[i] = vec._array[i] / sum;
1020 // In VC8 : min and max are already defined by a #define...
1029 inline T min(const T &lhs, const T &rhs)
1033 for (int i = 0; i < lhs.size(); i++)
1035 rt._array[i] = std::min(lhs._array[i], rhs._array[i]);
1041 // componentwise max
1043 inline T max(const T &lhs, const T &rhs)
1047 for (int i = 0; i < lhs.size(); i++)
1049 rt._array[i] = std::max(lhs._array[i], rhs._array[i]);