Bullet Collision Detection & Physics Library
btGeneric6DofSpring2Constraint.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 /*
17 2014 May: btGeneric6DofSpring2Constraint is created from the original (2.82.2712) btGeneric6DofConstraint by Gabor Puhr and Tamas Umenhoffer
18 Pros:
19 - Much more accurate and stable in a lot of situation. (Especially when a sleeping chain of RBs connected with 6dof2 is pulled)
20 - Stable and accurate spring with minimal energy loss that works with all of the solvers. (latter is not true for the original 6dof spring)
21 - Servo motor functionality
22 - Much more accurate bouncing. 0 really means zero bouncing (not true for the original 6odf) and there is only a minimal energy loss when the value is 1 (because of the solvers' precision)
23 - Rotation order for the Euler system can be set. (One axis' freedom is still limited to pi/2)
24 
25 Cons:
26 - It is slower than the original 6dof. There is no exact ratio, but half speed is a good estimation.
27 - At bouncing the correct velocity is calculated, but not the correct position. (it is because of the solver can correct position or velocity, but not both.)
28 */
29 
32 
33 /*
34 2007-09-09
35 btGeneric6DofConstraint Refactored by Francisco Le?n
36 email: projectileman@yahoo.com
37 http://gimpact.sf.net
38 */
39 
40 #ifndef BT_GENERIC_6DOF_CONSTRAINT2_H
41 #define BT_GENERIC_6DOF_CONSTRAINT2_H
42 
43 #include "LinearMath/btVector3.h"
44 #include "btJacobianEntry.h"
45 #include "btTypedConstraint.h"
46 
47 class btRigidBody;
48 
49 #ifdef BT_USE_DOUBLE_PRECISION
50 #define btGeneric6DofSpring2ConstraintData2 btGeneric6DofSpring2ConstraintDoubleData2
51 #define btGeneric6DofSpring2ConstraintDataName "btGeneric6DofSpring2ConstraintDoubleData2"
52 #else
53 #define btGeneric6DofSpring2ConstraintData2 btGeneric6DofSpring2ConstraintData
54 #define btGeneric6DofSpring2ConstraintDataName "btGeneric6DofSpring2ConstraintData"
55 #endif //BT_USE_DOUBLE_PRECISION
56 
58 {
59  RO_XYZ = 0,
65 };
66 
68 {
69 public:
70  // upper < lower means free
71  // upper == lower means locked
72  // upper > lower means limited
91 
96 
98  {
99  m_loLimit = 1.0f;
100  m_hiLimit = -1.0f;
101  m_bounce = 0.0f;
102  m_stopERP = 0.2f;
103  m_stopCFM = 0.f;
104  m_motorERP = 0.9f;
105  m_motorCFM = 0.f;
106  m_enableMotor = false;
107  m_targetVelocity = 0;
108  m_maxMotorForce = 6.0f;
109  m_servoMotor = false;
110  m_servoTarget = 0;
111  m_enableSpring = false;
112  m_springStiffness = 0;
113  m_springStiffnessLimited = false;
114  m_springDamping = 0;
115  m_springDampingLimited = false;
116  m_equilibriumPoint = 0;
117 
120  m_currentPosition = 0;
121  m_currentLimit = 0;
122  }
123 
125  {
126  m_loLimit = limot.m_loLimit;
127  m_hiLimit = limot.m_hiLimit;
128  m_bounce = limot.m_bounce;
129  m_stopERP = limot.m_stopERP;
130  m_stopCFM = limot.m_stopCFM;
131  m_motorERP = limot.m_motorERP;
132  m_motorCFM = limot.m_motorCFM;
136  m_servoMotor = limot.m_servoMotor;
144 
149  }
150 
151  bool isLimited()
152  {
153  if (m_loLimit > m_hiLimit) return false;
154  return true;
155  }
156 
157  void testLimitValue(btScalar test_value);
158 };
159 
161 {
162 public:
163  // upper < lower means free
164  // upper == lower means locked
165  // upper > lower means limited
173  bool m_enableMotor[3];
174  bool m_servoMotor[3];
175  bool m_enableSpring[3];
184 
189 
191  {
192  m_lowerLimit.setValue(0.f, 0.f, 0.f);
193  m_upperLimit.setValue(0.f, 0.f, 0.f);
194  m_bounce.setValue(0.f, 0.f, 0.f);
195  m_stopERP.setValue(0.2f, 0.2f, 0.2f);
196  m_stopCFM.setValue(0.f, 0.f, 0.f);
197  m_motorERP.setValue(0.9f, 0.9f, 0.9f);
198  m_motorCFM.setValue(0.f, 0.f, 0.f);
199 
200  m_currentLimitError.setValue(0.f, 0.f, 0.f);
201  m_currentLimitErrorHi.setValue(0.f, 0.f, 0.f);
202  m_currentLinearDiff.setValue(0.f, 0.f, 0.f);
203 
204  for (int i = 0; i < 3; i++)
205  {
206  m_enableMotor[i] = false;
207  m_servoMotor[i] = false;
208  m_enableSpring[i] = false;
209  m_servoTarget[i] = btScalar(0.f);
210  m_springStiffness[i] = btScalar(0.f);
211  m_springStiffnessLimited[i] = false;
212  m_springDamping[i] = btScalar(0.f);
213  m_springDampingLimited[i] = false;
214  m_equilibriumPoint[i] = btScalar(0.f);
215  m_targetVelocity[i] = btScalar(0.f);
216  m_maxMotorForce[i] = btScalar(0.f);
217 
218  m_currentLimit[i] = 0;
219  }
220  }
221 
223  {
224  m_lowerLimit = other.m_lowerLimit;
225  m_upperLimit = other.m_upperLimit;
226  m_bounce = other.m_bounce;
227  m_stopERP = other.m_stopERP;
228  m_stopCFM = other.m_stopCFM;
229  m_motorERP = other.m_motorERP;
230  m_motorCFM = other.m_motorCFM;
231 
235 
236  for (int i = 0; i < 3; i++)
237  {
238  m_enableMotor[i] = other.m_enableMotor[i];
239  m_servoMotor[i] = other.m_servoMotor[i];
240  m_enableSpring[i] = other.m_enableSpring[i];
241  m_servoTarget[i] = other.m_servoTarget[i];
242  m_springStiffness[i] = other.m_springStiffness[i];
244  m_springDamping[i] = other.m_springDamping[i];
247  m_targetVelocity[i] = other.m_targetVelocity[i];
248  m_maxMotorForce[i] = other.m_maxMotorForce[i];
249 
250  m_currentLimit[i] = other.m_currentLimit[i];
251  }
252  }
253 
254  inline bool isLimited(int limitIndex)
255  {
256  return (m_upperLimit[limitIndex] >= m_lowerLimit[limitIndex]);
257  }
258 
259  void testLimitValue(int limitIndex, btScalar test_value);
260 };
261 
263 {
268 };
269 #define BT_6DOF_FLAGS_AXIS_SHIFT2 4 // bits per axis
270 
273 {
274 protected:
277 
278  btJacobianEntry m_jacLinear[3];
279  btJacobianEntry m_jacAng[3];
280 
282  btRotationalLimitMotor2 m_angularLimits[3];
283 
285 
286 protected:
290  btVector3 m_calculatedAxis[3];
295  int m_flags;
296 
298  {
299  btAssert(0);
300  return *this;
301  }
302 
303  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);
304  int setLinearLimits(btConstraintInfo2 * info, int row, const btTransform& transA, const btTransform& transB, const btVector3& linVelA, const btVector3& linVelB, const btVector3& angVelA, const btVector3& angVelB);
305 
306  void calculateLinearInfo();
307  void calculateAngleInfo();
308  void testAngularLimitMotor(int axis_index);
309 
310  void calculateJacobi(btRotationalLimitMotor2 * limot, const btTransform& transA, const btTransform& transB, btConstraintInfo2* info, int srow, btVector3& ax1, int rotational, int rotAllowed);
311  int get_limit_motor_info2(btRotationalLimitMotor2 * limot,
312  const btTransform& transA, const btTransform& transB, const btVector3& linVelA, const btVector3& linVelB, const btVector3& angVelA, const btVector3& angVelB,
313  btConstraintInfo2* info, int row, btVector3& ax1, int rotational, int rotAllowed = false);
314 
315 public:
317 
318  btGeneric6DofSpring2Constraint(btRigidBody & rbA, btRigidBody & rbB, const btTransform& frameInA, const btTransform& frameInB, RotateOrder rotOrder = RO_XYZ);
319  btGeneric6DofSpring2Constraint(btRigidBody & rbB, const btTransform& frameInB, RotateOrder rotOrder = RO_XYZ);
320 
321  virtual void buildJacobian() {}
322  virtual void getInfo1(btConstraintInfo1 * info);
323  virtual void getInfo2(btConstraintInfo2 * info);
324  virtual int calculateSerializeBufferSize() const;
325  virtual const char* serialize(void* dataBuffer, btSerializer* serializer) const;
326 
327  btRotationalLimitMotor2* getRotationalLimitMotor(int index) { return &m_angularLimits[index]; }
329 
330  // Calculates the global transform for the joint offset for body A an B, and also calculates the angle differences between the bodies.
331  void calculateTransforms(const btTransform& transA, const btTransform& transB);
332  void calculateTransforms();
333 
334  // Gets the global transform of the offset for body A
335  const btTransform& getCalculatedTransformA() const { return m_calculatedTransformA; }
336  // Gets the global transform of the offset for body B
337  const btTransform& getCalculatedTransformB() const { return m_calculatedTransformB; }
338 
339  const btTransform& getFrameOffsetA() const { return m_frameInA; }
340  const btTransform& getFrameOffsetB() const { return m_frameInB; }
341 
342  btTransform& getFrameOffsetA() { return m_frameInA; }
343  btTransform& getFrameOffsetB() { return m_frameInB; }
344 
345  // Get the rotation axis in global coordinates ( btGeneric6DofSpring2Constraint::calculateTransforms() must be called previously )
346  btVector3 getAxis(int axis_index) const { return m_calculatedAxis[axis_index]; }
347 
348  // Get the relative Euler angle ( btGeneric6DofSpring2Constraint::calculateTransforms() must be called previously )
349  btScalar getAngle(int axis_index) const { return m_calculatedAxisAngleDiff[axis_index]; }
350 
351  // Get the relative position of the constraint pivot ( btGeneric6DofSpring2Constraint::calculateTransforms() must be called previously )
352  btScalar getRelativePivotPosition(int axis_index) const { return m_calculatedLinearDiff[axis_index]; }
353 
354  void setFrames(const btTransform& frameA, const btTransform& frameB);
355 
356  void setLinearLowerLimit(const btVector3& linearLower) { m_linearLimits.m_lowerLimit = linearLower; }
357  void getLinearLowerLimit(btVector3 & linearLower) { linearLower = m_linearLimits.m_lowerLimit; }
358  void setLinearUpperLimit(const btVector3& linearUpper) { m_linearLimits.m_upperLimit = linearUpper; }
359  void getLinearUpperLimit(btVector3 & linearUpper) { linearUpper = m_linearLimits.m_upperLimit; }
360 
361  void setAngularLowerLimit(const btVector3& angularLower)
362  {
363  for (int i = 0; i < 3; i++)
364  m_angularLimits[i].m_loLimit = btNormalizeAngle(angularLower[i]);
365  }
366 
367  void setAngularLowerLimitReversed(const btVector3& angularLower)
368  {
369  for (int i = 0; i < 3; i++)
370  m_angularLimits[i].m_hiLimit = btNormalizeAngle(-angularLower[i]);
371  }
372 
373  void getAngularLowerLimit(btVector3 & angularLower)
374  {
375  for (int i = 0; i < 3; i++)
376  angularLower[i] = m_angularLimits[i].m_loLimit;
377  }
378 
380  {
381  for (int i = 0; i < 3; i++)
382  angularLower[i] = -m_angularLimits[i].m_hiLimit;
383  }
384 
385  void setAngularUpperLimit(const btVector3& angularUpper)
386  {
387  for (int i = 0; i < 3; i++)
388  m_angularLimits[i].m_hiLimit = btNormalizeAngle(angularUpper[i]);
389  }
390 
391  void setAngularUpperLimitReversed(const btVector3& angularUpper)
392  {
393  for (int i = 0; i < 3; i++)
394  m_angularLimits[i].m_loLimit = btNormalizeAngle(-angularUpper[i]);
395  }
396 
397  void getAngularUpperLimit(btVector3 & angularUpper)
398  {
399  for (int i = 0; i < 3; i++)
400  angularUpper[i] = m_angularLimits[i].m_hiLimit;
401  }
402 
404  {
405  for (int i = 0; i < 3; i++)
406  angularUpper[i] = -m_angularLimits[i].m_loLimit;
407  }
408 
409  //first 3 are linear, next 3 are angular
410 
411  void setLimit(int axis, btScalar lo, btScalar hi)
412  {
413  if (axis < 3)
414  {
415  m_linearLimits.m_lowerLimit[axis] = lo;
416  m_linearLimits.m_upperLimit[axis] = hi;
417  }
418  else
419  {
420  lo = btNormalizeAngle(lo);
421  hi = btNormalizeAngle(hi);
422  m_angularLimits[axis - 3].m_loLimit = lo;
423  m_angularLimits[axis - 3].m_hiLimit = hi;
424  }
425  }
426 
427  void setLimitReversed(int axis, btScalar lo, btScalar hi)
428  {
429  if (axis < 3)
430  {
431  m_linearLimits.m_lowerLimit[axis] = lo;
432  m_linearLimits.m_upperLimit[axis] = hi;
433  }
434  else
435  {
436  lo = btNormalizeAngle(lo);
437  hi = btNormalizeAngle(hi);
438  m_angularLimits[axis - 3].m_hiLimit = -lo;
439  m_angularLimits[axis - 3].m_loLimit = -hi;
440  }
441  }
442 
443  bool isLimited(int limitIndex)
444  {
445  if (limitIndex < 3)
446  {
447  return m_linearLimits.isLimited(limitIndex);
448  }
449  return m_angularLimits[limitIndex - 3].isLimited();
450  }
451 
452  void setRotationOrder(RotateOrder order) { m_rotateOrder = order; }
453  RotateOrder getRotationOrder() { return m_rotateOrder; }
454 
455  void setAxis(const btVector3& axis1, const btVector3& axis2);
456 
457  void setBounce(int index, btScalar bounce);
458 
459  void enableMotor(int index, bool onOff);
460  void setServo(int index, bool onOff); // set the type of the motor (servo or not) (the motor has to be turned on for servo also)
461  void setTargetVelocity(int index, btScalar velocity);
462  void setServoTarget(int index, btScalar target);
463  void setMaxMotorForce(int index, btScalar force);
464 
465  void enableSpring(int index, bool onOff);
466  void setStiffness(int index, btScalar stiffness, bool limitIfNeeded = true); // if limitIfNeeded is true the system will automatically limit the stiffness in necessary situations where otherwise the spring would move unrealistically too widely
467  void setDamping(int index, btScalar damping, bool limitIfNeeded = true); // if limitIfNeeded is true the system will automatically limit the damping in necessary situations where otherwise the spring would blow up
468  void setEquilibriumPoint(); // set the current constraint position/orientation as an equilibrium point for all DOF
469  void setEquilibriumPoint(int index); // set the current constraint position/orientation as an equilibrium point for given DOF
470  void setEquilibriumPoint(int index, btScalar val);
471 
472  //override the default global value of a parameter (such as ERP or CFM), optionally provide the axis (0..5).
473  //If no axis is provided, it uses the default axis for this constraint.
474  virtual void setParam(int num, btScalar value, int axis = -1);
475  virtual btScalar getParam(int num, int axis = -1) const;
476 
477  static btScalar btGetMatrixElem(const btMatrix3x3& mat, int index);
478  static bool matrixToEulerXYZ(const btMatrix3x3& mat, btVector3& xyz);
479  static bool matrixToEulerXZY(const btMatrix3x3& mat, btVector3& xyz);
480  static bool matrixToEulerYXZ(const btMatrix3x3& mat, btVector3& xyz);
481  static bool matrixToEulerYZX(const btMatrix3x3& mat, btVector3& xyz);
482  static bool matrixToEulerZXY(const btMatrix3x3& mat, btVector3& xyz);
483  static bool matrixToEulerZYX(const btMatrix3x3& mat, btVector3& xyz);
484 };
485 
487 {
491 
510  char m_padding1[4];
511 
530 
532 };
533 
535 {
539 
558  char m_padding1[4];
559 
578 
580 };
581 
583 {
585 }
586 
587 SIMD_FORCE_INLINE const char* btGeneric6DofSpring2Constraint::serialize(void* dataBuffer, btSerializer* serializer) const
588 {
590  btTypedConstraint::serialize(&dof->m_typeConstraintData, serializer);
591 
592  m_frameInA.serialize(dof->m_rbAFrame);
593  m_frameInB.serialize(dof->m_rbBFrame);
594 
595  int i;
596  for (i = 0; i < 3; i++)
597  {
598  dof->m_angularLowerLimit.m_floats[i] = m_angularLimits[i].m_loLimit;
599  dof->m_angularUpperLimit.m_floats[i] = m_angularLimits[i].m_hiLimit;
600  dof->m_angularBounce.m_floats[i] = m_angularLimits[i].m_bounce;
601  dof->m_angularStopERP.m_floats[i] = m_angularLimits[i].m_stopERP;
602  dof->m_angularStopCFM.m_floats[i] = m_angularLimits[i].m_stopCFM;
603  dof->m_angularMotorERP.m_floats[i] = m_angularLimits[i].m_motorERP;
604  dof->m_angularMotorCFM.m_floats[i] = m_angularLimits[i].m_motorCFM;
605  dof->m_angularTargetVelocity.m_floats[i] = m_angularLimits[i].m_targetVelocity;
606  dof->m_angularMaxMotorForce.m_floats[i] = m_angularLimits[i].m_maxMotorForce;
607  dof->m_angularServoTarget.m_floats[i] = m_angularLimits[i].m_servoTarget;
608  dof->m_angularSpringStiffness.m_floats[i] = m_angularLimits[i].m_springStiffness;
609  dof->m_angularSpringDamping.m_floats[i] = m_angularLimits[i].m_springDamping;
610  dof->m_angularEquilibriumPoint.m_floats[i] = m_angularLimits[i].m_equilibriumPoint;
611  }
612  dof->m_angularLowerLimit.m_floats[3] = 0;
613  dof->m_angularUpperLimit.m_floats[3] = 0;
614  dof->m_angularBounce.m_floats[3] = 0;
615  dof->m_angularStopERP.m_floats[3] = 0;
616  dof->m_angularStopCFM.m_floats[3] = 0;
617  dof->m_angularMotorERP.m_floats[3] = 0;
618  dof->m_angularMotorCFM.m_floats[3] = 0;
619  dof->m_angularTargetVelocity.m_floats[3] = 0;
620  dof->m_angularMaxMotorForce.m_floats[3] = 0;
621  dof->m_angularServoTarget.m_floats[3] = 0;
622  dof->m_angularSpringStiffness.m_floats[3] = 0;
623  dof->m_angularSpringDamping.m_floats[3] = 0;
624  dof->m_angularEquilibriumPoint.m_floats[3] = 0;
625  for (i = 0; i < 4; i++)
626  {
627  dof->m_angularEnableMotor[i] = i < 3 ? (m_angularLimits[i].m_enableMotor ? 1 : 0) : 0;
628  dof->m_angularServoMotor[i] = i < 3 ? (m_angularLimits[i].m_servoMotor ? 1 : 0) : 0;
629  dof->m_angularEnableSpring[i] = i < 3 ? (m_angularLimits[i].m_enableSpring ? 1 : 0) : 0;
630  dof->m_angularSpringStiffnessLimited[i] = i < 3 ? (m_angularLimits[i].m_springStiffnessLimited ? 1 : 0) : 0;
631  dof->m_angularSpringDampingLimited[i] = i < 3 ? (m_angularLimits[i].m_springDampingLimited ? 1 : 0) : 0;
632  }
633 
634  m_linearLimits.m_lowerLimit.serialize(dof->m_linearLowerLimit);
635  m_linearLimits.m_upperLimit.serialize(dof->m_linearUpperLimit);
636  m_linearLimits.m_bounce.serialize(dof->m_linearBounce);
637  m_linearLimits.m_stopERP.serialize(dof->m_linearStopERP);
638  m_linearLimits.m_stopCFM.serialize(dof->m_linearStopCFM);
639  m_linearLimits.m_motorERP.serialize(dof->m_linearMotorERP);
640  m_linearLimits.m_motorCFM.serialize(dof->m_linearMotorCFM);
641  m_linearLimits.m_targetVelocity.serialize(dof->m_linearTargetVelocity);
642  m_linearLimits.m_maxMotorForce.serialize(dof->m_linearMaxMotorForce);
643  m_linearLimits.m_servoTarget.serialize(dof->m_linearServoTarget);
644  m_linearLimits.m_springStiffness.serialize(dof->m_linearSpringStiffness);
645  m_linearLimits.m_springDamping.serialize(dof->m_linearSpringDamping);
646  m_linearLimits.m_equilibriumPoint.serialize(dof->m_linearEquilibriumPoint);
647  for (i = 0; i < 4; i++)
648  {
649  dof->m_linearEnableMotor[i] = i < 3 ? (m_linearLimits.m_enableMotor[i] ? 1 : 0) : 0;
650  dof->m_linearServoMotor[i] = i < 3 ? (m_linearLimits.m_servoMotor[i] ? 1 : 0) : 0;
651  dof->m_linearEnableSpring[i] = i < 3 ? (m_linearLimits.m_enableSpring[i] ? 1 : 0) : 0;
652  dof->m_linearSpringStiffnessLimited[i] = i < 3 ? (m_linearLimits.m_springStiffnessLimited[i] ? 1 : 0) : 0;
653  dof->m_linearSpringDampingLimited[i] = i < 3 ? (m_linearLimits.m_springDampingLimited[i] ? 1 : 0) : 0;
654  }
655 
656  dof->m_rotateOrder = m_rotateOrder;
657 
658  dof->m_padding1[0] = 0;
659  dof->m_padding1[1] = 0;
660  dof->m_padding1[2] = 0;
661  dof->m_padding1[3] = 0;
662 
664 }
665 
666 #endif //BT_GENERIC_6DOF_CONSTRAINT_H
void getAngularUpperLimitReversed(btVector3 &angularUpper)
void getAngularLowerLimitReversed(btVector3 &angularLower)
void testLimitValue(int limitIndex, btScalar test_value)
void setValue(const btScalar &_x, const btScalar &_y, const btScalar &_z)
Definition: btVector3.h:640
Jacobian entry is an abstraction that allows to describe constraints it can be used in combination wi...
void setLimit(int axis, btScalar lo, btScalar hi)
btGeneric6DofSpring2Constraint & operator=(btGeneric6DofSpring2Constraint &)
btScalar btGetMatrixElem(const btMatrix3x3 &mat, int index)
void setAngularLowerLimitReversed(const btVector3 &angularLower)
#define btAssert(x)
Definition: btScalar.h:133
void getLinearLowerLimit(btVector3 &linearLower)
#define SIMD_FORCE_INLINE
Definition: btScalar.h:83
virtual const char * serialize(void *dataBuffer, btSerializer *serializer) const
fills the dataBuffer and returns the struct name (and 0 on failure)
const btTransform & getCalculatedTransformA() const
btRotationalLimitMotor2(const btRotationalLimitMotor2 &limot)
btVector3 getAxis(int axis_index) const
void getAngularUpperLimit(btVector3 &angularUpper)
void getLinearUpperLimit(btVector3 &linearUpper)
btTranslationalLimitMotor2 * getTranslationalLimitMotor()
const btTransform & getCalculatedTransformB() const
The btRigidBody is the main class for rigid body objects.
Definition: btRigidBody.h:59
void serialize(struct btTransformData &dataOut) const
Definition: btTransform.h:256
void setLinearUpperLimit(const btVector3 &linearUpper)
btRotationalLimitMotor2 * getRotationalLimitMotor(int index)
this structure is not used, except for loading pre-2.82 .bullet files
void setLinearLowerLimit(const btVector3 &linearLower)
void setAngularLowerLimit(const btVector3 &angularLower)
virtual void buildJacobian()
internal method used by the constraint solver, don&#39;t use them directly
btVector3 can be used to represent 3D points and vectors.
Definition: btVector3.h:80
#define ATTRIBUTE_ALIGNED16(a)
Definition: btScalar.h:84
btScalar btNormalizeAngle(btScalar angleInRadians)
Definition: btScalar.h:761
#define btGeneric6DofSpring2ConstraintDataName
bool matrixToEulerXYZ(const btMatrix3x3 &mat, btVector3 &xyz)
MatrixToEulerXYZ from http://www.geometrictools.com/LibFoundation/Mathematics/Wm4Matrix3.inl.html.
The btTransform class supports rigid transforms with only translation and rotation and no scaling/she...
Definition: btTransform.h:28
void serialize(struct btVector3Data &dataOut) const
Definition: btVector3.h:1317
btScalar getRelativePivotPosition(int axis_index) const
btScalar getAngle(int axis_index) const
virtual const char * serialize(void *dataBuffer, btSerializer *serializer) const
fills the dataBuffer and returns the struct name (and 0 on failure)
TypedConstraint is the baseclass for Bullet constraints and vehicles.
void getAngularLowerLimit(btVector3 &angularLower)
for serialization
Definition: btTransform.h:244
#define BT_DECLARE_ALIGNED_ALLOCATOR()
Definition: btScalar.h:405
#define btGeneric6DofSpring2ConstraintData2
void setAngularUpperLimitReversed(const btVector3 &angularUpper)
The btMatrix3x3 class implements a 3x3 rotation matrix, to perform linear algebra in combination with...
Definition: btMatrix3x3.h:46
void testLimitValue(btScalar test_value)
void setAngularUpperLimit(const btVector3 &angularUpper)
void setLimitReversed(int axis, btScalar lo, btScalar hi)
float btScalar
The btScalar type abstracts floating point numbers, to easily switch between double and single floati...
Definition: btScalar.h:294
btTranslationalLimitMotor2(const btTranslationalLimitMotor2 &other)