1 /*
2 Copyright (c) 2003-2006 Gino van den Bergen / Erwin Coumans  http://continuousphysics.com/Bullet/
3 
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:
9 
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.
13 */
14 
15 
16 #ifndef BT_SIMD_QUADWORD_H
17 #define BT_SIMD_QUADWORD_H
18 
19 #include "btScalar.h"
20 #include "btMinMax.h"
21 
22 
23 
24 
25 
26 #if defined (__CELLOS_LV2) && defined (__SPU__)
27 #include <altivec.h>
28 #endif
29 
30 /**@brief The btQuadWord class is base class for btVector3 and btQuaternion.
31  * Some issues under PS3 Linux with IBM 2.1 SDK, gcc compiler prevent from using aligned quadword.
32  */
33 #ifndef USE_LIBSPE2
ATTRIBUTE_ALIGNED16(class)34 ATTRIBUTE_ALIGNED16(class) btQuadWord
35 #else
36 class btQuadWord
37 #endif
38 {
39 protected:
40 
41 #if defined (__SPU__) && defined (__CELLOS_LV2__)
42 	union {
43 		vec_float4 mVec128;
44 		btScalar	m_floats[4];
45 	};
46 public:
47 	vec_float4	get128() const
48 	{
49 		return mVec128;
50 	}
51 protected:
52 #else //__CELLOS_LV2__ __SPU__
53 
54 #if defined(BT_USE_SSE) || defined(BT_USE_NEON)
55 	union {
56 		btSimdFloat4 mVec128;
57 		btScalar	m_floats[4];
58 	};
59 public:
60 	SIMD_FORCE_INLINE	btSimdFloat4	get128() const
61 	{
62 		return mVec128;
63 	}
64 	SIMD_FORCE_INLINE	void	set128(btSimdFloat4 v128)
65 	{
66 		mVec128 = v128;
67 	}
68 #else
69 	btScalar	m_floats[4];
70 #endif // BT_USE_SSE
71 
72 #endif //__CELLOS_LV2__ __SPU__
73 
74 	public:
75 
76 #if (defined(BT_USE_SSE_IN_API) && defined(BT_USE_SSE)) || defined(BT_USE_NEON)
77 
78 	// Set Vector
79 	SIMD_FORCE_INLINE btQuadWord(const btSimdFloat4 vec)
80 	{
81 		mVec128 = vec;
82 	}
83 
84 	// Copy constructor
85 	SIMD_FORCE_INLINE btQuadWord(const btQuadWord& rhs)
86 	{
87 		mVec128 = rhs.mVec128;
88 	}
89 
90 	// Assignment Operator
91 	SIMD_FORCE_INLINE btQuadWord&
92 	operator=(const btQuadWord& v)
93 	{
94 		mVec128 = v.mVec128;
95 
96 		return *this;
97 	}
98 
99 #endif
100 
101   /**@brief Return the x value */
102 		SIMD_FORCE_INLINE const btScalar& getX() const { return m_floats[0]; }
103   /**@brief Return the y value */
104 		SIMD_FORCE_INLINE const btScalar& getY() const { return m_floats[1]; }
105   /**@brief Return the z value */
106 		SIMD_FORCE_INLINE const btScalar& getZ() const { return m_floats[2]; }
107   /**@brief Set the x value */
108 		SIMD_FORCE_INLINE void	setX(btScalar _x) { m_floats[0] = _x;};
109   /**@brief Set the y value */
110 		SIMD_FORCE_INLINE void	setY(btScalar _y) { m_floats[1] = _y;};
111   /**@brief Set the z value */
112 		SIMD_FORCE_INLINE void	setZ(btScalar _z) { m_floats[2] = _z;};
113   /**@brief Set the w value */
114 		SIMD_FORCE_INLINE void	setW(btScalar _w) { m_floats[3] = _w;};
115   /**@brief Return the x value */
116 		SIMD_FORCE_INLINE const btScalar& x() const { return m_floats[0]; }
117   /**@brief Return the y value */
118 		SIMD_FORCE_INLINE const btScalar& y() const { return m_floats[1]; }
119   /**@brief Return the z value */
120 		SIMD_FORCE_INLINE const btScalar& z() const { return m_floats[2]; }
121   /**@brief Return the w value */
122 		SIMD_FORCE_INLINE const btScalar& w() const { return m_floats[3]; }
123 
124 	//SIMD_FORCE_INLINE btScalar&       operator[](int i)       { return (&m_floats[0])[i];	}
125 	//SIMD_FORCE_INLINE const btScalar& operator[](int i) const { return (&m_floats[0])[i]; }
126 	///operator btScalar*() replaces operator[], using implicit conversion. We added operator != and operator == to avoid pointer comparisons.
127 	SIMD_FORCE_INLINE	operator       btScalar *()       { return &m_floats[0]; }
128 	SIMD_FORCE_INLINE	operator const btScalar *() const { return &m_floats[0]; }
129 
130 	SIMD_FORCE_INLINE	bool	operator==(const btQuadWord& other) const
131 	{
132 #ifdef BT_USE_SSE
133         return (0xf == _mm_movemask_ps((__m128)_mm_cmpeq_ps(mVec128, other.mVec128)));
134 #else
135 		return ((m_floats[3]==other.m_floats[3]) &&
136                 (m_floats[2]==other.m_floats[2]) &&
137                 (m_floats[1]==other.m_floats[1]) &&
138                 (m_floats[0]==other.m_floats[0]));
139 #endif
140 	}
141 
142 	SIMD_FORCE_INLINE	bool	operator!=(const btQuadWord& other) const
143 	{
144 		return !(*this == other);
145 	}
146 
147   /**@brief Set x,y,z and zero w
148    * @param x Value of x
149    * @param y Value of y
150    * @param z Value of z
151    */
152 		SIMD_FORCE_INLINE void 	setValue(const btScalar& _x, const btScalar& _y, const btScalar& _z)
153 		{
154 			m_floats[0]=_x;
155 			m_floats[1]=_y;
156 			m_floats[2]=_z;
157 			m_floats[3] = 0.f;
158 		}
159 
160 /*		void getValue(btScalar *m) const
161 		{
162 			m[0] = m_floats[0];
163 			m[1] = m_floats[1];
164 			m[2] = m_floats[2];
165 		}
166 */
167 /**@brief Set the values
168    * @param x Value of x
169    * @param y Value of y
170    * @param z Value of z
171    * @param w Value of w
172    */
173 		SIMD_FORCE_INLINE void	setValue(const btScalar& _x, const btScalar& _y, const btScalar& _z,const btScalar& _w)
174 		{
175 			m_floats[0]=_x;
176 			m_floats[1]=_y;
177 			m_floats[2]=_z;
178 			m_floats[3]=_w;
179 		}
180   /**@brief No initialization constructor */
181 		SIMD_FORCE_INLINE btQuadWord()
182 		//	:m_floats[0](btScalar(0.)),m_floats[1](btScalar(0.)),m_floats[2](btScalar(0.)),m_floats[3](btScalar(0.))
183 		{
184 		}
185 
186   /**@brief Three argument constructor (zeros w)
187    * @param x Value of x
188    * @param y Value of y
189    * @param z Value of z
190    */
191 		SIMD_FORCE_INLINE btQuadWord(const btScalar& _x, const btScalar& _y, const btScalar& _z)
192 		{
193 			m_floats[0] = _x, m_floats[1] = _y, m_floats[2] = _z, m_floats[3] = 0.0f;
194 		}
195 
196 /**@brief Initializing constructor
197    * @param x Value of x
198    * @param y Value of y
199    * @param z Value of z
200    * @param w Value of w
201    */
202 		SIMD_FORCE_INLINE btQuadWord(const btScalar& _x, const btScalar& _y, const btScalar& _z,const btScalar& _w)
203 		{
204 			m_floats[0] = _x, m_floats[1] = _y, m_floats[2] = _z, m_floats[3] = _w;
205 		}
206 
207   /**@brief Set each element to the max of the current values and the values of another btQuadWord
208    * @param other The other btQuadWord to compare with
209    */
210 		SIMD_FORCE_INLINE void	setMax(const btQuadWord& other)
211 		{
212         #ifdef BT_USE_SSE
213             mVec128 = _mm_max_ps(mVec128, other.mVec128);
214         #elif defined(BT_USE_NEON)
215             mVec128 = vmaxq_f32(mVec128, other.mVec128);
216         #else
217         	btSetMax(m_floats[0], other.m_floats[0]);
218 			btSetMax(m_floats[1], other.m_floats[1]);
219 			btSetMax(m_floats[2], other.m_floats[2]);
220 			btSetMax(m_floats[3], other.m_floats[3]);
221 		#endif
222         }
223   /**@brief Set each element to the min of the current values and the values of another btQuadWord
224    * @param other The other btQuadWord to compare with
225    */
226 		SIMD_FORCE_INLINE void	setMin(const btQuadWord& other)
227 		{
228         #ifdef BT_USE_SSE
229             mVec128 = _mm_min_ps(mVec128, other.mVec128);
230         #elif defined(BT_USE_NEON)
231             mVec128 = vminq_f32(mVec128, other.mVec128);
232         #else
233         	btSetMin(m_floats[0], other.m_floats[0]);
234 			btSetMin(m_floats[1], other.m_floats[1]);
235 			btSetMin(m_floats[2], other.m_floats[2]);
236 			btSetMin(m_floats[3], other.m_floats[3]);
237 		#endif
238         }
239 
240 
241 
242 };
243 
244 #endif //BT_SIMD_QUADWORD_H
245