Blender  V2.59
btTypedConstraint.h
Go to the documentation of this file.
00001 /*
00002 Bullet Continuous Collision Detection and Physics Library
00003 Copyright (c) 2003-2010 Erwin Coumans  http://continuousphysics.com/Bullet/
00004 
00005 This software is provided 'as-is', without any express or implied warranty.
00006 In no event will the authors be held liable for any damages arising from the use of this software.
00007 Permission is granted to anyone to use this software for any purpose, 
00008 including commercial applications, and to alter it and redistribute it freely, 
00009 subject to the following restrictions:
00010 
00011 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.
00012 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
00013 3. This notice may not be removed or altered from any source distribution.
00014 */
00015 
00016 #ifndef TYPED_CONSTRAINT_H
00017 #define TYPED_CONSTRAINT_H
00018 
00019 class btRigidBody;
00020 #include "LinearMath/btScalar.h"
00021 #include "btSolverConstraint.h"
00022 
00023 class btSerializer;
00024 
00025 //Don't change any of the existing enum values, so add enum types at the end for serialization compatibility
00026 enum btTypedConstraintType
00027 {
00028         POINT2POINT_CONSTRAINT_TYPE=3,
00029         HINGE_CONSTRAINT_TYPE,
00030         CONETWIST_CONSTRAINT_TYPE,
00031         D6_CONSTRAINT_TYPE,
00032         SLIDER_CONSTRAINT_TYPE,
00033         CONTACT_CONSTRAINT_TYPE,
00034         D6_SPRING_CONSTRAINT_TYPE,
00035         MAX_CONSTRAINT_TYPE
00036 };
00037 
00038 
00039 enum btConstraintParams
00040 {
00041         BT_CONSTRAINT_ERP=1,
00042         BT_CONSTRAINT_STOP_ERP,
00043         BT_CONSTRAINT_CFM,
00044         BT_CONSTRAINT_STOP_CFM
00045 };
00046 
00047 #if 1
00048         #define btAssertConstrParams(_par) btAssert(_par) 
00049 #else
00050         #define btAssertConstrParams(_par)
00051 #endif
00052 
00053 
00055 class btTypedConstraint : public btTypedObject
00056 {
00057         int     m_userConstraintType;
00058 
00059         union
00060         {
00061                 int     m_userConstraintId;
00062                 void* m_userConstraintPtr;
00063         };
00064 
00065         bool m_needsFeedback;
00066 
00067         btTypedConstraint&      operator=(btTypedConstraint&    other)
00068         {
00069                 btAssert(0);
00070                 (void) other;
00071                 return *this;
00072         }
00073 
00074 protected:
00075         btRigidBody&    m_rbA;
00076         btRigidBody&    m_rbB;
00077         btScalar        m_appliedImpulse;
00078         btScalar        m_dbgDrawSize;
00079 
00081         btScalar getMotorFactor(btScalar pos, btScalar lowLim, btScalar uppLim, btScalar vel, btScalar timeFact);
00082         
00083         static btRigidBody& getFixedBody();
00084 
00085 public:
00086 
00087         virtual ~btTypedConstraint() {};
00088         btTypedConstraint(btTypedConstraintType type, btRigidBody& rbA);
00089         btTypedConstraint(btTypedConstraintType type, btRigidBody& rbA,btRigidBody& rbB);
00090 
00091         struct btConstraintInfo1 {
00092                 int m_numConstraintRows,nub;
00093         };
00094 
00095         struct btConstraintInfo2 {
00096                 // integrator parameters: frames per second (1/stepsize), default error
00097                 // reduction parameter (0..1).
00098                 btScalar fps,erp;
00099 
00100                 // for the first and second body, pointers to two (linear and angular)
00101                 // n*3 jacobian sub matrices, stored by rows. these matrices will have
00102                 // been initialized to 0 on entry. if the second body is zero then the
00103                 // J2xx pointers may be 0.
00104                 btScalar *m_J1linearAxis,*m_J1angularAxis,*m_J2linearAxis,*m_J2angularAxis;
00105 
00106                 // elements to jump from one row to the next in J's
00107                 int rowskip;
00108 
00109                 // right hand sides of the equation J*v = c + cfm * lambda. cfm is the
00110                 // "constraint force mixing" vector. c is set to zero on entry, cfm is
00111                 // set to a constant value (typically very small or zero) value on entry.
00112                 btScalar *m_constraintError,*cfm;
00113 
00114                 // lo and hi limits for variables (set to -/+ infinity on entry).
00115                 btScalar *m_lowerLimit,*m_upperLimit;
00116 
00117                 // findex vector for variables. see the LCP solver interface for a
00118                 // description of what this does. this is set to -1 on entry.
00119                 // note that the returned indexes are relative to the first index of
00120                 // the constraint.
00121                 int *findex;
00122                 // number of solver iterations
00123                 int m_numIterations;
00124 
00125                 //damping of the velocity
00126                 btScalar        m_damping;
00127         };
00128 
00130         virtual void    buildJacobian() {};
00131 
00133         virtual void    setupSolverConstraint(btConstraintArray& ca, int solverBodyA,int solverBodyB, btScalar timeStep)
00134         {
00135         (void)ca;
00136         (void)solverBodyA;
00137         (void)solverBodyB;
00138         (void)timeStep;
00139         }
00140         
00142         virtual void getInfo1 (btConstraintInfo1* info)=0;
00143 
00145         virtual void getInfo2 (btConstraintInfo2* info)=0;
00146 
00148         void    internalSetAppliedImpulse(btScalar appliedImpulse)
00149         {
00150                 m_appliedImpulse = appliedImpulse;
00151         }
00153         btScalar        internalGetAppliedImpulse()
00154         {
00155                 return m_appliedImpulse;
00156         }
00157 
00159         virtual void    solveConstraintObsolete(btRigidBody& /*bodyA*/,btRigidBody& /*bodyB*/,btScalar  /*timeStep*/) {};
00160 
00161         
00162         const btRigidBody& getRigidBodyA() const
00163         {
00164                 return m_rbA;
00165         }
00166         const btRigidBody& getRigidBodyB() const
00167         {
00168                 return m_rbB;
00169         }
00170 
00171         btRigidBody& getRigidBodyA() 
00172         {
00173                 return m_rbA;
00174         }
00175         btRigidBody& getRigidBodyB()
00176         {
00177                 return m_rbB;
00178         }
00179 
00180         int getUserConstraintType() const
00181         {
00182                 return m_userConstraintType ;
00183         }
00184 
00185         void    setUserConstraintType(int userConstraintType)
00186         {
00187                 m_userConstraintType = userConstraintType;
00188         };
00189 
00190         void    setUserConstraintId(int uid)
00191         {
00192                 m_userConstraintId = uid;
00193         }
00194 
00195         int getUserConstraintId() const
00196         {
00197                 return m_userConstraintId;
00198         }
00199 
00200         void    setUserConstraintPtr(void* ptr)
00201         {
00202                 m_userConstraintPtr = ptr;
00203         }
00204 
00205         void*   getUserConstraintPtr()
00206         {
00207                 return m_userConstraintPtr;
00208         }
00209 
00210         int getUid() const
00211         {
00212                 return m_userConstraintId;   
00213         } 
00214 
00215         bool    needsFeedback() const
00216         {
00217                 return m_needsFeedback;
00218         }
00219 
00222         void    enableFeedback(bool needsFeedback)
00223         {
00224                 m_needsFeedback = needsFeedback;
00225         }
00226 
00229         btScalar        getAppliedImpulse() const
00230         {
00231                 btAssert(m_needsFeedback);
00232                 return m_appliedImpulse;
00233         }
00234 
00235         btTypedConstraintType getConstraintType () const
00236         {
00237                 return btTypedConstraintType(m_objectType);
00238         }
00239         
00240         void setDbgDrawSize(btScalar dbgDrawSize)
00241         {
00242                 m_dbgDrawSize = dbgDrawSize;
00243         }
00244         btScalar getDbgDrawSize()
00245         {
00246                 return m_dbgDrawSize;
00247         }
00248 
00251         virtual void    setParam(int num, btScalar value, int axis = -1) = 0;
00252 
00254         virtual btScalar getParam(int num, int axis = -1) const = 0;
00255         
00256         virtual int     calculateSerializeBufferSize() const;
00257 
00259         virtual const char*     serialize(void* dataBuffer, btSerializer* serializer) const;
00260 
00261 };
00262 
00263 // returns angle in range [-SIMD_2_PI, SIMD_2_PI], closest to one of the limits 
00264 // all arguments should be normalized angles (i.e. in range [-SIMD_PI, SIMD_PI])
00265 SIMD_FORCE_INLINE btScalar btAdjustAngleToLimits(btScalar angleInRadians, btScalar angleLowerLimitInRadians, btScalar angleUpperLimitInRadians)
00266 {
00267         if(angleLowerLimitInRadians >= angleUpperLimitInRadians)
00268         {
00269                 return angleInRadians;
00270         }
00271         else if(angleInRadians < angleLowerLimitInRadians)
00272         {
00273                 btScalar diffLo = btFabs(btNormalizeAngle(angleLowerLimitInRadians - angleInRadians));
00274                 btScalar diffHi = btFabs(btNormalizeAngle(angleUpperLimitInRadians - angleInRadians));
00275                 return (diffLo < diffHi) ? angleInRadians : (angleInRadians + SIMD_2_PI);
00276         }
00277         else if(angleInRadians > angleUpperLimitInRadians)
00278         {
00279                 btScalar diffHi = btFabs(btNormalizeAngle(angleInRadians - angleUpperLimitInRadians));
00280                 btScalar diffLo = btFabs(btNormalizeAngle(angleInRadians - angleLowerLimitInRadians));
00281                 return (diffLo < diffHi) ? (angleInRadians - SIMD_2_PI) : angleInRadians;
00282         }
00283         else
00284         {
00285                 return angleInRadians;
00286         }
00287 }
00288 
00290 struct  btTypedConstraintData
00291 {
00292         btRigidBodyData         *m_rbA;
00293         btRigidBodyData         *m_rbB;
00294         char    *m_name;
00295 
00296         int     m_objectType;
00297         int     m_userConstraintType;
00298         int     m_userConstraintId;
00299         int     m_needsFeedback;
00300 
00301         float   m_appliedImpulse;
00302         float   m_dbgDrawSize;
00303 
00304         int     m_disableCollisionsBetweenLinkedBodies;
00305         char    m_pad4[4];
00306         
00307 };
00308 
00309 SIMD_FORCE_INLINE       int     btTypedConstraint::calculateSerializeBufferSize() const
00310 {
00311         return sizeof(btTypedConstraintData);
00312 }
00313 
00314 
00315 
00316 class btAngularLimit
00317 {
00318 private:
00319         btScalar 
00320                 m_center,
00321                 m_halfRange,
00322                 m_softness,
00323                 m_biasFactor,
00324                 m_relaxationFactor,
00325                 m_correction,
00326                 m_sign;
00327 
00328         bool
00329                 m_solveLimit;
00330 
00331 public:
00333         btAngularLimit()
00334                 :m_center(0.0f),
00335                 m_halfRange(-1.0f),
00336                 m_softness(0.9f),
00337                 m_biasFactor(0.3f),
00338                 m_relaxationFactor(1.0f),
00339                 m_correction(0.0f),
00340                 m_sign(0.0f),
00341                 m_solveLimit(false)
00342         {}
00343 
00347         void set(btScalar low, btScalar high, btScalar _softness = 0.9f, btScalar _biasFactor = 0.3f, btScalar _relaxationFactor = 1.0f);
00348 
00351         void test(const btScalar angle);
00352 
00354         inline btScalar getSoftness() const
00355         {
00356                 return m_softness;
00357         }
00358 
00360         inline btScalar getBiasFactor() const
00361         {
00362                 return m_biasFactor;
00363         }
00364 
00366         inline btScalar getRelaxationFactor() const
00367         {
00368                 return m_relaxationFactor;
00369         }
00370 
00372         inline btScalar getCorrection() const
00373         {
00374                 return m_correction;
00375         }
00376 
00378         inline btScalar getSign() const
00379         {
00380                 return m_sign;
00381         }
00382 
00384         inline btScalar getHalfRange() const
00385         {
00386                 return m_halfRange;
00387         }
00388 
00390         inline bool isLimit() const
00391         {
00392                 return m_solveLimit;
00393         }
00394 
00397         void fit(btScalar& angle) const;
00398 
00400         btScalar getError() const;
00401 
00402         btScalar getLow() const;
00403 
00404         btScalar getHigh() const;
00405 
00406 };
00407 
00408 
00409 
00410 #endif //TYPED_CONSTRAINT_H