2 Bullet Continuous Collision Detection and Physics Library
3 Copyright (c) 2003-2010 Erwin Coumans https://bulletphysics.org
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:
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.
16 #ifndef BT_TYPED_CONSTRAINT_H
17 #define BT_TYPED_CONSTRAINT_H
19 #include "LinearMath/btScalar.h"
20 #include "btSolverConstraint.h"
21 #include "BulletDynamics/Dynamics/btRigidBody.h"
23 #ifdef BT_USE_DOUBLE_PRECISION
24 #define btTypedConstraintData2 btTypedConstraintDoubleData
25 #define btTypedConstraintDataName "btTypedConstraintDoubleData"
27 #define btTypedConstraintData2 btTypedConstraintFloatData
28 #define btTypedConstraintDataName "btTypedConstraintFloatData"
29 #endif //BT_USE_DOUBLE_PRECISION
33 //Don't change any of the existing enum values, so add enum types at the end for serialization compatibility
34 enum btTypedConstraintType
36 POINT2POINT_CONSTRAINT_TYPE = 3,
37 HINGE_CONSTRAINT_TYPE,
38 CONETWIST_CONSTRAINT_TYPE,
40 SLIDER_CONSTRAINT_TYPE,
41 CONTACT_CONSTRAINT_TYPE,
42 D6_SPRING_CONSTRAINT_TYPE,
44 FIXED_CONSTRAINT_TYPE,
45 D6_SPRING_2_CONSTRAINT_TYPE,
49 enum btConstraintParams
51 BT_CONSTRAINT_ERP = 1,
52 BT_CONSTRAINT_STOP_ERP,
54 BT_CONSTRAINT_STOP_CFM
58 #define btAssertConstrParams(_par) btAssert(_par)
60 #define btAssertConstrParams(_par)
63 ATTRIBUTE_ALIGNED16(struct)
66 BT_DECLARE_ALIGNED_ALLOCATOR();
67 btVector3 m_appliedForceBodyA;
68 btVector3 m_appliedTorqueBodyA;
69 btVector3 m_appliedForceBodyB;
70 btVector3 m_appliedTorqueBodyB;
73 ///TypedConstraint is the baseclass for Bullet constraints and vehicles
74 ATTRIBUTE_ALIGNED16(class)
75 btTypedConstraint : public btTypedObject
77 int m_userConstraintType;
80 int m_userConstraintId;
81 void* m_userConstraintPtr;
84 btScalar m_breakingImpulseThreshold;
87 int m_overrideNumSolverIterations;
89 btTypedConstraint& operator=(btTypedConstraint& other)
99 btScalar m_appliedImpulse;
100 btScalar m_dbgDrawSize;
101 btJointFeedback* m_jointFeedback;
103 ///internal method used by the constraint solver, don't use them directly
104 btScalar getMotorFactor(btScalar pos, btScalar lowLim, btScalar uppLim, btScalar vel, btScalar timeFact);
107 BT_DECLARE_ALIGNED_ALLOCATOR();
109 virtual ~btTypedConstraint(){};
110 btTypedConstraint(btTypedConstraintType type, btRigidBody & rbA);
111 btTypedConstraint(btTypedConstraintType type, btRigidBody & rbA, btRigidBody & rbB);
113 struct btConstraintInfo1
115 int m_numConstraintRows, nub;
118 static btRigidBody& getFixedBody();
120 struct btConstraintInfo2
122 // integrator parameters: frames per second (1/stepsize), default error
123 // reduction parameter (0..1).
126 // for the first and second body, pointers to two (linear and angular)
127 // n*3 jacobian sub matrices, stored by rows. these matrices will have
128 // been initialized to 0 on entry. if the second body is zero then the
129 // J2xx pointers may be 0.
130 btScalar *m_J1linearAxis, *m_J1angularAxis, *m_J2linearAxis, *m_J2angularAxis;
132 // elements to jump from one row to the next in J's
135 // right hand sides of the equation J*v = c + cfm * lambda. cfm is the
136 // "constraint force mixing" vector. c is set to zero on entry, cfm is
137 // set to a constant value (typically very small or zero) value on entry.
138 btScalar *m_constraintError, *cfm;
140 // lo and hi limits for variables (set to -/+ infinity on entry).
141 btScalar *m_lowerLimit, *m_upperLimit;
143 // number of solver iterations
146 //damping of the velocity
150 int getOverrideNumSolverIterations() const
152 return m_overrideNumSolverIterations;
155 ///override the number of constraint solver iterations used to solve this constraint
156 ///-1 will use the default number of iterations, as specified in SolverInfo.m_numIterations
157 void setOverrideNumSolverIterations(int overideNumIterations)
159 m_overrideNumSolverIterations = overideNumIterations;
162 ///internal method used by the constraint solver, don't use them directly
163 virtual void buildJacobian(){};
165 ///internal method used by the constraint solver, don't use them directly
166 virtual void setupSolverConstraint(btConstraintArray & ca, int solverBodyA, int solverBodyB, btScalar timeStep)
174 ///internal method used by the constraint solver, don't use them directly
175 virtual void getInfo1(btConstraintInfo1 * info) = 0;
177 ///internal method used by the constraint solver, don't use them directly
178 virtual void getInfo2(btConstraintInfo2 * info) = 0;
180 ///internal method used by the constraint solver, don't use them directly
181 void internalSetAppliedImpulse(btScalar appliedImpulse)
183 m_appliedImpulse = appliedImpulse;
185 ///internal method used by the constraint solver, don't use them directly
186 btScalar internalGetAppliedImpulse()
188 return m_appliedImpulse;
191 btScalar getBreakingImpulseThreshold() const
193 return m_breakingImpulseThreshold;
196 void setBreakingImpulseThreshold(btScalar threshold)
198 m_breakingImpulseThreshold = threshold;
201 bool isEnabled() const
206 void setEnabled(bool enabled)
208 m_isEnabled = enabled;
211 ///internal method used by the constraint solver, don't use them directly
212 virtual void solveConstraintObsolete(btSolverBody& /*bodyA*/, btSolverBody& /*bodyB*/, btScalar /*timeStep*/){};
214 const btRigidBody& getRigidBodyA() const
218 const btRigidBody& getRigidBodyB() const
223 btRigidBody& getRigidBodyA()
227 btRigidBody& getRigidBodyB()
232 int getUserConstraintType() const
234 return m_userConstraintType;
237 void setUserConstraintType(int userConstraintType)
239 m_userConstraintType = userConstraintType;
242 void setUserConstraintId(int uid)
244 m_userConstraintId = uid;
247 int getUserConstraintId() const
249 return m_userConstraintId;
252 void setUserConstraintPtr(void* ptr)
254 m_userConstraintPtr = ptr;
257 void* getUserConstraintPtr()
259 return m_userConstraintPtr;
262 void setJointFeedback(btJointFeedback * jointFeedback)
264 m_jointFeedback = jointFeedback;
267 const btJointFeedback* getJointFeedback() const
269 return m_jointFeedback;
272 btJointFeedback* getJointFeedback()
274 return m_jointFeedback;
279 return m_userConstraintId;
282 bool needsFeedback() const
284 return m_needsFeedback;
287 ///enableFeedback will allow to read the applied linear and angular impulse
288 ///use getAppliedImpulse, getAppliedLinearImpulse and getAppliedAngularImpulse to read feedback information
289 void enableFeedback(bool needsFeedback)
291 m_needsFeedback = needsFeedback;
294 ///getAppliedImpulse is an estimated total applied impulse.
295 ///This feedback could be used to determine breaking constraints or playing sounds.
296 btScalar getAppliedImpulse() const
298 btAssert(m_needsFeedback);
299 return m_appliedImpulse;
302 btTypedConstraintType getConstraintType() const
304 return btTypedConstraintType(m_objectType);
307 void setDbgDrawSize(btScalar dbgDrawSize)
309 m_dbgDrawSize = dbgDrawSize;
311 btScalar getDbgDrawSize()
313 return m_dbgDrawSize;
316 ///override the default global value of a parameter (such as ERP or CFM), optionally provide the axis (0..5).
317 ///If no axis is provided, it uses the default axis for this constraint.
318 virtual void setParam(int num, btScalar value, int axis = -1) = 0;
320 ///return the local value of parameter
321 virtual btScalar getParam(int num, int axis = -1) const = 0;
323 virtual int calculateSerializeBufferSize() const;
325 ///fills the dataBuffer and returns the struct name (and 0 on failure)
326 virtual const char* serialize(void* dataBuffer, btSerializer* serializer) const;
329 // returns angle in range [-SIMD_2_PI, SIMD_2_PI], closest to one of the limits
330 // all arguments should be normalized angles (i.e. in range [-SIMD_PI, SIMD_PI])
331 SIMD_FORCE_INLINE btScalar btAdjustAngleToLimits(btScalar angleInRadians, btScalar angleLowerLimitInRadians, btScalar angleUpperLimitInRadians)
333 if (angleLowerLimitInRadians >= angleUpperLimitInRadians)
335 return angleInRadians;
337 else if (angleInRadians < angleLowerLimitInRadians)
339 btScalar diffLo = btFabs(btNormalizeAngle(angleLowerLimitInRadians - angleInRadians));
340 btScalar diffHi = btFabs(btNormalizeAngle(angleUpperLimitInRadians - angleInRadians));
341 return (diffLo < diffHi) ? angleInRadians : (angleInRadians + SIMD_2_PI);
343 else if (angleInRadians > angleUpperLimitInRadians)
345 btScalar diffHi = btFabs(btNormalizeAngle(angleInRadians - angleUpperLimitInRadians));
346 btScalar diffLo = btFabs(btNormalizeAngle(angleInRadians - angleLowerLimitInRadians));
347 return (diffLo < diffHi) ? (angleInRadians - SIMD_2_PI) : angleInRadians;
351 return angleInRadians;
357 ///do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64
358 struct btTypedConstraintFloatData
360 btRigidBodyFloatData *m_rbA;
361 btRigidBodyFloatData *m_rbB;
365 int m_userConstraintType;
366 int m_userConstraintId;
369 float m_appliedImpulse;
372 int m_disableCollisionsBetweenLinkedBodies;
373 int m_overrideNumSolverIterations;
375 float m_breakingImpulseThreshold;
382 ///do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64
384 #define BT_BACKWARDS_COMPATIBLE_SERIALIZATION
385 #ifdef BT_BACKWARDS_COMPATIBLE_SERIALIZATION
386 ///this structure is not used, except for loading pre-2.82 .bullet files
387 struct btTypedConstraintData
389 btRigidBodyData *m_rbA;
390 btRigidBodyData *m_rbB;
394 int m_userConstraintType;
395 int m_userConstraintId;
398 float m_appliedImpulse;
401 int m_disableCollisionsBetweenLinkedBodies;
402 int m_overrideNumSolverIterations;
404 float m_breakingImpulseThreshold;
408 #endif //BACKWARDS_COMPATIBLE
410 struct btTypedConstraintDoubleData
412 btRigidBodyDoubleData *m_rbA;
413 btRigidBodyDoubleData *m_rbB;
417 int m_userConstraintType;
418 int m_userConstraintId;
421 double m_appliedImpulse;
422 double m_dbgDrawSize;
424 int m_disableCollisionsBetweenLinkedBodies;
425 int m_overrideNumSolverIterations;
427 double m_breakingImpulseThreshold;
435 SIMD_FORCE_INLINE int btTypedConstraint::calculateSerializeBufferSize() const
437 return sizeof(btTypedConstraintData2);
456 /// Default constructor initializes limit as inactive, allowing free constraint movement
462 m_relaxationFactor(1.0f),
469 /// Sets all limit's parameters.
470 /// When low > high limit becomes inactive.
471 /// When high - low > 2PI limit is ineffective too becouse no angle can exceed the limit
472 void set(btScalar low, btScalar high, btScalar _softness = 0.9f, btScalar _biasFactor = 0.3f, btScalar _relaxationFactor = 1.0f);
474 /// Checks conastaint angle against limit. If limit is active and the angle violates the limit
475 /// correction is calculated.
476 void test(const btScalar angle);
478 /// Returns limit's softness
479 inline btScalar getSoftness() const
484 /// Returns limit's bias factor
485 inline btScalar getBiasFactor() const
490 /// Returns limit's relaxation factor
491 inline btScalar getRelaxationFactor() const
493 return m_relaxationFactor;
496 /// Returns correction value evaluated when test() was invoked
497 inline btScalar getCorrection() const
502 /// Returns sign value evaluated when test() was invoked
503 inline btScalar getSign() const
508 /// Gives half of the distance between min and max limit angle
509 inline btScalar getHalfRange() const
514 /// Returns true when the last test() invocation recognized limit violation
515 inline bool isLimit() const
520 /// Checks given angle against limit. If limit is active and angle doesn't fit it, the angle
521 /// returned is modified so it equals to the limit closest to given angle.
522 void fit(btScalar& angle) const;
524 /// Returns correction value multiplied by sign value
525 btScalar getError() const;
527 btScalar getLow() const;
529 btScalar getHigh() const;
532 #endif //BT_TYPED_CONSTRAINT_H