• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2 Bullet Continuous Collision Detection and Physics Library
3 Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/
4 
5 This software is provided 'as-is', without any express or implied warranty.
6 In no event will the authors be held liable for any damages arising from the use of this software.
7 Permission is granted to anyone to use this software for any purpose,
8 including commercial applications, and to alter it and redistribute it freely,
9 subject to the following restrictions:
10 
11 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.
12 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
13 3. This notice may not be removed or altered from any source distribution.
14 */
15 
16 #ifndef BT_SOLVER_BODY_H
17 #define BT_SOLVER_BODY_H
18 
19 class	btRigidBody;
20 #include "LinearMath/btVector3.h"
21 #include "LinearMath/btMatrix3x3.h"
22 
23 #include "LinearMath/btAlignedAllocator.h"
24 #include "LinearMath/btTransformUtil.h"
25 
26 ///Until we get other contributions, only use SIMD on Windows, when using Visual Studio 2008 or later, and not double precision
27 #ifdef BT_USE_SSE
28 #define USE_SIMD 1
29 #endif //
30 
31 
32 #ifdef USE_SIMD
33 
34 struct	btSimdScalar
35 {
btSimdScalarbtSimdScalar36 	SIMD_FORCE_INLINE	btSimdScalar()
37 	{
38 
39 	}
40 
btSimdScalarbtSimdScalar41 	SIMD_FORCE_INLINE	btSimdScalar(float	fl)
42 	:m_vec128 (_mm_set1_ps(fl))
43 	{
44 	}
45 
btSimdScalarbtSimdScalar46 	SIMD_FORCE_INLINE	btSimdScalar(__m128 v128)
47 		:m_vec128(v128)
48 	{
49 	}
50 	union
51 	{
52 		__m128		m_vec128;
53 		float		m_floats[4];
54 		int			m_ints[4];
55 		btScalar	m_unusedPadding;
56 	};
get128btSimdScalar57 	SIMD_FORCE_INLINE	__m128	get128()
58 	{
59 		return m_vec128;
60 	}
61 
get128btSimdScalar62 	SIMD_FORCE_INLINE	const __m128	get128() const
63 	{
64 		return m_vec128;
65 	}
66 
set128btSimdScalar67 	SIMD_FORCE_INLINE	void	set128(__m128 v128)
68 	{
69 		m_vec128 = v128;
70 	}
71 
__m128btSimdScalar72 	SIMD_FORCE_INLINE	operator       __m128()
73 	{
74 		return m_vec128;
75 	}
__m128btSimdScalar76 	SIMD_FORCE_INLINE	operator const __m128() const
77 	{
78 		return m_vec128;
79 	}
80 
81 	SIMD_FORCE_INLINE	operator float() const
82 	{
83 		return m_floats[0];
84 	}
85 
86 };
87 
88 ///@brief Return the elementwise product of two btSimdScalar
89 SIMD_FORCE_INLINE btSimdScalar
90 operator*(const btSimdScalar& v1, const btSimdScalar& v2)
91 {
92 	return btSimdScalar(_mm_mul_ps(v1.get128(),v2.get128()));
93 }
94 
95 ///@brief Return the elementwise product of two btSimdScalar
96 SIMD_FORCE_INLINE btSimdScalar
97 operator+(const btSimdScalar& v1, const btSimdScalar& v2)
98 {
99 	return btSimdScalar(_mm_add_ps(v1.get128(),v2.get128()));
100 }
101 
102 
103 #else
104 #define btSimdScalar btScalar
105 #endif
106 
107 ///The btSolverBody is an internal datastructure for the constraint solver. Only necessary data is packed to increase cache coherence/performance.
ATTRIBUTE_ALIGNED16(struct)108 ATTRIBUTE_ALIGNED16 (struct)	btSolverBody
109 {
110 	BT_DECLARE_ALIGNED_ALLOCATOR();
111 	btTransform		m_worldTransform;
112 	btVector3		m_deltaLinearVelocity;
113 	btVector3		m_deltaAngularVelocity;
114 	btVector3		m_angularFactor;
115 	btVector3		m_linearFactor;
116 	btVector3		m_invMass;
117 	btVector3		m_pushVelocity;
118 	btVector3		m_turnVelocity;
119 	btVector3		m_linearVelocity;
120 	btVector3		m_angularVelocity;
121 	btVector3		m_externalForceImpulse;
122 	btVector3		m_externalTorqueImpulse;
123 
124 	btRigidBody*	m_originalBody;
125 	void	setWorldTransform(const btTransform& worldTransform)
126 	{
127 		m_worldTransform = worldTransform;
128 	}
129 
130 	const btTransform& getWorldTransform() const
131 	{
132 		return m_worldTransform;
133 	}
134 
135 
136 
137 	SIMD_FORCE_INLINE void	getVelocityInLocalPointNoDelta(const btVector3& rel_pos, btVector3& velocity ) const
138 	{
139 		if (m_originalBody)
140 			velocity = m_linearVelocity + m_externalForceImpulse + (m_angularVelocity+m_externalTorqueImpulse).cross(rel_pos);
141 		else
142 			velocity.setValue(0,0,0);
143 	}
144 
145 
146 	SIMD_FORCE_INLINE void	getVelocityInLocalPointObsolete(const btVector3& rel_pos, btVector3& velocity ) const
147 	{
148 		if (m_originalBody)
149 			velocity = m_linearVelocity+m_deltaLinearVelocity + (m_angularVelocity+m_deltaAngularVelocity).cross(rel_pos);
150 		else
151 			velocity.setValue(0,0,0);
152 	}
153 
154 	SIMD_FORCE_INLINE void	getAngularVelocity(btVector3& angVel) const
155 	{
156 		if (m_originalBody)
157 			angVel =m_angularVelocity+m_deltaAngularVelocity;
158 		else
159 			angVel.setValue(0,0,0);
160 	}
161 
162 
163 	//Optimization for the iterative solver: avoid calculating constant terms involving inertia, normal, relative position
164 	SIMD_FORCE_INLINE void applyImpulse(const btVector3& linearComponent, const btVector3& angularComponent,const btScalar impulseMagnitude)
165 	{
166 		if (m_originalBody)
167 		{
168 			m_deltaLinearVelocity += linearComponent*impulseMagnitude*m_linearFactor;
169 			m_deltaAngularVelocity += angularComponent*(impulseMagnitude*m_angularFactor);
170 		}
171 	}
172 
173 	SIMD_FORCE_INLINE void internalApplyPushImpulse(const btVector3& linearComponent, const btVector3& angularComponent,btScalar impulseMagnitude)
174 	{
175 		if (m_originalBody)
176 		{
177 			m_pushVelocity += linearComponent*impulseMagnitude*m_linearFactor;
178 			m_turnVelocity += angularComponent*(impulseMagnitude*m_angularFactor);
179 		}
180 	}
181 
182 
183 
184 	const btVector3& getDeltaLinearVelocity() const
185 	{
186 		return m_deltaLinearVelocity;
187 	}
188 
189 	const btVector3& getDeltaAngularVelocity() const
190 	{
191 		return m_deltaAngularVelocity;
192 	}
193 
194 	const btVector3& getPushVelocity() const
195 	{
196 		return m_pushVelocity;
197 	}
198 
199 	const btVector3& getTurnVelocity() const
200 	{
201 		return m_turnVelocity;
202 	}
203 
204 
205 	////////////////////////////////////////////////
206 	///some internal methods, don't use them
207 
208 	btVector3& internalGetDeltaLinearVelocity()
209 	{
210 		return m_deltaLinearVelocity;
211 	}
212 
213 	btVector3& internalGetDeltaAngularVelocity()
214 	{
215 		return m_deltaAngularVelocity;
216 	}
217 
218 	const btVector3& internalGetAngularFactor() const
219 	{
220 		return m_angularFactor;
221 	}
222 
223 	const btVector3& internalGetInvMass() const
224 	{
225 		return m_invMass;
226 	}
227 
228 	void internalSetInvMass(const btVector3& invMass)
229 	{
230 		m_invMass = invMass;
231 	}
232 
233 	btVector3& internalGetPushVelocity()
234 	{
235 		return m_pushVelocity;
236 	}
237 
238 	btVector3& internalGetTurnVelocity()
239 	{
240 		return m_turnVelocity;
241 	}
242 
243 	SIMD_FORCE_INLINE void	internalGetVelocityInLocalPointObsolete(const btVector3& rel_pos, btVector3& velocity ) const
244 	{
245 		velocity = m_linearVelocity+m_deltaLinearVelocity + (m_angularVelocity+m_deltaAngularVelocity).cross(rel_pos);
246 	}
247 
248 	SIMD_FORCE_INLINE void	internalGetAngularVelocity(btVector3& angVel) const
249 	{
250 		angVel = m_angularVelocity+m_deltaAngularVelocity;
251 	}
252 
253 
254 	//Optimization for the iterative solver: avoid calculating constant terms involving inertia, normal, relative position
255 	SIMD_FORCE_INLINE void internalApplyImpulse(const btVector3& linearComponent, const btVector3& angularComponent,const btScalar impulseMagnitude)
256 	{
257 		if (m_originalBody)
258 		{
259 			m_deltaLinearVelocity += linearComponent*impulseMagnitude*m_linearFactor;
260 			m_deltaAngularVelocity += angularComponent*(impulseMagnitude*m_angularFactor);
261 		}
262 	}
263 
264 
265 
266 
267 	void	writebackVelocity()
268 	{
269 		if (m_originalBody)
270 		{
271 			m_linearVelocity +=m_deltaLinearVelocity;
272 			m_angularVelocity += m_deltaAngularVelocity;
273 
274 			//m_originalBody->setCompanionId(-1);
275 		}
276 	}
277 
278 
279 	void	writebackVelocityAndTransform(btScalar timeStep, btScalar splitImpulseTurnErp)
280 	{
281         (void) timeStep;
282 		if (m_originalBody)
283 		{
284 			m_linearVelocity += m_deltaLinearVelocity;
285 			m_angularVelocity += m_deltaAngularVelocity;
286 
287 			//correct the position/orientation based on push/turn recovery
288 			btTransform newTransform;
289 			if (m_pushVelocity[0]!=0.f || m_pushVelocity[1]!=0 || m_pushVelocity[2]!=0 || m_turnVelocity[0]!=0.f || m_turnVelocity[1]!=0 || m_turnVelocity[2]!=0)
290 			{
291 			//	btQuaternion orn = m_worldTransform.getRotation();
292 				btTransformUtil::integrateTransform(m_worldTransform,m_pushVelocity,m_turnVelocity*splitImpulseTurnErp,timeStep,newTransform);
293 				m_worldTransform = newTransform;
294 			}
295 			//m_worldTransform.setRotation(orn);
296 			//m_originalBody->setCompanionId(-1);
297 		}
298 	}
299 
300 
301 
302 };
303 
304 #endif //BT_SOLVER_BODY_H
305 
306 
307