Bullet Collision Detection & Physics Library
btGeneric6DofConstraint.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 
18 
19 /*
20 2007-09-09
21 btGeneric6DofConstraint Refactored by Francisco Le?n
22 email: projectileman@yahoo.com
23 http://gimpact.sf.net
24 */
25 
26 
27 #ifndef BT_GENERIC_6DOF_CONSTRAINT_H
28 #define BT_GENERIC_6DOF_CONSTRAINT_H
29 
30 #include "LinearMath/btVector3.h"
31 #include "btJacobianEntry.h"
32 #include "btTypedConstraint.h"
33 
34 class btRigidBody;
35 
36 
37 
38 
41 {
42 public:
57 
59 
67 
69  {
71  m_targetVelocity = 0;
72  m_maxMotorForce = 0.1f;
73  m_maxLimitForce = 300.0f;
74  m_loLimit = 1.0f;
75  m_hiLimit = -1.0f;
76  m_normalCFM = 0.f;
77  m_stopERP = 0.2f;
78  m_stopCFM = 0.f;
79  m_bounce = 0.0f;
80  m_damping = 1.0f;
81  m_limitSoftness = 0.5f;
82  m_currentLimit = 0;
84  m_enableMotor = false;
85  }
86 
88  {
92  m_loLimit = limot.m_loLimit;
93  m_hiLimit = limot.m_hiLimit;
94  m_normalCFM = limot.m_normalCFM;
95  m_stopERP = limot.m_stopERP;
96  m_stopCFM = limot.m_stopCFM;
97  m_bounce = limot.m_bounce;
101  }
102 
103 
104 
106  bool isLimited()
107  {
108  if(m_loLimit > m_hiLimit) return false;
109  return true;
110  }
111 
114  {
115  if(m_currentLimit == 0 && m_enableMotor == false) return false;
116  return true;
117  }
118 
120 
123  int testLimitValue(btScalar test_value);
124 
126  btScalar solveAngularLimits(btScalar timeStep,btVector3& axis, btScalar jacDiagABInv,btRigidBody * body0, btRigidBody * body1);
127 
128 };
129 
130 
131 
133 {
134 public:
146  bool m_enableMotor[3];
153 
155  {
156  m_lowerLimit.setValue(0.f,0.f,0.f);
157  m_upperLimit.setValue(0.f,0.f,0.f);
158  m_accumulatedImpulse.setValue(0.f,0.f,0.f);
159  m_normalCFM.setValue(0.f, 0.f, 0.f);
160  m_stopERP.setValue(0.2f, 0.2f, 0.2f);
161  m_stopCFM.setValue(0.f, 0.f, 0.f);
162 
163  m_limitSoftness = 0.7f;
164  m_damping = btScalar(1.0f);
165  m_restitution = btScalar(0.5f);
166  for(int i=0; i < 3; i++)
167  {
168  m_enableMotor[i] = false;
169  m_targetVelocity[i] = btScalar(0.f);
170  m_maxMotorForce[i] = btScalar(0.f);
171  }
172  }
173 
175  {
176  m_lowerLimit = other.m_lowerLimit;
177  m_upperLimit = other.m_upperLimit;
179 
181  m_damping = other.m_damping;
183  m_normalCFM = other.m_normalCFM;
184  m_stopERP = other.m_stopERP;
185  m_stopCFM = other.m_stopCFM;
186 
187  for(int i=0; i < 3; i++)
188  {
189  m_enableMotor[i] = other.m_enableMotor[i];
190  m_targetVelocity[i] = other.m_targetVelocity[i];
191  m_maxMotorForce[i] = other.m_maxMotorForce[i];
192  }
193  }
194 
196 
202  inline bool isLimited(int limitIndex)
203  {
204  return (m_upperLimit[limitIndex] >= m_lowerLimit[limitIndex]);
205  }
206  inline bool needApplyForce(int limitIndex)
207  {
208  if(m_currentLimit[limitIndex] == 0 && m_enableMotor[limitIndex] == false) return false;
209  return true;
210  }
211  int testLimitValue(int limitIndex, btScalar test_value);
212 
213 
215  btScalar timeStep,
216  btScalar jacDiagABInv,
217  btRigidBody& body1,const btVector3 &pointInA,
218  btRigidBody& body2,const btVector3 &pointInB,
219  int limit_index,
220  const btVector3 & axis_normal_on_a,
221  const btVector3 & anchorPos);
222 
223 
224 };
225 
227 {
231 };
232 #define BT_6DOF_FLAGS_AXIS_SHIFT 3 // bits per axis
233 
234 
236 
272 {
273 protected:
274 
279 
283  btJacobianEntry m_jacLinear[3];
284  btJacobianEntry m_jacAng[3];
285 
291 
292 
295  btRotationalLimitMotor m_angularLimits[3];
297 
298 
299 protected:
306  btVector3 m_calculatedAxis[3];
311 
312  btVector3 m_AnchorPos; // point betwen pivots of bodies A and B to solve linear axes
313 
316 
317  int m_flags;
318 
320 
322  {
323  btAssert(0);
324  (void) other;
325  return *this;
326  }
327 
328 
329  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);
330 
331  int setLinearLimits(btConstraintInfo2 *info, int row, const btTransform& transA,const btTransform& transB,const btVector3& linVelA,const btVector3& linVelB,const btVector3& angVelA,const btVector3& angVelB);
332 
333  void buildLinearJacobian(
334  btJacobianEntry & jacLinear,const btVector3 & normalWorld,
335  const btVector3 & pivotAInW,const btVector3 & pivotBInW);
336 
337  void buildAngularJacobian(btJacobianEntry & jacAngular,const btVector3 & jointAxisW);
338 
339  // tests linear limits
340  void calculateLinearInfo();
341 
343  void calculateAngleInfo();
344 
345 
346 
347 public:
348 
350 
353 
354  btGeneric6DofConstraint(btRigidBody& rbA, btRigidBody& rbB, const btTransform& frameInA, const btTransform& frameInB ,bool useLinearReferenceFrameA);
355  btGeneric6DofConstraint(btRigidBody& rbB, const btTransform& frameInB, bool useLinearReferenceFrameB);
356 
358 
362  void calculateTransforms(const btTransform& transA,const btTransform& transB);
363 
364  void calculateTransforms();
365 
367 
371  {
372  return m_calculatedTransformA;
373  }
374 
376 
380  {
381  return m_calculatedTransformB;
382  }
383 
384  const btTransform & getFrameOffsetA() const
385  {
386  return m_frameInA;
387  }
388 
389  const btTransform & getFrameOffsetB() const
390  {
391  return m_frameInB;
392  }
393 
394 
396  {
397  return m_frameInA;
398  }
399 
401  {
402  return m_frameInB;
403  }
404 
405 
407  virtual void buildJacobian();
408 
409  virtual void getInfo1 (btConstraintInfo1* info);
410 
411  void getInfo1NonVirtual (btConstraintInfo1* info);
412 
413  virtual void getInfo2 (btConstraintInfo2* info);
414 
415  void getInfo2NonVirtual (btConstraintInfo2* info,const btTransform& transA,const btTransform& transB,const btVector3& linVelA,const btVector3& linVelB,const btVector3& angVelA,const btVector3& angVelB);
416 
417 
418  void updateRHS(btScalar timeStep);
419 
421 
424  btVector3 getAxis(int axis_index) const;
425 
427 
430  btScalar getAngle(int axis_index) const;
431 
433 
436  btScalar getRelativePivotPosition(int axis_index) const;
437 
438  void setFrames(const btTransform & frameA, const btTransform & frameB);
439 
441 
445  bool testAngularLimitMotor(int axis_index);
446 
447  void setLinearLowerLimit(const btVector3& linearLower)
448  {
449  m_linearLimits.m_lowerLimit = linearLower;
450  }
451 
452  void getLinearLowerLimit(btVector3& linearLower)
453  {
454  linearLower = m_linearLimits.m_lowerLimit;
455  }
456 
457  void setLinearUpperLimit(const btVector3& linearUpper)
458  {
459  m_linearLimits.m_upperLimit = linearUpper;
460  }
461 
462  void getLinearUpperLimit(btVector3& linearUpper)
463  {
464  linearUpper = m_linearLimits.m_upperLimit;
465  }
466 
467  void setAngularLowerLimit(const btVector3& angularLower)
468  {
469  for(int i = 0; i < 3; i++)
470  m_angularLimits[i].m_loLimit = btNormalizeAngle(angularLower[i]);
471  }
472 
473  void getAngularLowerLimit(btVector3& angularLower)
474  {
475  for(int i = 0; i < 3; i++)
476  angularLower[i] = m_angularLimits[i].m_loLimit;
477  }
478 
479  void setAngularUpperLimit(const btVector3& angularUpper)
480  {
481  for(int i = 0; i < 3; i++)
482  m_angularLimits[i].m_hiLimit = btNormalizeAngle(angularUpper[i]);
483  }
484 
485  void getAngularUpperLimit(btVector3& angularUpper)
486  {
487  for(int i = 0; i < 3; i++)
488  angularUpper[i] = m_angularLimits[i].m_hiLimit;
489  }
490 
493  {
494  return &m_angularLimits[index];
495  }
496 
499  {
500  return &m_linearLimits;
501  }
502 
503  //first 3 are linear, next 3 are angular
504  void setLimit(int axis, btScalar lo, btScalar hi)
505  {
506  if(axis<3)
507  {
508  m_linearLimits.m_lowerLimit[axis] = lo;
509  m_linearLimits.m_upperLimit[axis] = hi;
510  }
511  else
512  {
513  lo = btNormalizeAngle(lo);
514  hi = btNormalizeAngle(hi);
515  m_angularLimits[axis-3].m_loLimit = lo;
516  m_angularLimits[axis-3].m_hiLimit = hi;
517  }
518  }
519 
521 
527  bool isLimited(int limitIndex)
528  {
529  if(limitIndex<3)
530  {
531  return m_linearLimits.isLimited(limitIndex);
532 
533  }
534  return m_angularLimits[limitIndex-3].isLimited();
535  }
536 
537  virtual void calcAnchorPos(void); // overridable
538 
539  int get_limit_motor_info2( btRotationalLimitMotor * limot,
540  const btTransform& transA,const btTransform& transB,const btVector3& linVelA,const btVector3& linVelB,const btVector3& angVelA,const btVector3& angVelB,
541  btConstraintInfo2 *info, int row, btVector3& ax1, int rotational, int rotAllowed = false);
542 
543  // access for UseFrameOffset
544  bool getUseFrameOffset() { return m_useOffsetForConstraintFrame; }
545  void setUseFrameOffset(bool frameOffsetOnOff) { m_useOffsetForConstraintFrame = frameOffsetOnOff; }
546 
549  virtual void setParam(int num, btScalar value, int axis = -1);
551  virtual btScalar getParam(int num, int axis = -1) const;
552 
553  void setAxis( const btVector3& axis1, const btVector3& axis2);
554 
555 
556  virtual int calculateSerializeBufferSize() const;
557 
559  virtual const char* serialize(void* dataBuffer, btSerializer* serializer) const;
560 
561 
562 };
563 
566 {
568  btTransformFloatData m_rbAFrame; // constraint axii. Assumes z is hinge axis.
570 
573 
576 
579 };
580 
582 {
583  return sizeof(btGeneric6DofConstraintData);
584 }
585 
587 SIMD_FORCE_INLINE const char* btGeneric6DofConstraint::serialize(void* dataBuffer, btSerializer* serializer) const
588 {
589 
592 
595 
596 
597  int i;
598  for (i=0;i<3;i++)
599  {
600  dof->m_angularLowerLimit.m_floats[i] = float(m_angularLimits[i].m_loLimit);
601  dof->m_angularUpperLimit.m_floats[i] = float(m_angularLimits[i].m_hiLimit);
604  }
605 
608 
609  return "btGeneric6DofConstraintData";
610 }
611 
612 
613 
614 
615 
616 #endif //BT_GENERIC_6DOF_CONSTRAINT_H