| collision.h | | collision.h | |
| | | | |
| skipping to change at line 34 | | skipping to change at line 34 | |
| #define _ODE_COLLISION_H_ | | #define _ODE_COLLISION_H_ | |
| | | | |
| #include <ode/common.h> | | #include <ode/common.h> | |
| #include <ode/collision_space.h> | | #include <ode/collision_space.h> | |
| #include <ode/contact.h> | | #include <ode/contact.h> | |
| | | | |
| #ifdef __cplusplus | | #ifdef __cplusplus | |
| extern "C" { | | extern "C" { | |
| #endif | | #endif | |
| | | | |
|
| | | /** | |
| | | * @defgroup collide Collision Detection | |
| | | * | |
| | | * ODE has two main components: a dynamics simulation engine and a collisio | |
| | | n | |
| | | * 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 use | |
| | | r. | |
| | | * 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 */ | | /* general functions */ | |
| | | | |
|
| void dGeomDestroy (dGeomID); | | /** | |
| void dGeomSetData (dGeomID, void *); | | * @brief Destroy a geom, removing it from any space. | |
| void *dGeomGetData (dGeomID); | | * | |
| void dGeomSetBody (dGeomID, dBodyID); | | * Destroy a geom, removing it from any space it is in first. This one | |
| dBodyID dGeomGetBody (dGeomID); | | * function destroys a geom of any type, but to create a geom you must call | |
| void dGeomSetPosition (dGeomID, dReal x, dReal y, dReal z); | | * a creation function for that type. | |
| void dGeomSetRotation (dGeomID, const dMatrix3 R); | | * | |
| void dGeomSetQuaternion (dGeomID, const dQuaternion); | | * When a space is destroyed, if its cleanup mode is 1 (the default) then a | |
| const dReal * dGeomGetPosition (dGeomID); | | ll | |
| const dReal * dGeomGetRotation (dGeomID); | | * the geoms in that space are automatically destroyed as well. | |
| void dGeomGetQuaternion (dGeomID, dQuaternion result); | | * | |
| void dGeomGetAABB (dGeomID, dReal aabb[6]); | | * @param geom the geom to be destroyed. | |
| int dGeomIsSpace (dGeomID); | | * @ingroup collide | |
| dSpaceID dGeomGetSpace (dGeomID); | | */ | |
| int dGeomGetClass (dGeomID); | | ODE_API void dGeomDestroy (dGeomID geom); | |
| void dGeomSetCategoryBits (dGeomID, unsigned long bits); | | | |
| void dGeomSetCollideBits (dGeomID, unsigned long bits); | | /** | |
| unsigned long dGeomGetCategoryBits (dGeomID); | | * @brief Set the user-defined data pointer stored in the geom. | |
| unsigned long dGeomGetCollideBits (dGeomID); | | * | |
| void dGeomEnable (dGeomID); | | * @param geom the geom to hold the data | |
| void dGeomDisable (dGeomID); | | * @param data the data pointer to be stored | |
| int dGeomIsEnabled (dGeomID); | | * @ingroup collide | |
| | | */ | |
| | | ODE_API 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 | |
| | | */ | |
| | | ODE_API 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/rotatio | |
| | | n | |
| | | * 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 | |
| | | */ | |
| | | ODE_API 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 | |
| | | */ | |
| | | ODE_API 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 chan | |
| | | ged. | |
| | | * 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 | |
| | | */ | |
| | | ODE_API 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 chan | |
| | | ged. | |
| | | * 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 | |
| | | */ | |
| | | ODE_API 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 chan | |
| | | ged. | |
| | | * | |
| | | * 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 | |
| | | */ | |
| | | ODE_API 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 | |
| | | */ | |
| | | ODE_API 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 | |
| | | */ | |
| | | ODE_API 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 returne | |
| | | d. | |
| | | * | |
| | | * 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 | |
| | | */ | |
| | | ODE_API 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 geo | |
| | | m. | |
| | | * 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 | |
| | | */ | |
| | | ODE_API 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 | |
| | | */ | |
| | | ODE_API 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 | |
| | | */ | |
| | | ODE_API dSpaceID dGeomGetSpace (dGeomID); | |
| | | | |
| | | /** | |
| | | * @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 | |
| | | */ | |
| | | ODE_API 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 | |
| | | */ | |
| | | ODE_API 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 | |
| | | */ | |
| | | ODE_API 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 | |
| | | */ | |
| | | ODE_API 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 | |
| | | */ | |
| | | ODE_API unsigned long dGeomGetCollideBits (dGeomID); | |
| | | | |
| | | /** | |
| | | * @brief Enable a geom. | |
| | | * | |
| | | * Disabled geoms are completely ignored by dSpaceCollide and dSpaceCollide | |
| | | 2, | |
| | | * 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 | |
| | | */ | |
| | | ODE_API void dGeomEnable (dGeomID geom); | |
| | | | |
| | | /** | |
| | | * @brief Disable a geom. | |
| | | * | |
| | | * Disabled geoms are completely ignored by dSpaceCollide and dSpaceCollide | |
| | | 2, | |
| | | * 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 | |
| | | */ | |
| | | ODE_API void dGeomDisable (dGeomID geom); | |
| | | | |
| | | /** | |
| | | * @brief Check to see if a geom is enabled. | |
| | | * | |
| | | * Disabled geoms are completely ignored by dSpaceCollide and dSpaceCollide | |
| | | 2, | |
| | | * 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 | |
| | | */ | |
| | | ODE_API int dGeomIsEnabled (dGeomID geom); | |
| | | | |
| | | /* ************************************************************************ | |
| | | */ | |
| | | /* geom offset from body */ | |
| | | | |
| | | /** | |
| | | * @brief Set the local offset position of a geom from its body. | |
| | | * | |
| | | * Sets the geom's positional offset in local coordinates. | |
| | | * After this call, the geom will be at a new position determined from the | |
| | | * body's position and the offset. | |
| | | * The geom must be attached to a body. | |
| | | * If the geom did not have an offset, it is automatically created. | |
| | | * | |
| | | * @param geom the geom to set. | |
| | | * @param x the new X coordinate. | |
| | | * @param y the new Y coordinate. | |
| | | * @param z the new Z coordinate. | |
| | | * @ingroup collide | |
| | | */ | |
| | | ODE_API void dGeomSetOffsetPosition (dGeomID geom, dReal x, dReal y, dReal | |
| | | z); | |
| | | | |
| | | /** | |
| | | * @brief Set the local offset rotation matrix of a geom from its body. | |
| | | * | |
| | | * Sets the geom's rotational offset in local coordinates. | |
| | | * After this call, the geom will be at a new position determined from the | |
| | | * body's position and the offset. | |
| | | * The geom must be attached to a body. | |
| | | * If the geom did not have an offset, it is automatically created. | |
| | | * | |
| | | * @param geom the geom to set. | |
| | | * @param R the new rotation matrix. | |
| | | * @ingroup collide | |
| | | */ | |
| | | ODE_API void dGeomSetOffsetRotation (dGeomID geom, const dMatrix3 R); | |
| | | | |
| | | /** | |
| | | * @brief Set the local offset rotation of a geom from its body. | |
| | | * | |
| | | * Sets the geom's rotational offset in local coordinates. | |
| | | * After this call, the geom will be at a new position determined from the | |
| | | * body's position and the offset. | |
| | | * The geom must be attached to a body. | |
| | | * If the geom did not have an offset, it is automatically created. | |
| | | * | |
| | | * @param geom the geom to set. | |
| | | * @param Q the new rotation. | |
| | | * @ingroup collide | |
| | | */ | |
| | | ODE_API void dGeomSetOffsetQuaternion (dGeomID geom, const dQuaternion Q); | |
| | | | |
| | | /** | |
| | | * @brief Set the offset position of a geom from its body. | |
| | | * | |
| | | * Sets the geom's positional offset to move it to the new world | |
| | | * coordinates. | |
| | | * After this call, the geom will be at the world position passed in, | |
| | | * and the offset will be the difference from the current body position. | |
| | | * The geom must be attached to a body. | |
| | | * If the geom did not have an offset, it is automatically created. | |
| | | * | |
| | | * @param geom the geom to set. | |
| | | * @param x the new X coordinate. | |
| | | * @param y the new Y coordinate. | |
| | | * @param z the new Z coordinate. | |
| | | * @ingroup collide | |
| | | */ | |
| | | ODE_API void dGeomSetOffsetWorldPosition (dGeomID geom, dReal x, dReal y, d | |
| | | Real z); | |
| | | | |
| | | /** | |
| | | * @brief Set the offset rotation of a geom from its body. | |
| | | * | |
| | | * Sets the geom's rotational offset to orient it to the new world | |
| | | * rotation matrix. | |
| | | * After this call, the geom will be at the world orientation passed in, | |
| | | * and the offset will be the difference from the current body orientation. | |
| | | * The geom must be attached to a body. | |
| | | * If the geom did not have an offset, it is automatically created. | |
| | | * | |
| | | * @param geom the geom to set. | |
| | | * @param R the new rotation matrix. | |
| | | * @ingroup collide | |
| | | */ | |
| | | ODE_API void dGeomSetOffsetWorldRotation (dGeomID geom, const dMatrix3 R); | |
| | | | |
| | | /** | |
| | | * @brief Set the offset rotation of a geom from its body. | |
| | | * | |
| | | * Sets the geom's rotational offset to orient it to the new world | |
| | | * rotation matrix. | |
| | | * After this call, the geom will be at the world orientation passed in, | |
| | | * and the offset will be the difference from the current body orientation. | |
| | | * The geom must be attached to a body. | |
| | | * If the geom did not have an offset, it is automatically created. | |
| | | * | |
| | | * @param geom the geom to set. | |
| | | * @param Q the new rotation. | |
| | | * @ingroup collide | |
| | | */ | |
| | | ODE_API void dGeomSetOffsetWorldQuaternion (dGeomID geom, const dQuaternion | |
| | | ); | |
| | | | |
| | | /** | |
| | | * @brief Clear any offset from the geom. | |
| | | * | |
| | | * If the geom has an offset, it is eliminated and the geom is | |
| | | * repositioned at the body's position. If the geom has no offset, | |
| | | * this function does nothing. | |
| | | * This is more efficient than calling dGeomSetOffsetPosition(zero) | |
| | | * and dGeomSetOffsetRotation(identiy), because this function actually | |
| | | * eliminates the offset, rather than leaving it as the identity transform. | |
| | | * | |
| | | * @param geom the geom to have its offset destroyed. | |
| | | * @ingroup collide | |
| | | */ | |
| | | ODE_API void dGeomClearOffset(dGeomID geom); | |
| | | | |
| | | /** | |
| | | * @brief Check to see whether the geom has an offset. | |
| | | * | |
| | | * This function will return non-zero if the offset has been created. | |
| | | * Note that there is a difference between a geom with no offset, | |
| | | * and a geom with an offset that is the identity transform. | |
| | | * In the latter case, although the observed behaviour is identical, | |
| | | * there is a unnecessary computation involved because the geom will | |
| | | * be applying the transform whenever it needs to recalculate its world | |
| | | * position. | |
| | | * | |
| | | * @param geom the geom to query. | |
| | | * @returns Non-zero if the geom has an offset, zero otherwise. | |
| | | * @ingroup collide | |
| | | */ | |
| | | ODE_API int dGeomIsOffset(dGeomID geom); | |
| | | | |
| | | /** | |
| | | * @brief Get the offset position vector of a geom. | |
| | | * | |
| | | * Returns the positional offset of the geom in local coordinates. | |
| | | * If the geom has no offset, this function returns the zero vector. | |
| | | * | |
| | | * @param geom the geom to query. | |
| | | * @returns A pointer to the geom's offset 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. | |
| | | * @ingroup collide | |
| | | */ | |
| | | ODE_API const dReal * dGeomGetOffsetPosition (dGeomID geom); | |
| | | | |
| | | /** | |
| | | * @brief Get the offset position vector of a geom. | |
| | | * | |
| | | * Returns the positional offset of the geom in local coordinates. | |
| | | * If the geom has no offset, this function returns the zero vector. | |
| | | * | |
| | | * @param geom the geom to query. | |
| | | * @returns A pointer to the geom's offset 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. | |
| | | * @ingroup collide | |
| | | */ | |
| | | ODE_API const dReal * dGeomGetOffsetRotation (dGeomID geom); | |
| | | | |
| | | /** | |
| | | * @brief Get the offset rotation quaternion of a geom. | |
| | | * | |
| | | * Returns the rotation offset of the geom as a quaternion. | |
| | | * If the geom has no offset, the identity quaternion is returned. | |
| | | * | |
| | | * @param geom the geom to query. | |
| | | * @param result a copy of the rotation quaternion. | |
| | | * @ingroup collide | |
| | | */ | |
| | | ODE_API void dGeomGetOffsetQuaternion (dGeomID geom, dQuaternion result); | |
| | | | |
| /* ************************************************************************
*/ | | /* ************************************************************************
*/ | |
| /* collision detection */ | | /* collision detection */ | |
| | | | |
|
| int dCollide (dGeomID o1, dGeomID o2, int flags, dContactGeom *contact, | | ODE_API int dCollide (dGeomID o1, dGeomID o2, int flags, dContactGeom *cont
act, | |
| int skip); | | int skip); | |
|
| void dSpaceCollide (dSpaceID space, void *data, dNearCallback *callback); | | ODE_API void dSpaceCollide (dSpaceID space, void *data, dNearCallback *call | |
| void dSpaceCollide2 (dGeomID o1, dGeomID o2, void *data, | | back); | |
| | | ODE_API void dSpaceCollide2 (dGeomID o1, dGeomID o2, void *data, | |
| dNearCallback *callback); | | dNearCallback *callback); | |
| | | | |
| /* ************************************************************************
*/ | | /* ************************************************************************
*/ | |
| /* standard classes */ | | /* standard classes */ | |
| | | | |
| /* the maximum number of user classes that are supported */ | | /* the maximum number of user classes that are supported */ | |
| enum { | | enum { | |
| dMaxUserClasses = 4 | | dMaxUserClasses = 4 | |
| }; | | }; | |
| | | | |
| /* class numbers - each geometry object needs a unique number */ | | /* class numbers - each geometry object needs a unique number */ | |
| enum { | | enum { | |
| dSphereClass = 0, | | dSphereClass = 0, | |
| dBoxClass, | | dBoxClass, | |
|
| dCCylinderClass, | | dCapsuleClass, | |
| dCylinderClass, | | dCylinderClass, | |
| dPlaneClass, | | dPlaneClass, | |
| dRayClass, | | dRayClass, | |
|
| | | dConvexClass, | |
| dGeomTransformClass, | | dGeomTransformClass, | |
| dTriMeshClass, | | dTriMeshClass, | |
| | | | |
| dFirstSpaceClass, | | dFirstSpaceClass, | |
| dSimpleSpaceClass = dFirstSpaceClass, | | dSimpleSpaceClass = dFirstSpaceClass, | |
| dHashSpaceClass, | | dHashSpaceClass, | |
| dQuadTreeSpaceClass, | | dQuadTreeSpaceClass, | |
| dLastSpaceClass = dQuadTreeSpaceClass, | | dLastSpaceClass = dQuadTreeSpaceClass, | |
| | | | |
| dFirstUserClass, | | dFirstUserClass, | |
| dLastUserClass = dFirstUserClass + dMaxUserClasses - 1, | | dLastUserClass = dFirstUserClass + dMaxUserClasses - 1, | |
| dGeomNumClasses | | dGeomNumClasses | |
| }; | | }; | |
| | | | |
|
| dGeomID dCreateSphere (dSpaceID space, dReal radius); | | ODE_API dGeomID dCreateSphere (dSpaceID space, dReal radius); | |
| void dGeomSphereSetRadius (dGeomID sphere, dReal radius); | | ODE_API void dGeomSphereSetRadius (dGeomID sphere, dReal radius); | |
| dReal dGeomSphereGetRadius (dGeomID sphere); | | ODE_API dReal dGeomSphereGetRadius (dGeomID sphere); | |
| dReal dGeomSpherePointDepth (dGeomID sphere, dReal x, dReal y, dReal z); | | ODE_API dReal dGeomSpherePointDepth (dGeomID sphere, dReal x, dReal y, dRea | |
| | | l z); | |
| dGeomID dCreateBox (dSpaceID space, dReal lx, dReal ly, dReal lz); | | | |
| void dGeomBoxSetLengths (dGeomID box, dReal lx, dReal ly, dReal lz); | | //--> Convex Functions | |
| void dGeomBoxGetLengths (dGeomID box, dVector3 result); | | ODE_API dGeomID dCreateConvex (dSpaceID space, | |
| dReal dGeomBoxPointDepth (dGeomID box, dReal x, dReal y, dReal z); | | dReal *_planes, | |
| | | unsigned int _planecount, | |
| dGeomID dCreatePlane (dSpaceID space, dReal a, dReal b, dReal c, dReal d); | | dReal *_points, | |
| void dGeomPlaneSetParams (dGeomID plane, dReal a, dReal b, dReal c, dReal d | | unsigned int _pointcount,unsigned int *_polyg | |
| ); | | ons); | |
| void dGeomPlaneGetParams (dGeomID plane, dVector4 result); | | | |
| dReal dGeomPlanePointDepth (dGeomID plane, dReal x, dReal y, dReal z); | | ODE_API void dGeomSetConvex (dGeomID g, | |
| | | dReal *_planes, | |
| dGeomID dCreateCCylinder (dSpaceID space, dReal radius, dReal length); | | unsigned int _count, | |
| void dGeomCCylinderSetParams (dGeomID ccylinder, dReal radius, dReal length | | dReal *_points, | |
| ); | | unsigned int _pointcount,unsigned int *_polygon | |
| void dGeomCCylinderGetParams (dGeomID ccylinder, dReal *radius, dReal *leng | | s); | |
| th); | | //<-- Convex Functions | |
| dReal dGeomCCylinderPointDepth (dGeomID ccylinder, dReal x, dReal y, dReal | | | |
| z); | | ODE_API dGeomID dCreateBox (dSpaceID space, dReal lx, dReal ly, dReal lz); | |
| | | ODE_API void dGeomBoxSetLengths (dGeomID box, dReal lx, dReal ly, dReal lz) | |
| dGeomID dCreateRay (dSpaceID space, dReal length); | | ; | |
| void dGeomRaySetLength (dGeomID ray, dReal length); | | ODE_API void dGeomBoxGetLengths (dGeomID box, dVector3 result); | |
| dReal dGeomRayGetLength (dGeomID ray); | | ODE_API dReal dGeomBoxPointDepth (dGeomID box, dReal x, dReal y, dReal z); | |
| void dGeomRaySet (dGeomID ray, dReal px, dReal py, dReal pz, | | | |
| | | ODE_API dGeomID dCreatePlane (dSpaceID space, dReal a, dReal b, dReal c, dR | |
| | | eal d); | |
| | | ODE_API void dGeomPlaneSetParams (dGeomID plane, dReal a, dReal b, dReal c, | |
| | | dReal d); | |
| | | ODE_API void dGeomPlaneGetParams (dGeomID plane, dVector4 result); | |
| | | ODE_API dReal dGeomPlanePointDepth (dGeomID plane, dReal x, dReal y, dReal | |
| | | z); | |
| | | | |
| | | ODE_API dGeomID dCreateCapsule (dSpaceID space, dReal radius, dReal length) | |
| | | ; | |
| | | ODE_API void dGeomCapsuleSetParams (dGeomID ccylinder, dReal radius, dReal | |
| | | length); | |
| | | ODE_API void dGeomCapsuleGetParams (dGeomID ccylinder, dReal *radius, dReal | |
| | | *length); | |
| | | ODE_API dReal dGeomCapsulePointDepth (dGeomID ccylinder, dReal x, dReal y, | |
| | | dReal z); | |
| | | | |
| | | // For now we want to have a backwards compatible C-API, note: C++ API is n | |
| | | ot. | |
| | | #define dCreateCCylinder dCreateCapsule | |
| | | #define dGeomCCylinderSetParams dGeomCapsuleSetParams | |
| | | #define dGeomCCylinderGetParams dGeomCapsuleGetParams | |
| | | #define dGeomCCylinderPointDepth dGeomCapsulePointDepth | |
| | | #define dCCylinderClass dCapsuleClass | |
| | | | |
| | | ODE_API dGeomID dCreateCylinder (dSpaceID space, dReal radius, dReal length | |
| | | ); | |
| | | ODE_API void dGeomCylinderSetParams (dGeomID cylinder, dReal radius, dReal | |
| | | length); | |
| | | ODE_API void dGeomCylinderGetParams (dGeomID cylinder, dReal *radius, dReal | |
| | | *length); | |
| | | | |
| | | ODE_API dGeomID dCreateRay (dSpaceID space, dReal length); | |
| | | ODE_API void dGeomRaySetLength (dGeomID ray, dReal length); | |
| | | ODE_API dReal dGeomRayGetLength (dGeomID ray); | |
| | | ODE_API void dGeomRaySet (dGeomID ray, dReal px, dReal py, dReal pz, | |
| dReal dx, dReal dy, dReal dz); | | dReal dx, dReal dy, dReal dz); | |
|
| void dGeomRayGet (dGeomID ray, dVector3 start, dVector3 dir); | | ODE_API void dGeomRayGet (dGeomID ray, dVector3 start, dVector3 dir); | |
| | | | |
| /* | | /* | |
| * Set/get ray flags that influence ray collision detection. | | * Set/get ray flags that influence ray collision detection. | |
| * These flags are currently only noticed by the trimesh collider, because | | * These flags are currently only noticed by the trimesh collider, because | |
| * they can make a major differences there. | | * they can make a major differences there. | |
| */ | | */ | |
|
| void dGeomRaySetParams (dGeomID g, int FirstContact, int BackfaceCull); | | ODE_API void dGeomRaySetParams (dGeomID g, int FirstContact, int BackfaceCu | |
| void dGeomRayGetParams (dGeomID g, int *FirstContact, int *BackfaceCull); | | ll); | |
| void dGeomRaySetClosestHit (dGeomID g, int closestHit); | | ODE_API void dGeomRayGetParams (dGeomID g, int *FirstContact, int *Backface | |
| int dGeomRayGetClosestHit (dGeomID g); | | Cull); | |
| | | ODE_API void dGeomRaySetClosestHit (dGeomID g, int closestHit); | |
| | | ODE_API int dGeomRayGetClosestHit (dGeomID g); | |
| | | | |
| #include "collision_trimesh.h" | | #include "collision_trimesh.h" | |
| | | | |
|
| dGeomID dCreateGeomTransform (dSpaceID space); | | ODE_API dGeomID dCreateGeomTransform (dSpaceID space); | |
| void dGeomTransformSetGeom (dGeomID g, dGeomID obj); | | ODE_API void dGeomTransformSetGeom (dGeomID g, dGeomID obj); | |
| dGeomID dGeomTransformGetGeom (dGeomID g); | | ODE_API dGeomID dGeomTransformGetGeom (dGeomID g); | |
| void dGeomTransformSetCleanup (dGeomID g, int mode); | | ODE_API void dGeomTransformSetCleanup (dGeomID g, int mode); | |
| int dGeomTransformGetCleanup (dGeomID g); | | ODE_API int dGeomTransformGetCleanup (dGeomID g); | |
| void dGeomTransformSetInfo (dGeomID g, int mode); | | ODE_API void dGeomTransformSetInfo (dGeomID g, int mode); | |
| int dGeomTransformGetInfo (dGeomID g); | | ODE_API int dGeomTransformGetInfo (dGeomID g); | |
| | | | |
| /* ************************************************************************
*/ | | /* ************************************************************************
*/ | |
| /* utility functions */ | | /* utility functions */ | |
| | | | |
|
| void dClosestLineSegmentPoints (const dVector3 a1, const dVector3 a2, | | ODE_API void dClosestLineSegmentPoints (const dVector3 a1, const dVector3 a
2, | |
| const dVector3 b1, const dVector3 b2, | | const dVector3 b1, const dVector3 b2, | |
| dVector3 cp1, dVector3 cp2); | | dVector3 cp1, dVector3 cp2); | |
| | | | |
|
| int dBoxTouchesBox (const dVector3 _p1, const dMatrix3 R1, | | ODE_API int dBoxTouchesBox (const dVector3 _p1, const dMatrix3 R1, | |
| const dVector3 side1, const dVector3 _p2, | | const dVector3 side1, const dVector3 _p2, | |
| const dMatrix3 R2, const dVector3 side2); | | const dMatrix3 R2, const dVector3 side2); | |
| | | | |
|
| void dInfiniteAABB (dGeomID geom, dReal aabb[6]); | | ODE_API int dBoxBox (const dVector3 p1, const dMatrix3 R1, | |
| void dCloseODE(); | | const dVector3 side1, const dVector3 p2, | |
| | | const dMatrix3 R2, const dVector3 side2, | |
| | | dVector3 normal, dReal *depth, int *return_code, | |
| | | int maxc, dContactGeom *contact, int skip); | |
| | | | |
| | | ODE_API void dInfiniteAABB (dGeomID geom, dReal aabb[6]); | |
| | | ODE_API void dCloseODE(void); | |
| | | | |
| /* ************************************************************************
*/ | | /* ************************************************************************
*/ | |
| /* custom classes */ | | /* custom classes */ | |
| | | | |
| typedef void dGetAABBFn (dGeomID, dReal aabb[6]); | | typedef void dGetAABBFn (dGeomID, dReal aabb[6]); | |
| typedef int dColliderFn (dGeomID o1, dGeomID o2, | | typedef int dColliderFn (dGeomID o1, dGeomID o2, | |
| int flags, dContactGeom *contact, int skip); | | int flags, dContactGeom *contact, int skip); | |
| typedef dColliderFn * dGetColliderFnFn (int num); | | typedef dColliderFn * dGetColliderFnFn (int num); | |
| typedef void dGeomDtorFn (dGeomID o); | | typedef void dGeomDtorFn (dGeomID o); | |
| typedef int dAABBTestFn (dGeomID o1, dGeomID o2, dReal aabb[6]); | | typedef int dAABBTestFn (dGeomID o1, dGeomID o2, dReal aabb[6]); | |
| | | | |
| typedef struct dGeomClass { | | typedef struct dGeomClass { | |
| int bytes; | | int bytes; | |
| dGetColliderFnFn *collider; | | dGetColliderFnFn *collider; | |
| dGetAABBFn *aabb; | | dGetAABBFn *aabb; | |
| dAABBTestFn *aabb_test; | | dAABBTestFn *aabb_test; | |
| dGeomDtorFn *dtor; | | dGeomDtorFn *dtor; | |
| } dGeomClass; | | } dGeomClass; | |
| | | | |
|
| int dCreateGeomClass (const dGeomClass *classptr); | | ODE_API int dCreateGeomClass (const dGeomClass *classptr); | |
| void * dGeomGetClassData (dGeomID); | | ODE_API void * dGeomGetClassData (dGeomID); | |
| dGeomID dCreateGeom (int classnum); | | ODE_API dGeomID dCreateGeom (int classnum); | |
| | | | |
| /* ************************************************************************
*/ | | /* ************************************************************************
*/ | |
| | | | |
| #ifdef __cplusplus | | #ifdef __cplusplus | |
| } | | } | |
| #endif | | #endif | |
| | | | |
| #endif | | #endif | |
| | | | |
End of changes. 14 change blocks. |
| 73 lines changed or deleted | | 614 lines changed or added | |
|
| collision_trimesh.h | | collision_trimesh.h | |
| | | | |
| skipping to change at line 51 | | skipping to change at line 51 | |
| /* | | /* | |
| * Data storage for triangle meshes. | | * Data storage for triangle meshes. | |
| */ | | */ | |
| struct dxTriMeshData; | | struct dxTriMeshData; | |
| typedef struct dxTriMeshData* dTriMeshDataID; | | typedef struct dxTriMeshData* dTriMeshDataID; | |
| | | | |
| /* | | /* | |
| * These dont make much sense now, but they will later when we add more | | * These dont make much sense now, but they will later when we add more | |
| * features. | | * features. | |
| */ | | */ | |
|
| dTriMeshDataID dGeomTriMeshDataCreate(); | | ODE_API dTriMeshDataID dGeomTriMeshDataCreate(void); | |
| void dGeomTriMeshDataDestroy(dTriMeshDataID g); | | ODE_API void dGeomTriMeshDataDestroy(dTriMeshDataID g); | |
| | | | |
| enum { TRIMESH_FACE_NORMALS, TRIMESH_LAST_TRANSFORMATION }; | | enum { TRIMESH_FACE_NORMALS, TRIMESH_LAST_TRANSFORMATION }; | |
|
| void dGeomTriMeshDataSet(dTriMeshDataID g, int data_id, void* data); | | ODE_API void dGeomTriMeshDataSet(dTriMeshDataID g, int data_id, void* in_da | |
| | | ta); | |
| | | ODE_API void* dGeomTriMeshDataGet(dTriMeshDataID g, int data_id); | |
| | | | |
| /* | | /* | |
| * Build TriMesh data with single pricision used in vertex data . | | * Build TriMesh data with single pricision used in vertex data . | |
| */ | | */ | |
|
| void dGeomTriMeshDataBuildSingle(dTriMeshDataID g, | | ODE_API void dGeomTriMeshDataBuildSingle(dTriMeshDataID g, | |
| const void* Vertices, int VertexStride, in
t VertexCount, | | const void* Vertices, int VertexStride, in
t VertexCount, | |
| const void* Indices, int IndexCount, int T
riStride); | | const void* Indices, int IndexCount, int T
riStride); | |
| /* same again with a normals array (used as trimesh-trimesh optimization) *
/ | | /* same again with a normals array (used as trimesh-trimesh optimization) *
/ | |
|
| void dGeomTriMeshDataBuildSingle1(dTriMeshDataID g, | | ODE_API void dGeomTriMeshDataBuildSingle1(dTriMeshDataID g, | |
| const void* Vertices, int VertexStride, i
nt VertexCount, | | const void* Vertices, int VertexStride, i
nt VertexCount, | |
| const void* Indices, int IndexCount, int
TriStride, | | const void* Indices, int IndexCount, int
TriStride, | |
| const void* Normals); | | const void* Normals); | |
| /* | | /* | |
| * Build TriMesh data with double pricision used in vertex data . | | * Build TriMesh data with double pricision used in vertex data . | |
| */ | | */ | |
|
| void dGeomTriMeshDataBuildDouble(dTriMeshDataID g, | | ODE_API void dGeomTriMeshDataBuildDouble(dTriMeshDataID g, | |
| const void* Vertices, int VertexStride, i
nt VertexCount, | | const void* Vertices, int VertexStride, i
nt VertexCount, | |
| const void* Indices, int IndexCount, int T
riStride); | | const void* Indices, int IndexCount, int T
riStride); | |
| /* same again with a normals array (used as trimesh-trimesh optimization) *
/ | | /* same again with a normals array (used as trimesh-trimesh optimization) *
/ | |
|
| void dGeomTriMeshDataBuildDouble1(dTriMeshDataID g, | | ODE_API void dGeomTriMeshDataBuildDouble1(dTriMeshDataID g, | |
| const void* Vertices, int VertexStride,
int VertexCount, | | const void* Vertices, int VertexStride,
int VertexCount, | |
| const void* Indices, int IndexCount, int
TriStride, | | const void* Indices, int IndexCount, int
TriStride, | |
| const void* Normals); | | const void* Normals); | |
| | | | |
| /* | | /* | |
| * Simple build. Single/double precision based on dSINGLE/dDOUBLE! | | * Simple build. Single/double precision based on dSINGLE/dDOUBLE! | |
| */ | | */ | |
|
| void dGeomTriMeshDataBuildSimple(dTriMeshDataID g, | | ODE_API void dGeomTriMeshDataBuildSimple(dTriMeshDataID g, | |
| const dReal* Vertices, int VertexCount, | | const dReal* Vertices, int VertexCount, | |
| const int* Indices, int IndexCount); | | const int* Indices, int IndexCount); | |
| /* same again with a normals array (used as trimesh-trimesh optimization) *
/ | | /* same again with a normals array (used as trimesh-trimesh optimization) *
/ | |
|
| void dGeomTriMeshDataBuildSimple1(dTriMeshDataID g, | | ODE_API void dGeomTriMeshDataBuildSimple1(dTriMeshDataID g, | |
| const dReal* Vertices, int VertexCount, | | const dReal* Vertices, int VertexCount, | |
| const int* Indices, int IndexCount, | | const int* Indices, int IndexCount, | |
| const int* Normals); | | const int* Normals); | |
|
| | | | |
| | | /* Preprocess the trimesh data to remove mark unnecessary edges and vertice | |
| | | s */ | |
| | | ODE_API void dGeomTriMeshDataPreprocess(dTriMeshDataID g); | |
| | | /* Get and set the internal preprocessed trimesh data buffer, for loading a | |
| | | nd saving */ | |
| | | ODE_API void dGeomTriMeshDataGetBuffer(dTriMeshDataID g, unsigned char** bu | |
| | | f, int* bufLen); | |
| | | ODE_API void dGeomTriMeshDataSetBuffer(dTriMeshDataID g, unsigned char* buf | |
| | | ); | |
| | | | |
| /* | | /* | |
| * Per triangle callback. Allows the user to say if he wants a collision wi
th | | * Per triangle callback. Allows the user to say if he wants a collision wi
th | |
| * a particular triangle. | | * a particular triangle. | |
| */ | | */ | |
| typedef int dTriCallback(dGeomID TriMesh, dGeomID RefObject, int TriangleIn
dex); | | typedef int dTriCallback(dGeomID TriMesh, dGeomID RefObject, int TriangleIn
dex); | |
|
| void dGeomTriMeshSetCallback(dGeomID g, dTriCallback* Callback); | | ODE_API void dGeomTriMeshSetCallback(dGeomID g, dTriCallback* Callback); | |
| dTriCallback* dGeomTriMeshGetCallback(dGeomID g); | | ODE_API dTriCallback* dGeomTriMeshGetCallback(dGeomID g); | |
| | | | |
| /* | | /* | |
| * Per object callback. Allows the user to get the list of triangles in 1 | | * Per object callback. Allows the user to get the list of triangles in 1 | |
| * shot. Maybe we should remove this one. | | * shot. Maybe we should remove this one. | |
| */ | | */ | |
| typedef void dTriArrayCallback(dGeomID TriMesh, dGeomID RefObject, const in
t* TriIndices, int TriCount); | | typedef void dTriArrayCallback(dGeomID TriMesh, dGeomID RefObject, const in
t* TriIndices, int TriCount); | |
|
| void dGeomTriMeshSetArrayCallback(dGeomID g, dTriArrayCallback* ArrayCallba | | ODE_API void dGeomTriMeshSetArrayCallback(dGeomID g, dTriArrayCallback* Arr | |
| ck); | | ayCallback); | |
| dTriArrayCallback* dGeomTriMeshGetArrayCallback(dGeomID g); | | ODE_API dTriArrayCallback* dGeomTriMeshGetArrayCallback(dGeomID g); | |
| | | | |
| /* | | /* | |
| * Ray callback. | | * Ray callback. | |
| * Allows the user to say if a ray collides with a triangle on barycentric | | * Allows the user to say if a ray collides with a triangle on barycentric | |
| * coords. The user can for example sample a texture with alpha transparenc
y | | * coords. The user can for example sample a texture with alpha transparenc
y | |
| * to determine if a collision should occur. | | * to determine if a collision should occur. | |
| */ | | */ | |
| typedef int dTriRayCallback(dGeomID TriMesh, dGeomID Ray, int TriangleIndex
, dReal u, dReal v); | | typedef int dTriRayCallback(dGeomID TriMesh, dGeomID Ray, int TriangleIndex
, dReal u, dReal v); | |
|
| void dGeomTriMeshSetRayCallback(dGeomID g, dTriRayCallback* Callback); | | ODE_API void dGeomTriMeshSetRayCallback(dGeomID g, dTriRayCallback* Callbac | |
| dTriRayCallback* dGeomTriMeshGetRayCallback(dGeomID g); | | k); | |
| | | ODE_API dTriRayCallback* dGeomTriMeshGetRayCallback(dGeomID g); | |
| | | | |
| /* | | /* | |
| * Trimesh class | | * Trimesh class | |
| * Construction. Callbacks are optional. | | * Construction. Callbacks are optional. | |
| */ | | */ | |
|
| dGeomID dCreateTriMesh(dSpaceID space, dTriMeshDataID Data, dTriCallback* C
allback, dTriArrayCallback* ArrayCallback, dTriRayCallback* RayCallback); | | ODE_API dGeomID dCreateTriMesh(dSpaceID space, dTriMeshDataID Data, dTriCal
lback* Callback, dTriArrayCallback* ArrayCallback, dTriRayCallback* RayCall
back); | |
| | | | |
|
| void dGeomTriMeshSetData(dGeomID g, dTriMeshDataID Data); | | ODE_API void dGeomTriMeshSetData(dGeomID g, dTriMeshDataID Data); | |
| | | ODE_API dTriMeshDataID dGeomTriMeshGetData(dGeomID g); | |
| | | | |
| // enable/disable/check temporal coherence | | // enable/disable/check temporal coherence | |
|
| void dGeomTriMeshEnableTC(dGeomID g, int geomClass, int enable); | | ODE_API void dGeomTriMeshEnableTC(dGeomID g, int geomClass, int enable); | |
| int dGeomTriMeshIsTCEnabled(dGeomID g, int geomClass); | | ODE_API int dGeomTriMeshIsTCEnabled(dGeomID g, int geomClass); | |
| | | | |
| /* | | /* | |
| * Clears the internal temporal coherence caches. When a geom has its | | * Clears the internal temporal coherence caches. When a geom has its | |
| * collision checked with a trimesh once, data is stored inside the trimesh
. | | * collision checked with a trimesh once, data is stored inside the trimesh
. | |
| * With large worlds with lots of seperate objects this list could get huge
. | | * With large worlds with lots of seperate objects this list could get huge
. | |
| * We should be able to do this automagically. | | * We should be able to do this automagically. | |
| */ | | */ | |
|
| void dGeomTriMeshClearTCCache(dGeomID g); | | ODE_API void dGeomTriMeshClearTCCache(dGeomID g); | |
| | | | |
| /* | | /* | |
| * returns the TriMeshDataID | | * returns the TriMeshDataID | |
| */ | | */ | |
|
| dTriMeshDataID dGeomTriMeshGetTriMeshDataID(dGeomID g); | | ODE_API dTriMeshDataID dGeomTriMeshGetTriMeshDataID(dGeomID g); | |
| | | | |
| /* | | /* | |
| * Gets a triangle. | | * Gets a triangle. | |
| */ | | */ | |
|
| void dGeomTriMeshGetTriangle(dGeomID g, int Index, dVector3* v0, dVector3*
v1, dVector3* v2); | | ODE_API void dGeomTriMeshGetTriangle(dGeomID g, int Index, dVector3* v0, dV
ector3* v1, dVector3* v2); | |
| | | | |
| /* | | /* | |
| * Gets the point on the requested triangle and the given barycentric | | * Gets the point on the requested triangle and the given barycentric | |
| * coordinates. | | * coordinates. | |
| */ | | */ | |
|
| void dGeomTriMeshGetPoint(dGeomID g, int Index, dReal u, dReal v, dVector3
Out); | | ODE_API void dGeomTriMeshGetPoint(dGeomID g, int Index, dReal u, dReal v, d
Vector3 Out); | |
| | | | |
| /* | | /* | |
| | | | |
| This is how the strided data works: | | This is how the strided data works: | |
| | | | |
| struct StridedVertex{ | | struct StridedVertex{ | |
| dVector3 Vertex; | | dVector3 Vertex; | |
| // Userdata | | // Userdata | |
| }; | | }; | |
| int VertexStride = sizeof(StridedVertex); | | int VertexStride = sizeof(StridedVertex); | |
| | | | |
| struct StridedTri{ | | struct StridedTri{ | |
| int Indices[3]; | | int Indices[3]; | |
| // Userdata | | // Userdata | |
| }; | | }; | |
| int TriStride = sizeof(StridedTri); | | int TriStride = sizeof(StridedTri); | |
| | | | |
| */ | | */ | |
| | | | |
|
| | | ODE_API int dGeomTriMeshGetTriangleCount (dGeomID g); | |
| | | | |
| | | ODE_API void dGeomTriMeshDataUpdate(dTriMeshDataID g); | |
| | | | |
| #ifdef __cplusplus | | #ifdef __cplusplus | |
| } | | } | |
| #endif | | #endif | |
| | | | |
| #endif /* _ODE_COLLISION_TRIMESH_H_ */ | | #endif /* _ODE_COLLISION_TRIMESH_H_ */ | |
| | | | |
End of changes. 20 change blocks. |
| 24 lines changed or deleted | | 43 lines changed or added | |
|
| matrix.h | | matrix.h | |
| | | | |
| skipping to change at line 36 | | skipping to change at line 36 | |
| #define _ODE_MATRIX_H_ | | #define _ODE_MATRIX_H_ | |
| | | | |
| #include <ode/common.h> | | #include <ode/common.h> | |
| | | | |
| #ifdef __cplusplus | | #ifdef __cplusplus | |
| extern "C" { | | extern "C" { | |
| #endif | | #endif | |
| | | | |
| /* set a vector/matrix of size n to all zeros, or to a specific value. */ | | /* set a vector/matrix of size n to all zeros, or to a specific value. */ | |
| | | | |
|
| void dSetZero (dReal *a, int n); | | ODE_API void dSetZero (dReal *a, int n); | |
| void dSetValue (dReal *a, int n, dReal value); | | ODE_API void dSetValue (dReal *a, int n, dReal value); | |
| | | | |
| /* get the dot product of two n*1 vectors. if n <= 0 then | | /* get the dot product of two n*1 vectors. if n <= 0 then | |
| * zero will be returned (in which case a and b need not be valid). | | * zero will be returned (in which case a and b need not be valid). | |
| */ | | */ | |
| | | | |
|
| dReal dDot (const dReal *a, const dReal *b, int n); | | ODE_API dReal dDot (const dReal *a, const dReal *b, int n); | |
| | | | |
| /* get the dot products of (a0,b), (a1,b), etc and return them in outsum. | | /* get the dot products of (a0,b), (a1,b), etc and return them in outsum. | |
| * all vectors are n*1. if n <= 0 then zeroes will be returned (in which ca
se | | * all vectors are n*1. if n <= 0 then zeroes will be returned (in which ca
se | |
| * the input vectors need not be valid). this function is somewhat faster | | * the input vectors need not be valid). this function is somewhat faster | |
| * than calling dDot() for all of the combinations separately. | | * than calling dDot() for all of the combinations separately. | |
| */ | | */ | |
| | | | |
| /* NOT INCLUDED in the library for now. | | /* NOT INCLUDED in the library for now. | |
| void dMultidot2 (const dReal *a0, const dReal *a1, | | void dMultidot2 (const dReal *a0, const dReal *a1, | |
| const dReal *b, dReal *outsum, int n); | | const dReal *b, dReal *outsum, int n); | |
| | | | |
| skipping to change at line 65 | | skipping to change at line 65 | |
| | | | |
| /* matrix multiplication. all matrices are stored in standard row format. | | /* matrix multiplication. all matrices are stored in standard row format. | |
| * the digit refers to the argument that is transposed: | | * the digit refers to the argument that is transposed: | |
| * 0: A = B * C (sizes: A:p*r B:p*q C:q*r) | | * 0: A = B * C (sizes: A:p*r B:p*q C:q*r) | |
| * 1: A = B' * C (sizes: A:p*r B:q*p C:q*r) | | * 1: A = B' * C (sizes: A:p*r B:q*p C:q*r) | |
| * 2: A = B * C' (sizes: A:p*r B:p*q C:r*q) | | * 2: A = B * C' (sizes: A:p*r B:p*q C:r*q) | |
| * case 1,2 are equivalent to saying that the operation is A=B*C but | | * case 1,2 are equivalent to saying that the operation is A=B*C but | |
| * B or C are stored in standard column format. | | * B or C are stored in standard column format. | |
| */ | | */ | |
| | | | |
|
| void dMultiply0 (dReal *A, const dReal *B, const dReal *C, int p,int q,int | | ODE_API void dMultiply0 (dReal *A, const dReal *B, const dReal *C, int p,in | |
| r); | | t q,int r); | |
| void dMultiply1 (dReal *A, const dReal *B, const dReal *C, int p,int q,int | | ODE_API void dMultiply1 (dReal *A, const dReal *B, const dReal *C, int p,in | |
| r); | | t q,int r); | |
| void dMultiply2 (dReal *A, const dReal *B, const dReal *C, int p,int q,int | | ODE_API void dMultiply2 (dReal *A, const dReal *B, const dReal *C, int p,in | |
| r); | | t q,int r); | |
| | | | |
| /* do an in-place cholesky decomposition on the lower triangle of the n*n | | /* do an in-place cholesky decomposition on the lower triangle of the n*n | |
| * symmetric matrix A (which is stored by rows). the resulting lower triang
le | | * symmetric matrix A (which is stored by rows). the resulting lower triang
le | |
| * will be such that L*L'=A. return 1 on success and 0 on failure (on failu
re | | * will be such that L*L'=A. return 1 on success and 0 on failure (on failu
re | |
| * the matrix is not positive definite). | | * the matrix is not positive definite). | |
| */ | | */ | |
| | | | |
|
| int dFactorCholesky (dReal *A, int n); | | ODE_API int dFactorCholesky (dReal *A, int n); | |
| | | | |
| /* solve for x: L*L'*x = b, and put the result back into x. | | /* solve for x: L*L'*x = b, and put the result back into x. | |
| * L is size n*n, b is size n*1. only the lower triangle of L is considered
. | | * L is size n*n, b is size n*1. only the lower triangle of L is considered
. | |
| */ | | */ | |
| | | | |
|
| void dSolveCholesky (const dReal *L, dReal *b, int n); | | ODE_API void dSolveCholesky (const dReal *L, dReal *b, int n); | |
| | | | |
| /* compute the inverse of the n*n positive definite matrix A and put it in | | /* compute the inverse of the n*n positive definite matrix A and put it in | |
| * Ainv. this is not especially fast. this returns 1 on success (A was | | * Ainv. this is not especially fast. this returns 1 on success (A was | |
| * positive definite) or 0 on failure (not PD). | | * positive definite) or 0 on failure (not PD). | |
| */ | | */ | |
| | | | |
|
| int dInvertPDMatrix (const dReal *A, dReal *Ainv, int n); | | ODE_API int dInvertPDMatrix (const dReal *A, dReal *Ainv, int n); | |
| | | | |
| /* check whether an n*n matrix A is positive definite, return 1/0 (yes/no). | | /* check whether an n*n matrix A is positive definite, return 1/0 (yes/no). | |
| * positive definite means that x'*A*x > 0 for any x. this performs a | | * positive definite means that x'*A*x > 0 for any x. this performs a | |
| * cholesky decomposition of A. if the decomposition fails then the matrix | | * cholesky decomposition of A. if the decomposition fails then the matrix | |
| * is not positive definite. A is stored by rows. A is not altered. | | * is not positive definite. A is stored by rows. A is not altered. | |
| */ | | */ | |
| | | | |
|
| int dIsPositiveDefinite (const dReal *A, int n); | | ODE_API int dIsPositiveDefinite (const dReal *A, int n); | |
| | | | |
| /* factorize a matrix A into L*D*L', where L is lower triangular with ones
on | | /* factorize a matrix A into L*D*L', where L is lower triangular with ones
on | |
| * the diagonal, and D is diagonal. | | * the diagonal, and D is diagonal. | |
| * A is an n*n matrix stored by rows, with a leading dimension of n rounded | | * A is an n*n matrix stored by rows, with a leading dimension of n rounded | |
| * up to 4. L is written into the strict lower triangle of A (the ones are
not | | * up to 4. L is written into the strict lower triangle of A (the ones are
not | |
| * written) and the reciprocal of the diagonal elements of D are written in
to | | * written) and the reciprocal of the diagonal elements of D are written in
to | |
| * d. | | * d. | |
| */ | | */ | |
|
| void dFactorLDLT (dReal *A, dReal *d, int n, int nskip); | | ODE_API void dFactorLDLT (dReal *A, dReal *d, int n, int nskip); | |
| | | | |
| /* solve L*x=b, where L is n*n lower triangular with ones on the diagonal, | | /* solve L*x=b, where L is n*n lower triangular with ones on the diagonal, | |
| * and x,b are n*1. b is overwritten with x. | | * and x,b are n*1. b is overwritten with x. | |
| * the leading dimension of L is `nskip'. | | * the leading dimension of L is `nskip'. | |
| */ | | */ | |
|
| void dSolveL1 (const dReal *L, dReal *b, int n, int nskip); | | ODE_API void dSolveL1 (const dReal *L, dReal *b, int n, int nskip); | |
| | | | |
| /* solve L'*x=b, where L is n*n lower triangular with ones on the diagonal, | | /* solve L'*x=b, where L is n*n lower triangular with ones on the diagonal, | |
| * and x,b are n*1. b is overwritten with x. | | * and x,b are n*1. b is overwritten with x. | |
| * the leading dimension of L is `nskip'. | | * the leading dimension of L is `nskip'. | |
| */ | | */ | |
|
| void dSolveL1T (const dReal *L, dReal *b, int n, int nskip); | | ODE_API void dSolveL1T (const dReal *L, dReal *b, int n, int nskip); | |
| | | | |
| /* in matlab syntax: a(1:n) = a(1:n) .* d(1:n) */ | | /* in matlab syntax: a(1:n) = a(1:n) .* d(1:n) */ | |
| | | | |
|
| void dVectorScale (dReal *a, const dReal *d, int n); | | ODE_API void dVectorScale (dReal *a, const dReal *d, int n); | |
| | | | |
| /* given `L', a n*n lower triangular matrix with ones on the diagonal, | | /* given `L', a n*n lower triangular matrix with ones on the diagonal, | |
| * and `d', a n*1 vector of the reciprocal diagonal elements of an n*n matr
ix | | * and `d', a n*1 vector of the reciprocal diagonal elements of an n*n matr
ix | |
| * D, solve L*D*L'*x=b where x,b are n*1. x overwrites b. | | * D, solve L*D*L'*x=b where x,b are n*1. x overwrites b. | |
| * the leading dimension of L is `nskip'. | | * the leading dimension of L is `nskip'. | |
| */ | | */ | |
| | | | |
|
| void dSolveLDLT (const dReal *L, const dReal *d, dReal *b, int n, int nskip
); | | ODE_API void dSolveLDLT (const dReal *L, const dReal *d, dReal *b, int n, i
nt nskip); | |
| | | | |
| /* given an L*D*L' factorization of an n*n matrix A, return the updated | | /* given an L*D*L' factorization of an n*n matrix A, return the updated | |
| * factorization L2*D2*L2' of A plus the following "top left" matrix: | | * factorization L2*D2*L2' of A plus the following "top left" matrix: | |
| * | | * | |
| * [ b a' ] <-- b is a[0] | | * [ b a' ] <-- b is a[0] | |
| * [ a 0 ] <-- a is a[1..n-1] | | * [ a 0 ] <-- a is a[1..n-1] | |
| * | | * | |
| * - L has size n*n, its leading dimension is nskip. L is lower triangula
r | | * - L has size n*n, its leading dimension is nskip. L is lower triangula
r | |
| * with ones on the diagonal. only the lower triangle of L is reference
d. | | * with ones on the diagonal. only the lower triangle of L is reference
d. | |
| * - d has size n. d contains the reciprocal diagonal elements of D. | | * - d has size n. d contains the reciprocal diagonal elements of D. | |
| * - a has size n. | | * - a has size n. | |
| * the result is written into L, except that the left column of L and d[0] | | * the result is written into L, except that the left column of L and d[0] | |
| * are not actually modified. see ldltaddTL.m for further comments. | | * are not actually modified. see ldltaddTL.m for further comments. | |
| */ | | */ | |
|
| void dLDLTAddTL (dReal *L, dReal *d, const dReal *a, int n, int nskip); | | ODE_API void dLDLTAddTL (dReal *L, dReal *d, const dReal *a, int n, int nsk
ip); | |
| | | | |
| /* given an L*D*L' factorization of a permuted matrix A, produce a new | | /* given an L*D*L' factorization of a permuted matrix A, produce a new | |
| * factorization for row and column `r' removed. | | * factorization for row and column `r' removed. | |
| * - A has size n1*n1, its leading dimension in nskip. A is symmetric and | | * - A has size n1*n1, its leading dimension in nskip. A is symmetric and | |
| * positive definite. only the lower triangle of A is referenced. | | * positive definite. only the lower triangle of A is referenced. | |
| * A itself may actually be an array of row pointers. | | * A itself may actually be an array of row pointers. | |
| * - L has size n2*n2, its leading dimension in nskip. L is lower triangu
lar | | * - L has size n2*n2, its leading dimension in nskip. L is lower triangu
lar | |
| * with ones on the diagonal. only the lower triangle of L is reference
d. | | * with ones on the diagonal. only the lower triangle of L is reference
d. | |
| * - d has size n2. d contains the reciprocal diagonal elements of D. | | * - d has size n2. d contains the reciprocal diagonal elements of D. | |
| * - p is a permutation vector. it contains n2 indexes into A. each index | | * - p is a permutation vector. it contains n2 indexes into A. each index | |
| * must be in the range 0..n1-1. | | * must be in the range 0..n1-1. | |
| * - r is the row/column of L to remove. | | * - r is the row/column of L to remove. | |
| * the new L will be written within the old L, i.e. will have the same lead
ing | | * the new L will be written within the old L, i.e. will have the same lead
ing | |
| * dimension. the last row and column of L, and the last element of d, are | | * dimension. the last row and column of L, and the last element of d, are | |
| * undefined on exit. | | * undefined on exit. | |
| * | | * | |
| * a fast O(n^2) algorithm is used. see ldltremove.m for further comments. | | * a fast O(n^2) algorithm is used. see ldltremove.m for further comments. | |
| */ | | */ | |
|
| void dLDLTRemove (dReal **A, const int *p, dReal *L, dReal *d, | | ODE_API void dLDLTRemove (dReal **A, const int *p, dReal *L, dReal *d, | |
| int n1, int n2, int r, int nskip); | | int n1, int n2, int r, int nskip); | |
| | | | |
| /* given an n*n matrix A (with leading dimension nskip), remove the r'th ro
w | | /* given an n*n matrix A (with leading dimension nskip), remove the r'th ro
w | |
| * and column by moving elements. the new matrix will have the same leading | | * and column by moving elements. the new matrix will have the same leading | |
| * dimension. the last row and column of A are untouched on exit. | | * dimension. the last row and column of A are untouched on exit. | |
| */ | | */ | |
|
| void dRemoveRowCol (dReal *A, int n, int nskip, int r); | | ODE_API void dRemoveRowCol (dReal *A, int n, int nskip, int r); | |
| | | | |
| #ifdef __cplusplus | | #ifdef __cplusplus | |
| } | | } | |
| #endif | | #endif | |
| | | | |
| #endif | | #endif | |
| | | | |
End of changes. 15 change blocks. |
| 21 lines changed or deleted | | 21 lines changed or added | |
|
| objects.h | | objects.h | |
| | | | |
| skipping to change at line 23 | | skipping to change at line 23 | |
| * (2) The BSD-style license that is included with this library in * | | * (2) The BSD-style license that is included with this library in * | |
| * the file LICENSE-BSD.TXT. * | | * the file LICENSE-BSD.TXT. * | |
| * * | | * * | |
| * This library is distributed in the hope that it will be useful, * | | * This library is distributed in the hope that it will be useful, * | |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of * | | * but WITHOUT ANY WARRANTY; without even the implied warranty of * | |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files * | | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files * | |
| * LICENSE.TXT and LICENSE-BSD.TXT for more details. * | | * LICENSE.TXT and LICENSE-BSD.TXT for more details. * | |
| * * | | * * | |
| *************************************************************************/ | | *************************************************************************/ | |
| | | | |
|
| // object, body, and world structs. | | #ifndef _ODE_OBJECTS_H_ | |
| | | #define _ODE_OBJECTS_H_ | |
| #ifndef _ODE_OBJECT_H_ | | | |
| #define _ODE_OBJECT_H_ | | | |
| | | | |
| #include <ode/common.h> | | #include <ode/common.h> | |
|
| #include <ode/memory.h> | | | |
| #include <ode/mass.h> | | #include <ode/mass.h> | |
|
| #include "array.h" | | #include <ode/contact.h> | |
| | | | |
| | | #ifdef __cplusplus | |
| | | extern "C" { | |
| | | #endif | |
| | | | |
| | | /** | |
| | | * @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. | |
| | | */ | |
| | | | |
| | | /** | |
| | | * @brief Create a new, empty world and return its ID number. | |
| | | * @return an identifier | |
| | | * @ingroup world | |
| | | */ | |
| | | ODE_API 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. | |
| | | */ | |
| | | ODE_API 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 | |
| | | */ | |
| | | ODE_API void dWorldSetGravity (dWorldID, dReal x, dReal y, dReal z); | |
| | | | |
| | | /** | |
| | | * @brief Get the gravity vector for a given world. | |
| | | * @ingroup world | |
| | | */ | |
| | | ODE_API 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. | |
| | | */ | |
| | | ODE_API void dWorldSetERP (dWorldID, dReal erp); | |
| | | | |
| | | /** | |
| | | * @brief Get the error reduction parameter. | |
| | | * @ingroup world | |
| | | * @return ERP value | |
| | | */ | |
| | | ODE_API 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. | |
| | | */ | |
| | | ODE_API void dWorldSetCFM (dWorldID, dReal cfm); | |
| | | | |
| | | /** | |
| | | * @brief Get the constraint force mixing value. | |
| | | * @ingroup world | |
| | | * @return CFM value | |
| | | */ | |
| | | ODE_API 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 constrain | |
| | | t | |
| | | * rows. For large systems this will use a lot of memory and can be very sl | |
| | | ow, | |
| | | * but this is currently the most accurate method. | |
| | | * @ingroup world | |
| | | * @param stepsize The number of seconds that the simulation has to advance | |
| | | . | |
| | | */ | |
| | | ODE_API void dWorldStep (dWorldID, dReal stepsize); | |
| | | | |
| | | /** | |
| | | * @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 conver | |
| | | t | |
| | | * 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. | |
| | | */ | |
| | | ODE_API 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, motor | |
| | | s, | |
| | | * or certain articulated structures. For example, a robot with multiple le | |
| | | gs | |
| | | * 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. | |
| | | */ | |
| | | ODE_API void dWorldQuickStep (dWorldID w, dReal stepsize); | |
| | | | |
| | | /** | |
| | | * @brief Set the number of iterations that the QuickStep method performs p | |
| | | er | |
| | | * 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. | |
| | | */ | |
| | | ODE_API void dWorldSetQuickStepNumIterations (dWorldID, int num); | |
| | | | |
| | | /** | |
| | | * @brief Get the number of iterations that the QuickStep method performs p | |
| | | er | |
| | | * step. | |
| | | * @ingroup world | |
| | | * @return nr of iterations | |
| | | */ | |
| | | ODE_API int dWorldGetQuickStepNumIterations (dWorldID); | |
| | | | |
| | | /** | |
| | | * @brief Set the SOR over-relaxation parameter | |
| | | * @ingroup world | |
| | | * @param over_relaxation value to use by SOR | |
| | | */ | |
| | | ODE_API void dWorldSetQuickStepW (dWorldID, dReal over_relaxation); | |
| | | | |
| | | /** | |
| | | * @brief Get the SOR over-relaxation parameter | |
| | | * @ingroup world | |
| | | * @returns the over-relaxation setting | |
| | | */ | |
| | | ODE_API 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 object | |
| | | s. | |
| | | */ | |
| | | ODE_API void dWorldSetContactMaxCorrectingVel (dWorldID, dReal vel); | |
| | | | |
| | | /** | |
| | | * @brief Get the maximum correcting velocity that contacts are allowed | |
| | | * to generated. | |
| | | * @ingroup world | |
| | | */ | |
| | | ODE_API 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. | |
| | | */ | |
| | | ODE_API void dWorldSetContactSurfaceLayer (dWorldID, dReal depth); | |
| | | | |
| | | /** | |
| | | * @brief Get the depth of the surface layer around all geometry objects. | |
| | | * @ingroup world | |
| | | * @returns the depth | |
| | | */ | |
| | | ODE_API 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 | |
| | | */ | |
| | | ODE_API 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 s | |
| | | tate. | |
| | | * | |
| | | * A disabled body that is connected through a joint to an enabled body wil | |
| | | l be | |
| | | * automatically re-enabled at the next simulation step. | |
| | | * | |
| | | * Disabled bodies do not consume CPU time, therefore to speed up the simul | |
| | | ation | |
| | | * bodies should be disabled when they come to rest. This can be done autom | |
| | | atically | |
| | | * with the auto-disable feature. | |
| | | * | |
| | | * If a body has its auto-disable flag turned on, it will automatically dis | |
| | | able | |
| | | * 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 v | |
| | | elocity | |
| | | * and angular velocity are below given thresholds. | |
| | | * | |
| | | * Thus, every body has five auto-disable parameters: an enabled flag, a id | |
| | | le step | |
| | | * count, an idle time, and linear/angular velocity thresholds. Newly creat | |
| | | ed bodies | |
| | | * get these parameters from world. | |
| | | */ | |
| | | | |
| | | /** | |
| | | * @brief Set the AutoEnableDepth parameter used by the StepFast1 algorithm | |
| | | . | |
| | | * @ingroup disable | |
| | | */ | |
| | | ODE_API void dWorldSetAutoEnableDepthSF1(dWorldID, int autoEnableDepth); | |
| | | | |
| | | /** | |
| | | * @brief Get the AutoEnableDepth parameter used by the StepFast1 algorithm | |
| | | . | |
| | | * @ingroup disable | |
| | | */ | |
| | | ODE_API int dWorldGetAutoEnableDepthSF1(dWorldID); | |
| | | | |
| | | /** | |
| | | * @brief Get auto disable linear threshold for newly created bodies. | |
| | | * @ingroup disable | |
| | | * @return the threshold | |
| | | */ | |
| | | ODE_API dReal dWorldGetAutoDisableLinearThreshold (dWorldID); | |
| | | | |
| | | /** | |
| | | * @brief Set auto disable linear threshold for newly created bodies. | |
| | | * @param linear_threshold default is 0.01 | |
| | | * @ingroup disable | |
| | | */ | |
| | | ODE_API void dWorldSetAutoDisableLinearThreshold (dWorldID, dReal linear_t | |
| | | hreshold); | |
| | | | |
| | | /** | |
| | | * @brief Get auto disable angular threshold for newly created bodies. | |
| | | * @ingroup disable | |
| | | * @return the threshold | |
| | | */ | |
| | | ODE_API dReal dWorldGetAutoDisableAngularThreshold (dWorldID); | |
| | | | |
| | | /** | |
| | | * @brief Set auto disable angular threshold for newly created bodies. | |
| | | * @param linear_threshold default is 0.01 | |
| | | * @ingroup disable | |
| | | */ | |
| | | ODE_API void dWorldSetAutoDisableAngularThreshold (dWorldID, dReal angular_ | |
| | | threshold); | |
| | | | |
| | | /** | |
| | | * @brief Get auto disable steps for newly created bodies. | |
| | | * @ingroup disable | |
| | | * @return nr of steps | |
| | | */ | |
| | | ODE_API int dWorldGetAutoDisableSteps (dWorldID); | |
| | | | |
| | | /** | |
| | | * @brief Set auto disable steps for newly created bodies. | |
| | | * @ingroup disable | |
| | | * @param steps default is 10 | |
| | | */ | |
| | | ODE_API void dWorldSetAutoDisableSteps (dWorldID, int steps); | |
| | | | |
| | | /** | |
| | | * @brief Get auto disable time for newly created bodies. | |
| | | * @ingroup disable | |
| | | * @return nr of seconds | |
| | | */ | |
| | | ODE_API dReal dWorldGetAutoDisableTime (dWorldID); | |
| | | | |
| | | /** | |
| | | * @brief Set auto disable time for newly created bodies. | |
| | | * @ingroup disable | |
| | | * @param time default is 0 seconds | |
| | | */ | |
| | | ODE_API void dWorldSetAutoDisableTime (dWorldID, dReal time); | |
| | | | |
| | | /** | |
| | | * @brief Get auto disable flag for newly created bodies. | |
| | | * @ingroup disable | |
| | | * @return 0 or 1 | |
| | | */ | |
| | | ODE_API int dWorldGetAutoDisableFlag (dWorldID); | |
| | | | |
| | | /** | |
| | | * @brief Set auto disable flag for newly created bodies. | |
| | | * @ingroup disable | |
| | | * @param do_auto_disable default is false. | |
| | | */ | |
| | | ODE_API 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 cent | |
| | | er 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 orientat | |
| | | ion | |
| | | * 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 referen | |
| | | ce. | |
| | | * 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 ha | |
| | | s an | |
| | | * x-y-z coordinate frame embedded in it that moves and rotates with t | |
| | | he body. | |
| | | * | |
| | | * The origin of this coordinate frame is the body's point of reference. So | |
| | | me 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 detecti | |
| | | on that cares | |
| | | * about the detailed shape of the body. | |
| | | */ | |
| | | | |
| | | /** | |
| | | * @brief Get auto disable linear threshold. | |
| | | * @ingroup bodies | |
| | | * @return the threshold | |
| | | */ | |
| | | ODE_API dReal dBodyGetAutoDisableLinearThreshold (dBodyID); | |
| | | | |
| | | /** | |
| | | * @brief Set auto disable linear threshold. | |
| | | * @ingroup bodies | |
| | | * @return the threshold | |
| | | */ | |
| | | ODE_API void dBodySetAutoDisableLinearThreshold (dBodyID, dReal linear_thr | |
| | | eshold); | |
| | | | |
| | | /** | |
| | | * @brief Get auto disable angular threshold. | |
| | | * @ingroup bodies | |
| | | * @return the threshold | |
| | | */ | |
| | | ODE_API dReal dBodyGetAutoDisableAngularThreshold (dBodyID); | |
| | | | |
| | | /** | |
| | | * @brief Set auto disable angular threshold. | |
| | | * @ingroup bodies | |
| | | * @return the threshold | |
| | | */ | |
| | | ODE_API void dBodySetAutoDisableAngularThreshold (dBodyID, dReal angular_t | |
| | | hreshold); | |
| | | | |
| | | /** | |
| | | * @brief Get auto disable steps. | |
| | | * @ingroup bodies | |
| | | * @return the nr of steps | |
| | | */ | |
| | | ODE_API int dBodyGetAutoDisableSteps (dBodyID); | |
| | | | |
| | | /** | |
| | | * @brief Set auto disable steps. | |
| | | * @ingroup bodies | |
| | | * @param steps the nr of steps. | |
| | | */ | |
| | | ODE_API void dBodySetAutoDisableSteps (dBodyID, int steps); | |
| | | | |
| | | /** | |
| | | * @brief Get auto disable time. | |
| | | * @ingroup bodies | |
| | | * @return nr of seconds | |
| | | */ | |
| | | ODE_API dReal dBodyGetAutoDisableTime (dBodyID); | |
| | | | |
| | | /** | |
| | | * @brief Set auto disable time. | |
| | | * @ingroup bodies | |
| | | * @param time nr of seconds. | |
| | | */ | |
| | | ODE_API void dBodySetAutoDisableTime (dBodyID, dReal time); | |
| | | | |
| | | /** | |
| | | * @brief Get auto disable flag. | |
| | | * @ingroup bodies | |
| | | * @return 0 or 1 | |
| | | */ | |
| | | ODE_API int dBodyGetAutoDisableFlag (dBodyID); | |
| | | | |
| | | /** | |
| | | * @brief Set auto disable flag. | |
| | | * @ingroup bodies | |
| | | * @param do_auto_disable 0 or 1 | |
| | | */ | |
| | | ODE_API 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 | |
| | | */ | |
| | | ODE_API void dBodySetAutoDisableDefaults (dBodyID); | |
| | | | |
| | | /** | |
| | | * @brief Create a body in given world. | |
| | | * @remarks | |
| | | * Default mass parameters are at position (0,0,0). | |
| | | * @ingroup bodies | |
| | | */ | |
| | | ODE_API 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 | |
| | | */ | |
| | | ODE_API void dBodyDestroy (dBodyID); | |
| | | | |
| | | /** | |
| | | * @brief Set the body's user-data pointer. | |
| | | * @ingroup bodies | |
| | | * @param data arbitraty pointer | |
| | | */ | |
| | | ODE_API void dBodySetData (dBodyID, void *data); | |
| | | | |
| | | /** | |
| | | * @brief Get the body's user-data pointer. | |
| | | * @ingroup bodies | |
| | | * @return a pointer to the user's data. | |
| | | */ | |
| | | ODE_API 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 | |
| | | */ | |
| | | ODE_API 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. | |
| | | */ | |
| | | ODE_API 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. | |
| | | */ | |
| | | ODE_API void dBodySetQuaternion (dBodyID, const dQuaternion q); | |
| | | | |
| | | /** | |
| | | * @brief Set the linear velocity of a body. | |
| | | * @ingroup bodies | |
| | | */ | |
| | | ODE_API void dBodySetLinearVel (dBodyID, dReal x, dReal y, dReal z); | |
| | | | |
| | | /** | |
| | | * @brief Set the angular velocity of a body. | |
| | | * @ingroup bodies | |
| | | */ | |
| | | ODE_API 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 structur | |
| | | es, | |
| | | * so the vectors are valid until any changes are made to the rigid body | |
| | | * system structure. | |
| | | */ | |
| | | ODE_API const dReal * dBodyGetPosition (dBodyID); | |
| | | | |
| | | /** | |
| | | * @brief Get the rotation of a body. | |
| | | * @ingroup bodies | |
| | | * @return pointer to a 4x3 rotation matrix. | |
| | | */ | |
| | | ODE_API const dReal * dBodyGetRotation (dBodyID); | |
| | | | |
| | | /** | |
| | | * @brief Get the rotation of a body. | |
| | | * @ingroup bodies | |
| | | * @return pointer to 4 scalars that represent the quaternion. | |
| | | */ | |
| | | ODE_API const dReal * dBodyGetQuaternion (dBodyID); | |
| | | | |
| | | /** | |
| | | * @brief Get the linear velocity of a body. | |
| | | * @ingroup bodies | |
| | | */ | |
| | | ODE_API const dReal * dBodyGetLinearVel (dBodyID); | |
| | | | |
| | | /** | |
| | | * @brief Get the angular velocity of a body. | |
| | | * @ingroup bodies | |
| | | */ | |
| | | ODE_API const dReal * dBodyGetAngularVel (dBodyID); | |
| | | | |
| | | /** | |
| | | * @brief Set the mass of a body. | |
| | | * @ingroup bodies | |
| | | */ | |
| | | ODE_API void dBodySetMass (dBodyID, const dMass *mass); | |
| | | | |
| | | /** | |
| | | * @brief Get the mass of a body. | |
| | | * @ingroup bodies | |
| | | */ | |
| | | ODE_API void dBodyGetMass (dBodyID, dMass *mass); | |
| | | | |
| | | /** | |
| | | * @brief Add force at centre of mass of body in absolute coordinates. | |
| | | * @ingroup bodies | |
| | | */ | |
| | | ODE_API void dBodyAddForce (dBodyID, dReal fx, dReal fy, dReal f | |
| | | z); | |
| | | | |
| | | /** | |
| | | * @brief Add torque at centre of mass of body in absolute coordinates. | |
| | | * @ingroup bodies | |
| | | */ | |
| | | ODE_API void dBodyAddTorque (dBodyID, dReal fx, dReal fy, dReal f | |
| | | z); | |
| | | | |
| | | /** | |
| | | * @brief Add force at centre of mass of body in coordinates relative to bo | |
| | | dy. | |
| | | * @ingroup bodies | |
| | | */ | |
| | | ODE_API void dBodyAddRelForce (dBodyID, dReal fx, dReal fy, dReal f | |
| | | z); | |
| | | | |
| | | /** | |
| | | * @brief Add torque at centre of mass of body in coordinates relative to b | |
| | | ody. | |
| | | * @ingroup bodies | |
| | | */ | |
| | | ODE_API void dBodyAddRelTorque (dBodyID, dReal fx, dReal fy, dReal f | |
| | | z); | |
| | | | |
| | | /** | |
| | | * @brief Add force at specified point in body in global coordinates. | |
| | | * @ingroup bodies | |
| | | */ | |
| | | ODE_API void dBodyAddForceAtPos (dBodyID, dReal fx, dReal fy, dReal f | |
| | | z, | |
| | | dReal px, dReal py, dReal pz); | |
| | | /** | |
| | | * @brief Add force at specified point in body in local coordinates. | |
| | | * @ingroup bodies | |
| | | */ | |
| | | ODE_API void dBodyAddForceAtRelPos (dBodyID, dReal fx, dReal fy, dReal f | |
| | | z, | |
| | | dReal px, dReal py, dReal pz); | |
| | | /** | |
| | | * @brief Add force at specified point in body in global coordinates. | |
| | | * @ingroup bodies | |
| | | */ | |
| | | ODE_API void dBodyAddRelForceAtPos (dBodyID, dReal fx, dReal fy, dReal f | |
| | | z, | |
| | | dReal px, dReal py, dReal pz); | |
| | | /** | |
| | | * @brief Add force at specified point in body in local coordinates. | |
| | | * @ingroup bodies | |
| | | */ | |
| | | ODE_API void dBodyAddRelForceAtRelPos (dBodyID, dReal fx, dReal fy, dReal f | |
| | | z, | |
| | | 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 | |
| | | */ | |
| | | ODE_API 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 | |
| | | */ | |
| | | ODE_API const dReal * dBodyGetTorque (dBodyID); | |
| | | | |
| | | /** | |
| | | * @brief Set the body force accumulation vector. | |
| | | * @remarks | |
| | | * This is mostly useful to zero the force and torque for deactivated bodie | |
| | | s | |
| | | * before they are reactivated, in the case where the force-adding function | |
| | | s | |
| | | * were called on them while they were deactivated. | |
| | | * @ingroup bodies | |
| | | */ | |
| | | ODE_API 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 bodie | |
| | | s | |
| | | * before they are reactivated, in the case where the force-adding function | |
| | | s | |
| | | * were called on them while they were deactivated. | |
| | | * @ingroup bodies | |
| | | */ | |
| | | ODE_API void dBodySetTorque (dBodyID b, dReal x, dReal y, dReal z); | |
| | | | |
| | | /** | |
| | | * @brief Get world position of a relative point on body. | |
| | | * @ingroup bodies | |
| | | * @param result will contain the result. | |
| | | */ | |
| | | ODE_API 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. | |
| | | */ | |
| | | ODE_API 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. | |
| | | */ | |
| | | ODE_API 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. | |
| | | */ | |
| | | ODE_API 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. | |
| | | */ | |
| | | ODE_API 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. | |
| | | */ | |
| | | ODE_API 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. | |
| | | */ | |
| | | ODE_API 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 fin | |
| | | ite | |
| | | * 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 quick | |
| | | ly | |
| | | * 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 t | |
| | | o | |
| | | * try and improve its behavior. | |
| | | */ | |
| | | ODE_API 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). | |
| | | */ | |
| | | ODE_API int dBodyGetFiniteRotationMode (dBodyID); | |
| | | | |
| | | /** | |
| | | * @brief Get the finite rotation axis. | |
| | | * @param result will contain the axis. | |
| | | * @ingroup bodies | |
| | | */ | |
| | | ODE_API void dBodyGetFiniteRotationAxis (dBodyID, dVector3 result); | |
| | | | |
| | | /** | |
| | | * @brief Get the number of joints that are attached to this body. | |
| | | * @ingroup bodies | |
| | | * @return nr of joints | |
| | | */ | |
| | | ODE_API 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(). | |
| | | */ | |
| | | ODE_API dJointID dBodyGetJoint (dBodyID, int index); | |
| | | | |
| | | /** | |
| | | * @brief Manually enable a body. | |
| | | * @param dBodyID identification of body. | |
| | | * @ingroup bodies | |
| | | */ | |
| | | ODE_API void dBodyEnable (dBodyID); | |
| | | | |
| | | /** | |
| | | * @brief Manually disable a body. | |
| | | * @ingroup bodies | |
| | | * @remarks | |
| | | * A disabled body that is connected through a joint to an enabled body wil | |
| | | l | |
| | | * be automatically re-enabled at the next simulation step. | |
| | | */ | |
| | | ODE_API 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. | |
| | | */ | |
| | | ODE_API 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. | |
| | | */ | |
| | | ODE_API 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. | |
| | | */ | |
| | | ODE_API int dBodyGetGravityMode (dBodyID b); | |
| | | | |
| | | /** | |
| | | * @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 be | |
| | | tween | |
| | | * 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 i | |
| | | t | |
| | | * 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 a | |
| | | xis | |
| | | * 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 simulati | |
| | | on) | |
| | | * 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. | |
| | | */ | |
| | | ODE_API dJointID dJointCreateBall (dWorldID, dJointGroupID); | |
| | | | |
|
| // some body flags | | /** | |
| | | * @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. | |
| | | */ | |
| | | ODE_API dJointID dJointCreateHinge (dWorldID, dJointGroupID); | |
| | | | |
|
| enum { | | /** | |
| dxBodyFlagFiniteRotation = 1, // use finite rotations | | * @brief Create a new joint of the slider type. | |
| dxBodyFlagFiniteRotationAxis = 2, // use finite rotations only along a | | * @ingroup joints | |
| xis | | * @param dJointGroupID set to 0 to allocate the joint normally. | |
| dxBodyDisabled = 4, // body is disabled | | * If it is nonzero the joint is allocated in the given joint group. | |
| dxBodyNoGravity = 8, // body is not influenced by gravity | | */ | |
| dxBodyAutoDisable = 16 // enable auto-disable on body | | ODE_API dJointID dJointCreateSlider (dWorldID, dJointGroupID); | |
| }; | | | |
| | | /** | |
| // base class that does correct object allocation / deallocation | | * @brief Create a new joint of the contact type. | |
| | | * @ingroup joints | |
| struct dBase { | | * @param dJointGroupID set to 0 to allocate the joint normally. | |
| void *operator new (size_t size) { return dAlloc (size); } | | * If it is nonzero the joint is allocated in the given joint group. | |
| void operator delete (void *ptr, size_t size) { dFree (ptr,size); } | | */ | |
| void *operator new[] (size_t size) { return dAlloc (size); } | | ODE_API dJointID dJointCreateContact (dWorldID, dJointGroupID, const dConta | |
| void operator delete[] (void *ptr, size_t size) { dFree (ptr,size); } | | ct *); | |
| }; | | | |
| | | /** | |
| // base class for bodies and joints | | * @brief Create a new joint of the hinge2 type. | |
| | | * @ingroup joints | |
| struct dObject : public dBase { | | * @param dJointGroupID set to 0 to allocate the joint normally. | |
| dxWorld *world; // world this object is in | | * If it is nonzero the joint is allocated in the given joint group. | |
| dObject *next; // next object of this type in list | | */ | |
| dObject **tome; // pointer to previous object's next ptr | | ODE_API dJointID dJointCreateHinge2 (dWorldID, dJointGroupID); | |
| void *userdata; // user settable data | | | |
| int tag; // used by dynamics algorithms | | /** | |
| }; | | * @brief Create a new joint of the universal type. | |
| | | * @ingroup joints | |
| // auto disable parameters | | * @param dJointGroupID set to 0 to allocate the joint normally. | |
| struct dxAutoDisable { | | * If it is nonzero the joint is allocated in the given joint group. | |
| dReal linear_threshold; // linear (squared) velocity treshold | | */ | |
| dReal angular_threshold; // angular (squared) velocity treshold | | ODE_API dJointID dJointCreateUniversal (dWorldID, dJointGroupID); | |
| dReal idle_time; // time the body needs to be idle to auto-di | | | |
| sable it | | /** | |
| int idle_steps; // steps the body needs to be idle to auto-d | | * @brief Create a new joint of the fixed type. | |
| isable it | | * @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. | |
| // quick-step parameters | | */ | |
| struct dxQuickStepParameters { | | ODE_API dJointID dJointCreateFixed (dWorldID, dJointGroupID); | |
| int num_iterations; // number of SOR iterations to perform | | | |
| dReal w; // the SOR over-relaxation parameter | | ODE_API dJointID dJointCreateNull (dWorldID, dJointGroupID); | |
| }; | | | |
| | | /** | |
| // contact generation parameters | | * @brief Create a new joint of the A-motor type. | |
| struct dxContactParameters { | | * @ingroup joints | |
| dReal max_vel; // maximum correcting velocity | | * @param dJointGroupID set to 0 to allocate the joint normally. | |
| dReal min_depth; // thickness of 'surface layer' | | * If it is nonzero the joint is allocated in the given joint group. | |
| }; | | */ | |
| | | ODE_API dJointID dJointCreateAMotor (dWorldID, dJointGroupID); | |
| struct dxBody : public dObject { | | | |
| dxJointNode *firstjoint; // list of attached joints | | /** | |
| int flags; // some dxBodyFlagXXX flags | | * @brief Create a new joint of the L-motor type. | |
| dGeomID geom; // first collision geom associated w | | * @ingroup joints | |
| ith body | | * @param dJointGroupID set to 0 to allocate the joint normally. | |
| dMass mass; // mass parameters about POR | | * If it is nonzero the joint is allocated in the given joint group. | |
| dMatrix3 invI; // inverse of mass.I | | */ | |
| dReal invMass; // 1 / mass.mass | | ODE_API dJointID dJointCreateLMotor (dWorldID, dJointGroupID); | |
| dVector3 pos; // position of POR (point of referen | | | |
| ce) | | /** | |
| dQuaternion q; // orientation quaternion | | * @brief Destroy a joint. | |
| dMatrix3 R; // rotation matrix, always corresponds to q | | * @ingroup joints | |
| dVector3 lvel,avel; // linear and angular velocity of POR | | * | |
| dVector3 facc,tacc; // force and torque accumulators | | * disconnects it from its attached bodies and removing it from the world. | |
| dVector3 finite_rot_axis; // finite rotation axis, unit length or 0=no | | * However, if the joint is a member of a group then this function has no | |
| ne | | * effect - to destroy that joint the group must be emptied or destroyed. | |
| | | */ | |
| // auto-disable information | | ODE_API void dJointDestroy (dJointID); | |
| dxAutoDisable adis; // auto-disable parameters | | | |
| dReal adis_timeleft; // time left to be idle | | /** | |
| int adis_stepsleft; // steps left to be idle | | * @brief Create a joint group | |
| }; | | * @ingroup joints | |
| | | * @param max_size deprecated. Set to 0. | |
| struct dxWorld : public dBase { | | */ | |
| dxBody *firstbody; // body linked list | | ODE_API dJointGroupID dJointGroupCreate (int max_size); | |
| dxJoint *firstjoint; // joint linked list | | | |
| int nb,nj; // number of bodies and joints in lists | | /** | |
| dVector3 gravity; // gravity vector (m/s/s) | | * @brief Destroy a joint group. | |
| dReal global_erp; // global error reduction parameter | | * @ingroup joints | |
| dReal global_cfm; // global costraint force mixing parameter | | * | |
| dxAutoDisable adis; // auto-disable parameters | | * All joints in the joint group will be destroyed. | |
| int adis_flag; // auto-disable flag for new bodies | | */ | |
| dxQuickStepParameters qs; | | ODE_API void dJointGroupDestroy (dJointGroupID); | |
| dxContactParameters contactp; | | | |
| }; | | /** | |
| | | * @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. | |
| | | */ | |
| | | ODE_API 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 bodie | |
| | | s | |
| | | * first. | |
| | | * To attach this joint to only one body, set body1 or body2 to zero - a ze | |
| | | ro | |
| | | * 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. | |
| | | */ | |
| | | ODE_API void dJointAttach (dJointID, dBodyID body1, dBodyID body2); | |
| | | | |
| | | /** | |
| | | * @brief Set the user-data pointer | |
| | | * @ingroup joints | |
| | | */ | |
| | | ODE_API void dJointSetData (dJointID, void *data); | |
| | | | |
| | | /** | |
| | | * @brief Get the user-data pointer | |
| | | * @ingroup joints | |
| | | */ | |
| | | ODE_API 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 | |
| | | */ | |
| | | ODE_API 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 o | |
| | | n | |
| | | * the simulation. | |
| | | */ | |
| | | ODE_API 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 | |
| | | */ | |
| | | ODE_API void dJointSetFeedback (dJointID, dJointFeedback *); | |
| | | | |
| | | /** | |
| | | * @brief Gets the datastructure that is to receive the feedback. | |
| | | * @ingroup joints | |
| | | */ | |
| | | ODE_API 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. | |
| | | */ | |
| | | ODE_API void dJointSetBallAnchor (dJointID, dReal x, dReal y, dReal z); | |
| | | | |
| | | /** | |
| | | * @brief Set the joint anchor point. | |
| | | * @ingroup joints | |
| | | */ | |
| | | ODE_API void dJointSetBallAnchor2 (dJointID, dReal x, dReal y, dReal z); | |
| | | | |
| | | /** | |
| | | * @brief Set hinge anchor parameter. | |
| | | * @ingroup joints | |
| | | */ | |
| | | ODE_API void dJointSetHingeAnchor (dJointID, dReal x, dReal y, dReal z); | |
| | | | |
| | | ODE_API void dJointSetHingeAnchorDelta (dJointID, dReal x, dReal y, dReal z | |
| | | , dReal ax, dReal ay, dReal az); | |
| | | | |
| | | /** | |
| | | * @brief Set hinge axis. | |
| | | * @ingroup joints | |
| | | */ | |
| | | ODE_API void dJointSetHingeAxis (dJointID, dReal x, dReal y, dReal z); | |
| | | | |
| | | /** | |
| | | * @brief set joint parameter | |
| | | * @ingroup joints | |
| | | */ | |
| | | ODE_API 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 opposit | |
| | | e | |
| | | * direction to body 2. This function is just a wrapper for dBodyAddTorque( | |
| | | )} | |
| | | * @ingroup joints | |
| | | */ | |
| | | ODE_API void dJointAddHingeTorque(dJointID joint, dReal torque); | |
| | | | |
| | | /** | |
| | | * @brief set the joint axis | |
| | | * @ingroup joints | |
| | | */ | |
| | | ODE_API void dJointSetSliderAxis (dJointID, dReal x, dReal y, dReal z); | |
| | | | |
| | | /** | |
| | | * @ingroup joints | |
| | | */ | |
| | | ODE_API void dJointSetSliderAxisDelta (dJointID, dReal x, dReal y, dReal z, | |
| | | dReal ax, dReal ay, dReal az); | |
| | | | |
| | | /** | |
| | | * @brief set joint parameter | |
| | | * @ingroup joints | |
| | | */ | |
| | | ODE_API 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 o | |
| | | f | |
| | | * 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 | |
| | | */ | |
| | | ODE_API void dJointAddSliderForce(dJointID joint, dReal force); | |
| | | | |
| | | /** | |
| | | * @brief set anchor | |
| | | * @ingroup joints | |
| | | */ | |
| | | ODE_API void dJointSetHinge2Anchor (dJointID, dReal x, dReal y, dReal z); | |
| | | | |
| | | /** | |
| | | * @brief set axis | |
| | | * @ingroup joints | |
| | | */ | |
| | | ODE_API void dJointSetHinge2Axis1 (dJointID, dReal x, dReal y, dReal z); | |
| | | | |
| | | /** | |
| | | * @brief set axis | |
| | | * @ingroup joints | |
| | | */ | |
| | | ODE_API void dJointSetHinge2Axis2 (dJointID, dReal x, dReal y, dReal z); | |
| | | | |
| | | /** | |
| | | * @brief set joint parameter | |
| | | * @ingroup joints | |
| | | */ | |
| | | ODE_API 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 | |
| | | */ | |
| | | ODE_API void dJointAddHinge2Torques(dJointID joint, dReal torque1, dReal to | |
| | | rque2); | |
| | | | |
| | | /** | |
| | | * @brief set anchor | |
| | | * @ingroup joints | |
| | | */ | |
| | | ODE_API void dJointSetUniversalAnchor (dJointID, dReal x, dReal y, dReal z) | |
| | | ; | |
| | | | |
| | | /** | |
| | | * @brief set axis | |
| | | * @ingroup joints | |
| | | */ | |
| | | ODE_API void dJointSetUniversalAxis1 (dJointID, dReal x, dReal y, dReal z); | |
| | | | |
| | | /** | |
| | | * @brief set axis | |
| | | * @ingroup joints | |
| | | */ | |
| | | ODE_API void dJointSetUniversalAxis2 (dJointID, dReal x, dReal y, dReal z); | |
| | | | |
| | | /** | |
| | | * @brief set joint parameter | |
| | | * @ingroup joints | |
| | | */ | |
| | | ODE_API 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 | |
| | | */ | |
| | | ODE_API 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 | |
| | | */ | |
| | | ODE_API void dJointSetFixed (dJointID); | |
| | | | |
| | | /** | |
| | | * @brief set the nr of axes | |
| | | * @param num 0..3 | |
| | | * @ingroup joints | |
| | | */ | |
| | | ODE_API void dJointSetAMotorNumAxes (dJointID, int num); | |
| | | | |
| | | /** | |
| | | * @brief set axis | |
| | | * @ingroup joints | |
| | | */ | |
| | | ODE_API 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 | |
| | | */ | |
| | | ODE_API void dJointSetAMotorAngle (dJointID, int anum, dReal angle); | |
| | | | |
| | | /** | |
| | | * @brief set joint parameter | |
| | | * @ingroup joints | |
| | | */ | |
| | | ODE_API void dJointSetAMotorParam (dJointID, int parameter, dReal value); | |
| | | | |
| | | /** | |
| | | * @brief set mode | |
| | | * @ingroup joints | |
| | | */ | |
| | | ODE_API 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 | |
| | | */ | |
| | | ODE_API void dJointAddAMotorTorques (dJointID, dReal torque1, dReal torque2 | |
| | | , dReal torque3); | |
| | | | |
| | | /** | |
| | | * @brief Set the number of axes that will be controlled by the LMotor. | |
| | | * @param num can range from 0 (which effectively deactivates the joint) to | |
| | | 3. | |
| | | * @ingroup joints | |
| | | */ | |
| | | ODE_API void dJointSetLMotorNumAxes (dJointID, int num); | |
| | | | |
| | | /** | |
| | | * @brief Set 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'' mode | |
| | | s | |
| | | * \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. | |
| | | * @remarks The axis vector is always specified in global coordinates | |
| | | * regardless of the setting of rel. | |
| | | * @ingroup joints | |
| | | */ | |
| | | ODE_API void dJointSetLMotorAxis (dJointID, int anum, int rel, dReal x, dRe | |
| | | al y, dReal z); | |
| | | | |
| | | /** | |
| | | * @brief set joint parameter | |
| | | * @ingroup joints | |
| | | */ | |
| | | ODE_API void dJointSetLMotorParam (dJointID, int parameter, dReal value); | |
| | | | |
| | | /** | |
| | | * @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. | |
| | | */ | |
| | | ODE_API 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. | |
| | | */ | |
| | | ODE_API 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 | |
| | | */ | |
| | | ODE_API 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 | |
| | | */ | |
| | | ODE_API void dJointGetHingeAnchor2 (dJointID, dVector3 result); | |
| | | | |
| | | /** | |
| | | * @brief get axis | |
| | | * @ingroup joints | |
| | | */ | |
| | | ODE_API void dJointGetHingeAxis (dJointID, dVector3 result); | |
| | | | |
| | | /** | |
| | | * @brief get joint parameter | |
| | | * @ingroup joints | |
| | | */ | |
| | | ODE_API 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 attach | |
| | | ed | |
| | | * bodies is examined and that position will be the zero angle. | |
| | | * @ingroup joints | |
| | | */ | |
| | | ODE_API dReal dJointGetHingeAngle (dJointID); | |
| | | | |
| | | /** | |
| | | * @brief Get the hinge angle time derivative. | |
| | | * @ingroup joints | |
| | | */ | |
| | | ODE_API 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 | |
| | | */ | |
| | | ODE_API dReal dJointGetSliderPosition (dJointID); | |
| | | | |
| | | /** | |
| | | * @brief Get the slider linear position's time derivative. | |
| | | * @ingroup joints | |
| | | */ | |
| | | ODE_API dReal dJointGetSliderPositionRate (dJointID); | |
| | | | |
| | | /** | |
| | | * @brief Get the slider axis | |
| | | * @ingroup joints | |
| | | */ | |
| | | ODE_API void dJointGetSliderAxis (dJointID, dVector3 result); | |
| | | | |
| | | /** | |
| | | * @brief get joint parameter | |
| | | * @ingroup joints | |
| | | */ | |
| | | ODE_API 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 | |
| | | */ | |
| | | ODE_API 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 | |
| | | */ | |
| | | ODE_API void dJointGetHinge2Anchor2 (dJointID, dVector3 result); | |
| | | | |
| | | /** | |
| | | * @brief Get joint axis | |
| | | * @ingroup joints | |
| | | */ | |
| | | ODE_API void dJointGetHinge2Axis1 (dJointID, dVector3 result); | |
| | | | |
| | | /** | |
| | | * @brief Get joint axis | |
| | | * @ingroup joints | |
| | | */ | |
| | | ODE_API void dJointGetHinge2Axis2 (dJointID, dVector3 result); | |
| | | | |
| | | /** | |
| | | * @brief get joint parameter | |
| | | * @ingroup joints | |
| | | */ | |
| | | ODE_API dReal dJointGetHinge2Param (dJointID, int parameter); | |
| | | | |
| | | /** | |
| | | * @brief Get angle | |
| | | * @ingroup joints | |
| | | */ | |
| | | ODE_API dReal dJointGetHinge2Angle1 (dJointID); | |
| | | | |
| | | /** | |
| | | * @brief Get time derivative of angle | |
| | | * @ingroup joints | |
| | | */ | |
| | | ODE_API dReal dJointGetHinge2Angle1Rate (dJointID); | |
| | | | |
| | | /** | |
| | | * @brief Get time derivative of angle | |
| | | * @ingroup joints | |
| | | */ | |
| | | ODE_API 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 | |
| | | */ | |
| | | ODE_API 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 | |
| | | */ | |
| | | ODE_API void dJointGetUniversalAnchor2 (dJointID, dVector3 result); | |
| | | | |
| | | /** | |
| | | * @brief Get axis | |
| | | * @ingroup joints | |
| | | */ | |
| | | ODE_API void dJointGetUniversalAxis1 (dJointID, dVector3 result); | |
| | | | |
| | | /** | |
| | | * @brief Get axis | |
| | | * @ingroup joints | |
| | | */ | |
| | | ODE_API void dJointGetUniversalAxis2 (dJointID, dVector3 result); | |
| | | | |
| | | /** | |
| | | * @brief get joint parameter | |
| | | * @ingroup joints | |
| | | */ | |
| | | ODE_API dReal dJointGetUniversalParam (dJointID, int parameter); | |
| | | | |
| | | /** | |
| | | * @brief Get angle | |
| | | * @ingroup joints | |
| | | */ | |
| | | ODE_API dReal dJointGetUniversalAngle1 (dJointID); | |
| | | | |
| | | /** | |
| | | * @brief Get angle | |
| | | * @ingroup joints | |
| | | */ | |
| | | ODE_API dReal dJointGetUniversalAngle2 (dJointID); | |
| | | | |
| | | /** | |
| | | * @brief Get time derivative of angle | |
| | | * @ingroup joints | |
| | | */ | |
| | | ODE_API dReal dJointGetUniversalAngle1Rate (dJointID); | |
| | | | |
| | | /** | |
| | | * @brief Get time derivative of angle | |
| | | * @ingroup joints | |
| | | */ | |
| | | ODE_API 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 | |
| | | */ | |
| | | ODE_API 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'' mode | |
| | | s. | |
| | | * \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 | |
| | | */ | |
| | | ODE_API 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 | |
| | | */ | |
| | | ODE_API 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 | |
| | | */ | |
| | | ODE_API 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 | |
| | | */ | |
| | | ODE_API dReal dJointGetAMotorAngleRate (dJointID, int anum); | |
| | | | |
| | | /** | |
| | | * @brief get joint parameter | |
| | | * @ingroup joints | |
| | | */ | |
| | | ODE_API 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 | |
| | | */ | |
| | | ODE_API int dJointGetAMotorMode (dJointID); | |
| | | | |
| | | /** | |
| | | * @brief Get nr of axes. | |
| | | * @ingroup joints | |
| | | */ | |
| | | ODE_API int dJointGetLMotorNumAxes (dJointID); | |
| | | | |
| | | /** | |
| | | * @brief Get axis. | |
| | | * @ingroup joints | |
| | | */ | |
| | | ODE_API void dJointGetLMotorAxis (dJointID, int anum, dVector3 result); | |
| | | | |
| | | /** | |
| | | * @brief get joint parameter | |
| | | * @ingroup joints | |
| | | */ | |
| | | ODE_API dReal dJointGetLMotorParam (dJointID, int parameter); | |
| | | | |
| | | /** | |
| | | * @ingroup joints | |
| | | */ | |
| | | ODE_API dJointID dConnectingJoint (dBodyID, dBodyID); | |
| | | | |
| | | /** | |
| | | * @ingroup joints | |
| | | */ | |
| | | ODE_API int dConnectingJointList (dBodyID, dBodyID, dJointID*); | |
| | | | |
| | | /** | |
| | | * @brief Utility function | |
| | | * @return 1 if the two bodies are connected together by | |
| | | * a joint, otherwise return 0. | |
| | | * @ingroup joints | |
| | | */ | |
| | | ODE_API 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 bo | |
| | | dies: | |
| | | * 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 betw | |
| | | een- | |
| | | * bodies that already have contacts. | |
| | | * @ingroup joints | |
| | | */ | |
| | | ODE_API int dAreConnectedExcluding (dBodyID, dBodyID, int joint_type); | |
| | | | |
| | | #ifdef __cplusplus | |
| | | } | |
| | | #endif | |
| | | | |
| #endif | | #endif | |
| | | | |
End of changes. 5 change blocks. |
| 92 lines changed or deleted | | 1731 lines changed or added | |
|
| odemath.h | | odemath.h | |
| | | | |
| skipping to change at line 41 | | skipping to change at line 41 | |
| #define PURE_INLINE inline | | #define PURE_INLINE inline | |
| #endif | | #endif | |
| | | | |
| /* | | /* | |
| * macro to access elements i,j in an NxM matrix A, independent of the | | * macro to access elements i,j in an NxM matrix A, independent of the | |
| * matrix storage convention. | | * matrix storage convention. | |
| */ | | */ | |
| #define dACCESS33(A,i,j) ((A)[(i)*4+(j)]) | | #define dACCESS33(A,i,j) ((A)[(i)*4+(j)]) | |
| | | | |
| /* | | /* | |
|
| | | * Macro to test for valid floating point values | |
| | | */ | |
| | | #define dVALIDVEC3(v) (!(dIsNan(v[0]) | dIsNan(v[1]) | dIsNan(v[2]))) | |
| | | #define dVALIDVEC4(v) (!(dIsNan(v[0]) | dIsNan(v[2]) | dIsNan(v[2]) | dIsNa | |
| | | n(v[3]))) | |
| | | #define dVALIDMAT(m) (!(dIsNan(m[0]) | dIsNan(m[2]) | dIsNan(m[2]) | dIsNan | |
| | | (m[3]) | dIsNan(m[4]) | dIsNan(m[5]) | dIsNan(m[6]) | dIsNan(m[7]) | dIsNan | |
| | | (m[8]) | dIsNan(m[9]) | dIsNan(m[10]) | dIsNan(m[11]))) | |
| | | | |
| | | /* | |
| * 3-way dot product. dDOTpq means that elements of `a' and `b' are spaced | | * 3-way dot product. dDOTpq means that elements of `a' and `b' are spaced | |
| * p and q indexes apart respectively. dDOT() means dDOT11. | | * p and q indexes apart respectively. dDOT() means dDOT11. | |
| * in C++ we could use function templates to get all the versions of these | | * in C++ we could use function templates to get all the versions of these | |
| * functions - but on some compilers this will result in sub-optimal code. | | * functions - but on some compilers this will result in sub-optimal code. | |
| */ | | */ | |
| | | | |
| #define dDOTpq(a,b,p,q) ((a)[0]*(b)[0] + (a)[p]*(b)[q] + (a)[2*(p)]*(b)[2*(
q)]) | | #define dDOTpq(a,b,p,q) ((a)[0]*(b)[0] + (a)[p]*(b)[q] + (a)[2*(p)]*(b)[2*(
q)]) | |
| | | | |
| #ifdef __cplusplus | | #ifdef __cplusplus | |
| | | | |
| | | | |
| skipping to change at line 79 | | skipping to change at line 86 | |
| #endif /* __cplusplus */ | | #endif /* __cplusplus */ | |
| | | | |
| /* | | /* | |
| * cross product, set a = b x c. dCROSSpqr means that elements of `a', `b' | | * cross product, set a = b x c. dCROSSpqr means that elements of `a', `b' | |
| * and `c' are spaced p, q and r indexes apart respectively. | | * and `c' are spaced p, q and r indexes apart respectively. | |
| * dCROSS() means dCROSS111. `op' is normally `=', but you can set it to | | * dCROSS() means dCROSS111. `op' is normally `=', but you can set it to | |
| * +=, -= etc to get other effects. | | * +=, -= etc to get other effects. | |
| */ | | */ | |
| | | | |
| #define dCROSS(a,op,b,c) \ | | #define dCROSS(a,op,b,c) \ | |
|
| | | do { \ | |
| (a)[0] op ((b)[1]*(c)[2] - (b)[2]*(c)[1]); \ | | (a)[0] op ((b)[1]*(c)[2] - (b)[2]*(c)[1]); \ | |
| (a)[1] op ((b)[2]*(c)[0] - (b)[0]*(c)[2]); \ | | (a)[1] op ((b)[2]*(c)[0] - (b)[0]*(c)[2]); \ | |
|
| (a)[2] op ((b)[0]*(c)[1] - (b)[1]*(c)[0]); | | (a)[2] op ((b)[0]*(c)[1] - (b)[1]*(c)[0]); \ | |
| | | } while(0) | |
| #define dCROSSpqr(a,op,b,c,p,q,r) \ | | #define dCROSSpqr(a,op,b,c,p,q,r) \ | |
|
| | | do { \ | |
| (a)[ 0] op ((b)[ q]*(c)[2*r] - (b)[2*q]*(c)[ r]); \ | | (a)[ 0] op ((b)[ q]*(c)[2*r] - (b)[2*q]*(c)[ r]); \ | |
| (a)[ p] op ((b)[2*q]*(c)[ 0] - (b)[ 0]*(c)[2*r]); \ | | (a)[ p] op ((b)[2*q]*(c)[ 0] - (b)[ 0]*(c)[2*r]); \ | |
|
| (a)[2*p] op ((b)[ 0]*(c)[ r] - (b)[ q]*(c)[ 0]); | | (a)[2*p] op ((b)[ 0]*(c)[ r] - (b)[ q]*(c)[ 0]); \ | |
| | | } while(0) | |
| #define dCROSS114(a,op,b,c) dCROSSpqr(a,op,b,c,1,1,4) | | #define dCROSS114(a,op,b,c) dCROSSpqr(a,op,b,c,1,1,4) | |
| #define dCROSS141(a,op,b,c) dCROSSpqr(a,op,b,c,1,4,1) | | #define dCROSS141(a,op,b,c) dCROSSpqr(a,op,b,c,1,4,1) | |
| #define dCROSS144(a,op,b,c) dCROSSpqr(a,op,b,c,1,4,4) | | #define dCROSS144(a,op,b,c) dCROSSpqr(a,op,b,c,1,4,4) | |
| #define dCROSS411(a,op,b,c) dCROSSpqr(a,op,b,c,4,1,1) | | #define dCROSS411(a,op,b,c) dCROSSpqr(a,op,b,c,4,1,1) | |
| #define dCROSS414(a,op,b,c) dCROSSpqr(a,op,b,c,4,1,4) | | #define dCROSS414(a,op,b,c) dCROSSpqr(a,op,b,c,4,1,4) | |
| #define dCROSS441(a,op,b,c) dCROSSpqr(a,op,b,c,4,4,1) | | #define dCROSS441(a,op,b,c) dCROSSpqr(a,op,b,c,4,4,1) | |
| #define dCROSS444(a,op,b,c) dCROSSpqr(a,op,b,c,4,4,4) | | #define dCROSS444(a,op,b,c) dCROSSpqr(a,op,b,c,4,4,4) | |
| | | | |
| /* | | /* | |
| * set a 3x3 submatrix of A to a matrix such that submatrix(A)*b = a x b. | | * set a 3x3 submatrix of A to a matrix such that submatrix(A)*b = a x b. | |
| * A is stored by rows, and has `skip' elements per row. the matrix is | | * A is stored by rows, and has `skip' elements per row. the matrix is | |
| * assumed to be already zero, so this does not write zero elements! | | * assumed to be already zero, so this does not write zero elements! | |
| * if (plus,minus) is (+,-) then a positive version will be written. | | * if (plus,minus) is (+,-) then a positive version will be written. | |
| * if (plus,minus) is (-,+) then a negative version will be written. | | * if (plus,minus) is (-,+) then a negative version will be written. | |
| */ | | */ | |
| | | | |
| #define dCROSSMAT(A,a,skip,plus,minus) \ | | #define dCROSSMAT(A,a,skip,plus,minus) \ | |
|
| | | do { \ | |
| (A)[1] = minus (a)[2]; \ | | (A)[1] = minus (a)[2]; \ | |
| (A)[2] = plus (a)[1]; \ | | (A)[2] = plus (a)[1]; \ | |
| (A)[(skip)+0] = plus (a)[2]; \ | | (A)[(skip)+0] = plus (a)[2]; \ | |
| (A)[(skip)+2] = minus (a)[0]; \ | | (A)[(skip)+2] = minus (a)[0]; \ | |
| (A)[2*(skip)+0] = minus (a)[1]; \ | | (A)[2*(skip)+0] = minus (a)[1]; \ | |
|
| (A)[2*(skip)+1] = plus (a)[0]; | | (A)[2*(skip)+1] = plus (a)[0]; \ | |
| | | } while(0) | |
| | | | |
| /* | | /* | |
|
| * compute the distance between two 3-vectors | | * compute the distance between two 3D-vectors | |
| */ | | */ | |
| | | | |
| #ifdef __cplusplus | | #ifdef __cplusplus | |
|
| PURE_INLINE float dDISTANCE (const float a[3], const float b[3]) | | PURE_INLINE dReal dDISTANCE (const dVector3 a, const dVector3 b) | |
| { return (float) dSqrt( (a[0]-b[0])*(a[0]-b[0]) + (a[1]-b[1])*(a[1]- | | | |
| b[1]) + (a[2]-b[2])*(a[2]-b[2]) ); } | | | |
| PURE_INLINE double dDISTANCE (const double a[3], const double b[3]) | | | |
| { return dSqrt( (a[0]-b[0])*(a[0]-b[0]) + (a[1]-b[1])*(a[1]-b[1]) +
(a[2]-b[2])*(a[2]-b[2]) ); } | | { return dSqrt( (a[0]-b[0])*(a[0]-b[0]) + (a[1]-b[1])*(a[1]-b[1]) +
(a[2]-b[2])*(a[2]-b[2]) ); } | |
| #else | | #else | |
| #define dDISTANCE(a,b) \ | | #define dDISTANCE(a,b) \ | |
| (dSqrt( ((a)[0]-(b)[0])*((a)[0]-(b)[0]) + ((a)[1]-(b)[1])*((a)[1]-(b
)[1]) + ((a)[2]-(b)[2])*((a)[2]-(b)[2]) )) | | (dSqrt( ((a)[0]-(b)[0])*((a)[0]-(b)[0]) + ((a)[1]-(b)[1])*((a)[1]-(b
)[1]) + ((a)[2]-(b)[2])*((a)[2]-(b)[2]) )) | |
| #endif | | #endif | |
| | | | |
| /* | | /* | |
| * special case matrix multipication, with operator selection | | * special case matrix multipication, with operator selection | |
| */ | | */ | |
| | | | |
| #define dMULTIPLYOP0_331(A,op,B,C) \ | | #define dMULTIPLYOP0_331(A,op,B,C) \ | |
|
| | | do { \ | |
| (A)[0] op dDOT((B),(C)); \ | | (A)[0] op dDOT((B),(C)); \ | |
| (A)[1] op dDOT((B+4),(C)); \ | | (A)[1] op dDOT((B+4),(C)); \ | |
|
| (A)[2] op dDOT((B+8),(C)); | | (A)[2] op dDOT((B+8),(C)); \ | |
| | | } while(0) | |
| #define dMULTIPLYOP1_331(A,op,B,C) \ | | #define dMULTIPLYOP1_331(A,op,B,C) \ | |
|
| | | do { \ | |
| (A)[0] op dDOT41((B),(C)); \ | | (A)[0] op dDOT41((B),(C)); \ | |
| (A)[1] op dDOT41((B+1),(C)); \ | | (A)[1] op dDOT41((B+1),(C)); \ | |
|
| (A)[2] op dDOT41((B+2),(C)); | | (A)[2] op dDOT41((B+2),(C)); \ | |
| | | } while(0) | |
| #define dMULTIPLYOP0_133(A,op,B,C) \ | | #define dMULTIPLYOP0_133(A,op,B,C) \ | |
|
| | | do { \ | |
| (A)[0] op dDOT14((B),(C)); \ | | (A)[0] op dDOT14((B),(C)); \ | |
| (A)[1] op dDOT14((B),(C+1)); \ | | (A)[1] op dDOT14((B),(C+1)); \ | |
|
| (A)[2] op dDOT14((B),(C+2)); | | (A)[2] op dDOT14((B),(C+2)); \ | |
| | | } while(0) | |
| #define dMULTIPLYOP0_333(A,op,B,C) \ | | #define dMULTIPLYOP0_333(A,op,B,C) \ | |
|
| | | do { \ | |
| (A)[0] op dDOT14((B),(C)); \ | | (A)[0] op dDOT14((B),(C)); \ | |
| (A)[1] op dDOT14((B),(C+1)); \ | | (A)[1] op dDOT14((B),(C+1)); \ | |
| (A)[2] op dDOT14((B),(C+2)); \ | | (A)[2] op dDOT14((B),(C+2)); \ | |
| (A)[4] op dDOT14((B+4),(C)); \ | | (A)[4] op dDOT14((B+4),(C)); \ | |
| (A)[5] op dDOT14((B+4),(C+1)); \ | | (A)[5] op dDOT14((B+4),(C+1)); \ | |
| (A)[6] op dDOT14((B+4),(C+2)); \ | | (A)[6] op dDOT14((B+4),(C+2)); \ | |
| (A)[8] op dDOT14((B+8),(C)); \ | | (A)[8] op dDOT14((B+8),(C)); \ | |
| (A)[9] op dDOT14((B+8),(C+1)); \ | | (A)[9] op dDOT14((B+8),(C+1)); \ | |
|
| (A)[10] op dDOT14((B+8),(C+2)); | | (A)[10] op dDOT14((B+8),(C+2)); \ | |
| | | } while(0) | |
| #define dMULTIPLYOP1_333(A,op,B,C) \ | | #define dMULTIPLYOP1_333(A,op,B,C) \ | |
|
| | | do { \ | |
| (A)[0] op dDOT44((B),(C)); \ | | (A)[0] op dDOT44((B),(C)); \ | |
| (A)[1] op dDOT44((B),(C+1)); \ | | (A)[1] op dDOT44((B),(C+1)); \ | |
| (A)[2] op dDOT44((B),(C+2)); \ | | (A)[2] op dDOT44((B),(C+2)); \ | |
| (A)[4] op dDOT44((B+1),(C)); \ | | (A)[4] op dDOT44((B+1),(C)); \ | |
| (A)[5] op dDOT44((B+1),(C+1)); \ | | (A)[5] op dDOT44((B+1),(C+1)); \ | |
| (A)[6] op dDOT44((B+1),(C+2)); \ | | (A)[6] op dDOT44((B+1),(C+2)); \ | |
| (A)[8] op dDOT44((B+2),(C)); \ | | (A)[8] op dDOT44((B+2),(C)); \ | |
| (A)[9] op dDOT44((B+2),(C+1)); \ | | (A)[9] op dDOT44((B+2),(C+1)); \ | |
|
| (A)[10] op dDOT44((B+2),(C+2)); | | (A)[10] op dDOT44((B+2),(C+2)); \ | |
| | | } while(0) | |
| #define dMULTIPLYOP2_333(A,op,B,C) \ | | #define dMULTIPLYOP2_333(A,op,B,C) \ | |
|
| | | do { \ | |
| (A)[0] op dDOT((B),(C)); \ | | (A)[0] op dDOT((B),(C)); \ | |
| (A)[1] op dDOT((B),(C+4)); \ | | (A)[1] op dDOT((B),(C+4)); \ | |
| (A)[2] op dDOT((B),(C+8)); \ | | (A)[2] op dDOT((B),(C+8)); \ | |
| (A)[4] op dDOT((B+4),(C)); \ | | (A)[4] op dDOT((B+4),(C)); \ | |
| (A)[5] op dDOT((B+4),(C+4)); \ | | (A)[5] op dDOT((B+4),(C+4)); \ | |
| (A)[6] op dDOT((B+4),(C+8)); \ | | (A)[6] op dDOT((B+4),(C+8)); \ | |
| (A)[8] op dDOT((B+8),(C)); \ | | (A)[8] op dDOT((B+8),(C)); \ | |
| (A)[9] op dDOT((B+8),(C+4)); \ | | (A)[9] op dDOT((B+8),(C+4)); \ | |
|
| (A)[10] op dDOT((B+8),(C+8)); | | (A)[10] op dDOT((B+8),(C+8)); \ | |
| | | } while(0) | |
| | | | |
| #ifdef __cplusplus | | #ifdef __cplusplus | |
| | | | |
| #define DECL template <class TA, class TB, class TC> PURE_INLINE void | | #define DECL template <class TA, class TB, class TC> PURE_INLINE void | |
| | | | |
|
| DECL dMULTIPLY0_331(TA *A, const TB *B, const TC *C) { dMULTIPLYOP0_331(A,= | | DECL dMULTIPLY0_331(TA *A, const TB *B, const TC *C) { dMULTIPLYOP0_331(A,= | |
| ,B,C) } | | ,B,C); } | |
| DECL dMULTIPLY1_331(TA *A, const TB *B, const TC *C) { dMULTIPLYOP1_331(A,= | | DECL dMULTIPLY1_331(TA *A, const TB *B, const TC *C) { dMULTIPLYOP1_331(A,= | |
| ,B,C) } | | ,B,C); } | |
| DECL dMULTIPLY0_133(TA *A, const TB *B, const TC *C) { dMULTIPLYOP0_133(A,= | | DECL dMULTIPLY0_133(TA *A, const TB *B, const TC *C) { dMULTIPLYOP0_133(A,= | |
| ,B,C) } | | ,B,C); } | |
| DECL dMULTIPLY0_333(TA *A, const TB *B, const TC *C) { dMULTIPLYOP0_333(A,= | | DECL dMULTIPLY0_333(TA *A, const TB *B, const TC *C) { dMULTIPLYOP0_333(A,= | |
| ,B,C) } | | ,B,C); } | |
| DECL dMULTIPLY1_333(TA *A, const TB *B, const TC *C) { dMULTIPLYOP1_333(A,= | | DECL dMULTIPLY1_333(TA *A, const TB *B, const TC *C) { dMULTIPLYOP1_333(A,= | |
| ,B,C) } | | ,B,C); } | |
| DECL dMULTIPLY2_333(TA *A, const TB *B, const TC *C) { dMULTIPLYOP2_333(A,= | | DECL dMULTIPLY2_333(TA *A, const TB *B, const TC *C) { dMULTIPLYOP2_333(A,= | |
| ,B,C) } | | ,B,C); } | |
| | | | |
| DECL dMULTIPLYADD0_331(TA *A, const TB *B, const TC *C) { dMULTIPLYOP0_331( | | DECL dMULTIPLYADD0_331(TA *A, const TB *B, const TC *C) { dMULTIPLYOP0_331( | |
| A,+=,B,C) } | | A,+=,B,C); } | |
| DECL dMULTIPLYADD1_331(TA *A, const TB *B, const TC *C) { dMULTIPLYOP1_331( | | DECL dMULTIPLYADD1_331(TA *A, const TB *B, const TC *C) { dMULTIPLYOP1_331( | |
| A,+=,B,C) } | | A,+=,B,C); } | |
| DECL dMULTIPLYADD0_133(TA *A, const TB *B, const TC *C) { dMULTIPLYOP0_133( | | DECL dMULTIPLYADD0_133(TA *A, const TB *B, const TC *C) { dMULTIPLYOP0_133( | |
| A,+=,B,C) } | | A,+=,B,C); } | |
| DECL dMULTIPLYADD0_333(TA *A, const TB *B, const TC *C) { dMULTIPLYOP0_333( | | DECL dMULTIPLYADD0_333(TA *A, const TB *B, const TC *C) { dMULTIPLYOP0_333( | |
| A,+=,B,C) } | | A,+=,B,C); } | |
| DECL dMULTIPLYADD1_333(TA *A, const TB *B, const TC *C) { dMULTIPLYOP1_333( | | DECL dMULTIPLYADD1_333(TA *A, const TB *B, const TC *C) { dMULTIPLYOP1_333( | |
| A,+=,B,C) } | | A,+=,B,C); } | |
| DECL dMULTIPLYADD2_333(TA *A, const TB *B, const TC *C) { dMULTIPLYOP2_333( | | DECL dMULTIPLYADD2_333(TA *A, const TB *B, const TC *C) { dMULTIPLYOP2_333( | |
| A,+=,B,C) } | | A,+=,B,C); } | |
| | | | |
| #undef DECL | | #undef DECL | |
| | | | |
| #else | | #else | |
| | | | |
| #define dMULTIPLY0_331(A,B,C) dMULTIPLYOP0_331(A,=,B,C) | | #define dMULTIPLY0_331(A,B,C) dMULTIPLYOP0_331(A,=,B,C) | |
| #define dMULTIPLY1_331(A,B,C) dMULTIPLYOP1_331(A,=,B,C) | | #define dMULTIPLY1_331(A,B,C) dMULTIPLYOP1_331(A,=,B,C) | |
| #define dMULTIPLY0_133(A,B,C) dMULTIPLYOP0_133(A,=,B,C) | | #define dMULTIPLY0_133(A,B,C) dMULTIPLYOP0_133(A,=,B,C) | |
| #define dMULTIPLY0_333(A,B,C) dMULTIPLYOP0_333(A,=,B,C) | | #define dMULTIPLY0_333(A,B,C) dMULTIPLYOP0_333(A,=,B,C) | |
| #define dMULTIPLY1_333(A,B,C) dMULTIPLYOP1_333(A,=,B,C) | | #define dMULTIPLY1_333(A,B,C) dMULTIPLYOP1_333(A,=,B,C) | |
| | | | |
| skipping to change at line 216 | | skipping to change at line 239 | |
| | | | |
| #endif | | #endif | |
| | | | |
| #ifdef __cplusplus | | #ifdef __cplusplus | |
| extern "C" { | | extern "C" { | |
| #endif | | #endif | |
| | | | |
| /* | | /* | |
| * normalize 3x1 and 4x1 vectors (i.e. scale them to unit length) | | * normalize 3x1 and 4x1 vectors (i.e. scale them to unit length) | |
| */ | | */ | |
|
| void dNormalize3 (dVector3 a); | | ODE_API void dNormalize3 (dVector3 a); | |
| void dNormalize4 (dVector4 a); | | ODE_API void dNormalize4 (dVector4 a); | |
| | | | |
| /* | | /* | |
| * given a unit length "normal" vector n, generate vectors p and q vectors | | * given a unit length "normal" vector n, generate vectors p and q vectors | |
| * that are an orthonormal basis for the plane space perpendicular to n. | | * that are an orthonormal basis for the plane space perpendicular to n. | |
| * i.e. this makes p,q such that n,p,q are all perpendicular to each other. | | * i.e. this makes p,q such that n,p,q are all perpendicular to each other. | |
| * q will equal n x p. if n is not unit length then p will be unit length b
ut | | * q will equal n x p. if n is not unit length then p will be unit length b
ut | |
| * q wont be. | | * q wont be. | |
| */ | | */ | |
| | | | |
|
| void dPlaneSpace (const dVector3 n, dVector3 p, dVector3 q); | | ODE_API void dPlaneSpace (const dVector3 n, dVector3 p, dVector3 q); | |
| | | | |
| #ifdef __cplusplus | | #ifdef __cplusplus | |
| } | | } | |
| #endif | | #endif | |
| | | | |
| #endif | | #endif | |
| | | | |
End of changes. 24 change blocks. |
| 42 lines changed or deleted | | 67 lines changed or added | |
|