Bullet Collision Detection & Physics Library
btConeTwistConstraint.h
Go to the documentation of this file.
1 /*
2 Bullet Continuous Collision Detection and Physics Library
3 btConeTwistConstraint is Copyright (c) 2007 Starbreeze Studios
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 Written by: Marcus Hennix
16 */
17 
18 
19 
20 /*
21 Overview:
22 
23 btConeTwistConstraint can be used to simulate ragdoll joints (upper arm, leg etc).
24 It is a fixed translation, 3 degree-of-freedom (DOF) rotational "joint".
25 It divides the 3 rotational DOFs into swing (movement within a cone) and twist.
26 Swing is divided into swing1 and swing2 which can have different limits, giving an elliptical shape.
27 (Note: the cone's base isn't flat, so this ellipse is "embedded" on the surface of a sphere.)
28 
29 In the contraint's frame of reference:
30 twist is along the x-axis,
31 and swing 1 and 2 are along the z and y axes respectively.
32 */
33 
34 
35 
36 #ifndef BT_CONETWISTCONSTRAINT_H
37 #define BT_CONETWISTCONSTRAINT_H
38 
39 #include "LinearMath/btVector3.h"
40 #include "btJacobianEntry.h"
41 #include "btTypedConstraint.h"
42 
43 #ifdef BT_USE_DOUBLE_PRECISION
44 #define btConeTwistConstraintData2 btConeTwistConstraintDoubleData
45 #define btConeTwistConstraintDataName "btConeTwistConstraintDoubleData"
46 #else
47 #define btConeTwistConstraintData2 btConeTwistConstraintData
48 #define btConeTwistConstraintDataName "btConeTwistConstraintData"
49 #endif //BT_USE_DOUBLE_PRECISION
50 
51 
52 class btRigidBody;
53 
55 {
59 };
60 
63 {
64 #ifdef IN_PARALLELL_SOLVER
65 public:
66 #endif
67  btJacobianEntry m_jac[3]; //3 orthogonal linear constraints
68 
71 
75 
77 
81 
83 
86 
89 
93 
95 
98 
102 
104 
105  // not yet used...
109 
110  // motor
116 
117  // parameters
118  int m_flags;
122 
123 protected:
124 
125  void init();
126 
127  void computeConeLimitInfo(const btQuaternion& qCone, // in
128  btScalar& swingAngle, btVector3& vSwingAxis, btScalar& swingLimit); // all outs
129 
130  void computeTwistLimitInfo(const btQuaternion& qTwist, // in
131  btScalar& twistAngle, btVector3& vTwistAxis); // all outs
132 
133  void adjustSwingAxisToUseEllipseNormal(btVector3& vSwingAxis) const;
134 
135 
136 public:
137 
139 
140  btConeTwistConstraint(btRigidBody& rbA,btRigidBody& rbB,const btTransform& rbAFrame, const btTransform& rbBFrame);
141 
142  btConeTwistConstraint(btRigidBody& rbA,const btTransform& rbAFrame);
143 
144  virtual void buildJacobian();
145 
146  virtual void getInfo1 (btConstraintInfo1* info);
147 
148  void getInfo1NonVirtual(btConstraintInfo1* info);
149 
150  virtual void getInfo2 (btConstraintInfo2* info);
151 
152  void getInfo2NonVirtual(btConstraintInfo2* info,const btTransform& transA,const btTransform& transB,const btMatrix3x3& invInertiaWorldA,const btMatrix3x3& invInertiaWorldB);
153 
154  virtual void solveConstraintObsolete(btSolverBody& bodyA,btSolverBody& bodyB,btScalar timeStep);
155 
156 
157  void updateRHS(btScalar timeStep);
158 
159 
160  const btRigidBody& getRigidBodyA() const
161  {
162  return m_rbA;
163  }
164  const btRigidBody& getRigidBodyB() const
165  {
166  return m_rbB;
167  }
168 
169  void setAngularOnly(bool angularOnly)
170  {
171  m_angularOnly = angularOnly;
172  }
173 
174  void setLimit(int limitIndex,btScalar limitValue)
175  {
176  switch (limitIndex)
177  {
178  case 3:
179  {
180  m_twistSpan = limitValue;
181  break;
182  }
183  case 4:
184  {
185  m_swingSpan2 = limitValue;
186  break;
187  }
188  case 5:
189  {
190  m_swingSpan1 = limitValue;
191  break;
192  }
193  default:
194  {
195  }
196  };
197  }
198 
199  // setLimit(), a few notes:
200  // _softness:
201  // 0->1, recommend ~0.8->1.
202  // describes % of limits where movement is free.
203  // beyond this softness %, the limit is gradually enforced until the "hard" (1.0) limit is reached.
204  // _biasFactor:
205  // 0->1?, recommend 0.3 +/-0.3 or so.
206  // strength with which constraint resists zeroth order (angular, not angular velocity) limit violation.
207  // __relaxationFactor:
208  // 0->1, recommend to stay near 1.
209  // the lower the value, the less the constraint will fight velocities which violate the angular limits.
210  void setLimit(btScalar _swingSpan1,btScalar _swingSpan2,btScalar _twistSpan, btScalar _softness = 1.f, btScalar _biasFactor = 0.3f, btScalar _relaxationFactor = 1.0f)
211  {
212  m_swingSpan1 = _swingSpan1;
213  m_swingSpan2 = _swingSpan2;
214  m_twistSpan = _twistSpan;
215 
216  m_limitSoftness = _softness;
217  m_biasFactor = _biasFactor;
218  m_relaxationFactor = _relaxationFactor;
219  }
220 
221  const btTransform& getAFrame() { return m_rbAFrame; };
222  const btTransform& getBFrame() { return m_rbBFrame; };
223 
224  inline int getSolveTwistLimit()
225  {
226  return m_solveTwistLimit;
227  }
228 
229  inline int getSolveSwingLimit()
230  {
231  return m_solveTwistLimit;
232  }
233 
235  {
236  return m_twistLimitSign;
237  }
238 
239  void calcAngleInfo();
240  void calcAngleInfo2(const btTransform& transA, const btTransform& transB,const btMatrix3x3& invInertiaWorldA,const btMatrix3x3& invInertiaWorldB);
241 
243  {
244  return m_swingSpan1;
245  }
247  {
248  return m_swingSpan2;
249  }
251  {
252  return m_twistSpan;
253  }
255  {
256  return m_twistAngle;
257  }
258  bool isPastSwingLimit() { return m_solveSwingLimit; }
259 
260  void setDamping(btScalar damping) { m_damping = damping; }
261 
262  void enableMotor(bool b) { m_bMotorEnabled = b; }
263  void setMaxMotorImpulse(btScalar maxMotorImpulse) { m_maxMotorImpulse = maxMotorImpulse; m_bNormalizedMotorStrength = false; }
264  void setMaxMotorImpulseNormalized(btScalar maxMotorImpulse) { m_maxMotorImpulse = maxMotorImpulse; m_bNormalizedMotorStrength = true; }
265 
266  btScalar getFixThresh() { return m_fixThresh; }
267  void setFixThresh(btScalar fixThresh) { m_fixThresh = fixThresh; }
268 
269  // setMotorTarget:
270  // q: the desired rotation of bodyA wrt bodyB.
271  // note: if q violates the joint limits, the internal target is clamped to avoid conflicting impulses (very bad for stability)
272  // note: don't forget to enableMotor()
273  void setMotorTarget(const btQuaternion &q);
274 
275  // same as above, but q is the desired rotation of frameA wrt frameB in constraint space
276  void setMotorTargetInConstraintSpace(const btQuaternion &q);
277 
278  btVector3 GetPointForAngle(btScalar fAngleInRadians, btScalar fLength) const;
279 
282  virtual void setParam(int num, btScalar value, int axis = -1);
283 
284  virtual void setFrames(const btTransform& frameA, const btTransform& frameB);
285 
287  {
288  return m_rbAFrame;
289  }
290 
292  {
293  return m_rbBFrame;
294  }
295 
296 
298  virtual btScalar getParam(int num, int axis = -1) const;
299 
300  virtual int calculateSerializeBufferSize() const;
301 
303  virtual const char* serialize(void* dataBuffer, btSerializer* serializer) const;
304 
305 };
306 
307 
308 
310 {
314 
315  //limits
316  double m_swingSpan1;
317  double m_swingSpan2;
318  double m_twistSpan;
320  double m_biasFactor;
322 
323  double m_damping;
324 
325 
326 
327 };
328 
329 #ifdef BT_BACKWARDS_COMPATIBLE_SERIALIZATION
332 {
336 
337  //limits
340  float m_twistSpan;
344 
345  float m_damping;
346 
347  char m_pad[4];
348 
349 };
350 #endif //BT_BACKWARDS_COMPATIBLE_SERIALIZATION
351 //
352 
354 {
355  return sizeof(btConeTwistConstraintData2);
356 
357 }
358 
359 
361 SIMD_FORCE_INLINE const char* btConeTwistConstraint::serialize(void* dataBuffer, btSerializer* serializer) const
362 {
364  btTypedConstraint::serialize(&cone->m_typeConstraintData,serializer);
365 
366  m_rbAFrame.serialize(cone->m_rbAFrame);
367  m_rbBFrame.serialize(cone->m_rbBFrame);
368 
369  cone->m_swingSpan1 = m_swingSpan1;
370  cone->m_swingSpan2 = m_swingSpan2;
371  cone->m_twistSpan = m_twistSpan;
372  cone->m_limitSoftness = m_limitSoftness;
373  cone->m_biasFactor = m_biasFactor;
374  cone->m_relaxationFactor = m_relaxationFactor;
375  cone->m_damping = m_damping;
376 
378 }
379 
380 
381 #endif //BT_CONETWISTCONSTRAINT_H
void setMaxMotorImpulseNormalized(btScalar maxMotorImpulse)
void setLimit(int limitIndex, btScalar limitValue)
btTransformFloatData m_rbAFrame
btTypedConstraintDoubleData m_typeConstraintData
Jacobian entry is an abstraction that allows to describe constraints it can be used in combination wi...
#define btConeTwistConstraintData2
const btRigidBody & getRigidBodyB() const
void setMaxMotorImpulse(btScalar maxMotorImpulse)
#define SIMD_FORCE_INLINE
Definition: btScalar.h:58
const btTransform & getFrameOffsetA() const
void setDamping(btScalar damping)
btTransformFloatData m_rbBFrame
virtual const char * serialize(void *dataBuffer, btSerializer *serializer) const
fills the dataBuffer and returns the struct name (and 0 on failure)
void setLimit(btScalar _swingSpan1, btScalar _swingSpan2, btScalar _twistSpan, btScalar _softness=1.f, btScalar _biasFactor=0.3f, btScalar _relaxationFactor=1.0f)
virtual int calculateSerializeBufferSize() const
btTypedConstraintData m_typeConstraintData
The btRigidBody is the main class for rigid body objects.
Definition: btRigidBody.h:59
this structure is not used, except for loading pre-2.82 .bullet files
btConeTwistFlags
void setAngularOnly(bool angularOnly)
const btTransform & getAFrame()
btVector3 can be used to represent 3D points and vectors.
Definition: btVector3.h:83
#define ATTRIBUTE_ALIGNED16(a)
Definition: btScalar.h:59
The btTransform class supports rigid transforms with only translation and rotation and no scaling/she...
Definition: btTransform.h:34
btConeTwistConstraint can be used to simulate ragdoll joints (upper arm, leg etc) ...
void setFixThresh(btScalar fixThresh)
The btSolverBody is an internal datastructure for the constraint solver. Only necessary data is packe...
Definition: btSolverBody.h:108
const btTransform & getBFrame()
TypedConstraint is the baseclass for Bullet constraints and vehicles.
for serialization
Definition: btTransform.h:253
#define BT_DECLARE_ALIGNED_ALLOCATOR()
Definition: btScalar.h:357
virtual const char * serialize(void *dataBuffer, class btSerializer *serializer) const
fills the dataBuffer and returns the struct name (and 0 on failure)
virtual const char * serialize(void *dataBuffer, btSerializer *serializer) const
fills the dataBuffer and returns the struct name (and 0 on failure)
The btMatrix3x3 class implements a 3x3 rotation matrix, to perform linear algebra in combination with...
Definition: btMatrix3x3.h:48
this structure is not used, except for loading pre-2.82 .bullet files
const btRigidBody & getRigidBodyA() const
The btQuaternion implements quaternion to perform linear algebra rotations in combination with btMatr...
Definition: btQuaternion.h:48
const btTransform & getFrameOffsetB() const
void serialize(struct btTransformData &dataOut) const
Definition: btTransform.h:267
virtual int calculateSerializeBufferSize() const
float btScalar
The btScalar type abstracts floating point numbers, to easily switch between double and single floati...
Definition: btScalar.h:266
#define btConeTwistConstraintDataName