Blender  V3.3
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
67  btScalar m_limitSign;
68  btScalar m_correction;
69 
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 
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  {
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.
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
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 
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
315  void setUseFrameOffset(bool frameOffsetOnOff) { m_useOffsetForConstraintFrame = frameOffsetOnOff; }
316  // access for 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 
360 ATTRIBUTE_ALIGNED16(class)
362 {
363 protected:
364  btScalar m_accumulatedAngle;
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  }
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
typedef float(TangentPoint)[2]
__forceinline ssef low(const avxf &a)
Definition: avxf.h:264
__forceinline ssef high(const avxf &a)
Definition: avxf.h:268
btScalar m_limitSoftness
btScalar m_biasFactor
btScalar m_relaxationFactor
btFixedConstraint btRigidBody & rbB
btScalar m_referenceSign
BT_DECLARE_ALIGNED_ALLOCATOR()
const btTransform & getAFrame() const
void setAccumulatedHingeAngle(btScalar accAngle)
btAngularLimit m_limit
virtual void getInfo2(btConstraintInfo2 *info)
btScalar getHingeAngle()
The getHingeAngle gives the hinge angle in range [-PI,PI].
void setMotorTarget(const btQuaternion &qAinB, btScalar dt)
btHingeAccumulatedAngleConstraint(btRigidBody &rbA, btRigidBody &rbB, const btVector3 &pivotInA, const btVector3 &pivotInB, const btVector3 &axisInA, const btVector3 &axisInB, bool useReferenceFrameA=false)
btTransform m_rbBFrame
void getInfo2NonVirtual(btConstraintInfo2 *info, const btTransform &transA, const btTransform &transB, const btVector3 &angVelA, const btVector3 &angVelB)
btScalar m_accMotorImpulse
btScalar m_stopERP
virtual void setParam(int num, btScalar value, int axis=-1)
btScalar getLimitBiasFactor() const
const btTransform & getBFrame() const
bool m_useReferenceFrameA
virtual int calculateSerializeBufferSize() const
btJacobianEntry m_jacAng[3]
btScalar getLowerLimit() const
btTransform & getFrameOffsetA()
btScalar getMotorTargetVelocity()
bool hasLimit() const
btScalar getLimitSign()
bool getUseReferenceFrameA() const
bool m_useSolveConstraintObsolete
void setUseFrameOffset(bool frameOffsetOnOff)
void setUseReferenceFrameA(bool useReferenceFrameA)
btScalar m_maxMotorImpulse
virtual int getFlags() const
btHingeConstraint(btRigidBody &rbA, btRigidBody &rbB, const btVector3 &pivotInA, const btVector3 &pivotInB, const btVector3 &axisInA, const btVector3 &axisInB, bool useReferenceFrameA=false)
void setMotorTargetVelocity(btScalar motorTargetVelocity)
void setLimit(btScalar low, btScalar high, btScalar _softness=0.9f, btScalar _biasFactor=0.3f, btScalar _relaxationFactor=1.0f)
bool getUseFrameOffset()
const btRigidBody & getRigidBodyA() const
btScalar getLimitRelaxationFactor() const
bool m_enableAngularMotor
btScalar m_kHinge
const btRigidBody & getRigidBodyB() const
virtual btScalar getParam(int num, int axis=-1) const
return the local value of parameter
btScalar getUpperLimit() const
btScalar getAccumulatedHingeAngle()
void enableAngularMotor(bool enableMotor, btScalar targetVelocity, btScalar maxMotorImpulse)
bool getEnableAngularMotor()
int getSolveLimit()
btHingeFlags
@ BT_HINGE_FLAGS_CFM_STOP
@ BT_HINGE_FLAGS_CFM_NORM
@ BT_HINGE_FLAGS_ERP_NORM
@ BT_HINGE_FLAGS_ERP_STOP
btScalar m_accLimitImpulse
void setFrames(const btTransform &frameA, const btTransform &frameB)
btScalar m_hingeAngle
virtual void buildJacobian()
obsolete methods
void setAngularOnly(bool angularOnly)
btScalar m_motorTargetVelocity
void getInfo1NonVirtual(btConstraintInfo1 *info)
btScalar getLimitSoftness() const
btTransform m_rbAFrame
void getInfo2Internal(btConstraintInfo2 *info, const btTransform &transA, const btTransform &transB, const btVector3 &angVelA, const btVector3 &angVelB)
virtual void getInfo1(btConstraintInfo1 *info)
bool getAngularOnly()
btScalar getMaxMotorImpulse()
btScalar m_normalCFM
void getInfo2InternalUsingFrameOffset(btConstraintInfo2 *info, const btTransform &transA, const btTransform &transB, const btVector3 &angVelA, const btVector3 &angVelB)
bool m_angularOnly
int m_flags
void testLimit(const btTransform &transA, const btTransform &transB)
void setAxis(btVector3 &axisInA)
void setMaxMotorImpulse(btScalar maxMotorImpulse)
#define btHingeConstraintData
void enableMotor(bool enableMotor)
#define btHingeConstraintDataName
btScalar m_stopCFM
bool m_useOffsetForConstraintFrame
btTransform & getFrameOffsetB()
btScalar m_normalERP
virtual const char * serialize(void *dataBuffer, btSerializer *serializer) const
fills the dataBuffer and returns the struct name (and 0 on failure)
void updateRHS(btScalar timeStep)
btJacobianEntry
btScalar m_lowerLimit
btScalar m_upperLimit
SIMD_FORCE_INLINE btQuaternion shortestArcQuat(const btVector3 &v0, const btVector3 &v1)
Definition: btQuaternion.h:940
SIMD_FORCE_INLINE btVector3 quatRotate(const btQuaternion &rotation, const btVector3 &v)
Definition: btQuaternion.h:926
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
btTransform
The btTransform class supports rigid transforms with only translation and rotation and no scaling/she...
Definition: btTransform.h:30
btRigidBody & m_rbA
btTypedConstraint(btTypedConstraintType type, btRigidBody &rbA)
btRigidBody & m_rbB
SIMD_FORCE_INLINE void btPlaneSpace1(const T &n, T &p, T &q)
Definition: btVector3.h:1251
btVector3
btVector3 can be used to represent 3D points and vectors. It has an un-used w component to suit 16-by...
Definition: btVector3.h:82
bool isLimit() const
Returns true when the last test() invocation recognized limit violation.
btScalar getBiasFactor() const
Returns limit's bias factor.
btScalar getLow() const
btScalar getHigh() const
btScalar getSoftness() const
Returns limit's softness.
btScalar getSign() const
Returns sign value evaluated when test() was invoked.
void set(btScalar low, btScalar high, btScalar _softness=0.9f, btScalar _biasFactor=0.3f, btScalar _relaxationFactor=1.0f)
btScalar getHalfRange() const
Gives half of the distance between min and max limit angle.
btScalar getRelaxationFactor() const
Returns limit's relaxation factor.
The btQuaternion implements quaternion to perform linear algebra rotations in combination with btMatr...
Definition: btQuaternion.h:50
const btTransform & getCenterOfMassTransform() const
Definition: btRigidBody.h:429
do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64
btTypedConstraintDoubleData m_typeConstraintData
btTransformDoubleData m_rbBFrame
btTransformDoubleData m_rbAFrame
this structure is not used, except for loading pre-2.82 .bullet files
btTransformDoubleData m_rbAFrame
btTransformDoubleData m_rbBFrame
btTypedConstraintData m_typeConstraintData
btTypedConstraintData m_typeConstraintData
btTransformFloatData m_rbAFrame
btTransformFloatData m_rbBFrame
for serialization
Definition: btTransform.h:245
this structure is not used, except for loading pre-2.82 .bullet files