Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/kicklib/src/external/bullet/BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.h @ 8526

Last change on this file since 8526 was 7983, checked in by rgrieder, 14 years ago

Updated Bullet Physics Engine from v2.74 to v2.77

  • Property svn:eol-style set to native
File size: 17.7 KB
Line 
1/*
2Bullet Continuous Collision Detection and Physics Library
3Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/
4
5This software is provided 'as-is', without any express or implied warranty.
6In no event will the authors be held liable for any damages arising from the use of this software.
7Permission is granted to anyone to use this software for any purpose,
8including commercial applications, and to alter it and redistribute it freely,
9subject to the following restrictions:
10
111. 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.
122. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
133. This notice may not be removed or altered from any source distribution.
14*/
15
16/// 2009 March: btGeneric6DofConstraint refactored by Roman Ponomarev
17/// Added support for generic constraint solver through getInfo1/getInfo2 methods
18
19/*
202007-09-09
21btGeneric6DofConstraint Refactored by Francisco Le?n
22email: projectileman@yahoo.com
23http://gimpact.sf.net
24*/
25
26
27#ifndef GENERIC_6DOF_CONSTRAINT_H
28#define GENERIC_6DOF_CONSTRAINT_H
29
30#include "LinearMath/btVector3.h"
31#include "btJacobianEntry.h"
32#include "btTypedConstraint.h"
33
34class btRigidBody;
35
36
37
38
39//! Rotation Limit structure for generic joints
40class btRotationalLimitMotor
41{
42public:
43    //! limit_parameters
44    //!@{
45    btScalar m_loLimit;//!< joint limit
46    btScalar m_hiLimit;//!< joint limit
47    btScalar m_targetVelocity;//!< target motor velocity
48    btScalar m_maxMotorForce;//!< max force on motor
49    btScalar m_maxLimitForce;//!< max force on limit
50    btScalar m_damping;//!< Damping.
51    btScalar m_limitSoftness;//! Relaxation factor
52    btScalar m_normalCFM;//!< Constraint force mixing factor
53    btScalar m_stopERP;//!< Error tolerance factor when joint is at limit
54    btScalar m_stopCFM;//!< Constraint force mixing factor when joint is at limit
55    btScalar m_bounce;//!< restitution factor
56    bool m_enableMotor;
57
58    //!@}
59
60    //! temp_variables
61    //!@{
62    btScalar m_currentLimitError;//!  How much is violated this limit
63    btScalar m_currentPosition;     //!  current value of angle
64    int m_currentLimit;//!< 0=free, 1=at lo limit, 2=at hi limit
65    btScalar m_accumulatedImpulse;
66    //!@}
67
68    btRotationalLimitMotor()
69    {
70        m_accumulatedImpulse = 0.f;
71        m_targetVelocity = 0;
72        m_maxMotorForce = 0.1f;
73        m_maxLimitForce = 300.0f;
74        m_loLimit = 1.0f;
75        m_hiLimit = -1.0f;
76                m_normalCFM = 0.f;
77                m_stopERP = 0.2f;
78                m_stopCFM = 0.f;
79        m_bounce = 0.0f;
80        m_damping = 1.0f;
81        m_limitSoftness = 0.5f;
82        m_currentLimit = 0;
83        m_currentLimitError = 0;
84        m_enableMotor = false;
85    }
86
87    btRotationalLimitMotor(const btRotationalLimitMotor & limot)
88    {
89        m_targetVelocity = limot.m_targetVelocity;
90        m_maxMotorForce = limot.m_maxMotorForce;
91        m_limitSoftness = limot.m_limitSoftness;
92        m_loLimit = limot.m_loLimit;
93        m_hiLimit = limot.m_hiLimit;
94                m_normalCFM = limot.m_normalCFM;
95                m_stopERP = limot.m_stopERP;
96                m_stopCFM =     limot.m_stopCFM;
97        m_bounce = limot.m_bounce;
98        m_currentLimit = limot.m_currentLimit;
99        m_currentLimitError = limot.m_currentLimitError;
100        m_enableMotor = limot.m_enableMotor;
101    }
102
103
104
105        //! Is limited
106    bool isLimited()
107    {
108        if(m_loLimit > m_hiLimit) return false;
109        return true;
110    }
111
112        //! Need apply correction
113    bool needApplyTorques()
114    {
115        if(m_currentLimit == 0 && m_enableMotor == false) return false;
116        return true;
117    }
118
119        //! calculates  error
120        /*!
121        calculates m_currentLimit and m_currentLimitError.
122        */
123        int testLimitValue(btScalar test_value);
124
125        //! apply the correction impulses for two bodies
126    btScalar solveAngularLimits(btScalar timeStep,btVector3& axis, btScalar jacDiagABInv,btRigidBody * body0, btRigidBody * body1);
127
128};
129
130
131
132class btTranslationalLimitMotor
133{
134public:
135        btVector3 m_lowerLimit;//!< the constraint lower limits
136    btVector3 m_upperLimit;//!< the constraint upper limits
137    btVector3 m_accumulatedImpulse;
138    //! Linear_Limit_parameters
139    //!@{
140    btScalar    m_limitSoftness;//!< Softness for linear limit
141    btScalar    m_damping;//!< Damping for linear limit
142    btScalar    m_restitution;//! Bounce parameter for linear limit
143        btVector3       m_normalCFM;//!< Constraint force mixing factor
144    btVector3   m_stopERP;//!< Error tolerance factor when joint is at limit
145        btVector3       m_stopCFM;//!< Constraint force mixing factor when joint is at limit
146    //!@}
147        bool            m_enableMotor[3];
148    btVector3   m_targetVelocity;//!< target motor velocity
149    btVector3   m_maxMotorForce;//!< max force on motor
150    btVector3   m_currentLimitError;//!  How much is violated this limit
151    btVector3   m_currentLinearDiff;//!  Current relative offset of constraint frames
152    int                 m_currentLimit[3];//!< 0=free, 1=at lower limit, 2=at upper limit
153
154    btTranslationalLimitMotor()
155    {
156        m_lowerLimit.setValue(0.f,0.f,0.f);
157        m_upperLimit.setValue(0.f,0.f,0.f);
158        m_accumulatedImpulse.setValue(0.f,0.f,0.f);
159                m_normalCFM.setValue(0.f, 0.f, 0.f);
160                m_stopERP.setValue(0.2f, 0.2f, 0.2f);
161                m_stopCFM.setValue(0.f, 0.f, 0.f);
162
163        m_limitSoftness = 0.7f;
164        m_damping = btScalar(1.0f);
165        m_restitution = btScalar(0.5f);
166                for(int i=0; i < 3; i++) 
167                {
168                        m_enableMotor[i] = false;
169                        m_targetVelocity[i] = btScalar(0.f);
170                        m_maxMotorForce[i] = btScalar(0.f);
171                }
172    }
173
174    btTranslationalLimitMotor(const btTranslationalLimitMotor & other )
175    {
176        m_lowerLimit = other.m_lowerLimit;
177        m_upperLimit = other.m_upperLimit;
178        m_accumulatedImpulse = other.m_accumulatedImpulse;
179
180        m_limitSoftness = other.m_limitSoftness ;
181        m_damping = other.m_damping;
182        m_restitution = other.m_restitution;
183                m_normalCFM = other.m_normalCFM;
184                m_stopERP = other.m_stopERP;
185                m_stopCFM = other.m_stopCFM;
186
187                for(int i=0; i < 3; i++) 
188                {
189                        m_enableMotor[i] = other.m_enableMotor[i];
190                        m_targetVelocity[i] = other.m_targetVelocity[i];
191                        m_maxMotorForce[i] = other.m_maxMotorForce[i];
192                }
193    }
194
195    //! Test limit
196        /*!
197    - free means upper < lower,
198    - locked means upper == lower
199    - limited means upper > lower
200    - limitIndex: first 3 are linear, next 3 are angular
201    */
202    inline bool isLimited(int limitIndex)
203    {
204       return (m_upperLimit[limitIndex] >= m_lowerLimit[limitIndex]);
205    }
206    inline bool needApplyForce(int limitIndex)
207    {
208        if(m_currentLimit[limitIndex] == 0 && m_enableMotor[limitIndex] == false) return false;
209        return true;
210    }
211        int testLimitValue(int limitIndex, btScalar test_value);
212
213
214    btScalar solveLinearAxis(
215        btScalar timeStep,
216        btScalar jacDiagABInv,
217        btRigidBody& body1,const btVector3 &pointInA,
218        btRigidBody& body2,const btVector3 &pointInB,
219        int limit_index,
220        const btVector3 & axis_normal_on_a,
221                const btVector3 & anchorPos);
222
223
224};
225
226enum bt6DofFlags
227{
228        BT_6DOF_FLAGS_CFM_NORM = 1,
229        BT_6DOF_FLAGS_CFM_STOP = 2,
230        BT_6DOF_FLAGS_ERP_STOP = 4
231};
232#define BT_6DOF_FLAGS_AXIS_SHIFT 3 // bits per axis
233
234
235/// btGeneric6DofConstraint between two rigidbodies each with a pivotpoint that descibes the axis location in local space
236/*!
237btGeneric6DofConstraint can leave any of the 6 degree of freedom 'free' or 'locked'.
238currently this limit supports rotational motors<br>
239<ul>
240<li> For Linear limits, use btGeneric6DofConstraint.setLinearUpperLimit, btGeneric6DofConstraint.setLinearLowerLimit. You can set the parameters with the btTranslationalLimitMotor structure accsesible through the btGeneric6DofConstraint.getTranslationalLimitMotor method.
241At this moment translational motors are not supported. May be in the future. </li>
242
243<li> For Angular limits, use the btRotationalLimitMotor structure for configuring the limit.
244This is accessible through btGeneric6DofConstraint.getLimitMotor method,
245This brings support for limit parameters and motors. </li>
246
247<li> Angulars limits have these possible ranges:
248<table border=1 >
249<tr>
250        <td><b>AXIS</b></td>
251        <td><b>MIN ANGLE</b></td>
252        <td><b>MAX ANGLE</b></td>
253</tr><tr>
254        <td>X</td>
255        <td>-PI</td>
256        <td>PI</td>
257</tr><tr>
258        <td>Y</td>
259        <td>-PI/2</td>
260        <td>PI/2</td>
261</tr><tr>
262        <td>Z</td>
263        <td>-PI</td>
264        <td>PI</td>
265</tr>
266</table>
267</li>
268</ul>
269
270*/
271class btGeneric6DofConstraint : public btTypedConstraint
272{
273protected:
274
275        //! relative_frames
276    //!@{
277        btTransform     m_frameInA;//!< the constraint space w.r.t body A
278    btTransform m_frameInB;//!< the constraint space w.r.t body B
279    //!@}
280
281    //! Jacobians
282    //!@{
283    btJacobianEntry     m_jacLinear[3];//!< 3 orthogonal linear constraints
284    btJacobianEntry     m_jacAng[3];//!< 3 orthogonal angular constraints
285    //!@}
286
287        //! Linear_Limit_parameters
288    //!@{
289    btTranslationalLimitMotor m_linearLimits;
290    //!@}
291
292
293    //! hinge_parameters
294    //!@{
295    btRotationalLimitMotor m_angularLimits[3];
296        //!@}
297
298
299protected:
300    //! temporal variables
301    //!@{
302    btScalar m_timeStep;
303    btTransform m_calculatedTransformA;
304    btTransform m_calculatedTransformB;
305    btVector3 m_calculatedAxisAngleDiff;
306    btVector3 m_calculatedAxis[3];
307    btVector3 m_calculatedLinearDiff;
308        btScalar        m_factA;
309        btScalar        m_factB;
310        bool            m_hasStaticBody;
311   
312        btVector3 m_AnchorPos; // point betwen pivots of bodies A and B to solve linear axes
313
314    bool        m_useLinearReferenceFrameA;
315        bool    m_useOffsetForConstraintFrame;
316   
317        int             m_flags;
318
319    //!@}
320
321    btGeneric6DofConstraint&    operator=(btGeneric6DofConstraint&      other)
322    {
323        btAssert(0);
324        (void) other;
325        return *this;
326    }
327
328
329        int setAngularLimits(btConstraintInfo2 *info, int row_offset,const btTransform& transA,const btTransform& transB,const btVector3& linVelA,const btVector3& linVelB,const btVector3& angVelA,const btVector3& angVelB);
330
331        int setLinearLimits(btConstraintInfo2 *info, int row, const btTransform& transA,const btTransform& transB,const btVector3& linVelA,const btVector3& linVelB,const btVector3& angVelA,const btVector3& angVelB);
332
333    void buildLinearJacobian(
334        btJacobianEntry & jacLinear,const btVector3 & normalWorld,
335        const btVector3 & pivotAInW,const btVector3 & pivotBInW);
336
337    void buildAngularJacobian(btJacobianEntry & jacAngular,const btVector3 & jointAxisW);
338
339        // tests linear limits
340        void calculateLinearInfo();
341
342        //! calcs the euler angles between the two bodies.
343    void calculateAngleInfo();
344
345
346
347public:
348
349        ///for backwards compatibility during the transition to 'getInfo/getInfo2'
350        bool            m_useSolveConstraintObsolete;
351
352    btGeneric6DofConstraint(btRigidBody& rbA, btRigidBody& rbB, const btTransform& frameInA, const btTransform& frameInB ,bool useLinearReferenceFrameA);
353    btGeneric6DofConstraint(btRigidBody& rbB, const btTransform& frameInB, bool useLinearReferenceFrameB);
354   
355        //! Calcs global transform of the offsets
356        /*!
357        Calcs the global transform for the joint offset for body A an B, and also calcs the agle differences between the bodies.
358        \sa btGeneric6DofConstraint.getCalculatedTransformA , btGeneric6DofConstraint.getCalculatedTransformB, btGeneric6DofConstraint.calculateAngleInfo
359        */
360    void calculateTransforms(const btTransform& transA,const btTransform& transB);
361
362        void calculateTransforms();
363
364        //! Gets the global transform of the offset for body A
365    /*!
366    \sa btGeneric6DofConstraint.getFrameOffsetA, btGeneric6DofConstraint.getFrameOffsetB, btGeneric6DofConstraint.calculateAngleInfo.
367    */
368    const btTransform & getCalculatedTransformA() const
369    {
370        return m_calculatedTransformA;
371    }
372
373    //! Gets the global transform of the offset for body B
374    /*!
375    \sa btGeneric6DofConstraint.getFrameOffsetA, btGeneric6DofConstraint.getFrameOffsetB, btGeneric6DofConstraint.calculateAngleInfo.
376    */
377    const btTransform & getCalculatedTransformB() const
378    {
379        return m_calculatedTransformB;
380    }
381
382    const btTransform & getFrameOffsetA() const
383    {
384        return m_frameInA;
385    }
386
387    const btTransform & getFrameOffsetB() const
388    {
389        return m_frameInB;
390    }
391
392
393    btTransform & getFrameOffsetA()
394    {
395        return m_frameInA;
396    }
397
398    btTransform & getFrameOffsetB()
399    {
400        return m_frameInB;
401    }
402
403
404        //! performs Jacobian calculation, and also calculates angle differences and axis
405    virtual void        buildJacobian();
406
407        virtual void getInfo1 (btConstraintInfo1* info);
408
409        void getInfo1NonVirtual (btConstraintInfo1* info);
410
411        virtual void getInfo2 (btConstraintInfo2* info);
412
413        void getInfo2NonVirtual (btConstraintInfo2* info,const btTransform& transA,const btTransform& transB,const btVector3& linVelA,const btVector3& linVelB,const btVector3& angVelA,const btVector3& angVelB);
414
415
416    void        updateRHS(btScalar      timeStep);
417
418        //! Get the rotation axis in global coordinates
419        /*!
420        \pre btGeneric6DofConstraint.buildJacobian must be called previously.
421        */
422    btVector3 getAxis(int axis_index) const;
423
424    //! Get the relative Euler angle
425    /*!
426        \pre btGeneric6DofConstraint::calculateTransforms() must be called previously.
427        */
428    btScalar getAngle(int axis_index) const;
429
430        //! Get the relative position of the constraint pivot
431    /*!
432        \pre btGeneric6DofConstraint::calculateTransforms() must be called previously.
433        */
434        btScalar getRelativePivotPosition(int axis_index) const;
435
436
437        //! Test angular limit.
438        /*!
439        Calculates angular correction and returns true if limit needs to be corrected.
440        \pre btGeneric6DofConstraint::calculateTransforms() must be called previously.
441        */
442    bool testAngularLimitMotor(int axis_index);
443
444    void        setLinearLowerLimit(const btVector3& linearLower)
445    {
446        m_linearLimits.m_lowerLimit = linearLower;
447    }
448
449    void        setLinearUpperLimit(const btVector3& linearUpper)
450    {
451        m_linearLimits.m_upperLimit = linearUpper;
452    }
453
454    void        setAngularLowerLimit(const btVector3& angularLower)
455    {
456                for(int i = 0; i < 3; i++) 
457                        m_angularLimits[i].m_loLimit = btNormalizeAngle(angularLower[i]);
458    }
459
460    void        setAngularUpperLimit(const btVector3& angularUpper)
461    {
462                for(int i = 0; i < 3; i++)
463                        m_angularLimits[i].m_hiLimit = btNormalizeAngle(angularUpper[i]);
464    }
465
466        //! Retrieves the angular limit informacion
467    btRotationalLimitMotor * getRotationalLimitMotor(int index)
468    {
469        return &m_angularLimits[index];
470    }
471
472    //! Retrieves the  limit informacion
473    btTranslationalLimitMotor * getTranslationalLimitMotor()
474    {
475        return &m_linearLimits;
476    }
477
478    //first 3 are linear, next 3 are angular
479    void setLimit(int axis, btScalar lo, btScalar hi)
480    {
481        if(axis<3)
482        {
483                m_linearLimits.m_lowerLimit[axis] = lo;
484                m_linearLimits.m_upperLimit[axis] = hi;
485        }
486        else
487        {
488                        lo = btNormalizeAngle(lo);
489                        hi = btNormalizeAngle(hi);
490                m_angularLimits[axis-3].m_loLimit = lo;
491                m_angularLimits[axis-3].m_hiLimit = hi;
492        }
493    }
494
495        //! Test limit
496        /*!
497    - free means upper < lower,
498    - locked means upper == lower
499    - limited means upper > lower
500    - limitIndex: first 3 are linear, next 3 are angular
501    */
502    bool        isLimited(int limitIndex)
503    {
504        if(limitIndex<3)
505        {
506                        return m_linearLimits.isLimited(limitIndex);
507
508        }
509        return m_angularLimits[limitIndex-3].isLimited();
510    }
511
512        virtual void calcAnchorPos(void); // overridable
513
514        int get_limit_motor_info2(      btRotationalLimitMotor * limot,
515                                                                const btTransform& transA,const btTransform& transB,const btVector3& linVelA,const btVector3& linVelB,const btVector3& angVelA,const btVector3& angVelB,
516                                                                btConstraintInfo2 *info, int row, btVector3& ax1, int rotational, int rotAllowed = false);
517
518        // access for UseFrameOffset
519        bool getUseFrameOffset() { return m_useOffsetForConstraintFrame; }
520        void setUseFrameOffset(bool frameOffsetOnOff) { m_useOffsetForConstraintFrame = frameOffsetOnOff; }
521
522        ///override the default global value of a parameter (such as ERP or CFM), optionally provide the axis (0..5).
523        ///If no axis is provided, it uses the default axis for this constraint.
524        virtual void setParam(int num, btScalar value, int axis = -1);
525        ///return the local value of parameter
526        virtual btScalar getParam(int num, int axis = -1) const;
527
528        virtual int     calculateSerializeBufferSize() const;
529
530        ///fills the dataBuffer and returns the struct name (and 0 on failure)
531        virtual const char*     serialize(void* dataBuffer, btSerializer* serializer) const;
532
533       
534};
535
536///do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64
537struct btGeneric6DofConstraintData
538{
539        btTypedConstraintData   m_typeConstraintData;
540        btTransformFloatData m_rbAFrame; // constraint axii. Assumes z is hinge axis.
541        btTransformFloatData m_rbBFrame;
542       
543        btVector3FloatData      m_linearUpperLimit;
544        btVector3FloatData      m_linearLowerLimit;
545
546        btVector3FloatData      m_angularUpperLimit;
547        btVector3FloatData      m_angularLowerLimit;
548       
549        int     m_useLinearReferenceFrameA;
550        int m_useOffsetForConstraintFrame;
551};
552
553SIMD_FORCE_INLINE       int     btGeneric6DofConstraint::calculateSerializeBufferSize() const
554{
555        return sizeof(btGeneric6DofConstraintData);
556}
557
558        ///fills the dataBuffer and returns the struct name (and 0 on failure)
559SIMD_FORCE_INLINE       const char*     btGeneric6DofConstraint::serialize(void* dataBuffer, btSerializer* serializer) const
560{
561
562        btGeneric6DofConstraintData* dof = (btGeneric6DofConstraintData*)dataBuffer;
563        btTypedConstraint::serialize(&dof->m_typeConstraintData,serializer);
564
565        m_frameInA.serializeFloat(dof->m_rbAFrame);
566        m_frameInB.serializeFloat(dof->m_rbBFrame);
567
568               
569        int i;
570        for (i=0;i<3;i++)
571        {
572                dof->m_angularLowerLimit.m_floats[i] =  float(m_angularLimits[i].m_loLimit);
573                dof->m_angularUpperLimit.m_floats[i] =  float(m_angularLimits[i].m_hiLimit);
574                dof->m_linearLowerLimit.m_floats[i] = float(m_linearLimits.m_lowerLimit[i]);
575                dof->m_linearUpperLimit.m_floats[i] = float(m_linearLimits.m_upperLimit[i]);
576        }
577       
578        dof->m_useLinearReferenceFrameA = m_useLinearReferenceFrameA? 1 : 0;
579        dof->m_useOffsetForConstraintFrame = m_useOffsetForConstraintFrame ? 1 : 0;
580
581        return "btGeneric6DofConstraintData";
582}
583
584
585
586
587
588#endif //GENERIC_6DOF_CONSTRAINT_H
Note: See TracBrowser for help on using the repository browser.