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