Bullet Collision Detection & Physics Library
btTypedConstraint.h
Go to the documentation of this file.
1 /*
2 Bullet Continuous Collision Detection and Physics Library
3 Copyright (c) 2003-2010 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 #ifndef BT_TYPED_CONSTRAINT_H
17 #define BT_TYPED_CONSTRAINT_H
18 
19 
20 #include "LinearMath/btScalar.h"
21 #include "btSolverConstraint.h"
23 
24 #ifdef BT_USE_DOUBLE_PRECISION
25 #define btTypedConstraintData2 btTypedConstraintDoubleData
26 #define btTypedConstraintDataName "btTypedConstraintDoubleData"
27 #else
28 #define btTypedConstraintData2 btTypedConstraintFloatData
29 #define btTypedConstraintDataName "btTypedConstraintFloatData"
30 #endif //BT_USE_DOUBLE_PRECISION
31 
32 
33 class btSerializer;
34 
35 //Don't change any of the existing enum values, so add enum types at the end for serialization compatibility
37 {
48 };
49 
50 
52 {
57 };
58 
59 #if 1
60  #define btAssertConstrParams(_par) btAssert(_par)
61 #else
62  #define btAssertConstrParams(_par)
63 #endif
64 
65 
67 {
72 };
73 
74 
77 {
79 
80  union
81  {
84  };
85 
90 
91 
93  {
94  btAssert(0);
95  (void) other;
96  return *this;
97  }
98 
99 protected:
105 
107  btScalar getMotorFactor(btScalar pos, btScalar lowLim, btScalar uppLim, btScalar vel, btScalar timeFact);
108 
109 
110 public:
111 
113 
114  virtual ~btTypedConstraint() {};
117 
119  int m_numConstraintRows,nub;
120  };
121 
122  static btRigidBody& getFixedBody();
123 
125  // integrator parameters: frames per second (1/stepsize), default error
126  // reduction parameter (0..1).
128 
129  // for the first and second body, pointers to two (linear and angular)
130  // n*3 jacobian sub matrices, stored by rows. these matrices will have
131  // been initialized to 0 on entry. if the second body is zero then the
132  // J2xx pointers may be 0.
133  btScalar *m_J1linearAxis,*m_J1angularAxis,*m_J2linearAxis,*m_J2angularAxis;
134 
135  // elements to jump from one row to the next in J's
136  int rowskip;
137 
138  // right hand sides of the equation J*v = c + cfm * lambda. cfm is the
139  // "constraint force mixing" vector. c is set to zero on entry, cfm is
140  // set to a constant value (typically very small or zero) value on entry.
142 
143  // lo and hi limits for variables (set to -/+ infinity on entry).
144  btScalar *m_lowerLimit,*m_upperLimit;
145 
146  // findex vector for variables. see the LCP solver interface for a
147  // description of what this does. this is set to -1 on entry.
148  // note that the returned indexes are relative to the first index of
149  // the constraint.
150  int *findex;
151  // number of solver iterations
153 
154  //damping of the velocity
156  };
157 
158  int getOverrideNumSolverIterations() const
159  {
160  return m_overrideNumSolverIterations;
161  }
162 
165  void setOverrideNumSolverIterations(int overideNumIterations)
166  {
167  m_overrideNumSolverIterations = overideNumIterations;
168  }
169 
171  virtual void buildJacobian() {};
172 
174  virtual void setupSolverConstraint(btConstraintArray& ca, int solverBodyA,int solverBodyB, btScalar timeStep)
175  {
176  (void)ca;
177  (void)solverBodyA;
178  (void)solverBodyB;
179  (void)timeStep;
180  }
181 
183  virtual void getInfo1 (btConstraintInfo1* info)=0;
184 
186  virtual void getInfo2 (btConstraintInfo2* info)=0;
187 
189  void internalSetAppliedImpulse(btScalar appliedImpulse)
190  {
191  m_appliedImpulse = appliedImpulse;
192  }
194  btScalar internalGetAppliedImpulse()
195  {
196  return m_appliedImpulse;
197  }
198 
199 
200  btScalar getBreakingImpulseThreshold() const
201  {
202  return m_breakingImpulseThreshold;
203  }
204 
205  void setBreakingImpulseThreshold(btScalar threshold)
206  {
207  m_breakingImpulseThreshold = threshold;
208  }
209 
210  bool isEnabled() const
211  {
212  return m_isEnabled;
213  }
214 
215  void setEnabled(bool enabled)
216  {
217  m_isEnabled=enabled;
218  }
219 
220 
222  virtual void solveConstraintObsolete(btSolverBody& /*bodyA*/,btSolverBody& /*bodyB*/,btScalar /*timeStep*/) {};
223 
224 
225  const btRigidBody& getRigidBodyA() const
226  {
227  return m_rbA;
228  }
229  const btRigidBody& getRigidBodyB() const
230  {
231  return m_rbB;
232  }
233 
234  btRigidBody& getRigidBodyA()
235  {
236  return m_rbA;
237  }
238  btRigidBody& getRigidBodyB()
239  {
240  return m_rbB;
241  }
242 
243  int getUserConstraintType() const
244  {
245  return m_userConstraintType ;
246  }
247 
248  void setUserConstraintType(int userConstraintType)
249  {
250  m_userConstraintType = userConstraintType;
251  };
252 
253  void setUserConstraintId(int uid)
254  {
255  m_userConstraintId = uid;
256  }
257 
258  int getUserConstraintId() const
259  {
260  return m_userConstraintId;
261  }
262 
263  void setUserConstraintPtr(void* ptr)
264  {
265  m_userConstraintPtr = ptr;
266  }
267 
268  void* getUserConstraintPtr()
269  {
270  return m_userConstraintPtr;
271  }
272 
273  void setJointFeedback(btJointFeedback* jointFeedback)
274  {
275  m_jointFeedback = jointFeedback;
276  }
277 
278  const btJointFeedback* getJointFeedback() const
279  {
280  return m_jointFeedback;
281  }
282 
283  btJointFeedback* getJointFeedback()
284  {
285  return m_jointFeedback;
286  }
287 
288 
289  int getUid() const
290  {
291  return m_userConstraintId;
292  }
293 
294  bool needsFeedback() const
295  {
296  return m_needsFeedback;
297  }
298 
301  void enableFeedback(bool needsFeedback)
302  {
303  m_needsFeedback = needsFeedback;
304  }
305 
308  btScalar getAppliedImpulse() const
309  {
310  btAssert(m_needsFeedback);
311  return m_appliedImpulse;
312  }
313 
314  btTypedConstraintType getConstraintType () const
315  {
316  return btTypedConstraintType(m_objectType);
317  }
318 
319  void setDbgDrawSize(btScalar dbgDrawSize)
320  {
321  m_dbgDrawSize = dbgDrawSize;
322  }
323  btScalar getDbgDrawSize()
324  {
325  return m_dbgDrawSize;
326  }
327 
330  virtual void setParam(int num, btScalar value, int axis = -1) = 0;
331 
333  virtual btScalar getParam(int num, int axis = -1) const = 0;
334 
335  virtual int calculateSerializeBufferSize() const;
336 
338  virtual const char* serialize(void* dataBuffer, btSerializer* serializer) const;
339 
340 };
341 
342 // returns angle in range [-SIMD_2_PI, SIMD_2_PI], closest to one of the limits
343 // all arguments should be normalized angles (i.e. in range [-SIMD_PI, SIMD_PI])
344 SIMD_FORCE_INLINE btScalar btAdjustAngleToLimits(btScalar angleInRadians, btScalar angleLowerLimitInRadians, btScalar angleUpperLimitInRadians)
345 {
346  if(angleLowerLimitInRadians >= angleUpperLimitInRadians)
347  {
348  return angleInRadians;
349  }
350  else if(angleInRadians < angleLowerLimitInRadians)
351  {
352  btScalar diffLo = btFabs(btNormalizeAngle(angleLowerLimitInRadians - angleInRadians));
353  btScalar diffHi = btFabs(btNormalizeAngle(angleUpperLimitInRadians - angleInRadians));
354  return (diffLo < diffHi) ? angleInRadians : (angleInRadians + SIMD_2_PI);
355  }
356  else if(angleInRadians > angleUpperLimitInRadians)
357  {
358  btScalar diffHi = btFabs(btNormalizeAngle(angleInRadians - angleUpperLimitInRadians));
359  btScalar diffLo = btFabs(btNormalizeAngle(angleInRadians - angleLowerLimitInRadians));
360  return (diffLo < diffHi) ? (angleInRadians - SIMD_2_PI) : angleInRadians;
361  }
362  else
363  {
364  return angleInRadians;
365  }
366 }
367 
370 {
373  char *m_name;
374 
379 
382 
385 
388 
389 };
390 
392 
393 #define BT_BACKWARDS_COMPATIBLE_SERIALIZATION
394 #ifdef BT_BACKWARDS_COMPATIBLE_SERIALIZATION
395 
397 {
400  char *m_name;
401 
406 
409 
412 
415 
416 };
417 #endif //BACKWARDS_COMPATIBLE
418 
420 {
423  char *m_name;
424 
429 
432 
435 
438  char padding[4];
439 
440 };
441 
442 
444 {
445  return sizeof(btTypedConstraintData2);
446 }
447 
448 
449 
451 {
452 private:
453  btScalar
455  m_halfRange,
456  m_softness,
457  m_biasFactor,
459  m_correction,
460  m_sign;
461 
462  bool
464 
465 public:
468  :m_center(0.0f),
469  m_halfRange(-1.0f),
470  m_softness(0.9f),
471  m_biasFactor(0.3f),
472  m_relaxationFactor(1.0f),
473  m_correction(0.0f),
474  m_sign(0.0f),
475  m_solveLimit(false)
476  {}
477 
481  void set(btScalar low, btScalar high, btScalar _softness = 0.9f, btScalar _biasFactor = 0.3f, btScalar _relaxationFactor = 1.0f);
482 
485  void test(const btScalar angle);
486 
488  inline btScalar getSoftness() const
489  {
490  return m_softness;
491  }
492 
494  inline btScalar getBiasFactor() const
495  {
496  return m_biasFactor;
497  }
498 
501  {
502  return m_relaxationFactor;
503  }
504 
506  inline btScalar getCorrection() const
507  {
508  return m_correction;
509  }
510 
512  inline btScalar getSign() const
513  {
514  return m_sign;
515  }
516 
518  inline btScalar getHalfRange() const
519  {
520  return m_halfRange;
521  }
522 
524  inline bool isLimit() const
525  {
526  return m_solveLimit;
527  }
528 
531  void fit(btScalar& angle) const;
532 
534  btScalar getError() const;
535 
536  btScalar getLow() const;
537 
538  btScalar getHigh() const;
539 
540 };
541 
542 
543 
544 #endif //BT_TYPED_CONSTRAINT_H