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 
24 #include "LinearMath/btVector3.h"
25 #include "btJacobianEntry.h"
26 #include "btTypedConstraint.h"
27 
28 class btRigidBody;
29 
30 #ifdef BT_USE_DOUBLE_PRECISION
31 #define btHingeConstraintData btHingeConstraintDoubleData2 //rename to 2 for backwards compatibility, so we can still load the 'btHingeConstraintDoubleData' version
32 #define btHingeConstraintDataName "btHingeConstraintDoubleData2"
33 #else
34 #define btHingeConstraintData btHingeConstraintFloatData
35 #define btHingeConstraintDataName "btHingeConstraintFloatData"
36 #endif //BT_USE_DOUBLE_PRECISION
37 
38 
39 
41 {
46 };
47 
48 
52 {
53 #ifdef IN_PARALLELL_SOLVER
54 public:
55 #endif
56  btJacobianEntry m_jac[3]; //3 orthogonal linear constraints
57  btJacobianEntry m_jacAng[3]; //2 orthogonal angular constraints+ 1 for limit/motor
58 
59  btTransform m_rbAFrame; // constraint axii. Assumes z is hinge axis.
61 
64 
65 
66 #ifdef _BT_USE_CENTER_LIMIT_
68 #else
69  btScalar m_lowerLimit;
70  btScalar m_upperLimit;
71  btScalar m_limitSign;
72  btScalar m_correction;
73 
74  btScalar m_limitSoftness;
75  btScalar m_biasFactor;
76  btScalar m_relaxationFactor;
77 
78  bool m_solveLimit;
79 #endif
80 
82 
83 
87 
93 
95 
96  int m_flags;
101 
102 
103 public:
104 
106 
107  btHingeConstraint(btRigidBody& rbA,btRigidBody& rbB, const btVector3& pivotInA,const btVector3& pivotInB, const btVector3& axisInA,const btVector3& axisInB, bool useReferenceFrameA = false);
108 
109  btHingeConstraint(btRigidBody& rbA,const btVector3& pivotInA,const btVector3& axisInA, bool useReferenceFrameA = false);
110 
111  btHingeConstraint(btRigidBody& rbA,btRigidBody& rbB, const btTransform& rbAFrame, const btTransform& rbBFrame, bool useReferenceFrameA = false);
112 
113  btHingeConstraint(btRigidBody& rbA,const btTransform& rbAFrame, bool useReferenceFrameA = false);
114 
115 
116  virtual void buildJacobian();
117 
118  virtual void getInfo1 (btConstraintInfo1* info);
119 
120  void getInfo1NonVirtual(btConstraintInfo1* info);
121 
122  virtual void getInfo2 (btConstraintInfo2* info);
123 
124  void getInfo2NonVirtual(btConstraintInfo2* info,const btTransform& transA,const btTransform& transB,const btVector3& angVelA,const btVector3& angVelB);
125 
126  void getInfo2Internal(btConstraintInfo2* info,const btTransform& transA,const btTransform& transB,const btVector3& angVelA,const btVector3& angVelB);
127  void getInfo2InternalUsingFrameOffset(btConstraintInfo2* info,const btTransform& transA,const btTransform& transB,const btVector3& angVelA,const btVector3& angVelB);
128 
129 
130  void updateRHS(btScalar timeStep);
131 
132  const btRigidBody& getRigidBodyA() const
133  {
134  return m_rbA;
135  }
136  const btRigidBody& getRigidBodyB() const
137  {
138  return m_rbB;
139  }
140 
142  {
143  return m_rbA;
144  }
145 
147  {
148  return m_rbB;
149  }
150 
152  {
153  return m_rbAFrame;
154  }
155 
157  {
158  return m_rbBFrame;
159  }
160 
161  void setFrames(const btTransform& frameA, const btTransform& frameB);
162 
163  void setAngularOnly(bool angularOnly)
164  {
165  m_angularOnly = angularOnly;
166  }
167 
168  void enableAngularMotor(bool enableMotor,btScalar targetVelocity,btScalar maxMotorImpulse)
169  {
170  m_enableAngularMotor = enableMotor;
171  m_motorTargetVelocity = targetVelocity;
172  m_maxMotorImpulse = maxMotorImpulse;
173  }
174 
175  // extra motor API, including ability to set a target rotation (as opposed to angular velocity)
176  // note: setMotorTarget sets angular velocity under the hood, so you must call it every tick to
177  // maintain a given angular target.
178  void enableMotor(bool enableMotor) { m_enableAngularMotor = enableMotor; }
179  void setMaxMotorImpulse(btScalar maxMotorImpulse) { m_maxMotorImpulse = maxMotorImpulse; }
180  void setMotorTarget(const btQuaternion& qAinB, btScalar dt); // qAinB is rotation of body A wrt body B.
181  void setMotorTarget(btScalar targetAngle, btScalar dt);
182 
183 
184  void setLimit(btScalar low,btScalar high,btScalar _softness = 0.9f, btScalar _biasFactor = 0.3f, btScalar _relaxationFactor = 1.0f)
185  {
186 #ifdef _BT_USE_CENTER_LIMIT_
187  m_limit.set(low, high, _softness, _biasFactor, _relaxationFactor);
188 #else
189  m_lowerLimit = btNormalizeAngle(low);
190  m_upperLimit = btNormalizeAngle(high);
191  m_limitSoftness = _softness;
192  m_biasFactor = _biasFactor;
193  m_relaxationFactor = _relaxationFactor;
194 #endif
195  }
196 
197  void setAxis(btVector3& axisInA)
198  {
199  btVector3 rbAxisA1, rbAxisA2;
200  btPlaneSpace1(axisInA, rbAxisA1, rbAxisA2);
201  btVector3 pivotInA = m_rbAFrame.getOrigin();
202 // m_rbAFrame.getOrigin() = pivotInA;
203  m_rbAFrame.getBasis().setValue( rbAxisA1.getX(),rbAxisA2.getX(),axisInA.getX(),
204  rbAxisA1.getY(),rbAxisA2.getY(),axisInA.getY(),
205  rbAxisA1.getZ(),rbAxisA2.getZ(),axisInA.getZ() );
206 
207  btVector3 axisInB = m_rbA.getCenterOfMassTransform().getBasis() * axisInA;
208 
209  btQuaternion rotationArc = shortestArcQuat(axisInA,axisInB);
210  btVector3 rbAxisB1 = quatRotate(rotationArc,rbAxisA1);
211  btVector3 rbAxisB2 = axisInB.cross(rbAxisB1);
212 
213  m_rbBFrame.getOrigin() = m_rbB.getCenterOfMassTransform().inverse()(m_rbA.getCenterOfMassTransform()(pivotInA));
214 
215  m_rbBFrame.getBasis().setValue( rbAxisB1.getX(),rbAxisB2.getX(),axisInB.getX(),
216  rbAxisB1.getY(),rbAxisB2.getY(),axisInB.getY(),
217  rbAxisB1.getZ(),rbAxisB2.getZ(),axisInB.getZ() );
218  m_rbBFrame.getBasis() = m_rbB.getCenterOfMassTransform().getBasis().inverse() * m_rbBFrame.getBasis();
219 
220  }
221 
222  bool hasLimit() const {
223 #ifdef _BT_USE_CENTER_LIMIT_
224  return m_limit.getHalfRange() > 0;
225 #else
226  return m_lowerLimit <= m_upperLimit;
227 #endif
228  }
229 
231  {
232 #ifdef _BT_USE_CENTER_LIMIT_
233  return m_limit.getLow();
234 #else
235  return m_lowerLimit;
236 #endif
237  }
238 
240  {
241 #ifdef _BT_USE_CENTER_LIMIT_
242  return m_limit.getHigh();
243 #else
244  return m_upperLimit;
245 #endif
246  }
247 
248 
250  btScalar getHingeAngle();
251 
252  btScalar getHingeAngle(const btTransform& transA,const btTransform& transB);
253 
254  void testLimit(const btTransform& transA,const btTransform& transB);
255 
256 
257  const btTransform& getAFrame() const { return m_rbAFrame; };
258  const btTransform& getBFrame() const { return m_rbBFrame; };
259 
260  btTransform& getAFrame() { return m_rbAFrame; };
261  btTransform& getBFrame() { return m_rbBFrame; };
262 
263  inline int getSolveLimit()
264  {
265 #ifdef _BT_USE_CENTER_LIMIT_
266  return m_limit.isLimit();
267 #else
268  return m_solveLimit;
269 #endif
270  }
271 
273  {
274 #ifdef _BT_USE_CENTER_LIMIT_
275  return m_limit.getSign();
276 #else
277  return m_limitSign;
278 #endif
279  }
280 
281  inline bool getAngularOnly()
282  {
283  return m_angularOnly;
284  }
285  inline bool getEnableAngularMotor()
286  {
287  return m_enableAngularMotor;
288  }
290  {
291  return m_motorTargetVelocity;
292  }
294  {
295  return m_maxMotorImpulse;
296  }
297  // access for UseFrameOffset
298  bool getUseFrameOffset() { return m_useOffsetForConstraintFrame; }
299  void setUseFrameOffset(bool frameOffsetOnOff) { m_useOffsetForConstraintFrame = frameOffsetOnOff; }
300 
301 
304  virtual void setParam(int num, btScalar value, int axis = -1);
306  virtual btScalar getParam(int num, int axis = -1) const;
307 
308  virtual int calculateSerializeBufferSize() const;
309 
311  virtual const char* serialize(void* dataBuffer, btSerializer* serializer) const;
312 
313 
314 };
315 
316 
317 //only for backward compatibility
318 #ifdef BT_BACKWARDS_COMPATIBLE_SERIALIZATION
321 {
323  btTransformDoubleData m_rbAFrame; // constraint axii. Assumes z is hinge axis.
330 
336 
337 };
338 #endif //BT_BACKWARDS_COMPATIBLE_SERIALIZATION
339 
342 {
343 protected:
345 public:
346 
348 
349  btHingeAccumulatedAngleConstraint(btRigidBody& rbA,btRigidBody& rbB, const btVector3& pivotInA,const btVector3& pivotInB, const btVector3& axisInA,const btVector3& axisInB, bool useReferenceFrameA = false)
350  :btHingeConstraint(rbA,rbB,pivotInA,pivotInB, axisInA,axisInB, useReferenceFrameA )
351  {
352  m_accumulatedAngle=getHingeAngle();
353  }
354 
355  btHingeAccumulatedAngleConstraint(btRigidBody& rbA,const btVector3& pivotInA,const btVector3& axisInA, bool useReferenceFrameA = false)
356  :btHingeConstraint(rbA,pivotInA,axisInA, useReferenceFrameA)
357  {
358  m_accumulatedAngle=getHingeAngle();
359  }
360 
361  btHingeAccumulatedAngleConstraint(btRigidBody& rbA,btRigidBody& rbB, const btTransform& rbAFrame, const btTransform& rbBFrame, bool useReferenceFrameA = false)
362  :btHingeConstraint(rbA,rbB, rbAFrame, rbBFrame, useReferenceFrameA )
363  {
364  m_accumulatedAngle=getHingeAngle();
365  }
366 
367  btHingeAccumulatedAngleConstraint(btRigidBody& rbA,const btTransform& rbAFrame, bool useReferenceFrameA = false)
368  :btHingeConstraint(rbA,rbAFrame, useReferenceFrameA )
369  {
370  m_accumulatedAngle=getHingeAngle();
371  }
372  btScalar getAccumulatedHingeAngle();
373  void setAccumulatedHingeAngle(btScalar accAngle);
374  virtual void getInfo1 (btConstraintInfo1* info);
375 
376 };
377 
379 {
381  btTransformFloatData m_rbAFrame; // constraint axii. Assumes z is hinge axis.
385 
389 
395 
396 };
397 
398 
399 
402 {
404  btTransformDoubleData m_rbAFrame; // constraint axii. Assumes z is hinge axis.
411 
412  double m_lowerLimit;
413  double m_upperLimit;
415  double m_biasFactor;
417  char m_padding1[4];
418 
419 };
420 
421 
422 
423 
425 {
426  return sizeof(btHingeConstraintData);
427 }
428 
430 SIMD_FORCE_INLINE const char* btHingeConstraint::serialize(void* dataBuffer, btSerializer* serializer) const
431 {
432  btHingeConstraintData* hingeData = (btHingeConstraintData*)dataBuffer;
433  btTypedConstraint::serialize(&hingeData->m_typeConstraintData,serializer);
434 
435  m_rbAFrame.serialize(hingeData->m_rbAFrame);
436  m_rbBFrame.serialize(hingeData->m_rbBFrame);
437 
438  hingeData->m_angularOnly = m_angularOnly;
439  hingeData->m_enableAngularMotor = m_enableAngularMotor;
440  hingeData->m_maxMotorImpulse = float(m_maxMotorImpulse);
441  hingeData->m_motorTargetVelocity = float(m_motorTargetVelocity);
442  hingeData->m_useReferenceFrameA = m_useReferenceFrameA;
443 #ifdef _BT_USE_CENTER_LIMIT_
444  hingeData->m_lowerLimit = float(m_limit.getLow());
445  hingeData->m_upperLimit = float(m_limit.getHigh());
446  hingeData->m_limitSoftness = float(m_limit.getSoftness());
447  hingeData->m_biasFactor = float(m_limit.getBiasFactor());
448  hingeData->m_relaxationFactor = float(m_limit.getRelaxationFactor());
449 #else
450  hingeData->m_lowerLimit = float(m_lowerLimit);
451  hingeData->m_upperLimit = float(m_upperLimit);
452  hingeData->m_limitSoftness = float(m_limitSoftness);
453  hingeData->m_biasFactor = float(m_biasFactor);
454  hingeData->m_relaxationFactor = float(m_relaxationFactor);
455 #endif
456 
458 }
459 
460 #endif //BT_HINGECONSTRAINT_H
btMatrix3x3 inverse() const
Return the inverse of the matrix.
Definition: btMatrix3x3.h:1046
void setUseFrameOffset(bool frameOffsetOnOff)
btTransformDoubleData m_rbBFrame
btTransformFloatData m_rbAFrame
const btTransform & getAFrame() const
btTransform & getBFrame()
Jacobian entry is an abstraction that allows to describe constraints it can be used in combination wi...
btTransform m_rbAFrame
bool isLimit() const
Returns true when the last test() invocation recognized limit violation.
void btPlaneSpace1(const T &n, T &p, T &q)
Definition: btVector3.h:1272
this structure is not used, except for loading pre-2.82 .bullet files
const btTransform & getBFrame() const
#define btHingeConstraintData
#define SIMD_FORCE_INLINE
Definition: btScalar.h:63
btTypedConstraintDoubleData m_typeConstraintData
const btRigidBody & getRigidBodyA() const
btScalar m_motorTargetVelocity
hinge constraint between two rigidbodies each with a pivotpoint that descibes the axis location in lo...
btVector3 quatRotate(const btQuaternion &rotation, const btVector3 &v)
Definition: btQuaternion.h:866
const btScalar & getZ() const
Return the z value.
Definition: btVector3.h:565
btHingeAccumulatedAngleConstraint(btRigidBody &rbA, btRigidBody &rbB, const btTransform &rbAFrame, const btTransform &rbBFrame, bool useReferenceFrameA=false)
virtual int calculateSerializeBufferSize() const
btScalar getHalfRange() const
Gives half of the distance between min and max limit angle.
btScalar getHigh() const
btVector3 & getOrigin()
Return the origin vector translation.
Definition: btTransform.h:117
bool hasLimit() const
btScalar getUpperLimit() const
btQuaternion shortestArcQuat(const btVector3 &v0, const btVector3 &v1)
Definition: btQuaternion.h:880
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 getSign() const
Returns sign value evaluated when test() was invoked.
btScalar getMaxMotorImpulse()
btTransform m_rbBFrame
void setAxis(btVector3 &axisInA)
btVector3 cross(const btVector3 &v) const
Return the cross product between this and another vector.
Definition: btVector3.h:377
btScalar getMotorTargetVelosity()
const btScalar & getY() const
Return the y value.
Definition: btVector3.h:563
btMatrix3x3 & getBasis()
Return the basis matrix for the rotation.
Definition: btTransform.h:112
const btScalar & getX() const
Return the x value.
Definition: btVector3.h:561
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:198
btScalar getLowerLimit() const
The btRigidBody is the main class for rigid body objects.
Definition: btRigidBody.h:62
btTypedConstraintData m_typeConstraintData
this structure is not used, except for loading pre-2.82 .bullet files
btRigidBody & getRigidBodyA()
btVector3 can be used to represent 3D points and vectors.
Definition: btVector3.h:83
#define ATTRIBUTE_ALIGNED16(a)
Definition: btScalar.h:64
btTransform & getAFrame()
btScalar btNormalizeAngle(btScalar angleInRadians)
Definition: btScalar.h:724
void setAngularOnly(bool angularOnly)
The btTransform class supports rigid transforms with only translation and rotation and no scaling/she...
Definition: btTransform.h:34
btTransformDoubleData m_rbAFrame
virtual int calculateSerializeBufferSize() const
TypedConstraint is the baseclass for Bullet constraints and vehicles.
void setLimit(btScalar low, btScalar high, btScalar _softness=0.9f, btScalar _biasFactor=0.3f, btScalar _relaxationFactor=1.0f)
for serialization
Definition: btTransform.h:253
void enableMotor(bool enableMotor)
#define BT_DECLARE_ALIGNED_ALLOCATOR()
Definition: btScalar.h:388
virtual const char * serialize(void *dataBuffer, class btSerializer *serializer) const
fills the dataBuffer and returns the struct name (and 0 on failure)
virtual const char * serialize(void *dataBuffer, btSerializer *serializer) const
fills the dataBuffer and returns the struct name (and 0 on failure)
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:48
btScalar getLow() const
void setMaxMotorImpulse(btScalar maxMotorImpulse)
const btRigidBody & getRigidBodyB() const
btAngularLimit m_limit
btTransform & getFrameOffsetA()
btHingeFlags
virtual const char * serialize(void *dataBuffer, btSerializer *serializer) const
fills the dataBuffer and returns the struct name (and 0 on failure)
btTypedConstraintData m_typeConstraintData
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:278
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