Home | History | Annotate | Download | only in ConstraintSolver
      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 {
     36 	SIMD_FORCE_INLINE	btSimdScalar()
     37 	{
     38 
     39 	}
     40 
     41 	SIMD_FORCE_INLINE	btSimdScalar(float	fl)
     42 	:m_vec128 (_mm_set1_ps(fl))
     43 	{
     44 	}
     45 
     46 	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 	};
     57 	SIMD_FORCE_INLINE	__m128	get128()
     58 	{
     59 		return m_vec128;
     60 	}
     61 
     62 	SIMD_FORCE_INLINE	const __m128	get128() const
     63 	{
     64 		return m_vec128;
     65 	}
     66 
     67 	SIMD_FORCE_INLINE	void	set128(__m128 v128)
     68 	{
     69 		m_vec128 = v128;
     70 	}
     71 
     72 	SIMD_FORCE_INLINE	operator       __m128()
     73 	{
     74 		return m_vec128;
     75 	}
     76 	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.
    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