1 /*************************************************************************
2  *                          D bindings for ODE                           *
3  *                                                                       *
4  *       C header port by Daniel "q66" Kolesa <quaker66@gmail.com>       *
5  *                                                                       *
6  * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith.       *
7  * All rights reserved.  Email: russ@q12.org   Web: www.q12.org          *
8  *                                                                       *
9  * This library is free software; you can redistribute it and/or         *
10  * modify it under the terms of EITHER:                                  *
11  *   (1) The GNU Lesser General Public License as published by the Free  *
12  *       Software Foundation; either version 2.1 of the License, or (at  *
13  *       your option) any later version. The text of the GNU Lesser      *
14  *       General Public License is included with this library in the     *
15  *       file LICENSE.TXT.                                               *
16  *   (2) The BSD-style license that is included with this library in     *
17  *       the file LICENSE-BSD.TXT.                                       *
18  *                                                                       *
19  * This library is distributed in the hope that it will be useful,       *
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of        *
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files    *
22  * LICENSE.TXT and LICENSE-BSD.TXT for more details.                     *
23  *                                                                       *
24  *************************************************************************/
25 
26 module deimos.ode.objects;
27 
28 private
29 {
30     import deimos.ode.common;
31     import deimos.ode.mass;
32     import deimos.ode.contact;
33 }
34 
35 extern (C):
36 nothrow:
37 
38 /**
39  * @defgroup world World
40  *
41  * The world object is a container for rigid bodies and joints. Objects in
42  * different worlds can not interact, for example rigid bodies from two
43  * different worlds can not collide.
44  *
45  * All the objects in a world exist at the same point in time, thus one
46  * reason to use separate worlds is to simulate systems at different rates.
47  * Most applications will only need one world.
48  */
49 
50 /**
51  * @brief Create a new, empty world and return its ID number.
52  * @return an identifier
53  * @ingroup world
54  */
55 dWorldID dWorldCreate();
56 
57 /**
58  * @brief Destroy a world and everything in it.
59  *
60  * This includes all bodies, and all joints that are not part of a joint
61  * group. Joints that are part of a joint group will be deactivated, and
62  * can be destroyed by calling, for example, dJointGroupEmpty().
63  * @ingroup world
64  * @param world the identifier for the world the be destroyed.
65  */
66 void dWorldDestroy(dWorldID world);
67 
68 
69 /**
70  * @brief Set the world's global gravity vector.
71  *
72  * The units are m/s^2, so Earth's gravity vector would be (0,0,-9.81),
73  * assuming that +z is up. The default is no gravity, i.e. (0,0,0).
74  *
75  * @ingroup world
76  */
77 void dWorldSetGravity(dWorldID, dReal x, dReal y, dReal z);
78 
79 
80 /**
81  * @brief Get the gravity vector for a given world.
82  * @ingroup world
83  */
84 void dWorldGetGravity(dWorldID, dVector3 gravity);
85 
86 
87 /**
88  * @brief Set the global ERP value, that controls how much error
89  * correction is performed in each time step.
90  * @ingroup world
91  * @param dWorldID the identifier of the world.
92  * @param erp Typical values are in the range 0.1--0.8. The default is 0.2.
93  */
94 void dWorldSetERP(dWorldID, dReal erp);
95 
96 /**
97  * @brief Get the error reduction parameter.
98  * @ingroup world
99  * @return ERP value
100  */
101 dReal dWorldGetERP(dWorldID);
102 
103 
104 /**
105  * @brief Set the global CFM (constraint force mixing) value.
106  * @ingroup world
107  * @param cfm Typical values are in the range @m{10^{-9}} -- 1.
108  * The default is 10^-5 if single precision is being used, or 10^-10
109  * if double precision is being used.
110  */
111 void dWorldSetCFM(dWorldID, dReal cfm);
112 
113 /**
114  * @brief Get the constraint force mixing value.
115  * @ingroup world
116  * @return CFM value
117  */
118 dReal dWorldGetCFM(dWorldID);
119 
120 
121 /**
122  * @brief Set the world to use shared working memory along with another world.
123  *
124  * The worlds allocate working memory internally for simulation stepping. This
125  * memory is cached among the calls to @c dWordStep and @c dWorldQuickStep. 
126  * Similarly, several worlds can be set up to share this memory caches thus 
127  * reducing overall memory usage by cost of making worlds inappropriate for 
128  * simultaneous simulation in multiple threads.
129  *
130  * If null value is passed for @a from_world parameter the world is detached from 
131  * sharing and returns to defaults for working memory, reservation policy and 
132  * memory manager as if just created. This can also be used to enable use of shared 
133  * memory for a world that has already had working memory allocated privately.
134  * Normally using shared memory after a world has its private working memory allocated
135  * is prohibited.
136  *
137  * Allocation policy used can only increase world's internal reserved memory size
138  * and never decreases it. @c dWorldCleanupWorkingMemory can be used to release 
139  * working memory for a world in case if number of objects/joint decreases 
140  * significantly in it.
141  *
142  * With sharing working memory worlds also automatically share memory reservation 
143  * policy and memory manager. Thus, these parameters need to be customized for
144  * initial world to be used as sharing source only.
145  *
146  * Failure result status means a memory allocation failure.
147  *
148  * @param w The world to use the shared memory with.
149  * @param from_world Null or the world the shared memory is to be used from.
150  * @returns 1 for success and 0 for failure.
151  *
152  * @ingroup world
153  * @see dWorldCleanupWorkingMemory
154  * @see dWorldSetStepMemoryReservationPolicy
155  * @see dWorldSetStepMemoryManager
156  */
157 int dWorldUseSharedWorkingMemory(dWorldID w, dWorldID from_world/*=NULL*/);
158 
159 /**
160  * @brief Release internal working memory allocated for world
161  *
162  * The worlds allocate working memory internally for simulation stepping. This 
163  * function can be used to free world's internal memory cache in case if number of
164  * objects/joints in the world decreases significantly. By default, internal 
165  * allocation policy is used to only increase cache size as necessary and never 
166  * decrease it.
167  *
168  * If a world shares its working memory with other worlds the cache deletion 
169  * affects all the linked worlds. However the shared status itself remains intact.
170  *
171  * The function call does affect neither memory reservation policy nor memory manager.
172  *
173  * @param w The world to release working memory for.
174  *
175  * @ingroup world
176  * @see dWorldUseSharedWorkingMemory
177  * @see dWorldSetStepMemoryReservationPolicy
178  * @see dWorldSetStepMemoryManager
179  */
180 void dWorldCleanupWorkingMemory(dWorldID w);
181 
182 enum dWORLDSTEP_RESERVEFACTOR_DEFAULT = 1.2f;
183 enum dWORLDSTEP_RESERVESIZE_DEFAULT = 65536U;
184 
185 /**
186  * @struct dWorldStepReserveInfo
187  * @brief Memory reservation policy descriptor structure for world stepping functions.
188  *
189  * @c struct_size should be assigned the size of the structure.
190  *
191  * @c reserve_factor is a quotient that is multiplied by required memory size
192  *  to allocate extra reserve whenever reallocation is needed.
193  *
194  * @c reserve_minimum is a minimum size that is checked against whenever reallocation 
195  * is needed to allocate expected working memory minimum at once without extra 
196  * reallocations as number of bodies/joints grows.
197  *
198  * @ingroup world
199  * @see dWorldSetStepMemoryReservationPolicy
200  */
201 struct dWorldStepReserveInfo
202 {
203     uint struct_size;
204 
205     float reserve_factor; // Use float as precision does not matter here
206     uint  reserve_minimum;
207 }
208 
209 /**
210  * @brief Set memory reservation policy for world to be used with simulation stepping functions
211  *
212  * The function allows to customize reservation policy to be used for internal
213  * memory which is allocated to aid simulation for a world. By default, values
214  * of @c dWORLDSTEP_RESERVEFACTOR_DEFAULT and @c dWORLDSTEP_RESERVESIZE_DEFAULT
215  * are used.
216  *
217  * Passing @a policyinfo argument as NULL results in reservation policy being
218  * reset to defaults as if the world has been just created. The content of 
219  * @a policyinfo structure is copied internally and does not need to remain valid
220  * after the call returns.
221  *
222  * If the world uses working memory sharing, changing memory reservation policy
223  * affects all the worlds linked together.
224  *
225  * Failure result status means a memory allocation failure.
226  *
227  * @param w The world to change memory reservation policy for.
228  * @param policyinfo Null or a pointer to policy descriptor structure.
229  * @returns 1 for success and 0 for failure.
230  *
231  * @ingroup world
232  * @see dWorldUseSharedWorkingMemory
233  */
234 int dWorldSetStepMemoryReservationPolicy(dWorldID w, in dWorldStepReserveInfo* policyinfo/*=NULL*/);
235 
236 /**
237 * @struct dWorldStepMemoryFunctionsInfo
238 * @brief World stepping memory manager descriptor structure
239 *
240 * This structure is intended to define the functions of memory manager to be used
241 * with world stepping functions.
242 *
243 * @c struct_size should be assigned the size of the structure
244 *
245 * @c alloc_block is a function to allocate memory block of given size.
246 *
247 * @c shrink_block is a function to shrink existing memory block to a smaller size.
248 * It must preserve the contents of block head while shrinking. The new block size
249 * is guaranteed to be always less than the existing one.
250 *
251 * @c free_block is a function to delete existing memory block.
252 *
253 * @ingroup init
254 * @see dWorldSetStepMemoryManager
255 */
256 struct dWorldStepMemoryFunctionsInfo
257 {
258     uint struct_size;
259 
260     void* function(size_t block_size) alloc_block;
261     void* function(
262         void* block_pointer,
263         size_t block_current_size,
264         size_t block_smaller_size
265     ) shrink_block;
266     void function(void* block_pointer, size_t block_current_size) free_block;
267 }
268 
269 /**
270 * @brief Set memory manager for world to be used with simulation stepping functions
271 *
272 * The function allows to customize memory manager to be used for internal
273 * memory allocation during simulation for a world. By default, @c dAlloc/@c dRealloc/@c dFree
274 * based memory manager is used.
275 *
276 * Passing @a memfuncs argument as NULL results in memory manager being
277 * reset to default one as if the world has been just created. The content of 
278 * @a memfuncs structure is copied internally and does not need to remain valid
279 * after the call returns.
280 *
281 * If the world uses working memory sharing, changing memory manager
282 * affects all the worlds linked together. 
283 *
284 * Failure result status means a memory allocation failure.
285 *
286 * @param w The world to change memory reservation policy for.
287 * @param memfuncs Null or a pointer to memory manager descriptor structure.
288 * @returns 1 for success and 0 for failure.
289 *
290 * @ingroup world
291 * @see dWorldUseSharedWorkingMemory
292 */
293 int dWorldSetStepMemoryManager(dWorldID w, in dWorldStepMemoryFunctionsInfo* memfuncs);
294 
295 /**
296  * @brief Step the world.
297  *
298  * This uses a "big matrix" method that takes time on the order of m^3
299  * and memory on the order of m^2, where m is the total number of constraint
300  * rows. For large systems this will use a lot of memory and can be very slow,
301  * but this is currently the most accurate method.
302  *
303  * Failure result status means that the memory allocation has failed for operation.
304  * In such a case all the objects remain in unchanged state and simulation can be
305  * retried as soon as more memory is available.
306  *
307  * @param w The world to be stepped
308  * @param stepsize The number of seconds that the simulation has to advance.
309  * @returns 1 for success and 0 for failure
310  *
311  * @ingroup world
312  */
313 int dWorldStep(dWorldID w, dReal stepsize);
314 
315 /**
316  * @brief Quick-step the world.
317  *
318  * This uses an iterative method that takes time on the order of m*N
319  * and memory on the order of m, where m is the total number of constraint
320  * rows N is the number of iterations.
321  * For large systems this is a lot faster than dWorldStep(),
322  * but it is less accurate.
323  *
324  * QuickStep is great for stacks of objects especially when the
325  * auto-disable feature is used as well.
326  * However, it has poor accuracy for near-singular systems.
327  * Near-singular systems can occur when using high-friction contacts, motors,
328  * or certain articulated structures. For example, a robot with multiple legs
329  * sitting on the ground may be near-singular.
330  *
331  * There are ways to help overcome QuickStep's inaccuracy problems:
332  *
333  * \li Increase CFM.
334  * \li Reduce the number of contacts in your system (e.g. use the minimum
335  *     number of contacts for the feet of a robot or creature).
336  * \li Don't use excessive friction in the contacts.
337  * \li Use contact slip if appropriate
338  * \li Avoid kinematic loops (however, kinematic loops are inevitable in
339  *     legged creatures).
340  * \li Don't use excessive motor strength.
341  * \liUse force-based motors instead of velocity-based motors.
342  *
343  * Increasing the number of QuickStep iterations may help a little bit, but
344  * it is not going to help much if your system is really near singular.
345  *
346  * Failure result status means that the memory allocation has failed for operation.
347  * In such a case all the objects remain in unchanged state and simulation can be
348  * retried as soon as more memory is available.
349  *
350  * @param w The world to be stepped
351  * @param stepsize The number of seconds that the simulation has to advance.
352  * @returns 1 for success and 0 for failure
353  *
354  * @ingroup world
355  */
356 int dWorldQuickStep(dWorldID w, dReal stepsize);
357 
358 
359 /**
360 * @brief Converts an impulse to a force.
361 * @ingroup world
362 * @remarks
363 * If you want to apply a linear or angular impulse to a rigid body,
364 * instead of a force or a torque, then you can use this function to convert
365 * the desired impulse into a force/torque vector before calling the
366 * BodyAdd... function.
367 * The current algorithm simply scales the impulse by 1/stepsize,
368 * where stepsize is the step size for the next step that will be taken.
369 * This function is given a dWorldID because, in the future, the force
370 * computation may depend on integrator parameters that are set as
371 * properties of the world.
372 */
373 void dWorldImpulseToForce(
374     dWorldID, dReal stepsize, dReal ix, dReal iy, dReal iz, dVector3 force
375 );
376 
377 
378 /**
379  * @brief Set the number of iterations that the QuickStep method performs per
380  *        step.
381  * @ingroup world
382  * @remarks
383  * More iterations will give a more accurate solution, but will take
384  * longer to compute.
385  * @param num The default is 20 iterations.
386  */
387 void dWorldSetQuickStepNumIterations(dWorldID, int num);
388 
389 
390 /**
391  * @brief Get the number of iterations that the QuickStep method performs per
392  *        step.
393  * @ingroup world
394  * @return nr of iterations
395  */
396 int dWorldGetQuickStepNumIterations(dWorldID);
397 
398 /**
399  * @brief Set the SOR over-relaxation parameter
400  * @ingroup world
401  * @param over_relaxation value to use by SOR
402  */
403 void dWorldSetQuickStepW(dWorldID, dReal over_relaxation);
404 
405 /**
406  * @brief Get the SOR over-relaxation parameter
407  * @ingroup world
408  * @returns the over-relaxation setting
409  */
410 dReal dWorldGetQuickStepW(dWorldID);
411 
412 /* World contact parameter functions */
413 
414 /**
415  * @brief Set the maximum correcting velocity that contacts are allowed
416  * to generate.
417  * @ingroup world
418  * @param vel The default value is infinity (i.e. no limit).
419  * @remarks
420  * Reducing this value can help prevent "popping" of deeply embedded objects.
421  */
422 void dWorldSetContactMaxCorrectingVel(dWorldID, dReal vel);
423 
424 /**
425  * @brief Get the maximum correcting velocity that contacts are allowed
426  * to generated.
427  * @ingroup world
428  */
429 dReal dWorldGetContactMaxCorrectingVel(dWorldID);
430 
431 /**
432  * @brief Set the depth of the surface layer around all geometry objects.
433  * @ingroup world
434  * @remarks
435  * Contacts are allowed to sink into the surface layer up to the given
436  * depth before coming to rest.
437  * @param depth The default value is zero.
438  * @remarks
439  * Increasing this to some small value (e.g. 0.001) can help prevent
440  * jittering problems due to contacts being repeatedly made and broken.
441  */
442 void dWorldSetContactSurfaceLayer(dWorldID, dReal depth);
443 
444 /**
445  * @brief Get the depth of the surface layer around all geometry objects.
446  * @ingroup world
447  * @returns the depth
448  */
449 dReal dWorldGetContactSurfaceLayer(dWorldID);
450 
451 
452 /**
453  * @defgroup disable Automatic Enabling and Disabling
454  * @ingroup world bodies
455  *
456  * Every body can be enabled or disabled. Enabled bodies participate in the
457  * simulation, while disabled bodies are turned off and do not get updated
458  * during a simulation step. New bodies are always created in the enabled state.
459  *
460  * A disabled body that is connected through a joint to an enabled body will be
461  * automatically re-enabled at the next simulation step.
462  *
463  * Disabled bodies do not consume CPU time, therefore to speed up the simulation
464  * bodies should be disabled when they come to rest. This can be done automatically
465  * with the auto-disable feature.
466  *
467  * If a body has its auto-disable flag turned on, it will automatically disable
468  * itself when
469  *   @li It has been idle for a given number of simulation steps.
470  *   @li It has also been idle for a given amount of simulation time.
471  *
472  * A body is considered to be idle when the magnitudes of both its
473  * linear average velocity and angular average velocity are below given thresholds.
474  * The sample size for the average defaults to one and can be disabled by setting
475  * to zero with 
476  *
477  * Thus, every body has six auto-disable parameters: an enabled flag, a idle step
478  * count, an idle time, linear/angular average velocity thresholds, and the
479  * average samples count.
480  *
481  * Newly created bodies get these parameters from world.
482  */
483 
484 /**
485  * @brief Get auto disable linear threshold for newly created bodies.
486  * @ingroup disable
487  * @return the threshold
488  */
489 dReal dWorldGetAutoDisableLinearThreshold(dWorldID);
490 
491 /**
492  * @brief Set auto disable linear threshold for newly created bodies.
493  * @param linear_threshold default is 0.01
494  * @ingroup disable
495  */
496 void  dWorldSetAutoDisableLinearThreshold(dWorldID, dReal linear_threshold);
497 
498 /**
499  * @brief Get auto disable angular threshold for newly created bodies.
500  * @ingroup disable
501  * @return the threshold
502  */
503 dReal dWorldGetAutoDisableAngularThreshold(dWorldID);
504 
505 /**
506  * @brief Set auto disable angular threshold for newly created bodies.
507  * @param linear_threshold default is 0.01
508  * @ingroup disable
509  */
510 void dWorldSetAutoDisableAngularThreshold(dWorldID, dReal angular_threshold);
511 
512 /**
513  * @brief Get auto disable linear average threshold for newly created bodies.
514  * @ingroup disable
515  * @return the threshold
516  */
517 dReal dWorldGetAutoDisableLinearAverageThreshold(dWorldID);
518 
519 /**
520  * @brief Set auto disable linear average threshold for newly created bodies.
521  * @param linear_average_threshold default is 0.01
522  * @ingroup disable
523  */
524 void  dWorldSetAutoDisableLinearAverageThreshold(dWorldID, dReal linear_average_threshold);
525 
526 /**
527  * @brief Get auto disable angular average threshold for newly created bodies.
528  * @ingroup disable
529  * @return the threshold
530  */
531 dReal dWorldGetAutoDisableAngularAverageThreshold(dWorldID);
532 
533 /**
534  * @brief Set auto disable angular average threshold for newly created bodies.
535  * @param linear_average_threshold default is 0.01
536  * @ingroup disable
537  */
538 void dWorldSetAutoDisableAngularAverageThreshold(dWorldID, dReal angular_average_threshold);
539 
540 /**
541  * @brief Get auto disable sample count for newly created bodies.
542  * @ingroup disable
543  * @return number of samples used
544  */
545 int dWorldGetAutoDisableAverageSamplesCount(dWorldID);
546 
547 /**
548  * @brief Set auto disable average sample count for newly created bodies.
549  * @ingroup disable
550  * @param average_samples_count Default is 1, meaning only instantaneous velocity is used.
551  * Set to zero to disable sampling and thus prevent any body from auto-disabling.
552  */
553 void dWorldSetAutoDisableAverageSamplesCount(dWorldID, uint average_samples_count);
554 
555 /**
556  * @brief Get auto disable steps for newly created bodies.
557  * @ingroup disable
558  * @return nr of steps
559  */
560 int dWorldGetAutoDisableSteps(dWorldID);
561 
562 /**
563  * @brief Set auto disable steps for newly created bodies.
564  * @ingroup disable
565  * @param steps default is 10
566  */
567 void dWorldSetAutoDisableSteps(dWorldID, int steps);
568 
569 /**
570  * @brief Get auto disable time for newly created bodies.
571  * @ingroup disable
572  * @return nr of seconds
573  */
574 dReal dWorldGetAutoDisableTime(dWorldID);
575 
576 /**
577  * @brief Set auto disable time for newly created bodies.
578  * @ingroup disable
579  * @param time default is 0 seconds
580  */
581 void dWorldSetAutoDisableTime(dWorldID, dReal time);
582 
583 /**
584  * @brief Get auto disable flag for newly created bodies.
585  * @ingroup disable
586  * @return 0 or 1
587  */
588 int dWorldGetAutoDisableFlag(dWorldID);
589 
590 /**
591  * @brief Set auto disable flag for newly created bodies.
592  * @ingroup disable
593  * @param do_auto_disable default is false.
594  */
595 void dWorldSetAutoDisableFlag(dWorldID, int do_auto_disable);
596 
597 
598 /**
599  * @defgroup damping Damping
600  * @ingroup bodies world
601  *
602  * Damping serves two purposes: reduce simulation instability, and to allow
603  * the bodies to come to rest (and possibly auto-disabling them).
604  *
605  * Bodies are constructed using the world's current damping parameters. Setting
606  * the scales to 0 disables the damping.
607  *
608  * Here is how it is done: after every time step linear and angular
609  * velocities are tested against the corresponding thresholds. If they
610  * are above, they are multiplied by (1 - scale). So a negative scale value
611  * will actually increase the speed, and values greater than one will
612  * make the object oscillate every step; both can make the simulation unstable.
613  *
614  * To disable damping just set the damping scale to zero.
615  *
616  * You can also limit the maximum angular velocity. In contrast to the damping
617  * functions, the angular velocity is affected before the body is moved.
618  * This means that it will introduce errors in joints that are forcing the body
619  * to rotate too fast. Some bodies have naturally high angular velocities
620  * (like cars' wheels), so you may want to give them a very high (like the default,
621  * dInfinity) limit.
622  *
623  * @note The velocities are damped after the stepper function has moved the
624  * object. Otherwise the damping could introduce errors in joints. First the
625  * joint constraints are processed by the stepper (moving the body), then
626  * the damping is applied.
627  *
628  * @note The damping happens right after the moved callback is called; this way 
629  * it still possible use the exact velocities the body has acquired during the
630  * step. You can even use the callback to create your own customized damping.
631  */
632 
633 /**
634  * @brief Get the world's linear damping threshold.
635  * @ingroup damping
636  */
637 dReal dWorldGetLinearDampingThreshold(dWorldID w);
638 
639 /**
640  * @brief Set the world's linear damping threshold.
641  * @param threshold The damping won't be applied if the linear speed is
642  *        below this threshold. Default is 0.01.
643  * @ingroup damping
644  */
645 void dWorldSetLinearDampingThreshold(dWorldID w, dReal threshold);
646 
647 /**
648  * @brief Get the world's angular damping threshold.
649  * @ingroup damping
650  */
651 dReal dWorldGetAngularDampingThreshold(dWorldID w);
652 
653 /**
654  * @brief Set the world's angular damping threshold.
655  * @param threshold The damping won't be applied if the angular speed is
656  *        below this threshold. Default is 0.01.
657  * @ingroup damping
658  */
659 void dWorldSetAngularDampingThreshold(dWorldID w, dReal threshold);
660 
661 /**
662  * @brief Get the world's linear damping scale.
663  * @ingroup damping
664  */
665 dReal dWorldGetLinearDamping(dWorldID w);
666 
667 /**
668  * @brief Set the world's linear damping scale.
669  * @param scale The linear damping scale that is to be applied to bodies.
670  * Default is 0 (no damping). Should be in the interval [0, 1].
671  * @ingroup damping
672  */
673 void dWorldSetLinearDamping(dWorldID w, dReal scale);
674 
675 /**
676  * @brief Get the world's angular damping scale.
677  * @ingroup damping
678  */
679 dReal dWorldGetAngularDamping(dWorldID w);
680 
681 /**
682  * @brief Set the world's angular damping scale.
683  * @param scale The angular damping scale that is to be applied to bodies.
684  * Default is 0 (no damping). Should be in the interval [0, 1].
685  * @ingroup damping
686  */
687 void dWorldSetAngularDamping(dWorldID w, dReal scale);
688 
689 /**
690  * @brief Convenience function to set body linear and angular scales.
691  * @param linear_scale The linear damping scale that is to be applied to bodies.
692  * @param angular_scale The angular damping scale that is to be applied to bodies.
693  * @ingroup damping
694  */
695 void dWorldSetDamping(dWorldID w, dReal linear_scale, dReal angular_scale);
696 
697 /**
698  * @brief Get the default maximum angular speed.
699  * @ingroup damping
700  * @sa dBodyGetMaxAngularSpeed()
701  */
702 dReal dWorldGetMaxAngularSpeed(dWorldID w);
703 
704 
705 /**
706  * @brief Set the default maximum angular speed for new bodies.
707  * @ingroup damping
708  * @sa dBodySetMaxAngularSpeed()
709  */
710 void dWorldSetMaxAngularSpeed(dWorldID w, dReal max_speed);
711 
712 
713 
714 /**
715  * @defgroup bodies Rigid Bodies
716  *
717  * A rigid body has various properties from the point of view of the
718  * simulation. Some properties change over time:
719  *
720  *  @li Position vector (x,y,z) of the body's point of reference.
721  *      Currently the point of reference must correspond to the body's center of mass.
722  *  @li Linear velocity of the point of reference, a vector (vx,vy,vz).
723  *  @li Orientation of a body, represented by a quaternion (qs,qx,qy,qz) or
724  *      a 3x3 rotation matrix.
725  *  @li Angular velocity vector (wx,wy,wz) which describes how the orientation
726  *      changes over time.
727  *
728  * Other body properties are usually constant over time:
729  *
730  *  @li Mass of the body.
731  *  @li Position of the center of mass with respect to the point of reference.
732  *      In the current implementation the center of mass and the point of
733  *      reference must coincide.
734  *  @li Inertia matrix. This is a 3x3 matrix that describes how the body's mass
735  *      is distributed around the center of mass. Conceptually each body has an
736  *      x-y-z coordinate frame embedded in it that moves and rotates with the body.
737  *
738  * The origin of this coordinate frame is the body's point of reference. Some values
739  * in ODE (vectors, matrices etc) are relative to the body coordinate frame, and others
740  * are relative to the global coordinate frame.
741  *
742  * Note that the shape of a rigid body is not a dynamical property (except insofar as
743  * it influences the various mass properties). It is only collision detection that cares
744  * about the detailed shape of the body.
745  */
746 
747 
748 /**
749  * @brief Get auto disable linear average threshold.
750  * @ingroup bodies disable
751  * @return the threshold
752  */
753 dReal dBodyGetAutoDisableLinearThreshold(dBodyID);
754 
755 /**
756  * @brief Set auto disable linear average threshold.
757  * @ingroup bodies disable
758  * @return the threshold
759  */
760 void  dBodySetAutoDisableLinearThreshold(dBodyID, dReal linear_average_threshold);
761 
762 /**
763  * @brief Get auto disable angular average threshold.
764  * @ingroup bodies disable
765  * @return the threshold
766  */
767 dReal dBodyGetAutoDisableAngularThreshold(dBodyID);
768 
769 /**
770  * @brief Set auto disable angular average threshold.
771  * @ingroup bodies disable
772  * @return the threshold
773  */
774 void  dBodySetAutoDisableAngularThreshold(dBodyID, dReal angular_average_threshold);
775 
776 /**
777  * @brief Get auto disable average size (samples count).
778  * @ingroup bodies disable
779  * @return the nr of steps/size.
780  */
781 int dBodyGetAutoDisableAverageSamplesCount(dBodyID);
782 
783 /**
784  * @brief Set auto disable average buffer size (average steps).
785  * @ingroup bodies disable
786  * @param average_samples_count the nr of samples to review.
787  */
788 void dBodySetAutoDisableAverageSamplesCount(dBodyID, uint average_samples_count);
789 
790 
791 /**
792  * @brief Get auto steps a body must be thought of as idle to disable
793  * @ingroup bodies disable
794  * @return the nr of steps
795  */
796 int dBodyGetAutoDisableSteps(dBodyID);
797 
798 /**
799  * @brief Set auto disable steps.
800  * @ingroup bodies disable
801  * @param steps the nr of steps.
802  */
803 void dBodySetAutoDisableSteps(dBodyID, int steps);
804 
805 /**
806  * @brief Get auto disable time.
807  * @ingroup bodies disable
808  * @return nr of seconds
809  */
810 dReal dBodyGetAutoDisableTime(dBodyID);
811 
812 /**
813  * @brief Set auto disable time.
814  * @ingroup bodies disable
815  * @param time nr of seconds.
816  */
817 void  dBodySetAutoDisableTime(dBodyID, dReal time);
818 
819 /**
820  * @brief Get auto disable flag.
821  * @ingroup bodies disable
822  * @return 0 or 1
823  */
824 int dBodyGetAutoDisableFlag(dBodyID);
825 
826 /**
827  * @brief Set auto disable flag.
828  * @ingroup bodies disable
829  * @param do_auto_disable 0 or 1
830  */
831 void dBodySetAutoDisableFlag(dBodyID, int do_auto_disable);
832 
833 /**
834  * @brief Set auto disable defaults.
835  * @remarks
836  * Set the values for the body to those set as default for the world.
837  * @ingroup bodies disable
838  */
839 void  dBodySetAutoDisableDefaults(dBodyID);
840 
841 
842 /**
843  * @brief Retrieves the world attached to te given body.
844  * @remarks
845  * 
846  * @ingroup bodies
847  */
848 dWorldID dBodyGetWorld(dBodyID);
849 
850 /**
851  * @brief Create a body in given world.
852  * @remarks
853  * Default mass parameters are at position (0,0,0).
854  * @ingroup bodies
855  */
856 dBodyID dBodyCreate(dWorldID);
857 
858 /**
859  * @brief Destroy a body.
860  * @remarks
861  * All joints that are attached to this body will be put into limbo:
862  * i.e. unattached and not affecting the simulation, but they will NOT be
863  * deleted.
864  * @ingroup bodies
865  */
866 void dBodyDestroy(dBodyID);
867 
868 /**
869  * @brief Set the body's user-data pointer.
870  * @ingroup bodies
871  * @param data arbitraty pointer
872  */
873 void  dBodySetData(dBodyID, void* data);
874 
875 /**
876  * @brief Get the body's user-data pointer.
877  * @ingroup bodies
878  * @return a pointer to the user's data.
879  */
880 void* dBodyGetData(dBodyID);
881 
882 /**
883  * @brief Set position of a body.
884  * @remarks
885  * After setting, the outcome of the simulation is undefined
886  * if the new configuration is inconsistent with the joints/constraints
887  * that are present.
888  * @ingroup bodies
889  */
890 void dBodySetPosition(dBodyID, dReal x, dReal y, dReal z);
891 
892 /**
893  * @brief Set the orientation of a body.
894  * @ingroup bodies
895  * @remarks
896  * After setting, the outcome of the simulation is undefined
897  * if the new configuration is inconsistent with the joints/constraints
898  * that are present.
899  */
900 void dBodySetRotation(dBodyID, in dMatrix3 R);
901 
902 /**
903  * @brief Set the orientation of a body.
904  * @ingroup bodies
905  * @remarks
906  * After setting, the outcome of the simulation is undefined
907  * if the new configuration is inconsistent with the joints/constraints
908  * that are present.
909  */
910 void dBodySetQuaternion(dBodyID, in dQuaternion q);
911 
912 /**
913  * @brief Set the linear velocity of a body.
914  * @ingroup bodies
915  */
916 void dBodySetLinearVel(dBodyID, dReal x, dReal y, dReal z);
917 
918 /**
919  * @brief Set the angular velocity of a body.
920  * @ingroup bodies
921  */
922 void dBodySetAngularVel(dBodyID, dReal x, dReal y, dReal z);
923 
924 /**
925  * @brief Get the position of a body.
926  * @ingroup bodies
927  * @remarks
928  * When getting, the returned values are pointers to internal data structures,
929  * so the vectors are valid until any changes are made to the rigid body
930  * system structure.
931  * @sa dBodyCopyPosition
932  */
933 const(dReal)* dBodyGetPosition(dBodyID);
934 
935 
936 /**
937  * @brief Copy the position of a body into a vector.
938  * @ingroup bodies
939  * @param body  the body to query
940  * @param pos   a copy of the body position
941  * @sa dBodyGetPosition
942  */
943 void dBodyCopyPosition(dBodyID dbody, dVector3 pos);
944 
945 
946 /**
947  * @brief Get the rotation of a body.
948  * @ingroup bodies
949  * @return pointer to a 4x3 rotation matrix.
950  */
951 const(dReal)* dBodyGetRotation(dBodyID);
952 
953 
954 /**
955  * @brief Copy the rotation of a body.
956  * @ingroup bodies
957  * @param body   the body to query
958  * @param R      a copy of the rotation matrix
959  * @sa dBodyGetRotation
960  */
961 void dBodyCopyRotation(dBodyID, dMatrix3 R);
962 
963 
964 /**
965  * @brief Get the rotation of a body.
966  * @ingroup bodies
967  * @return pointer to 4 scalars that represent the quaternion.
968  */
969 const(dReal)* dBodyGetQuaternion(dBodyID);
970 
971 
972 /**
973  * @brief Copy the orientation of a body into a quaternion.
974  * @ingroup bodies
975  * @param body  the body to query
976  * @param quat  a copy of the orientation quaternion
977  * @sa dBodyGetQuaternion
978  */
979 void dBodyCopyQuaternion(dBodyID dbody, dQuaternion quat);
980 
981 
982 /**
983  * @brief Get the linear velocity of a body.
984  * @ingroup bodies
985  */
986 const(dReal)* dBodyGetLinearVel(dBodyID);
987 
988 /**
989  * @brief Get the angular velocity of a body.
990  * @ingroup bodies
991  */
992 const(dReal)* dBodyGetAngularVel(dBodyID);
993 
994 /**
995  * @brief Set the mass of a body.
996  * @ingroup bodies
997  */
998 void dBodySetMass(dBodyID, in dMass* mass);
999 
1000 /**
1001  * @brief Get the mass of a body.
1002  * @ingroup bodies
1003  */
1004 void dBodyGetMass(dBodyID, dMass* mass);
1005 
1006 /**
1007  * @brief Add force at centre of mass of body in absolute coordinates.
1008  * @ingroup bodies
1009  */
1010 void dBodyAddForce(dBodyID, dReal fx, dReal fy, dReal fz);
1011 
1012 /**
1013  * @brief Add torque at centre of mass of body in absolute coordinates.
1014  * @ingroup bodies
1015  */
1016 void dBodyAddTorque(dBodyID, dReal fx, dReal fy, dReal fz);
1017 
1018 /**
1019  * @brief Add force at centre of mass of body in coordinates relative to body.
1020  * @ingroup bodies
1021  */
1022 void dBodyAddRelForce(dBodyID, dReal fx, dReal fy, dReal fz);
1023 
1024 /**
1025  * @brief Add torque at centre of mass of body in coordinates relative to body.
1026  * @ingroup bodies
1027  */
1028 void dBodyAddRelTorque(dBodyID, dReal fx, dReal fy, dReal fz);
1029 
1030 /**
1031  * @brief Add force at specified point in body in global coordinates.
1032  * @ingroup bodies
1033  */
1034 void dBodyAddForceAtPos(
1035     dBodyID, dReal fx, dReal fy, dReal fz, dReal px, dReal py, dReal pz
1036 );
1037 /**
1038  * @brief Add force at specified point in body in local coordinates.
1039  * @ingroup bodies
1040  */
1041 void dBodyAddForceAtRelPos(
1042     dBodyID, dReal fx, dReal fy, dReal fz, dReal px, dReal py, dReal pz
1043 );
1044 /**
1045  * @brief Add force at specified point in body in global coordinates.
1046  * @ingroup bodies
1047  */
1048 void dBodyAddRelForceAtPos(
1049     dBodyID, dReal fx, dReal fy, dReal fz, dReal px, dReal py, dReal pz
1050 );
1051 /**
1052  * @brief Add force at specified point in body in local coordinates.
1053  * @ingroup bodies
1054  */
1055 void dBodyAddRelForceAtRelPos(
1056     dBodyID, dReal fx, dReal fy, dReal fz, dReal px, dReal py, dReal pz
1057 );
1058 
1059 /**
1060  * @brief Return the current accumulated force vector.
1061  * @return points to an array of 3 reals.
1062  * @remarks
1063  * The returned values are pointers to internal data structures, so
1064  * the vectors are only valid until any changes are made to the rigid
1065  * body system.
1066  * @ingroup bodies
1067  */
1068 const(dReal)* dBodyGetForce(dBodyID);
1069 
1070 /**
1071  * @brief Return the current accumulated torque vector.
1072  * @return points to an array of 3 reals.
1073  * @remarks
1074  * The returned values are pointers to internal data structures, so
1075  * the vectors are only valid until any changes are made to the rigid
1076  * body system.
1077  * @ingroup bodies
1078  */
1079 const(dReal)* dBodyGetTorque(dBodyID);
1080 
1081 /**
1082  * @brief Set the body force accumulation vector.
1083  * @remarks
1084  * This is mostly useful to zero the force and torque for deactivated bodies
1085  * before they are reactivated, in the case where the force-adding functions
1086  * were called on them while they were deactivated.
1087  * @ingroup bodies
1088  */
1089 void dBodySetForce(dBodyID b, dReal x, dReal y, dReal z);
1090 
1091 /**
1092  * @brief Set the body torque accumulation vector.
1093  * @remarks
1094  * This is mostly useful to zero the force and torque for deactivated bodies
1095  * before they are reactivated, in the case where the force-adding functions
1096  * were called on them while they were deactivated.
1097  * @ingroup bodies
1098  */
1099 void dBodySetTorque(dBodyID b, dReal x, dReal y, dReal z);
1100 
1101 /**
1102  * @brief Get world position of a relative point on body.
1103  * @ingroup bodies
1104  * @param result will contain the result.
1105  */
1106 void dBodyGetRelPointPos(dBodyID, dReal px, dReal py, dReal pz,dVector3 result);
1107 
1108 /**
1109  * @brief Get velocity vector in global coords of a relative point on body.
1110  * @ingroup bodies
1111  * @param result will contain the result.
1112  */
1113 void dBodyGetRelPointVel(dBodyID, dReal px, dReal py, dReal pz, dVector3 result);
1114 
1115 /**
1116  * @brief Get velocity vector in global coords of a globally
1117  * specified point on a body.
1118  * @ingroup bodies
1119  * @param result will contain the result.
1120  */
1121 void dBodyGetPointVel(dBodyID, dReal px, dReal py, dReal pz, dVector3 result);
1122 
1123 /**
1124  * @brief takes a point in global coordinates and returns
1125  * the point's position in body-relative coordinates.
1126  * @remarks
1127  * This is the inverse of dBodyGetRelPointPos()
1128  * @ingroup bodies
1129  * @param result will contain the result.
1130  */
1131 void dBodyGetPosRelPoint(dBodyID, dReal px, dReal py, dReal pz, dVector3 result);
1132 
1133 /**
1134  * @brief Convert from local to world coordinates.
1135  * @ingroup bodies
1136  * @param result will contain the result.
1137  */
1138 void dBodyVectorToWorld(dBodyID, dReal px, dReal py, dReal pz, dVector3 result);
1139 
1140 /**
1141  * @brief Convert from world to local coordinates.
1142  * @ingroup bodies
1143  * @param result will contain the result.
1144  */
1145 void dBodyVectorFromWorld(dBodyID, dReal px, dReal py, dReal pz, dVector3 result);
1146 
1147 /**
1148  * @brief controls the way a body's orientation is updated at each timestep.
1149  * @ingroup bodies
1150  * @param mode can be 0 or 1:
1151  * \li 0: An ``infinitesimal'' orientation update is used.
1152  * This is fast to compute, but it can occasionally cause inaccuracies
1153  * for bodies that are rotating at high speed, especially when those
1154  * bodies are joined to other bodies.
1155  * This is the default for every new body that is created.
1156  * \li 1: A ``finite'' orientation update is used.
1157  * This is more costly to compute, but will be more accurate for high
1158  * speed rotations.
1159  * @remarks
1160  * Note however that high speed rotations can result in many types of
1161  * error in a simulation, and the finite mode will only fix one of those
1162  * sources of error.
1163  */
1164 void dBodySetFiniteRotationMode(dBodyID, int mode);
1165 
1166 /**
1167  * @brief sets the finite rotation axis for a body.
1168  * @ingroup bodies
1169  * @remarks
1170  * This is axis only has meaning when the finite rotation mode is set
1171  * If this axis is zero (0,0,0), full finite rotations are performed on
1172  * the body.
1173  * If this axis is nonzero, the body is rotated by performing a partial finite
1174  * rotation along the axis direction followed by an infinitesimal rotation
1175  * along an orthogonal direction.
1176  * @remarks
1177  * This can be useful to alleviate certain sources of error caused by quickly
1178  * spinning bodies. For example, if a car wheel is rotating at high speed
1179  * you can call this function with the wheel's hinge axis as the argument to
1180  * try and improve its behavior.
1181  */
1182 void dBodySetFiniteRotationAxis(dBodyID, dReal x, dReal y, dReal z);
1183 
1184 /**
1185  * @brief Get the way a body's orientation is updated each timestep.
1186  * @ingroup bodies
1187  * @return the mode 0 (infitesimal) or 1 (finite).
1188  */
1189 int dBodyGetFiniteRotationMode(dBodyID);
1190 
1191 /**
1192  * @brief Get the finite rotation axis.
1193  * @param result will contain the axis.
1194  * @ingroup bodies
1195  */
1196 void dBodyGetFiniteRotationAxis(dBodyID, dVector3 result);
1197 
1198 /**
1199  * @brief Get the number of joints that are attached to this body.
1200  * @ingroup bodies
1201  * @return nr of joints
1202  */
1203 int dBodyGetNumJoints(dBodyID b);
1204 
1205 /**
1206  * @brief Return a joint attached to this body, given by index.
1207  * @ingroup bodies
1208  * @param index valid range is  0 to n-1 where n is the value returned by
1209  * dBodyGetNumJoints().
1210  */
1211 dJointID dBodyGetJoint(dBodyID, int index);
1212 
1213 
1214 
1215 
1216 /**
1217  * @brief Set rigid body to dynamic state (default).
1218  * @param dBodyID identification of body.
1219  * @ingroup bodies
1220  */
1221 void dBodySetDynamic(dBodyID);
1222 
1223 /**
1224  * @brief Set rigid body to kinematic state.
1225  * When in kinematic state the body isn't simulated as a dynamic
1226  * body (it's "unstoppable", doesn't respond to forces),
1227  * but can still affect dynamic bodies (e.g. in joints).
1228  * Kinematic bodies can be controlled by position and velocity.
1229  * @note A kinematic body has infinite mass. If you set its mass
1230  * to something else, it loses the kinematic state and behaves
1231  * as a normal dynamic body.
1232  * @param dBodyID identification of body.
1233  * @ingroup bodies
1234  */
1235 void dBodySetKinematic(dBodyID);
1236 
1237 /**
1238  * @brief Check wether a body is in kinematic state.
1239  * @ingroup bodies
1240  * @return 1 if a body is kinematic or 0 if it is dynamic.
1241  */
1242 int dBodyIsKinematic(dBodyID);
1243 
1244 /**
1245  * @brief Manually enable a body.
1246  * @param dBodyID identification of body.
1247  * @ingroup bodies
1248  */
1249 void dBodyEnable(dBodyID);
1250 
1251 /**
1252  * @brief Manually disable a body.
1253  * @ingroup bodies
1254  * @remarks
1255  * A disabled body that is connected through a joint to an enabled body will
1256  * be automatically re-enabled at the next simulation step.
1257  */
1258 void dBodyDisable(dBodyID);
1259 
1260 /**
1261  * @brief Check wether a body is enabled.
1262  * @ingroup bodies
1263  * @return 1 if a body is currently enabled or 0 if it is disabled.
1264  */
1265 int dBodyIsEnabled(dBodyID);
1266 
1267 /**
1268  * @brief Set whether the body is influenced by the world's gravity or not.
1269  * @ingroup bodies
1270  * @param mode when nonzero gravity affects this body.
1271  * @remarks
1272  * Newly created bodies are always influenced by the world's gravity.
1273  */
1274 void dBodySetGravityMode(dBodyID b, int mode);
1275 
1276 /**
1277  * @brief Get whether the body is influenced by the world's gravity or not.
1278  * @ingroup bodies
1279  * @return nonzero means gravity affects this body.
1280  */
1281 int dBodyGetGravityMode(dBodyID b);
1282 
1283 /**
1284  * @brief Set the 'moved' callback of a body.
1285  *
1286  * Whenever a body has its position or rotation changed during the
1287  * timestep, the callback will be called (with body as the argument).
1288  * Use it to know which body may need an update in an external
1289  * structure (like a 3D engine).
1290  *
1291  * @param b the body that needs to be watched.
1292  * @param callback the callback to be invoked when the body moves. Set to zero
1293  * to disable.
1294  * @ingroup bodies
1295  */
1296 void dBodySetMovedCallback(dBodyID b, void function(dBodyID) callback);
1297 
1298 
1299 /**
1300  * @brief Return the first geom associated with the body.
1301  * 
1302  * You can traverse through the geoms by repeatedly calling
1303  * dBodyGetNextGeom().
1304  *
1305  * @return the first geom attached to this body, or 0.
1306  * @ingroup bodies
1307  */
1308 dGeomID dBodyGetFirstGeom(dBodyID b);
1309 
1310 
1311 /**
1312  * @brief returns the next geom associated with the same body.
1313  * @param g a geom attached to some body.
1314  * @return the next geom attached to the same body, or 0.
1315  * @sa dBodyGetFirstGeom
1316  * @ingroup bodies
1317  */
1318 dGeomID dBodyGetNextGeom(dGeomID g);
1319 
1320 
1321 /**
1322  * @brief Resets the damping settings to the current world's settings.
1323  * @ingroup bodies damping
1324  */
1325 void dBodySetDampingDefaults(dBodyID b);
1326 
1327 /**
1328  * @brief Get the body's linear damping scale.
1329  * @ingroup bodies damping
1330  */
1331 dReal dBodyGetLinearDamping(dBodyID b);
1332 
1333 /**
1334  * @brief Set the body's linear damping scale.
1335  * @param scale The linear damping scale. Should be in the interval [0, 1].
1336  * @ingroup bodies damping
1337  * @remarks From now on the body will not use the world's linear damping
1338  * scale until dBodySetDampingDefaults() is called.
1339  * @sa dBodySetDampingDefaults()
1340  */
1341 void dBodySetLinearDamping(dBodyID b, dReal scale);
1342 
1343 /**
1344  * @brief Get the body's angular damping scale.
1345  * @ingroup bodies damping
1346  * @remarks If the body's angular damping scale was not set, this function
1347  * returns the world's angular damping scale.
1348  */
1349 dReal dBodyGetAngularDamping(dBodyID b);
1350 
1351 /**
1352  * @brief Set the body's angular damping scale.
1353  * @param scale The angular damping scale. Should be in the interval [0, 1].
1354  * @ingroup bodies damping
1355  * @remarks From now on the body will not use the world's angular damping
1356  * scale until dBodyResetAngularDamping() is called.
1357  * @sa dBodyResetAngularDamping()
1358  */
1359 void dBodySetAngularDamping(dBodyID b, dReal scale);
1360 
1361 /**
1362  * @brief Convenience function to set linear and angular scales at once.
1363  * @param linear_scale The linear damping scale. Should be in the interval [0, 1].
1364  * @param angular_scale The angular damping scale. Should be in the interval [0, 1].
1365  * @ingroup bodies damping
1366  * @sa dBodySetLinearDamping() dBodySetAngularDamping()
1367  */
1368 void dBodySetDamping(dBodyID b, dReal linear_scale, dReal angular_scale);
1369 
1370 /**
1371  * @brief Get the body's linear damping threshold.
1372  * @ingroup bodies damping
1373  */
1374 dReal dBodyGetLinearDampingThreshold(dBodyID b);
1375 
1376 /**
1377  * @brief Set the body's linear damping threshold.
1378  * @param threshold The linear threshold to be used. Damping
1379  *      is only applied if the linear speed is above this limit.
1380  * @ingroup bodies damping
1381  */
1382 void dBodySetLinearDampingThreshold(dBodyID b, dReal threshold);
1383 
1384 /**
1385  * @brief Get the body's angular damping threshold.
1386  * @ingroup bodies damping
1387  */
1388 dReal dBodyGetAngularDampingThreshold(dBodyID b);
1389 
1390 /**
1391  * @brief Set the body's angular damping threshold.
1392  * @param threshold The angular threshold to be used. Damping is
1393  *      only used if the angular speed is above this limit.
1394  * @ingroup bodies damping
1395  */
1396 void dBodySetAngularDampingThreshold(dBodyID b, dReal threshold);
1397 
1398 /**
1399  * @brief Get the body's maximum angular speed.
1400  * @ingroup damping bodies
1401  * @sa dWorldGetMaxAngularSpeed()
1402  */
1403 dReal dBodyGetMaxAngularSpeed(dBodyID b);
1404 
1405 /**
1406  * @brief Set the body's maximum angular speed.
1407  * @ingroup damping bodies
1408  * @sa dWorldSetMaxAngularSpeed() dBodyResetMaxAngularSpeed()
1409  * The default value is dInfinity, but it's a good idea to limit
1410  * it at less than 500 if the body has the gyroscopic term
1411  * enabled.
1412  */
1413 void dBodySetMaxAngularSpeed(dBodyID b, dReal max_speed);
1414 
1415 
1416 
1417 /**
1418  * @brief Get the body's gyroscopic state.
1419  *
1420  * @return nonzero if gyroscopic term computation is enabled (default),
1421  * zero otherwise.
1422  * @ingroup bodies
1423  */
1424 int dBodyGetGyroscopicMode(dBodyID b);
1425 
1426 
1427 /**
1428  * @brief Enable/disable the body's gyroscopic term.
1429  *
1430  * Disabling the gyroscopic term of a body usually improves
1431  * stability. It also helps turning spining objects, like cars'
1432  * wheels.
1433  *
1434  * @param enabled   nonzero (default) to enable gyroscopic term, 0
1435  * to disable.
1436  * @ingroup bodies
1437  */
1438 void dBodySetGyroscopicMode(dBodyID b, int enabled);
1439 
1440 
1441 
1442 
1443 /**
1444  * @defgroup joints Joints
1445  *
1446  * In real life a joint is something like a hinge, that is used to connect two
1447  * objects.
1448  * In ODE a joint is very similar: It is a relationship that is enforced between
1449  * two bodies so that they can only have certain positions and orientations
1450  * relative to each other.
1451  * This relationship is called a constraint -- the words joint and
1452  * constraint are often used interchangeably.
1453  *
1454  * A joint has a set of parameters that can be set. These include:
1455  *
1456  *
1457  * \li  dParamLoStop Low stop angle or position. Setting this to
1458  *    -dInfinity (the default value) turns off the low stop.
1459  *    For rotational joints, this stop must be greater than -pi to be
1460  *    effective.
1461  * \li  dParamHiStop High stop angle or position. Setting this to
1462  *    dInfinity (the default value) turns off the high stop.
1463  *    For rotational joints, this stop must be less than pi to be
1464  *    effective.
1465  *    If the high stop is less than the low stop then both stops will
1466  *    be ineffective.
1467  * \li  dParamVel Desired motor velocity (this will be an angular or
1468  *    linear velocity).
1469  * \li  dParamFMax The maximum force or torque that the motor will use to
1470  *    achieve the desired velocity.
1471  *    This must always be greater than or equal to zero.
1472  *    Setting this to zero (the default value) turns off the motor.
1473  * \li  dParamFudgeFactor The current joint stop/motor implementation has
1474  *    a small problem:
1475  *    when the joint is at one stop and the motor is set to move it away
1476  *    from the stop, too much force may be applied for one time step,
1477  *    causing a ``jumping'' motion.
1478  *    This fudge factor is used to scale this excess force.
1479  *    It should have a value between zero and one (the default value).
1480  *    If the jumping motion is too visible in a joint, the value can be
1481  *    reduced.
1482  *    Making this value too small can prevent the motor from being able to
1483  *    move the joint away from a stop.
1484  * \li  dParamBounce The bouncyness of the stops.
1485  *    This is a restitution parameter in the range 0..1.
1486  *    0 means the stops are not bouncy at all, 1 means maximum bouncyness.
1487  * \li  dParamCFM The constraint force mixing (CFM) value used when not
1488  *    at a stop.
1489  * \li  dParamStopERP The error reduction parameter (ERP) used by the
1490  *    stops.
1491  * \li  dParamStopCFM The constraint force mixing (CFM) value used by the
1492  *    stops. Together with the ERP value this can be used to get spongy or
1493  *    soft stops.
1494  *    Note that this is intended for unpowered joints, it does not really
1495  *    work as expected when a powered joint reaches its limit.
1496  * \li  dParamSuspensionERP Suspension error reduction parameter (ERP).
1497  *    Currently this is only implemented on the hinge-2 joint.
1498  * \li  dParamSuspensionCFM Suspension constraint force mixing (CFM) value.
1499  *    Currently this is only implemented on the hinge-2 joint.
1500  *
1501  * If a particular parameter is not implemented by a given joint, setting it
1502  * will have no effect.
1503  * These parameter names can be optionally followed by a digit (2 or 3)
1504  * to indicate the second or third set of parameters, e.g. for the second axis
1505  * in a hinge-2 joint, or the third axis in an AMotor joint.
1506  */
1507 
1508 
1509 /**
1510  * @brief Create a new joint of the ball type.
1511  * @ingroup joints
1512  * @remarks
1513  * The joint is initially in "limbo" (i.e. it has no effect on the simulation)
1514  * because it does not connect to any bodies.
1515  * @param dJointGroupID set to 0 to allocate the joint normally.
1516  * If it is nonzero the joint is allocated in the given joint group.
1517  */
1518 dJointID dJointCreateBall(dWorldID, dJointGroupID);
1519 
1520 /**
1521  * @brief Create a new joint of the hinge type.
1522  * @ingroup joints
1523  * @param dJointGroupID set to 0 to allocate the joint normally.
1524  * If it is nonzero the joint is allocated in the given joint group.
1525  */
1526 dJointID dJointCreateHinge(dWorldID, dJointGroupID);
1527 
1528 /**
1529  * @brief Create a new joint of the slider type.
1530  * @ingroup joints
1531  * @param dJointGroupID set to 0 to allocate the joint normally.
1532  * If it is nonzero the joint is allocated in the given joint group.
1533  */
1534 dJointID dJointCreateSlider(dWorldID, dJointGroupID);
1535 
1536 /**
1537  * @brief Create a new joint of the contact type.
1538  * @ingroup joints
1539  * @param dJointGroupID set to 0 to allocate the joint normally.
1540  * If it is nonzero the joint is allocated in the given joint group.
1541  */
1542 dJointID dJointCreateContact(dWorldID, dJointGroupID, in dContact *);
1543 
1544 /**
1545  * @brief Create a new joint of the hinge2 type.
1546  * @ingroup joints
1547  * @param dJointGroupID set to 0 to allocate the joint normally.
1548  * If it is nonzero the joint is allocated in the given joint group.
1549  */
1550 dJointID dJointCreateHinge2(dWorldID, dJointGroupID);
1551 
1552 /**
1553  * @brief Create a new joint of the universal type.
1554  * @ingroup joints
1555  * @param dJointGroupID set to 0 to allocate the joint normally.
1556  * If it is nonzero the joint is allocated in the given joint group.
1557  */
1558 dJointID dJointCreateUniversal(dWorldID, dJointGroupID);
1559 
1560 /**
1561  * @brief Create a new joint of the PR (Prismatic and Rotoide) type.
1562  * @ingroup joints
1563  * @param dJointGroupID set to 0 to allocate the joint normally.
1564  * If it is nonzero the joint is allocated in the given joint group.
1565  */
1566 dJointID dJointCreatePR(dWorldID, dJointGroupID);
1567 
1568 /**
1569  * @brief Create a new joint of the PU (Prismatic and Universal) type.
1570  * @ingroup joints
1571  * @param dJointGroupID set to 0 to allocate the joint normally.
1572  * If it is nonzero the joint is allocated in the given joint group.
1573  */
1574   dJointID dJointCreatePU(dWorldID, dJointGroupID);
1575 
1576 /**
1577  * @brief Create a new joint of the Piston type.
1578  * @ingroup joints
1579  * @param dJointGroupID set to 0 to allocate the joint normally.
1580  *                      If it is nonzero the joint is allocated in the given
1581  *                      joint group.
1582  */
1583   dJointID dJointCreatePiston(dWorldID, dJointGroupID);
1584 
1585 /**
1586  * @brief Create a new joint of the fixed type.
1587  * @ingroup joints
1588  * @param dJointGroupID set to 0 to allocate the joint normally.
1589  * If it is nonzero the joint is allocated in the given joint group.
1590  */
1591 dJointID dJointCreateFixed(dWorldID, dJointGroupID);
1592 
1593 dJointID dJointCreateNull(dWorldID, dJointGroupID);
1594 
1595 /**
1596  * @brief Create a new joint of the A-motor type.
1597  * @ingroup joints
1598  * @param dJointGroupID set to 0 to allocate the joint normally.
1599  * If it is nonzero the joint is allocated in the given joint group.
1600  */
1601 dJointID dJointCreateAMotor(dWorldID, dJointGroupID);
1602 
1603 /**
1604  * @brief Create a new joint of the L-motor type.
1605  * @ingroup joints
1606  * @param dJointGroupID set to 0 to allocate the joint normally.
1607  * If it is nonzero the joint is allocated in the given joint group.
1608  */
1609 dJointID dJointCreateLMotor(dWorldID, dJointGroupID);
1610 
1611 /**
1612  * @brief Create a new joint of the plane-2d type.
1613  * @ingroup joints
1614  * @param dJointGroupID set to 0 to allocate the joint normally.
1615  * If it is nonzero the joint is allocated in the given joint group.
1616  */
1617 dJointID dJointCreatePlane2D(dWorldID, dJointGroupID);
1618 
1619 /**
1620  * @brief Destroy a joint.
1621  * @ingroup joints
1622  *
1623  * disconnects it from its attached bodies and removing it from the world.
1624  * However, if the joint is a member of a group then this function has no
1625  * effect - to destroy that joint the group must be emptied or destroyed.
1626  */
1627 void dJointDestroy(dJointID);
1628 
1629 
1630 /**
1631  * @brief Create a joint group
1632  * @ingroup joints
1633  * @param max_size deprecated. Set to 0.
1634  */
1635 dJointGroupID dJointGroupCreate(int max_size);
1636 
1637 /**
1638  * @brief Destroy a joint group.
1639  * @ingroup joints
1640  *
1641  * All joints in the joint group will be destroyed.
1642  */
1643 void dJointGroupDestroy(dJointGroupID);
1644 
1645 /**
1646  * @brief Empty a joint group.
1647  * @ingroup joints
1648  *
1649  * All joints in the joint group will be destroyed,
1650  * but the joint group itself will not be destroyed.
1651  */
1652 void dJointGroupEmpty(dJointGroupID);
1653 
1654 /**
1655  * @brief Return the number of bodies attached to the joint
1656  * @ingroup joints
1657  */
1658 int dJointGetNumBodies(dJointID);
1659 
1660 /**
1661  * @brief Attach the joint to some new bodies.
1662  * @ingroup joints
1663  *
1664  * If the joint is already attached, it will be detached from the old bodies
1665  * first.
1666  * To attach this joint to only one body, set body1 or body2 to zero - a zero
1667  * body refers to the static environment.
1668  * Setting both bodies to zero puts the joint into "limbo", i.e. it will
1669  * have no effect on the simulation.
1670  * @remarks
1671  * Some joints, like hinge-2 need to be attached to two bodies to work.
1672  */
1673 void dJointAttach(dJointID, dBodyID body1, dBodyID body2);
1674 
1675 /**
1676  * @brief Manually enable a joint.
1677  * @param dJointID identification of joint.
1678  * @ingroup joints
1679  */
1680 void dJointEnable(dJointID);
1681 
1682 /**
1683  * @brief Manually disable a joint.
1684  * @ingroup joints
1685  * @remarks
1686  * A disabled joint will not affect the simulation, but will maintain the anchors and
1687  * axes so it can be enabled later.
1688  */
1689 void dJointDisable(dJointID);
1690 
1691 /**
1692  * @brief Check wether a joint is enabled.
1693  * @ingroup joints
1694  * @return 1 if a joint is currently enabled or 0 if it is disabled.
1695  */
1696 int dJointIsEnabled(dJointID);
1697 
1698 /**
1699  * @brief Set the user-data pointer
1700  * @ingroup joints
1701  */
1702 void dJointSetData(dJointID, void* data);
1703 
1704 /**
1705  * @brief Get the user-data pointer
1706  * @ingroup joints
1707  */
1708 void* dJointGetData(dJointID);
1709 
1710 /**
1711  * @brief Get the type of the joint
1712  * @ingroup joints
1713  * @return the type, being one of these:
1714  * \li dJointTypeBall
1715  * \li dJointTypeHinge
1716  * \li dJointTypeSlider
1717  * \li dJointTypeContact
1718  * \li dJointTypeUniversal
1719  * \li dJointTypeHinge2
1720  * \li dJointTypeFixed
1721  * \li dJointTypeNull
1722  * \li dJointTypeAMotor
1723  * \li dJointTypeLMotor
1724  * \li dJointTypePlane2D
1725  * \li dJointTypePR
1726  * \li dJointTypePU
1727  * \li dJointTypePiston
1728  */
1729 dJointType dJointGetType(dJointID);
1730 
1731 /**
1732  * @brief Return the bodies that this joint connects.
1733  * @ingroup joints
1734  * @param index return the first (0) or second (1) body.
1735  * @remarks
1736  * If one of these returned body IDs is zero, the joint connects the other body
1737  * to the static environment.
1738  * If both body IDs are zero, the joint is in ``limbo'' and has no effect on
1739  * the simulation.
1740  */
1741 dBodyID dJointGetBody(dJointID, int index);
1742 
1743 /**
1744  * @brief Sets the datastructure that is to receive the feedback.
1745  *
1746  * The feedback can be used by the user, so that it is known how
1747  * much force an individual joint exerts.
1748  * @ingroup joints
1749  */
1750 void dJointSetFeedback(dJointID, dJointFeedback*);
1751 
1752 /**
1753  * @brief Gets the datastructure that is to receive the feedback.
1754  * @ingroup joints
1755  */
1756 dJointFeedback* dJointGetFeedback(dJointID);
1757 
1758 /**
1759  * @brief Set the joint anchor point.
1760  * @ingroup joints
1761  *
1762  * The joint will try to keep this point on each body
1763  * together. The input is specified in world coordinates.
1764  */
1765 void dJointSetBallAnchor(dJointID, dReal x, dReal y, dReal z);
1766 
1767 /**
1768  * @brief Set the joint anchor point.
1769  * @ingroup joints
1770  */
1771 void dJointSetBallAnchor2(dJointID, dReal x, dReal y, dReal z);
1772 
1773 /**
1774  * @brief Param setting for Ball joints
1775  * @ingroup joints
1776  */
1777 void dJointSetBallParam(dJointID, int parameter, dReal value);
1778 
1779 /**
1780  * @brief Set hinge anchor parameter.
1781  * @ingroup joints
1782  */
1783 void dJointSetHingeAnchor(dJointID, dReal x, dReal y, dReal z);
1784 
1785 void dJointSetHingeAnchorDelta(
1786     dJointID, dReal x, dReal y, dReal z, dReal ax, dReal ay, dReal az
1787 );
1788 
1789 /**
1790  * @brief Set hinge axis.
1791  * @ingroup joints
1792  */
1793 void dJointSetHingeAxis(dJointID, dReal x, dReal y, dReal z);
1794 
1795 /**
1796  * @brief Set the Hinge axis as if the 2 bodies were already at angle appart.
1797  * @ingroup joints
1798  *
1799  * This function initialize the Axis and the relative orientation of each body
1800  * as if body1 was rotated around the axis by the angle value. \br
1801  * Ex:
1802  * <PRE>
1803  * dJointSetHingeAxis(jId, 1, 0, 0);
1804  * // If you request the position you will have: dJointGetHingeAngle(jId) == 0
1805  * dJointSetHingeAxisDelta(jId, 1, 0, 0, 0.23);
1806  * // If you request the position you will have: dJointGetHingeAngle(jId) == 0.23
1807  * </PRE>
1808 
1809  * @param j The Hinge joint ID for which the axis will be set
1810  * @param x The X component of the axis in world frame
1811  * @param y The Y component of the axis in world frame
1812  * @param z The Z component of the axis in world frame
1813  * @param angle The angle for the offset of the relative orientation.
1814  *              As if body1 was rotated by angle when the Axis was set (see below).
1815  *              The rotation is around the new Hinge axis.
1816  *
1817  * @note Usually the function dJointSetHingeAxis set the current position of body1
1818  *       and body2 as the zero angle position. This function set the current position
1819  *       as the if the 2 bodies where \b angle appart.
1820  * @warning Calling dJointSetHingeAnchor or dJointSetHingeAxis will reset the "zero"
1821  *          angle position.
1822  */
1823 void dJointSetHingeAxisOffset(dJointID j, dReal x, dReal y, dReal z, dReal angle);
1824 
1825 /**
1826  * @brief set joint parameter
1827  * @ingroup joints
1828  */
1829 void dJointSetHingeParam(dJointID, int parameter, dReal value);
1830 
1831 /**
1832  * @brief Applies the torque about the hinge axis.
1833  *
1834  * That is, it applies a torque with specified magnitude in the direction
1835  * of the hinge axis, to body 1, and with the same magnitude but in opposite
1836  * direction to body 2. This function is just a wrapper for dBodyAddTorque()}
1837  * @ingroup joints
1838  */
1839 void dJointAddHingeTorque(dJointID joint, dReal torque);
1840 
1841 /**
1842  * @brief set the joint axis
1843  * @ingroup joints
1844  */
1845 void dJointSetSliderAxis(dJointID, dReal x, dReal y, dReal z);
1846 
1847 /**
1848  * @ingroup joints
1849  */
1850 void dJointSetSliderAxisDelta(dJointID, dReal x, dReal y, dReal z, dReal ax, dReal ay, dReal az);
1851 
1852 /**
1853  * @brief set joint parameter
1854  * @ingroup joints
1855  */
1856 void dJointSetSliderParam(dJointID, int parameter, dReal value);
1857 
1858 /**
1859  * @brief Applies the given force in the slider's direction.
1860  *
1861  * That is, it applies a force with specified magnitude, in the direction of
1862  * slider's axis, to body1, and with the same magnitude but opposite
1863  * direction to body2.  This function is just a wrapper for dBodyAddForce().
1864  * @ingroup joints
1865  */
1866 void dJointAddSliderForce(dJointID joint, dReal force);
1867 
1868 /**
1869  * @brief set anchor
1870  * @ingroup joints
1871  */
1872 void dJointSetHinge2Anchor(dJointID, dReal x, dReal y, dReal z);
1873 
1874 /**
1875  * @brief set axis
1876  * @ingroup joints
1877  */
1878 void dJointSetHinge2Axis1(dJointID, dReal x, dReal y, dReal z);
1879 
1880 /**
1881  * @brief set axis
1882  * @ingroup joints
1883  */
1884 void dJointSetHinge2Axis2(dJointID, dReal x, dReal y, dReal z);
1885 
1886 /**
1887  * @brief set joint parameter
1888  * @ingroup joints
1889  */
1890 void dJointSetHinge2Param(dJointID, int parameter, dReal value);
1891 
1892 /**
1893  * @brief Applies torque1 about the hinge2's axis 1, torque2 about the
1894  * hinge2's axis 2.
1895  * @remarks  This function is just a wrapper for dBodyAddTorque().
1896  * @ingroup joints
1897  */
1898 void dJointAddHinge2Torques(dJointID joint, dReal torque1, dReal torque2);
1899 
1900 /**
1901  * @brief set anchor
1902  * @ingroup joints
1903  */
1904 void dJointSetUniversalAnchor(dJointID, dReal x, dReal y, dReal z);
1905 
1906 /**
1907  * @brief set axis
1908  * @ingroup joints
1909  */
1910 void dJointSetUniversalAxis1(dJointID, dReal x, dReal y, dReal z);
1911 
1912 /**
1913  * @brief Set the Universal axis1 as if the 2 bodies were already at 
1914  *        offset1 and offset2 appart with respect to axis1 and axis2.
1915  * @ingroup joints
1916  *
1917  * This function initialize the axis1 and the relative orientation of 
1918  * each body as if body1 was rotated around the new axis1 by the offset1 
1919  * value and as if body2 was rotated around the axis2 by offset2. \br
1920  * Ex:
1921 * <PRE>
1922  * dJointSetHuniversalAxis1(jId, 1, 0, 0);
1923  * // If you request the position you will have: dJointGetUniversalAngle1(jId) == 0
1924  * // If you request the position you will have: dJointGetUniversalAngle2(jId) == 0
1925  * dJointSetHuniversalAxis1Offset(jId, 1, 0, 0, 0.2, 0.17);
1926  * // If you request the position you will have: dJointGetUniversalAngle1(jId) == 0.2
1927  * // If you request the position you will have: dJointGetUniversalAngle2(jId) == 0.17
1928  * </PRE>
1929  *
1930  * @param j The Hinge joint ID for which the axis will be set
1931  * @param x The X component of the axis in world frame
1932  * @param y The Y component of the axis in world frame
1933  * @param z The Z component of the axis in world frame
1934  * @param angle The angle for the offset of the relative orientation.
1935  *              As if body1 was rotated by angle when the Axis was set (see below).
1936  *              The rotation is around the new Hinge axis.
1937  *
1938  * @note Usually the function dJointSetHingeAxis set the current position of body1
1939  *       and body2 as the zero angle position. This function set the current position
1940  *       as the if the 2 bodies where \b offsets appart.
1941  *
1942  * @note Any previous offsets are erased.
1943  *
1944  * @warning Calling dJointSetUniversalAnchor, dJointSetUnivesalAxis1, 
1945  *          dJointSetUniversalAxis2, dJointSetUniversalAxis2Offset 
1946  *          will reset the "zero" angle position.
1947  */
1948 void dJointSetUniversalAxis1Offset(
1949     dJointID, dReal x, dReal y, dReal z, dReal offset1, dReal offset2
1950 );
1951 
1952 /**
1953  * @brief set axis
1954  * @ingroup joints
1955  */
1956 void dJointSetUniversalAxis2(dJointID, dReal x, dReal y, dReal z);
1957 
1958 /**
1959  * @brief Set the Universal axis2 as if the 2 bodies were already at 
1960  *        offset1 and offset2 appart with respect to axis1 and axis2.
1961  * @ingroup joints
1962  *
1963  * This function initialize the axis2 and the relative orientation of 
1964  * each body as if body1 was rotated around the axis1 by the offset1 
1965  * value and as if body2 was rotated around the new axis2 by offset2. \br
1966  * Ex:
1967  * <PRE>
1968  * dJointSetHuniversalAxis2(jId, 0, 1, 0);
1969  * // If you request the position you will have: dJointGetUniversalAngle1(jId) == 0
1970  * // If you request the position you will have: dJointGetUniversalAngle2(jId) == 0
1971  * dJointSetHuniversalAxis2Offset(jId, 0, 1, 0, 0.2, 0.17);
1972  * // If you request the position you will have: dJointGetUniversalAngle1(jId) == 0.2
1973  * // If you request the position you will have: dJointGetUniversalAngle2(jId) == 0.17
1974  * </PRE>
1975 
1976  * @param j The Hinge joint ID for which the axis will be set
1977  * @param x The X component of the axis in world frame
1978  * @param y The Y component of the axis in world frame
1979  * @param z The Z component of the axis in world frame
1980  * @param angle The angle for the offset of the relative orientation.
1981  *              As if body1 was rotated by angle when the Axis was set (see below).
1982  *              The rotation is around the new Hinge axis.
1983  *
1984  * @note Usually the function dJointSetHingeAxis set the current position of body1
1985  *       and body2 as the zero angle position. This function set the current position
1986  *       as the if the 2 bodies where \b offsets appart.
1987  *
1988  * @note Any previous offsets are erased.
1989  *
1990  * @warning Calling dJointSetUniversalAnchor, dJointSetUnivesalAxis1, 
1991  *          dJointSetUniversalAxis2, dJointSetUniversalAxis2Offset 
1992  *          will reset the "zero" angle position.
1993  */
1994 
1995 
1996 void dJointSetUniversalAxis2Offset(
1997     dJointID, dReal x, dReal y, dReal z, dReal offset1, dReal offset2
1998 );
1999 
2000 /**
2001  * @brief set joint parameter
2002  * @ingroup joints
2003  */
2004 void dJointSetUniversalParam(dJointID, int parameter, dReal value);
2005 
2006 /**
2007  * @brief Applies torque1 about the universal's axis 1, torque2 about the
2008  * universal's axis 2.
2009  * @remarks This function is just a wrapper for dBodyAddTorque().
2010  * @ingroup joints
2011  */
2012 void dJointAddUniversalTorques(dJointID joint, dReal torque1, dReal torque2);
2013 
2014 
2015 /**
2016  * @brief set anchor
2017  * @ingroup joints
2018  */
2019 void dJointSetPRAnchor(dJointID, dReal x, dReal y, dReal z);
2020 
2021 /**
2022  * @brief set the axis for the prismatic articulation
2023  * @ingroup joints
2024  */
2025 void dJointSetPRAxis1(dJointID, dReal x, dReal y, dReal z);
2026 
2027 /**
2028  * @brief set the axis for the rotoide articulation
2029  * @ingroup joints
2030  */
2031 void dJointSetPRAxis2(dJointID, dReal x, dReal y, dReal z);
2032 
2033 /**
2034  * @brief set joint parameter
2035  * @ingroup joints
2036  *
2037  * @note parameterX where X equal 2 refer to parameter for the rotoide articulation
2038  */
2039 void dJointSetPRParam(dJointID, int parameter, dReal value);
2040 
2041 /**
2042  * @brief Applies the torque about the rotoide axis of the PR joint
2043  *
2044  * That is, it applies a torque with specified magnitude in the direction 
2045  * of the rotoide axis, to body 1, and with the same magnitude but in opposite
2046  * direction to body 2. This function is just a wrapper for dBodyAddTorque()}
2047  * @ingroup joints
2048  */
2049 void dJointAddPRTorque(dJointID j, dReal torque);
2050 
2051 
2052 /**
2053 * @brief set anchor
2054 * @ingroup joints
2055 */
2056 void dJointSetPUAnchor(dJointID, dReal x, dReal y, dReal z);
2057 
2058 /**
2059  * @brief Set the PU anchor as if the 2 bodies were already at [dx, dy, dz] appart.
2060  * @ingroup joints
2061  *
2062  * This function initialize the anchor and the relative position of each body
2063  * as if the position between body1 and body2 was already the projection of [dx, dy, dz]
2064  * along the Piston axis. (i.e as if the body1 was at its current position - [dx,dy,dy] when the
2065  * axis is set).
2066  * Ex:
2067  * <PRE>
2068  * dReal offset = 3;
2069  * dVector3 axis;
2070  * dJointGetPUAxis(jId, axis);
2071  * dJointSetPUAnchor(jId, 0, 0, 0);
2072  * // If you request the position you will have: dJointGetPUPosition(jId) == 0
2073  * dJointSetPUAnchorOffset(jId, 0, 0, 0, axis[X]*offset, axis[Y]*offset, axis[Z]*offset);
2074  * // If you request the position you will have: dJointGetPUPosition(jId) == offset
2075  * </PRE>
2076  * @param j The PU joint for which the anchor point will be set
2077  * @param x The X position of the anchor point in world frame
2078  * @param y The Y position of the anchor point in world frame
2079  * @param z The Z position of the anchor point in world frame
2080  * @param dx A delta to be substracted to the X position as if the anchor was set
2081  *           when body1 was at current_position[X] - dx
2082  * @param dx A delta to be substracted to the Y position as if the anchor was set
2083  *           when body1 was at current_position[Y] - dy
2084  * @param dx A delta to be substracted to the Z position as if the anchor was set
2085  *           when body1 was at current_position[Z] - dz
2086  */
2087 void dJointSetPUAnchorOffset(
2088     dJointID, dReal x, dReal y, dReal z, dReal dx, dReal dy, dReal dz
2089 );
2090 
2091 /**
2092  * @brief set the axis for the first axis or the universal articulation
2093  * @ingroup joints
2094  */
2095 void dJointSetPUAxis1(dJointID, dReal x, dReal y, dReal z);
2096 
2097 /**
2098  * @brief set the axis for the second axis or the universal articulation
2099  * @ingroup joints
2100  */
2101 void dJointSetPUAxis2(dJointID, dReal x, dReal y, dReal z);
2102 
2103 /**
2104  * @brief set the axis for the prismatic articulation
2105  * @ingroup joints
2106  */
2107 void dJointSetPUAxis3(dJointID, dReal x, dReal y, dReal z);
2108 
2109 /**
2110  * @brief set the axis for the prismatic articulation
2111  * @ingroup joints
2112  * @note This function was added for convenience it is the same as
2113  *       dJointSetPUAxis3
2114  */
2115 void dJointSetPUAxisP(dJointID id, dReal x, dReal y, dReal z);
2116 
2117 
2118 
2119 /**
2120  * @brief set joint parameter
2121  * @ingroup joints
2122  *
2123  * @note parameterX where X equal 2 refer to parameter for second axis of the
2124  *       universal articulation
2125  * @note parameterX where X equal 3 refer to parameter for prismatic
2126  *       articulation
2127  */
2128 void dJointSetPUParam(dJointID, int parameter, dReal value);
2129 
2130 /**
2131  * @brief Applies the torque about the rotoide axis of the PU joint
2132  *
2133  * That is, it applies a torque with specified magnitude in the direction
2134  * of the rotoide axis, to body 1, and with the same magnitude but in opposite
2135  * direction to body 2. This function is just a wrapper for dBodyAddTorque()}
2136  * @ingroup joints
2137  */
2138 void dJointAddPUTorque(dJointID j, dReal torque);
2139 
2140 
2141 
2142 
2143 /**
2144  * @brief set the joint anchor
2145  * @ingroup joints
2146  */
2147 void dJointSetPistonAnchor(dJointID, dReal x, dReal y, dReal z);
2148 
2149 /**
2150  * @brief Set the Piston anchor as if the 2 bodies were already at [dx,dy, dz] appart.
2151  * @ingroup joints
2152  *
2153  * This function initialize the anchor and the relative position of each body
2154  * as if the position between body1 and body2 was already the projection of [dx, dy, dz]
2155  * along the Piston axis. (i.e as if the body1 was at its current position - [dx,dy,dy] when the
2156  * axis is set).
2157  * Ex:
2158  * <PRE>
2159  * dReal offset = 3;
2160  * dVector3 axis;
2161  * dJointGetPistonAxis(jId, axis);
2162  * dJointSetPistonAnchor(jId, 0, 0, 0);
2163  * // If you request the position you will have: dJointGetPistonPosition(jId) == 0
2164  * dJointSetPistonAnchorOffset(jId, 0, 0, 0, axis[X]*offset, axis[Y]*offset, axis[Z]*offset);
2165  * // If you request the position you will have: dJointGetPistonPosition(jId) == offset
2166  * </PRE>
2167  * @param j The Piston joint for which the anchor point will be set
2168  * @param x The X position of the anchor point in world frame
2169  * @param y The Y position of the anchor point in world frame
2170  * @param z The Z position of the anchor point in world frame
2171  * @param dx A delta to be substracted to the X position as if the anchor was set
2172  *           when body1 was at current_position[X] - dx
2173  * @param dx A delta to be substracted to the Y position as if the anchor was set
2174  *           when body1 was at current_position[Y] - dy
2175  * @param dx A delta to be substracted to the Z position as if the anchor was set
2176  *           when body1 was at current_position[Z] - dz
2177  */
2178 void dJointSetPistonAnchorOffset(
2179     dJointID j, dReal x, dReal y, dReal z, dReal dx, dReal dy, dReal dz
2180 );
2181 
2182     /**
2183      * @brief set the joint axis
2184  * @ingroup joints
2185  */
2186 void dJointSetPistonAxis(dJointID, dReal x, dReal y, dReal z);
2187 
2188 /**
2189  * @brief set joint parameter
2190  * @ingroup joints
2191  */
2192 void dJointSetPistonParam(dJointID, int parameter, dReal value);
2193 
2194 /**
2195  * @brief Applies the given force in the slider's direction.
2196  *
2197  * That is, it applies a force with specified magnitude, in the direction of
2198  * prismatic's axis, to body1, and with the same magnitude but opposite
2199  * direction to body2.  This function is just a wrapper for dBodyAddForce().
2200  * @ingroup joints
2201  */
2202 void dJointAddPistonForce(dJointID joint, dReal force);
2203 
2204 
2205 /**
2206  * @brief Call this on the fixed joint after it has been attached to
2207  * remember the current desired relative offset and desired relative
2208  * rotation between the bodies.
2209  * @ingroup joints
2210  */
2211 void dJointSetFixed(dJointID);
2212 
2213 /*
2214  * @brief Sets joint parameter
2215  *
2216  * @ingroup joints
2217  */
2218 void dJointSetFixedParam(dJointID, int parameter, dReal value);
2219 
2220 /**
2221  * @brief set the nr of axes
2222  * @param num 0..3
2223  * @ingroup joints
2224  */
2225 void dJointSetAMotorNumAxes(dJointID, int num);
2226 
2227 /**
2228  * @brief set axis
2229  * @ingroup joints
2230  */
2231 void dJointSetAMotorAxis(dJointID, int anum, int rel,
2232               dReal x, dReal y, dReal z);
2233 
2234 /**
2235  * @brief Tell the AMotor what the current angle is along axis anum.
2236  *
2237  * This function should only be called in dAMotorUser mode, because in this
2238  * mode the AMotor has no other way of knowing the joint angles.
2239  * The angle information is needed if stops have been set along the axis,
2240  * but it is not needed for axis motors.
2241  * @ingroup joints
2242  */
2243 void dJointSetAMotorAngle(dJointID, int anum, dReal angle);
2244 
2245 /**
2246  * @brief set joint parameter
2247  * @ingroup joints
2248  */
2249 void dJointSetAMotorParam(dJointID, int parameter, dReal value);
2250 
2251 /**
2252  * @brief set mode
2253  * @ingroup joints
2254  */
2255 void dJointSetAMotorMode(dJointID, int mode);
2256 
2257 /**
2258  * @brief Applies torque0 about the AMotor's axis 0, torque1 about the
2259  * AMotor's axis 1, and torque2 about the AMotor's axis 2.
2260  * @remarks
2261  * If the motor has fewer than three axes, the higher torques are ignored.
2262  * This function is just a wrapper for dBodyAddTorque().
2263  * @ingroup joints
2264  */
2265 void dJointAddAMotorTorques(dJointID, dReal torque1, dReal torque2, dReal torque3);
2266 
2267 /**
2268  * @brief Set the number of axes that will be controlled by the LMotor.
2269  * @param num can range from 0 (which effectively deactivates the joint) to 3.
2270  * @ingroup joints
2271  */
2272 void dJointSetLMotorNumAxes(dJointID, int num);
2273 
2274 /**
2275  * @brief Set the AMotor axes.
2276  * @param anum selects the axis to change (0,1 or 2).
2277  * @param rel Each axis can have one of three ``relative orientation'' modes
2278  * \li 0: The axis is anchored to the global frame.
2279  * \li 1: The axis is anchored to the first body.
2280  * \li 2: The axis is anchored to the second body.
2281  * @remarks The axis vector is always specified in global coordinates
2282  * regardless of the setting of rel.
2283  * @ingroup joints
2284  */
2285 void dJointSetLMotorAxis(dJointID, int anum, int rel, dReal x, dReal y, dReal z);
2286 
2287 /**
2288  * @brief set joint parameter
2289  * @ingroup joints
2290  */
2291 void dJointSetLMotorParam(dJointID, int parameter, dReal value);
2292 
2293 /**
2294  * @ingroup joints
2295  */
2296 void dJointSetPlane2DXParam(dJointID, int parameter, dReal value);
2297 
2298 /**
2299  * @ingroup joints
2300  */
2301 
2302 void dJointSetPlane2DYParam(dJointID, int parameter, dReal value);
2303 
2304 /**
2305  * @ingroup joints
2306  */
2307 void dJointSetPlane2DAngleParam(dJointID, int parameter, dReal value);
2308 
2309 /**
2310  * @brief Get the joint anchor point, in world coordinates.
2311  *
2312  * This returns the point on body 1. If the joint is perfectly satisfied,
2313  * this will be the same as the point on body 2.
2314  */
2315 void dJointGetBallAnchor(dJointID, dVector3 result);
2316 
2317 /**
2318  * @brief Get the joint anchor point, in world coordinates.
2319  *
2320  * This returns the point on body 2. You can think of a ball and socket
2321  * joint as trying to keep the result of dJointGetBallAnchor() and
2322  * dJointGetBallAnchor2() the same.  If the joint is perfectly satisfied,
2323  * this function will return the same value as dJointGetBallAnchor() to
2324  * within roundoff errors. dJointGetBallAnchor2() can be used, along with
2325  * dJointGetBallAnchor(), to see how far the joint has come apart.
2326  */
2327 void dJointGetBallAnchor2(dJointID, dVector3 result);
2328 
2329 /**
2330  * @brief get joint parameter
2331  * @ingroup joints
2332  */
2333 dReal dJointGetBallParam(dJointID, int parameter);
2334 
2335 /**
2336  * @brief Get the hinge anchor point, in world coordinates.
2337  *
2338  * This returns the point on body 1. If the joint is perfectly satisfied,
2339  * this will be the same as the point on body 2.
2340  * @ingroup joints
2341  */
2342 void dJointGetHingeAnchor(dJointID, dVector3 result);
2343 
2344 /**
2345  * @brief Get the joint anchor point, in world coordinates.
2346  * @return The point on body 2. If the joint is perfectly satisfied,
2347  * this will return the same value as dJointGetHingeAnchor().
2348  * If not, this value will be slightly different.
2349  * This can be used, for example, to see how far the joint has come apart.
2350  * @ingroup joints
2351  */
2352 void dJointGetHingeAnchor2(dJointID, dVector3 result);
2353 
2354 /**
2355  * @brief get axis
2356  * @ingroup joints
2357  */
2358 void dJointGetHingeAxis(dJointID, dVector3 result);
2359 
2360 /**
2361  * @brief get joint parameter
2362  * @ingroup joints
2363  */
2364 dReal dJointGetHingeParam(dJointID, int parameter);
2365 
2366 /**
2367  * @brief Get the hinge angle.
2368  *
2369  * The angle is measured between the two bodies, or between the body and
2370  * the static environment.
2371  * The angle will be between -pi..pi.
2372  * Give the relative rotation with respect to the Hinge axis of Body 1 with
2373  * respect to Body 2.
2374  * When the hinge anchor or axis is set, the current position of the attached
2375  * bodies is examined and that position will be the zero angle.
2376  * @ingroup joints
2377  */
2378 dReal dJointGetHingeAngle(dJointID);
2379 
2380 /**
2381  * @brief Get the hinge angle time derivative.
2382  * @ingroup joints
2383  */
2384 dReal dJointGetHingeAngleRate(dJointID);
2385 
2386 /**
2387  * @brief Get the slider linear position (i.e. the slider's extension)
2388  *
2389  * When the axis is set, the current position of the attached bodies is
2390  * examined and that position will be the zero position.
2391 
2392  * The position is the distance, with respect to the zero position,
2393  * along the slider axis of body 1 with respect to
2394  * body 2. (A NULL body is replaced by the world).
2395  * @ingroup joints
2396  */
2397 dReal dJointGetSliderPosition(dJointID);
2398 
2399 /**
2400  * @brief Get the slider linear position's time derivative.
2401  * @ingroup joints
2402  */
2403 dReal dJointGetSliderPositionRate(dJointID);
2404 
2405 /**
2406  * @brief Get the slider axis
2407  * @ingroup joints
2408  */
2409 void dJointGetSliderAxis(dJointID, dVector3 result);
2410 
2411 /**
2412  * @brief get joint parameter
2413  * @ingroup joints
2414  */
2415 dReal dJointGetSliderParam(dJointID, int parameter);
2416 
2417 /**
2418  * @brief Get the joint anchor point, in world coordinates.
2419  * @return the point on body 1.  If the joint is perfectly satisfied,
2420  * this will be the same as the point on body 2.
2421  * @ingroup joints
2422  */
2423 void dJointGetHinge2Anchor(dJointID, dVector3 result);
2424 
2425 /**
2426  * @brief Get the joint anchor point, in world coordinates.
2427  * This returns the point on body 2. If the joint is perfectly satisfied,
2428  * this will return the same value as dJointGetHinge2Anchor.
2429  * If not, this value will be slightly different.
2430  * This can be used, for example, to see how far the joint has come apart.
2431  * @ingroup joints
2432  */
2433 void dJointGetHinge2Anchor2(dJointID, dVector3 result);
2434 
2435 /**
2436  * @brief Get joint axis
2437  * @ingroup joints
2438  */
2439 void dJointGetHinge2Axis1(dJointID, dVector3 result);
2440 
2441 /**
2442  * @brief Get joint axis
2443  * @ingroup joints
2444  */
2445 void dJointGetHinge2Axis2(dJointID, dVector3 result);
2446 
2447 /**
2448  * @brief get joint parameter
2449  * @ingroup joints
2450  */
2451 dReal dJointGetHinge2Param(dJointID, int parameter);
2452 
2453 /**
2454  * @brief Get angle
2455  * @ingroup joints
2456  */
2457 dReal dJointGetHinge2Angle1(dJointID);
2458 
2459 /**
2460  * @brief Get time derivative of angle
2461  * @ingroup joints
2462  */
2463 dReal dJointGetHinge2Angle1Rate(dJointID);
2464 
2465 /**
2466  * @brief Get time derivative of angle
2467  * @ingroup joints
2468  */
2469 dReal dJointGetHinge2Angle2Rate(dJointID);
2470 
2471 /**
2472  * @brief Get the joint anchor point, in world coordinates.
2473  * @return the point on body 1. If the joint is perfectly satisfied,
2474  * this will be the same as the point on body 2.
2475  * @ingroup joints
2476  */
2477 void dJointGetUniversalAnchor(dJointID, dVector3 result);
2478 
2479 /**
2480  * @brief Get the joint anchor point, in world coordinates.
2481  * @return This returns the point on body 2.
2482  * @remarks
2483  * You can think of the ball and socket part of a universal joint as
2484  * trying to keep the result of dJointGetBallAnchor() and
2485  * dJointGetBallAnchor2() the same. If the joint is
2486  * perfectly satisfied, this function will return the same value
2487  * as dJointGetUniversalAnchor() to within roundoff errors.
2488  * dJointGetUniversalAnchor2() can be used, along with
2489  * dJointGetUniversalAnchor(), to see how far the joint has come apart.
2490  * @ingroup joints
2491  */
2492 void dJointGetUniversalAnchor2(dJointID, dVector3 result);
2493 
2494 /**
2495  * @brief Get axis
2496  * @ingroup joints
2497  */
2498 void dJointGetUniversalAxis1(dJointID, dVector3 result);
2499 
2500 /**
2501  * @brief Get axis
2502  * @ingroup joints
2503  */
2504 void dJointGetUniversalAxis2(dJointID, dVector3 result);
2505 
2506 
2507 /**
2508  * @brief get joint parameter
2509  * @ingroup joints
2510  */
2511 dReal dJointGetUniversalParam(dJointID, int parameter);
2512 
2513 /**
2514  * @brief Get both angles at the same time.
2515  * @ingroup joints
2516  *
2517  * @param joint   The universal joint for which we want to calculate the angles
2518  * @param angle1  The angle between the body1 and the axis 1
2519  * @param angle2  The angle between the body2 and the axis 2
2520  *
2521  * @note This function combine getUniversalAngle1 and getUniversalAngle2 together
2522  *       and try to avoid redundant calculation
2523  */
2524 void dJointGetUniversalAngles(dJointID, dReal* angle1, dReal* angle2);
2525 
2526 /**
2527  * @brief Get angle
2528  * @ingroup joints
2529  */
2530 dReal dJointGetUniversalAngle1(dJointID);
2531 
2532 /**
2533  * @brief Get angle
2534  * @ingroup joints
2535  */
2536 dReal dJointGetUniversalAngle2(dJointID);
2537 
2538 /**
2539  * @brief Get time derivative of angle
2540  * @ingroup joints
2541  */
2542 dReal dJointGetUniversalAngle1Rate(dJointID);
2543 
2544 /**
2545  * @brief Get time derivative of angle
2546  * @ingroup joints
2547  */
2548 dReal dJointGetUniversalAngle2Rate(dJointID);
2549 
2550 
2551 
2552 /**
2553  * @brief Get the joint anchor point, in world coordinates.
2554  * @return the point on body 1. If the joint is perfectly satisfied, 
2555  * this will be the same as the point on body 2.
2556  * @ingroup joints
2557  */
2558 void dJointGetPRAnchor(dJointID, dVector3 result);
2559 
2560 /**
2561  * @brief Get the PR linear position (i.e. the prismatic's extension)
2562  *
2563  * When the axis is set, the current position of the attached bodies is
2564  * examined and that position will be the zero position.
2565  *
2566  * The position is the "oriented" length between the
2567  * position = (Prismatic axis) dot_product [(body1 + offset) - (body2 + anchor2)]
2568  *
2569  * @ingroup joints
2570  */
2571 dReal dJointGetPRPosition(dJointID);
2572 
2573 /**
2574  * @brief Get the PR linear position's time derivative
2575  *
2576  * @ingroup joints
2577  */
2578 dReal dJointGetPRPositionRate(dJointID);
2579 
2580 
2581 /**
2582  * @brief Get the PR angular position (i.e. the  twist between the 2 bodies)
2583  *
2584  * When the axis is set, the current position of the attached bodies is
2585  * examined and that position will be the zero position.
2586  * @ingroup joints
2587  */
2588 dReal dJointGetPRAngle(dJointID);
2589 
2590 /**
2591  * @brief Get the PR angular position's time derivative
2592  *
2593  * @ingroup joints
2594  */
2595 dReal dJointGetPRAngleRate(dJointID);
2596 
2597 
2598 /**
2599  * @brief Get the prismatic axis
2600  * @ingroup joints
2601  */
2602 void dJointGetPRAxis1(dJointID, dVector3 result);
2603 
2604 /**
2605  * @brief Get the Rotoide axis
2606  * @ingroup joints
2607  */
2608 void dJointGetPRAxis2(dJointID, dVector3 result);
2609 
2610 /**
2611  * @brief get joint parameter
2612  * @ingroup joints
2613  */
2614 dReal dJointGetPRParam(dJointID, int parameter);
2615 
2616     
2617     
2618 /**
2619  * @brief Get the joint anchor point, in world coordinates.
2620  * @return the point on body 1. If the joint is perfectly satisfied,
2621  * this will be the same as the point on body 2.
2622  * @ingroup joints
2623  */
2624 void dJointGetPUAnchor(dJointID, dVector3 result);
2625 
2626 /**
2627  * @brief Get the PU linear position (i.e. the prismatic's extension)
2628  *
2629  * When the axis is set, the current position of the attached bodies is
2630  * examined and that position will be the zero position.
2631  *
2632  * The position is the "oriented" length between the
2633  * position = (Prismatic axis) dot_product [(body1 + offset) - (body2 + anchor2)]
2634  *
2635  * @ingroup joints
2636  */
2637 dReal dJointGetPUPosition(dJointID);
2638 
2639 /**
2640  * @brief Get the PR linear position's time derivative
2641  *
2642  * @ingroup joints
2643  */
2644 dReal dJointGetPUPositionRate(dJointID);
2645 
2646 /**
2647  * @brief Get the first axis of the universal component of the joint
2648  * @ingroup joints
2649  */
2650 void dJointGetPUAxis1(dJointID, dVector3 result);
2651 
2652 /**
2653  * @brief Get the second axis of the Universal component of the joint
2654  * @ingroup joints
2655  */
2656 void dJointGetPUAxis2(dJointID, dVector3 result);
2657 
2658 /**
2659  * @brief Get the prismatic axis
2660  * @ingroup joints
2661  */
2662 void dJointGetPUAxis3(dJointID, dVector3 result);
2663 
2664 /**
2665  * @brief Get the prismatic axis
2666  * @ingroup joints
2667  *
2668  * @note This function was added for convenience it is the same as
2669  *       dJointGetPUAxis3
2670  */
2671 void dJointGetPUAxisP(dJointID id, dVector3 result);
2672 
2673 
2674 
2675 
2676 /**
2677  * @brief Get both angles at the same time.
2678  * @ingroup joints
2679  *
2680  * @param joint   The Prismatic universal joint for which we want to calculate the angles
2681  * @param angle1  The angle between the body1 and the axis 1
2682  * @param angle2  The angle between the body2 and the axis 2
2683  *
2684  * @note This function combine dJointGetPUAngle1 and dJointGetPUAngle2 together
2685  *       and try to avoid redundant calculation
2686  */
2687 void dJointGetPUAngles(dJointID, dReal* angle1, dReal* angle2);
2688 
2689 /**
2690  * @brief Get angle
2691  * @ingroup joints
2692  */
2693 dReal dJointGetPUAngle1(dJointID);
2694 
2695 /**
2696  * @brief * @brief Get time derivative of angle1
2697  *
2698  * @ingroup joints
2699  */
2700 dReal dJointGetPUAngle1Rate(dJointID);
2701 
2702 
2703 /**
2704  * @brief Get angle
2705  * @ingroup joints
2706  */
2707 dReal dJointGetPUAngle2(dJointID);
2708 
2709 /**
2710  * @brief * @brief Get time derivative of angle2
2711  *
2712  * @ingroup joints
2713  */
2714 dReal dJointGetPUAngle2Rate(dJointID);
2715 
2716 /**
2717  * @brief get joint parameter
2718  * @ingroup joints
2719  */
2720 dReal dJointGetPUParam(dJointID, int parameter);
2721 
2722 
2723 
2724 
2725 
2726 /**
2727  * @brief Get the Piston linear position (i.e. the piston's extension)
2728  *
2729  * When the axis is set, the current position of the attached bodies is
2730  * examined and that position will be the zero position.
2731  * @ingroup joints
2732  */
2733 dReal dJointGetPistonPosition(dJointID);
2734 
2735 /**
2736  * @brief Get the piston linear position's time derivative.
2737  * @ingroup joints
2738  */
2739 dReal dJointGetPistonPositionRate(dJointID);
2740 
2741 /**
2742  * @brief Get the Piston angular position (i.e. the  twist between the 2 bodies)
2743  *
2744  * When the axis is set, the current position of the attached bodies is
2745  * examined and that position will be the zero position.
2746  * @ingroup joints
2747  */
2748 dReal dJointGetPistonAngle(dJointID);
2749 
2750 /**
2751  * @brief Get the piston angular position's time derivative.
2752  * @ingroup joints
2753  */
2754 dReal dJointGetPistonAngleRate(dJointID);
2755 
2756 
2757 /**
2758  * @brief Get the joint anchor
2759  *
2760  * This returns the point on body 1. If the joint is perfectly satisfied,
2761  * this will be the same as the point on body 2 in direction perpendicular
2762  * to the prismatic axis.
2763  *
2764  * @ingroup joints
2765  */
2766 void dJointGetPistonAnchor(dJointID, dVector3 result);
2767 
2768 /**
2769  * @brief Get the joint anchor w.r.t. body 2
2770  *
2771  * This returns the point on body 2. You can think of a Piston
2772  * joint as trying to keep the result of dJointGetPistonAnchor() and
2773  * dJointGetPistonAnchor2() the same in the direction perpendicular to the
2774  * pirsmatic axis. If the joint is perfectly satisfied,
2775  * this function will return the same value as dJointGetPistonAnchor() to
2776  * within roundoff errors. dJointGetPistonAnchor2() can be used, along with
2777  * dJointGetPistonAnchor(), to see how far the joint has come apart.
2778  *
2779  * @ingroup joints
2780  */
2781 void dJointGetPistonAnchor2(dJointID, dVector3 result);
2782 
2783 /**
2784  * @brief Get the prismatic axis (This is also the rotoide axis.
2785  * @ingroup joints
2786  */
2787 void dJointGetPistonAxis(dJointID, dVector3 result);
2788 
2789 /**
2790  * @brief get joint parameter
2791  * @ingroup joints
2792  */
2793 dReal dJointGetPistonParam(dJointID, int parameter);
2794 
2795 
2796 /**
2797  * @brief Get the number of angular axes that will be controlled by the
2798  * AMotor.
2799  * @param num can range from 0 (which effectively deactivates the
2800  * joint) to 3.
2801  * This is automatically set to 3 in dAMotorEuler mode.
2802  * @ingroup joints
2803  */
2804 int dJointGetAMotorNumAxes(dJointID);
2805 
2806 /**
2807  * @brief Get the AMotor axes.
2808  * @param anum selects the axis to change (0,1 or 2).
2809  * @param rel Each axis can have one of three ``relative orientation'' modes.
2810  * \li 0: The axis is anchored to the global frame.
2811  * \li 1: The axis is anchored to the first body.
2812  * \li 2: The axis is anchored to the second body.
2813  * @ingroup joints
2814  */
2815 void dJointGetAMotorAxis(dJointID, int anum, dVector3 result);
2816 
2817 /**
2818  * @brief Get axis
2819  * @remarks
2820  * The axis vector is always specified in global coordinates regardless
2821  * of the setting of rel.
2822  * There are two GetAMotorAxis functions, one to return the axis and one to
2823  * return the relative mode.
2824  *
2825  * For dAMotorEuler mode:
2826  * \li    Only axes 0 and 2 need to be set. Axis 1 will be determined
2827     automatically at each time step.
2828  * \li    Axes 0 and 2 must be perpendicular to each other.
2829  * \li    Axis 0 must be anchored to the first body, axis 2 must be anchored
2830     to the second body.
2831  * @ingroup joints
2832  */
2833 int dJointGetAMotorAxisRel(dJointID, int anum);
2834 
2835 /**
2836  * @brief Get the current angle for axis.
2837  * @remarks
2838  * In dAMotorUser mode this is simply the value that was set with
2839  * dJointSetAMotorAngle().
2840  * In dAMotorEuler mode this is the corresponding euler angle.
2841  * @ingroup joints
2842  */
2843 dReal dJointGetAMotorAngle(dJointID, int anum);
2844 
2845 /**
2846  * @brief Get the current angle rate for axis anum.
2847  * @remarks
2848  * In dAMotorUser mode this is always zero, as not enough information is
2849  * available.
2850  * In dAMotorEuler mode this is the corresponding euler angle rate.
2851  * @ingroup joints
2852  */
2853 dReal dJointGetAMotorAngleRate(dJointID, int anum);
2854 
2855 /**
2856  * @brief get joint parameter
2857  * @ingroup joints
2858  */
2859 dReal dJointGetAMotorParam(dJointID, int parameter);
2860 
2861 /**
2862  * @brief Get the angular motor mode.
2863  * @param mode must be one of the following constants:
2864  * \li dAMotorUser The AMotor axes and joint angle settings are entirely
2865  * controlled by the user.  This is the default mode.
2866  * \li dAMotorEuler Euler angles are automatically computed.
2867  * The axis a1 is also automatically computed.
2868  * The AMotor axes must be set correctly when in this mode,
2869  * as described below.
2870  * When this mode is initially set the current relative orientations
2871  * of the bodies will correspond to all euler angles at zero.
2872  * @ingroup joints
2873  */
2874 int dJointGetAMotorMode(dJointID);
2875 
2876 /**
2877  * @brief Get nr of axes.
2878  * @ingroup joints
2879  */
2880 int dJointGetLMotorNumAxes(dJointID);
2881 
2882 /**
2883  * @brief Get axis.
2884  * @ingroup joints
2885  */
2886 void dJointGetLMotorAxis(dJointID, int anum, dVector3 result);
2887 
2888 /**
2889  * @brief get joint parameter
2890  * @ingroup joints
2891  */
2892 dReal dJointGetLMotorParam(dJointID, int parameter);
2893 
2894 /**
2895  * @brief get joint parameter
2896  * @ingroup joints
2897  */
2898 dReal dJointGetFixedParam(dJointID, int parameter);
2899 
2900 
2901 /**
2902  * @ingroup joints
2903  */
2904 dJointID dConnectingJoint(dBodyID, dBodyID);
2905 
2906 /**
2907  * @ingroup joints
2908  */
2909 int dConnectingJointList(dBodyID, dBodyID, dJointID*);
2910 
2911 /**
2912  * @brief Utility function
2913  * @return 1 if the two bodies are connected together by
2914  * a joint, otherwise return 0.
2915  * @ingroup joints
2916  */
2917 int dAreConnected(dBodyID, dBodyID);
2918 
2919 /**
2920  * @brief Utility function
2921  * @return 1 if the two bodies are connected together by
2922  * a joint that does not have type @arg{joint_type}, otherwise return 0.
2923  * @param body1 A body to check.
2924  * @param body2 A body to check.
2925  * @param joint_type is a dJointTypeXXX constant.
2926  * This is useful for deciding whether to add contact joints between two bodies:
2927  * if they are already connected by non-contact joints then it may not be
2928  * appropriate to add contacts, however it is okay to add more contact between-
2929  * bodies that already have contacts.
2930  * @ingroup joints
2931  */
2932 int dAreConnectedExcluding(dBodyID body1, dBodyID body2, int joint_type);