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