2 Bullet Continuous Collision Detection and Physics Library
3 Copyright (c) 2003-2006 Erwin Coumans https://bulletphysics.org
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:
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.
16 #ifndef BT_SOLVER_BODY_H
17 #define BT_SOLVER_BODY_H
20 #include "LinearMath/btVector3.h"
21 #include "LinearMath/btMatrix3x3.h"
23 #include "LinearMath/btAlignedAllocator.h"
24 #include "LinearMath/btTransformUtil.h"
26 ///Until we get other contributions, only use SIMD on Windows, when using Visual Studio 2008 or later, and not double precision
35 SIMD_FORCE_INLINE btSimdScalar()
39 SIMD_FORCE_INLINE btSimdScalar(float fl)
40 : m_vec128(_mm_set1_ps(fl))
44 SIMD_FORCE_INLINE btSimdScalar(__m128 v128)
52 btScalar m_unusedPadding;
54 SIMD_FORCE_INLINE __m128 get128()
59 SIMD_FORCE_INLINE const __m128 get128() const
64 SIMD_FORCE_INLINE void set128(__m128 v128)
69 SIMD_FORCE_INLINE operator __m128()
73 SIMD_FORCE_INLINE operator const __m128() const
78 SIMD_FORCE_INLINE operator float() const
84 ///@brief Return the elementwise product of two btSimdScalar
85 SIMD_FORCE_INLINE btSimdScalar
86 operator*(const btSimdScalar& v1, const btSimdScalar& v2)
88 return btSimdScalar(_mm_mul_ps(v1.get128(), v2.get128()));
91 ///@brief Return the elementwise product of two btSimdScalar
92 SIMD_FORCE_INLINE btSimdScalar
93 operator+(const btSimdScalar& v1, const btSimdScalar& v2)
95 return btSimdScalar(_mm_add_ps(v1.get128(), v2.get128()));
99 #define btSimdScalar btScalar
102 ///The btSolverBody is an internal datastructure for the constraint solver. Only necessary data is packed to increase cache coherence/performance.
103 ATTRIBUTE_ALIGNED16(struct)
106 BT_DECLARE_ALIGNED_ALLOCATOR();
107 btTransform m_worldTransform;
108 btVector3 m_deltaLinearVelocity;
109 btVector3 m_deltaAngularVelocity;
110 btVector3 m_angularFactor;
111 btVector3 m_linearFactor;
113 btVector3 m_pushVelocity;
114 btVector3 m_turnVelocity;
115 btVector3 m_linearVelocity;
116 btVector3 m_angularVelocity;
117 btVector3 m_externalForceImpulse;
118 btVector3 m_externalTorqueImpulse;
120 btRigidBody* m_originalBody;
121 void setWorldTransform(const btTransform& worldTransform)
123 m_worldTransform = worldTransform;
126 const btTransform& getWorldTransform() const
128 return m_worldTransform;
131 SIMD_FORCE_INLINE void getVelocityInLocalPointNoDelta(const btVector3& rel_pos, btVector3& velocity) const
134 velocity = m_linearVelocity + m_externalForceImpulse + (m_angularVelocity + m_externalTorqueImpulse).cross(rel_pos);
136 velocity.setValue(0, 0, 0);
139 SIMD_FORCE_INLINE void getVelocityInLocalPointObsolete(const btVector3& rel_pos, btVector3& velocity) const
142 velocity = m_linearVelocity + m_deltaLinearVelocity + (m_angularVelocity + m_deltaAngularVelocity).cross(rel_pos);
144 velocity.setValue(0, 0, 0);
147 SIMD_FORCE_INLINE void getAngularVelocity(btVector3 & angVel) const
150 angVel = m_angularVelocity + m_deltaAngularVelocity;
152 angVel.setValue(0, 0, 0);
155 //Optimization for the iterative solver: avoid calculating constant terms involving inertia, normal, relative position
156 SIMD_FORCE_INLINE void applyImpulse(const btVector3& linearComponent, const btVector3& angularComponent, const btScalar impulseMagnitude)
160 m_deltaLinearVelocity += linearComponent * impulseMagnitude * m_linearFactor;
161 m_deltaAngularVelocity += angularComponent * (impulseMagnitude * m_angularFactor);
165 SIMD_FORCE_INLINE void internalApplyPushImpulse(const btVector3& linearComponent, const btVector3& angularComponent, btScalar impulseMagnitude)
169 m_pushVelocity += linearComponent * impulseMagnitude * m_linearFactor;
170 m_turnVelocity += angularComponent * (impulseMagnitude * m_angularFactor);
174 const btVector3& getDeltaLinearVelocity() const
176 return m_deltaLinearVelocity;
179 const btVector3& getDeltaAngularVelocity() const
181 return m_deltaAngularVelocity;
184 const btVector3& getPushVelocity() const
186 return m_pushVelocity;
189 const btVector3& getTurnVelocity() const
191 return m_turnVelocity;
194 ////////////////////////////////////////////////
195 ///some internal methods, don't use them
197 btVector3& internalGetDeltaLinearVelocity()
199 return m_deltaLinearVelocity;
202 btVector3& internalGetDeltaAngularVelocity()
204 return m_deltaAngularVelocity;
207 const btVector3& internalGetAngularFactor() const
209 return m_angularFactor;
212 const btVector3& internalGetInvMass() const
217 void internalSetInvMass(const btVector3& invMass)
222 btVector3& internalGetPushVelocity()
224 return m_pushVelocity;
227 btVector3& internalGetTurnVelocity()
229 return m_turnVelocity;
232 SIMD_FORCE_INLINE void internalGetVelocityInLocalPointObsolete(const btVector3& rel_pos, btVector3& velocity) const
234 velocity = m_linearVelocity + m_deltaLinearVelocity + (m_angularVelocity + m_deltaAngularVelocity).cross(rel_pos);
237 SIMD_FORCE_INLINE void internalGetAngularVelocity(btVector3 & angVel) const
239 angVel = m_angularVelocity + m_deltaAngularVelocity;
242 //Optimization for the iterative solver: avoid calculating constant terms involving inertia, normal, relative position
243 SIMD_FORCE_INLINE void internalApplyImpulse(const btVector3& linearComponent, const btVector3& angularComponent, const btScalar impulseMagnitude)
247 m_deltaLinearVelocity += linearComponent * impulseMagnitude * m_linearFactor;
248 m_deltaAngularVelocity += angularComponent * (impulseMagnitude * m_angularFactor);
252 void writebackVelocity()
256 m_linearVelocity += m_deltaLinearVelocity;
257 m_angularVelocity += m_deltaAngularVelocity;
259 //m_originalBody->setCompanionId(-1);
263 void writebackVelocityAndTransform(btScalar timeStep, btScalar splitImpulseTurnErp)
268 m_linearVelocity += m_deltaLinearVelocity;
269 m_angularVelocity += m_deltaAngularVelocity;
271 //correct the position/orientation based on push/turn recovery
272 btTransform newTransform;
273 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)
275 // btQuaternion orn = m_worldTransform.getRotation();
276 btTransformUtil::integrateTransform(m_worldTransform, m_pushVelocity, m_turnVelocity * splitImpulseTurnErp, timeStep, newTransform);
277 m_worldTransform = newTransform;
279 //m_worldTransform.setRotation(orn);
280 //m_originalBody->setCompanionId(-1);
285 #endif //BT_SOLVER_BODY_H