Blender V4.3
btGeneric6DofConstraint.h
Go to the documentation of this file.
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
18
19/*
202007-09-09
21btGeneric6DofConstraint Refactored by Francisco Le?n
22email: projectileman@yahoo.com
23http://gimpact.sf.net
24*/
25
26#ifndef BT_GENERIC_6DOF_CONSTRAINT_H
27#define BT_GENERIC_6DOF_CONSTRAINT_H
28
30#include "btJacobianEntry.h"
31#include "btTypedConstraint.h"
32
33class btRigidBody;
34
35#ifdef BT_USE_DOUBLE_PRECISION
36#define btGeneric6DofConstraintData2 btGeneric6DofConstraintDoubleData2
37#define btGeneric6DofConstraintDataName "btGeneric6DofConstraintDoubleData2"
38#else
39#define btGeneric6DofConstraintData2 btGeneric6DofConstraintData
40#define btGeneric6DofConstraintDataName "btGeneric6DofConstraintData"
41#endif //BT_USE_DOUBLE_PRECISION
42
45{
46public:
61
63
71
73 {
76 m_maxMotorForce = 6.0f;
77 m_maxLimitForce = 300.0f;
78 m_loLimit = 1.0f;
79 m_hiLimit = -1.0f;
80 m_normalCFM = 0.f;
81 m_stopERP = 0.2f;
82 m_stopCFM = 0.f;
83 m_bounce = 0.0f;
84 m_damping = 1.0f;
85 m_limitSoftness = 0.5f;
88 m_enableMotor = false;
89 }
90
106
108 bool isLimited() const
109 {
110 if (m_loLimit > m_hiLimit) return false;
111 return true;
112 }
113
115 bool needApplyTorques() const
116 {
117 if (m_currentLimit == 0 && m_enableMotor == false) return false;
118 return true;
119 }
120
122
125 int testLimitValue(btScalar test_value);
126
128 btScalar solveAngularLimits(btScalar timeStep, btVector3& axis, btScalar jacDiagABInv, btRigidBody* body0, btRigidBody* body1);
129};
130
132{
133public:
134 btVector3 m_lowerLimit;
135 btVector3 m_upperLimit;
142 btVector3 m_normalCFM;
143 btVector3 m_stopERP;
144 btVector3 m_stopCFM;
148 btVector3 m_maxMotorForce;
152
154 {
155 m_lowerLimit.setValue(0.f, 0.f, 0.f);
156 m_upperLimit.setValue(0.f, 0.f, 0.f);
157 m_accumulatedImpulse.setValue(0.f, 0.f, 0.f);
158 m_normalCFM.setValue(0.f, 0.f, 0.f);
159 m_stopERP.setValue(0.2f, 0.2f, 0.2f);
160 m_stopCFM.setValue(0.f, 0.f, 0.f);
161
162 m_limitSoftness = 0.7f;
163 m_damping = btScalar(1.0f);
164 m_restitution = btScalar(0.5f);
165 for (int i = 0; i < 3; i++)
166 {
167 m_enableMotor[i] = false;
168 m_targetVelocity[i] = btScalar(0.f);
169 m_maxMotorForce[i] = btScalar(0.f);
170 }
171 }
172
174 {
175 m_lowerLimit = other.m_lowerLimit;
176 m_upperLimit = other.m_upperLimit;
177 m_accumulatedImpulse = other.m_accumulatedImpulse;
178
179 m_limitSoftness = other.m_limitSoftness;
180 m_damping = other.m_damping;
181 m_restitution = other.m_restitution;
182 m_normalCFM = other.m_normalCFM;
183 m_stopERP = other.m_stopERP;
184 m_stopCFM = other.m_stopCFM;
185
186 for (int i = 0; i < 3; i++)
187 {
188 m_enableMotor[i] = other.m_enableMotor[i];
189 m_targetVelocity[i] = other.m_targetVelocity[i];
190 m_maxMotorForce[i] = other.m_maxMotorForce[i];
191 }
192 }
193
195
201 inline bool isLimited(int limitIndex) const
202 {
203 return (m_upperLimit[limitIndex] >= m_lowerLimit[limitIndex]);
204 }
205 inline bool needApplyForce(int limitIndex) const
206 {
207 if (m_currentLimit[limitIndex] == 0 && m_enableMotor[limitIndex] == false) return false;
208 return true;
209 }
210 int testLimitValue(int limitIndex, btScalar test_value);
211
213 btScalar timeStep,
214 btScalar jacDiagABInv,
215 btRigidBody& body1, const btVector3& pointInA,
216 btRigidBody& body2, const btVector3& pointInB,
217 int limit_index,
218 const btVector3& axis_normal_on_a,
219 const btVector3& anchorPos);
220};
221
228#define BT_6DOF_FLAGS_AXIS_SHIFT 3 // bits per axis
229
231
267btGeneric6DofConstraint : public btTypedConstraint
268{
269protected:
275
281
286
291
292protected:
299 btVector3 m_calculatedAxis[3];
304
305 btVector3 m_AnchorPos; // point betwen pivots of bodies A and B to solve linear axes
306
309
311
313
315 {
316 btAssert(0);
317 (void)other;
318 return *this;
319 }
320
321 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);
322
323 int setLinearLimits(btConstraintInfo2 * info, int row, const btTransform& transA, const btTransform& transB, const btVector3& linVelA, const btVector3& linVelB, const btVector3& angVelA, const btVector3& angVelB);
324
326 btJacobianEntry & jacLinear, const btVector3& normalWorld,
327 const btVector3& pivotAInW, const btVector3& pivotBInW);
328
329 void buildAngularJacobian(btJacobianEntry & jacAngular, const btVector3& jointAxisW);
330
331 // tests linear limits
332 void calculateLinearInfo();
333
335 void calculateAngleInfo();
336
337public:
339
342
343 btGeneric6DofConstraint(btRigidBody & rbA, btRigidBody & rbB, const btTransform& frameInA, const btTransform& frameInB, bool useLinearReferenceFrameA);
344 btGeneric6DofConstraint(btRigidBody & rbB, const btTransform& frameInB, bool useLinearReferenceFrameB);
345
347
351 void calculateTransforms(const btTransform& transA, const btTransform& transB);
352
353 void calculateTransforms();
354
356
360 {
362 }
363
365
369 {
371 }
372
374 {
375 return m_frameInA;
376 }
377
379 {
380 return m_frameInB;
381 }
382
384 {
385 return m_frameInA;
386 }
387
389 {
390 return m_frameInB;
391 }
392
394 virtual void buildJacobian();
395
396 virtual void getInfo1(btConstraintInfo1 * info);
397
399
400 virtual void getInfo2(btConstraintInfo2 * info);
401
402 void getInfo2NonVirtual(btConstraintInfo2 * info, const btTransform& transA, const btTransform& transB, const btVector3& linVelA, const btVector3& linVelB, const btVector3& angVelA, const btVector3& angVelB);
403
404 void updateRHS(btScalar timeStep);
405
407
410 btVector3 getAxis(int axis_index) const;
411
413
416 btScalar getAngle(int axis_index) const;
417
419
422 btScalar getRelativePivotPosition(int axis_index) const;
423
424 void setFrames(const btTransform& frameA, const btTransform& frameB);
425
427
431 bool testAngularLimitMotor(int axis_index);
432
433 void setLinearLowerLimit(const btVector3& linearLower)
434 {
435 m_linearLimits.m_lowerLimit = linearLower;
436 }
437
438 void getLinearLowerLimit(btVector3 & linearLower) const
439 {
440 linearLower = m_linearLimits.m_lowerLimit;
441 }
442
443 void setLinearUpperLimit(const btVector3& linearUpper)
444 {
445 m_linearLimits.m_upperLimit = linearUpper;
446 }
447
448 void getLinearUpperLimit(btVector3 & linearUpper) const
449 {
450 linearUpper = m_linearLimits.m_upperLimit;
451 }
452
453 void setAngularLowerLimit(const btVector3& angularLower)
454 {
455 for (int i = 0; i < 3; i++)
456 m_angularLimits[i].m_loLimit = btNormalizeAngle(angularLower[i]);
457 }
458
459 void getAngularLowerLimit(btVector3 & angularLower) const
460 {
461 for (int i = 0; i < 3; i++)
462 angularLower[i] = m_angularLimits[i].m_loLimit;
463 }
464
465 void setAngularUpperLimit(const btVector3& angularUpper)
466 {
467 for (int i = 0; i < 3; i++)
468 m_angularLimits[i].m_hiLimit = btNormalizeAngle(angularUpper[i]);
469 }
470
471 void getAngularUpperLimit(btVector3 & angularUpper) const
472 {
473 for (int i = 0; i < 3; i++)
474 angularUpper[i] = m_angularLimits[i].m_hiLimit;
475 }
476
479 {
480 return &m_angularLimits[index];
481 }
482
488
489 //first 3 are linear, next 3 are angular
490 void setLimit(int axis, btScalar lo, btScalar hi)
491 {
492 if (axis < 3)
493 {
494 m_linearLimits.m_lowerLimit[axis] = lo;
495 m_linearLimits.m_upperLimit[axis] = hi;
496 }
497 else
498 {
499 lo = btNormalizeAngle(lo);
500 hi = btNormalizeAngle(hi);
501 m_angularLimits[axis - 3].m_loLimit = lo;
502 m_angularLimits[axis - 3].m_hiLimit = hi;
503 }
504 }
505
507
513 bool isLimited(int limitIndex) const
514 {
515 if (limitIndex < 3)
516 {
517 return m_linearLimits.isLimited(limitIndex);
518 }
519 return m_angularLimits[limitIndex - 3].isLimited();
520 }
521
522 virtual void calcAnchorPos(void); // overridable
523
525 const btTransform& transA, const btTransform& transB, const btVector3& linVelA, const btVector3& linVelB, const btVector3& angVelA, const btVector3& angVelB,
526 btConstraintInfo2* info, int row, btVector3& ax1, int rotational, int rotAllowed = false);
527
528 // access for UseFrameOffset
530 void setUseFrameOffset(bool frameOffsetOnOff) { m_useOffsetForConstraintFrame = frameOffsetOnOff; }
531
533 void setUseLinearReferenceFrameA(bool linearReferenceFrameA) { m_useLinearReferenceFrameA = linearReferenceFrameA; }
534
537 virtual void setParam(int num, btScalar value, int axis = -1);
539 virtual btScalar getParam(int num, int axis = -1) const;
540
541 void setAxis(const btVector3& axis1, const btVector3& axis2);
542
543 virtual int getFlags() const
544 {
545 return m_flags;
546 }
547
548 virtual int calculateSerializeBufferSize() const;
549
551 virtual const char* serialize(void* dataBuffer, btSerializer* serializer) const;
552};
553
569
585
586SIMD_FORCE_INLINE int btGeneric6DofConstraint::calculateSerializeBufferSize() const
587{
588 return sizeof(btGeneric6DofConstraintData2);
589}
590
592SIMD_FORCE_INLINE const char* btGeneric6DofConstraint::serialize(void* dataBuffer, btSerializer* serializer) const
593{
595 btTypedConstraint::serialize(&dof->m_typeConstraintData, serializer);
596
597 m_frameInA.serialize(dof->m_rbAFrame);
598 m_frameInB.serialize(dof->m_rbBFrame);
599
600 int i;
601 for (i = 0; i < 3; i++)
602 {
603 dof->m_angularLowerLimit.m_floats[i] = m_angularLimits[i].m_loLimit;
604 dof->m_angularUpperLimit.m_floats[i] = m_angularLimits[i].m_hiLimit;
605 dof->m_linearLowerLimit.m_floats[i] = m_linearLimits.m_lowerLimit[i];
606 dof->m_linearUpperLimit.m_floats[i] = m_linearLimits.m_upperLimit[i];
607 }
608
609 dof->m_useLinearReferenceFrameA = m_useLinearReferenceFrameA ? 1 : 0;
610 dof->m_useOffsetForConstraintFrame = m_useOffsetForConstraintFrame ? 1 : 0;
611
613}
614
615#endif //BT_GENERIC_6DOF_CONSTRAINT_H
btFixedConstraint btRigidBody & rbB
btFixedConstraint btRigidBody const btTransform & frameInA
btFixedConstraint btRigidBody const btTransform const btTransform & frameInB
#define btGeneric6DofConstraintDataName
btScalar getAngle(int axis_index) const
Get the relative Euler angle.
BT_DECLARE_ALIGNED_ALLOCATOR()
void setAngularUpperLimit(const btVector3 &angularUpper)
virtual void getInfo2(btConstraintInfo2 *info)
void getInfo2NonVirtual(btConstraintInfo2 *info, const btTransform &transA, const btTransform &transB, const btVector3 &linVelA, const btVector3 &linVelB, const btVector3 &angVelA, const btVector3 &angVelB)
@ BT_6DOF_FLAGS_ERP_STOP
@ BT_6DOF_FLAGS_CFM_STOP
@ BT_6DOF_FLAGS_CFM_NORM
virtual void calcAnchorPos(void)
void setUseLinearReferenceFrameA(bool linearReferenceFrameA)
void getAngularLowerLimit(btVector3 &angularLower) const
btTransform m_calculatedTransformB
void buildLinearJacobian(btJacobianEntry &jacLinear, const btVector3 &normalWorld, const btVector3 &pivotAInW, const btVector3 &pivotBInW)
btScalar m_factA
virtual void setParam(int num, btScalar value, int axis=-1)
btScalar m_factB
#define btGeneric6DofConstraintData2
void setLinearLowerLimit(const btVector3 &linearLower)
btVector3 m_calculatedAxis[3]
void calculateLinearInfo()
virtual int calculateSerializeBufferSize() const
btVector3 m_calculatedLinearDiff
btJacobianEntry m_jacAng[3]
const btTransform & getCalculatedTransformA() const
Gets the global transform of the offset for body A.
btRotationalLimitMotor m_angularLimits[3]
void setLimit(int axis, btScalar lo, btScalar hi)
btGeneric6DofConstraint(btRigidBody &rbA, btRigidBody &rbB, const btTransform &frameInA, const btTransform &frameInB, bool useLinearReferenceFrameA)
const btTransform & getFrameOffsetA() const
btVector3 m_AnchorPos
bool m_useSolveConstraintObsolete
for backwards compatibility during the transition to 'getInfo/getInfo2'
void setUseFrameOffset(bool frameOffsetOnOff)
int setLinearLimits(btConstraintInfo2 *info, int row, const btTransform &transA, const btTransform &transB, const btVector3 &linVelA, const btVector3 &linVelB, const btVector3 &angVelA, const btVector3 &angVelB)
btJacobianEntry m_jacLinear[3]
3 orthogonal linear constraints
virtual int getFlags() const
bool isLimited(int limitIndex) const
Test limit.
btScalar getRelativePivotPosition(int axis_index) const
Get the relative position of the constraint pivot.
void setAxis(const btVector3 &axis1, const btVector3 &axis2)
bool getUseFrameOffset() const
virtual btScalar getParam(int num, int axis=-1) const
return the local value of parameter
bool getUseLinearReferenceFrameA() const
bool m_useLinearReferenceFrameA
btGeneric6DofConstraint & operator=(btGeneric6DofConstraint &other)
int get_limit_motor_info2(btRotationalLimitMotor *limot, const btTransform &transA, const btTransform &transB, const btVector3 &linVelA, const btVector3 &linVelB, const btVector3 &angVelA, const btVector3 &angVelB, btConstraintInfo2 *info, int row, btVector3 &ax1, int rotational, int rotAllowed=false)
void setLinearUpperLimit(const btVector3 &linearUpper)
btRotationalLimitMotor * getRotationalLimitMotor(int index)
Retrieves the angular limit informacion.
void getAngularUpperLimit(btVector3 &angularUpper) const
void setFrames(const btTransform &frameA, const btTransform &frameB)
btTranslationalLimitMotor m_linearLimits
btTransform m_frameInB
const btTransform & getCalculatedTransformB() const
Gets the global transform of the offset for body B.
void calculateAngleInfo()
calcs the euler angles between the two bodies.
void getLinearLowerLimit(btVector3 &linearLower) const
virtual void buildJacobian()
performs Jacobian calculation, and also calculates angle differences and axis
void buildAngularJacobian(btJacobianEntry &jacAngular, const btVector3 &jointAxisW)
void getInfo1NonVirtual(btConstraintInfo1 *info)
btScalar m_timeStep
btVector3 m_calculatedAxisAngleDiff
btVector3 getAxis(int axis_index) const
Get the rotation axis in global coordinates.
virtual void getInfo1(btConstraintInfo1 *info)
bool testAngularLimitMotor(int axis_index)
Test angular limit.
btTranslationalLimitMotor * getTranslationalLimitMotor()
Retrieves the limit informacion.
virtual const char * serialize(void *dataBuffer, btSerializer *serializer) const
fills the dataBuffer and returns the struct name (and 0 on failure)
void getLinearUpperLimit(btVector3 &linearUpper) const
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)
btTransform m_calculatedTransformA
void setAngularLowerLimit(const btVector3 &angularLower)
void calculateTransforms()
bool m_hasStaticBody
bool m_useOffsetForConstraintFrame
const btTransform & getFrameOffsetB() const
void updateRHS(btScalar timeStep)
btJacobianEntry
float btScalar
The btScalar type abstracts floating point numbers, to easily switch between double and single floati...
Definition btScalar.h:314
#define ATTRIBUTE_ALIGNED16(a)
Definition btScalar.h:285
SIMD_FORCE_INLINE btScalar btNormalizeAngle(btScalar angleInRadians)
Definition btScalar.h:781
#define SIMD_FORCE_INLINE
Definition btScalar.h:280
#define btAssert(x)
Definition btScalar.h:295
btTransform m_frameInA
btTransform
The btTransform class supports rigid transforms with only translation and rotation and no scaling/she...
Definition btTransform.h:30
Rotation Limit structure for generic joints.
btScalar m_currentPosition
How much is violated this limit.
btScalar m_targetVelocity
target motor velocity
btRotationalLimitMotor(const btRotationalLimitMotor &limot)
btScalar m_normalCFM
Relaxation factor.
btScalar m_maxMotorForce
max force on motor
btScalar m_bounce
restitution factor
btScalar m_stopERP
Error tolerance factor when joint is at limit.
bool needApplyTorques() const
Need apply correction.
bool isLimited() const
Is limited.
int testLimitValue(btScalar test_value)
calculates error
btScalar m_maxLimitForce
max force on limit
int m_currentLimit
current value of angle
btScalar solveAngularLimits(btScalar timeStep, btVector3 &axis, btScalar jacDiagABInv, btRigidBody *body0, btRigidBody *body1)
apply the correction impulses for two bodies
btScalar m_stopCFM
Constraint force mixing factor when joint is at limit.
btVector3 m_stopERP
Error tolerance factor when joint is at limit.
int m_currentLimit[3]
Current relative offset of constraint frames.
btScalar solveLinearAxis(btScalar timeStep, btScalar jacDiagABInv, btRigidBody &body1, const btVector3 &pointInA, btRigidBody &body2, const btVector3 &pointInB, int limit_index, const btVector3 &axis_normal_on_a, const btVector3 &anchorPos)
btVector3 m_maxMotorForce
max force on motor
int testLimitValue(int limitIndex, btScalar test_value)
btVector3 m_currentLinearDiff
How much is violated this limit.
btVector3 m_normalCFM
Bounce parameter for linear limit.
bool needApplyForce(int limitIndex) const
btScalar m_limitSoftness
Softness for linear limit.
btVector3 m_targetVelocity
target motor velocity
btVector3 m_lowerLimit
the constraint lower limits
btTranslationalLimitMotor(const btTranslationalLimitMotor &other)
bool isLimited(int limitIndex) const
Test limit.
btScalar m_damping
Damping for linear limit.
btVector3 m_upperLimit
the constraint upper limits
btTypedConstraintData m_typeConstraintData
btTypedConstraintDoubleData m_typeConstraintData
for serialization
this structure is not used, except for loading pre-2.82 .bullet files