Blender V2.61 - r43446

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