Bullet Collision Detection & Physics Library
btHingeConstraint.h
Go to the documentation of this file.
1 /*
2 Bullet Continuous Collision Detection and Physics Library
3 Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
4 
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:
10 
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.
14 */
15 
16 /* Hinge Constraint by Dirk Gregorius. Limits added by Marcus Hennix at Starbreeze Studios */
17 
18 #ifndef BT_HINGECONSTRAINT_H
19 #define BT_HINGECONSTRAINT_H
20 
21 #define _BT_USE_CENTER_LIMIT_ 1
22 
23 #include "LinearMath/btVector3.h"
24 #include "btJacobianEntry.h"
25 #include "btTypedConstraint.h"
26 
27 class btRigidBody;
28 
29 #ifdef BT_USE_DOUBLE_PRECISION
30 #define btHingeConstraintData btHingeConstraintDoubleData2 //rename to 2 for backwards compatibility, so we can still load the 'btHingeConstraintDoubleData' version
31 #define btHingeConstraintDataName "btHingeConstraintDoubleData2"
32 #else
33 #define btHingeConstraintData btHingeConstraintFloatData
34 #define btHingeConstraintDataName "btHingeConstraintFloatData"
35 #endif //BT_USE_DOUBLE_PRECISION
36 
38 {
43 };
44 
49 {
50 #ifdef IN_PARALLELL_SOLVER
51 public:
52 #endif
53  btJacobianEntry m_jac[3]; //3 orthogonal linear constraints
54  btJacobianEntry m_jacAng[3]; //2 orthogonal angular constraints+ 1 for limit/motor
55 
56  btTransform m_rbAFrame; // constraint axii. Assumes z is hinge axis.
58 
61 
62 #ifdef _BT_USE_CENTER_LIMIT_
64 #else
65  btScalar m_lowerLimit;
66  btScalar m_upperLimit;
67  btScalar m_limitSign;
68  btScalar m_correction;
69 
70  btScalar m_limitSoftness;
71  btScalar m_biasFactor;
72  btScalar m_relaxationFactor;
73 
74  bool m_solveLimit;
75 #endif
76 
78 
82 
88 
90 
91  int m_flags;
96 
97 public:
99 
100  btHingeConstraint(btRigidBody & rbA, btRigidBody & rbB, const btVector3& pivotInA, const btVector3& pivotInB, const btVector3& axisInA, const btVector3& axisInB, bool useReferenceFrameA = false);
101 
102  btHingeConstraint(btRigidBody & rbA, const btVector3& pivotInA, const btVector3& axisInA, bool useReferenceFrameA = false);
103 
104  btHingeConstraint(btRigidBody & rbA, btRigidBody & rbB, const btTransform& rbAFrame, const btTransform& rbBFrame, bool useReferenceFrameA = false);
105 
106  btHingeConstraint(btRigidBody & rbA, const btTransform& rbAFrame, bool useReferenceFrameA = false);
107 
108  virtual void buildJacobian();
109 
110  virtual void getInfo1(btConstraintInfo1 * info);
111 
112  void getInfo1NonVirtual(btConstraintInfo1 * info);
113 
114  virtual void getInfo2(btConstraintInfo2 * info);
115 
116  void getInfo2NonVirtual(btConstraintInfo2 * info, const btTransform& transA, const btTransform& transB, const btVector3& angVelA, const btVector3& angVelB);
117 
118  void getInfo2Internal(btConstraintInfo2 * info, const btTransform& transA, const btTransform& transB, const btVector3& angVelA, const btVector3& angVelB);
119  void getInfo2InternalUsingFrameOffset(btConstraintInfo2 * info, const btTransform& transA, const btTransform& transB, const btVector3& angVelA, const btVector3& angVelB);
120 
121  void updateRHS(btScalar timeStep);
122 
123  const btRigidBody& getRigidBodyA() const
124  {
125  return m_rbA;
126  }
127  const btRigidBody& getRigidBodyB() const
128  {
129  return m_rbB;
130  }
131 
133  {
134  return m_rbA;
135  }
136 
138  {
139  return m_rbB;
140  }
141 
143  {
144  return m_rbAFrame;
145  }
146 
148  {
149  return m_rbBFrame;
150  }
151 
152  void setFrames(const btTransform& frameA, const btTransform& frameB);
153 
154  void setAngularOnly(bool angularOnly)
155  {
156  m_angularOnly = angularOnly;
157  }
158 
159  void enableAngularMotor(bool enableMotor, btScalar targetVelocity, btScalar maxMotorImpulse)
160  {
161  m_enableAngularMotor = enableMotor;
162  m_motorTargetVelocity = targetVelocity;
163  m_maxMotorImpulse = maxMotorImpulse;
164  }
165 
166  // extra motor API, including ability to set a target rotation (as opposed to angular velocity)
167  // note: setMotorTarget sets angular velocity under the hood, so you must call it every tick to
168  // maintain a given angular target.
169  void enableMotor(bool enableMotor) { m_enableAngularMotor = enableMotor; }
170  void setMaxMotorImpulse(btScalar maxMotorImpulse) { m_maxMotorImpulse = maxMotorImpulse; }
171  void setMotorTargetVelocity(btScalar motorTargetVelocity) { m_motorTargetVelocity = motorTargetVelocity; }
172  void setMotorTarget(const btQuaternion& qAinB, btScalar dt); // qAinB is rotation of body A wrt body B.
173  void setMotorTarget(btScalar targetAngle, btScalar dt);
174 
175  void setLimit(btScalar low, btScalar high, btScalar _softness = 0.9f, btScalar _biasFactor = 0.3f, btScalar _relaxationFactor = 1.0f)
176  {
177 #ifdef _BT_USE_CENTER_LIMIT_
178  m_limit.set(low, high, _softness, _biasFactor, _relaxationFactor);
179 #else
180  m_lowerLimit = btNormalizeAngle(low);
181  m_upperLimit = btNormalizeAngle(high);
182  m_limitSoftness = _softness;
183  m_biasFactor = _biasFactor;
184  m_relaxationFactor = _relaxationFactor;
185 #endif
186  }
187 
189  {
190 #ifdef _BT_USE_CENTER_LIMIT_
191  return m_limit.getSoftness();
192 #else
193  return m_limitSoftness;
194 #endif
195  }
196 
198  {
199 #ifdef _BT_USE_CENTER_LIMIT_
200  return m_limit.getBiasFactor();
201 #else
202  return m_biasFactor;
203 #endif
204  }
205 
207  {
208 #ifdef _BT_USE_CENTER_LIMIT_
209  return m_limit.getRelaxationFactor();
210 #else
211  return m_relaxationFactor;
212 #endif
213  }
214 
215  void setAxis(btVector3 & axisInA)
216  {
217  btVector3 rbAxisA1, rbAxisA2;
218  btPlaneSpace1(axisInA, rbAxisA1, rbAxisA2);
219  btVector3 pivotInA = m_rbAFrame.getOrigin();
220  // m_rbAFrame.getOrigin() = pivotInA;
221  m_rbAFrame.getBasis().setValue(rbAxisA1.getX(), rbAxisA2.getX(), axisInA.getX(),
222  rbAxisA1.getY(), rbAxisA2.getY(), axisInA.getY(),
223  rbAxisA1.getZ(), rbAxisA2.getZ(), axisInA.getZ());
224 
225  btVector3 axisInB = m_rbA.getCenterOfMassTransform().getBasis() * axisInA;
226 
227  btQuaternion rotationArc = shortestArcQuat(axisInA, axisInB);
228  btVector3 rbAxisB1 = quatRotate(rotationArc, rbAxisA1);
229  btVector3 rbAxisB2 = axisInB.cross(rbAxisB1);
230 
231  m_rbBFrame.getOrigin() = m_rbB.getCenterOfMassTransform().inverse()(m_rbA.getCenterOfMassTransform()(pivotInA));
232 
233  m_rbBFrame.getBasis().setValue(rbAxisB1.getX(), rbAxisB2.getX(), axisInB.getX(),
234  rbAxisB1.getY(), rbAxisB2.getY(), axisInB.getY(),
235  rbAxisB1.getZ(), rbAxisB2.getZ(), axisInB.getZ());
236  m_rbBFrame.getBasis() = m_rbB.getCenterOfMassTransform().getBasis().inverse() * m_rbBFrame.getBasis();
237  }
238 
239  bool hasLimit() const
240  {
241 #ifdef _BT_USE_CENTER_LIMIT_
242  return m_limit.getHalfRange() > 0;
243 #else
244  return m_lowerLimit <= m_upperLimit;
245 #endif
246  }
247 
249  {
250 #ifdef _BT_USE_CENTER_LIMIT_
251  return m_limit.getLow();
252 #else
253  return m_lowerLimit;
254 #endif
255  }
256 
258  {
259 #ifdef _BT_USE_CENTER_LIMIT_
260  return m_limit.getHigh();
261 #else
262  return m_upperLimit;
263 #endif
264  }
265 
267  btScalar getHingeAngle();
268 
269  btScalar getHingeAngle(const btTransform& transA, const btTransform& transB);
270 
271  void testLimit(const btTransform& transA, const btTransform& transB);
272 
273  const btTransform& getAFrame() const { return m_rbAFrame; };
274  const btTransform& getBFrame() const { return m_rbBFrame; };
275 
276  btTransform& getAFrame() { return m_rbAFrame; };
277  btTransform& getBFrame() { return m_rbBFrame; };
278 
279  inline int getSolveLimit()
280  {
281 #ifdef _BT_USE_CENTER_LIMIT_
282  return m_limit.isLimit();
283 #else
284  return m_solveLimit;
285 #endif
286  }
287 
289  {
290 #ifdef _BT_USE_CENTER_LIMIT_
291  return m_limit.getSign();
292 #else
293  return m_limitSign;
294 #endif
295  }
296 
297  inline bool getAngularOnly()
298  {
299  return m_angularOnly;
300  }
301  inline bool getEnableAngularMotor()
302  {
303  return m_enableAngularMotor;
304  }
306  {
307  return m_motorTargetVelocity;
308  }
310  {
311  return m_maxMotorImpulse;
312  }
313  // access for UseFrameOffset
314  bool getUseFrameOffset() { return m_useOffsetForConstraintFrame; }
315  void setUseFrameOffset(bool frameOffsetOnOff) { m_useOffsetForConstraintFrame = frameOffsetOnOff; }
316  // access for UseReferenceFrameA
317  bool getUseReferenceFrameA() const { return m_useReferenceFrameA; }
318  void setUseReferenceFrameA(bool useReferenceFrameA) { m_useReferenceFrameA = useReferenceFrameA; }
319 
322  virtual void setParam(int num, btScalar value, int axis = -1);
324  virtual btScalar getParam(int num, int axis = -1) const;
325 
326  virtual int getFlags() const
327  {
328  return m_flags;
329  }
330 
331  virtual int calculateSerializeBufferSize() const;
332 
334  virtual const char* serialize(void* dataBuffer, btSerializer* serializer) const;
335 };
336 
337 //only for backward compatibility
338 #ifdef BT_BACKWARDS_COMPATIBLE_SERIALIZATION
341 {
343  btTransformDoubleData m_rbAFrame; // constraint axii. Assumes z is hinge axis.
350 
356 };
357 #endif //BT_BACKWARDS_COMPATIBLE_SERIALIZATION
358 
362 {
363 protected:
365 
366 public:
368 
369  btHingeAccumulatedAngleConstraint(btRigidBody & rbA, btRigidBody & rbB, const btVector3& pivotInA, const btVector3& pivotInB, const btVector3& axisInA, const btVector3& axisInB, bool useReferenceFrameA = false)
370  : btHingeConstraint(rbA, rbB, pivotInA, pivotInB, axisInA, axisInB, useReferenceFrameA)
371  {
372  m_accumulatedAngle = getHingeAngle();
373  }
374 
375  btHingeAccumulatedAngleConstraint(btRigidBody & rbA, const btVector3& pivotInA, const btVector3& axisInA, bool useReferenceFrameA = false)
376  : btHingeConstraint(rbA, pivotInA, axisInA, useReferenceFrameA)
377  {
378  m_accumulatedAngle = getHingeAngle();
379  }
380 
381  btHingeAccumulatedAngleConstraint(btRigidBody & rbA, btRigidBody & rbB, const btTransform& rbAFrame, const btTransform& rbBFrame, bool useReferenceFrameA = false)
382  : btHingeConstraint(rbA, rbB, rbAFrame, rbBFrame, useReferenceFrameA)
383  {
384  m_accumulatedAngle = getHingeAngle();
385  }
386 
387  btHingeAccumulatedAngleConstraint(btRigidBody & rbA, const btTransform& rbAFrame, bool useReferenceFrameA = false)
388  : btHingeConstraint(rbA, rbAFrame, useReferenceFrameA)
389  {
390  m_accumulatedAngle = getHingeAngle();
391  }
392  btScalar getAccumulatedHingeAngle();
393  void setAccumulatedHingeAngle(btScalar accAngle);
394  virtual void getInfo1(btConstraintInfo1 * info);
395 };
396 
398 {
400  btTransformFloatData m_rbAFrame; // constraint axii. Assumes z is hinge axis.
404 
408 
414 };
415 
418 {
420  btTransformDoubleData m_rbAFrame; // constraint axii. Assumes z is hinge axis.
427 
428  double m_lowerLimit;
429  double m_upperLimit;
431  double m_biasFactor;
433  char m_padding1[4];
434 };
435 
437 {
438  return sizeof(btHingeConstraintData);
439 }
440 
442 SIMD_FORCE_INLINE const char* btHingeConstraint::serialize(void* dataBuffer, btSerializer* serializer) const
443 {
444  btHingeConstraintData* hingeData = (btHingeConstraintData*)dataBuffer;
445  btTypedConstraint::serialize(&hingeData->m_typeConstraintData, serializer);
446 
447  m_rbAFrame.serialize(hingeData->m_rbAFrame);
448  m_rbBFrame.serialize(hingeData->m_rbBFrame);
449 
450  hingeData->m_angularOnly = m_angularOnly;
451  hingeData->m_enableAngularMotor = m_enableAngularMotor;
452  hingeData->m_maxMotorImpulse = float(m_maxMotorImpulse);
453  hingeData->m_motorTargetVelocity = float(m_motorTargetVelocity);
454  hingeData->m_useReferenceFrameA = m_useReferenceFrameA;
455 #ifdef _BT_USE_CENTER_LIMIT_
456  hingeData->m_lowerLimit = float(m_limit.getLow());
457  hingeData->m_upperLimit = float(m_limit.getHigh());
458  hingeData->m_limitSoftness = float(m_limit.getSoftness());
459  hingeData->m_biasFactor = float(m_limit.getBiasFactor());
460  hingeData->m_relaxationFactor = float(m_limit.getRelaxationFactor());
461 #else
462  hingeData->m_lowerLimit = float(m_lowerLimit);
463  hingeData->m_upperLimit = float(m_upperLimit);
464  hingeData->m_limitSoftness = float(m_limitSoftness);
465  hingeData->m_biasFactor = float(m_biasFactor);
466  hingeData->m_relaxationFactor = float(m_relaxationFactor);
467 #endif
468 
469  // Fill padding with zeros to appease msan.
470 #ifdef BT_USE_DOUBLE_PRECISION
471  hingeData->m_padding1[0] = 0;
472  hingeData->m_padding1[1] = 0;
473  hingeData->m_padding1[2] = 0;
474  hingeData->m_padding1[3] = 0;
475 #endif
476 
478 }
479 
480 #endif //BT_HINGECONSTRAINT_H
void setUseFrameOffset(bool frameOffsetOnOff)
btScalar getLimitBiasFactor() const
btTransformDoubleData m_rbBFrame
btTransformFloatData m_rbAFrame
btScalar getUpperLimit() const
btTransform & getBFrame()
const btRigidBody & getRigidBodyB() const
const btTransform & getBFrame() const
Jacobian entry is an abstraction that allows to describe constraints it can be used in combination wi...
btScalar getMotorTargetVelocity()
btScalar getLowerLimit() const
virtual const char * serialize(void *dataBuffer, btSerializer *serializer) const
fills the dataBuffer and returns the struct name (and 0 on failure)
btTransform m_rbAFrame
btScalar getHalfRange() const
Gives half of the distance between min and max limit angle.
void btPlaneSpace1(const T &n, T &p, T &q)
Definition: btVector3.h:1251
this structure is not used, except for loading pre-2.82 .bullet files
virtual int calculateSerializeBufferSize() const
#define btHingeConstraintData
#define SIMD_FORCE_INLINE
Definition: btScalar.h:83
const btScalar & getY() const
Return the y value.
Definition: btVector3.h:563
btTypedConstraintDoubleData m_typeConstraintData
btScalar getRelaxationFactor() const
Returns limit&#39;s relaxation factor.
btScalar m_motorTargetVelocity
hinge constraint between two rigidbodies each with a pivotpoint that descibes the axis location in lo...
btScalar getLimitRelaxationFactor() const
btVector3 quatRotate(const btQuaternion &rotation, const btVector3 &v)
Definition: btQuaternion.h:926
btHingeAccumulatedAngleConstraint(btRigidBody &rbA, btRigidBody &rbB, const btTransform &rbAFrame, const btTransform &rbBFrame, bool useReferenceFrameA=false)
const btScalar & getZ() const
Return the z value.
Definition: btVector3.h:565
btScalar getBiasFactor() const
Returns limit&#39;s bias factor.
virtual int getFlags() const
btVector3 & getOrigin()
Return the origin vector translation.
Definition: btTransform.h:113
btQuaternion shortestArcQuat(const btVector3 &v0, const btVector3 &v1)
Definition: btQuaternion.h:940
void set(btScalar low, btScalar high, btScalar _softness=0.9f, btScalar _biasFactor=0.3f, btScalar _relaxationFactor=1.0f)
Sets all limit&#39;s parameters.
btScalar getMaxMotorImpulse()
btTransform m_rbBFrame
btScalar getSoftness() const
Returns limit&#39;s softness.
btVector3 cross(const btVector3 &v) const
Return the cross product between this and another vector.
Definition: btVector3.h:380
void setAxis(btVector3 &axisInA)
btScalar getSign() const
Returns sign value evaluated when test() was invoked.
btMatrix3x3 & getBasis()
Return the basis matrix for the rotation.
Definition: btTransform.h:108
void setValue(const btScalar &xx, const btScalar &xy, const btScalar &xz, const btScalar &yx, const btScalar &yy, const btScalar &yz, const btScalar &zx, const btScalar &zy, const btScalar &zz)
Set the values of the matrix explicitly (row major)
Definition: btMatrix3x3.h:195
void setUseReferenceFrameA(bool useReferenceFrameA)
The btRigidBody is the main class for rigid body objects.
Definition: btRigidBody.h:59
btTypedConstraintData m_typeConstraintData
void serialize(struct btTransformData &dataOut) const
Definition: btTransform.h:256
btScalar getLimitSoftness() const
this structure is not used, except for loading pre-2.82 .bullet files
btScalar getLow() const
btRigidBody & getRigidBodyA()
btVector3 can be used to represent 3D points and vectors.
Definition: btVector3.h:80
#define ATTRIBUTE_ALIGNED16(a)
Definition: btScalar.h:84
const btTransform & getAFrame() const
void setMotorTargetVelocity(btScalar motorTargetVelocity)
btTransform & getAFrame()
btScalar getHigh() const
btScalar btNormalizeAngle(btScalar angleInRadians)
Definition: btScalar.h:761
bool getUseReferenceFrameA() const
void setAngularOnly(bool angularOnly)
The btTransform class supports rigid transforms with only translation and rotation and no scaling/she...
Definition: btTransform.h:28
virtual const char * serialize(void *dataBuffer, btSerializer *serializer) const
fills the dataBuffer and returns the struct name (and 0 on failure)
btTransformDoubleData m_rbAFrame
TypedConstraint is the baseclass for Bullet constraints and vehicles.
bool isLimit() const
Returns true when the last test() invocation recognized limit violation.
void setLimit(btScalar low, btScalar high, btScalar _softness=0.9f, btScalar _biasFactor=0.3f, btScalar _relaxationFactor=1.0f)
for serialization
Definition: btTransform.h:244
void enableMotor(bool enableMotor)
#define BT_DECLARE_ALIGNED_ALLOCATOR()
Definition: btScalar.h:405
virtual int calculateSerializeBufferSize() const
btHingeAccumulatedAngleConstraint(btRigidBody &rbA, const btTransform &rbAFrame, bool useReferenceFrameA=false)
btTransform & getFrameOffsetB()
btTransformDoubleData m_rbBFrame
btRigidBody & getRigidBodyB()
btHingeAccumulatedAngleConstraint(btRigidBody &rbA, const btVector3 &pivotInA, const btVector3 &axisInA, bool useReferenceFrameA=false)
#define btHingeConstraintDataName
The getAccumulatedHingeAngle returns the accumulated hinge angle, taking rotation across the -PI/PI b...
btTransformDoubleData m_rbAFrame
The btQuaternion implements quaternion to perform linear algebra rotations in combination with btMatr...
Definition: btQuaternion.h:49
void setMaxMotorImpulse(btScalar maxMotorImpulse)
btAngularLimit m_limit
btMatrix3x3 inverse() const
Return the inverse of the matrix.
Definition: btMatrix3x3.h:1070
const btRigidBody & getRigidBodyA() const
btTransform & getFrameOffsetA()
btHingeFlags
btTypedConstraintData m_typeConstraintData
virtual const char * serialize(void *dataBuffer, class btSerializer *serializer) const
fills the dataBuffer and returns the struct name (and 0 on failure)
const btScalar & getX() const
Return the x value.
Definition: btVector3.h:561
do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64 ...
float btScalar
The btScalar type abstracts floating point numbers, to easily switch between double and single floati...
Definition: btScalar.h:294
void enableAngularMotor(bool enableMotor, btScalar targetVelocity, btScalar maxMotorImpulse)
btHingeAccumulatedAngleConstraint(btRigidBody &rbA, btRigidBody &rbB, const btVector3 &pivotInA, const btVector3 &pivotInB, const btVector3 &axisInA, const btVector3 &axisInB, bool useReferenceFrameA=false)
btTransformFloatData m_rbBFrame