1 /*************************************************************************
2  *                                                                       *
3  * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith.       *
4  * All rights reserved.  Email: russ@q12.org   Web: www.q12.org          *
5  *                                                                       *
6  * This library is free software; you can redistribute it and/or         *
7  * modify it under the terms of EITHER:                                  *
8  *   (1) The GNU Lesser General Public License as published by the Free  *
9  *       Software Foundation; either version 2.1 of the License, or (at  *
10  *       your option) any later version. The text of the GNU Lesser      *
11  *       General Public License is included with this library in the     *
12  *       file LICENSE.TXT.                                               *
13  *   (2) The BSD-style license that is included with this library in     *
14  *       the file LICENSE-BSD.TXT.                                       *
15  *                                                                       *
16  * This library is distributed in the hope that it will be useful,       *
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of        *
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files    *
19  * LICENSE.TXT and LICENSE-BSD.TXT for more details.                     *
20  *                                                                       *
21  *************************************************************************/
22 
23 #include "ode/ode.h"
24 #include "objects.h"
25 #include "joints/joint.h"
26 #include "util.h"
27 
28 #define ALLOCA dALLOCA16
29 
30 //****************************************************************************
31 // Auto disabling
32 
dInternalHandleAutoDisabling(dxWorld * world,dReal stepsize)33 void dInternalHandleAutoDisabling (dxWorld *world, dReal stepsize)
34 {
35 	dxBody *bb;
36 	for ( bb=world->firstbody; bb; bb=(dxBody*)bb->next )
37 	{
38 		// don't freeze objects mid-air (patch 1586738)
39 		if ( bb->firstjoint == NULL ) continue;
40 
41 		// nothing to do unless this body is currently enabled and has
42 		// the auto-disable flag set
43 		if ( (bb->flags & (dxBodyAutoDisable|dxBodyDisabled)) != dxBodyAutoDisable ) continue;
44 
45 		// if sampling / threshold testing is disabled, we can never sleep.
46 		if ( bb->adis.average_samples == 0 ) continue;
47 
48 		//
49 		// see if the body is idle
50 		//
51 
52 #ifndef dNODEBUG
53 		// sanity check
54 		if ( bb->average_counter >= bb->adis.average_samples )
55 		{
56 			dUASSERT( bb->average_counter < bb->adis.average_samples, "buffer overflow" );
57 
58 			// something is going wrong, reset the average-calculations
59 			bb->average_ready = 0; // not ready for average calculation
60 			bb->average_counter = 0; // reset the buffer index
61 		}
62 #endif // dNODEBUG
63 
64 		// sample the linear and angular velocity
65 		bb->average_lvel_buffer[bb->average_counter][0] = bb->lvel[0];
66 		bb->average_lvel_buffer[bb->average_counter][1] = bb->lvel[1];
67 		bb->average_lvel_buffer[bb->average_counter][2] = bb->lvel[2];
68 		bb->average_avel_buffer[bb->average_counter][0] = bb->avel[0];
69 		bb->average_avel_buffer[bb->average_counter][1] = bb->avel[1];
70 		bb->average_avel_buffer[bb->average_counter][2] = bb->avel[2];
71 		bb->average_counter++;
72 
73 		// buffer ready test
74 		if ( bb->average_counter >= bb->adis.average_samples )
75 		{
76 			bb->average_counter = 0; // fill the buffer from the beginning
77 			bb->average_ready = 1; // this body is ready now for average calculation
78 		}
79 
80 		int idle = 0; // Assume it's in motion unless we have samples to disprove it.
81 
82 		// enough samples?
83 		if ( bb->average_ready )
84 		{
85 			idle = 1; // Initial assumption: IDLE
86 
87 			// the sample buffers are filled and ready for calculation
88 			dVector3 average_lvel, average_avel;
89 
90 			// Store first velocity samples
91 			average_lvel[0] = bb->average_lvel_buffer[0][0];
92 			average_avel[0] = bb->average_avel_buffer[0][0];
93 			average_lvel[1] = bb->average_lvel_buffer[0][1];
94 			average_avel[1] = bb->average_avel_buffer[0][1];
95 			average_lvel[2] = bb->average_lvel_buffer[0][2];
96 			average_avel[2] = bb->average_avel_buffer[0][2];
97 
98 			// If we're not in "instantaneous mode"
99 			if ( bb->adis.average_samples > 1 )
100 			{
101 				// add remaining velocities together
102 				for ( unsigned int i = 1; i < bb->adis.average_samples; ++i )
103 				{
104 					average_lvel[0] += bb->average_lvel_buffer[i][0];
105 					average_avel[0] += bb->average_avel_buffer[i][0];
106 					average_lvel[1] += bb->average_lvel_buffer[i][1];
107 					average_avel[1] += bb->average_avel_buffer[i][1];
108 					average_lvel[2] += bb->average_lvel_buffer[i][2];
109 					average_avel[2] += bb->average_avel_buffer[i][2];
110 				}
111 
112 				// make average
113 				dReal r1 = dReal( 1.0 ) / dReal( bb->adis.average_samples );
114 
115 				average_lvel[0] *= r1;
116 				average_avel[0] *= r1;
117 				average_lvel[1] *= r1;
118 				average_avel[1] *= r1;
119 				average_lvel[2] *= r1;
120 				average_avel[2] *= r1;
121 			}
122 
123 			// threshold test
124 			dReal av_lspeed, av_aspeed;
125 			av_lspeed = dDOT( average_lvel, average_lvel );
126 			if ( av_lspeed > bb->adis.linear_average_threshold )
127 			{
128 				idle = 0; // average linear velocity is too high for idle
129 			}
130 			else
131 			{
132 				av_aspeed = dDOT( average_avel, average_avel );
133 				if ( av_aspeed > bb->adis.angular_average_threshold )
134 				{
135 					idle = 0; // average angular velocity is too high for idle
136 				}
137 			}
138 		}
139 
140 		// if it's idle, accumulate steps and time.
141 		// these counters won't overflow because this code doesn't run for disabled bodies.
142 		if (idle) {
143 			bb->adis_stepsleft--;
144 			bb->adis_timeleft -= stepsize;
145 		}
146 		else {
147 			// Reset countdowns
148 			bb->adis_stepsleft = bb->adis.idle_steps;
149 			bb->adis_timeleft = bb->adis.idle_time;
150 		}
151 
152 		// disable the body if it's idle for a long enough time
153 		if ( bb->adis_stepsleft <= 0 && bb->adis_timeleft <= 0 )
154 		{
155 			bb->flags |= dxBodyDisabled; // set the disable flag
156 
157 			// disabling bodies should also include resetting the velocity
158 			// should prevent jittering in big "islands"
159 			bb->lvel[0] = 0;
160 			bb->lvel[1] = 0;
161 			bb->lvel[2] = 0;
162 			bb->avel[0] = 0;
163 			bb->avel[1] = 0;
164 			bb->avel[2] = 0;
165 		}
166 	}
167 }
168 
169 
170 //****************************************************************************
171 // body rotation
172 
173 // return sin(x)/x. this has a singularity at 0 so special handling is needed
174 // for small arguments.
175 
sinc(dReal x)176 static inline dReal sinc (dReal x)
177 {
178   // if |x| < 1e-4 then use a taylor series expansion. this two term expansion
179   // is actually accurate to one LS bit within this range if double precision
180   // is being used - so don't worry!
181   if (dFabs(x) < 1.0e-4) return REAL(1.0) - x*x*REAL(0.166666666666666666667);
182   else return dSin(x)/x;
183 }
184 
185 
186 // given a body b, apply its linear and angular rotation over the time
187 // interval h, thereby adjusting its position and orientation.
188 
dxStepBody(dxBody * b,dReal h)189 void dxStepBody (dxBody *b, dReal h)
190 {
191   // cap the angular velocity
192   if (b->flags & dxBodyMaxAngularSpeed) {
193         const dReal max_ang_speed = b->max_angular_speed;
194         const dReal aspeed = dDOT( b->avel, b->avel );
195         if (aspeed > max_ang_speed*max_ang_speed) {
196                 const dReal coef = max_ang_speed/dSqrt(aspeed);
197                 dOPEC(b->avel, *=, coef);
198         }
199   }
200   // end of angular velocity cap
201 
202 
203   int j;
204 
205   // handle linear velocity
206   for (j=0; j<3; j++) b->posr.pos[j] += h * b->lvel[j];
207 
208   if (b->flags & dxBodyFlagFiniteRotation) {
209     dVector3 irv;	// infitesimal rotation vector
210     dQuaternion q;	// quaternion for finite rotation
211 
212     if (b->flags & dxBodyFlagFiniteRotationAxis) {
213       // split the angular velocity vector into a component along the finite
214       // rotation axis, and a component orthogonal to it.
215       dVector3 frv;		// finite rotation vector
216       dReal k = dDOT (b->finite_rot_axis,b->avel);
217       frv[0] = b->finite_rot_axis[0] * k;
218       frv[1] = b->finite_rot_axis[1] * k;
219       frv[2] = b->finite_rot_axis[2] * k;
220       irv[0] = b->avel[0] - frv[0];
221       irv[1] = b->avel[1] - frv[1];
222       irv[2] = b->avel[2] - frv[2];
223 
224       // make a rotation quaternion q that corresponds to frv * h.
225       // compare this with the full-finite-rotation case below.
226       h *= REAL(0.5);
227       dReal theta = k * h;
228       q[0] = dCos(theta);
229       dReal s = sinc(theta) * h;
230       q[1] = frv[0] * s;
231       q[2] = frv[1] * s;
232       q[3] = frv[2] * s;
233     }
234     else {
235       // make a rotation quaternion q that corresponds to w * h
236       dReal wlen = dSqrt (b->avel[0]*b->avel[0] + b->avel[1]*b->avel[1] +
237 			  b->avel[2]*b->avel[2]);
238       h *= REAL(0.5);
239       dReal theta = wlen * h;
240       q[0] = dCos(theta);
241       dReal s = sinc(theta) * h;
242       q[1] = b->avel[0] * s;
243       q[2] = b->avel[1] * s;
244       q[3] = b->avel[2] * s;
245     }
246 
247     // do the finite rotation
248     dQuaternion q2;
249     dQMultiply0 (q2,q,b->q);
250     for (j=0; j<4; j++) b->q[j] = q2[j];
251 
252     // do the infitesimal rotation if required
253     if (b->flags & dxBodyFlagFiniteRotationAxis) {
254       dReal dq[4];
255       dWtoDQ (irv,b->q,dq);
256       for (j=0; j<4; j++) b->q[j] += h * dq[j];
257     }
258   }
259   else {
260     // the normal way - do an infitesimal rotation
261     dReal dq[4];
262     dWtoDQ (b->avel,b->q,dq);
263     for (j=0; j<4; j++) b->q[j] += h * dq[j];
264   }
265 
266   // normalize the quaternion and convert it to a rotation matrix
267   dNormalize4 (b->q);
268   dQtoR (b->q,b->posr.R);
269 
270   // notify all attached geoms that this body has moved
271   for (dxGeom *geom = b->geom; geom; geom = dGeomGetBodyNext (geom))
272     dGeomMoved (geom);
273 
274   // notify the user
275   if (b->moved_callback)
276     b->moved_callback(b);
277 
278 
279   // damping
280   if (b->flags & dxBodyLinearDamping) {
281         const dReal lin_threshold = b->dampingp.linear_threshold;
282         const dReal lin_speed = dDOT( b->lvel, b->lvel );
283         if ( lin_speed > lin_threshold) {
284                 const dReal k = 1 - b->dampingp.linear_scale;
285                 dOPEC(b->lvel, *=, k);
286         }
287   }
288   if (b->flags & dxBodyAngularDamping) {
289         const dReal ang_threshold = b->dampingp.angular_threshold;
290         const dReal ang_speed = dDOT( b->avel, b->avel );
291         if ( ang_speed > ang_threshold) {
292                 const dReal k = 1 - b->dampingp.angular_scale;
293                 dOPEC(b->avel, *=, k);
294         }
295   }
296 
297 }
298 
299 //****************************************************************************
300 // island processing
301 
302 // this groups all joints and bodies in a world into islands. all objects
303 // in an island are reachable by going through connected bodies and joints.
304 // each island can be simulated separately.
305 // note that joints that are not attached to anything will not be included
306 // in any island, an so they do not affect the simulation.
307 //
308 // this function starts new island from unvisited bodies. however, it will
309 // never start a new islands from a disabled body. thus islands of disabled
310 // bodies will not be included in the simulation. disabled bodies are
311 // re-enabled if they are found to be part of an active island.
312 
dxProcessIslands(dxWorld * world,dReal stepsize,dstepper_fn_t stepper)313 void dxProcessIslands (dxWorld *world, dReal stepsize, dstepper_fn_t stepper)
314 {
315   dxBody *b,*bb,**body;
316   dxJoint *j,**joint;
317 
318   // nothing to do if no bodies
319   if (world->nb <= 0) return;
320 
321   // handle auto-disabling of bodies
322   dInternalHandleAutoDisabling (world,stepsize);
323 
324   // make arrays for body and joint lists (for a single island) to go into
325   body = (dxBody**) ALLOCA (world->nb * sizeof(dxBody*));
326   joint = (dxJoint**) ALLOCA (world->nj * sizeof(dxJoint*));
327   int bcount = 0;	// number of bodies in `body'
328   int jcount = 0;	// number of joints in `joint'
329 
330   // set all body/joint tags to 0
331   for (b=world->firstbody; b; b=(dxBody*)b->next) b->tag = 0;
332   for (j=world->firstjoint; j; j=(dxJoint*)j->next) j->tag = 0;
333 
334   // allocate a stack of unvisited bodies in the island. the maximum size of
335   // the stack can be the lesser of the number of bodies or joints, because
336   // new bodies are only ever added to the stack by going through untagged
337   // joints. all the bodies in the stack must be tagged!
338   int stackalloc = (world->nj < world->nb) ? world->nj : world->nb;
339   dxBody **stack = (dxBody**) ALLOCA (stackalloc * sizeof(dxBody*));
340 
341   for (bb=world->firstbody; bb; bb=(dxBody*)bb->next) {
342     // get bb = the next enabled, untagged body, and tag it
343     if (bb->tag || (bb->flags & dxBodyDisabled)) continue;
344     bb->tag = 1;
345 
346     // tag all bodies and joints starting from bb.
347     int stacksize = 0;
348     b = bb;
349     body[0] = bb;
350     bcount = 1;
351     jcount = 0;
352     goto quickstart;
353     while (stacksize > 0) {
354       b = stack[--stacksize];	// pop body off stack
355       body[bcount++] = b;	// put body on body list
356       quickstart:
357 
358       // traverse and tag all body's joints, add untagged connected bodies
359       // to stack
360       for (dxJointNode *n=b->firstjoint; n; n=n->next) {
361         if (!n->joint->tag && n->joint->isEnabled()) {
362 	  n->joint->tag = 1;
363 	  joint[jcount++] = n->joint;
364 	  if (n->body && !n->body->tag) {
365 	    n->body->tag = 1;
366 	    stack[stacksize++] = n->body;
367 	  }
368 	}
369       }
370       dIASSERT(stacksize <= world->nb);
371       dIASSERT(stacksize <= world->nj);
372     }
373 
374     // now do something with body and joint lists
375     stepper (world,body,bcount,joint,jcount,stepsize);
376 
377     // what we've just done may have altered the body/joint tag values.
378     // we must make sure that these tags are nonzero.
379     // also make sure all bodies are in the enabled state.
380     int i;
381     for (i=0; i<bcount; i++) {
382       body[i]->tag = 1;
383       body[i]->flags &= ~dxBodyDisabled;
384     }
385     for (i=0; i<jcount; i++) joint[i]->tag = 1;
386   }
387 
388   // if debugging, check that all objects (except for disabled bodies,
389   // unconnected joints, and joints that are connected to disabled bodies)
390   // were tagged.
391 # ifndef dNODEBUG
392   for (b=world->firstbody; b; b=(dxBody*)b->next) {
393     if (b->flags & dxBodyDisabled) {
394       if (b->tag) dDebug (0,"disabled body tagged");
395     }
396     else {
397       if (!b->tag) dDebug (0,"enabled body not tagged");
398     }
399   }
400   for (j=world->firstjoint; j; j=(dxJoint*)j->next) {
401     if ( (( j->node[0].body && (j->node[0].body->flags & dxBodyDisabled)==0 ) ||
402           (j->node[1].body && (j->node[1].body->flags & dxBodyDisabled)==0) )
403          &&
404          j->isEnabled() ) {
405       if (!j->tag) dDebug (0,"attached enabled joint not tagged");
406     }
407     else {
408       if (j->tag) dDebug (0,"unattached or disabled joint tagged");
409     }
410   }
411 # endif
412 }
413 
414 
415 
416