Bullet Collision Detection & Physics Library
btGeneric6DofSpring2Constraint.h
Go to the documentation of this file.
1/*
2Bullet Continuous Collision Detection and Physics Library
3Copyright (c) 2003-2006 Erwin Coumans https://bulletphysics.org
4
5This software is provided 'as-is', without any express or implied warranty.
6In no event will the authors be held liable for any damages arising from the use of this software.
7Permission is granted to anyone to use this software for any purpose,
8including commercial applications, and to alter it and redistribute it freely,
9subject to the following restrictions:
10
111. 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.
122. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
133. This notice may not be removed or altered from any source distribution.
14*/
15
16/*
172014 May: btGeneric6DofSpring2Constraint is created from the original (2.82.2712) btGeneric6DofConstraint by Gabor Puhr and Tamas Umenhoffer
18Pros:
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
25Cons:
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/*
342007-09-09
35btGeneric6DofConstraint Refactored by Francisco Le?n
36email: projectileman@yahoo.com
37http://gimpact.sf.net
38*/
39
40#ifndef BT_GENERIC_6DOF_CONSTRAINT2_H
41#define BT_GENERIC_6DOF_CONSTRAINT2_H
42
44#include "btJacobianEntry.h"
45#include "btTypedConstraint.h"
46
47class 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,
64 RO_ZYX
65};
66
68{
69public:
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;
108 m_maxMotorForce = 6.0f;
109 m_servoMotor = false;
110 m_servoTarget = 0;
111 m_enableSpring = false;
114 m_springDamping = 0;
117
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;
144
149 }
150
152 {
153 if (m_loLimit > m_hiLimit) return false;
154 return true;
155 }
156
157 void testLimitValue(btScalar test_value);
158};
159
161{
162public:
163 // upper < lower means free
164 // upper == lower means locked
165 // upper > lower means limited
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;
215 m_targetVelocity[i] = btScalar(0.f);
216 m_maxMotorForce[i] = btScalar(0.f);
217
218 m_currentLimit[i] = 0;
219 }
220 }
221
223 {
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];
244 m_springDamping[i] = other.m_springDamping[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{
270#define BT_6DOF_FLAGS_AXIS_SHIFT2 4 // bits per axis
271
274{
275protected:
278
279 btJacobianEntry m_jacLinear[3];
280 btJacobianEntry m_jacAng[3];
281
283 btRotationalLimitMotor2 m_angularLimits[3];
284
286
287protected:
291 btVector3 m_calculatedAxis[3];
297
299 {
300 btAssert(0);
301 return *this;
302 }
303
304 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);
305 int setLinearLimits(btConstraintInfo2 * info, int row, const btTransform& transA, const btTransform& transB, const btVector3& linVelA, const btVector3& linVelB, const btVector3& angVelA, const btVector3& angVelB);
306
307 void calculateLinearInfo();
308 void calculateAngleInfo();
309 void testAngularLimitMotor(int axis_index);
310
311 void calculateJacobi(btRotationalLimitMotor2 * limot, const btTransform& transA, const btTransform& transB, btConstraintInfo2* info, int srow, btVector3& ax1, int rotational, int rotAllowed);
312 int get_limit_motor_info2(btRotationalLimitMotor2 * limot,
313 const btTransform& transA, const btTransform& transB, const btVector3& linVelA, const btVector3& linVelB, const btVector3& angVelA, const btVector3& angVelB,
314 btConstraintInfo2* info, int row, btVector3& ax1, int rotational, int rotAllowed = false);
315
316public:
318
319 btGeneric6DofSpring2Constraint(btRigidBody & rbA, btRigidBody & rbB, const btTransform& frameInA, const btTransform& frameInB, RotateOrder rotOrder = RO_XYZ);
320 btGeneric6DofSpring2Constraint(btRigidBody & rbB, const btTransform& frameInB, RotateOrder rotOrder = RO_XYZ);
321
322 virtual void buildJacobian() {}
323 virtual void getInfo1(btConstraintInfo1 * info);
324 virtual void getInfo2(btConstraintInfo2 * info);
325 virtual int calculateSerializeBufferSize() const;
326 virtual const char* serialize(void* dataBuffer, btSerializer* serializer) const;
327
328 btRotationalLimitMotor2* getRotationalLimitMotor(int index) { return &m_angularLimits[index]; }
330
331 // Calculates the global transform for the joint offset for body A an B, and also calculates the angle differences between the bodies.
332 void calculateTransforms(const btTransform& transA, const btTransform& transB);
333 void calculateTransforms();
334
335 // Gets the global transform of the offset for body A
336 const btTransform& getCalculatedTransformA() const { return m_calculatedTransformA; }
337 // Gets the global transform of the offset for body B
338 const btTransform& getCalculatedTransformB() const { return m_calculatedTransformB; }
339
340 const btTransform& getFrameOffsetA() const { return m_frameInA; }
341 const btTransform& getFrameOffsetB() const { return m_frameInB; }
342
343 btTransform& getFrameOffsetA() { return m_frameInA; }
344 btTransform& getFrameOffsetB() { return m_frameInB; }
345
346 // Get the rotation axis in global coordinates ( btGeneric6DofSpring2Constraint::calculateTransforms() must be called previously )
347 btVector3 getAxis(int axis_index) const { return m_calculatedAxis[axis_index]; }
348
349 // Get the relative Euler angle ( btGeneric6DofSpring2Constraint::calculateTransforms() must be called previously )
350 btScalar getAngle(int axis_index) const { return m_calculatedAxisAngleDiff[axis_index]; }
351
352 // Get the relative position of the constraint pivot ( btGeneric6DofSpring2Constraint::calculateTransforms() must be called previously )
353 btScalar getRelativePivotPosition(int axis_index) const { return m_calculatedLinearDiff[axis_index]; }
354
355 void setFrames(const btTransform& frameA, const btTransform& frameB);
356
357 void setLinearLowerLimit(const btVector3& linearLower) { m_linearLimits.m_lowerLimit = linearLower; }
358 void getLinearLowerLimit(btVector3 & linearLower) { linearLower = m_linearLimits.m_lowerLimit; }
359 void setLinearUpperLimit(const btVector3& linearUpper) { m_linearLimits.m_upperLimit = linearUpper; }
360 void getLinearUpperLimit(btVector3 & linearUpper) { linearUpper = m_linearLimits.m_upperLimit; }
361
362 void setAngularLowerLimit(const btVector3& angularLower)
363 {
364 for (int i = 0; i < 3; i++)
365 m_angularLimits[i].m_loLimit = btNormalizeAngle(angularLower[i]);
366 }
367
368 void setAngularLowerLimitReversed(const btVector3& angularLower)
369 {
370 for (int i = 0; i < 3; i++)
371 m_angularLimits[i].m_hiLimit = btNormalizeAngle(-angularLower[i]);
372 }
373
374 void getAngularLowerLimit(btVector3 & angularLower)
375 {
376 for (int i = 0; i < 3; i++)
377 angularLower[i] = m_angularLimits[i].m_loLimit;
378 }
379
381 {
382 for (int i = 0; i < 3; i++)
383 angularLower[i] = -m_angularLimits[i].m_hiLimit;
384 }
385
386 void setAngularUpperLimit(const btVector3& angularUpper)
387 {
388 for (int i = 0; i < 3; i++)
389 m_angularLimits[i].m_hiLimit = btNormalizeAngle(angularUpper[i]);
390 }
391
392 void setAngularUpperLimitReversed(const btVector3& angularUpper)
393 {
394 for (int i = 0; i < 3; i++)
395 m_angularLimits[i].m_loLimit = btNormalizeAngle(-angularUpper[i]);
396 }
397
398 void getAngularUpperLimit(btVector3 & angularUpper)
399 {
400 for (int i = 0; i < 3; i++)
401 angularUpper[i] = m_angularLimits[i].m_hiLimit;
402 }
403
405 {
406 for (int i = 0; i < 3; i++)
407 angularUpper[i] = -m_angularLimits[i].m_loLimit;
408 }
409
410 //first 3 are linear, next 3 are angular
411
412 void setLimit(int axis, btScalar lo, btScalar hi)
413 {
414 if (axis < 3)
415 {
416 m_linearLimits.m_lowerLimit[axis] = lo;
417 m_linearLimits.m_upperLimit[axis] = hi;
418 }
419 else
420 {
421 lo = btNormalizeAngle(lo);
422 hi = btNormalizeAngle(hi);
423 m_angularLimits[axis - 3].m_loLimit = lo;
424 m_angularLimits[axis - 3].m_hiLimit = hi;
425 }
426 }
427
428 void setLimitReversed(int axis, btScalar lo, btScalar hi)
429 {
430 if (axis < 3)
431 {
432 m_linearLimits.m_lowerLimit[axis] = lo;
433 m_linearLimits.m_upperLimit[axis] = hi;
434 }
435 else
436 {
437 lo = btNormalizeAngle(lo);
438 hi = btNormalizeAngle(hi);
439 m_angularLimits[axis - 3].m_hiLimit = -lo;
440 m_angularLimits[axis - 3].m_loLimit = -hi;
441 }
442 }
443
444 bool isLimited(int limitIndex)
445 {
446 if (limitIndex < 3)
447 {
448 return m_linearLimits.isLimited(limitIndex);
449 }
450 return m_angularLimits[limitIndex - 3].isLimited();
451 }
452
453 void setRotationOrder(RotateOrder order) { m_rotateOrder = order; }
454 RotateOrder getRotationOrder() { return m_rotateOrder; }
455
456 void setAxis(const btVector3& axis1, const btVector3& axis2);
457
458 void setBounce(int index, btScalar bounce);
459
460 void enableMotor(int index, bool onOff);
461 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)
462 void setTargetVelocity(int index, btScalar velocity);
463 void setServoTarget(int index, btScalar target);
464 void setMaxMotorForce(int index, btScalar force);
465
466 void enableSpring(int index, bool onOff);
467 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
468 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
469 void setEquilibriumPoint(); // set the current constraint position/orientation as an equilibrium point for all DOF
470 void setEquilibriumPoint(int index); // set the current constraint position/orientation as an equilibrium point for given DOF
471 void setEquilibriumPoint(int index, btScalar val);
472
473 //override the default global value of a parameter (such as ERP or CFM), optionally provide the axis (0..5).
474 //If no axis is provided, it uses the default axis for this constraint.
475 virtual void setParam(int num, btScalar value, int axis = -1);
476 virtual btScalar getParam(int num, int axis = -1) const;
477
478 static btScalar btGetMatrixElem(const btMatrix3x3& mat, int index);
479 static bool matrixToEulerXYZ(const btMatrix3x3& mat, btVector3& xyz);
480 static bool matrixToEulerXZY(const btMatrix3x3& mat, btVector3& xyz);
481 static bool matrixToEulerYXZ(const btMatrix3x3& mat, btVector3& xyz);
482 static bool matrixToEulerYZX(const btMatrix3x3& mat, btVector3& xyz);
483 static bool matrixToEulerZXY(const btMatrix3x3& mat, btVector3& xyz);
484 static bool matrixToEulerZYX(const btMatrix3x3& mat, btVector3& xyz);
485};
486
488{
492
511 char m_padding1[4];
512
531
533};
534
536{
540
559 char m_padding1[4];
560
579
581};
582
584{
586}
587
588SIMD_FORCE_INLINE const char* btGeneric6DofSpring2Constraint::serialize(void* dataBuffer, btSerializer* serializer) const
589{
591 btTypedConstraint::serialize(&dof->m_typeConstraintData, serializer);
592
593 m_frameInA.serialize(dof->m_rbAFrame);
594 m_frameInB.serialize(dof->m_rbBFrame);
595
596 int i;
597 for (i = 0; i < 3; i++)
598 {
599 dof->m_angularLowerLimit.m_floats[i] = m_angularLimits[i].m_loLimit;
600 dof->m_angularUpperLimit.m_floats[i] = m_angularLimits[i].m_hiLimit;
601 dof->m_angularBounce.m_floats[i] = m_angularLimits[i].m_bounce;
602 dof->m_angularStopERP.m_floats[i] = m_angularLimits[i].m_stopERP;
603 dof->m_angularStopCFM.m_floats[i] = m_angularLimits[i].m_stopCFM;
604 dof->m_angularMotorERP.m_floats[i] = m_angularLimits[i].m_motorERP;
605 dof->m_angularMotorCFM.m_floats[i] = m_angularLimits[i].m_motorCFM;
606 dof->m_angularTargetVelocity.m_floats[i] = m_angularLimits[i].m_targetVelocity;
607 dof->m_angularMaxMotorForce.m_floats[i] = m_angularLimits[i].m_maxMotorForce;
608 dof->m_angularServoTarget.m_floats[i] = m_angularLimits[i].m_servoTarget;
609 dof->m_angularSpringStiffness.m_floats[i] = m_angularLimits[i].m_springStiffness;
610 dof->m_angularSpringDamping.m_floats[i] = m_angularLimits[i].m_springDamping;
611 dof->m_angularEquilibriumPoint.m_floats[i] = m_angularLimits[i].m_equilibriumPoint;
612 }
613 dof->m_angularLowerLimit.m_floats[3] = 0;
614 dof->m_angularUpperLimit.m_floats[3] = 0;
615 dof->m_angularBounce.m_floats[3] = 0;
616 dof->m_angularStopERP.m_floats[3] = 0;
617 dof->m_angularStopCFM.m_floats[3] = 0;
618 dof->m_angularMotorERP.m_floats[3] = 0;
619 dof->m_angularMotorCFM.m_floats[3] = 0;
620 dof->m_angularTargetVelocity.m_floats[3] = 0;
621 dof->m_angularMaxMotorForce.m_floats[3] = 0;
622 dof->m_angularServoTarget.m_floats[3] = 0;
623 dof->m_angularSpringStiffness.m_floats[3] = 0;
624 dof->m_angularSpringDamping.m_floats[3] = 0;
625 dof->m_angularEquilibriumPoint.m_floats[3] = 0;
626 for (i = 0; i < 4; i++)
627 {
628 dof->m_angularEnableMotor[i] = i < 3 ? (m_angularLimits[i].m_enableMotor ? 1 : 0) : 0;
629 dof->m_angularServoMotor[i] = i < 3 ? (m_angularLimits[i].m_servoMotor ? 1 : 0) : 0;
630 dof->m_angularEnableSpring[i] = i < 3 ? (m_angularLimits[i].m_enableSpring ? 1 : 0) : 0;
631 dof->m_angularSpringStiffnessLimited[i] = i < 3 ? (m_angularLimits[i].m_springStiffnessLimited ? 1 : 0) : 0;
632 dof->m_angularSpringDampingLimited[i] = i < 3 ? (m_angularLimits[i].m_springDampingLimited ? 1 : 0) : 0;
633 }
634
635 m_linearLimits.m_lowerLimit.serialize(dof->m_linearLowerLimit);
636 m_linearLimits.m_upperLimit.serialize(dof->m_linearUpperLimit);
637 m_linearLimits.m_bounce.serialize(dof->m_linearBounce);
638 m_linearLimits.m_stopERP.serialize(dof->m_linearStopERP);
639 m_linearLimits.m_stopCFM.serialize(dof->m_linearStopCFM);
640 m_linearLimits.m_motorERP.serialize(dof->m_linearMotorERP);
641 m_linearLimits.m_motorCFM.serialize(dof->m_linearMotorCFM);
642 m_linearLimits.m_targetVelocity.serialize(dof->m_linearTargetVelocity);
643 m_linearLimits.m_maxMotorForce.serialize(dof->m_linearMaxMotorForce);
644 m_linearLimits.m_servoTarget.serialize(dof->m_linearServoTarget);
645 m_linearLimits.m_springStiffness.serialize(dof->m_linearSpringStiffness);
646 m_linearLimits.m_springDamping.serialize(dof->m_linearSpringDamping);
647 m_linearLimits.m_equilibriumPoint.serialize(dof->m_linearEquilibriumPoint);
648 for (i = 0; i < 4; i++)
649 {
650 dof->m_linearEnableMotor[i] = i < 3 ? (m_linearLimits.m_enableMotor[i] ? 1 : 0) : 0;
651 dof->m_linearServoMotor[i] = i < 3 ? (m_linearLimits.m_servoMotor[i] ? 1 : 0) : 0;
652 dof->m_linearEnableSpring[i] = i < 3 ? (m_linearLimits.m_enableSpring[i] ? 1 : 0) : 0;
653 dof->m_linearSpringStiffnessLimited[i] = i < 3 ? (m_linearLimits.m_springStiffnessLimited[i] ? 1 : 0) : 0;
654 dof->m_linearSpringDampingLimited[i] = i < 3 ? (m_linearLimits.m_springDampingLimited[i] ? 1 : 0) : 0;
655 }
656
657 dof->m_rotateOrder = m_rotateOrder;
658
659 dof->m_padding1[0] = 0;
660 dof->m_padding1[1] = 0;
661 dof->m_padding1[2] = 0;
662 dof->m_padding1[3] = 0;
663
665}
666
667#endif //BT_GENERIC_6DOF_CONSTRAINT_H
btScalar btGetMatrixElem(const btMatrix3x3 &mat, int index)
bool matrixToEulerXYZ(const btMatrix3x3 &mat, btVector3 &xyz)
MatrixToEulerXYZ from http://www.geometrictools.com/LibFoundation/Mathematics/Wm4Matrix3....
#define btGeneric6DofSpring2ConstraintData2
@ BT_6DOF_FLAGS_USE_INFINITE_ERROR
#define btGeneric6DofSpring2ConstraintDataName
btScalar btNormalizeAngle(btScalar angleInRadians)
Definition: btScalar.h:781
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:99
#define SIMD_FORCE_INLINE
Definition: btScalar.h:98
#define btAssert(x)
Definition: btScalar.h:153
virtual const char * serialize(void *dataBuffer, btSerializer *serializer) const
fills the dataBuffer and returns the struct name (and 0 on failure)
void setAngularUpperLimitReversed(const btVector3 &angularUpper)
void getAngularLowerLimitReversed(btVector3 &angularLower)
void getAngularLowerLimit(btVector3 &angularLower)
void getAngularUpperLimit(btVector3 &angularUpper)
void setLimit(int axis, btScalar lo, btScalar hi)
void getLinearLowerLimit(btVector3 &linearLower)
void setAngularLowerLimitReversed(const btVector3 &angularLower)
void setLinearUpperLimit(const btVector3 &linearUpper)
btRotationalLimitMotor2 * getRotationalLimitMotor(int index)
const btTransform & getCalculatedTransformA() const
const btTransform & getCalculatedTransformB() const
btScalar getRelativePivotPosition(int axis_index) const
void setAngularUpperLimit(const btVector3 &angularUpper)
void setAngularLowerLimit(const btVector3 &angularLower)
void setLinearLowerLimit(const btVector3 &linearLower)
btGeneric6DofSpring2Constraint & operator=(const btGeneric6DofSpring2Constraint &)
void getAngularUpperLimitReversed(btVector3 &angularUpper)
btVector3 getAxis(int axis_index) const
void getLinearUpperLimit(btVector3 &linearUpper)
virtual void buildJacobian()
internal method used by the constraint solver, don't use them directly
btScalar getAngle(int axis_index) const
void setLimitReversed(int axis, btScalar lo, btScalar hi)
btTranslationalLimitMotor2 * getTranslationalLimitMotor()
Jacobian entry is an abstraction that allows to describe constraints it can be used in combination wi...
The btMatrix3x3 class implements a 3x3 rotation matrix, to perform linear algebra in combination with...
Definition: btMatrix3x3.h:50
The btRigidBody is the main class for rigid body objects.
Definition: btRigidBody.h:60
void testLimitValue(btScalar test_value)
btRotationalLimitMotor2(const btRotationalLimitMotor2 &limot)
The btTransform class supports rigid transforms with only translation and rotation and no scaling/she...
Definition: btTransform.h:30
void serialize(struct btTransformData &dataOut) const
Definition: btTransform.h:257
btTranslationalLimitMotor2(const btTranslationalLimitMotor2 &other)
void testLimitValue(int limitIndex, btScalar test_value)
TypedConstraint is the baseclass for Bullet constraints and vehicles.
virtual const char * serialize(void *dataBuffer, btSerializer *serializer) const
fills the dataBuffer and returns the struct name (and 0 on failure)
btVector3 can be used to represent 3D points and vectors.
Definition: btVector3.h:82
void setValue(const btScalar &_x, const btScalar &_y, const btScalar &_z)
Definition: btVector3.h:640
void serialize(struct btVector3Data &dataOut) const
Definition: btVector3.h:1317
for serialization
Definition: btTransform.h:246
this structure is not used, except for loading pre-2.82 .bullet files