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 {
45 };
46 
47 
51 {
52 #ifdef IN_PARALLELL_SOLVER
53 public:
54 #endif
55  btJacobianEntry m_jac[3]; //3 orthogonal linear constraints
56  btJacobianEntry m_jacAng[3]; //2 orthogonal angular constraints+ 1 for limit/motor
57 
58  btTransform m_rbAFrame; // constraint axii. Assumes z is hinge axis.
60 
63 
64 
65 #ifdef _BT_USE_CENTER_LIMIT_
67 #else
68  btScalar m_lowerLimit;
69  btScalar m_upperLimit;
70  btScalar m_limitSign;
71  btScalar m_correction;
72 
73  btScalar m_limitSoftness;
74  btScalar m_biasFactor;
75  btScalar m_relaxationFactor;
76 
77  bool m_solveLimit;
78 #endif
79 
81 
82 
86 
92 
94 
95  int m_flags;
99 
100 
101 public:
102 
104 
105  btHingeConstraint(btRigidBody& rbA,btRigidBody& rbB, const btVector3& pivotInA,const btVector3& pivotInB, const btVector3& axisInA,const btVector3& axisInB, bool useReferenceFrameA = false);
106 
107  btHingeConstraint(btRigidBody& rbA,const btVector3& pivotInA,const btVector3& axisInA, bool useReferenceFrameA = false);
108 
109  btHingeConstraint(btRigidBody& rbA,btRigidBody& rbB, const btTransform& rbAFrame, const btTransform& rbBFrame, bool useReferenceFrameA = false);
110 
111  btHingeConstraint(btRigidBody& rbA,const btTransform& rbAFrame, bool useReferenceFrameA = false);
112 
113 
114  virtual void buildJacobian();
115 
116  virtual void getInfo1 (btConstraintInfo1* info);
117 
118  void getInfo1NonVirtual(btConstraintInfo1* info);
119 
120  virtual void getInfo2 (btConstraintInfo2* info);
121 
122  void getInfo2NonVirtual(btConstraintInfo2* info,const btTransform& transA,const btTransform& transB,const btVector3& angVelA,const btVector3& angVelB);
123 
124  void getInfo2Internal(btConstraintInfo2* info,const btTransform& transA,const btTransform& transB,const btVector3& angVelA,const btVector3& angVelB);
125  void getInfo2InternalUsingFrameOffset(btConstraintInfo2* info,const btTransform& transA,const btTransform& transB,const btVector3& angVelA,const btVector3& angVelB);
126 
127 
128  void updateRHS(btScalar timeStep);
129 
130  const btRigidBody& getRigidBodyA() const
131  {
132  return m_rbA;
133  }
134  const btRigidBody& getRigidBodyB() const
135  {
136  return m_rbB;
137  }
138 
140  {
141  return m_rbA;
142  }
143 
145  {
146  return m_rbB;
147  }
148 
150  {
151  return m_rbAFrame;
152  }
153 
155  {
156  return m_rbBFrame;
157  }
158 
159  void setFrames(const btTransform& frameA, const btTransform& frameB);
160 
161  void setAngularOnly(bool angularOnly)
162  {
163  m_angularOnly = angularOnly;
164  }
165 
166  void enableAngularMotor(bool enableMotor,btScalar targetVelocity,btScalar maxMotorImpulse)
167  {
168  m_enableAngularMotor = enableMotor;
169  m_motorTargetVelocity = targetVelocity;
170  m_maxMotorImpulse = maxMotorImpulse;
171  }
172 
173  // extra motor API, including ability to set a target rotation (as opposed to angular velocity)
174  // note: setMotorTarget sets angular velocity under the hood, so you must call it every tick to
175  // maintain a given angular target.
176  void enableMotor(bool enableMotor) { m_enableAngularMotor = enableMotor; }
177  void setMaxMotorImpulse(btScalar maxMotorImpulse) { m_maxMotorImpulse = maxMotorImpulse; }
178  void setMotorTarget(const btQuaternion& qAinB, btScalar dt); // qAinB is rotation of body A wrt body B.
179  void setMotorTarget(btScalar targetAngle, btScalar dt);
180 
181 
182  void setLimit(btScalar low,btScalar high,btScalar _softness = 0.9f, btScalar _biasFactor = 0.3f, btScalar _relaxationFactor = 1.0f)
183  {
184 #ifdef _BT_USE_CENTER_LIMIT_
185  m_limit.set(low, high, _softness, _biasFactor, _relaxationFactor);
186 #else
187  m_lowerLimit = btNormalizeAngle(low);
188  m_upperLimit = btNormalizeAngle(high);
189  m_limitSoftness = _softness;
190  m_biasFactor = _biasFactor;
191  m_relaxationFactor = _relaxationFactor;
192 #endif
193  }
194 
195  void setAxis(btVector3& axisInA)
196  {
197  btVector3 rbAxisA1, rbAxisA2;
198  btPlaneSpace1(axisInA, rbAxisA1, rbAxisA2);
199  btVector3 pivotInA = m_rbAFrame.getOrigin();
200 // m_rbAFrame.getOrigin() = pivotInA;
201  m_rbAFrame.getBasis().setValue( rbAxisA1.getX(),rbAxisA2.getX(),axisInA.getX(),
202  rbAxisA1.getY(),rbAxisA2.getY(),axisInA.getY(),
203  rbAxisA1.getZ(),rbAxisA2.getZ(),axisInA.getZ() );
204 
205  btVector3 axisInB = m_rbA.getCenterOfMassTransform().getBasis() * axisInA;
206 
207  btQuaternion rotationArc = shortestArcQuat(axisInA,axisInB);
208  btVector3 rbAxisB1 = quatRotate(rotationArc,rbAxisA1);
209  btVector3 rbAxisB2 = axisInB.cross(rbAxisB1);
210 
211  m_rbBFrame.getOrigin() = m_rbB.getCenterOfMassTransform().inverse()(m_rbA.getCenterOfMassTransform()(pivotInA));
212 
213  m_rbBFrame.getBasis().setValue( rbAxisB1.getX(),rbAxisB2.getX(),axisInB.getX(),
214  rbAxisB1.getY(),rbAxisB2.getY(),axisInB.getY(),
215  rbAxisB1.getZ(),rbAxisB2.getZ(),axisInB.getZ() );
216  m_rbBFrame.getBasis() = m_rbB.getCenterOfMassTransform().getBasis().inverse() * m_rbBFrame.getBasis();
217 
218  }
219 
221  {
222 #ifdef _BT_USE_CENTER_LIMIT_
223  return m_limit.getLow();
224 #else
225  return m_lowerLimit;
226 #endif
227  }
228 
230  {
231 #ifdef _BT_USE_CENTER_LIMIT_
232  return m_limit.getHigh();
233 #else
234  return m_upperLimit;
235 #endif
236  }
237 
238 
239  btScalar getHingeAngle();
240 
241  btScalar getHingeAngle(const btTransform& transA,const btTransform& transB);
242 
243  void testLimit(const btTransform& transA,const btTransform& transB);
244 
245 
246  const btTransform& getAFrame() const { return m_rbAFrame; };
247  const btTransform& getBFrame() const { return m_rbBFrame; };
248 
249  btTransform& getAFrame() { return m_rbAFrame; };
250  btTransform& getBFrame() { return m_rbBFrame; };
251 
252  inline int getSolveLimit()
253  {
254 #ifdef _BT_USE_CENTER_LIMIT_
255  return m_limit.isLimit();
256 #else
257  return m_solveLimit;
258 #endif
259  }
260 
262  {
263 #ifdef _BT_USE_CENTER_LIMIT_
264  return m_limit.getSign();
265 #else
266  return m_limitSign;
267 #endif
268  }
269 
270  inline bool getAngularOnly()
271  {
272  return m_angularOnly;
273  }
274  inline bool getEnableAngularMotor()
275  {
276  return m_enableAngularMotor;
277  }
279  {
280  return m_motorTargetVelocity;
281  }
283  {
284  return m_maxMotorImpulse;
285  }
286  // access for UseFrameOffset
287  bool getUseFrameOffset() { return m_useOffsetForConstraintFrame; }
288  void setUseFrameOffset(bool frameOffsetOnOff) { m_useOffsetForConstraintFrame = frameOffsetOnOff; }
289 
290 
293  virtual void setParam(int num, btScalar value, int axis = -1);
295  virtual btScalar getParam(int num, int axis = -1) const;
296 
297  virtual int calculateSerializeBufferSize() const;
298 
300  virtual const char* serialize(void* dataBuffer, btSerializer* serializer) const;
301 
302 
303 };
304 
305 
306 //only for backward compatibility
307 #ifdef BT_BACKWARDS_COMPATIBLE_SERIALIZATION
310 {
312  btTransformDoubleData m_rbAFrame; // constraint axii. Assumes z is hinge axis.
319 
325 
326 };
327 #endif //BT_BACKWARDS_COMPATIBLE_SERIALIZATION
328 
329 
331 {
333  btTransformFloatData m_rbAFrame; // constraint axii. Assumes z is hinge axis.
337 
341 
347 
348 };
349 
350 
351 
354 {
356  btTransformDoubleData m_rbAFrame; // constraint axii. Assumes z is hinge axis.
363 
364  double m_lowerLimit;
365  double m_upperLimit;
367  double m_biasFactor;
369  char m_padding1[4];
370 
371 };
372 
373 
374 
375 
377 {
378  return sizeof(btHingeConstraintData);
379 }
380 
382 SIMD_FORCE_INLINE const char* btHingeConstraint::serialize(void* dataBuffer, btSerializer* serializer) const
383 {
384  btHingeConstraintData* hingeData = (btHingeConstraintData*)dataBuffer;
385  btTypedConstraint::serialize(&hingeData->m_typeConstraintData,serializer);
386 
387  m_rbAFrame.serialize(hingeData->m_rbAFrame);
388  m_rbBFrame.serialize(hingeData->m_rbBFrame);
389 
390  hingeData->m_angularOnly = m_angularOnly;
391  hingeData->m_enableAngularMotor = m_enableAngularMotor;
392  hingeData->m_maxMotorImpulse = float(m_maxMotorImpulse);
393  hingeData->m_motorTargetVelocity = float(m_motorTargetVelocity);
394  hingeData->m_useReferenceFrameA = m_useReferenceFrameA;
395 #ifdef _BT_USE_CENTER_LIMIT_
396  hingeData->m_lowerLimit = float(m_limit.getLow());
397  hingeData->m_upperLimit = float(m_limit.getHigh());
398  hingeData->m_limitSoftness = float(m_limit.getSoftness());
399  hingeData->m_biasFactor = float(m_limit.getBiasFactor());
400  hingeData->m_relaxationFactor = float(m_limit.getRelaxationFactor());
401 #else
402  hingeData->m_lowerLimit = float(m_lowerLimit);
403  hingeData->m_upperLimit = float(m_upperLimit);
404  hingeData->m_limitSoftness = float(m_limitSoftness);
405  hingeData->m_biasFactor = float(m_biasFactor);
406  hingeData->m_relaxationFactor = float(m_relaxationFactor);
407 #endif
408 
410 }
411 
412 #endif //BT_HINGECONSTRAINT_H
btMatrix3x3 inverse() const
Return the inverse of the matrix.
Definition: btMatrix3x3.h:1025
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:1271
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:58
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
virtual int calculateSerializeBufferSize() const
btScalar getHigh() const
btVector3 & getOrigin()
Return the origin vector translation.
Definition: btTransform.h:117
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's parameters.
btScalar getSign() const
Returns sign value evaluated when test() was invoked.
btScalar getMaxMotorImpulse()
btTransform m_rbBFrame
btScalar getSoftness() const
Returns limit's softness.
void setAxis(btVector3 &axisInA)
btScalar getBiasFactor() const
Returns limit's bias factor.
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:59
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:59
btTransform & getAFrame()
btScalar btNormalizeAngle(btScalar angleInRadians)
Definition: btScalar.h:674
void setAngularOnly(bool angularOnly)
The btTransform class supports rigid transforms with only translation and rotation and no scaling/she...
Definition: btTransform.h:34
btScalar getRelaxationFactor() const
Returns limit's relaxation factor.
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:357
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)
btTransform & getFrameOffsetB()
btTransformDoubleData m_rbBFrame
btRigidBody & getRigidBodyB()
#define btHingeConstraintDataName
btTransformDoubleData m_rbAFrame
The btQuaternion implements quaternion to perform linear algebra rotations in combination with btMatr...
Definition: btQuaternion.h:48
void serialize(struct btTransformData &dataOut) const
Definition: btTransform.h:267
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:266
void enableAngularMotor(bool enableMotor, btScalar targetVelocity, btScalar maxMotorImpulse)
btTransformFloatData m_rbBFrame