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