Blender  V3.3
btSliderConstraint.cpp
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 /*
17 Added by Roman Ponomarev (rponom@gmail.com)
18 April 04, 2008
19 */
20 
21 #include "btSliderConstraint.h"
24 #include <new>
25 
26 #define USE_OFFSET_FOR_CONSTANT_FRAME true
27 
29 {
31  m_upperLinLimit = btScalar(-1.0);
58 
59  m_poweredLinMotor = false;
63 
64  m_poweredAngMotor = false;
68 
69  m_flags = 0;
70  m_flags = 0;
71 
73 
75 }
76 
82  m_useLinearReferenceFrameA(useLinearReferenceFrameA)
83 {
84  initParams();
85 }
86 
91  m_useLinearReferenceFrameA(useLinearReferenceFrameA)
92 {
95  // m_frameInA.getOrigin() = m_rbA.getCenterOfMassTransform()(m_frameInA.getOrigin());
96 
97  initParams();
98 }
99 
101 {
103  {
104  info->m_numConstraintRows = 0;
105  info->nub = 0;
106  }
107  else
108  {
109  info->m_numConstraintRows = 4; // Fixed 2 linear + 2 angular
110  info->nub = 2;
111  //prepare constraint
113  testAngLimits();
114  testLinLimits();
116  {
117  info->m_numConstraintRows++; // limit 3rd linear as well
118  info->nub--;
119  }
121  {
122  info->m_numConstraintRows++; // limit 3rd angular as well
123  info->nub--;
124  }
125  }
126 }
127 
129 {
130  info->m_numConstraintRows = 6; // Fixed 2 linear + 2 angular + 1 limit (even if not used)
131  info->nub = 0;
132 }
133 
135 {
137 }
138 
139 void btSliderConstraint::calculateTransforms(const btTransform& transA, const btTransform& transB)
140 {
142  {
145  }
146  else
147  {
150  }
153  m_sliderAxis = m_calculatedTransformA.getBasis().getColumn(0); // along X
155  {
157  }
158  else
159  {
161  }
163  btVector3 normalWorld;
164  int i;
165  //linear part
166  for (i = 0; i < 3; i++)
167  {
168  normalWorld = m_calculatedTransformA.getBasis().getColumn(i);
169  m_depth[i] = m_delta.dot(normalWorld);
170  }
171 }
172 
174 {
175  m_solveLinLim = false;
176  m_linPos = m_depth[0];
178  {
179  if (m_depth[0] > m_upperLinLimit)
180  {
181  m_depth[0] -= m_upperLinLimit;
182  m_solveLinLim = true;
183  }
184  else if (m_depth[0] < m_lowerLinLimit)
185  {
186  m_depth[0] -= m_lowerLinLimit;
187  m_solveLinLim = true;
188  }
189  else
190  {
191  m_depth[0] = btScalar(0.);
192  }
193  }
194  else
195  {
196  m_depth[0] = btScalar(0.);
197  }
198 }
199 
201 {
202  m_angDepth = btScalar(0.);
203  m_solveAngLim = false;
205  {
206  const btVector3 axisA0 = m_calculatedTransformA.getBasis().getColumn(1);
207  const btVector3 axisA1 = m_calculatedTransformA.getBasis().getColumn(2);
208  const btVector3 axisB0 = m_calculatedTransformB.getBasis().getColumn(1);
209  // btScalar rot = btAtan2Fast(axisB0.dot(axisA1), axisB0.dot(axisA0));
210  btScalar rot = btAtan2(axisB0.dot(axisA1), axisB0.dot(axisA0));
212  m_angPos = rot;
213  if (rot < m_lowerAngLimit)
214  {
216  m_solveAngLim = true;
217  }
218  else if (rot > m_upperAngLimit)
219  {
221  m_solveAngLim = true;
222  }
223  }
224 }
225 
227 {
228  btVector3 ancorInA;
230  ancorInA = m_rbA.getCenterOfMassTransform().inverse() * ancorInA;
231  return ancorInA;
232 }
233 
235 {
236  btVector3 ancorInB;
237  ancorInB = m_frameInB.getOrigin();
238  return ancorInB;
239 }
240 
241 void btSliderConstraint::getInfo2NonVirtual(btConstraintInfo2* info, const btTransform& transA, const btTransform& transB, const btVector3& linVelA, const btVector3& linVelB, btScalar rbAinvMass, btScalar rbBinvMass)
242 {
243  const btTransform& trA = getCalculatedTransformA();
244  const btTransform& trB = getCalculatedTransformB();
245 
247  int i, s = info->rowskip;
248 
249  btScalar signFact = m_useLinearReferenceFrameA ? btScalar(1.0f) : btScalar(-1.0f);
250 
251  // difference between frames in WCS
252  btVector3 ofs = trB.getOrigin() - trA.getOrigin();
253  // now get weight factors depending on masses
254  btScalar miA = rbAinvMass;
255  btScalar miB = rbBinvMass;
256  bool hasStaticBody = (miA < SIMD_EPSILON) || (miB < SIMD_EPSILON);
257  btScalar miS = miA + miB;
258  btScalar factA, factB;
259  if (miS > btScalar(0.f))
260  {
261  factA = miB / miS;
262  }
263  else
264  {
265  factA = btScalar(0.5f);
266  }
267  factB = btScalar(1.0f) - factA;
268  btVector3 ax1, p, q;
269  btVector3 ax1A = trA.getBasis().getColumn(0);
270  btVector3 ax1B = trB.getBasis().getColumn(0);
272  {
273  // get the desired direction of slider axis
274  // as weighted sum of X-orthos of frameA and frameB in WCS
275  ax1 = ax1A * factA + ax1B * factB;
276  ax1.normalize();
277  // construct two orthos to slider axis
278  btPlaneSpace1(ax1, p, q);
279  }
280  else
281  { // old way - use frameA
282  ax1 = trA.getBasis().getColumn(0);
283  // get 2 orthos to slider axis (Y, Z)
284  p = trA.getBasis().getColumn(1);
285  q = trA.getBasis().getColumn(2);
286  }
287  // make rotations around these orthos equal
288  // the slider axis should be the only unconstrained
289  // rotational axis, the angular velocity of the two bodies perpendicular to
290  // the slider axis should be equal. thus the constraint equations are
291  // p*w1 - p*w2 = 0
292  // q*w1 - q*w2 = 0
293  // where p and q are unit vectors normal to the slider axis, and w1 and w2
294  // are the angular velocity vectors of the two bodies.
295  info->m_J1angularAxis[0] = p[0];
296  info->m_J1angularAxis[1] = p[1];
297  info->m_J1angularAxis[2] = p[2];
298  info->m_J1angularAxis[s + 0] = q[0];
299  info->m_J1angularAxis[s + 1] = q[1];
300  info->m_J1angularAxis[s + 2] = q[2];
301 
302  info->m_J2angularAxis[0] = -p[0];
303  info->m_J2angularAxis[1] = -p[1];
304  info->m_J2angularAxis[2] = -p[2];
305  info->m_J2angularAxis[s + 0] = -q[0];
306  info->m_J2angularAxis[s + 1] = -q[1];
307  info->m_J2angularAxis[s + 2] = -q[2];
308  // compute the right hand side of the constraint equation. set relative
309  // body velocities along p and q to bring the slider back into alignment.
310  // if ax1A,ax1B are the unit length slider axes as computed from bodyA and
311  // bodyB, we need to rotate both bodies along the axis u = (ax1 x ax2).
312  // if "theta" is the angle between ax1 and ax2, we need an angular velocity
313  // along u to cover angle erp*theta in one step :
314  // |angular_velocity| = angle/time = erp*theta / stepsize
315  // = (erp*fps) * theta
316  // angular_velocity = |angular_velocity| * (ax1 x ax2) / |ax1 x ax2|
317  // = (erp*fps) * theta * (ax1 x ax2) / sin(theta)
318  // ...as ax1 and ax2 are unit length. if theta is smallish,
319  // theta ~= sin(theta), so
320  // angular_velocity = (erp*fps) * (ax1 x ax2)
321  // ax1 x ax2 is in the plane space of ax1, so we project the angular
322  // velocity to p and q to find the right hand side.
323  // btScalar k = info->fps * info->erp * getSoftnessOrthoAng();
325  btScalar k = info->fps * currERP;
326 
327  btVector3 u = ax1A.cross(ax1B);
328  info->m_constraintError[0] = k * u.dot(p);
329  info->m_constraintError[s] = k * u.dot(q);
331  {
332  info->cfm[0] = m_cfmOrthoAng;
333  info->cfm[s] = m_cfmOrthoAng;
334  }
335 
336  int nrow = 1; // last filled row
337  int srow;
338  btScalar limit_err;
339  int limit;
340 
341  // next two rows.
342  // we want: velA + wA x relA == velB + wB x relB ... but this would
343  // result in three equations, so we project along two orthos to the slider axis
344 
345  btTransform bodyA_trans = transA;
346  btTransform bodyB_trans = transB;
347  nrow++;
348  int s2 = nrow * s;
349  nrow++;
350  int s3 = nrow * s;
351  btVector3 tmpA(0, 0, 0), tmpB(0, 0, 0), relA(0, 0, 0), relB(0, 0, 0), c(0, 0, 0);
353  {
354  // get vector from bodyB to frameB in WCS
355  relB = trB.getOrigin() - bodyB_trans.getOrigin();
356  // get its projection to slider axis
357  btVector3 projB = ax1 * relB.dot(ax1);
358  // get vector directed from bodyB to slider axis (and orthogonal to it)
359  btVector3 orthoB = relB - projB;
360  // same for bodyA
361  relA = trA.getOrigin() - bodyA_trans.getOrigin();
362  btVector3 projA = ax1 * relA.dot(ax1);
363  btVector3 orthoA = relA - projA;
364  // get desired offset between frames A and B along slider axis
365  btScalar sliderOffs = m_linPos - m_depth[0];
366  // desired vector from projection of center of bodyA to projection of center of bodyB to slider axis
367  btVector3 totalDist = projA + ax1 * sliderOffs - projB;
368  // get offset vectors relA and relB
369  relA = orthoA + totalDist * factA;
370  relB = orthoB - totalDist * factB;
371  // now choose average ortho to slider axis
372  p = orthoB * factA + orthoA * factB;
373  btScalar len2 = p.length2();
374  if (len2 > SIMD_EPSILON)
375  {
376  p /= btSqrt(len2);
377  }
378  else
379  {
380  p = trA.getBasis().getColumn(1);
381  }
382  // make one more ortho
383  q = ax1.cross(p);
384  // fill two rows
385  tmpA = relA.cross(p);
386  tmpB = relB.cross(p);
387  for (i = 0; i < 3; i++) info->m_J1angularAxis[s2 + i] = tmpA[i];
388  for (i = 0; i < 3; i++) info->m_J2angularAxis[s2 + i] = -tmpB[i];
389  tmpA = relA.cross(q);
390  tmpB = relB.cross(q);
391  if (hasStaticBody && getSolveAngLimit())
392  { // to make constraint between static and dynamic objects more rigid
393  // remove wA (or wB) from equation if angular limit is hit
394  tmpB *= factB;
395  tmpA *= factA;
396  }
397  for (i = 0; i < 3; i++) info->m_J1angularAxis[s3 + i] = tmpA[i];
398  for (i = 0; i < 3; i++) info->m_J2angularAxis[s3 + i] = -tmpB[i];
399  for (i = 0; i < 3; i++) info->m_J1linearAxis[s2 + i] = p[i];
400  for (i = 0; i < 3; i++) info->m_J1linearAxis[s3 + i] = q[i];
401  for (i = 0; i < 3; i++) info->m_J2linearAxis[s2 + i] = -p[i];
402  for (i = 0; i < 3; i++) info->m_J2linearAxis[s3 + i] = -q[i];
403  }
404  else
405  { // old way - maybe incorrect if bodies are not on the slider axis
406  // see discussion "Bug in slider constraint" http://bulletphysics.org/Bullet/phpBB3/viewtopic.php?f=9&t=4024&start=0
407  c = bodyB_trans.getOrigin() - bodyA_trans.getOrigin();
408  btVector3 tmp = c.cross(p);
409  for (i = 0; i < 3; i++) info->m_J1angularAxis[s2 + i] = factA * tmp[i];
410  for (i = 0; i < 3; i++) info->m_J2angularAxis[s2 + i] = factB * tmp[i];
411  tmp = c.cross(q);
412  for (i = 0; i < 3; i++) info->m_J1angularAxis[s3 + i] = factA * tmp[i];
413  for (i = 0; i < 3; i++) info->m_J2angularAxis[s3 + i] = factB * tmp[i];
414 
415  for (i = 0; i < 3; i++) info->m_J1linearAxis[s2 + i] = p[i];
416  for (i = 0; i < 3; i++) info->m_J1linearAxis[s3 + i] = q[i];
417  for (i = 0; i < 3; i++) info->m_J2linearAxis[s2 + i] = -p[i];
418  for (i = 0; i < 3; i++) info->m_J2linearAxis[s3 + i] = -q[i];
419  }
420  // compute two elements of right hand side
421 
422  // k = info->fps * info->erp * getSoftnessOrthoLin();
424  k = info->fps * currERP;
425 
426  btScalar rhs = k * p.dot(ofs);
427  info->m_constraintError[s2] = rhs;
428  rhs = k * q.dot(ofs);
429  info->m_constraintError[s3] = rhs;
431  {
432  info->cfm[s2] = m_cfmOrthoLin;
433  info->cfm[s3] = m_cfmOrthoLin;
434  }
435 
436  // check linear limits
437  limit_err = btScalar(0.0);
438  limit = 0;
439  if (getSolveLinLimit())
440  {
441  limit_err = getLinDepth() * signFact;
442  limit = (limit_err > btScalar(0.0)) ? 2 : 1;
443  }
444  bool powered = getPoweredLinMotor();
445  // if the slider has joint limits or motor, add in the extra row
446  if (limit || powered)
447  {
448  nrow++;
449  srow = nrow * info->rowskip;
450  info->m_J1linearAxis[srow + 0] = ax1[0];
451  info->m_J1linearAxis[srow + 1] = ax1[1];
452  info->m_J1linearAxis[srow + 2] = ax1[2];
453  info->m_J2linearAxis[srow + 0] = -ax1[0];
454  info->m_J2linearAxis[srow + 1] = -ax1[1];
455  info->m_J2linearAxis[srow + 2] = -ax1[2];
456  // linear torque decoupling step:
457  //
458  // we have to be careful that the linear constraint forces (+/- ax1) applied to the two bodies
459  // do not create a torque couple. in other words, the points that the
460  // constraint force is applied at must lie along the same ax1 axis.
461  // a torque couple will result in limited slider-jointed free
462  // bodies from gaining angular momentum.
464  {
465  // this is needed only when bodyA and bodyB are both dynamic.
466  if (!hasStaticBody)
467  {
468  tmpA = relA.cross(ax1);
469  tmpB = relB.cross(ax1);
470  info->m_J1angularAxis[srow + 0] = tmpA[0];
471  info->m_J1angularAxis[srow + 1] = tmpA[1];
472  info->m_J1angularAxis[srow + 2] = tmpA[2];
473  info->m_J2angularAxis[srow + 0] = -tmpB[0];
474  info->m_J2angularAxis[srow + 1] = -tmpB[1];
475  info->m_J2angularAxis[srow + 2] = -tmpB[2];
476  }
477  }
478  else
479  { // The old way. May be incorrect if bodies are not on the slider axis
480  btVector3 ltd; // Linear Torque Decoupling vector (a torque)
481  ltd = c.cross(ax1);
482  info->m_J1angularAxis[srow + 0] = factA * ltd[0];
483  info->m_J1angularAxis[srow + 1] = factA * ltd[1];
484  info->m_J1angularAxis[srow + 2] = factA * ltd[2];
485  info->m_J2angularAxis[srow + 0] = factB * ltd[0];
486  info->m_J2angularAxis[srow + 1] = factB * ltd[1];
487  info->m_J2angularAxis[srow + 2] = factB * ltd[2];
488  }
489  // right-hand part
490  btScalar lostop = getLowerLinLimit();
491  btScalar histop = getUpperLinLimit();
492  if (limit && (lostop == histop))
493  { // the joint motor is ineffective
494  powered = false;
495  }
496  info->m_constraintError[srow] = 0.;
497  info->m_lowerLimit[srow] = 0.;
498  info->m_upperLimit[srow] = 0.;
499  currERP = (m_flags & BT_SLIDER_FLAGS_ERP_LIMLIN) ? m_softnessLimLin : info->erp;
500  if (powered)
501  {
503  {
504  info->cfm[srow] = m_cfmDirLin;
505  }
507  btScalar mot_fact = getMotorFactor(m_linPos, m_lowerLinLimit, m_upperLinLimit, tag_vel, info->fps * currERP);
508  info->m_constraintError[srow] -= signFact * mot_fact * getTargetLinMotorVelocity();
509  info->m_lowerLimit[srow] += -getMaxLinMotorForce() / info->fps;
510  info->m_upperLimit[srow] += getMaxLinMotorForce() / info->fps;
511  }
512  if (limit)
513  {
514  k = info->fps * currERP;
515  info->m_constraintError[srow] += k * limit_err;
517  {
518  info->cfm[srow] = m_cfmLimLin;
519  }
520  if (lostop == histop)
521  { // limited low and high simultaneously
522  info->m_lowerLimit[srow] = -SIMD_INFINITY;
523  info->m_upperLimit[srow] = SIMD_INFINITY;
524  }
525  else if (limit == 1)
526  { // low limit
527  info->m_lowerLimit[srow] = -SIMD_INFINITY;
528  info->m_upperLimit[srow] = 0;
529  }
530  else
531  { // high limit
532  info->m_lowerLimit[srow] = 0;
533  info->m_upperLimit[srow] = SIMD_INFINITY;
534  }
535  // bounce (we'll use slider parameter abs(1.0 - m_dampingLimLin) for that)
536  btScalar bounce = btFabs(btScalar(1.0) - getDampingLimLin());
537  if (bounce > btScalar(0.0))
538  {
539  btScalar vel = linVelA.dot(ax1);
540  vel -= linVelB.dot(ax1);
541  vel *= signFact;
542  // only apply bounce if the velocity is incoming, and if the
543  // resulting c[] exceeds what we already have.
544  if (limit == 1)
545  { // low limit
546  if (vel < 0)
547  {
548  btScalar newc = -bounce * vel;
549  if (newc > info->m_constraintError[srow])
550  {
551  info->m_constraintError[srow] = newc;
552  }
553  }
554  }
555  else
556  { // high limit - all those computations are reversed
557  if (vel > 0)
558  {
559  btScalar newc = -bounce * vel;
560  if (newc < info->m_constraintError[srow])
561  {
562  info->m_constraintError[srow] = newc;
563  }
564  }
565  }
566  }
567  info->m_constraintError[srow] *= getSoftnessLimLin();
568  } // if(limit)
569  } // if linear limit
570  // check angular limits
571  limit_err = btScalar(0.0);
572  limit = 0;
573  if (getSolveAngLimit())
574  {
575  limit_err = getAngDepth();
576  limit = (limit_err > btScalar(0.0)) ? 1 : 2;
577  }
578  // if the slider has joint limits, add in the extra row
579  powered = getPoweredAngMotor();
580  if (limit || powered)
581  {
582  nrow++;
583  srow = nrow * info->rowskip;
584  info->m_J1angularAxis[srow + 0] = ax1[0];
585  info->m_J1angularAxis[srow + 1] = ax1[1];
586  info->m_J1angularAxis[srow + 2] = ax1[2];
587 
588  info->m_J2angularAxis[srow + 0] = -ax1[0];
589  info->m_J2angularAxis[srow + 1] = -ax1[1];
590  info->m_J2angularAxis[srow + 2] = -ax1[2];
591 
592  btScalar lostop = getLowerAngLimit();
593  btScalar histop = getUpperAngLimit();
594  if (limit && (lostop == histop))
595  { // the joint motor is ineffective
596  powered = false;
597  }
598  currERP = (m_flags & BT_SLIDER_FLAGS_ERP_LIMANG) ? m_softnessLimAng : info->erp;
599  if (powered)
600  {
602  {
603  info->cfm[srow] = m_cfmDirAng;
604  }
606  info->m_constraintError[srow] = mot_fact * getTargetAngMotorVelocity();
607  info->m_lowerLimit[srow] = -getMaxAngMotorForce() / info->fps;
608  info->m_upperLimit[srow] = getMaxAngMotorForce() / info->fps;
609  }
610  if (limit)
611  {
612  k = info->fps * currERP;
613  info->m_constraintError[srow] += k * limit_err;
615  {
616  info->cfm[srow] = m_cfmLimAng;
617  }
618  if (lostop == histop)
619  {
620  // limited low and high simultaneously
621  info->m_lowerLimit[srow] = -SIMD_INFINITY;
622  info->m_upperLimit[srow] = SIMD_INFINITY;
623  }
624  else if (limit == 1)
625  { // low limit
626  info->m_lowerLimit[srow] = 0;
627  info->m_upperLimit[srow] = SIMD_INFINITY;
628  }
629  else
630  { // high limit
631  info->m_lowerLimit[srow] = -SIMD_INFINITY;
632  info->m_upperLimit[srow] = 0;
633  }
634  // bounce (we'll use slider parameter abs(1.0 - m_dampingLimAng) for that)
635  btScalar bounce = btFabs(btScalar(1.0) - getDampingLimAng());
636  if (bounce > btScalar(0.0))
637  {
638  btScalar vel = m_rbA.getAngularVelocity().dot(ax1);
639  vel -= m_rbB.getAngularVelocity().dot(ax1);
640  // only apply bounce if the velocity is incoming, and if the
641  // resulting c[] exceeds what we already have.
642  if (limit == 1)
643  { // low limit
644  if (vel < 0)
645  {
646  btScalar newc = -bounce * vel;
647  if (newc > info->m_constraintError[srow])
648  {
649  info->m_constraintError[srow] = newc;
650  }
651  }
652  }
653  else
654  { // high limit - all those computations are reversed
655  if (vel > 0)
656  {
657  btScalar newc = -bounce * vel;
658  if (newc < info->m_constraintError[srow])
659  {
660  info->m_constraintError[srow] = newc;
661  }
662  }
663  }
664  }
665  info->m_constraintError[srow] *= getSoftnessLimAng();
666  } // if(limit)
667  } // if angular limit or powered
668 }
669 
672 void btSliderConstraint::setParam(int num, btScalar value, int axis)
673 {
674  switch (num)
675  {
677  if (axis < 1)
678  {
679  m_softnessLimLin = value;
681  }
682  else if (axis < 3)
683  {
684  m_softnessOrthoLin = value;
686  }
687  else if (axis == 3)
688  {
689  m_softnessLimAng = value;
691  }
692  else if (axis < 6)
693  {
694  m_softnessOrthoAng = value;
696  }
697  else
698  {
700  }
701  break;
702  case BT_CONSTRAINT_CFM:
703  if (axis < 1)
704  {
705  m_cfmDirLin = value;
707  }
708  else if (axis == 3)
709  {
710  m_cfmDirAng = value;
712  }
713  else
714  {
716  }
717  break;
719  if (axis < 1)
720  {
721  m_cfmLimLin = value;
723  }
724  else if (axis < 3)
725  {
726  m_cfmOrthoLin = value;
728  }
729  else if (axis == 3)
730  {
731  m_cfmLimAng = value;
733  }
734  else if (axis < 6)
735  {
736  m_cfmOrthoAng = value;
738  }
739  else
740  {
742  }
743  break;
744  }
745 }
746 
748 btScalar btSliderConstraint::getParam(int num, int axis) const
749 {
750  btScalar retVal(SIMD_INFINITY);
751  switch (num)
752  {
754  if (axis < 1)
755  {
757  retVal = m_softnessLimLin;
758  }
759  else if (axis < 3)
760  {
762  retVal = m_softnessOrthoLin;
763  }
764  else if (axis == 3)
765  {
767  retVal = m_softnessLimAng;
768  }
769  else if (axis < 6)
770  {
772  retVal = m_softnessOrthoAng;
773  }
774  else
775  {
777  }
778  break;
779  case BT_CONSTRAINT_CFM:
780  if (axis < 1)
781  {
783  retVal = m_cfmDirLin;
784  }
785  else if (axis == 3)
786  {
788  retVal = m_cfmDirAng;
789  }
790  else
791  {
793  }
794  break;
796  if (axis < 1)
797  {
799  retVal = m_cfmLimLin;
800  }
801  else if (axis < 3)
802  {
804  retVal = m_cfmOrthoLin;
805  }
806  else if (axis == 3)
807  {
809  retVal = m_cfmLimAng;
810  }
811  else if (axis < 6)
812  {
814  retVal = m_cfmOrthoAng;
815  }
816  else
817  {
819  }
820  break;
821  }
822  return retVal;
823 }
virtual void getInfo2(btConstraintInfo2 *info)
virtual void setParam(int num, btScalar value, int axis=-1)
bool m_useSolveConstraintObsolete
virtual void getInfo1(btConstraintInfo1 *info)
void getInfo2NonVirtual(btConstraintInfo2 *info, const btTransform &transA, const btTransform &transB, const btMatrix3x3 &invInertiaWorldA, const btMatrix3x3 &invInertiaWorldB)
virtual btScalar getParam(int num, int axis=-1) const
return the local value of parameter
int m_flags
void getInfo1NonVirtual(btConstraintInfo1 *info)
btFixedConstraint btRigidBody & rbB
btFixedConstraint btRigidBody const btTransform & frameInA
btFixedConstraint btRigidBody const btTransform const btTransform & frameInB
const btTransform & getCalculatedTransformA() const
Gets the global transform of the offset for body A.
btTransform m_calculatedTransformB
bool m_useLinearReferenceFrameA
const btTransform & getCalculatedTransformB() const
Gets the global transform of the offset for body B.
btTransform m_frameInB
void calculateTransforms(const btTransform &transA, const btTransform &transB)
Calcs global transform of the offsets.
btTransform m_calculatedTransformA
bool m_useOffsetForConstraintFrame
float btScalar
The btScalar type abstracts floating point numbers, to easily switch between double and single floati...
Definition: btScalar.h:314
SIMD_FORCE_INLINE btScalar btFabs(btScalar x)
Definition: btScalar.h:497
SIMD_FORCE_INLINE btScalar btSqrt(btScalar y)
Definition: btScalar.h:466
#define SIMD_INFINITY
Definition: btScalar.h:544
SIMD_FORCE_INLINE btScalar btAtan2(btScalar x, btScalar y)
Definition: btScalar.h:518
#define SIMD_EPSILON
Definition: btScalar.h:543
#define btAssert(x)
Definition: btScalar.h:295
#define USE_OFFSET_FOR_CONSTANT_FRAME
btScalar m_dampingDirLin
btVector3 getAncorInA()
btVector3 getAncorInB()
btScalar m_softnessOrthoLin
btScalar m_lowerAngLimit
btScalar getDampingLimLin()
btScalar getSoftnessLimAng()
@ BT_SLIDER_FLAGS_CFM_DIRANG
@ BT_SLIDER_FLAGS_ERP_LIMLIN
@ BT_SLIDER_FLAGS_CFM_DIRLIN
@ BT_SLIDER_FLAGS_CFM_ORTANG
@ BT_SLIDER_FLAGS_CFM_ORTLIN
@ BT_SLIDER_FLAGS_ERP_ORTANG
@ BT_SLIDER_FLAGS_CFM_LIMANG
@ BT_SLIDER_FLAGS_ERP_ORTLIN
@ BT_SLIDER_FLAGS_CFM_LIMLIN
@ BT_SLIDER_FLAGS_ERP_LIMANG
btScalar getLowerLinLimit()
btScalar getUpperLinLimit()
btScalar m_dampingOrthoAng
btScalar m_restitutionDirAng
btScalar m_softnessDirLin
bool m_solveAngLim
btScalar m_softnessOrthoAng
btTransform m_frameInA
btVector3 m_depth
bool m_poweredLinMotor
btSliderConstraint(btRigidBody &rbA, btRigidBody &rbB, const btTransform &frameInA, const btTransform &frameInB, bool useLinearReferenceFrameA)
btScalar m_cfmDirLin
btScalar m_dampingLimLin
bool getSolveLinLimit()
btScalar m_restitutionLimLin
btVector3 m_sliderAxis
btScalar m_lowerLinLimit
btScalar m_accumulatedLinMotorImpulse
btScalar m_maxLinMotorForce
btVector3 m_realPivotAInW
btScalar getLinDepth()
btScalar getMaxLinMotorForce()
void initParams()
btScalar m_cfmOrthoLin
btScalar getAngDepth()
btVector3 m_projPivotInW
#define SLIDER_CONSTRAINT_DEF_DAMPING
btScalar m_dampingLimAng
btScalar getMaxAngMotorForce()
btScalar m_upperAngLimit
bool m_solveLinLim
btScalar m_restitutionLimAng
btScalar m_targetAngMotorVelocity
btScalar m_angDepth
btScalar m_angPos
btScalar m_softnessDirAng
btScalar m_maxAngMotorForce
btScalar m_softnessLimAng
btScalar m_cfmLimAng
btScalar m_linPos
btScalar m_restitutionDirLin
btScalar m_accumulatedAngMotorImpulse
#define SLIDER_CONSTRAINT_DEF_SOFTNESS
btScalar m_cfmDirAng
btScalar m_restitutionOrthoLin
btScalar m_dampingDirAng
#define SLIDER_CONSTRAINT_DEF_RESTITUTION
void testAngLimits()
btScalar m_upperLinLimit
btScalar getDampingLimAng()
btVector3 m_realPivotBInW
btScalar getUpperAngLimit()
btScalar getLowerAngLimit()
bool getPoweredAngMotor()
btScalar m_targetLinMotorVelocity
btScalar m_softnessLimLin
bool getSolveAngLimit()
btScalar getSoftnessLimLin()
bool getPoweredLinMotor()
bool m_poweredAngMotor
btScalar m_dampingOrthoLin
btScalar m_cfmLimLin
#define SLIDER_CONSTRAINT_DEF_CFM
void testLinLimits()
btVector3 m_delta
btScalar getTargetLinMotorVelocity()
btScalar m_restitutionOrthoAng
btScalar m_cfmOrthoAng
btScalar getTargetAngMotorVelocity()
btTransform
The btTransform class supports rigid transforms with only translation and rotation and no scaling/she...
Definition: btTransform.h:30
btScalar getMotorFactor(btScalar pos, btScalar lowLim, btScalar uppLim, btScalar vel, btScalar timeFact)
internal method used by the constraint solver, don't use them directly
btRigidBody & m_rbA
SIMD_FORCE_INLINE btScalar btAdjustAngleToLimits(btScalar angleInRadians, btScalar angleLowerLimitInRadians, btScalar angleUpperLimitInRadians)
#define btAssertConstrParams(_par)
btTypedConstraint(btTypedConstraintType type, btRigidBody &rbA)
btRigidBody & m_rbB
static btRigidBody & getFixedBody()
@ BT_CONSTRAINT_CFM
@ BT_CONSTRAINT_STOP_CFM
@ BT_CONSTRAINT_STOP_ERP
@ SLIDER_CONSTRAINT_TYPE
SIMD_FORCE_INLINE void btPlaneSpace1(const T &n, T &p, T &q)
Definition: btVector3.h:1251
btVector3
btVector3 can be used to represent 3D points and vectors. It has an un-used w component to suit 16-by...
Definition: btVector3.h:82
const btVector3 & getAngularVelocity() const
Definition: btRigidBody.h:437
btScalar getInvMass() const
Definition: btRigidBody.h:263
const btTransform & getCenterOfMassTransform() const
Definition: btRigidBody.h:429
const btVector3 & getLinearVelocity() const
Definition: btRigidBody.h:433
#define rot(x, k)
static unsigned c
Definition: RandGen.cpp:83
btScalar * m_J2angularAxis
btScalar * m_J1angularAxis
btScalar * m_constraintError