1/*
2 * Copyright 2008 Haiku Inc. All rights reserved.
3 * Distributed under the terms of the MIT License.
4 *
5 * Authors:
6 *		Alexandre Deckner
7 *
8 */
9
10/*
11 *
12 * This is a refactored and stripped down version of bullet-2.66 src\LinearMath\btVector3.h
13 * The dependancies on base class btQuadWord have been removed for simplification.
14 *
15 */
16
17/*
18Copyright (c) 2003-2006 Gino van den Bergen / Erwin Coumans  http://continuousphysics.com/Bullet/
19
20This software is provided 'as-is', without any express or implied warranty.
21In no event will the authors be held liable for any damages arising from the use of this software.
22Permission is granted to anyone to use this software for any purpose,
23including commercial applications, and to alter it and redistribute it freely,
24subject to the following restrictions:
25
261. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
272. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
283. This notice may not be removed or altered from any source distribution.
29*/
30
31
32#ifndef __VECTOR3_H__
33#define __VECTOR3_H__
34
35///Vector3 can be used to represent 3D points and vectors.
36
37class	Vector3 {
38protected:
39	float	m_x;
40	float	m_y;
41	float	m_z;
42
43public:
44	inline Vector3() {}
45
46
47	inline Vector3(const Vector3& v)
48	{
49		*((Vector3*)this) = v;
50	}
51
52
53	inline Vector3(const float& x, const float& y, const float& z)
54	{
55		m_x = x, m_y = y, m_z = z;
56	}
57
58
59	inline const float& x() const { return m_x; }
60
61
62	inline const float& y() const { return m_y; }
63
64
65	inline const float& z() const { return m_z; }
66
67
68	inline  void 	setValue(const float& x, const float& y, const float& z)
69	{
70		m_x=x;
71		m_y=y;
72		m_z=z;
73	}
74
75	inline Vector3& operator+=(const Vector3& v)
76	{
77		m_x += v.x(); m_y += v.y(); m_z += v.z();
78		return *this;
79	}
80
81
82	inline Vector3& operator-=(const Vector3& v)
83	{
84		m_x -= v.x(); m_y -= v.y(); m_z -= v.z();
85		return *this;
86	}
87
88
89	inline  Vector3& operator*=(const float& s)
90	{
91		m_x *= s; m_y *= s; m_z *= s;
92		return *this;
93	}
94
95
96	inline Vector3& operator/=(const float& s)
97	{
98		assert(s != 0.0f);
99		return *this *= 1.0f / s;
100	}
101
102
103	inline float dot(const Vector3& v) const
104	{
105		return m_x * v.x() + m_y * v.y() + m_z * v.z();
106	}
107
108
109	inline float length2() const
110	{
111		return dot(*this);
112	}
113
114
115	inline float length() const
116	{
117		return sqrt(length2());
118	}
119
120
121	inline float distance2(const Vector3& v) const;
122
123
124	inline float distance(const Vector3& v) const;
125
126
127	inline Vector3& normalize()
128	{
129		return *this /= length();
130	}
131
132
133	inline Vector3 normalized() const;
134
135
136	inline Vector3 rotate( const Vector3& wAxis, const float angle );
137
138
139	inline float angle(const Vector3& v) const
140	{
141		float s = sqrt(length2() * v.length2());
142		assert(s != 0.0f);
143		return acos(dot(v) / s);
144	}
145
146
147	inline Vector3 absolute() const
148	{
149		return Vector3(
150			fabs(m_x),
151			fabs(m_y),
152			fabs(m_z));
153	}
154
155
156	inline Vector3 cross(const Vector3& v) const
157	{
158		return Vector3(
159			m_y * v.z() - m_z * v.y(),
160			m_z * v.x() - m_x * v.z(),
161			m_x * v.y() - m_y * v.x());
162	}
163
164
165	inline float triple(const Vector3& v1, const Vector3& v2) const
166	{
167		return m_x * (v1.y() * v2.z() - v1.z() * v2.y()) +
168			m_y * (v1.z() * v2.x() - v1.x() * v2.z()) +
169			m_z * (v1.x() * v2.y() - v1.y() * v2.x());
170	}
171
172
173	inline int minAxis() const
174	{
175		return m_x < m_y ? (m_x < m_z ? 0 : 2) : (m_y < m_z ? 1 : 2);
176	}
177
178
179	inline int maxAxis() const
180	{
181		return m_x < m_y ? (m_y < m_z ? 2 : 1) : (m_x < m_z ? 2 : 0);
182	}
183
184
185	inline int furthestAxis() const
186	{
187		return absolute().minAxis();
188	}
189
190
191	inline int closestAxis() const
192	{
193		return absolute().maxAxis();
194	}
195
196
197	inline void setInterpolate3(const Vector3& v0, const Vector3& v1, float rt)
198	{
199		float s = 1.0f - rt;
200		m_x = s * v0.x() + rt * v1.x();
201		m_y = s * v0.y() + rt * v1.y();
202		m_z = s * v0.z() + rt * v1.z();
203		//don't do the unused w component
204		//		m_co[3] = s * v0[3] + rt * v1[3];
205	}
206
207
208	inline Vector3 lerp(const Vector3& v, const float& t) const
209	{
210		return Vector3(m_x + (v.x() - m_x) * t,
211			m_y + (v.y() - m_y) * t,
212			m_z + (v.z() - m_z) * t);
213	}
214
215
216	inline Vector3& operator*=(const Vector3& v)
217	{
218		m_x *= v.x(); m_y *= v.y(); m_z *= v.z();
219		return *this;
220	}
221
222};
223
224inline Vector3
225operator+(const Vector3& v1, const Vector3& v2)
226{
227	return Vector3(v1.x() + v2.x(), v1.y() + v2.y(), v1.z() + v2.z());
228}
229
230inline Vector3
231operator*(const Vector3& v1, const Vector3& v2)
232{
233	return Vector3(v1.x() * v2.x(), v1.y() * v2.y(), v1.z() * v2.z());
234}
235
236inline Vector3
237operator-(const Vector3& v1, const Vector3& v2)
238{
239	return Vector3(v1.x() - v2.x(), v1.y() - v2.y(), v1.z() - v2.z());
240}
241
242inline Vector3
243operator-(const Vector3& v)
244{
245	return Vector3(-v.x(), -v.y(), -v.z());
246}
247
248inline Vector3
249operator*(const Vector3& v, const float& s)
250{
251	return Vector3(v.x() * s, v.y() * s, v.z() * s);
252}
253
254inline Vector3
255operator*(const float& s, const Vector3& v)
256{
257	return v * s;
258}
259
260inline Vector3
261operator/(const Vector3& v, const float& s)
262{
263	assert(s != 0.0f);
264	return v * (1.0f / s);
265}
266
267inline Vector3
268operator/(const Vector3& v1, const Vector3& v2)
269{
270	return Vector3(v1.x() / v2.x(),v1.y() / v2.y(),v1.z() / v2.z());
271}
272
273inline float
274dot(const Vector3& v1, const Vector3& v2)
275{
276	return v1.dot(v2);
277}
278
279inline float
280distance2(const Vector3& v1, const Vector3& v2)
281{
282	return v1.distance2(v2);
283}
284
285
286inline float
287distance(const Vector3& v1, const Vector3& v2)
288{
289	return v1.distance(v2);
290}
291
292inline float
293angle(const Vector3& v1, const Vector3& v2)
294{
295	return v1.angle(v2);
296}
297
298inline Vector3
299cross(const Vector3& v1, const Vector3& v2)
300{
301	return v1.cross(v2);
302}
303
304inline float
305triple(const Vector3& v1, const Vector3& v2, const Vector3& v3)
306{
307	return v1.triple(v2, v3);
308}
309
310inline Vector3
311lerp(const Vector3& v1, const Vector3& v2, const float& t)
312{
313	return v1.lerp(v2, t);
314}
315
316
317inline bool operator==(const Vector3& p1, const Vector3& p2)
318{
319	return p1.x() == p2.x() && p1.y() == p2.y() && p1.z() == p2.z();
320}
321
322inline float Vector3::distance2(const Vector3& v) const
323{
324	return (v - *this).length2();
325}
326
327inline float Vector3::distance(const Vector3& v) const
328{
329	return (v - *this).length();
330}
331
332inline Vector3 Vector3::normalized() const
333{
334	return *this / length();
335}
336
337inline Vector3 Vector3::rotate( const Vector3& wAxis, const float angle )
338{
339	// wAxis must be a unit lenght vector
340
341	Vector3 o = wAxis * wAxis.dot( *this );
342	Vector3 x = *this - o;
343	Vector3 y;
344
345	y = wAxis.cross( *this );
346
347	return ( o + x * cos( angle ) + y * sin( angle ) );
348}
349
350#endif //__VECTOR3_H__
351