[dali_2.3.21] Merge branch 'devel/master'
[platform/core/uifw/dali-toolkit.git] / dali-physics / third-party / bullet3 / src / BulletDynamics / ConstraintSolver / btSequentialImpulseConstraintSolver.h
1 /*
2 Bullet Continuous Collision Detection and Physics Library
3 Copyright (c) 2003-2006 Erwin Coumans  https://bulletphysics.org
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_SEQUENTIAL_IMPULSE_CONSTRAINT_SOLVER_H
17 #define BT_SEQUENTIAL_IMPULSE_CONSTRAINT_SOLVER_H
18
19 class btIDebugDraw;
20 class btPersistentManifold;
21 class btDispatcher;
22 class btCollisionObject;
23 #include "BulletDynamics/ConstraintSolver/btTypedConstraint.h"
24 #include "BulletDynamics/ConstraintSolver/btContactSolverInfo.h"
25 #include "BulletDynamics/ConstraintSolver/btSolverBody.h"
26 #include "BulletDynamics/ConstraintSolver/btSolverConstraint.h"
27 #include "BulletCollision/NarrowPhaseCollision/btManifoldPoint.h"
28 #include "BulletDynamics/ConstraintSolver/btConstraintSolver.h"
29
30 typedef btScalar (*btSingleConstraintRowSolver)(btSolverBody&, btSolverBody&, const btSolverConstraint&);
31
32 struct btSolverAnalyticsData
33 {
34         btSolverAnalyticsData()
35         {
36                 m_numSolverCalls = 0;
37                 m_numIterationsUsed = -1;
38                 m_remainingLeastSquaresResidual = -1;
39                 m_islandId = -2;
40         }
41         int m_islandId;
42         int m_numBodies;
43         int m_numContactManifolds;
44         int m_numSolverCalls;
45         int m_numIterationsUsed;
46         double m_remainingLeastSquaresResidual;
47 };
48
49 ///The btSequentialImpulseConstraintSolver is a fast SIMD implementation of the Projected Gauss Seidel (iterative LCP) method.
50 ATTRIBUTE_ALIGNED16(class)
51 btSequentialImpulseConstraintSolver : public btConstraintSolver
52 {
53         
54
55 protected:
56         btAlignedObjectArray<btSolverBody> m_tmpSolverBodyPool;
57         btConstraintArray m_tmpSolverContactConstraintPool;
58         btConstraintArray m_tmpSolverNonContactConstraintPool;
59         btConstraintArray m_tmpSolverContactFrictionConstraintPool;
60         btConstraintArray m_tmpSolverContactRollingFrictionConstraintPool;
61
62         btAlignedObjectArray<int> m_orderTmpConstraintPool;
63         btAlignedObjectArray<int> m_orderNonContactConstraintPool;
64         btAlignedObjectArray<int> m_orderFrictionConstraintPool;
65         btAlignedObjectArray<btTypedConstraint::btConstraintInfo1> m_tmpConstraintSizesPool;
66         int m_maxOverrideNumSolverIterations;
67         int m_fixedBodyId;
68         // When running solvers on multiple threads, a race condition exists for Kinematic objects that
69         // participate in more than one solver.
70         // The getOrInitSolverBody() function writes the companionId of each body (storing the index of the solver body
71         // for the current solver). For normal dynamic bodies it isn't an issue because they can only be in one island
72         // (and therefore one thread) at a time. But kinematic bodies can be in multiple islands at once.
73         // To avoid this race condition, this solver does not write the companionId, instead it stores the solver body
74         // index in this solver-local table, indexed by the uniqueId of the body.
75         btAlignedObjectArray<int> m_kinematicBodyUniqueIdToSolverBodyTable;  // only used for multithreading
76
77         btSingleConstraintRowSolver m_resolveSingleConstraintRowGeneric;
78         btSingleConstraintRowSolver m_resolveSingleConstraintRowLowerLimit;
79         btSingleConstraintRowSolver m_resolveSplitPenetrationImpulse;
80         int m_cachedSolverMode;  // used to check if SOLVER_SIMD flag has been changed
81         void setupSolverFunctions(bool useSimd);
82
83         btScalar m_leastSquaresResidual;
84
85         void setupFrictionConstraint(btSolverConstraint & solverConstraint, const btVector3& normalAxis, int solverBodyIdA, int solverBodyIdB,
86                 btManifoldPoint& cp, const btVector3& rel_pos1, const btVector3& rel_pos2,
87                 btCollisionObject* colObj0, btCollisionObject* colObj1, btScalar relaxation,
88                 const btContactSolverInfo& infoGlobal,
89                 btScalar desiredVelocity = 0., btScalar cfmSlip = 0.);
90
91         void setupTorsionalFrictionConstraint(btSolverConstraint & solverConstraint, const btVector3& normalAxis, int solverBodyIdA, int solverBodyIdB,
92                 btManifoldPoint& cp, btScalar combinedTorsionalFriction, const btVector3& rel_pos1, const btVector3& rel_pos2,
93                 btCollisionObject* colObj0, btCollisionObject* colObj1, btScalar relaxation,
94                 btScalar desiredVelocity = 0., btScalar cfmSlip = 0.);
95
96         btSolverConstraint& addFrictionConstraint(const btVector3& normalAxis, int solverBodyIdA, int solverBodyIdB, int frictionIndex, btManifoldPoint& cp, const btVector3& rel_pos1, const btVector3& rel_pos2, btCollisionObject* colObj0, btCollisionObject* colObj1, btScalar relaxation, const btContactSolverInfo& infoGlobal, btScalar desiredVelocity = 0., btScalar cfmSlip = 0.);
97         btSolverConstraint& addTorsionalFrictionConstraint(const btVector3& normalAxis, int solverBodyIdA, int solverBodyIdB, int frictionIndex, btManifoldPoint& cp, btScalar torsionalFriction, const btVector3& rel_pos1, const btVector3& rel_pos2, btCollisionObject* colObj0, btCollisionObject* colObj1, btScalar relaxation, btScalar desiredVelocity = 0, btScalar cfmSlip = 0.f);
98
99         void setupContactConstraint(btSolverConstraint & solverConstraint, int solverBodyIdA, int solverBodyIdB, btManifoldPoint& cp,
100                 const btContactSolverInfo& infoGlobal, btScalar& relaxation, const btVector3& rel_pos1, const btVector3& rel_pos2);
101
102         static void applyAnisotropicFriction(btCollisionObject * colObj, btVector3 & frictionDirection, int frictionMode);
103
104         void setFrictionConstraintImpulse(btSolverConstraint & solverConstraint, int solverBodyIdA, int solverBodyIdB,
105                 btManifoldPoint& cp, const btContactSolverInfo& infoGlobal);
106
107         ///m_btSeed2 is used for re-arranging the constraint rows. improves convergence/quality of friction
108         unsigned long m_btSeed2;
109
110         btScalar restitutionCurve(btScalar rel_vel, btScalar restitution, btScalar velocityThreshold);
111
112         virtual void convertContacts(btPersistentManifold * *manifoldPtr, int numManifolds, const btContactSolverInfo& infoGlobal);
113
114         void convertContact(btPersistentManifold * manifold, const btContactSolverInfo& infoGlobal);
115
116         virtual void convertJoints(btTypedConstraint * *constraints, int numConstraints, const btContactSolverInfo& infoGlobal);
117         void convertJoint(btSolverConstraint * currentConstraintRow, btTypedConstraint * constraint, const btTypedConstraint::btConstraintInfo1& info1, int solverBodyIdA, int solverBodyIdB, const btContactSolverInfo& infoGlobal);
118
119         virtual void convertBodies(btCollisionObject * *bodies, int numBodies, const btContactSolverInfo& infoGlobal);
120
121         btScalar resolveSplitPenetrationSIMD(btSolverBody & bodyA, btSolverBody & bodyB, const btSolverConstraint& contactConstraint)
122         {
123                 return m_resolveSplitPenetrationImpulse(bodyA, bodyB, contactConstraint);
124         }
125
126         btScalar resolveSplitPenetrationImpulseCacheFriendly(btSolverBody & bodyA, btSolverBody & bodyB, const btSolverConstraint& contactConstraint)
127         {
128                 return m_resolveSplitPenetrationImpulse(bodyA, bodyB, contactConstraint);
129         }
130
131         //internal method
132         int getOrInitSolverBody(btCollisionObject & body, btScalar timeStep);
133         void initSolverBody(btSolverBody * solverBody, btCollisionObject * collisionObject, btScalar timeStep);
134
135         btScalar resolveSingleConstraintRowGeneric(btSolverBody & bodyA, btSolverBody & bodyB, const btSolverConstraint& contactConstraint);
136         btScalar resolveSingleConstraintRowGenericSIMD(btSolverBody & bodyA, btSolverBody & bodyB, const btSolverConstraint& contactConstraint);
137         btScalar resolveSingleConstraintRowLowerLimit(btSolverBody & bodyA, btSolverBody & bodyB, const btSolverConstraint& contactConstraint);
138         btScalar resolveSingleConstraintRowLowerLimitSIMD(btSolverBody & bodyA, btSolverBody & bodyB, const btSolverConstraint& contactConstraint);
139         btScalar resolveSplitPenetrationImpulse(btSolverBody & bodyA, btSolverBody & bodyB, const btSolverConstraint& contactConstraint)
140         {
141                 return m_resolveSplitPenetrationImpulse(bodyA, bodyB, contactConstraint);
142         }
143
144 protected:
145         void writeBackContacts(int iBegin, int iEnd, const btContactSolverInfo& infoGlobal);
146         void writeBackJoints(int iBegin, int iEnd, const btContactSolverInfo& infoGlobal);
147         void writeBackBodies(int iBegin, int iEnd, const btContactSolverInfo& infoGlobal);
148         virtual void solveGroupCacheFriendlySplitImpulseIterations(btCollisionObject * *bodies, int numBodies, btPersistentManifold** manifoldPtr, int numManifolds, btTypedConstraint** constraints, int numConstraints, const btContactSolverInfo& infoGlobal, btIDebugDraw* debugDrawer);
149         virtual btScalar solveGroupCacheFriendlyFinish(btCollisionObject * *bodies, int numBodies, const btContactSolverInfo& infoGlobal);
150         virtual btScalar solveSingleIteration(int iteration, btCollisionObject** bodies, int numBodies, btPersistentManifold** manifoldPtr, int numManifolds, btTypedConstraint** constraints, int numConstraints, const btContactSolverInfo& infoGlobal, btIDebugDraw* debugDrawer);
151
152         virtual btScalar solveGroupCacheFriendlySetup(btCollisionObject * *bodies, int numBodies, btPersistentManifold** manifoldPtr, int numManifolds, btTypedConstraint** constraints, int numConstraints, const btContactSolverInfo& infoGlobal, btIDebugDraw* debugDrawer);
153         virtual btScalar solveGroupCacheFriendlyIterations(btCollisionObject * *bodies, int numBodies, btPersistentManifold** manifoldPtr, int numManifolds, btTypedConstraint** constraints, int numConstraints, const btContactSolverInfo& infoGlobal, btIDebugDraw* debugDrawer);
154
155 public:
156         BT_DECLARE_ALIGNED_ALLOCATOR();
157
158         btSequentialImpulseConstraintSolver();
159         virtual ~btSequentialImpulseConstraintSolver();
160
161         virtual btScalar solveGroup(btCollisionObject * *bodies, int numBodies, btPersistentManifold** manifold, int numManifolds, btTypedConstraint** constraints, int numConstraints, const btContactSolverInfo& info, btIDebugDraw* debugDrawer, btDispatcher* dispatcher);
162
163         ///clear internal cached data and reset random seed
164         virtual void reset();
165
166         unsigned long btRand2();
167
168         int btRandInt2(int n);
169
170         void setRandSeed(unsigned long seed)
171         {
172                 m_btSeed2 = seed;
173         }
174         unsigned long getRandSeed() const
175         {
176                 return m_btSeed2;
177         }
178
179         virtual btConstraintSolverType getSolverType() const
180         {
181                 return BT_SEQUENTIAL_IMPULSE_SOLVER;
182         }
183
184         btSingleConstraintRowSolver getActiveConstraintRowSolverGeneric()
185         {
186                 return m_resolveSingleConstraintRowGeneric;
187         }
188         void setConstraintRowSolverGeneric(btSingleConstraintRowSolver rowSolver)
189         {
190                 m_resolveSingleConstraintRowGeneric = rowSolver;
191         }
192         btSingleConstraintRowSolver getActiveConstraintRowSolverLowerLimit()
193         {
194                 return m_resolveSingleConstraintRowLowerLimit;
195         }
196         void setConstraintRowSolverLowerLimit(btSingleConstraintRowSolver rowSolver)
197         {
198                 m_resolveSingleConstraintRowLowerLimit = rowSolver;
199         }
200
201
202
203         ///Various implementations of solving a single constraint row using a generic equality constraint, using scalar reference, SSE2 or SSE4
204         btSingleConstraintRowSolver getScalarConstraintRowSolverGeneric();
205         btSingleConstraintRowSolver getSSE2ConstraintRowSolverGeneric();
206         btSingleConstraintRowSolver getSSE4_1ConstraintRowSolverGeneric();
207
208         ///Various implementations of solving a single constraint row using an inequality (lower limit) constraint, using scalar reference, SSE2 or SSE4
209         btSingleConstraintRowSolver getScalarConstraintRowSolverLowerLimit();
210         btSingleConstraintRowSolver getSSE2ConstraintRowSolverLowerLimit();
211         btSingleConstraintRowSolver getSSE4_1ConstraintRowSolverLowerLimit();
212         btSolverAnalyticsData m_analyticsData;
213 };
214
215 #endif  //BT_SEQUENTIAL_IMPULSE_CONSTRAINT_SOLVER_H