Compile fixes for gcc 3.4
[blender-staging.git] / extern / solid / include / MT / Vector3.h
1 /*
2  * SOLID - Software Library for Interference Detection
3  * 
4  * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
5  *
6  * This library may be distributed under the terms of the Q Public License
7  * (QPL) as defined by Trolltech AS of Norway and appearing in the file
8  * LICENSE.QPL included in the packaging of this file.
9  *
10  * This library may be distributed and/or modified under the terms of the
11  * GNU General Public License (GPL) version 2 as published by the Free Software
12  * Foundation and appearing in the file LICENSE.GPL included in the
13  * packaging of this file.
14  *
15  * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
16  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
17  *
18  * Commercial use or any other use of this library not covered by either 
19  * the QPL or the GPL requires an additional license from Dtecta. 
20  * Please contact info@dtecta.com for enquiries about the terms of commercial
21  * use of this library.
22  */
23
24 #ifndef VECTOR3_H
25 #define VECTOR3_H
26
27 #include <cassert>
28
29 #include "Tuple3.h"
30
31 namespace MT {
32
33         template <typename Scalar>      
34         class Vector3 : public Tuple3<Scalar> {
35         public:
36                 Vector3() {}
37         
38                 template <typename Scalar2>
39                 explicit Vector3(const Scalar2 *v) : Tuple3<Scalar>(v) {}
40                 
41                 template <typename Scalar2>
42                 Vector3(const Scalar2& x, const Scalar2& y, const Scalar2& z) 
43                         : Tuple3<Scalar>(x, y, z) 
44                 {}
45                 
46                 Vector3<Scalar>& operator+=(const Vector3<Scalar>& v)
47                 {
48                         this->m_co[0] += v[0]; this->m_co[1] += v[1]; this->m_co[2] += v[2];
49                         return *this;
50                 }
51                 
52                 Vector3<Scalar>& operator-=(const Vector3<Scalar>& v) 
53                 {
54                         this->m_co[0] -= v[0]; this->m_co[1] -= v[1]; this->m_co[2] -= v[2];
55                         return *this;
56                 }
57
58                 Vector3<Scalar>& operator*=(const Scalar& s)
59                 {
60                         this->m_co[0] *= s; this->m_co[1] *= s; this->m_co[2] *= s;
61                         return *this;
62                 }
63                 
64                 Vector3<Scalar>& operator/=(const Scalar& s) 
65                 {
66                         assert(s != Scalar(0.0));
67                         return *this *= Scalar(1.0) / s;
68                 }
69   
70                 Scalar dot(const Vector3<Scalar>& v) const
71                 {
72                         return this->m_co[0] * v[0] + this->m_co[1] * v[1] + this->m_co[2] * v[2];
73                 }
74
75                 Scalar length2() const
76                 {
77                         return dot(*this);
78                 }
79
80                 Scalar length() const
81                 {
82                         return Scalar_traits<Scalar>::sqrt(length2());
83                 }
84
85                 Scalar distance2(const Vector3<Scalar>& v) const 
86                 {
87                         return (v - *this).length2();
88                 }
89
90                 Scalar distance(const Vector3<Scalar>& v) const 
91                 {
92                         return (v - *this).length();
93                 }
94                 
95                 Vector3<Scalar>& normalize() 
96                 {
97                         return *this /= length();
98                 }
99                 
100                 Vector3<Scalar> normalized() const 
101                 {
102                         return *this / length();
103                 } 
104
105                 Scalar angle(const Vector3<Scalar>& v) const 
106                 {
107                         Scalar s = Scalar_traits<Scalar>::sqrt(length2() * v.length2());
108                         assert(s != Scalar(0.0));
109                         return Scalar_traits<Scalar>::acos(dot(v) / s);
110                 }
111    
112                 Vector3<Scalar> absolute() const 
113                 {
114                         return Vector3<Scalar>(Scalar_traits<Scalar>::abs(this->m_co[0]), 
115                                                                    Scalar_traits<Scalar>::abs(this->m_co[1]), 
116                                                                    Scalar_traits<Scalar>::abs(this->m_co[2]));
117                 }
118
119                 Vector3<Scalar> cross(const Vector3<Scalar>& v) const
120                 {
121                         return Vector3<Scalar>(this->m_co[1] * v[2] - this->m_co[2] * v[1],
122                                                                    this->m_co[2] * v[0] - this->m_co[0] * v[2],
123                                                                    this->m_co[0] * v[1] - this->m_co[1] * v[0]);
124                 }
125                 
126                 Scalar triple(const Vector3<Scalar>& v1, const Vector3<Scalar>& v2) const
127                 {
128                         return this->m_co[0] * (v1[1] * v2[2] - v1[2] * v2[1]) + 
129                                    this->m_co[1] * (v1[2] * v2[0] - v1[0] * v2[2]) + 
130                                    this->m_co[2] * (v1[0] * v2[1] - v1[1] * v2[0]);
131                 }
132
133                 int minAxis() const
134                 {
135                         return this->m_co[0] < this->m_co[1] ? (this->m_co[0] < this->m_co[2] ? 0 : 2) : (this->m_co[1] < this->m_co[2] ? 1 : 2);
136                 }
137
138                 int maxAxis() const 
139                 {
140                         return this->m_co[0] < this->m_co[1] ? (this->m_co[1] < this->m_co[2] ? 2 : 1) : (this->m_co[0] < this->m_co[2] ? 2 : 0);
141                 }
142
143                 int furthestAxis() const
144                 {
145                         return absolute().minAxis();
146                 }
147
148                 int closestAxis() const 
149                 {
150                         return absolute().maxAxis();
151                 }
152
153                 Vector3<Scalar> lerp(const Vector3<Scalar>& v, const Scalar& t) const 
154                 {
155                         return Vector3<Scalar>(this->m_co[0] + (v[0] - this->m_co[0]) * t,
156                                                                    this->m_co[1] + (v[1] - this->m_co[1]) * t,
157                                                                    this->m_co[2] + (v[2] - this->m_co[2]) * t);
158                 }
159     
160                 static Vector3<Scalar> random() 
161                 {
162                         Scalar z = Scalar(2.0) * Scalar_traits<Scalar>::random() - Scalar(1.0);
163                         Scalar r = Scalar_traits<Scalar>::sqrt(Scalar(1.0) - z * z);
164                         Scalar t = Scalar_traits<Scalar>::TwoTimesPi() * Scalar_traits<Scalar>::random();
165                         return Vector3<Scalar>(r * Scalar_traits<Scalar>::cos(t), 
166                                                                    r * Scalar_traits<Scalar>::sin(t), 
167                                                                    z);
168                 }
169         };
170
171         template <typename Scalar>
172         inline Vector3<Scalar> 
173         operator+(const Vector3<Scalar>& v1, const Vector3<Scalar>& v2) 
174         {
175                 return Vector3<Scalar>(v1[0] + v2[0], v1[1] + v2[1], v1[2] + v2[2]);
176         }
177
178         template <typename Scalar>
179         inline Vector3<Scalar> 
180         operator-(const Vector3<Scalar>& v1, const Vector3<Scalar>& v2)
181         {
182                 return Vector3<Scalar>(v1[0] - v2[0], v1[1] - v2[1], v1[2] - v2[2]);
183         }
184         
185         template <typename Scalar>
186         inline Vector3<Scalar> 
187         operator-(const Vector3<Scalar>& v)
188         {
189                 return Vector3<Scalar>(-v[0], -v[1], -v[2]);
190         }
191         
192         template <typename Scalar>
193         inline Vector3<Scalar> 
194         operator*(const Vector3<Scalar>& v, const Scalar& s)
195         {
196                 return Vector3<Scalar>(v[0] * s, v[1] * s, v[2] * s);
197         }
198         
199         template <typename Scalar>
200         inline Vector3<Scalar> 
201         operator*(const Scalar& s, const Vector3<Scalar>& v)
202         { 
203                 return v * s; 
204         }
205         
206         template <typename Scalar>
207         inline Vector3<Scalar>
208         operator/(const Vector3<Scalar>& v, const Scalar& s)
209         {
210                 assert(s != Scalar(0.0));
211                 return v * (Scalar(1.0) / s);
212         }
213         
214         template <typename Scalar>
215         inline Scalar 
216         dot(const Vector3<Scalar>& v1, const Vector3<Scalar>& v2) 
217         { 
218                 return v1.dot(v2); 
219         }
220         
221         template <typename Scalar>
222         inline Scalar
223         length2(const Vector3<Scalar>& v) 
224         { 
225                 return v.length2(); 
226         }
227
228         template <typename Scalar>
229         inline Scalar
230         length(const Vector3<Scalar>& v) 
231         { 
232                 return v.length(); 
233         }
234
235         template <typename Scalar>
236         inline Scalar
237         distance2(const Vector3<Scalar>& v1, const Vector3<Scalar>& v2) 
238         { 
239                 return v1.distance2(v2); 
240         }
241
242         template <typename Scalar>
243         inline Scalar
244         distance(const Vector3<Scalar>& v1, const Vector3<Scalar>& v2) 
245         { 
246                 return v1.distance(v2); 
247         }
248
249         template <typename Scalar>
250         inline Scalar
251         angle(const Vector3<Scalar>& v1, const Vector3<Scalar>& v2) 
252         { 
253                 return v1.angle(v2); 
254         }
255
256         template <typename Scalar>
257         inline Vector3<Scalar> 
258         cross(const Vector3<Scalar>& v1, const Vector3<Scalar>& v2) 
259         { 
260                 return v1.cross(v2); 
261         }
262
263         template <typename Scalar>
264         inline Scalar
265         triple(const Vector3<Scalar>& v1, const Vector3<Scalar>& v2, const Vector3<Scalar>& v3)
266         {
267                 return v1.triple(v2, v3);
268         }
269
270         template <typename Scalar>
271         inline Vector3<Scalar> 
272         lerp(const Vector3<Scalar>& v1, const Vector3<Scalar>& v2, const Scalar& t)
273         {
274                 return v1.lerp(v2, t);
275         }
276
277 }
278
279 #endif