Blender V4.3
btHingeConstraint.h
Go to the documentation of this file.
1/*
2Bullet Continuous Collision Detection and Physics Library
3Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
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/* 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
24#include "btJacobianEntry.h"
25#include "btTypedConstraint.h"
26
27class 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
44
48btHingeConstraint : public btTypedConstraint
49{
50#ifdef IN_PARALLELL_SOLVER
51public:
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
96
97public:
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
124 {
125 return m_rbA;
126 }
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_
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 }
302 {
304 }
306 {
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
357#endif //BT_BACKWARDS_COMPATIBLE_SERIALIZATION
358
362{
363protected:
364 btScalar m_accumulatedAngle;
365
366public:
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
415
435
436SIMD_FORCE_INLINE int btHingeConstraint::calculateSerializeBufferSize() const
437{
438 return sizeof(btHingeConstraintData);
439}
440
442SIMD_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
btScalar m_limitSoftness
btScalar m_biasFactor
btScalar m_relaxationFactor
btFixedConstraint btRigidBody & rbB
btScalar m_referenceSign
BT_DECLARE_ALIGNED_ALLOCATOR()
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
const btTransform & getBFrame() const
btScalar m_stopERP
const btRigidBody & getRigidBodyA() const
virtual void setParam(int num, btScalar value, int axis=-1)
btScalar getLimitBiasFactor() const
bool m_useReferenceFrameA
virtual int calculateSerializeBufferSize() const
btJacobianEntry m_jacAng[3]
btScalar getLowerLimit() const
btScalar getMotorTargetVelocity()
bool hasLimit() const
btTransform & getFrameOffsetB()
btScalar getLimitSign()
bool getUseReferenceFrameA() const
bool m_useSolveConstraintObsolete
void setUseFrameOffset(bool frameOffsetOnOff)
void setUseReferenceFrameA(bool useReferenceFrameA)
const btRigidBody & getRigidBodyB() const
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()
btScalar getLimitRelaxationFactor() const
bool m_enableAngularMotor
btScalar m_kHinge
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
const btTransform & getAFrame() const
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
btTransform & getFrameOffsetA()
void testLimit(const btTransform &transA, const btTransform &transB)
void setAxis(btVector3 &axisInA)
virtual const char * serialize(void *dataBuffer, btSerializer *serializer) const
fills the dataBuffer and returns the struct name (and 0 on failure)
void setMaxMotorImpulse(btScalar maxMotorImpulse)
#define btHingeConstraintData
void enableMotor(bool enableMotor)
#define btHingeConstraintDataName
btScalar m_stopCFM
bool m_useOffsetForConstraintFrame
btScalar m_normalERP
void updateRHS(btScalar timeStep)
btJacobianEntry
btScalar m_lowerLimit
btScalar m_upperLimit
SIMD_FORCE_INLINE btQuaternion shortestArcQuat(const btVector3 &v0, const btVector3 &v1)
SIMD_FORCE_INLINE btVector3 quatRotate(const btQuaternion &rotation, const btVector3 &v)
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
btRigidBody & m_rbB
SIMD_FORCE_INLINE void btPlaneSpace1(const T &n, T &p, T &q)
Definition btVector3.h:1251
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...
const btTransform & getCenterOfMassTransform() const
draw_view in_light_buf[] float
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
this structure is not used, except for loading pre-2.82 .bullet files