Initialize libbullet git in 2.0_beta.
[platform/upstream/libbullet.git] / src / BulletDynamics / ConstraintSolver / btTypedConstraint.h
1 /*
2 Bullet Continuous Collision Detection and Physics Library
3 Copyright (c) 2003-2010 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_TYPED_CONSTRAINT_H
17 #define BT_TYPED_CONSTRAINT_H
18
19 class btRigidBody;
20 #include "LinearMath/btScalar.h"
21 #include "btSolverConstraint.h"
22
23 class btSerializer;
24
25 //Don't change any of the existing enum values, so add enum types at the end for serialization compatibility
26 enum btTypedConstraintType
27 {
28         POINT2POINT_CONSTRAINT_TYPE=3,
29         HINGE_CONSTRAINT_TYPE,
30         CONETWIST_CONSTRAINT_TYPE,
31         D6_CONSTRAINT_TYPE,
32         SLIDER_CONSTRAINT_TYPE,
33         CONTACT_CONSTRAINT_TYPE,
34         D6_SPRING_CONSTRAINT_TYPE,
35         MAX_CONSTRAINT_TYPE
36 };
37
38
39 enum btConstraintParams
40 {
41         BT_CONSTRAINT_ERP=1,
42         BT_CONSTRAINT_STOP_ERP,
43         BT_CONSTRAINT_CFM,
44         BT_CONSTRAINT_STOP_CFM
45 };
46
47 #if 1
48         #define btAssertConstrParams(_par) btAssert(_par) 
49 #else
50         #define btAssertConstrParams(_par)
51 #endif
52
53
54 ///TypedConstraint is the baseclass for Bullet constraints and vehicles
55 class btTypedConstraint : public btTypedObject
56 {
57         int     m_userConstraintType;
58
59         union
60         {
61                 int     m_userConstraintId;
62                 void* m_userConstraintPtr;
63         };
64
65         btScalar        m_breakingImpulseThreshold;
66         bool            m_isEnabled;
67         bool            m_needsFeedback;
68         int                     m_overrideNumSolverIterations;
69
70
71         btTypedConstraint&      operator=(btTypedConstraint&    other)
72         {
73                 btAssert(0);
74                 (void) other;
75                 return *this;
76         }
77
78 protected:
79         btRigidBody&    m_rbA;
80         btRigidBody&    m_rbB;
81         btScalar        m_appliedImpulse;
82         btScalar        m_dbgDrawSize;
83
84         ///internal method used by the constraint solver, don't use them directly
85         btScalar getMotorFactor(btScalar pos, btScalar lowLim, btScalar uppLim, btScalar vel, btScalar timeFact);
86         
87
88 public:
89
90         virtual ~btTypedConstraint() {};
91         btTypedConstraint(btTypedConstraintType type, btRigidBody& rbA);
92         btTypedConstraint(btTypedConstraintType type, btRigidBody& rbA,btRigidBody& rbB);
93
94         struct btConstraintInfo1 {
95                 int m_numConstraintRows,nub;
96         };
97
98         static btRigidBody& getFixedBody();
99
100         struct btConstraintInfo2 {
101                 // integrator parameters: frames per second (1/stepsize), default error
102                 // reduction parameter (0..1).
103                 btScalar fps,erp;
104
105                 // for the first and second body, pointers to two (linear and angular)
106                 // n*3 jacobian sub matrices, stored by rows. these matrices will have
107                 // been initialized to 0 on entry. if the second body is zero then the
108                 // J2xx pointers may be 0.
109                 btScalar *m_J1linearAxis,*m_J1angularAxis,*m_J2linearAxis,*m_J2angularAxis;
110
111                 // elements to jump from one row to the next in J's
112                 int rowskip;
113
114                 // right hand sides of the equation J*v = c + cfm * lambda. cfm is the
115                 // "constraint force mixing" vector. c is set to zero on entry, cfm is
116                 // set to a constant value (typically very small or zero) value on entry.
117                 btScalar *m_constraintError,*cfm;
118
119                 // lo and hi limits for variables (set to -/+ infinity on entry).
120                 btScalar *m_lowerLimit,*m_upperLimit;
121
122                 // findex vector for variables. see the LCP solver interface for a
123                 // description of what this does. this is set to -1 on entry.
124                 // note that the returned indexes are relative to the first index of
125                 // the constraint.
126                 int *findex;
127                 // number of solver iterations
128                 int m_numIterations;
129
130                 //damping of the velocity
131                 btScalar        m_damping;
132         };
133
134         int     getOverrideNumSolverIterations() const
135         {
136                 return m_overrideNumSolverIterations;
137         }
138
139         ///override the number of constraint solver iterations used to solve this constraint
140         ///-1 will use the default number of iterations, as specified in SolverInfo.m_numIterations
141         void setOverrideNumSolverIterations(int overideNumIterations)
142         {
143                 m_overrideNumSolverIterations = overideNumIterations;
144         }
145
146         ///internal method used by the constraint solver, don't use them directly
147         virtual void    buildJacobian() {};
148
149         ///internal method used by the constraint solver, don't use them directly
150         virtual void    setupSolverConstraint(btConstraintArray& ca, int solverBodyA,int solverBodyB, btScalar timeStep)
151         {
152         (void)ca;
153         (void)solverBodyA;
154         (void)solverBodyB;
155         (void)timeStep;
156         }
157         
158         ///internal method used by the constraint solver, don't use them directly
159         virtual void getInfo1 (btConstraintInfo1* info)=0;
160
161         ///internal method used by the constraint solver, don't use them directly
162         virtual void getInfo2 (btConstraintInfo2* info)=0;
163
164         ///internal method used by the constraint solver, don't use them directly
165         void    internalSetAppliedImpulse(btScalar appliedImpulse)
166         {
167                 m_appliedImpulse = appliedImpulse;
168         }
169         ///internal method used by the constraint solver, don't use them directly
170         btScalar        internalGetAppliedImpulse()
171         {
172                 return m_appliedImpulse;
173         }
174
175
176         btScalar        getBreakingImpulseThreshold() const
177         {
178                 return  m_breakingImpulseThreshold;
179         }
180
181         void    setBreakingImpulseThreshold(btScalar threshold)
182         {
183                 m_breakingImpulseThreshold = threshold;
184         }
185
186         bool    isEnabled() const
187         {
188                 return m_isEnabled;
189         }
190
191         void    setEnabled(bool enabled)
192         {
193                 m_isEnabled=enabled;
194         }
195
196
197         ///internal method used by the constraint solver, don't use them directly
198         virtual void    solveConstraintObsolete(btRigidBody& /*bodyA*/,btRigidBody& /*bodyB*/,btScalar  /*timeStep*/) {};
199
200         
201         const btRigidBody& getRigidBodyA() const
202         {
203                 return m_rbA;
204         }
205         const btRigidBody& getRigidBodyB() const
206         {
207                 return m_rbB;
208         }
209
210         btRigidBody& getRigidBodyA() 
211         {
212                 return m_rbA;
213         }
214         btRigidBody& getRigidBodyB()
215         {
216                 return m_rbB;
217         }
218
219         int getUserConstraintType() const
220         {
221                 return m_userConstraintType ;
222         }
223
224         void    setUserConstraintType(int userConstraintType)
225         {
226                 m_userConstraintType = userConstraintType;
227         };
228
229         void    setUserConstraintId(int uid)
230         {
231                 m_userConstraintId = uid;
232         }
233
234         int getUserConstraintId() const
235         {
236                 return m_userConstraintId;
237         }
238
239         void    setUserConstraintPtr(void* ptr)
240         {
241                 m_userConstraintPtr = ptr;
242         }
243
244         void*   getUserConstraintPtr()
245         {
246                 return m_userConstraintPtr;
247         }
248
249         int getUid() const
250         {
251                 return m_userConstraintId;   
252         } 
253
254         bool    needsFeedback() const
255         {
256                 return m_needsFeedback;
257         }
258
259         ///enableFeedback will allow to read the applied linear and angular impulse
260         ///use getAppliedImpulse, getAppliedLinearImpulse and getAppliedAngularImpulse to read feedback information
261         void    enableFeedback(bool needsFeedback)
262         {
263                 m_needsFeedback = needsFeedback;
264         }
265
266         ///getAppliedImpulse is an estimated total applied impulse. 
267         ///This feedback could be used to determine breaking constraints or playing sounds.
268         btScalar        getAppliedImpulse() const
269         {
270                 btAssert(m_needsFeedback);
271                 return m_appliedImpulse;
272         }
273
274         btTypedConstraintType getConstraintType () const
275         {
276                 return btTypedConstraintType(m_objectType);
277         }
278         
279         void setDbgDrawSize(btScalar dbgDrawSize)
280         {
281                 m_dbgDrawSize = dbgDrawSize;
282         }
283         btScalar getDbgDrawSize()
284         {
285                 return m_dbgDrawSize;
286         }
287
288         ///override the default global value of a parameter (such as ERP or CFM), optionally provide the axis (0..5). 
289         ///If no axis is provided, it uses the default axis for this constraint.
290         virtual void    setParam(int num, btScalar value, int axis = -1) = 0;
291
292         ///return the local value of parameter
293         virtual btScalar getParam(int num, int axis = -1) const = 0;
294         
295         virtual int     calculateSerializeBufferSize() const;
296
297         ///fills the dataBuffer and returns the struct name (and 0 on failure)
298         virtual const char*     serialize(void* dataBuffer, btSerializer* serializer) const;
299
300 };
301
302 // returns angle in range [-SIMD_2_PI, SIMD_2_PI], closest to one of the limits 
303 // all arguments should be normalized angles (i.e. in range [-SIMD_PI, SIMD_PI])
304 SIMD_FORCE_INLINE btScalar btAdjustAngleToLimits(btScalar angleInRadians, btScalar angleLowerLimitInRadians, btScalar angleUpperLimitInRadians)
305 {
306         if(angleLowerLimitInRadians >= angleUpperLimitInRadians)
307         {
308                 return angleInRadians;
309         }
310         else if(angleInRadians < angleLowerLimitInRadians)
311         {
312                 btScalar diffLo = btFabs(btNormalizeAngle(angleLowerLimitInRadians - angleInRadians));
313                 btScalar diffHi = btFabs(btNormalizeAngle(angleUpperLimitInRadians - angleInRadians));
314                 return (diffLo < diffHi) ? angleInRadians : (angleInRadians + SIMD_2_PI);
315         }
316         else if(angleInRadians > angleUpperLimitInRadians)
317         {
318                 btScalar diffHi = btFabs(btNormalizeAngle(angleInRadians - angleUpperLimitInRadians));
319                 btScalar diffLo = btFabs(btNormalizeAngle(angleInRadians - angleLowerLimitInRadians));
320                 return (diffLo < diffHi) ? (angleInRadians - SIMD_2_PI) : angleInRadians;
321         }
322         else
323         {
324                 return angleInRadians;
325         }
326 }
327
328 ///do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64
329 struct  btTypedConstraintData
330 {
331         btRigidBodyData         *m_rbA;
332         btRigidBodyData         *m_rbB;
333         char    *m_name;
334
335         int     m_objectType;
336         int     m_userConstraintType;
337         int     m_userConstraintId;
338         int     m_needsFeedback;
339
340         float   m_appliedImpulse;
341         float   m_dbgDrawSize;
342
343         int     m_disableCollisionsBetweenLinkedBodies;
344         int     m_overrideNumSolverIterations;
345
346         float   m_breakingImpulseThreshold;
347         int             m_isEnabled;
348         
349 };
350
351 SIMD_FORCE_INLINE       int     btTypedConstraint::calculateSerializeBufferSize() const
352 {
353         return sizeof(btTypedConstraintData);
354 }
355
356
357
358 class btAngularLimit
359 {
360 private:
361         btScalar 
362                 m_center,
363                 m_halfRange,
364                 m_softness,
365                 m_biasFactor,
366                 m_relaxationFactor,
367                 m_correction,
368                 m_sign;
369
370         bool
371                 m_solveLimit;
372
373 public:
374         /// Default constructor initializes limit as inactive, allowing free constraint movement
375         btAngularLimit()
376                 :m_center(0.0f),
377                 m_halfRange(-1.0f),
378                 m_softness(0.9f),
379                 m_biasFactor(0.3f),
380                 m_relaxationFactor(1.0f),
381                 m_correction(0.0f),
382                 m_sign(0.0f),
383                 m_solveLimit(false)
384         {}
385
386         /// Sets all limit's parameters.
387         /// When low > high limit becomes inactive.
388         /// When high - low > 2PI limit is ineffective too becouse no angle can exceed the limit
389         void set(btScalar low, btScalar high, btScalar _softness = 0.9f, btScalar _biasFactor = 0.3f, btScalar _relaxationFactor = 1.0f);
390
391         /// Checks conastaint angle against limit. If limit is active and the angle violates the limit
392         /// correction is calculated.
393         void test(const btScalar angle);
394
395         /// Returns limit's softness
396         inline btScalar getSoftness() const
397         {
398                 return m_softness;
399         }
400
401         /// Returns limit's bias factor
402         inline btScalar getBiasFactor() const
403         {
404                 return m_biasFactor;
405         }
406
407         /// Returns limit's relaxation factor
408         inline btScalar getRelaxationFactor() const
409         {
410                 return m_relaxationFactor;
411         }
412
413         /// Returns correction value evaluated when test() was invoked 
414         inline btScalar getCorrection() const
415         {
416                 return m_correction;
417         }
418
419         /// Returns sign value evaluated when test() was invoked 
420         inline btScalar getSign() const
421         {
422                 return m_sign;
423         }
424
425         /// Gives half of the distance between min and max limit angle
426         inline btScalar getHalfRange() const
427         {
428                 return m_halfRange;
429         }
430
431         /// Returns true when the last test() invocation recognized limit violation
432         inline bool isLimit() const
433         {
434                 return m_solveLimit;
435         }
436
437         /// Checks given angle against limit. If limit is active and angle doesn't fit it, the angle
438         /// returned is modified so it equals to the limit closest to given angle.
439         void fit(btScalar& angle) const;
440
441         /// Returns correction value multiplied by sign value
442         btScalar getError() const;
443
444         btScalar getLow() const;
445
446         btScalar getHigh() const;
447
448 };
449
450
451
452 #endif //BT_TYPED_CONSTRAINT_H