Reverted incorrect merge (missing files)
[blender.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 #if defined (__sgi)
28 #include <assert.h>
29 #else
30 #include <cassert>
31 #endif
32
33 #include "Tuple3.h"
34
35 namespace MT {
36
37         template <typename Scalar>      
38         class Vector3 : public Tuple3<Scalar> {
39         public:
40                 Vector3() {}
41         
42                 template <typename Scalar2>
43                 explicit Vector3(const Scalar2 *v) : Tuple3<Scalar>(v) {}
44                 
45                 template <typename Scalar2>
46                 Vector3(const Scalar2& x, const Scalar2& y, const Scalar2& z) 
47                         : Tuple3<Scalar>(x, y, z) 
48                 {}
49                 
50                 Vector3<Scalar>& operator+=(const Vector3<Scalar>& v)
51                 {
52                         this->m_co[0] += v[0]; this->m_co[1] += v[1]; this->m_co[2] += v[2];
53                         return *this;
54                 }
55                 
56                 Vector3<Scalar>& operator-=(const Vector3<Scalar>& v) 
57                 {
58                         this->m_co[0] -= v[0]; this->m_co[1] -= v[1]; this->m_co[2] -= v[2];
59                         return *this;
60                 }
61
62                 Vector3<Scalar>& operator*=(const Scalar& s)
63                 {
64                         this->m_co[0] *= s; this->m_co[1] *= s; this->m_co[2] *= s;
65                         return *this;
66                 }
67                 
68                 Vector3<Scalar>& operator/=(const Scalar& s) 
69                 {
70                         assert(s != Scalar(0.0));
71                         return *this *= Scalar(1.0) / s;
72                 }
73   
74                 Scalar dot(const Vector3<Scalar>& v) const
75                 {
76                         return this->m_co[0] * v[0] + this->m_co[1] * v[1] + this->m_co[2] * v[2];
77                 }
78
79                 Scalar length2() const
80                 {
81                         return dot(*this);
82                 }
83
84                 Scalar length() const
85                 {
86                         return Scalar_traits<Scalar>::sqrt(length2());
87                 }
88
89                 Scalar distance2(const Vector3<Scalar>& v) const 
90                 {
91                         return (v - *this).length2();
92                 }
93
94                 Scalar distance(const Vector3<Scalar>& v) const 
95                 {
96                         return (v - *this).length();
97                 }
98                 
99                 Vector3<Scalar>& normalize() 
100                 {
101                         return *this /= length();
102                 }
103                 
104                 Vector3<Scalar> normalized() const 
105                 {
106                         return *this / length();
107                 } 
108
109                 Scalar angle(const Vector3<Scalar>& v) const 
110                 {
111                         Scalar s = Scalar_traits<Scalar>::sqrt(length2() * v.length2());
112                         assert(s != Scalar(0.0));
113                         return Scalar_traits<Scalar>::acos(dot(v) / s);
114                 }
115    
116                 Vector3<Scalar> absolute() const 
117                 {
118                         return Vector3<Scalar>(Scalar_traits<Scalar>::abs(this->m_co[0]), 
119                                                                    Scalar_traits<Scalar>::abs(this->m_co[1]), 
120                                                                    Scalar_traits<Scalar>::abs(this->m_co[2]));
121                 }
122
123                 Vector3<Scalar> cross(const Vector3<Scalar>& v) const
124                 {
125                         return Vector3<Scalar>(this->m_co[1] * v[2] - this->m_co[2] * v[1],
126                                                                    this->m_co[2] * v[0] - this->m_co[0] * v[2],
127                                                                    this->m_co[0] * v[1] - this->m_co[1] * v[0]);
128                 }
129                 
130                 Scalar triple(const Vector3<Scalar>& v1, const Vector3<Scalar>& v2) const
131                 {
132                         return this->m_co[0] * (v1[1] * v2[2] - v1[2] * v2[1]) + 
133                                    this->m_co[1] * (v1[2] * v2[0] - v1[0] * v2[2]) + 
134                                    this->m_co[2] * (v1[0] * v2[1] - v1[1] * v2[0]);
135                 }
136
137                 int minAxis() const
138                 {
139                         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);
140                 }
141
142                 int maxAxis() const 
143                 {
144                         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);
145                 }
146
147                 int furthestAxis() const
148                 {
149                         return absolute().minAxis();
150                 }
151
152                 int closestAxis() const 
153                 {
154                         return absolute().maxAxis();
155                 }
156
157                 Vector3<Scalar> lerp(const Vector3<Scalar>& v, const Scalar& t) const 
158                 {
159                         return Vector3<Scalar>(this->m_co[0] + (v[0] - this->m_co[0]) * t,
160                                                                    this->m_co[1] + (v[1] - this->m_co[1]) * t,
161                                                                    this->m_co[2] + (v[2] - this->m_co[2]) * t);
162                 }
163     
164                 static Vector3<Scalar> random() 
165                 {
166                         Scalar z = Scalar(2.0) * Scalar_traits<Scalar>::random() - Scalar(1.0);
167                         Scalar r = Scalar_traits<Scalar>::sqrt(Scalar(1.0) - z * z);
168                         Scalar t = Scalar_traits<Scalar>::TwoTimesPi() * Scalar_traits<Scalar>::random();
169                         return Vector3<Scalar>(r * Scalar_traits<Scalar>::cos(t), 
170                                                                    r * Scalar_traits<Scalar>::sin(t), 
171                                                                    z);
172                 }
173         };
174
175         template <typename Scalar>
176         inline Vector3<Scalar> 
177         operator+(const Vector3<Scalar>& v1, const Vector3<Scalar>& v2) 
178         {
179                 return Vector3<Scalar>(v1[0] + v2[0], v1[1] + v2[1], v1[2] + v2[2]);
180         }
181
182         template <typename Scalar>
183         inline Vector3<Scalar> 
184         operator-(const Vector3<Scalar>& v1, const Vector3<Scalar>& v2)
185         {
186                 return Vector3<Scalar>(v1[0] - v2[0], v1[1] - v2[1], v1[2] - v2[2]);
187         }
188         
189         template <typename Scalar>
190         inline Vector3<Scalar> 
191         operator-(const Vector3<Scalar>& v)
192         {
193                 return Vector3<Scalar>(-v[0], -v[1], -v[2]);
194         }
195         
196         template <typename Scalar>
197         inline Vector3<Scalar> 
198         operator*(const Vector3<Scalar>& v, const Scalar& s)
199         {
200                 return Vector3<Scalar>(v[0] * s, v[1] * s, v[2] * s);
201         }
202         
203         template <typename Scalar>
204         inline Vector3<Scalar> 
205         operator*(const Scalar& s, const Vector3<Scalar>& v)
206         { 
207                 return v * s; 
208         }
209         
210         template <typename Scalar>
211         inline Vector3<Scalar>
212         operator/(const Vector3<Scalar>& v, const Scalar& s)
213         {
214                 assert(s != Scalar(0.0));
215                 return v * (Scalar(1.0) / s);
216         }
217         
218         template <typename Scalar>
219         inline Scalar 
220         dot(const Vector3<Scalar>& v1, const Vector3<Scalar>& v2) 
221         { 
222                 return v1.dot(v2); 
223         }
224         
225         template <typename Scalar>
226         inline Scalar
227         length2(const Vector3<Scalar>& v) 
228         { 
229                 return v.length2(); 
230         }
231
232         template <typename Scalar>
233         inline Scalar
234         length(const Vector3<Scalar>& v) 
235         { 
236                 return v.length(); 
237         }
238
239         template <typename Scalar>
240         inline Scalar
241         distance2(const Vector3<Scalar>& v1, const Vector3<Scalar>& v2) 
242         { 
243                 return v1.distance2(v2); 
244         }
245
246         template <typename Scalar>
247         inline Scalar
248         distance(const Vector3<Scalar>& v1, const Vector3<Scalar>& v2) 
249         { 
250                 return v1.distance(v2); 
251         }
252
253         template <typename Scalar>
254         inline Scalar
255         angle(const Vector3<Scalar>& v1, const Vector3<Scalar>& v2) 
256         { 
257                 return v1.angle(v2); 
258         }
259
260         template <typename Scalar>
261         inline Vector3<Scalar> 
262         cross(const Vector3<Scalar>& v1, const Vector3<Scalar>& v2) 
263         { 
264                 return v1.cross(v2); 
265         }
266
267         template <typename Scalar>
268         inline Scalar
269         triple(const Vector3<Scalar>& v1, const Vector3<Scalar>& v2, const Vector3<Scalar>& v3)
270         {
271                 return v1.triple(v2, v3);
272         }
273
274         template <typename Scalar>
275         inline Vector3<Scalar> 
276         lerp(const Vector3<Scalar>& v1, const Vector3<Scalar>& v2, const Scalar& t)
277         {
278                 return v1.lerp(v2, t);
279         }
280
281 }
282
283 #endif