Bullet Collision Detection & Physics Library
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 
24 #include "LinearMath/btVector3.h"
25 #include "btJacobianEntry.h"
26 #include "btTypedConstraint.h"
27 
28 class btRigidBody;
29 
30 #ifdef BT_USE_DOUBLE_PRECISION
31 #define btHingeConstraintData btHingeConstraintDoubleData2 //rename to 2 for backwards compatibility, so we can still load the 'btHingeConstraintDoubleData' version
32 #define btHingeConstraintDataName "btHingeConstraintDoubleData2"
33 #else
34 #define btHingeConstraintData btHingeConstraintFloatData
35 #define btHingeConstraintDataName "btHingeConstraintFloatData"
36 #endif //BT_USE_DOUBLE_PRECISION
37 
38 
39 
41 {
45 };
46 
47 
51 {
52 #ifdef IN_PARALLELL_SOLVER
53 public:
54 #endif
55  btJacobianEntry m_jac[3]; //3 orthogonal linear constraints
56  btJacobianEntry m_jacAng[3]; //2 orthogonal angular constraints+ 1 for limit/motor
57 
58  btTransform m_rbAFrame; // constraint axii. Assumes z is hinge axis.
60 
63 
64 
65 #ifdef _BT_USE_CENTER_LIMIT_
67 #else
68  btScalar m_lowerLimit;
69  btScalar m_upperLimit;
70  btScalar m_limitSign;
71  btScalar m_correction;
72 
73  btScalar m_limitSoftness;
74  btScalar m_biasFactor;
75  btScalar m_relaxationFactor;
76 
77  bool m_solveLimit;
78 #endif
79 
81 
82 
86 
92 
94 
95  int m_flags;
99 
100 
101 public:
102 
104 
105  btHingeConstraint(btRigidBody& rbA,btRigidBody& rbB, const btVector3& pivotInA,const btVector3& pivotInB, const btVector3& axisInA,const btVector3& axisInB, bool useReferenceFrameA = false);
106 
107  btHingeConstraint(btRigidBody& rbA,const btVector3& pivotInA,const btVector3& axisInA, bool useReferenceFrameA = false);
108 
109  btHingeConstraint(btRigidBody& rbA,btRigidBody& rbB, const btTransform& rbAFrame, const btTransform& rbBFrame, bool useReferenceFrameA = false);
110 
111  btHingeConstraint(btRigidBody& rbA,const btTransform& rbAFrame, bool useReferenceFrameA = false);
112 
113 
114  virtual void buildJacobian();
115 
116  virtual void getInfo1 (btConstraintInfo1* info);
117 
118  void getInfo1NonVirtual(btConstraintInfo1* info);
119 
120  virtual void getInfo2 (btConstraintInfo2* info);
121 
122  void getInfo2NonVirtual(btConstraintInfo2* info,const btTransform& transA,const btTransform& transB,const btVector3& angVelA,const btVector3& angVelB);
123 
124  void getInfo2Internal(btConstraintInfo2* info,const btTransform& transA,const btTransform& transB,const btVector3& angVelA,const btVector3& angVelB);
125  void getInfo2InternalUsingFrameOffset(btConstraintInfo2* info,const btTransform& transA,const btTransform& transB,const btVector3& angVelA,const btVector3& angVelB);
126 
127 
128  void updateRHS(btScalar timeStep);
129 
130  const btRigidBody& getRigidBodyA() const
131  {
132  return m_rbA;
133  }
134  const btRigidBody& getRigidBodyB() const
135  {
136  return m_rbB;
137  }
138 
139  btRigidBody& getRigidBodyA()
140  {
141  return m_rbA;
142  }
143 
144  btRigidBody& getRigidBodyB()
145  {
146  return m_rbB;
147  }
148 
149  btTransform& getFrameOffsetA()
150  {
151  return m_rbAFrame;
152  }
153 
154  btTransform& getFrameOffsetB()
155  {
156  return m_rbBFrame;
157  }
158 
159  void setFrames(const btTransform& frameA, const btTransform& frameB);
160 
161  void setAngularOnly(bool angularOnly)
162  {
163  m_angularOnly = angularOnly;
164  }
165 
166  void enableAngularMotor(bool enableMotor,btScalar targetVelocity,btScalar maxMotorImpulse)
167  {
168  m_enableAngularMotor = enableMotor;
169  m_motorTargetVelocity = targetVelocity;
170  m_maxMotorImpulse = maxMotorImpulse;
171  }
172 
173  // extra motor API, including ability to set a target rotation (as opposed to angular velocity)
174  // note: setMotorTarget sets angular velocity under the hood, so you must call it every tick to
175  // maintain a given angular target.
176  void enableMotor(bool enableMotor) { m_enableAngularMotor = enableMotor; }
177  void setMaxMotorImpulse(btScalar maxMotorImpulse) { m_maxMotorImpulse = maxMotorImpulse; }
178  void setMotorTarget(const btQuaternion& qAinB, btScalar dt); // qAinB is rotation of body A wrt body B.
179  void setMotorTarget(btScalar targetAngle, btScalar dt);
180 
181 
182  void setLimit(btScalar low,btScalar high,btScalar _softness = 0.9f, btScalar _biasFactor = 0.3f, btScalar _relaxationFactor = 1.0f)
183  {
184 #ifdef _BT_USE_CENTER_LIMIT_
185  m_limit.set(low, high, _softness, _biasFactor, _relaxationFactor);
186 #else
187  m_lowerLimit = btNormalizeAngle(low);
188  m_upperLimit = btNormalizeAngle(high);
189  m_limitSoftness = _softness;
190  m_biasFactor = _biasFactor;
191  m_relaxationFactor = _relaxationFactor;
192 #endif
193  }
194 
195  void setAxis(btVector3& axisInA)
196  {
197  btVector3 rbAxisA1, rbAxisA2;
198  btPlaneSpace1(axisInA, rbAxisA1, rbAxisA2);
199  btVector3 pivotInA = m_rbAFrame.getOrigin();
200 // m_rbAFrame.getOrigin() = pivotInA;
201  m_rbAFrame.getBasis().setValue( rbAxisA1.getX(),rbAxisA2.getX(),axisInA.getX(),
202  rbAxisA1.getY(),rbAxisA2.getY(),axisInA.getY(),
203  rbAxisA1.getZ(),rbAxisA2.getZ(),axisInA.getZ() );
204 
205  btVector3 axisInB = m_rbA.getCenterOfMassTransform().getBasis() * axisInA;
206 
207  btQuaternion rotationArc = shortestArcQuat(axisInA,axisInB);
208  btVector3 rbAxisB1 = quatRotate(rotationArc,rbAxisA1);
209  btVector3 rbAxisB2 = axisInB.cross(rbAxisB1);
210 
211  m_rbBFrame.getOrigin() = m_rbB.getCenterOfMassTransform().inverse()(m_rbA.getCenterOfMassTransform()(pivotInA));
212 
213  m_rbBFrame.getBasis().setValue( rbAxisB1.getX(),rbAxisB2.getX(),axisInB.getX(),
214  rbAxisB1.getY(),rbAxisB2.getY(),axisInB.getY(),
215  rbAxisB1.getZ(),rbAxisB2.getZ(),axisInB.getZ() );
216  m_rbBFrame.getBasis() = m_rbB.getCenterOfMassTransform().getBasis().inverse() * m_rbBFrame.getBasis();
217 
218  }
219 
220  btScalar getLowerLimit() const
221  {
222 #ifdef _BT_USE_CENTER_LIMIT_
223  return m_limit.getLow();
224 #else
225  return m_lowerLimit;
226 #endif
227  }
228 
229  btScalar getUpperLimit() const
230  {
231 #ifdef _BT_USE_CENTER_LIMIT_
232  return m_limit.getHigh();
233 #else
234  return m_upperLimit;
235 #endif
236  }
237 
238 
239  btScalar getHingeAngle();
240 
241  btScalar getHingeAngle(const btTransform& transA,const btTransform& transB);
242 
243  void testLimit(const btTransform& transA,const btTransform& transB);
244 
245 
246  const btTransform& getAFrame() const { return m_rbAFrame; };
247  const btTransform& getBFrame() const { return m_rbBFrame; };
248 
249  btTransform& getAFrame() { return m_rbAFrame; };
250  btTransform& getBFrame() { return m_rbBFrame; };
251 
252  inline int getSolveLimit()
253  {
254 #ifdef _BT_USE_CENTER_LIMIT_
255  return m_limit.isLimit();
256 #else
257  return m_solveLimit;
258 #endif
259  }
260 
261  inline btScalar getLimitSign()
262  {
263 #ifdef _BT_USE_CENTER_LIMIT_
264  return m_limit.getSign();
265 #else
266  return m_limitSign;
267 #endif
268  }
269 
270  inline bool getAngularOnly()
271  {
272  return m_angularOnly;
273  }
274  inline bool getEnableAngularMotor()
275  {
276  return m_enableAngularMotor;
277  }
278  inline btScalar getMotorTargetVelosity()
279  {
280  return m_motorTargetVelocity;
281  }
282  inline btScalar getMaxMotorImpulse()
283  {
284  return m_maxMotorImpulse;
285  }
286  // access for UseFrameOffset
287  bool getUseFrameOffset() { return m_useOffsetForConstraintFrame; }
288  void setUseFrameOffset(bool frameOffsetOnOff) { m_useOffsetForConstraintFrame = frameOffsetOnOff; }
289 
290 
293  virtual void setParam(int num, btScalar value, int axis = -1);
295  virtual btScalar getParam(int num, int axis = -1) const;
296 
297  virtual int calculateSerializeBufferSize() const;
298 
300  virtual const char* serialize(void* dataBuffer, btSerializer* serializer) const;
301 
302 
303 };
304 
305 
306 //only for backward compatibility
307 #ifdef BT_BACKWARDS_COMPATIBLE_SERIALIZATION
308 
310 {
312  btTransformDoubleData m_rbAFrame; // constraint axii. Assumes z is hinge axis.
319 
325 
326 };
327 #endif //BT_BACKWARDS_COMPATIBLE_SERIALIZATION
328 
329 
331 {
333  btTransformFloatData m_rbAFrame; // constraint axii. Assumes z is hinge axis.
337 
341 
347 
348 };
349 
350 
351 
354 {
356  btTransformDoubleData m_rbAFrame; // constraint axii. Assumes z is hinge axis.
363 
364  double m_lowerLimit;
365  double m_upperLimit;
367  double m_biasFactor;
369  char m_padding1[4];
370 
371 };
372 
373 
374 
375 
377 {
378  return sizeof(btHingeConstraintData);
379 }
380 
382 SIMD_FORCE_INLINE const char* btHingeConstraint::serialize(void* dataBuffer, btSerializer* serializer) const
383 {
384  btHingeConstraintData* hingeData = (btHingeConstraintData*)dataBuffer;
385  btTypedConstraint::serialize(&hingeData->m_typeConstraintData,serializer);
386 
387  m_rbAFrame.serialize(hingeData->m_rbAFrame);
388  m_rbBFrame.serialize(hingeData->m_rbBFrame);
389 
390  hingeData->m_angularOnly = m_angularOnly;
391  hingeData->m_enableAngularMotor = m_enableAngularMotor;
392  hingeData->m_maxMotorImpulse = float(m_maxMotorImpulse);
393  hingeData->m_motorTargetVelocity = float(m_motorTargetVelocity);
394  hingeData->m_useReferenceFrameA = m_useReferenceFrameA;
395 #ifdef _BT_USE_CENTER_LIMIT_
396  hingeData->m_lowerLimit = float(m_limit.getLow());
397  hingeData->m_upperLimit = float(m_limit.getHigh());
398  hingeData->m_limitSoftness = float(m_limit.getSoftness());
399  hingeData->m_biasFactor = float(m_limit.getBiasFactor());
400  hingeData->m_relaxationFactor = float(m_limit.getRelaxationFactor());
401 #else
402  hingeData->m_lowerLimit = float(m_lowerLimit);
403  hingeData->m_upperLimit = float(m_upperLimit);
404  hingeData->m_limitSoftness = float(m_limitSoftness);
405  hingeData->m_biasFactor = float(m_biasFactor);
406  hingeData->m_relaxationFactor = float(m_relaxationFactor);
407 #endif
408 
410 }
411 
412 #endif //BT_HINGECONSTRAINT_H