From c79e4ed8402b9b3e1df07dc83601db06b1c71fd8 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Tue, 23 Jan 2018 15:24:20 +0500 Subject: [PATCH] Added documentation from ODE 0.6 --- Externals/ode/include/ode/collision.h | 363 ++++++- Externals/ode/include/ode/common.h | 2 +- Externals/ode/include/ode/contact.h | 24 +- Externals/ode/include/ode/objects.h | 1429 ++++++++++++++++++++++++- Externals/ode/include/ode/timer.h | 6 +- 5 files changed, 1760 insertions(+), 64 deletions(-) diff --git a/Externals/ode/include/ode/collision.h b/Externals/ode/include/ode/collision.h index 250cdeac1d2..06c78201266 100644 --- a/Externals/ode/include/ode/collision.h +++ b/Externals/ode/include/ode/collision.h @@ -31,31 +31,354 @@ extern "C" { #endif +/** + * @defgroup collide Collision Detection + * + * ODE has two main components: a dynamics simulation engine and a collision + * detection engine. The collision engine is given information about the + * shape of each body. At each time step it figures out which bodies touch + * each other and passes the resulting contact point information to the user. + * The user in turn creates contact joints between bodies. + * + * Using ODE's collision detection is optional - an alternative collision + * detection system can be used as long as it can supply the right kinds of + * contact information. + */ + + /* ************************************************************************ */ /* general functions */ -void dGeomDestroy (dGeomID); -void dGeomSetData (dGeomID, void *); -void *dGeomGetData (dGeomID); -void dGeomSetBody (dGeomID, dBodyID); -dBodyID dGeomGetBody (dGeomID); -void dGeomSetPosition (dGeomID, dReal x, dReal y, dReal z); -void dGeomSetRotation (dGeomID, const dMatrix3 R); -void dGeomSetQuaternion (dGeomID, const dQuaternion); -const dReal * dGeomGetPosition (dGeomID); -const dReal * dGeomGetRotation (dGeomID); -void dGeomGetQuaternion (dGeomID, dQuaternion result); -void dGeomGetAABB (dGeomID, dReal aabb[6]); -int dGeomIsSpace (dGeomID); +/** + * @brief Destroy a geom, removing it from any space. + * + * Destroy a geom, removing it from any space it is in first. This one + * function destroys a geom of any type, but to create a geom you must call + * a creation function for that type. + * + * When a space is destroyed, if its cleanup mode is 1 (the default) then all + * the geoms in that space are automatically destroyed as well. + * + * @param geom the geom to be destroyed. + * @ingroup collide + */ +void dGeomDestroy (dGeomID geom); + + +/** + * @brief Set the user-defined data pointer stored in the geom. + * + * @param geom the geom to hold the data + * @param data the data pointer to be stored + * @ingroup collide + */ +void dGeomSetData (dGeomID geom, void* data); + + +/** + * @brief Get the user-defined data pointer stored in the geom. + * + * @param geom the geom containing the data + * @ingroup collide + */ +void *dGeomGetData (dGeomID geom); + + +/** + * @brief Set the body associated with a placeable geom. + * + * Setting a body on a geom automatically combines the position vector and + * rotation matrix of the body and geom, so that setting the position or + * orientation of one will set the value for both objects. Setting a body + * ID of zero gives the geom its own position and rotation, independent + * from any body. If the geom was previously connected to a body then its + * new independent position/rotation is set to the current position/rotation + * of the body. + * + * Calling these functions on a non-placeable geom results in a runtime + * error in the debug build of ODE. + * + * @param geom the geom to connect + * @param body the body to attach to the geom + * @ingroup collide + */ +void dGeomSetBody (dGeomID geom, dBodyID body); + + +/** + * @brief Get the body associated with a placeable geom. + * @param geom the geom to query. + * @sa dGeomSetBody + * @ingroup collide + */ +dBodyID dGeomGetBody (dGeomID geom); + + +/** + * @brief Set the position vector of a placeable geom. + * + * If the geom is attached to a body, the body's position will also be changed. + * Calling this function on a non-placeable geom results in a runtime error in + * the debug build of ODE. + * + * @param geom the geom to set. + * @param x the new X coordinate. + * @param y the new Y coordinate. + * @param z the new Z coordinate. + * @sa dBodySetPosition + * @ingroup collide + */ +void dGeomSetPosition (dGeomID geom, dReal x, dReal y, dReal z); + + +/** + * @brief Set the rotation matrix of a placeable geom. + * + * If the geom is attached to a body, the body's rotation will also be changed. + * Calling this function on a non-placeable geom results in a runtime error in + * the debug build of ODE. + * + * @param geom the geom to set. + * @param R the new rotation matrix. + * @sa dBodySetRotation + * @ingroup collide + */ +void dGeomSetRotation (dGeomID geom, const dMatrix3 R); + + +/** + * @brief Set the rotation of a placeable geom. + * + * If the geom is attached to a body, the body's rotation will also be changed. + * + * Calling this function on a non-placeable geom results in a runtime error in + * the debug build of ODE. + * + * @param geom the geom to set. + * @param Q the new rotation. + * @sa dBodySetQuaternion + * @ingroup collide + */ +void dGeomSetQuaternion (dGeomID geom, const dQuaternion Q); + + +/** + * @brief Get the position vector of a placeable geom. + * + * If the geom is attached to a body, the body's position will be returned. + * + * Calling this function on a non-placeable geom results in a runtime error in + * the debug build of ODE. + * + * @param geom the geom to query. + * @returns A pointer to the geom's position vector. + * @remarks The returned value is a pointer to the geom's internal + * data structure. It is valid until any changes are made + * to the geom. + * @sa dBodyGetPosition + * @ingroup collide + */ +const dReal * dGeomGetPosition (dGeomID geom); + + +/** + * @brief Get the rotation matrix of a placeable geom. + * + * If the geom is attached to a body, the body's rotation will be returned. + * + * Calling this function on a non-placeable geom results in a runtime error in + * the debug build of ODE. + * + * @param geom the geom to query. + * @returns A pointer to the geom's rotation matrix. + * @remarks The returned value is a pointer to the geom's internal + * data structure. It is valid until any changes are made + * to the geom. + * @sa dBodyGetRotation + * @ingroup collide + */ +const dReal * dGeomGetRotation (dGeomID geom); + + +/** + * @brief Get the rotation quaternion of a placeable geom. + * + * If the geom is attached to a body, the body's quaternion will be returned. + * + * Calling this function on a non-placeable geom results in a runtime error in + * the debug build of ODE. + * + * @param geom the geom to query. + * @param result a copy of the rotation quaternion. + * @sa dBodyGetQuaternion + * @ingroup collide + */ +void dGeomGetQuaternion (dGeomID geom, dQuaternion result); + + +/** + * @brief Return the axis-aligned bounding box. + * + * Return in aabb an axis aligned bounding box that surrounds the given geom. + * The aabb array has elements (minx, maxx, miny, maxy, minz, maxz). If the + * geom is a space, a bounding box that surrounds all contained geoms is + * returned. + * + * This function may return a pre-computed cached bounding box, if it can + * determine that the geom has not moved since the last time the bounding + * box was computed. + * + * @param geom the geom to query + * @param aabb the returned bounding box + * @ingroup collide + */ +void dGeomGetAABB (dGeomID geom, dReal aabb[6]); + + +/** + * @brief Determing if a geom is a space. + * @param geom the geom to query + * @returns Non-zero if the geom is a space, zero otherwise. + * @ingroup collide + */ +int dGeomIsSpace (dGeomID geom); + + +/** + * @brief Query for the space containing a particular geom. + * @param geom the geom to query + * @returns The space that contains the geom, or NULL if the geom is + * not contained by a space. + * @ingroup collide + */ dSpaceID dGeomGetSpace (dGeomID); -int dGeomGetClass (dGeomID); -void dGeomSetCategoryBits (dGeomID, unsigned long bits); -void dGeomSetCollideBits (dGeomID, unsigned long bits); + + +/** + * @brief Given a geom, this returns its class. + * + * The ODE classes are: + * @li dSphereClass + * @li dBoxClass + * @li dCylinderClass + * @li dPlaneClass + * @li dRayClass + * @li dConvexClass + * @li dGeomTransformClass + * @li dTriMeshClass + * @li dSimpleSpaceClass + * @li dHashSpaceClass + * @li dQuadTreeSpaceClass + * @li dFirstUserClass + * @li dLastUserClass + * + * User-defined class will return their own number. + * + * @param geom the geom to query + * @returns The geom class ID. + * @ingroup collide + */ +int dGeomGetClass (dGeomID geom); + + +/** + * @brief Set the "category" bitfield for the given geom. + * + * The category bitfield is used by spaces to govern which geoms will + * interact with each other. The bitfield is guaranteed to be at least + * 32 bits wide. The default category values for newly created geoms + * have all bits set. + * + * @param geom the geom to set + * @param bits the new bitfield value + * @ingroup collide + */ +void dGeomSetCategoryBits (dGeomID geom, unsigned long bits); + + +/** + * @brief Set the "collide" bitfield for the given geom. + * + * The collide bitfield is used by spaces to govern which geoms will + * interact with each other. The bitfield is guaranteed to be at least + * 32 bits wide. The default category values for newly created geoms + * have all bits set. + * + * @param geom the geom to set + * @param bits the new bitfield value + * @ingroup collide + */ +void dGeomSetCollideBits (dGeomID geom, unsigned long bits); + + +/** + * @brief Get the "category" bitfield for the given geom. + * + * @param geom the geom to set + * @param bits the new bitfield value + * @sa dGeomSetCategoryBits + * @ingroup collide + */ unsigned long dGeomGetCategoryBits (dGeomID); + + +/** + * @brief Get the "collide" bitfield for the given geom. + * + * @param geom the geom to set + * @param bits the new bitfield value + * @sa dGeomSetCollideBits + * @ingroup collide + */ unsigned long dGeomGetCollideBits (dGeomID); -void dGeomEnable (dGeomID); -void dGeomDisable (dGeomID); -int dGeomIsEnabled (dGeomID); + + +/** + * @brief Enable a geom. + * + * Disabled geoms are completely ignored by dSpaceCollide and dSpaceCollide2, + * although they can still be members of a space. New geoms are created in + * the enabled state. + * + * @param geom the geom to enable + * @sa dGeomDisable + * @sa dGeomIsEnabled + * @ingroup collide + */ +void dGeomEnable (dGeomID geom); + + +/** + * @brief Disable a geom. + * + * Disabled geoms are completely ignored by dSpaceCollide and dSpaceCollide2, + * although they can still be members of a space. New geoms are created in + * the enabled state. + * + * @param geom the geom to disable + * @sa dGeomDisable + * @sa dGeomIsEnabled + * @ingroup collide + */ +void dGeomDisable (dGeomID geom); + + +/** + * @brief Check to see if a geom is enabled. + * + * Disabled geoms are completely ignored by dSpaceCollide and dSpaceCollide2, + * although they can still be members of a space. New geoms are created in + * the enabled state. + * + * @param geom the geom to query + * @returns Non-zero if the geom is enabled, zero otherwise. + * @sa dGeomDisable + * @sa dGeomIsEnabled + * @ingroup collide + */ +int dGeomIsEnabled (dGeomID geom); + + /* ************************************************************************ */ /* collision detection */ @@ -156,7 +479,7 @@ int dBoxTouchesBox (const dVector3 _p1, const dMatrix3 R1, const dMatrix3 R2, const dVector3 side2); void dInfiniteAABB (dGeomID geom, dReal aabb[6]); -void dCloseODE(); +void dCloseODE(void); /* ************************************************************************ */ /* custom classes */ diff --git a/Externals/ode/include/ode/common.h b/Externals/ode/include/ode/common.h index 6edeade763e..c593ce67a63 100644 --- a/Externals/ode/include/ode/common.h +++ b/Externals/ode/include/ode/common.h @@ -22,9 +22,9 @@ #ifndef _ODE_COMMON_H_ #define _ODE_COMMON_H_ - #include #include +#include #ifdef __cplusplus extern "C" { diff --git a/Externals/ode/include/ode/contact.h b/Externals/ode/include/ode/contact.h index 926d77f6c43..ed1bbff9956 100644 --- a/Externals/ode/include/ode/contact.h +++ b/Externals/ode/include/ode/contact.h @@ -64,13 +64,25 @@ typedef struct dSurfaceParameters { } dSurfaceParameters; -/* contact info set by collision functions */ - +/** + * @brief Describe the contact point between two geoms. + * + * If two bodies touch, or if a body touches a static feature in its + * environment, the contact is represented by one or more "contact + * points", described by dContactGeom. + * + * The convention is that if body 1 is moved along the normal vector by + * a distance depth (or equivalently if body 2 is moved the same distance + * in the opposite direction) then the contact depth will be reduced to + * zero. This means that the normal vector points "in" to body 1. + * + * @ingroup collide + */ typedef struct dContactGeom { - dVector3 pos; - dVector3 normal; - dReal depth; - dGeomID g1,g2; + dVector3 pos; ///< contact position + dVector3 normal; ///< normal vector + dReal depth; ///< penetration depth + dGeomID g1,g2; ///< the colliding geoms } dContactGeom; diff --git a/Externals/ode/include/ode/objects.h b/Externals/ode/include/ode/objects.h index 64cf4cdf8b3..8e8d07902a1 100644 --- a/Externals/ode/include/ode/objects.h +++ b/Externals/ode/include/ode/objects.h @@ -31,235 +31,1596 @@ extern "C" { #endif -/* world */ +/** + * @defgroup world World + * + * The world object is a container for rigid bodies and joints. Objects in + * different worlds can not interact, for example rigid bodies from two + * different worlds can not collide. + * + * All the objects in a world exist at the same point in time, thus one + * reason to use separate worlds is to simulate systems at different rates. + * Most applications will only need one world. + */ -dWorldID dWorldCreate(); -void dWorldDestroy (dWorldID); +/** + * @brief Create a new, empty world and return its ID number. + * @return an identifier + * @ingroup world + */ +dWorldID dWorldCreate(void); + + +/** + * @brief Destroy a world and everything in it. + * + * This includes all bodies, and all joints that are not part of a joint + * group. Joints that are part of a joint group will be deactivated, and + * can be destroyed by calling, for example, dJointGroupEmpty(). + * @ingroup world + * @param world the identifier for the world the be destroyed. + */ +void dWorldDestroy (dWorldID world); + + +/** + * @brief Set the world's global gravity vector. + * + * The units are m/s^2, so Earth's gravity vector would be (0,0,-9.81), + * assuming that +z is up. The default is no gravity, i.e. (0,0,0). + * + * @ingroup world + */ void dWorldSetGravity (dWorldID, dReal x, dReal y, dReal z); + + +/** + * @brief Get the gravity vector for a given world. + * @ingroup world + */ void dWorldGetGravity (dWorldID, dVector3 gravity); + + +/** + * @brief Set the global ERP value, that controls how much error + * correction is performed in each time step. + * @ingroup world + * @param dWorldID the identifier of the world. + * @param erp Typical values are in the range 0.1--0.8. The default is 0.2. + */ void dWorldSetERP (dWorldID, dReal erp); + +/** + * @brief Get the error reduction parameter. + * @ingroup world + * @return ERP value + */ dReal dWorldGetERP (dWorldID); + + +/** + * @brief Set the global CFM (constraint force mixing) value. + * @ingroup world + * @param cfm Typical values are in the range @m{10^{-9}} -- 1. + * The default is 10^-5 if single precision is being used, or 10^-10 + * if double precision is being used. + */ void dWorldSetCFM (dWorldID, dReal cfm); + + +/** + * @brief Get the constraint force mixing value. + * @ingroup world + * @return CFM value + */ dReal dWorldGetCFM (dWorldID); + + +/** + * @brief Step the world. + * + * This uses a "big matrix" method that takes time on the order of m^3 + * and memory on the order of m^2, where m is the total number of constraint + * rows. For large systems this will use a lot of memory and can be very slow, + * but this is currently the most accurate method. + * @ingroup world + * @param stepsize The number of seconds that the simulation has to advance. + */ void dWorldStep (dWorldID, dReal stepsize); -void dWorldImpulseToForce (dWorldID, dReal stepsize, - dReal ix, dReal iy, dReal iz, dVector3 force); -/* World QuickStep functions */ +/** + * @brief Converts an impulse to a force. + * @ingroup world + * @remarks + * If you want to apply a linear or angular impulse to a rigid body, + * instead of a force or a torque, then you can use this function to convert + * the desired impulse into a force/torque vector before calling the + * BodyAdd... function. + * The current algorithm simply scales the impulse by 1/stepsize, + * where stepsize is the step size for the next step that will be taken. + * This function is given a dWorldID because, in the future, the force + * computation may depend on integrator parameters that are set as + * properties of the world. + */ +void dWorldImpulseToForce +( + dWorldID, dReal stepsize, + dReal ix, dReal iy, dReal iz, dVector3 force +); + + +/** + * @brief Step the world. + * @ingroup world + * @remarks + * This uses an iterative method that takes time on the order of m*N + * and memory on the order of m, where m is the total number of constraint + * rows N is the number of iterations. + * For large systems this is a lot faster than dWorldStep(), + * but it is less accurate. + * @remarks + * QuickStep is great for stacks of objects especially when the + * auto-disable feature is used as well. + * However, it has poor accuracy for near-singular systems. + * Near-singular systems can occur when using high-friction contacts, motors, + * or certain articulated structures. For example, a robot with multiple legs + * sitting on the ground may be near-singular. + * @remarks + * There are ways to help overcome QuickStep's inaccuracy problems: + * \li Increase CFM. + * \li Reduce the number of contacts in your system (e.g. use the minimum + * number of contacts for the feet of a robot or creature). + * \li Don't use excessive friction in the contacts. + * \li Use contact slip if appropriate + * \li Avoid kinematic loops (however, kinematic loops are inevitable in + * legged creatures). + * \li Don't use excessive motor strength. + * \liUse force-based motors instead of velocity-based motors. + * + * Increasing the number of QuickStep iterations may help a little bit, but + * it is not going to help much if your system is really near singular. + */ void dWorldQuickStep (dWorldID w, dReal stepsize); + + +/** + * @brief Set the number of iterations that the QuickStep method performs per + * step. + * @ingroup world + * @remarks + * More iterations will give a more accurate solution, but will take + * longer to compute. + * @param num The default is 20 iterations. + */ void dWorldSetQuickStepNumIterations (dWorldID, int num); + + +/** + * @brief Get the number of iterations that the QuickStep method performs per + * step. + * @ingroup world + * @return nr of iterations + */ int dWorldGetQuickStepNumIterations (dWorldID); -void dWorldSetQuickStepW (dWorldID, dReal param); + +/** + * @brief Set the SOR over-relaxation parameter + * @ingroup world + * @param over_relaxation value to use by SOR + */ +void dWorldSetQuickStepW (dWorldID, dReal over_relaxation); + +/** + * @brief Get the SOR over-relaxation parameter + * @ingroup world + * @returns the over-relaxation setting + */ dReal dWorldGetQuickStepW (dWorldID); /* World contact parameter functions */ +/** + * @brief Set the maximum correcting velocity that contacts are allowed + * to generate. + * @ingroup world + * @param vel The default value is infinity (i.e. no limit). + * @remarks + * Reducing this value can help prevent "popping" of deeply embedded objects. + */ void dWorldSetContactMaxCorrectingVel (dWorldID, dReal vel); + +/** + * @brief Get the maximum correcting velocity that contacts are allowed + * to generated. + * @ingroup world + */ dReal dWorldGetContactMaxCorrectingVel (dWorldID); + +/** + * @brief Set the depth of the surface layer around all geometry objects. + * @ingroup world + * @remarks + * Contacts are allowed to sink into the surface layer up to the given + * depth before coming to rest. + * @param depth The default value is zero. + * @remarks + * Increasing this to some small value (e.g. 0.001) can help prevent + * jittering problems due to contacts being repeatedly made and broken. + */ void dWorldSetContactSurfaceLayer (dWorldID, dReal depth); + +/** + * @brief Get the depth of the surface layer around all geometry objects. + * @ingroup world + * @returns the depth + */ dReal dWorldGetContactSurfaceLayer (dWorldID); /* StepFast1 functions */ +/** + * @brief Step the world using the StepFast1 algorithm. + * @param stepsize the nr of seconds to advance the simulation. + * @param maxiterations The number of iterations to perform. + * @ingroup world + */ void dWorldStepFast1(dWorldID, dReal stepsize, int maxiterations); + +/** + * @defgroup disable Automatic Enabling and Disabling + * + * Every body can be enabled or disabled. Enabled bodies participate in the + * simulation, while disabled bodies are turned off and do not get updated + * during a simulation step. New bodies are always created in the enabled state. + * + * A disabled body that is connected through a joint to an enabled body will be + * automatically re-enabled at the next simulation step. + * + * Disabled bodies do not consume CPU time, therefore to speed up the simulation + * bodies should be disabled when they come to rest. This can be done automatically + * with the auto-disable feature. + * + * If a body has its auto-disable flag turned on, it will automatically disable + * itself when + * @li It has been idle for a given number of simulation steps. + * @li It has also been idle for a given amount of simulation time. + * + * A body is considered to be idle when the magnitudes of both its linear velocity + * and angular velocity are below given thresholds. + * + * Thus, every body has five auto-disable parameters: an enabled flag, a idle step + * count, an idle time, and linear/angular velocity thresholds. Newly created bodies + * get these parameters from world. + */ + +/** + * @brief Set the AutoEnableDepth parameter used by the StepFast1 algorithm. + * @ingroup disable + */ void dWorldSetAutoEnableDepthSF1(dWorldID, int autoEnableDepth); -int dWorldGetAutoEnableDepthSF1(dWorldID); -/* Auto-disable functions */ +/** + * @brief Get the AutoEnableDepth parameter used by the StepFast1 algorithm. + * @ingroup disable + */ +int dWorldGetAutoEnableDepthSF1(dWorldID); +/** + * @brief Get auto disable linear threshold for newly created bodies. + * @ingroup disable + * @return the threshold + */ dReal dWorldGetAutoDisableLinearThreshold (dWorldID); + +/** + * @brief Set auto disable linear threshold for newly created bodies. + * @param linear_threshold default is 0.01 + * @ingroup disable + */ void dWorldSetAutoDisableLinearThreshold (dWorldID, dReal linear_threshold); + +/** + * @brief Get auto disable angular threshold for newly created bodies. + * @ingroup disable + * @return the threshold + */ dReal dWorldGetAutoDisableAngularThreshold (dWorldID); -void dWorldSetAutoDisableAngularThreshold (dWorldID, dReal angular_threshold); -int dWorldGetAutoDisableSteps (dWorldID); -void dWorldSetAutoDisableSteps (dWorldID, int steps); + +/** + * @brief Set auto disable angular threshold for newly created bodies. + * @param linear_threshold default is 0.01 + * @ingroup disable + */ +void dWorldSetAutoDisableAngularThreshold (dWorldID, dReal angular_threshold); + +/** + * @brief Get auto disable steps for newly created bodies. + * @ingroup disable + * @return nr of steps + */ +int dWorldGetAutoDisableSteps (dWorldID); + +/** + * @brief Set auto disable steps for newly created bodies. + * @ingroup disable + * @param steps default is 10 + */ +void dWorldSetAutoDisableSteps (dWorldID, int steps); + +/** + * @brief Get auto disable time for newly created bodies. + * @ingroup disable + * @return nr of seconds + */ dReal dWorldGetAutoDisableTime (dWorldID); -void dWorldSetAutoDisableTime (dWorldID, dReal time); -int dWorldGetAutoDisableFlag (dWorldID); -void dWorldSetAutoDisableFlag (dWorldID, int do_auto_disable); +/** + * @brief Set auto disable time for newly created bodies. + * @ingroup disable + * @param time default is 0 seconds + */ +void dWorldSetAutoDisableTime (dWorldID, dReal time); + +/** + * @brief Get auto disable flag for newly created bodies. + * @ingroup disable + * @return 0 or 1 + */ +int dWorldGetAutoDisableFlag (dWorldID); + +/** + * @brief Set auto disable flag for newly created bodies. + * @ingroup disable + * @param do_auto_disable default is false. + */ +void dWorldSetAutoDisableFlag (dWorldID, int do_auto_disable); + + + +/** + * @defgroup bodies Rigid Bodies + * + * A rigid body has various properties from the point of view of the + * simulation. Some properties change over time: + * + * @li Position vector (x,y,z) of the body's point of reference. + * Currently the point of reference must correspond to the body's center of mass. + * @li Linear velocity of the point of reference, a vector (vx,vy,vz). + * @li Orientation of a body, represented by a quaternion (qs,qx,qy,qz) or + * a 3x3 rotation matrix. + * @li Angular velocity vector (wx,wy,wz) which describes how the orientation + * changes over time. + * + * Other body properties are usually constant over time: + * + * @li Mass of the body. + * @li Position of the center of mass with respect to the point of reference. + * In the current implementation the center of mass and the point of + * reference must coincide. + * @li Inertia matrix. This is a 3x3 matrix that describes how the body's mass + * is distributed around the center of mass. Conceptually each body has an + * x-y-z coordinate frame embedded in it that moves and rotates with the body. + * + * The origin of this coordinate frame is the body's point of reference. Some values + * in ODE (vectors, matrices etc) are relative to the body coordinate frame, and others + * are relative to the global coordinate frame. + * + * Note that the shape of a rigid body is not a dynamical property (except insofar as + * it influences the various mass properties). It is only collision detection that cares + * about the detailed shape of the body. + */ + + +/** + * @brief Get auto disable linear threshold. + * @ingroup bodies + * @return the threshold + */ dReal dBodyGetAutoDisableLinearThreshold (dBodyID); + +/** + * @brief Set auto disable linear threshold. + * @ingroup bodies + * @return the threshold + */ void dBodySetAutoDisableLinearThreshold (dBodyID, dReal linear_threshold); + +/** + * @brief Get auto disable angular threshold. + * @ingroup bodies + * @return the threshold + */ dReal dBodyGetAutoDisableAngularThreshold (dBodyID); + +/** + * @brief Set auto disable angular threshold. + * @ingroup bodies + * @return the threshold + */ void dBodySetAutoDisableAngularThreshold (dBodyID, dReal angular_threshold); + +/** + * @brief Get auto disable steps. + * @ingroup bodies + * @return the nr of steps + */ int dBodyGetAutoDisableSteps (dBodyID); + +/** + * @brief Set auto disable steps. + * @ingroup bodies + * @param steps the nr of steps. + */ void dBodySetAutoDisableSteps (dBodyID, int steps); + +/** + * @brief Get auto disable time. + * @ingroup bodies + * @return nr of seconds + */ dReal dBodyGetAutoDisableTime (dBodyID); + +/** + * @brief Set auto disable time. + * @ingroup bodies + * @param time nr of seconds. + */ void dBodySetAutoDisableTime (dBodyID, dReal time); + +/** + * @brief Get auto disable flag. + * @ingroup bodies + * @return 0 or 1 + */ int dBodyGetAutoDisableFlag (dBodyID); + +/** + * @brief Set auto disable flag. + * @ingroup bodies + * @param do_auto_disable 0 or 1 + */ void dBodySetAutoDisableFlag (dBodyID, int do_auto_disable); + +/** + * @brief Set auto disable defaults. + * @remarks + * Set the values for the body to those set as default for the world. + * @ingroup bodies + */ void dBodySetAutoDisableDefaults (dBodyID); -/* bodies */ + +/** + * @brief Create a body in given world. + * @remarks + * Default mass parameters are at position (0,0,0). + * @ingroup bodies + */ dBodyID dBodyCreate (dWorldID); + +/** + * @brief Destroy a body. + * @remarks + * All joints that are attached to this body will be put into limbo: + * i.e. unattached and not affecting the simulation, but they will NOT be + * deleted. + * @ingroup bodies + */ void dBodyDestroy (dBodyID); -void dWorldAddBody (dWorldID,dBodyID); -void dWorldAddJoint (dWorldID,dJointID); -void dWorldRemoveBody (dWorldID,dBodyID); -void dWorldRemoveJoint (dWorldID,dJointID); +void dWorldAddBody (dWorldID,dBodyID); // X-Ray custom probably +void dWorldAddJoint (dWorldID,dJointID); // X-Ray custom probably +void dWorldRemoveBody (dWorldID,dBodyID); // X-Ray custom probably +void dWorldRemoveJoint (dWorldID,dJointID); // X-Ray custom probably + +/** + * @brief Set the body's user-data pointer. + * @ingroup bodies + * @param data arbitraty pointer + */ void dBodySetData (dBodyID, void *data); + +/** + * @brief Get the body's user-data pointer. + * @ingroup bodies + * @return a pointer to the user's data. + */ void *dBodyGetData (dBodyID); +/** + * @brief Set position of a body. + * @remarks + * After setting, the outcome of the simulation is undefined + * if the new configuration is inconsistent with the joints/constraints + * that are present. + * @ingroup bodies + */ void dBodySetPosition (dBodyID, dReal x, dReal y, dReal z); + +/** + * @brief Set the orientation of a body. + * @ingroup bodies + * @remarks + * After setting, the outcome of the simulation is undefined + * if the new configuration is inconsistent with the joints/constraints + * that are present. + */ void dBodySetRotation (dBodyID, const dMatrix3 R); + +/** + * @brief Set the orientation of a body. + * @ingroup bodies + * @remarks + * After setting, the outcome of the simulation is undefined + * if the new configuration is inconsistent with the joints/constraints + * that are present. + */ void dBodySetQuaternion (dBodyID, const dQuaternion q); + +/** + * @brief Set the linear velocity of a body. + * @ingroup bodies + */ void dBodySetLinearVel (dBodyID, dReal x, dReal y, dReal z); + +/** + * @brief Set the angular velocity of a body. + * @ingroup bodies + */ void dBodySetAngularVel (dBodyID, dReal x, dReal y, dReal z); + +/** + * @brief Get the position of a body. + * @ingroup bodies + * @remarks + * When getting, the returned values are pointers to internal data structures, + * so the vectors are valid until any changes are made to the rigid body + * system structure. + */ const dReal * dBodyGetPosition (dBodyID); + +/** + * @brief Get the rotation of a body. + * @ingroup bodies + * @return pointer to a 4x3 rotation matrix. + */ const dReal * dBodyGetRotation (dBodyID); /* ptr to 4x3 rot matrix */ + +/** + * @brief Get the rotation of a body. + * @ingroup bodies + * @return pointer to 4 scalars that represent the quaternion. + */ const dReal * dBodyGetQuaternion (dBodyID); + +/** + * @brief Get the linear velocity of a body. + * @ingroup bodies + */ const dReal * dBodyGetLinearVel (dBodyID); + +/** + * @brief Get the angular velocity of a body. + * @ingroup bodies + */ const dReal * dBodyGetAngularVel (dBodyID); +/** + * @brief Set the mass of a body. + * @ingroup bodies + */ void dBodySetMass (dBodyID, const dMass *mass); + +/** + * @brief Get the mass of a body. + * @ingroup bodies + */ void dBodyGetMass (dBodyID, dMass *mass); +/** + * @brief Add force at centre of mass of body in absolute coordinates. + * @ingroup bodies + */ void dBodyAddForce (dBodyID, dReal fx, dReal fy, dReal fz); + +/** + * @brief Add torque at centre of mass of body in absolute coordinates. + * @ingroup bodies + */ void dBodyAddTorque (dBodyID, dReal fx, dReal fy, dReal fz); + +/** + * @brief Add force at centre of mass of body in coordinates relative to body. + * @ingroup bodies + */ void dBodyAddRelForce (dBodyID, dReal fx, dReal fy, dReal fz); + +/** + * @brief Add torque at centre of mass of body in coordinates relative to body. + * @ingroup bodies + */ void dBodyAddRelTorque (dBodyID, dReal fx, dReal fy, dReal fz); + +/** + * @brief Add force at specified point in body in global coordinates. + * @ingroup bodies + */ void dBodyAddForceAtPos (dBodyID, dReal fx, dReal fy, dReal fz, dReal px, dReal py, dReal pz); +/** + * @brief Add force at specified point in body in local coordinates. + * @ingroup bodies + */ void dBodyAddForceAtRelPos (dBodyID, dReal fx, dReal fy, dReal fz, dReal px, dReal py, dReal pz); +/** + * @brief Add force at specified point in body in global coordinates. + * @ingroup bodies + */ void dBodyAddRelForceAtPos (dBodyID, dReal fx, dReal fy, dReal fz, dReal px, dReal py, dReal pz); +/** + * @brief Add force at specified point in body in local coordinates. + * @ingroup bodies + */ void dBodyAddRelForceAtRelPos (dBodyID, dReal fx, dReal fy, dReal fz, dReal px, dReal py, dReal pz); +/** + * @brief Return the current accumulated force vector. + * @return points to an array of 3 reals. + * @remarks + * The returned values are pointers to internal data structures, so + * the vectors are only valid until any changes are made to the rigid + * body system. + * @ingroup bodies + */ const dReal * dBodyGetForce (dBodyID); + +/** + * @brief Return the current accumulated torque vector. + * @return points to an array of 3 reals. + * @remarks + * The returned values are pointers to internal data structures, so + * the vectors are only valid until any changes are made to the rigid + * body system. + * @ingroup bodies + */ const dReal * dBodyGetTorque (dBodyID); + +/** + * @brief Set the body force accumulation vector. + * @remarks + * This is mostly useful to zero the force and torque for deactivated bodies + * before they are reactivated, in the case where the force-adding functions + * were called on them while they were deactivated. + * @ingroup bodies + */ void dBodySetForce (dBodyID b, dReal x, dReal y, dReal z); + +/** + * @brief Set the body torque accumulation vector. + * @remarks + * This is mostly useful to zero the force and torque for deactivated bodies + * before they are reactivated, in the case where the force-adding functions + * were called on them while they were deactivated. + * @ingroup bodies + */ void dBodySetTorque (dBodyID b, dReal x, dReal y, dReal z); -void dBodyGetRelPointPos (dBodyID, dReal px, dReal py, dReal pz, - dVector3 result); -void dBodyGetRelPointVel (dBodyID, dReal px, dReal py, dReal pz, - dVector3 result); -void dBodyGetPointVel (dBodyID, dReal px, dReal py, dReal pz, - dVector3 result); -void dBodyGetPosRelPoint (dBodyID, dReal px, dReal py, dReal pz, - dVector3 result); -void dBodyVectorToWorld (dBodyID, dReal px, dReal py, dReal pz, - dVector3 result); -void dBodyVectorFromWorld (dBodyID, dReal px, dReal py, dReal pz, - dVector3 result); +/** + * @brief Get world position of a relative point on body. + * @ingroup bodies + * @param result will contain the result. + */ +void dBodyGetRelPointPos +( + dBodyID, dReal px, dReal py, dReal pz, + dVector3 result +); + +/** + * @brief Get velocity vector in global coords of a relative point on body. + * @ingroup bodies + * @param result will contain the result. + */ +void dBodyGetRelPointVel +( + dBodyID, dReal px, dReal py, dReal pz, + dVector3 result +); + +/** + * @brief Get velocity vector in global coords of a globally + * specified point on a body. + * @ingroup bodies + * @param result will contain the result. + */ +void dBodyGetPointVel +( + dBodyID, dReal px, dReal py, dReal pz, + dVector3 result +); + +/** + * @brief takes a point in global coordinates and returns + * the point's position in body-relative coordinates. + * @remarks + * This is the inverse of dBodyGetRelPointPos() + * @ingroup bodies + * @param result will contain the result. + */ +void dBodyGetPosRelPoint +( + dBodyID, dReal px, dReal py, dReal pz, + dVector3 result +); +/** + * @brief Convert from local to world coordinates. + * @ingroup bodies + * @param result will contain the result. + */ +void dBodyVectorToWorld +( + dBodyID, dReal px, dReal py, dReal pz, + dVector3 result +); + +/** + * @brief Convert from world to local coordinates. + * @ingroup bodies + * @param result will contain the result. + */ +void dBodyVectorFromWorld +( + dBodyID, dReal px, dReal py, dReal pz, + dVector3 result +); + +/** + * @brief controls the way a body's orientation is updated at each timestep. + * @ingroup bodies + * @param mode can be 0 or 1: + * \li 0: An ``infinitesimal'' orientation update is used. + * This is fast to compute, but it can occasionally cause inaccuracies + * for bodies that are rotating at high speed, especially when those + * bodies are joined to other bodies. + * This is the default for every new body that is created. + * \li 1: A ``finite'' orientation update is used. + * This is more costly to compute, but will be more accurate for high + * speed rotations. + * @remarks + * Note however that high speed rotations can result in many types of + * error in a simulation, and the finite mode will only fix one of those + * sources of error. + */ void dBodySetFiniteRotationMode (dBodyID, int mode); + +/** + * @brief sets the finite rotation axis for a body. + * @ingroup bodies + * @remarks + * This is axis only has meaning when the finite rotation mode is set + * If this axis is zero (0,0,0), full finite rotations are performed on + * the body. + * If this axis is nonzero, the body is rotated by performing a partial finite + * rotation along the axis direction followed by an infinitesimal rotation + * along an orthogonal direction. + * @remarks + * This can be useful to alleviate certain sources of error caused by quickly + * spinning bodies. For example, if a car wheel is rotating at high speed + * you can call this function with the wheel's hinge axis as the argument to + * try and improve its behavior. + */ void dBodySetFiniteRotationAxis (dBodyID, dReal x, dReal y, dReal z); +/** + * @brief Get the way a body's orientation is updated each timestep. + * @ingroup bodies + * @return the mode 0 (infitesimal) or 1 (finite). + */ int dBodyGetFiniteRotationMode (dBodyID); + +/** + * @brief Get the finite rotation axis. + * @param result will contain the axis. + * @ingroup bodies + */ void dBodyGetFiniteRotationAxis (dBodyID, dVector3 result); +/** + * @brief Get the number of joints that are attached to this body. + * @ingroup bodies + * @return nr of joints + */ int dBodyGetNumJoints (dBodyID b); + +/** + * @brief Return a joint attached to this body, given by index. + * @ingroup bodies + * @param index valid range is 0 to n-1 where n is the value returned by + * dBodyGetNumJoints(). + */ dJointID dBodyGetJoint (dBodyID, int index); +/** + * @brief Manually enable a body. + * @param dBodyID identification of body. + * @ingroup bodies + */ void dBodyEnable (dBodyID); + +/** + * @brief Manually disable a body. + * @ingroup bodies + * @remarks + * A disabled body that is connected through a joint to an enabled body will + * be automatically re-enabled at the next simulation step. + */ void dBodyDisable (dBodyID); + +/** + * @brief Check wether a body is enabled. + * @ingroup bodies + * @return 1 if a body is currently enabled or 0 if it is disabled. + */ int dBodyIsEnabled (dBodyID); +/** + * @brief Set whether the body is influenced by the world's gravity or not. + * @ingroup bodies + * @param mode when nonzero gravity affects this body. + * @remarks + * Newly created bodies are always influenced by the world's gravity. + */ void dBodySetGravityMode (dBodyID b, int mode); + +/** + * @brief Get whether the body is influenced by the world's gravity or not. + * @ingroup bodies + * @return nonzero means gravity affects this body. + */ int dBodyGetGravityMode (dBodyID b); -/* joints */ +/** + * @defgroup joints Joints + * + * In real life a joint is something like a hinge, that is used to connect two + * objects. + * In ODE a joint is very similar: It is a relationship that is enforced between + * two bodies so that they can only have certain positions and orientations + * relative to each other. + * This relationship is called a constraint -- the words joint and + * constraint are often used interchangeably. + * + * A joint has a set of parameters that can be set. These include: + * + * + * \li dParamLoStop Low stop angle or position. Setting this to + * -dInfinity (the default value) turns off the low stop. + * For rotational joints, this stop must be greater than -pi to be + * effective. + * \li dParamHiStop High stop angle or position. Setting this to + * dInfinity (the default value) turns off the high stop. + * For rotational joints, this stop must be less than pi to be + * effective. + * If the high stop is less than the low stop then both stops will + * be ineffective. + * \li dParamVel Desired motor velocity (this will be an angular or + * linear velocity). + * \li dParamFMax The maximum force or torque that the motor will use to + * achieve the desired velocity. + * This must always be greater than or equal to zero. + * Setting this to zero (the default value) turns off the motor. + * \li dParamFudgeFactor The current joint stop/motor implementation has + * a small problem: + * when the joint is at one stop and the motor is set to move it away + * from the stop, too much force may be applied for one time step, + * causing a ``jumping'' motion. + * This fudge factor is used to scale this excess force. + * It should have a value between zero and one (the default value). + * If the jumping motion is too visible in a joint, the value can be + * reduced. + * Making this value too small can prevent the motor from being able to + * move the joint away from a stop. + * \li dParamBounce The bouncyness of the stops. + * This is a restitution parameter in the range 0..1. + * 0 means the stops are not bouncy at all, 1 means maximum bouncyness. + * \li dParamCFM The constraint force mixing (CFM) value used when not + * at a stop. + * \li dParamStopERP The error reduction parameter (ERP) used by the + * stops. + * \li dParamStopCFM The constraint force mixing (CFM) value used by the + * stops. Together with the ERP value this can be used to get spongy or + * soft stops. + * Note that this is intended for unpowered joints, it does not really + * work as expected when a powered joint reaches its limit. + * \li dParamSuspensionERP Suspension error reduction parameter (ERP). + * Currently this is only implemented on the hinge-2 joint. + * \li dParamSuspensionCFM Suspension constraint force mixing (CFM) value. + * Currently this is only implemented on the hinge-2 joint. + * + * If a particular parameter is not implemented by a given joint, setting it + * will have no effect. + * These parameter names can be optionally followed by a digit (2 or 3) + * to indicate the second or third set of parameters, e.g. for the second axis + * in a hinge-2 joint, or the third axis in an AMotor joint. + */ + + +/** + * @brief Create a new joint of the ball type. + * @ingroup joints + * @remarks + * The joint is initially in "limbo" (i.e. it has no effect on the simulation) + * because it does not connect to any bodies. + * @param dJointGroupID set to 0 to allocate the joint normally. + * If it is nonzero the joint is allocated in the given joint group. + */ dJointID dJointCreateBall (dWorldID, dJointGroupID); + +/** + * @brief Create a new joint of the hinge type. + * @ingroup joints + * @param dJointGroupID set to 0 to allocate the joint normally. + * If it is nonzero the joint is allocated in the given joint group. + */ dJointID dJointCreateHinge (dWorldID, dJointGroupID); + +/** + * @brief Create a new joint of the slider type. + * @ingroup joints + * @param dJointGroupID set to 0 to allocate the joint normally. + * If it is nonzero the joint is allocated in the given joint group. + */ dJointID dJointCreateSlider (dWorldID, dJointGroupID); + +/** + * @brief Create a new joint of the contact type. + * @ingroup joints + * @param dJointGroupID set to 0 to allocate the joint normally. + * If it is nonzero the joint is allocated in the given joint group. + */ dJointID dJointCreateContact (dWorldID, dJointGroupID, const dContact *); dJointID dJointCreateContactSpecial (dWorldID, dJointGroupID, const dContact *); + +/** + * @brief Create a new joint of the hinge2 type. + * @ingroup joints + * @param dJointGroupID set to 0 to allocate the joint normally. + * If it is nonzero the joint is allocated in the given joint group. + */ dJointID dJointCreateHinge2 (dWorldID, dJointGroupID); + +/** + * @brief Create a new joint of the universal type. + * @ingroup joints + * @param dJointGroupID set to 0 to allocate the joint normally. + * If it is nonzero the joint is allocated in the given joint group. + */ dJointID dJointCreateUniversal (dWorldID, dJointGroupID); + +/** + * @brief Create a new joint of the fixed type. + * @ingroup joints + * @param dJointGroupID set to 0 to allocate the joint normally. + * If it is nonzero the joint is allocated in the given joint group. + */ dJointID dJointCreateFixed (dWorldID, dJointGroupID); + dJointID dJointCreateNull (dWorldID, dJointGroupID); + +/** + * @brief Create a new joint of the A-motor type. + * @ingroup joints + * @param dJointGroupID set to 0 to allocate the joint normally. + * If it is nonzero the joint is allocated in the given joint group. + */ dJointID dJointCreateAMotor (dWorldID, dJointGroupID); +/** + * @brief Destroy a joint. + * @ingroup joints + * + * disconnects it from its attached bodies and removing it from the world. + * However, if the joint is a member of a group then this function has no + * effect - to destroy that joint the group must be emptied or destroyed. + */ void dJointDestroy (dJointID); + +/** + * @brief Create a joint group + * @ingroup joints + * @param max_size deprecated. Set to 0. + */ dJointGroupID dJointGroupCreate (int max_size); + +/** + * @brief Destroy a joint group. + * @ingroup joints + * + * All joints in the joint group will be destroyed. + */ void dJointGroupDestroy (dJointGroupID); -void dJointGroupEmpty (dJointGroupID); +/** + * @brief Empty a joint group. + * @ingroup joints + * + * All joints in the joint group will be destroyed, + * but the joint group itself will not be destroyed. + */ +void dJointGroupEmpty (dJointGroupID); +/** + * @brief Attach the joint to some new bodies. + * @ingroup joints + * + * If the joint is already attached, it will be detached from the old bodies + * first. + * To attach this joint to only one body, set body1 or body2 to zero - a zero + * body refers to the static environment. + * Setting both bodies to zero puts the joint into "limbo", i.e. it will + * have no effect on the simulation. + * @remarks + * Some joints, like hinge-2 need to be attached to two bodies to work. + */ void dJointAttach (dJointID, dBodyID body1, dBodyID body2); + +/** + * @brief Set the user-data pointer + * @ingroup joints + */ void dJointSetData (dJointID, void *data); + +/** + * @brief Get the user-data pointer + * @ingroup joints + */ void *dJointGetData (dJointID); + +/** + * @brief Get the type of the joint + * @ingroup joints + * @return the type, being one of these: + * \li JointTypeBall + * \li JointTypeHinge + * \li JointTypeSlider + * \li JointTypeContact + * \li JointTypeUniversal + * \li JointTypeHinge2 + * \li JointTypeFixed + * \li JointTypeAMotor + * \li JointTypeLMotor + */ int dJointGetType (dJointID); + +/** + * @brief Return the bodies that this joint connects. + * @ingroup joints + * @param index return the first (0) or second (1) body. + * @remarks + * If one of these returned body IDs is zero, the joint connects the other body + * to the static environment. + * If both body IDs are zero, the joint is in ``limbo'' and has no effect on + * the simulation. + */ dBodyID dJointGetBody (dJointID, int index); +/** + * @brief Sets the datastructure that is to receive the feedback. + * + * The feedback can be used by the user, so that it is known how + * much force an individual joint exerts. + * @ingroup joints + */ void dJointSetFeedback (dJointID, dJointFeedback *); + +/** + * @brief Gets the datastructure that is to receive the feedback. + * @ingroup joints + */ dJointFeedback *dJointGetFeedback (dJointID); +/** + * @brief Set the joint anchor point. + * @ingroup joints + * + * The joint will try to keep this point on each body + * together. The input is specified in world coordinates. + */ void dJointSetBallAnchor (dJointID, dReal x, dReal y, dReal z); +/** + * @brief Set hinge anchor parameter. + * @ingroup joints + */ void dJointSetHingeAnchor (dJointID, dReal x, dReal y, dReal z); + +/** + * @brief Set hinge axis. + * @ingroup joints + */ void dJointSetHingeAxis (dJointID, dReal x, dReal y, dReal z); + +/** + * @brief set joint parameter + * @ingroup joints + */ void dJointSetHingeParam (dJointID, int parameter, dReal value); + +/** + * @brief Applies the torque about the hinge axis. + * + * That is, it applies a torque with specified magnitude in the direction + * of the hinge axis, to body 1, and with the same magnitude but in opposite + * direction to body 2. This function is just a wrapper for dBodyAddTorque()} + * @ingroup joints + */ void dJointAddHingeTorque(dJointID joint, dReal torque); + +/** + * @brief set the joint axis + * @ingroup joints + */ void dJointSetSliderAxis (dJointID, dReal x, dReal y, dReal z); +/** + * @brief set joint parameter + * @ingroup joints + */ void dJointSetSliderParam (dJointID, int parameter, dReal value); + +/** + * @brief Applies the given force in the slider's direction. + * + * That is, it applies a force with specified magnitude, in the direction of + * slider's axis, to body1, and with the same magnitude but opposite + * direction to body2. This function is just a wrapper for dBodyAddForce(). + * @ingroup joints + */ void dJointAddSliderForce(dJointID joint, dReal force); + +/** + * @brief set anchor + * @ingroup joints + */ void dJointSetHinge2Anchor (dJointID, dReal x, dReal y, dReal z); + +/** + * @brief set axis + * @ingroup joints + */ void dJointSetHinge2Axis1 (dJointID, dReal x, dReal y, dReal z); + +/** + * @brief set axis + * @ingroup joints + */ void dJointSetHinge2Axis2 (dJointID, dReal x, dReal y, dReal z); + +/** + * @brief set joint parameter + * @ingroup joints + */ void dJointSetHinge2Param (dJointID, int parameter, dReal value); + +/** + * @brief Applies torque1 about the hinge2's axis 1, torque2 about the + * hinge2's axis 2. + * @remarks This function is just a wrapper for dBodyAddTorque(). + * @ingroup joints + */ void dJointAddHinge2Torques(dJointID joint, dReal torque1, dReal torque2); + +/** + * @brief set anchor + * @ingroup joints + */ void dJointSetUniversalAnchor (dJointID, dReal x, dReal y, dReal z); + +/** + * @brief set axis + * @ingroup joints + */ void dJointSetUniversalAxis1 (dJointID, dReal x, dReal y, dReal z); + +/** + * @brief set axis + * @ingroup joints + */ void dJointSetUniversalAxis2 (dJointID, dReal x, dReal y, dReal z); + +/** + * @brief set joint parameter + * @ingroup joints + */ void dJointSetUniversalParam (dJointID, int parameter, dReal value); + +/** + * @brief Applies torque1 about the universal's axis 1, torque2 about the + * universal's axis 2. + * @remarks This function is just a wrapper for dBodyAddTorque(). + * @ingroup joints + */ void dJointAddUniversalTorques(dJointID joint, dReal torque1, dReal torque2); + +/** + * @brief Call this on the fixed joint after it has been attached to + * remember the current desired relative offset and desired relative + * rotation between the bodies. + * @ingroup joints + */ void dJointSetFixed (dJointID); void dJointSetFixedQuaternionPos (dJointID joint, dQuaternion quaternion, dReal* pos); + +/** + * @brief set the nr of axes + * @param num 0..3 + * @ingroup joints + */ void dJointSetAMotorNumAxes (dJointID, int num); + +/** + * @brief set axis + * @ingroup joints + */ void dJointSetAMotorAxis (dJointID, int anum, int rel, dReal x, dReal y, dReal z); + +/** + * @brief Tell the AMotor what the current angle is along axis anum. + * + * This function should only be called in dAMotorUser mode, because in this + * mode the AMotor has no other way of knowing the joint angles. + * The angle information is needed if stops have been set along the axis, + * but it is not needed for axis motors. + * @ingroup joints + */ void dJointSetAMotorAngle (dJointID, int anum, dReal angle); + +/** + * @brief set joint parameter + * @ingroup joints + */ void dJointSetAMotorParam (dJointID, int parameter, dReal value); + +/** + * @brief set mode + * @ingroup joints + */ void dJointSetAMotorMode (dJointID, int mode); + +/** + * @brief Applies torque0 about the AMotor's axis 0, torque1 about the + * AMotor's axis 1, and torque2 about the AMotor's axis 2. + * @remarks + * If the motor has fewer than three axes, the higher torques are ignored. + * This function is just a wrapper for dBodyAddTorque(). + * @ingroup joints + */ void dJointAddAMotorTorques (dJointID, dReal torque1, dReal torque2, dReal torque3); +/** + * @brief Get the joint anchor point, in world coordinates. + * + * This returns the point on body 1. If the joint is perfectly satisfied, + * this will be the same as the point on body 2. + */ void dJointGetBallAnchor (dJointID, dVector3 result); + +/** + * @brief Get the joint anchor point, in world coordinates. + * + * This returns the point on body 2. You can think of a ball and socket + * joint as trying to keep the result of dJointGetBallAnchor() and + * dJointGetBallAnchor2() the same. If the joint is perfectly satisfied, + * this function will return the same value as dJointGetBallAnchor() to + * within roundoff errors. dJointGetBallAnchor2() can be used, along with + * dJointGetBallAnchor(), to see how far the joint has come apart. + */ void dJointGetBallAnchor2 (dJointID, dVector3 result); + +/** + * @brief Get the hinge anchor point, in world coordinates. + * + * This returns the point on body 1. If the joint is perfectly satisfied, + * this will be the same as the point on body 2. + * @ingroup joints + */ void dJointGetHingeAnchor (dJointID, dVector3 result); + +/** + * @brief Get the joint anchor point, in world coordinates. + * @return The point on body 2. If the joint is perfectly satisfied, + * this will return the same value as dJointGetHingeAnchor(). + * If not, this value will be slightly different. + * This can be used, for example, to see how far the joint has come apart. + * @ingroup joints + */ void dJointGetHingeAnchor2 (dJointID, dVector3 result); + +/** + * @brief get axis + * @ingroup joints + */ void dJointGetHingeAxis (dJointID, dVector3 result); + +/** + * @brief get joint parameter + * @ingroup joints + */ dReal dJointGetHingeParam (dJointID, int parameter); + +/** + * @brief Get the hinge angle. + * + * The angle is measured between the two bodies, or between the body and + * the static environment. + * The angle will be between -pi..pi. + * When the hinge anchor or axis is set, the current position of the attached + * bodies is examined and that position will be the zero angle. + * @ingroup joints + */ dReal dJointGetHingeAngle (dJointID); + +/** + * @brief Get the hinge angle time derivative. + * @ingroup joints + */ dReal dJointGetHingeAngleRate (dJointID); + +/** + * @brief Get the slider linear position (i.e. the slider's extension) + * + * When the axis is set, the current position of the attached bodies is + * examined and that position will be the zero position. + * @ingroup joints + */ dReal dJointGetSliderPosition (dJointID); + +/** + * @brief Get the slider linear position's time derivative. + * @ingroup joints + */ dReal dJointGetSliderPositionRate (dJointID); + +/** + * @brief Get the slider axis + * @ingroup joints + */ void dJointGetSliderAxis (dJointID, dVector3 result); + +/** + * @brief get joint parameter + * @ingroup joints + */ dReal dJointGetSliderParam (dJointID, int parameter); + +/** + * @brief Get the joint anchor point, in world coordinates. + * @return the point on body 1. If the joint is perfectly satisfied, + * this will be the same as the point on body 2. + * @ingroup joints + */ void dJointGetHinge2Anchor (dJointID, dVector3 result); + +/** + * @brief Get the joint anchor point, in world coordinates. + * This returns the point on body 2. If the joint is perfectly satisfied, + * this will return the same value as dJointGetHinge2Anchor. + * If not, this value will be slightly different. + * This can be used, for example, to see how far the joint has come apart. + * @ingroup joints + */ void dJointGetHinge2Anchor2 (dJointID, dVector3 result); + +/** + * @brief Get joint axis + * @ingroup joints + */ void dJointGetHinge2Axis1 (dJointID, dVector3 result); + +/** + * @brief Get joint axis + * @ingroup joints + */ void dJointGetHinge2Axis2 (dJointID, dVector3 result); + +/** + * @brief get joint parameter + * @ingroup joints + */ dReal dJointGetHinge2Param (dJointID, int parameter); + +/** + * @brief Get angle + * @ingroup joints + */ dReal dJointGetHinge2Angle1 (dJointID); + +/** + * @brief Get time derivative of angle + * @ingroup joints + */ dReal dJointGetHinge2Angle1Rate (dJointID); + +/** + * @brief Get time derivative of angle + * @ingroup joints + */ dReal dJointGetHinge2Angle2Rate (dJointID); + +/** + * @brief Get the joint anchor point, in world coordinates. + * @return the point on body 1. If the joint is perfectly satisfied, + * this will be the same as the point on body 2. + * @ingroup joints + */ void dJointGetUniversalAnchor (dJointID, dVector3 result); + +/** + * @brief Get the joint anchor point, in world coordinates. + * @return This returns the point on body 2. + * @remarks + * You can think of the ball and socket part of a universal joint as + * trying to keep the result of dJointGetBallAnchor() and + * dJointGetBallAnchor2() the same. If the joint is + * perfectly satisfied, this function will return the same value + * as dJointGetUniversalAnchor() to within roundoff errors. + * dJointGetUniversalAnchor2() can be used, along with + * dJointGetUniversalAnchor(), to see how far the joint has come apart. + * @ingroup joints + */ void dJointGetUniversalAnchor2 (dJointID, dVector3 result); + +/** + * @brief Get axis + * @ingroup joints + */ void dJointGetUniversalAxis1 (dJointID, dVector3 result); + +/** + * @brief Get axis + * @ingroup joints + */ void dJointGetUniversalAxis2 (dJointID, dVector3 result); + + +/** + * @brief get joint parameter + * @ingroup joints + */ dReal dJointGetUniversalParam (dJointID, int parameter); + +/** + * @brief Get angle + * @ingroup joints + */ dReal dJointGetUniversalAngle1 (dJointID); + +/** + * @brief Get angle + * @ingroup joints + */ dReal dJointGetUniversalAngle2 (dJointID); + +/** + * @brief Get time derivative of angle + * @ingroup joints + */ dReal dJointGetUniversalAngle1Rate (dJointID); + +/** + * @brief Get time derivative of angle + * @ingroup joints + */ dReal dJointGetUniversalAngle2Rate (dJointID); + +/** + * @brief Get the number of angular axes that will be controlled by the + * AMotor. + * @param num can range from 0 (which effectively deactivates the + * joint) to 3. + * This is automatically set to 3 in dAMotorEuler mode. + * @ingroup joints + */ int dJointGetAMotorNumAxes (dJointID); + +/** + * @brief Get the AMotor axes. + * @param anum selects the axis to change (0,1 or 2). + * @param rel Each axis can have one of three ``relative orientation'' modes. + * \li 0: The axis is anchored to the global frame. + * \li 1: The axis is anchored to the first body. + * \li 2: The axis is anchored to the second body. + * @ingroup joints + */ void dJointGetAMotorAxis (dJointID, int anum, dVector3 result); + +/** + * @brief Get axis + * @remarks + * The axis vector is always specified in global coordinates regardless + * of the setting of rel. + * There are two GetAMotorAxis functions, one to return the axis and one to + * return the relative mode. + * + * For dAMotorEuler mode: + * \li Only axes 0 and 2 need to be set. Axis 1 will be determined + automatically at each time step. + * \li Axes 0 and 2 must be perpendicular to each other. + * \li Axis 0 must be anchored to the first body, axis 2 must be anchored + to the second body. + * @ingroup joints + */ int dJointGetAMotorAxisRel (dJointID, int anum); + +/** + * @brief Get the current angle for axis. + * @remarks + * In dAMotorUser mode this is simply the value that was set with + * dJointSetAMotorAngle(). + * In dAMotorEuler mode this is the corresponding euler angle. + * @ingroup joints + */ dReal dJointGetAMotorAngle (dJointID, int anum); + +/** + * @brief Get the current angle rate for axis anum. + * @remarks + * In dAMotorUser mode this is always zero, as not enough information is + * available. + * In dAMotorEuler mode this is the corresponding euler angle rate. + * @ingroup joints + */ dReal dJointGetAMotorAngleRate (dJointID, int anum); + +/** + * @brief get joint parameter + * @ingroup joints + */ dReal dJointGetAMotorParam (dJointID, int parameter); + +/** + * @brief Get the angular motor mode. + * @param mode must be one of the following constants: + * \li dAMotorUser The AMotor axes and joint angle settings are entirely + * controlled by the user. This is the default mode. + * \li dAMotorEuler Euler angles are automatically computed. + * The axis a1 is also automatically computed. + * The AMotor axes must be set correctly when in this mode, + * as described below. + * When this mode is initially set the current relative orientations + * of the bodies will correspond to all euler angles at zero. + * @ingroup joints + */ int dJointGetAMotorMode (dJointID); + +/** + * @brief Utility function + * @return 1 if the two bodies are connected together by + * a joint, otherwise return 0. + * @ingroup joints + */ int dAreConnected (dBodyID, dBodyID); + +/** + * @brief Utility function + * @return 1 if the two bodies are connected together by + * a joint that does not have type @arg{joint_type}, otherwise return 0. + * @param joint_type is a dJointTypeXXX constant. + * This is useful for deciding whether to add contact joints between two bodies: + * if they are already connected by non-contact joints then it may not be + * appropriate to add contacts, however it is okay to add more contact between- + * bodies that already have contacts. + * @ingroup joints + */ int dAreConnectedExcluding (dBodyID, dBodyID, int joint_type); diff --git a/Externals/ode/include/ode/timer.h b/Externals/ode/include/ode/timer.h index dcae5b5141c..7ca462a88bb 100644 --- a/Externals/ode/include/ode/timer.h +++ b/Externals/ode/include/ode/timer.h @@ -47,7 +47,7 @@ double dStopwatchTime (dStopwatch *); /* returns total time in secs */ void dTimerStart (const char *description); /* pass a static string here */ void dTimerNow (const char *description); /* pass a static string here */ -void dTimerEnd(); +void dTimerEnd(void); /* print out a timer report. if `average' is nonzero, print out the average * time for each slot (this is only meaningful if the same start-now-end @@ -61,12 +61,12 @@ void dTimerReport (FILE *fout, int average); /* returns the timer ticks per second implied by the timing hardware or API. * the actual timer resolution may not be this great. */ -double dTimerTicksPerSecond(); +double dTimerTicksPerSecond(void); /* returns an estimate of the actual timer resolution, in seconds. this may * be greater than 1/ticks_per_second. */ -double dTimerResolution(); +double dTimerResolution(void); #ifdef __cplusplus