00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
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 #include "BulletCollision/NarrowPhaseCollision/btPersistentManifold.h"
00023
00024 class btSerializer;
00025
00026 enum btTypedConstraintType
00027 {
00028 POINT2POINT_CONSTRAINT_TYPE=MAX_CONTACT_MANIFOLD_TYPE+1,
00029 HINGE_CONSTRAINT_TYPE,
00030 CONETWIST_CONSTRAINT_TYPE,
00031 D6_CONSTRAINT_TYPE,
00032 SLIDER_CONSTRAINT_TYPE,
00033 CONTACT_CONSTRAINT_TYPE
00034 };
00035
00036
00037 enum btConstraintParams
00038 {
00039 BT_CONSTRAINT_ERP=1,
00040 BT_CONSTRAINT_STOP_ERP,
00041 BT_CONSTRAINT_CFM,
00042 BT_CONSTRAINT_STOP_CFM
00043 };
00044
00045 #if 1
00046 #define btAssertConstrParams(_par) btAssert(_par)
00047 #else
00048 #define btAssertConstrParams(_par)
00049 #endif
00050
00051
00053 class btTypedConstraint : public btTypedObject
00054 {
00055 int m_userConstraintType;
00056 int m_userConstraintId;
00057 bool m_needsFeedback;
00058
00059 btTypedConstraint& operator=(btTypedConstraint& other)
00060 {
00061 btAssert(0);
00062 (void) other;
00063 return *this;
00064 }
00065
00066 protected:
00067 btRigidBody& m_rbA;
00068 btRigidBody& m_rbB;
00069 btScalar m_appliedImpulse;
00070 btScalar m_dbgDrawSize;
00071
00073 btScalar getMotorFactor(btScalar pos, btScalar lowLim, btScalar uppLim, btScalar vel, btScalar timeFact);
00074
00075 static btRigidBody& getFixedBody()
00076 {
00077 static btRigidBody s_fixed(0, 0,0);
00078 s_fixed.setMassProps(btScalar(0.),btVector3(btScalar(0.),btScalar(0.),btScalar(0.)));
00079 return s_fixed;
00080 }
00081
00082
00083 public:
00084
00085 virtual ~btTypedConstraint() {};
00086 btTypedConstraint(btTypedConstraintType type, btRigidBody& rbA);
00087 btTypedConstraint(btTypedConstraintType type, btRigidBody& rbA,btRigidBody& rbB);
00088
00089 struct btConstraintInfo1 {
00090 int m_numConstraintRows,nub;
00091 };
00092
00093 struct btConstraintInfo2 {
00094
00095
00096 btScalar fps,erp;
00097
00098
00099
00100
00101
00102 btScalar *m_J1linearAxis,*m_J1angularAxis,*m_J2linearAxis,*m_J2angularAxis;
00103
00104
00105 int rowskip;
00106
00107
00108
00109
00110 btScalar *m_constraintError,*cfm;
00111
00112
00113 btScalar *m_lowerLimit,*m_upperLimit;
00114
00115
00116
00117
00118
00119 int *findex;
00120
00121 int m_numIterations;
00122 };
00123
00125 virtual void buildJacobian() {};
00126
00128 virtual void setupSolverConstraint(btConstraintArray& ca, int solverBodyA,int solverBodyB, btScalar timeStep)
00129 {
00130 (void)ca;
00131 (void)solverBodyA;
00132 (void)solverBodyB;
00133 (void)timeStep;
00134 }
00135
00137 virtual void getInfo1 (btConstraintInfo1* info)=0;
00138
00140 virtual void getInfo2 (btConstraintInfo2* info)=0;
00141
00143 void internalSetAppliedImpulse(btScalar appliedImpulse)
00144 {
00145 m_appliedImpulse = appliedImpulse;
00146 }
00148 btScalar internalGetAppliedImpulse()
00149 {
00150 return m_appliedImpulse;
00151 }
00152
00154 virtual void solveConstraintObsolete(btRigidBody& bodyA,btRigidBody& bodyB,btScalar timeStep) {};
00155
00156
00157 const btRigidBody& getRigidBodyA() const
00158 {
00159 return m_rbA;
00160 }
00161 const btRigidBody& getRigidBodyB() const
00162 {
00163 return m_rbB;
00164 }
00165
00166 btRigidBody& getRigidBodyA()
00167 {
00168 return m_rbA;
00169 }
00170 btRigidBody& getRigidBodyB()
00171 {
00172 return m_rbB;
00173 }
00174
00175 int getUserConstraintType() const
00176 {
00177 return m_userConstraintType ;
00178 }
00179
00180 void setUserConstraintType(int userConstraintType)
00181 {
00182 m_userConstraintType = userConstraintType;
00183 };
00184
00185 void setUserConstraintId(int uid)
00186 {
00187 m_userConstraintId = uid;
00188 }
00189
00190 int getUserConstraintId() const
00191 {
00192 return m_userConstraintId;
00193 }
00194
00195 int getUid() const
00196 {
00197 return m_userConstraintId;
00198 }
00199
00200 bool needsFeedback() const
00201 {
00202 return m_needsFeedback;
00203 }
00204
00207 void enableFeedback(bool needsFeedback)
00208 {
00209 m_needsFeedback = needsFeedback;
00210 }
00211
00214 btScalar getAppliedImpulse() const
00215 {
00216 btAssert(m_needsFeedback);
00217 return m_appliedImpulse;
00218 }
00219
00220 btTypedConstraintType getConstraintType () const
00221 {
00222 return btTypedConstraintType(m_objectType);
00223 }
00224
00225 void setDbgDrawSize(btScalar dbgDrawSize)
00226 {
00227 m_dbgDrawSize = dbgDrawSize;
00228 }
00229 btScalar getDbgDrawSize()
00230 {
00231 return m_dbgDrawSize;
00232 }
00233
00236 virtual void setParam(int num, btScalar value, int axis = -1) = 0;
00237
00239 virtual btScalar getParam(int num, int axis = -1) const = 0;
00240
00241 virtual int calculateSerializeBufferSize() const;
00242
00244 virtual const char* serialize(void* dataBuffer, btSerializer* serializer) const;
00245
00246 };
00247
00248
00249
00250 SIMD_FORCE_INLINE btScalar btAdjustAngleToLimits(btScalar angleInRadians, btScalar angleLowerLimitInRadians, btScalar angleUpperLimitInRadians)
00251 {
00252 if(angleLowerLimitInRadians >= angleUpperLimitInRadians)
00253 {
00254 return angleInRadians;
00255 }
00256 else if(angleInRadians < angleLowerLimitInRadians)
00257 {
00258 btScalar diffLo = btNormalizeAngle(angleLowerLimitInRadians - angleInRadians);
00259 btScalar diffHi = btFabs(btNormalizeAngle(angleUpperLimitInRadians - angleInRadians));
00260 return (diffLo < diffHi) ? angleInRadians : (angleInRadians + SIMD_2_PI);
00261 }
00262 else if(angleInRadians > angleUpperLimitInRadians)
00263 {
00264 btScalar diffHi = btNormalizeAngle(angleInRadians - angleUpperLimitInRadians);
00265 btScalar diffLo = btFabs(btNormalizeAngle(angleInRadians - angleLowerLimitInRadians));
00266 return (diffLo < diffHi) ? (angleInRadians - SIMD_2_PI) : angleInRadians;
00267 }
00268 else
00269 {
00270 return angleInRadians;
00271 }
00272 }
00273
00275 struct btTypedConstraintData
00276 {
00277 btRigidBodyData *m_rbA;
00278 btRigidBodyData *m_rbB;
00279 char *m_name;
00280
00281 int m_objectType;
00282 int m_userConstraintType;
00283 int m_userConstraintId;
00284 int m_needsFeedback;
00285
00286 float m_appliedImpulse;
00287 float m_dbgDrawSize;
00288
00289 int m_disableCollisionsBetweenLinkedBodies;
00290 char m_pad4[4];
00291
00292 };
00293
00294 SIMD_FORCE_INLINE int btTypedConstraint::calculateSerializeBufferSize() const
00295 {
00296 return sizeof(btTypedConstraintData);
00297 }
00298
00299
00300
00301
00302 #endif //TYPED_CONSTRAINT_H