1 /*************************************************************************
3 * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. *
4 * All rights reserved. Email: russ@q12.org Web: www.q12.org *
6 * Fast iterative solver, David Whittaker. Email: david@csworkbench.com *
8 * This library is free software; you can redistribute it and/or *
9 * modify it under the terms of EITHER: *
10 * (1) The GNU Lesser General Public License as published by the Free *
11 * Software Foundation; either version 2.1 of the License, or (at *
12 * your option) any later version. The text of the GNU Lesser *
13 * General Public License is included with this library in the *
15 * (2) The BSD-style license that is included with this library in *
16 * the file LICENSE-BSD.TXT. *
18 * This library is distributed in the hope that it will be useful, *
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files *
21 * LICENSE.TXT and LICENSE-BSD.TXT for more details. *
23 *************************************************************************/
25 // This is the StepFast code by David Whittaker. This code is faster, but
26 // sometimes less stable than, the original "big matrix" code.
27 // Refer to the user's manual for more information.
28 // Note that this source file duplicates a lot of stuff from step.cpp,
29 // eventually we should move the common code to a third file.
33 #include <ode/odeconfig.h>
35 #include <ode/objects.h>
36 #include <ode/odemath.h>
37 #include <ode/rotation.h>
38 #include <ode/timer.h>
39 #include <ode/error.h>
40 #include <ode/matrix.h>
49 #define ALLOCA dALLOCA16
51 #define RANDOM_JOINT_ORDER
52 //#define FAST_FACTOR //use a factorization approximation to the LCP solver (fast, theoretically less accurate)
53 #define SLOW_LCP //use the old LCP solver
54 //#define NO_ISLANDS //does not perform island creation code (3~4% of simulation time), body disabling doesn't work
58 static int autoEnableDepth
= 2;
60 void dWorldSetAutoEnableDepthSF1 (dxWorld
*world
, int autodepth
)
63 autoEnableDepth
= autodepth
;
68 int dWorldGetAutoEnableDepthSF1 (dxWorld
*world
)
70 return autoEnableDepth
;
73 //little bit of math.... the _sym_ functions assume the return matrix will be symmetric
75 Multiply2_sym_p8p (dReal
* A
, dReal
* B
, dReal
* C
, int p
, int Askip
)
78 dReal sum
, *aa
, *ad
, *bb
, *cc
;
79 dIASSERT (p
> 0 && A
&& B
&& C
);
81 for (i
= 0; i
< p
; i
++)
83 //aa is going accross the matrix, ad down
86 for (j
= i
; j
< p
; j
++)
105 MultiplyAdd2_sym_p8p (dReal
* A
, dReal
* B
, dReal
* C
, int p
, int Askip
)
108 dReal sum
, *aa
, *ad
, *bb
, *cc
;
109 dIASSERT (p
> 0 && A
&& B
&& C
);
111 for (i
= 0; i
< p
; i
++)
113 //aa is going accross the matrix, ad down
116 for (j
= i
; j
< p
; j
++)
119 sum
+= bb
[1] * cc
[1];
120 sum
+= bb
[2] * cc
[2];
121 sum
+= bb
[4] * cc
[4];
122 sum
+= bb
[5] * cc
[5];
123 sum
+= bb
[6] * cc
[6];
136 // this assumes the 4th and 8th rows of B are zero.
139 Multiply0_p81 (dReal
* A
, dReal
* B
, dReal
* C
, int p
)
142 dIASSERT (p
> 0 && A
&& B
&& C
);
158 // this assumes the 4th and 8th rows of B are zero.
161 MultiplyAdd0_p81 (dReal
* A
, dReal
* B
, dReal
* C
, int p
)
164 dIASSERT (p
> 0 && A
&& B
&& C
);
180 // this assumes the 4th and 8th rows of B are zero.
183 Multiply1_8q1 (dReal
* A
, dReal
* B
, dReal
* C
, int q
)
187 dIASSERT (q
> 0 && A
&& B
&& C
);
189 for (k
= 0; k
< q
; k
++)
190 sum
+= B
[k
* 8] * C
[k
];
193 for (k
= 0; k
< q
; k
++)
194 sum
+= B
[1 + k
* 8] * C
[k
];
197 for (k
= 0; k
< q
; k
++)
198 sum
+= B
[2 + k
* 8] * C
[k
];
201 for (k
= 0; k
< q
; k
++)
202 sum
+= B
[4 + k
* 8] * C
[k
];
205 for (k
= 0; k
< q
; k
++)
206 sum
+= B
[5 + k
* 8] * C
[k
];
209 for (k
= 0; k
< q
; k
++)
210 sum
+= B
[6 + k
* 8] * C
[k
];
214 //****************************************************************************
217 // return sin(x)/x. this has a singularity at 0 so special handling is needed
218 // for small arguments.
223 // if |x| < 1e-4 then use a taylor series expansion. this two term expansion
224 // is actually accurate to one LS bit within this range if double precision
225 // is being used - so don't worry!
226 if (dFabs (x
) < 1.0e-4)
227 return REAL (1.0) - x
* x
* REAL (0.166666666666666666667);
232 #if 0 // this is just dxStepBody()
233 // given a body b, apply its linear and angular rotation over the time
234 // interval h, thereby adjusting its position and orientation.
237 moveAndRotateBody (dxBody
* b
, dReal h
)
241 // handle linear velocity
242 for (j
= 0; j
< 3; j
++)
243 b
->posr
.pos
[j
] += h
* b
->lvel
[j
];
245 if (b
->flags
& dxBodyFlagFiniteRotation
)
247 dVector3 irv
; // infitesimal rotation vector
248 dQuaternion q
; // quaternion for finite rotation
250 if (b
->flags
& dxBodyFlagFiniteRotationAxis
)
252 // split the angular velocity vector into a component along the finite
253 // rotation axis, and a component orthogonal to it.
254 dVector3 frv
, irv
; // finite rotation vector
255 dReal k
= dDOT (b
->finite_rot_axis
, b
->avel
);
256 frv
[0] = b
->finite_rot_axis
[0] * k
;
257 frv
[1] = b
->finite_rot_axis
[1] * k
;
258 frv
[2] = b
->finite_rot_axis
[2] * k
;
259 irv
[0] = b
->avel
[0] - frv
[0];
260 irv
[1] = b
->avel
[1] - frv
[1];
261 irv
[2] = b
->avel
[2] - frv
[2];
263 // make a rotation quaternion q that corresponds to frv * h.
264 // compare this with the full-finite-rotation case below.
268 dReal s
= sinc (theta
) * h
;
275 // make a rotation quaternion q that corresponds to w * h
276 dReal wlen
= dSqrt (b
->avel
[0] * b
->avel
[0] + b
->avel
[1] * b
->avel
[1] + b
->avel
[2] * b
->avel
[2]);
278 dReal theta
= wlen
* h
;
280 dReal s
= sinc (theta
) * h
;
281 q
[1] = b
->avel
[0] * s
;
282 q
[2] = b
->avel
[1] * s
;
283 q
[3] = b
->avel
[2] * s
;
286 // do the finite rotation
288 dQMultiply0 (q2
, q
, b
->q
);
289 for (j
= 0; j
< 4; j
++)
292 // do the infitesimal rotation if required
293 if (b
->flags
& dxBodyFlagFiniteRotationAxis
)
296 dWtoDQ (irv
, b
->q
, dq
);
297 for (j
= 0; j
< 4; j
++)
298 b
->q
[j
] += h
* dq
[j
];
303 // the normal way - do an infitesimal rotation
305 dWtoDQ (b
->avel
, b
->q
, dq
);
306 for (j
= 0; j
< 4; j
++)
307 b
->q
[j
] += h
* dq
[j
];
310 // normalize the quaternion and convert it to a rotation matrix
312 dQtoR (b
->q
, b
->posr
.R
);
314 // notify all attached geoms that this body has moved
315 for (dxGeom
* geom
= b
->geom
; geom
; geom
= dGeomGetBodyNext (geom
))
320 //****************************************************************************
321 //This is an implementation of the iterated/relaxation algorithm.
322 //Here is a quick overview of the algorithm per Sergi Valverde's posts to the
327 // Solve constraint c-th
328 // Apply forces to constraint bodies
334 dInternalStepFast (dxWorld
* world
, dxBody
* body
[2], dReal
* GI
[2], dReal
* GinvI
[2], dxJoint
* joint
, dxJoint::Info1 info
, dxJoint::Info2 Jinfo
, dReal stepsize
)
338 dTimerNow ("constraint preprocessing");
341 dReal stepsize1
= dRecip (stepsize
);
344 // nothing to do if no constraints.
349 if (info
.nub
== info
.m
)
352 // compute A = J*invM*J'. first compute JinvM = J*invM. this has the same
353 // format as J so we just go through the constraints in J multiplying by
354 // the appropriate scalars and matrices.
356 dTimerNow ("compute A");
358 dReal JinvM
[2 * 6 * 8];
359 //dSetZero (JinvM, 2 * m * 8);
361 dReal
*Jsrc
= Jinfo
.J1l
;
365 for (j
= m
- 1; j
>= 0; j
--)
367 for (k
= 0; k
< 3; k
++)
368 Jdst
[k
] = Jsrc
[k
] * body
[0]->invMass
;
369 dMULTIPLY0_133 (Jdst
+ 4, Jsrc
+ 4, GinvI
[0]);
377 Jdst
= JinvM
+ 8 * m
;
378 for (j
= m
- 1; j
>= 0; j
--)
380 for (k
= 0; k
< 3; k
++)
381 Jdst
[k
] = Jsrc
[k
] * body
[1]->invMass
;
382 dMULTIPLY0_133 (Jdst
+ 4, Jsrc
+ 4, GinvI
[1]);
389 // now compute A = JinvM * J'.
390 int mskip
= dPAD (m
);
392 //dSetZero (A, 6 * 8);
395 Multiply2_sym_p8p (A
, JinvM
, Jinfo
.J1l
, m
, mskip
);
397 MultiplyAdd2_sym_p8p (A
, JinvM
+ 8 * m
, Jinfo
.J2l
,
401 Multiply2_sym_p8p (A
, JinvM
+ 8 * m
, Jinfo
.J2l
,
405 // add cfm to the diagonal of A
406 for (i
= 0; i
< m
; i
++)
407 A
[i
* mskip
+ i
] += Jinfo
.cfm
[i
] * stepsize1
;
409 // compute the right hand side `rhs'
411 dTimerNow ("compute rhs");
414 //dSetZero (tmp1, 16);
415 // put v/h + invM*fe into tmp1
416 for (i
= 0; i
< 2; i
++)
420 for (j
= 0; j
< 3; j
++)
421 tmp1
[i
* 8 + j
] = body
[i
]->facc
[j
] * body
[i
]->invMass
+ body
[i
]->lvel
[j
] * stepsize1
;
422 dMULTIPLY0_331 (tmp1
+ i
* 8 + 4, GinvI
[i
], body
[i
]->tacc
);
423 for (j
= 0; j
< 3; j
++)
424 tmp1
[i
* 8 + 4 + j
] += body
[i
]->avel
[j
] * stepsize1
;
426 // put J*tmp1 into rhs
431 Multiply0_p81 (rhs
, Jinfo
.J1l
, tmp1
, m
);
433 MultiplyAdd0_p81 (rhs
, Jinfo
.J2l
, tmp1
+ 8, m
);
436 Multiply0_p81 (rhs
, Jinfo
.J2l
, tmp1
+ 8, m
);
440 for (i
= 0; i
< m
; i
++)
441 rhs
[i
] = Jinfo
.c
[i
] * stepsize1
- rhs
[i
];
444 // solve the LCP problem and get lambda.
445 // this will destroy A but that's okay
447 dTimerNow ("solving LCP problem");
449 dReal
*lambda
= (dReal
*) ALLOCA (m
* sizeof (dReal
));
450 dReal
*residual
= (dReal
*) ALLOCA (m
* sizeof (dReal
));
452 memcpy (lo
, Jinfo
.lo
, m
* sizeof (dReal
));
453 memcpy (hi
, Jinfo
.hi
, m
* sizeof (dReal
));
454 dSolveLCP (m
, A
, lambda
, rhs
, residual
, nub
, lo
, hi
, Jinfo
.findex
);
457 // LCP Solver replacement:
458 // This algorithm goes like this:
459 // Do a straightforward LDLT factorization of the matrix A, solving for
461 // For each x[i] that is outside of the bounds of lo[i] and hi[i],
462 // clamp x[i] into that range.
463 // Substitute into A the now known x's
464 // subtract the residual away from the rhs.
465 // Remove row and column i from L, updating the factorization
466 // place the known x's at the end of the array, keeping up with location in p
467 // Repeat until all constraints have been clamped or all are within bounds
469 // This is probably only faster in the single joint case where only one repeat is
473 // factorize A (L*D*L'=A)
475 dTimerNow ("factorize A");
479 memcpy (L
, A
, m
* mskip
* sizeof (dReal
));
480 dFactorLDLT (L
, d
, m
, mskip
);
484 dTimerNow ("compute lambda");
487 int left
= m
; //constraints left to solve.
492 for (i
= 0; i
< 6; i
++)
496 memcpy (x
, rhs
, left
* sizeof (dReal
));
497 dSolveLDLT (L
, d
, x
, left
, mskip
);
500 for (i
= 0; i
< left
; i
++)
504 // This isn't the exact same use of findex as dSolveLCP.... since x[findex]
505 // may change after I've already clamped x[i], but it should be close
506 if (Jinfo
.findex
[j
] > -1)
508 dReal f
= fabs (Jinfo
.hi
[j
] * x
[p
[Jinfo
.findex
[j
]]]);
518 if (x
[i
] > Jinfo
.hi
[j
])
520 else if (x
[i
] < Jinfo
.lo
[j
])
528 if (fixed
== 0 || fixed
== left
) //no change or all constraints solved
531 for (i
= 0; i
< left
; i
++) //sub in to right hand side.
533 for (j
= 0; j
< left
; j
++)
535 rhs
[j
] -= A
[j
* mskip
+ i
] * x
[i
];
537 for (int r
= left
- 1; r
>= 0; r
--) //eliminate row/col for fixed variables
541 //dRemoveLDLT adapted for use without row pointers.
545 continue; // deleting last row/col is easy
550 for (i
= 0; i
< left
; i
++)
551 a
[i
] = -A
[i
* mskip
];
553 dLDLTAddTL (L
, d
, a
, left
, mskip
);
559 for (i
= 0; i
< r
; i
++)
560 t
[i
] = L
[r
* mskip
+ i
] / d
[i
];
561 for (i
= 0; i
< left
- r
; i
++)
562 a
[i
] = dDot (L
+ (r
+ i
) * mskip
, t
, r
) - A
[(r
+ i
) * mskip
+ r
];
564 dLDLTAddTL (L
+ r
* mskip
+ r
, d
+ r
, a
, left
- r
, mskip
);
567 dRemoveRowCol (L
, left
, mskip
, r
);
574 memmove (d
+ r
, d
+ r
+ 1, (left
- r
) * sizeof (dReal
));
575 memmove (rhs
+ r
, rhs
+ r
+ 1, (left
- r
) * sizeof (dReal
));
576 //x will get written over by rhs anyway, no need to move it around
577 //just store the fixed value we just discovered in it.
579 for (i
= 0; i
< m
; i
++)
580 if (p
[i
] > r
&& p
[i
] <= left
)
588 for (i
= 0; i
< m
; i
++)
591 // compute the constraint force `cforce'
593 dTimerNow ("compute constraint force");
596 // compute cforce = J'*lambda
597 dJointFeedback
*fb
= joint
->feedback
;
599 //dSetZero (cforce, 16);
603 // the user has requested feedback on the amount of force that this
604 // joint is applying to the bodies. we use a slightly slower
605 // computation that splits out the force components and puts them
606 // in the feedback structure.
607 dReal data1
[8], data2
[8];
610 Multiply1_8q1 (data1
, Jinfo
.J1l
, lambda
, m
);
612 cf1
[0] = (fb
->f1
[0] = data1
[0]);
613 cf1
[1] = (fb
->f1
[1] = data1
[1]);
614 cf1
[2] = (fb
->f1
[2] = data1
[2]);
615 cf1
[4] = (fb
->t1
[0] = data1
[4]);
616 cf1
[5] = (fb
->t1
[1] = data1
[5]);
617 cf1
[6] = (fb
->t1
[2] = data1
[6]);
621 Multiply1_8q1 (data2
, Jinfo
.J2l
, lambda
, m
);
622 dReal
*cf2
= cforce
+ 8;
623 cf2
[0] = (fb
->f2
[0] = data2
[0]);
624 cf2
[1] = (fb
->f2
[1] = data2
[1]);
625 cf2
[2] = (fb
->f2
[2] = data2
[2]);
626 cf2
[4] = (fb
->t2
[0] = data2
[4]);
627 cf2
[5] = (fb
->t2
[1] = data2
[5]);
628 cf2
[6] = (fb
->t2
[2] = data2
[6]);
633 // no feedback is required, let's compute cforce the faster way
635 Multiply1_8q1 (cforce
, Jinfo
.J1l
, lambda
, m
);
637 Multiply1_8q1 (cforce
+ 8, Jinfo
.J2l
, lambda
, m
);
640 for (i
= 0; i
< 2; i
++)
644 for (j
= 0; j
< 3; j
++)
646 body
[i
]->facc
[j
] += cforce
[i
* 8 + j
];
647 body
[i
]->tacc
[j
] += cforce
[i
* 8 + 4 + j
];
653 dInternalStepIslandFast (dxWorld
* world
, dxBody
* const *bodies
, int nb
, dxJoint
* const *_joints
, int nj
, dReal stepsize
, int maxiterations
)
656 dTimerNow ("preprocessing");
658 dxBody
*bodyPair
[2], *body
;
659 dReal
*GIPair
[2], *GinvIPair
[2];
662 dReal ministep
= stepsize
/ maxiterations
;
664 // make a local copy of the joint array, because we might want to modify it.
665 // (the "dxJoint *const*" declaration says we're allowed to modify the joints
666 // but not the joint array, because the caller might need it unchanged).
667 dxJoint
**joints
= (dxJoint
**) ALLOCA (nj
* sizeof (dxJoint
*));
668 memcpy (joints
, _joints
, nj
* sizeof (dxJoint
*));
670 // get m = total constraint dimension, nub = number of unbounded variables.
671 // create constraint offset array and number-of-rows array for all joints.
672 // the constraints are re-ordered as follows: the purely unbounded
673 // constraints, the mixed unbounded + LCP constraints, and last the purely
674 // LCP constraints. this assists the LCP solver to put all unbounded
675 // variables at the start for a quick factorization.
677 // joints with m=0 are inactive and are removed from the joints array
678 // entirely, so that the code that follows does not consider them.
679 // also number all active joints in the joint list (set their tag values).
680 // inactive joints receive a tag value of -1.
683 dxJoint::Info1
* info
= (dxJoint::Info1
*) ALLOCA (nj
* sizeof (dxJoint::Info1
));
684 int *ofs
= (int *) ALLOCA (nj
* sizeof (int));
685 for (i
= 0, j
= 0; j
< nj
; j
++)
687 joints
[j
]->vtable
->getInfo1 (joints
[j
], info
+ i
);
688 dIASSERT (info
[i
].m
>= 0 && info
[i
].m
<= 6 && info
[i
].nub
>= 0 && info
[i
].nub
<= info
[i
].m
);
691 joints
[i
] = joints
[j
];
702 // the purely unbounded constraints
703 for (i
= 0; i
< nj
; i
++)
715 dxJoint::Info2
* Jinfo
= NULL
;
719 // create a constraint equation right hand side vector `c', a constraint
720 // force mixing vector `cfm', and LCP low and high bound vectors, and an
722 c
= (dReal
*) ALLOCA (m
* sizeof (dReal
));
723 cfm
= (dReal
*) ALLOCA (m
* sizeof (dReal
));
724 lo
= (dReal
*) ALLOCA (m
* sizeof (dReal
));
725 hi
= (dReal
*) ALLOCA (m
* sizeof (dReal
));
726 findex
= (int *) ALLOCA (m
* sizeof (int));
728 dSetValue (cfm
, m
, world
->global_cfm
);
729 dSetValue (lo
, m
, -dInfinity
);
730 dSetValue (hi
, m
, dInfinity
);
731 for (i
= 0; i
< m
; i
++)
734 // get jacobian data from constraints. a (2*m)x8 matrix will be created
735 // to store the two jacobian blocks from each constraint. it has this
738 // l l l 0 a a a 0 \ .
739 // l l l 0 a a a 0 }-- jacobian body 1 block for joint 0 (3 rows)
741 // l l l 0 a a a 0 \ .
742 // l l l 0 a a a 0 }-- jacobian body 2 block for joint 0 (3 rows)
744 // l l l 0 a a a 0 }--- jacobian body 1 block for joint 1 (1 row)
745 // l l l 0 a a a 0 }--- jacobian body 2 block for joint 1 (1 row)
748 // (lll) = linear jacobian data
749 // (aaa) = angular jacobian data
752 dTimerNow ("create J");
754 J
= (dReal
*) ALLOCA (2 * m
* 8 * sizeof (dReal
));
755 dSetZero (J
, 2 * m
* 8);
756 Jinfo
= (dxJoint::Info2
*) ALLOCA (nj
* sizeof (dxJoint::Info2
));
757 for (i
= 0; i
< nj
; i
++)
759 Jinfo
[i
].rowskip
= 8;
760 Jinfo
[i
].fps
= dRecip (stepsize
);
761 Jinfo
[i
].erp
= world
->global_erp
;
762 Jinfo
[i
].J1l
= J
+ 2 * 8 * ofs
[i
];
763 Jinfo
[i
].J1a
= Jinfo
[i
].J1l
+ 4;
764 Jinfo
[i
].J2l
= Jinfo
[i
].J1l
+ 8 * info
[i
].m
;
765 Jinfo
[i
].J2a
= Jinfo
[i
].J2l
+ 4;
766 Jinfo
[i
].c
= c
+ ofs
[i
];
767 Jinfo
[i
].cfm
= cfm
+ ofs
[i
];
768 Jinfo
[i
].lo
= lo
+ ofs
[i
];
769 Jinfo
[i
].hi
= hi
+ ofs
[i
];
770 Jinfo
[i
].findex
= findex
+ ofs
[i
];
771 //joints[i]->vtable->getInfo2 (joints[i], Jinfo+i);
776 dReal
*saveFacc
= (dReal
*) ALLOCA (nb
* 4 * sizeof (dReal
));
777 dReal
*saveTacc
= (dReal
*) ALLOCA (nb
* 4 * sizeof (dReal
));
778 dReal
*globalI
= (dReal
*) ALLOCA (nb
* 12 * sizeof (dReal
));
779 dReal
*globalInvI
= (dReal
*) ALLOCA (nb
* 12 * sizeof (dReal
));
780 for (b
= 0; b
< nb
; b
++)
782 for (i
= 0; i
< 4; i
++)
784 saveFacc
[b
* 4 + i
] = bodies
[b
]->facc
[i
];
785 saveTacc
[b
* 4 + i
] = bodies
[b
]->tacc
[i
];
790 for (iter
= 0; iter
< maxiterations
; iter
++)
793 dTimerNow ("applying inertia and gravity");
795 dReal tmp
[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
797 for (b
= 0; b
< nb
; b
++)
801 // for all bodies, compute the inertia tensor and its inverse in the global
802 // frame, and compute the rotational force and add it to the torque
803 // accumulator. I and invI are vertically stacked 3x4 matrices, one per body.
804 // @@@ check computation of rotational force.
806 // compute inertia tensor in global frame
807 dMULTIPLY2_333 (tmp
, body
->mass
.I
, body
->posr
.R
);
808 dMULTIPLY0_333 (globalI
+ b
* 12, body
->posr
.R
, tmp
);
809 // compute inverse inertia tensor in global frame
810 dMULTIPLY2_333 (tmp
, body
->invI
, body
->posr
.R
);
811 dMULTIPLY0_333 (globalInvI
+ b
* 12, body
->posr
.R
, tmp
);
813 for (i
= 0; i
< 4; i
++)
814 body
->tacc
[i
] = saveTacc
[b
* 4 + i
];
816 // compute rotational force
817 dMULTIPLY0_331 (tmp
, globalI
+ b
* 12, body
->avel
);
818 dCROSS (body
->tacc
, -=, body
->avel
, tmp
);
821 // add the gravity force to all bodies
822 if ((body
->flags
& dxBodyNoGravity
) == 0)
824 body
->facc
[0] = saveFacc
[b
* 4 + 0] + body
->mass
.mass
* world
->gravity
[0];
825 body
->facc
[1] = saveFacc
[b
* 4 + 1] + body
->mass
.mass
* world
->gravity
[1];
826 body
->facc
[2] = saveFacc
[b
* 4 + 2] + body
->mass
.mass
* world
->gravity
[2];
829 body
->facc
[0] = saveFacc
[b
* 4 + 0];
830 body
->facc
[1] = saveFacc
[b
* 4 + 1];
831 body
->facc
[2] = saveFacc
[b
* 4 + 2];
837 #ifdef RANDOM_JOINT_ORDER
839 dTimerNow ("randomizing joint order");
841 //randomize the order of the joints by looping through the array
842 //and swapping the current joint pointer with a random one before it.
843 for (j
= 0; j
< nj
; j
++)
846 dxJoint::Info1 i1
= info
[j
];
847 dxJoint::Info2 i2
= Jinfo
[j
];
848 const int r
= dRandInt(j
+1);
850 joints
[j
] = joints
[r
];
859 //now iterate through the random ordered joint array we created.
860 for (j
= 0; j
< nj
; j
++)
863 dTimerNow ("setting up joint");
866 bodyPair
[0] = joint
->node
[0].body
;
867 bodyPair
[1] = joint
->node
[1].body
;
869 if (bodyPair
[0] && (bodyPair
[0]->flags
& dxBodyDisabled
))
871 if (bodyPair
[1] && (bodyPair
[1]->flags
& dxBodyDisabled
))
874 //if this joint is not connected to any enabled bodies, skip it.
875 if (!bodyPair
[0] && !bodyPair
[1])
880 GIPair
[0] = globalI
+ bodyPair
[0]->tag
* 12;
881 GinvIPair
[0] = globalInvI
+ bodyPair
[0]->tag
* 12;
885 GIPair
[1] = globalI
+ bodyPair
[1]->tag
* 12;
886 GinvIPair
[1] = globalInvI
+ bodyPair
[1]->tag
* 12;
889 joints
[j
]->vtable
->getInfo2 (joints
[j
], Jinfo
+ j
);
891 //dInternalStepIslandFast is an exact copy of the old routine with one
892 //modification: the calculated forces are added back to the facc and tacc
893 //vectors instead of applying them to the bodies and moving them.
896 dInternalStepFast (world
, bodyPair
, GIPair
, GinvIPair
, joint
, info
[j
], Jinfo
[j
], ministep
);
901 dTimerNow ("moving bodies");
903 //Now we can simulate all the free floating bodies, and move them.
904 for (b
= 0; b
< nb
; b
++)
908 for (i
= 0; i
< 4; i
++)
910 body
->facc
[i
] *= ministep
;
911 body
->tacc
[i
] *= ministep
;
915 dMULTIPLYADD0_331 (body
->avel
, globalInvI
+ b
* 12, body
->tacc
);
918 for (i
= 0; i
< 3; i
++)
919 body
->lvel
[i
] += body
->invMass
* body
->facc
[i
];
922 dxStepBody (body
, ministep
);
925 for (b
= 0; b
< nb
; b
++)
926 for (j
= 0; j
< 4; j
++)
927 bodies
[b
]->facc
[j
] = bodies
[b
]->tacc
[j
] = 0;
933 // Since the iterative algorithm doesn't care about islands of bodies, this is a
934 // faster algorithm that just sends it all the joints and bodies in one array.
935 // It's downfall is it's inability to handle disabled bodies as well as the old one.
937 processIslandsFast (dxWorld
* world
, dReal stepsize
, int maxiterations
)
939 // nothing to do if no bodies
943 dInternalHandleAutoDisabling (world
,stepsize
);
946 dTimerStart ("creating joint and body arrays");
948 dxBody
**bodies
, *body
;
949 dxJoint
**joints
, *joint
;
950 joints
= (dxJoint
**) ALLOCA (world
->nj
* sizeof (dxJoint
*));
951 bodies
= (dxBody
**) ALLOCA (world
->nb
* sizeof (dxBody
*));
954 for (joint
= world
->firstjoint
; joint
; joint
= (dxJoint
*) joint
->next
)
955 joints
[nj
++] = joint
;
958 for (body
= world
->firstbody
; body
; body
= (dxBody
*) body
->next
)
961 dInternalStepIslandFast (world
, bodies
, nb
, joints
, nj
, stepsize
, maxiterations
);
964 dTimerReport (stdout
, 1);
970 //****************************************************************************
973 // this groups all joints and bodies in a world into islands. all objects
974 // in an island are reachable by going through connected bodies and joints.
975 // each island can be simulated separately.
976 // note that joints that are not attached to anything will not be included
977 // in any island, an so they do not affect the simulation.
979 // this function starts new island from unvisited bodies. however, it will
980 // never start a new islands from a disabled body. thus islands of disabled
981 // bodies will not be included in the simulation. disabled bodies are
982 // re-enabled if they are found to be part of an active island.
985 processIslandsFast (dxWorld
* world
, dReal stepsize
, int maxiterations
)
988 dTimerStart ("Island Setup");
990 dxBody
*b
, *bb
, **body
;
993 // nothing to do if no bodies
997 dInternalHandleAutoDisabling (world
,stepsize
);
999 // make arrays for body and joint lists (for a single island) to go into
1000 body
= (dxBody
**) ALLOCA (world
->nb
* sizeof (dxBody
*));
1001 joint
= (dxJoint
**) ALLOCA (world
->nj
* sizeof (dxJoint
*));
1002 int bcount
= 0; // number of bodies in `body'
1003 int jcount
= 0; // number of joints in `joint'
1007 // set all body/joint tags to 0
1008 for (b
= world
->firstbody
; b
; b
= (dxBody
*) b
->next
)
1010 for (j
= world
->firstjoint
; j
; j
= (dxJoint
*) j
->next
)
1013 // allocate a stack of unvisited bodies in the island. the maximum size of
1014 // the stack can be the lesser of the number of bodies or joints, because
1015 // new bodies are only ever added to the stack by going through untagged
1016 // joints. all the bodies in the stack must be tagged!
1017 int stackalloc
= (world
->nj
< world
->nb
) ? world
->nj
: world
->nb
;
1018 dxBody
**stack
= (dxBody
**) ALLOCA (stackalloc
* sizeof (dxBody
*));
1019 int *autostack
= (int *) ALLOCA (stackalloc
* sizeof (int));
1021 for (bb
= world
->firstbody
; bb
; bb
= (dxBody
*) bb
->next
)
1024 dTimerNow ("Island Processing");
1026 // get bb = the next enabled, untagged body, and tag it
1027 if (bb
->tag
|| (bb
->flags
& dxBodyDisabled
))
1031 // tag all bodies and joints starting from bb.
1033 int autoDepth
= autoEnableDepth
;
1039 while (stacksize
> 0)
1041 b
= stack
[--stacksize
]; // pop body off stack
1042 autoDepth
= autostack
[stacksize
];
1043 body
[bcount
++] = b
; // put body on body list
1046 // traverse and tag all body's joints, add untagged connected bodies
1048 for (dxJointNode
* n
= b
->firstjoint
; n
; n
= n
->next
)
1052 int thisDepth
= autoEnableDepth
;
1054 joint
[jcount
++] = n
->joint
;
1055 if (n
->body
&& !n
->body
->tag
)
1057 if (n
->body
->flags
& dxBodyDisabled
)
1058 thisDepth
= autoDepth
- 1;
1061 n
->body
->flags
&= ~dxBodyDisabled
;
1063 autostack
[stacksize
] = thisDepth
;
1064 stack
[stacksize
++] = n
->body
;
1068 dIASSERT (stacksize
<= world
->nb
);
1069 dIASSERT (stacksize
<= world
->nj
);
1072 // now do something with body and joint lists
1073 dInternalStepIslandFast (world
, body
, bcount
, joint
, jcount
, stepsize
, maxiterations
);
1075 // what we've just done may have altered the body/joint tag values.
1076 // we must make sure that these tags are nonzero.
1077 // also make sure all bodies are in the enabled state.
1079 for (i
= 0; i
< bcount
; i
++)
1082 body
[i
]->flags
&= ~dxBodyDisabled
;
1084 for (i
= 0; i
< jcount
; i
++)
1092 dMessage(0, "Total joints processed: %i, bodies: %i", tjcount
, tbcount
);
1095 // if debugging, check that all objects (except for disabled bodies,
1096 // unconnected joints, and joints that are connected to disabled bodies)
1099 for (b
= world
->firstbody
; b
; b
= (dxBody
*) b
->next
)
1101 if (b
->flags
& dxBodyDisabled
)
1104 dDebug (0, "disabled body tagged");
1109 dDebug (0, "enabled body not tagged");
1112 for (j
= world
->firstjoint
; j
; j
= (dxJoint
*) j
->next
)
1114 if ((j
->node
[0].body
&& (j
->node
[0].body
->flags
& dxBodyDisabled
) == 0) || (j
->node
[1].body
&& (j
->node
[1].body
->flags
& dxBodyDisabled
) == 0))
1117 dDebug (0, "attached enabled joint not tagged");
1122 dDebug (0, "unattached or disabled joint tagged");
1129 dTimerReport (stdout
, 1);
1136 void dWorldStepFast1 (dWorldID w
, dReal stepsize
, int maxiterations
)
1138 dUASSERT (w
, "bad world argument");
1139 dUASSERT (stepsize
> 0, "stepsize must be > 0");
1140 processIslandsFast (w
, stepsize
, maxiterations
);