2 Copyright (c) 2003-2006 Gino van den Bergen / Erwin Coumans http://continuousphysics.com/Bullet/
4 This software is provided 'as-is', without any express or implied warranty.
5 In no event will the authors be held liable for any damages arising from the use of this software.
6 Permission is granted to anyone to use this software for any purpose,
7 including commercial applications, and to alter it and redistribute it freely,
8 subject to the following restrictions:
10 1. 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.
11 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
12 3. This notice may not be removed or altered from any source distribution.
17 #ifndef SIMD__VECTOR3_H
18 #define SIMD__VECTOR3_H
20 #include "SimdQuadWord.h"
23 ///SimdVector3 is 16byte aligned, and has an extra unused component m_w
24 ///this extra component can be used by derived classes (Quaternion?) or by user
25 class SimdVector3 : public SimdQuadWord {
29 SIMD_FORCE_INLINE SimdVector3() {}
33 SIMD_FORCE_INLINE SimdVector3(const SimdScalar& x, const SimdScalar& y, const SimdScalar& z)
34 :SimdQuadWord(x,y,z,0.f)
38 // SIMD_FORCE_INLINE SimdVector3(const SimdScalar& x, const SimdScalar& y, const SimdScalar& z,const SimdScalar& w)
39 // : SimdQuadWord(x,y,z,w)
45 SIMD_FORCE_INLINE SimdVector3& operator+=(const SimdVector3& v)
47 m_x += v.x(); m_y += v.y(); m_z += v.z();
53 SIMD_FORCE_INLINE SimdVector3& operator-=(const SimdVector3& v)
55 m_x -= v.x(); m_y -= v.y(); m_z -= v.z();
59 SIMD_FORCE_INLINE SimdVector3& operator*=(const SimdScalar& s)
61 m_x *= s; m_y *= s; m_z *= s;
65 SIMD_FORCE_INLINE SimdVector3& operator/=(const SimdScalar& s)
67 assert(s != SimdScalar(0.0));
68 return *this *= SimdScalar(1.0) / s;
71 SIMD_FORCE_INLINE SimdScalar dot(const SimdVector3& v) const
73 return m_x * v.x() + m_y * v.y() + m_z * v.z();
76 SIMD_FORCE_INLINE SimdScalar length2() const
81 SIMD_FORCE_INLINE SimdScalar length() const
83 return SimdSqrt(length2());
86 SIMD_FORCE_INLINE SimdScalar distance2(const SimdVector3& v) const;
88 SIMD_FORCE_INLINE SimdScalar distance(const SimdVector3& v) const;
90 SIMD_FORCE_INLINE SimdVector3& normalize()
92 return *this /= length();
95 SIMD_FORCE_INLINE SimdVector3 normalized() const;
97 SIMD_FORCE_INLINE SimdVector3 rotate( const SimdVector3& wAxis, const SimdScalar angle );
99 SIMD_FORCE_INLINE SimdScalar angle(const SimdVector3& v) const
101 SimdScalar s = SimdSqrt(length2() * v.length2());
102 assert(s != SimdScalar(0.0));
103 return SimdAcos(dot(v) / s);
106 SIMD_FORCE_INLINE SimdVector3 absolute() const
114 SIMD_FORCE_INLINE SimdVector3 cross(const SimdVector3& v) const
117 m_y * v.z() - m_z * v.y(),
118 m_z * v.x() - m_x * v.z(),
119 m_x * v.y() - m_y * v.x());
122 SIMD_FORCE_INLINE SimdScalar triple(const SimdVector3& v1, const SimdVector3& v2) const
124 return m_x * (v1.y() * v2.z() - v1.z() * v2.y()) +
125 m_y * (v1.z() * v2.x() - v1.x() * v2.z()) +
126 m_z * (v1.x() * v2.y() - v1.y() * v2.x());
129 SIMD_FORCE_INLINE int minAxis() const
131 return m_x < m_y ? (m_x < m_z ? 0 : 2) : (m_y < m_z ? 1 : 2);
134 SIMD_FORCE_INLINE int maxAxis() const
136 return m_x < m_y ? (m_y < m_z ? 2 : 1) : (m_x < m_z ? 2 : 0);
139 SIMD_FORCE_INLINE int furthestAxis() const
141 return absolute().minAxis();
144 SIMD_FORCE_INLINE int closestAxis() const
146 return absolute().maxAxis();
149 SIMD_FORCE_INLINE void setInterpolate3(const SimdVector3& v0, const SimdVector3& v1, SimdScalar rt)
151 SimdScalar s = 1.0f - rt;
152 m_x = s * v0[0] + rt * v1.x();
153 m_y = s * v0[1] + rt * v1.y();
154 m_z = s * v0[2] + rt * v1.z();
155 //don't do the unused w component
156 // m_co[3] = s * v0[3] + rt * v1[3];
159 SIMD_FORCE_INLINE SimdVector3 lerp(const SimdVector3& v, const SimdScalar& t) const
161 return SimdVector3(m_x + (v.x() - m_x) * t,
162 m_y + (v.y() - m_y) * t,
163 m_z + (v.z() - m_z) * t);
167 SIMD_FORCE_INLINE SimdVector3& operator*=(const SimdVector3& v)
169 m_x *= v.x(); m_y *= v.y(); m_z *= v.z();
177 SIMD_FORCE_INLINE SimdVector3
178 operator+(const SimdVector3& v1, const SimdVector3& v2)
180 return SimdVector3(v1.x() + v2.x(), v1.y() + v2.y(), v1.z() + v2.z());
183 SIMD_FORCE_INLINE SimdVector3
184 operator*(const SimdVector3& v1, const SimdVector3& v2)
186 return SimdVector3(v1.x() * v2.x(), v1.y() * v2.y(), v1.z() *+ v2.z());
189 SIMD_FORCE_INLINE SimdVector3
190 operator-(const SimdVector3& v1, const SimdVector3& v2)
192 return SimdVector3(v1.x() - v2.x(), v1.y() - v2.y(), v1.z() - v2.z());
195 SIMD_FORCE_INLINE SimdVector3
196 operator-(const SimdVector3& v)
198 return SimdVector3(-v.x(), -v.y(), -v.z());
201 SIMD_FORCE_INLINE SimdVector3
202 operator*(const SimdVector3& v, const SimdScalar& s)
204 return SimdVector3(v.x() * s, v.y() * s, v.z() * s);
207 SIMD_FORCE_INLINE SimdVector3
208 operator*(const SimdScalar& s, const SimdVector3& v)
213 SIMD_FORCE_INLINE SimdVector3
214 operator/(const SimdVector3& v, const SimdScalar& s)
216 assert(s != SimdScalar(0.0));
217 return v * (SimdScalar(1.0) / s);
220 SIMD_FORCE_INLINE SimdVector3
221 operator/(const SimdVector3& v1, const SimdVector3& v2)
223 return SimdVector3(v1.x() / v2.x(),v1.y() / v2.y(),v1.z() / v2.z());
226 SIMD_FORCE_INLINE SimdScalar
227 dot(const SimdVector3& v1, const SimdVector3& v2)
234 SIMD_FORCE_INLINE SimdScalar
235 distance2(const SimdVector3& v1, const SimdVector3& v2)
237 return v1.distance2(v2);
241 SIMD_FORCE_INLINE SimdScalar
242 distance(const SimdVector3& v1, const SimdVector3& v2)
244 return v1.distance(v2);
247 SIMD_FORCE_INLINE SimdScalar
248 angle(const SimdVector3& v1, const SimdVector3& v2)
253 SIMD_FORCE_INLINE SimdVector3
254 cross(const SimdVector3& v1, const SimdVector3& v2)
259 SIMD_FORCE_INLINE SimdScalar
260 triple(const SimdVector3& v1, const SimdVector3& v2, const SimdVector3& v3)
262 return v1.triple(v2, v3);
265 SIMD_FORCE_INLINE SimdVector3
266 lerp(const SimdVector3& v1, const SimdVector3& v2, const SimdScalar& t)
268 return v1.lerp(v2, t);
272 SIMD_FORCE_INLINE bool operator==(const SimdVector3& p1, const SimdVector3& p2)
274 return p1[0] == p2[0] && p1[1] == p2[1] && p1[2] == p2[2];
277 SIMD_FORCE_INLINE SimdScalar SimdVector3::distance2(const SimdVector3& v) const
279 return (v - *this).length2();
282 SIMD_FORCE_INLINE SimdScalar SimdVector3::distance(const SimdVector3& v) const
284 return (v - *this).length();
287 SIMD_FORCE_INLINE SimdVector3 SimdVector3::normalized() const
289 return *this / length();
292 SIMD_FORCE_INLINE SimdVector3 SimdVector3::rotate( const SimdVector3& wAxis, const SimdScalar angle )
294 // wAxis must be a unit lenght vector
296 SimdVector3 o = wAxis * wAxis.dot( *this );
297 SimdVector3 x = *this - o;
300 y = wAxis.cross( *this );
302 return ( o + x * SimdCos( angle ) + y * SimdSin( angle ) );
305 class SimdVector4 : public SimdVector3
309 SIMD_FORCE_INLINE SimdVector4() {}
312 SIMD_FORCE_INLINE SimdVector4(const SimdScalar& x, const SimdScalar& y, const SimdScalar& z,const SimdScalar& w)
319 SIMD_FORCE_INLINE SimdVector4 absolute4() const
325 SimdFabs(m_unusedW));
330 float getW() const { return m_unusedW;}
333 SIMD_FORCE_INLINE int maxAxis4() const
336 float maxVal = -1e30f;
352 if (m_unusedW > maxVal)
366 SIMD_FORCE_INLINE int minAxis4() const
369 float minVal = 1e30f;
385 if (m_unusedW < minVal)
396 SIMD_FORCE_INLINE int closestAxis4() const
398 return absolute4().maxAxis4();
403 #endif //SIMD__VECTOR3_H