]> git.rm.cloudns.org Git - xonotic/xonotic.git/commitdiff
update ALL the dlls
authorXonotic Build Service <xonotic@xonotic.org>
Thu, 5 Apr 2012 08:39:49 +0000 (10:39 +0200)
committerXonotic Build Service <xonotic@xonotic.org>
Thu, 5 Apr 2012 08:39:49 +0000 (10:39 +0200)
94 files changed:
misc/builddeps/dp.linux32/bin/blind_id
misc/builddeps/dp.linux32/bin/ode-config [new file with mode: 0755]
misc/builddeps/dp.linux32/include/d0_blind_id/d0.h
misc/builddeps/dp.linux32/include/ode/collision.h [new file with mode: 0644]
misc/builddeps/dp.linux32/include/ode/collision_space.h [new file with mode: 0644]
misc/builddeps/dp.linux32/include/ode/collision_trimesh.h [new file with mode: 0644]
misc/builddeps/dp.linux32/include/ode/common.h [new file with mode: 0644]
misc/builddeps/dp.linux32/include/ode/compatibility.h [new file with mode: 0644]
misc/builddeps/dp.linux32/include/ode/contact.h [new file with mode: 0644]
misc/builddeps/dp.linux32/include/ode/error.h [new file with mode: 0644]
misc/builddeps/dp.linux32/include/ode/export-dif.h [new file with mode: 0644]
misc/builddeps/dp.linux32/include/ode/mass.h [new file with mode: 0644]
misc/builddeps/dp.linux32/include/ode/matrix.h [new file with mode: 0644]
misc/builddeps/dp.linux32/include/ode/memory.h [new file with mode: 0644]
misc/builddeps/dp.linux32/include/ode/misc.h [new file with mode: 0644]
misc/builddeps/dp.linux32/include/ode/objects.h [new file with mode: 0644]
misc/builddeps/dp.linux32/include/ode/ode.h [new file with mode: 0644]
misc/builddeps/dp.linux32/include/ode/odeconfig.h [new file with mode: 0644]
misc/builddeps/dp.linux32/include/ode/odecpp.h [new file with mode: 0644]
misc/builddeps/dp.linux32/include/ode/odecpp_collision.h [new file with mode: 0644]
misc/builddeps/dp.linux32/include/ode/odeinit.h [new file with mode: 0644]
misc/builddeps/dp.linux32/include/ode/odemath.h [new file with mode: 0644]
misc/builddeps/dp.linux32/include/ode/odemath_legacy.h [new file with mode: 0644]
misc/builddeps/dp.linux32/include/ode/rotation.h [new file with mode: 0644]
misc/builddeps/dp.linux32/include/ode/timer.h [new file with mode: 0644]
misc/builddeps/dp.linux32/lib/libd0_blind_id.a
misc/builddeps/dp.linux32/lib/libd0_rijndael.a
misc/builddeps/dp.linux32/lib/libmodplug.a
misc/builddeps/dp.linux32/lib/libmodplug.la
misc/builddeps/dp.linux32/lib/libode.a [new file with mode: 0644]
misc/builddeps/dp.linux32/lib/libode.la [new file with mode: 0755]
misc/builddeps/dp.linux32/lib/pkgconfig/ode.pc [new file with mode: 0644]
misc/builddeps/dp.linux64/bin/blind_id
misc/builddeps/dp.linux64/bin/ode-config [new file with mode: 0755]
misc/builddeps/dp.linux64/include/d0_blind_id/d0.h
misc/builddeps/dp.linux64/include/ode/collision.h [new file with mode: 0644]
misc/builddeps/dp.linux64/include/ode/collision_space.h [new file with mode: 0644]
misc/builddeps/dp.linux64/include/ode/collision_trimesh.h [new file with mode: 0644]
misc/builddeps/dp.linux64/include/ode/common.h [new file with mode: 0644]
misc/builddeps/dp.linux64/include/ode/compatibility.h [new file with mode: 0644]
misc/builddeps/dp.linux64/include/ode/contact.h [new file with mode: 0644]
misc/builddeps/dp.linux64/include/ode/error.h [new file with mode: 0644]
misc/builddeps/dp.linux64/include/ode/export-dif.h [new file with mode: 0644]
misc/builddeps/dp.linux64/include/ode/mass.h [new file with mode: 0644]
misc/builddeps/dp.linux64/include/ode/matrix.h [new file with mode: 0644]
misc/builddeps/dp.linux64/include/ode/memory.h [new file with mode: 0644]
misc/builddeps/dp.linux64/include/ode/misc.h [new file with mode: 0644]
misc/builddeps/dp.linux64/include/ode/objects.h [new file with mode: 0644]
misc/builddeps/dp.linux64/include/ode/ode.h [new file with mode: 0644]
misc/builddeps/dp.linux64/include/ode/odeconfig.h [new file with mode: 0644]
misc/builddeps/dp.linux64/include/ode/odecpp.h [new file with mode: 0644]
misc/builddeps/dp.linux64/include/ode/odecpp_collision.h [new file with mode: 0644]
misc/builddeps/dp.linux64/include/ode/odeinit.h [new file with mode: 0644]
misc/builddeps/dp.linux64/include/ode/odemath.h [new file with mode: 0644]
misc/builddeps/dp.linux64/include/ode/odemath_legacy.h [new file with mode: 0644]
misc/builddeps/dp.linux64/include/ode/rotation.h [new file with mode: 0644]
misc/builddeps/dp.linux64/include/ode/timer.h [new file with mode: 0644]
misc/builddeps/dp.linux64/lib/libd0_blind_id.a
misc/builddeps/dp.linux64/lib/libd0_rijndael.a
misc/builddeps/dp.linux64/lib/libmodplug.a
misc/builddeps/dp.linux64/lib/libmodplug.la
misc/builddeps/dp.linux64/lib/libode.a [new file with mode: 0644]
misc/builddeps/dp.linux64/lib/libode.la [new file with mode: 0755]
misc/builddeps/dp.linux64/lib/pkgconfig/ode.pc [new file with mode: 0644]
misc/builddeps/dp.win32/bin/zlib1.dll
misc/builddeps/dp.win32/include/zconf.h
misc/builddeps/dp.win32/include/zlib.h
misc/builddeps/dp.win32/lib/libz.a
misc/builddeps/dp.win32/lib/pkgconfig/zlib.pc [new file with mode: 0644]
misc/builddeps/dp.win64/bin/zlib1.dll
misc/builddeps/dp.win64/include/zconf.h
misc/builddeps/dp.win64/include/zlib.h
misc/builddeps/dp.win64/lib/libz.a
misc/builddeps/dp.win64/lib/pkgconfig/zlib.pc [new file with mode: 0644]
misc/buildfiles/osx/Xonotic.app/Contents/MacOS/libd0_blind_id.0.dylib
misc/buildfiles/osx/Xonotic.app/Contents/MacOS/libd0_blind_id.dylib [new symlink]
misc/buildfiles/osx/Xonotic.app/Contents/MacOS/libd0_rijndael.dylib [new symlink]
misc/buildfiles/osx/Xonotic.app/Contents/MacOS/libode.3.dylib [new file with mode: 0755]
misc/buildfiles/osx/Xonotic.app/Contents/MacOS/libode.dylib [new symlink]
misc/buildfiles/osx/Xonotic.app/Contents/MacOS/libpng.dylib [new symlink]
misc/buildfiles/osx/Xonotic.app/Contents/MacOS/libpng15.15.dylib [new file with mode: 0755]
misc/buildfiles/osx/Xonotic.app/Contents/MacOS/libpng15.dylib [new symlink]
misc/buildfiles/win32/libd0_blind_id-0.dll
misc/buildfiles/win32/libd0_rijndael-0.dll
misc/buildfiles/win32/libmodplug-1.dll
misc/buildfiles/win32/libode-3.dll [new file with mode: 0755]
misc/buildfiles/win32/libpng12.dll [deleted file]
misc/buildfiles/win32/libpng15-15.dll [new file with mode: 0755]
misc/buildfiles/win64/libd0_blind_id-0.dll
misc/buildfiles/win64/libd0_rijndael-0.dll
misc/buildfiles/win64/libmodplug-1.dll
misc/buildfiles/win64/libode-3.dll [new file with mode: 0755]
misc/buildfiles/win64/libpng12.dll [deleted file]
misc/buildfiles/win64/libpng15-15.dll [new file with mode: 0755]

index 49550cc38beb10eebb5fbda7b1575182f92e1b25..35bb6834de8df59b4dbeb3380f08a1db93fb8ccf 100755 (executable)
Binary files a/misc/builddeps/dp.linux32/bin/blind_id and b/misc/builddeps/dp.linux32/bin/blind_id differ
diff --git a/misc/builddeps/dp.linux32/bin/ode-config b/misc/builddeps/dp.linux32/bin/ode-config
new file mode 100755 (executable)
index 0000000..dddc75d
--- /dev/null
@@ -0,0 +1,53 @@
+#!/bin/sh
+
+prefix=/usr/local
+exec_prefix=${prefix}
+exec_prefix_set=no
+
+usage="\
+Usage: ode-config [--prefix[=DIR]] [--exec-prefix[=DIR]] [--version] [--cflags] [--libs]"
+
+if test $# -eq 0; then
+      echo "${usage}" 1>&2
+      exit 1
+fi
+
+while test $# -gt 0; do
+  case "$1" in
+  -*=*) optarg=`echo "$1" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
+  *) optarg= ;;
+  esac
+
+  case $1 in
+    --prefix=*)
+      prefix=$optarg
+      if test $exec_prefix_set = no ; then
+        exec_prefix=$optarg
+      fi
+      ;;
+    --prefix)
+      echo $prefix
+      ;;
+    --exec-prefix=*)
+      exec_prefix=$optarg
+      exec_prefix_set=yes
+      ;;
+    --exec-prefix)
+      echo $exec_prefix
+      ;;
+    --version)
+      echo 0.12
+      ;;
+    --cflags)
+      echo  -I${prefix}/include -DdDOUBLE
+      ;;
+    --libs)
+      echo  -L${exec_prefix}/lib -lode
+      ;;
+    *)
+      echo "${usage}" 1>&2
+      exit 1
+      ;;
+  esac
+  shift
+done
index 89d86fe5182345a2177c6dc8f99f5353afa26b78..4c8708e32a513a92a5d46a17b702f5d8a3f7e2b0 100644 (file)
@@ -30,7 +30,7 @@
  * SUCH DAMAGE.
  *
  * $Format:commit %H$
- * $Id: 0f9b41999f2a57f07067272a8b89919394c4b04f $
+ * $Id: 6c55afeb50f24bd316079ae46582e65f8020b19b $
  */
 
 #ifndef __D0_H__
@@ -39,6 +39,7 @@
 #include <unistd.h> // size_t
 
 #define D0_EXPORT __attribute__((__visibility__("default")))
+#define D0_USED __attribute__((used))
 #define D0_WARN_UNUSED_RESULT __attribute__((warn_unused_result))
 #define D0_BOOL int
 
diff --git a/misc/builddeps/dp.linux32/include/ode/collision.h b/misc/builddeps/dp.linux32/include/ode/collision.h
new file mode 100644 (file)
index 0000000..e89726c
--- /dev/null
@@ -0,0 +1,1523 @@
+/*************************************************************************
+ *                                                                       *
+ * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith.       *
+ * All rights reserved.  Email: russ@q12.org   Web: www.q12.org          *
+ *                                                                       *
+ * This library is free software; you can redistribute it and/or         *
+ * modify it under the terms of EITHER:                                  *
+ *   (1) The GNU Lesser General Public License as published by the Free  *
+ *       Software Foundation; either version 2.1 of the License, or (at  *
+ *       your option) any later version. The text of the GNU Lesser      *
+ *       General Public License is included with this library in the     *
+ *       file LICENSE.TXT.                                               *
+ *   (2) The BSD-style license that is included with this library in     *
+ *       the file LICENSE-BSD.TXT.                                       *
+ *                                                                       *
+ * This library is distributed in the hope that it will be useful,       *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files    *
+ * LICENSE.TXT and LICENSE-BSD.TXT for more details.                     *
+ *                                                                       *
+ *************************************************************************/
+
+#ifndef _ODE_COLLISION_H_
+#define _ODE_COLLISION_H_
+
+#include <ode/common.h>
+#include <ode/collision_space.h>
+#include <ode/contact.h>
+// Include odeinit.h for backward compatibility as some of initialization APIs 
+// were initally declared in current header.
+#include <ode/odeinit.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup collide Collision Detection
+ *
+ * ODE has two main components: a dynamics simulation engine and a collision
+ * detection engine. The collision engine is given information about the
+ * shape of each body. At each time step it figures out which bodies touch
+ * each other and passes the resulting contact point information to the user.
+ * The user in turn creates contact joints between bodies.
+ *
+ * Using ODE's collision detection is optional - an alternative collision
+ * detection system can be used as long as it can supply the right kinds of
+ * contact information.
+ */
+
+
+/* ************************************************************************ */
+/* general functions */
+
+/**
+ * @brief Destroy a geom, removing it from any space.
+ *
+ * Destroy a geom, removing it from any space it is in first. This one
+ * function destroys a geom of any type, but to create a geom you must call
+ * a creation function for that type.
+ *
+ * When a space is destroyed, if its cleanup mode is 1 (the default) then all
+ * the geoms in that space are automatically destroyed as well.
+ *
+ * @param geom the geom to be destroyed.
+ * @ingroup collide
+ */
+ODE_API void dGeomDestroy (dGeomID geom);
+
+
+/**
+ * @brief Set the user-defined data pointer stored in the geom.
+ *
+ * @param geom the geom to hold the data
+ * @param data the data pointer to be stored
+ * @ingroup collide
+ */
+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/rotation
+ * of the body.
+ *
+ * Calling these functions on a non-placeable geom results in a runtime
+ * error in the debug build of ODE.
+ *
+ * @param geom the geom to connect
+ * @param body the body to attach to the geom
+ * @ingroup collide
+ */
+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 changed.
+ * Calling this function on a non-placeable geom results in a runtime error in
+ * the debug build of ODE.
+ *
+ * @param geom the geom to set.
+ * @param x the new X coordinate.
+ * @param y the new Y coordinate.
+ * @param z the new Z coordinate.
+ * @sa dBodySetPosition
+ * @ingroup collide
+ */
+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 changed.
+ * Calling this function on a non-placeable geom results in a runtime error in
+ * the debug build of ODE.
+ *
+ * @param geom the geom to set.
+ * @param R the new rotation matrix.
+ * @sa dBodySetRotation
+ * @ingroup collide
+ */
+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 changed.
+ *
+ * Calling this function on a non-placeable geom results in a runtime error in
+ * the debug build of ODE.
+ *
+ * @param geom the geom to set.
+ * @param Q the new rotation.
+ * @sa dBodySetQuaternion
+ * @ingroup collide
+ */
+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 Copy the position of a geom into a vector.
+ * @ingroup collide
+ * @param geom  the geom to query
+ * @param pos   a copy of the geom position
+ * @sa dGeomGetPosition
+ */
+ODE_API void dGeomCopyPosition (dGeomID geom, dVector3 pos);
+
+
+/**
+ * @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 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.
+ * @param R      a copy of the geom rotation
+ * @sa dGeomGetRotation
+ * @ingroup collide
+ */
+ODE_API void dGeomCopyRotation(dGeomID geom, dMatrix3 R);
+
+
+/**
+ * @brief Get the rotation quaternion of a placeable geom.
+ *
+ * If the geom is attached to a body, the body's quaternion will be returned.
+ *
+ * Calling this function on a non-placeable geom results in a runtime error in
+ * the debug build of ODE.
+ *
+ * @param geom the geom to query.
+ * @param result a copy of the rotation quaternion.
+ * @sa dBodyGetQuaternion
+ * @ingroup collide
+ */
+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 geom.
+ * The aabb array has elements (minx, maxx, miny, maxy, minz, maxz). If the
+ * geom is a space, a bounding box that surrounds all contained geoms is
+ * returned.
+ *
+ * This function may return a pre-computed cached bounding box, if it can
+ * determine that the geom has not moved since the last time the bounding
+ * box was computed.
+ *
+ * @param geom the geom to query
+ * @param aabb the returned bounding box
+ * @ingroup collide
+ */
+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 dSpaceCollide2,
+ * although they can still be members of a space. New geoms are created in
+ * the enabled state.
+ *
+ * @param geom   the geom to enable
+ * @sa dGeomDisable
+ * @sa dGeomIsEnabled
+ * @ingroup collide
+ */
+ODE_API void dGeomEnable (dGeomID geom);
+
+
+/**
+ * @brief Disable a geom.
+ *
+ * Disabled geoms are completely ignored by dSpaceCollide and dSpaceCollide2,
+ * although they can still be members of a space. New geoms are created in
+ * the enabled state.
+ *
+ * @param geom   the geom to disable
+ * @sa dGeomDisable
+ * @sa dGeomIsEnabled
+ * @ingroup collide
+ */
+ODE_API void dGeomDisable (dGeomID geom);
+
+
+/**
+ * @brief Check to see if a geom is enabled.
+ *
+ * Disabled geoms are completely ignored by dSpaceCollide and dSpaceCollide2,
+ * although they can still be members of a space. New geoms are created in
+ * the enabled state.
+ *
+ * @param geom   the geom to query
+ * @returns Non-zero if the geom is enabled, zero otherwise.
+ * @sa dGeomDisable
+ * @sa dGeomIsEnabled
+ * @ingroup collide
+ */
+ODE_API int dGeomIsEnabled (dGeomID geom);
+
+
+enum
+{
+       dGeomCommonControlClass = 0,
+       dGeomColliderControlClass = 1
+};
+
+enum
+{
+       dGeomCommonAnyControlCode = 0,
+
+       dGeomColliderSetMergeSphereContactsControlCode = 1,
+       dGeomColliderGetMergeSphereContactsControlCode = 2
+};
+
+enum
+{
+       dGeomColliderMergeContactsValue__Default = 0, // Used with Set... to restore default value
+       dGeomColliderMergeContactsValue_None = 1,
+       dGeomColliderMergeContactsValue_Normals = 2,
+       dGeomColliderMergeContactsValue_Full = 3
+};
+
+/**
+ * @brief Execute low level control operation for geometry.
+ *
+ * The variable the dataSize points to must be initialized before the call.
+ * If the size does not match the one expected for the control class/code function
+ * changes it to the size expected and returns failure. This implies the function 
+ * can be called with NULL data and zero size to test if control class/code is supported
+ * and obtain required data size for it.
+ *
+ * dGeomCommonAnyControlCode applies to any control class and returns success if 
+ * at least one control code is available for the given class with given geom.
+ *
+ * Currently there are the folliwing control classes supported:
+ *  @li dGeomColliderControlClass
+ *
+ * For dGeomColliderControlClass there are the following codes available:
+ *  @li dGeomColliderSetMergeSphereContactsControlCode (arg of type int, dGeomColliderMergeContactsValue_*)
+ *  @li dGeomColliderGetMergeSphereContactsControlCode (arg of type int, dGeomColliderMergeContactsValue_*)
+ *
+ * @param geom   the geom to control
+ * @param controlClass   the control class
+ * @param controlCode   the control code for the class
+ * @param dataValue   the control argument pointer
+ * @param dataSize   the control argument size provided or expected
+ * @returns Boolean execution status
+ * @ingroup collide
+ */
+ODE_API int dGeomLowLevelControl (dGeomID geom, int controlClass, int controlCode, void *dataValue, int *dataSize);
+
+
+/**
+ * @brief Get world position of a relative point on geom.
+ *
+ * Calling this function on a non-placeable geom results in the same point being
+ * returned.
+ *
+ * @ingroup collide
+ * @param result will contain the result.
+ */
+ODE_API void dGeomGetRelPointPos
+(
+  dGeomID geom, dReal px, dReal py, dReal pz,
+  dVector3 result
+);
+
+/**
+ * @brief takes a point in global coordinates and returns
+ * the point's position in geom-relative coordinates.
+ *
+ * Calling this function on a non-placeable geom results in the same point being
+ * returned.
+ *
+ * @remarks
+ * This is the inverse of dGeomGetRelPointPos()
+ * @ingroup collide
+ * @param result will contain the result.
+ */
+ODE_API void dGeomGetPosRelPoint
+(
+  dGeomID geom, dReal px, dReal py, dReal pz,
+  dVector3 result
+);
+
+/**
+ * @brief Convert from geom-local to world coordinates.
+ *
+ * Calling this function on a non-placeable geom results in the same vector being
+ * returned.
+ *
+ * @ingroup collide
+ * @param result will contain the result.
+ */
+ODE_API void dGeomVectorToWorld
+(
+  dGeomID geom, dReal px, dReal py, dReal pz,
+  dVector3 result
+);
+
+/**
+ * @brief Convert from world to geom-local coordinates.
+ *
+ * Calling this function on a non-placeable geom results in the same vector being
+ * returned.
+ *
+ * @ingroup collide
+ * @param result will contain the result.
+ */
+ODE_API void dGeomVectorFromWorld
+(
+  dGeomID geom, dReal px, dReal py, dReal pz,
+  dVector3 result
+);
+
+
+/* ************************************************************************ */
+/* 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, dReal 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 Copy 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.
+ * @param pos    returns the offset position
+ * @ingroup collide
+ */
+ODE_API void dGeomCopyOffsetPosition (dGeomID geom, dVector3 pos);
+
+
+/**
+ * @brief Get the offset rotation matrix of a geom.
+ *
+ * Returns the rotational offset of the geom in local coordinates.
+ * If the geom has no offset, this function returns the identity
+ * matrix.
+ *
+ * @param geom the geom to query.
+ * @returns A pointer to the geom's offset 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.
+ * @ingroup collide
+ */
+ODE_API const dReal * dGeomGetOffsetRotation (dGeomID geom);
+
+
+/**
+ * @brief Copy the offset rotation matrix of a geom.
+ *
+ * Returns the rotational offset of the geom in local coordinates.
+ * If the geom has no offset, this function returns the identity
+ * matrix.
+ *
+ * @param geom   the geom to query.
+ * @param R      returns the rotation matrix.
+ * @ingroup collide
+ */
+ODE_API void dGeomCopyOffsetRotation (dGeomID geom, dMatrix3 R);
+
+
+/**
+ * @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 */
+
+/*
+ *     Just generate any contacts (disables any contact refining).
+ */
+#define CONTACTS_UNIMPORTANT                   0x80000000
+
+/**
+ *
+ * @brief Given two geoms o1 and o2 that potentially intersect,
+ * generate contact information for them.
+ *
+ * Internally, this just calls the correct class-specific collision
+ * functions for o1 and o2.
+ *
+ * @param o1 The first geom to test.
+ * @param o2 The second geom to test.
+ *
+ * @param flags The flags specify how contacts should be generated if
+ * the geoms touch. The lower 16 bits of flags is an integer that
+ * specifies the maximum number of contact points to generate. You must
+ * ask for at least one contact. 
+ * Additionally, following bits may be set:
+ * CONTACTS_UNIMPORTANT -- just generate any contacts (skip contact refining).
+ * All other bits in flags must be set to zero. In the future the other bits 
+ * may be used to select from different contact generation strategies.
+ *
+ * @param contact Points to an array of dContactGeom structures. The array
+ * must be able to hold at least the maximum number of contacts. These
+ * dContactGeom structures may be embedded within larger structures in the
+ * array -- the skip parameter is the byte offset from one dContactGeom to
+ * the next in the array. If skip is sizeof(dContactGeom) then contact
+ * points to a normal (C-style) array. It is an error for skip to be smaller
+ * than sizeof(dContactGeom).
+ *
+ * @returns If the geoms intersect, this function returns the number of contact
+ * points generated (and updates the contact array), otherwise it returns 0
+ * (and the contact array is not touched).
+ *
+ * @remarks If a space is passed as o1 or o2 then this function will collide
+ * all objects contained in o1 with all objects contained in o2, and return
+ * the resulting contact points. This method for colliding spaces with geoms
+ * (or spaces with spaces) provides no user control over the individual
+ * collisions. To get that control, use dSpaceCollide or dSpaceCollide2 instead.
+ *
+ * @remarks If o1 and o2 are the same geom then this function will do nothing
+ * and return 0. Technically speaking an object intersects with itself, but it
+ * is not useful to find contact points in this case.
+ *
+ * @remarks This function does not care if o1 and o2 are in the same space or not
+ * (or indeed if they are in any space at all).
+ *
+ * @ingroup collide
+ */
+ODE_API int dCollide (dGeomID o1, dGeomID o2, int flags, dContactGeom *contact,
+             int skip);
+
+/**
+ * @brief Determines which pairs of geoms in a space may potentially intersect,
+ * and calls the callback function for each candidate pair.
+ *
+ * @param space The space to test.
+ *
+ * @param data Passed from dSpaceCollide directly to the callback
+ * function. Its meaning is user defined. The o1 and o2 arguments are the
+ * geoms that may be near each other.
+ *
+ * @param callback A callback function is of type @ref dNearCallback.
+ *
+ * @remarks Other spaces that are contained within the colliding space are
+ * not treated specially, i.e. they are not recursed into. The callback
+ * function may be passed these contained spaces as one or both geom
+ * arguments.
+ *
+ * @remarks dSpaceCollide() is guaranteed to pass all intersecting geom
+ * pairs to the callback function, but may also pass close but
+ * non-intersecting pairs. The number of these calls depends on the
+ * internal algorithms used by the space. Thus you should not expect
+ * that dCollide will return contacts for every pair passed to the
+ * callback.
+ *
+ * @sa dSpaceCollide2
+ * @ingroup collide
+ */
+ODE_API void dSpaceCollide (dSpaceID space, void *data, dNearCallback *callback);
+
+
+/**
+ * @brief Determines which geoms from one space may potentially intersect with 
+ * geoms from another space, and calls the callback function for each candidate 
+ * pair. 
+ *
+ * @param space1 The first space to test.
+ *
+ * @param space2 The second space to test.
+ *
+ * @param data Passed from dSpaceCollide directly to the callback
+ * function. Its meaning is user defined. The o1 and o2 arguments are the
+ * geoms that may be near each other.
+ *
+ * @param callback A callback function is of type @ref dNearCallback.
+ *
+ * @remarks This function can also test a single non-space geom against a 
+ * space. This function is useful when there is a collision hierarchy, i.e. 
+ * when there are spaces that contain other spaces.
+ *
+ * @remarks Other spaces that are contained within the colliding space are
+ * not treated specially, i.e. they are not recursed into. The callback
+ * function may be passed these contained spaces as one or both geom
+ * arguments.
+ *
+ * @remarks Sublevel value of space affects how the spaces are iterated.
+ * Both spaces are recursed only if their sublevels match. Otherwise, only
+ * the space with greater sublevel is recursed and the one with lesser sublevel
+ * is used as a geom itself.
+ *
+ * @remarks dSpaceCollide2() is guaranteed to pass all intersecting geom
+ * pairs to the callback function, but may also pass close but
+ * non-intersecting pairs. The number of these calls depends on the
+ * internal algorithms used by the space. Thus you should not expect
+ * that dCollide will return contacts for every pair passed to the
+ * callback.
+ *
+ * @sa dSpaceCollide
+ * @sa dSpaceSetSublevel
+ * @ingroup collide
+ */
+ODE_API void dSpaceCollide2 (dGeomID space1, dGeomID space2, void *data, dNearCallback *callback);
+
+
+/* ************************************************************************ */
+/* standard classes */
+
+/* the maximum number of user classes that are supported */
+enum {
+  dMaxUserClasses = 4
+};
+
+/* class numbers - each geometry object needs a unique number */
+enum {
+  dSphereClass = 0,
+  dBoxClass,
+  dCapsuleClass,
+  dCylinderClass,
+  dPlaneClass,
+  dRayClass,
+  dConvexClass,
+  dGeomTransformClass,
+  dTriMeshClass,
+  dHeightfieldClass,
+
+  dFirstSpaceClass,
+  dSimpleSpaceClass = dFirstSpaceClass,
+  dHashSpaceClass,
+  dSweepAndPruneSpaceClass, // SAP
+  dQuadTreeSpaceClass,
+  dLastSpaceClass = dQuadTreeSpaceClass,
+
+  dFirstUserClass,
+  dLastUserClass = dFirstUserClass + dMaxUserClasses - 1,
+  dGeomNumClasses
+};
+
+
+/**
+ * @defgroup collide_sphere Sphere Class
+ * @ingroup collide
+ */
+
+/**
+ * @brief Create a sphere geom of the given radius, and return its ID. 
+ *
+ * @param space   a space to contain the new geom. May be null.
+ * @param radius  the radius of the sphere.
+ *
+ * @returns A new sphere geom.
+ *
+ * @remarks The point of reference for a sphere is its center.
+ *
+ * @sa dGeomDestroy
+ * @sa dGeomSphereSetRadius
+ * @ingroup collide_sphere
+ */
+ODE_API dGeomID dCreateSphere (dSpaceID space, dReal radius);
+
+
+/**
+ * @brief Set the radius of a sphere geom.
+ *
+ * @param sphere  the sphere to set.
+ * @param radius  the new radius.
+ *
+ * @sa dGeomSphereGetRadius
+ * @ingroup collide_sphere
+ */
+ODE_API void dGeomSphereSetRadius (dGeomID sphere, dReal radius);
+
+
+/**
+ * @brief Retrieves the radius of a sphere geom.
+ *
+ * @param sphere  the sphere to query.
+ *
+ * @sa dGeomSphereSetRadius
+ * @ingroup collide_sphere
+ */
+ODE_API dReal dGeomSphereGetRadius (dGeomID sphere);
+
+
+/**
+ * @brief Calculate the depth of the a given point within a sphere.
+ *
+ * @param sphere  the sphere to query.
+ * @param x       the X coordinate of the point.
+ * @param y       the Y coordinate of the point.
+ * @param z       the Z coordinate of the point.
+ *
+ * @returns The depth of the point. Points inside the sphere will have a 
+ * positive depth, points outside it will have a negative depth, and points
+ * on the surface will have a depth of zero.
+ *
+ * @ingroup collide_sphere
+ */
+ODE_API dReal dGeomSpherePointDepth (dGeomID sphere, dReal x, dReal y, dReal z);
+
+
+//--> Convex Functions
+ODE_API dGeomID dCreateConvex (dSpaceID space,
+                              dReal *_planes,
+                              unsigned int _planecount,
+                              dReal *_points,
+                              unsigned int _pointcount,unsigned int *_polygons);
+
+ODE_API void dGeomSetConvex (dGeomID g,
+                            dReal *_planes,
+                            unsigned int _count,
+                            dReal *_points,
+                            unsigned int _pointcount,unsigned int *_polygons);
+//<-- Convex Functions
+
+/**
+ * @defgroup collide_box Box Class
+ * @ingroup collide
+ */
+
+/**
+ * @brief Create a box geom with the provided side lengths.
+ *
+ * @param space   a space to contain the new geom. May be null.
+ * @param lx      the length of the box along the X axis
+ * @param ly      the length of the box along the Y axis
+ * @param lz      the length of the box along the Z axis
+ *
+ * @returns A new box geom.
+ *
+ * @remarks The point of reference for a box is its center.
+ *
+ * @sa dGeomDestroy
+ * @sa dGeomBoxSetLengths
+ * @ingroup collide_box
+ */
+ODE_API dGeomID dCreateBox (dSpaceID space, dReal lx, dReal ly, dReal lz);
+
+
+/**
+ * @brief Set the side lengths of the given box.
+ *
+ * @param box  the box to set
+ * @param lx      the length of the box along the X axis
+ * @param ly      the length of the box along the Y axis
+ * @param lz      the length of the box along the Z axis
+ *
+ * @sa dGeomBoxGetLengths
+ * @ingroup collide_box
+ */
+ODE_API void dGeomBoxSetLengths (dGeomID box, dReal lx, dReal ly, dReal lz);
+
+
+/**
+ * @brief Get the side lengths of a box.
+ *
+ * @param box     the box to query
+ * @param result  the returned side lengths
+ *
+ * @sa dGeomBoxSetLengths
+ * @ingroup collide_box
+ */
+ODE_API void dGeomBoxGetLengths (dGeomID box, dVector3 result);
+
+
+/**
+ * @brief Return the depth of a point in a box.
+ * 
+ * @param box  the box to query
+ * @param x    the X coordinate of the point to test.
+ * @param y    the Y coordinate of the point to test.
+ * @param z    the Z coordinate of the point to test.
+ *
+ * @returns The depth of the point. Points inside the box will have a 
+ * positive depth, points outside it will have a negative depth, and points
+ * on the surface will have a depth of zero.
+ */
+ODE_API dReal dGeomBoxPointDepth (dGeomID box, dReal x, dReal y, dReal z);
+
+
+ODE_API dGeomID dCreatePlane (dSpaceID space, dReal a, dReal b, dReal c, dReal 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 not.
+#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);
+ODE_API void dGeomRayGet (dGeomID ray, dVector3 start, dVector3 dir);
+
+/*
+ * Set/get ray flags that influence ray collision detection.
+ * These flags are currently only noticed by the trimesh collider, because
+ * they can make a major differences there.
+ */
+ODE_API void dGeomRaySetParams (dGeomID g, int FirstContact, int BackfaceCull);
+ODE_API void dGeomRayGetParams (dGeomID g, int *FirstContact, int *BackfaceCull);
+ODE_API void dGeomRaySetClosestHit (dGeomID g, int closestHit);
+ODE_API int dGeomRayGetClosestHit (dGeomID g);
+
+#include "collision_trimesh.h"
+
+ODE_API dGeomID dCreateGeomTransform (dSpaceID space);
+ODE_API void dGeomTransformSetGeom (dGeomID g, dGeomID obj);
+ODE_API dGeomID dGeomTransformGetGeom (dGeomID g);
+ODE_API void dGeomTransformSetCleanup (dGeomID g, int mode);
+ODE_API int dGeomTransformGetCleanup (dGeomID g);
+ODE_API void dGeomTransformSetInfo (dGeomID g, int mode);
+ODE_API int dGeomTransformGetInfo (dGeomID g);
+
+
+/* ************************************************************************ */
+/* heightfield functions */
+
+
+// Data storage for heightfield data.
+struct dxHeightfieldData;
+typedef struct dxHeightfieldData* dHeightfieldDataID;
+
+
+/**
+ * @brief Callback prototype
+ *
+ * Used by the callback heightfield data type to sample a height for a
+ * given cell position.
+ *
+ * @param p_user_data User data specified when creating the dHeightfieldDataID
+ * @param x The index of a sample in the local x axis. It is a value
+ * in the range zero to ( nWidthSamples - 1 ).
+ * @param x The index of a sample in the local z axis. It is a value
+ * in the range zero to ( nDepthSamples - 1 ).
+ *
+ * @return The sample height which is then scaled and offset using the
+ * values specified when the heightfield data was created.
+ *
+ * @ingroup collide
+ */
+typedef dReal dHeightfieldGetHeight( void* p_user_data, int x, int z );
+
+
+
+/**
+ * @brief Creates a heightfield geom.
+ *
+ * Uses the information in the given dHeightfieldDataID to construct
+ * a geom representing a heightfield in a collision space.
+ *
+ * @param space The space to add the geom to.
+ * @param data The dHeightfieldDataID created by dGeomHeightfieldDataCreate and
+ * setup by dGeomHeightfieldDataBuildCallback, dGeomHeightfieldDataBuildByte,
+ * dGeomHeightfieldDataBuildShort or dGeomHeightfieldDataBuildFloat.
+ * @param bPlaceable If non-zero this geom can be transformed in the world using the
+ * usual functions such as dGeomSetPosition and dGeomSetRotation. If the geom is
+ * not set as placeable, then it uses a fixed orientation where the global y axis
+ * represents the dynamic 'height' of the heightfield.
+ *
+ * @return A geom id to reference this geom in other calls.
+ *
+ * @ingroup collide
+ */
+ODE_API dGeomID dCreateHeightfield( dSpaceID space,
+                                       dHeightfieldDataID data, int bPlaceable );
+
+
+/**
+ * @brief Creates a new empty dHeightfieldDataID.
+ *
+ * Allocates a new dHeightfieldDataID and returns it. You must call
+ * dGeomHeightfieldDataDestroy to destroy it after the geom has been removed.
+ * The dHeightfieldDataID value is used when specifying a data format type.
+ *
+ * @return A dHeightfieldDataID for use with dGeomHeightfieldDataBuildCallback,
+ * dGeomHeightfieldDataBuildByte, dGeomHeightfieldDataBuildShort or
+ * dGeomHeightfieldDataBuildFloat.
+ * @ingroup collide
+ */
+ODE_API dHeightfieldDataID dGeomHeightfieldDataCreate(void);
+
+
+/**
+ * @brief Destroys a dHeightfieldDataID.
+ *
+ * Deallocates a given dHeightfieldDataID and all managed resources.
+ *
+ * @param d A dHeightfieldDataID created by dGeomHeightfieldDataCreate
+ * @ingroup collide
+ */
+ODE_API void dGeomHeightfieldDataDestroy( dHeightfieldDataID d );
+
+
+
+/**
+ * @brief Configures a dHeightfieldDataID to use a callback to
+ * retrieve height data.
+ *
+ * Before a dHeightfieldDataID can be used by a geom it must be
+ * configured to specify the format of the height data.
+ * This call specifies that the heightfield data is computed by
+ * the user and it should use the given callback when determining
+ * the height of a given element of it's shape.
+ *
+ * @param d A new dHeightfieldDataID created by dGeomHeightfieldDataCreate
+ *
+ * @param width Specifies the total 'width' of the heightfield along
+ * the geom's local x axis.
+ * @param depth Specifies the total 'depth' of the heightfield along
+ * the geom's local z axis.
+ *
+ * @param widthSamples Specifies the number of vertices to sample
+ * along the width of the heightfield. Each vertex has a corresponding
+ * height value which forms the overall shape.
+ * Naturally this value must be at least two or more.
+ * @param depthSamples Specifies the number of vertices to sample
+ * along the depth of the heightfield.
+ *
+ * @param scale A uniform scale applied to all raw height data.
+ * @param offset An offset applied to the scaled height data.
+ *
+ * @param thickness A value subtracted from the lowest height
+ * value which in effect adds an additional cuboid to the base of the
+ * heightfield. This is used to prevent geoms from looping under the
+ * desired terrain and not registering as a collision. Note that the
+ * thickness is not affected by the scale or offset parameters.
+ *
+ * @param bWrap If non-zero the heightfield will infinitely tile in both
+ * directions along the local x and z axes. If zero the heightfield is
+ * bounded from zero to width in the local x axis, and zero to depth in
+ * the local z axis.
+ *
+ * @ingroup collide
+ */
+ODE_API void dGeomHeightfieldDataBuildCallback( dHeightfieldDataID d,
+                               void* pUserData, dHeightfieldGetHeight* pCallback,
+                               dReal width, dReal depth, int widthSamples, int depthSamples,
+                               dReal scale, dReal offset, dReal thickness, int bWrap );
+
+/**
+ * @brief Configures a dHeightfieldDataID to use height data in byte format.
+ *
+ * Before a dHeightfieldDataID can be used by a geom it must be
+ * configured to specify the format of the height data.
+ * This call specifies that the heightfield data is stored as a rectangular
+ * array of bytes (8 bit unsigned) representing the height at each sample point.
+ *
+ * @param d A new dHeightfieldDataID created by dGeomHeightfieldDataCreate
+ *
+ * @param pHeightData A pointer to the height data.
+ * @param bCopyHeightData When non-zero the height data is copied to an
+ * internal store. When zero the height data is accessed by reference and
+ * so must persist throughout the lifetime of the heightfield.
+ *
+ * @param width Specifies the total 'width' of the heightfield along
+ * the geom's local x axis.
+ * @param depth Specifies the total 'depth' of the heightfield along
+ * the geom's local z axis.
+ *
+ * @param widthSamples Specifies the number of vertices to sample
+ * along the width of the heightfield. Each vertex has a corresponding
+ * height value which forms the overall shape.
+ * Naturally this value must be at least two or more.
+ * @param depthSamples Specifies the number of vertices to sample
+ * along the depth of the heightfield.
+ *
+ * @param scale A uniform scale applied to all raw height data.
+ * @param offset An offset applied to the scaled height data.
+ *
+ * @param thickness A value subtracted from the lowest height
+ * value which in effect adds an additional cuboid to the base of the
+ * heightfield. This is used to prevent geoms from looping under the
+ * desired terrain and not registering as a collision. Note that the
+ * thickness is not affected by the scale or offset parameters.
+ *
+ * @param bWrap If non-zero the heightfield will infinitely tile in both
+ * directions along the local x and z axes. If zero the heightfield is
+ * bounded from zero to width in the local x axis, and zero to depth in
+ * the local z axis.
+ *
+ * @ingroup collide
+ */
+ODE_API void dGeomHeightfieldDataBuildByte( dHeightfieldDataID d,
+                               const unsigned char* pHeightData, int bCopyHeightData,
+                               dReal width, dReal depth, int widthSamples, int depthSamples,
+                               dReal scale, dReal offset, dReal thickness,     int bWrap );
+
+/**
+ * @brief Configures a dHeightfieldDataID to use height data in short format.
+ *
+ * Before a dHeightfieldDataID can be used by a geom it must be
+ * configured to specify the format of the height data.
+ * This call specifies that the heightfield data is stored as a rectangular
+ * array of shorts (16 bit signed) representing the height at each sample point.
+ *
+ * @param d A new dHeightfieldDataID created by dGeomHeightfieldDataCreate
+ *
+ * @param pHeightData A pointer to the height data.
+ * @param bCopyHeightData When non-zero the height data is copied to an
+ * internal store. When zero the height data is accessed by reference and
+ * so must persist throughout the lifetime of the heightfield.
+ *
+ * @param width Specifies the total 'width' of the heightfield along
+ * the geom's local x axis.
+ * @param depth Specifies the total 'depth' of the heightfield along
+ * the geom's local z axis.
+ *
+ * @param widthSamples Specifies the number of vertices to sample
+ * along the width of the heightfield. Each vertex has a corresponding
+ * height value which forms the overall shape.
+ * Naturally this value must be at least two or more.
+ * @param depthSamples Specifies the number of vertices to sample
+ * along the depth of the heightfield.
+ *
+ * @param scale A uniform scale applied to all raw height data.
+ * @param offset An offset applied to the scaled height data.
+ *
+ * @param thickness A value subtracted from the lowest height
+ * value which in effect adds an additional cuboid to the base of the
+ * heightfield. This is used to prevent geoms from looping under the
+ * desired terrain and not registering as a collision. Note that the
+ * thickness is not affected by the scale or offset parameters.
+ *
+ * @param bWrap If non-zero the heightfield will infinitely tile in both
+ * directions along the local x and z axes. If zero the heightfield is
+ * bounded from zero to width in the local x axis, and zero to depth in
+ * the local z axis.
+ *
+ * @ingroup collide
+ */
+ODE_API void dGeomHeightfieldDataBuildShort( dHeightfieldDataID d,
+                               const short* pHeightData, int bCopyHeightData,
+                               dReal width, dReal depth, int widthSamples, int depthSamples,
+                               dReal scale, dReal offset, dReal thickness, int bWrap );
+
+/**
+ * @brief Configures a dHeightfieldDataID to use height data in 
+ * single precision floating point format.
+ *
+ * Before a dHeightfieldDataID can be used by a geom it must be
+ * configured to specify the format of the height data.
+ * This call specifies that the heightfield data is stored as a rectangular
+ * array of single precision floats representing the height at each
+ * sample point.
+ *
+ * @param d A new dHeightfieldDataID created by dGeomHeightfieldDataCreate
+ *
+ * @param pHeightData A pointer to the height data.
+ * @param bCopyHeightData When non-zero the height data is copied to an
+ * internal store. When zero the height data is accessed by reference and
+ * so must persist throughout the lifetime of the heightfield.
+ *
+ * @param width Specifies the total 'width' of the heightfield along
+ * the geom's local x axis.
+ * @param depth Specifies the total 'depth' of the heightfield along
+ * the geom's local z axis.
+ *
+ * @param widthSamples Specifies the number of vertices to sample
+ * along the width of the heightfield. Each vertex has a corresponding
+ * height value which forms the overall shape.
+ * Naturally this value must be at least two or more.
+ * @param depthSamples Specifies the number of vertices to sample
+ * along the depth of the heightfield.
+ *
+ * @param scale A uniform scale applied to all raw height data.
+ * @param offset An offset applied to the scaled height data.
+ *
+ * @param thickness A value subtracted from the lowest height
+ * value which in effect adds an additional cuboid to the base of the
+ * heightfield. This is used to prevent geoms from looping under the
+ * desired terrain and not registering as a collision. Note that the
+ * thickness is not affected by the scale or offset parameters.
+ *
+ * @param bWrap If non-zero the heightfield will infinitely tile in both
+ * directions along the local x and z axes. If zero the heightfield is
+ * bounded from zero to width in the local x axis, and zero to depth in
+ * the local z axis.
+ *
+ * @ingroup collide
+ */
+ODE_API void dGeomHeightfieldDataBuildSingle( dHeightfieldDataID d,
+                               const float* pHeightData, int bCopyHeightData,
+                               dReal width, dReal depth, int widthSamples, int depthSamples,
+                               dReal scale, dReal offset, dReal thickness, int bWrap );
+
+/**
+ * @brief Configures a dHeightfieldDataID to use height data in 
+ * double precision floating point format.
+ *
+ * Before a dHeightfieldDataID can be used by a geom it must be
+ * configured to specify the format of the height data.
+ * This call specifies that the heightfield data is stored as a rectangular
+ * array of double precision floats representing the height at each
+ * sample point.
+ *
+ * @param d A new dHeightfieldDataID created by dGeomHeightfieldDataCreate
+ *
+ * @param pHeightData A pointer to the height data.
+ * @param bCopyHeightData When non-zero the height data is copied to an
+ * internal store. When zero the height data is accessed by reference and
+ * so must persist throughout the lifetime of the heightfield.
+ *
+ * @param width Specifies the total 'width' of the heightfield along
+ * the geom's local x axis.
+ * @param depth Specifies the total 'depth' of the heightfield along
+ * the geom's local z axis.
+ *
+ * @param widthSamples Specifies the number of vertices to sample
+ * along the width of the heightfield. Each vertex has a corresponding
+ * height value which forms the overall shape.
+ * Naturally this value must be at least two or more.
+ * @param depthSamples Specifies the number of vertices to sample
+ * along the depth of the heightfield.
+ *
+ * @param scale A uniform scale applied to all raw height data.
+ * @param offset An offset applied to the scaled height data.
+ *
+ * @param thickness A value subtracted from the lowest height
+ * value which in effect adds an additional cuboid to the base of the
+ * heightfield. This is used to prevent geoms from looping under the
+ * desired terrain and not registering as a collision. Note that the
+ * thickness is not affected by the scale or offset parameters.
+ *
+ * @param bWrap If non-zero the heightfield will infinitely tile in both
+ * directions along the local x and z axes. If zero the heightfield is
+ * bounded from zero to width in the local x axis, and zero to depth in
+ * the local z axis.
+ *
+ * @ingroup collide
+ */
+ODE_API void dGeomHeightfieldDataBuildDouble( dHeightfieldDataID d,
+                               const double* pHeightData, int bCopyHeightData,
+                               dReal width, dReal depth, int widthSamples, int depthSamples,
+                               dReal scale, dReal offset, dReal thickness, int bWrap );
+
+/**
+ * @brief Manually set the minimum and maximum height bounds.
+ *
+ * This call allows you to set explicit min / max values after initial
+ * creation typically for callback heightfields which default to +/- infinity,
+ * or those whose data has changed. This must be set prior to binding with a
+ * geom, as the the AABB is not recomputed after it's first generation.
+ *
+ * @remarks The minimum and maximum values are used to compute the AABB
+ * for the heightfield which is used for early rejection of collisions.
+ * A close fit will yield a more efficient collision check.
+ *
+ * @param d A dHeightfieldDataID created by dGeomHeightfieldDataCreate
+ * @param min_height The new minimum height value. Scale, offset and thickness is then applied.
+ * @param max_height The new maximum height value. Scale and offset is then applied.
+ * @ingroup collide
+ */
+ODE_API void dGeomHeightfieldDataSetBounds( dHeightfieldDataID d,
+                               dReal minHeight, dReal maxHeight );
+
+
+/**
+ * @brief Assigns a dHeightfieldDataID to a heightfield geom.
+ *
+ * Associates the given dHeightfieldDataID with a heightfield geom.
+ * This is done without affecting the GEOM_PLACEABLE flag.
+ *
+ * @param g A geom created by dCreateHeightfield
+ * @param d A dHeightfieldDataID created by dGeomHeightfieldDataCreate
+ * @ingroup collide
+ */
+ODE_API void dGeomHeightfieldSetHeightfieldData( dGeomID g, dHeightfieldDataID d );
+
+
+/**
+ * @brief Gets the dHeightfieldDataID bound to a heightfield geom.
+ *
+ * Returns the dHeightfieldDataID associated with a heightfield geom.
+ *
+ * @param g A geom created by dCreateHeightfield
+ * @return The dHeightfieldDataID which may be NULL if none was assigned.
+ * @ingroup collide
+ */
+ODE_API dHeightfieldDataID dGeomHeightfieldGetHeightfieldData( dGeomID g );
+
+
+
+/* ************************************************************************ */
+/* utility functions */
+
+ODE_API void dClosestLineSegmentPoints (const dVector3 a1, const dVector3 a2,
+                               const dVector3 b1, const dVector3 b2,
+                               dVector3 cp1, dVector3 cp2);
+
+ODE_API int dBoxTouchesBox (const dVector3 _p1, const dMatrix3 R1,
+                   const dVector3 side1, const dVector3 _p2,
+                   const dMatrix3 R2, const dVector3 side2);
+
+// The meaning of flags parameter is the same as in dCollide()
+ODE_API int dBoxBox (const dVector3 p1, const dMatrix3 R1,
+            const dVector3 side1, const dVector3 p2,
+            const dMatrix3 R2, const dVector3 side2,
+            dVector3 normal, dReal *depth, int *return_code,
+            int flags, dContactGeom *contact, int skip);
+
+ODE_API void dInfiniteAABB (dGeomID geom, dReal aabb[6]);
+
+
+/* ************************************************************************ */
+/* custom classes */
+
+typedef void dGetAABBFn (dGeomID, dReal aabb[6]);
+typedef int dColliderFn (dGeomID o1, dGeomID o2,
+                        int flags, dContactGeom *contact, int skip);
+typedef dColliderFn * dGetColliderFnFn (int num);
+typedef void dGeomDtorFn (dGeomID o);
+typedef int dAABBTestFn (dGeomID o1, dGeomID o2, dReal aabb[6]);
+
+typedef struct dGeomClass {
+  int bytes;
+  dGetColliderFnFn *collider;
+  dGetAABBFn *aabb;
+  dAABBTestFn *aabb_test;
+  dGeomDtorFn *dtor;
+} dGeomClass;
+
+ODE_API int dCreateGeomClass (const dGeomClass *classptr);
+ODE_API void * dGeomGetClassData (dGeomID);
+ODE_API dGeomID dCreateGeom (int classnum);
+
+/**
+ * @brief Sets a custom collider function for two geom classes. 
+ *
+ * @param i The first geom class handled by this collider
+ * @param j The second geom class handled by this collider
+ * @param fn The collider function to use to determine collisions.
+ * @ingroup collide
+ */
+ODE_API void dSetColliderOverride (int i, int j, dColliderFn *fn);
+
+
+/* ************************************************************************ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/misc/builddeps/dp.linux32/include/ode/collision_space.h b/misc/builddeps/dp.linux32/include/ode/collision_space.h
new file mode 100644 (file)
index 0000000..bf7ef9b
--- /dev/null
@@ -0,0 +1,182 @@
+/*************************************************************************
+ *                                                                       *
+ * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith.       *
+ * All rights reserved.  Email: russ@q12.org   Web: www.q12.org          *
+ *                                                                       *
+ * This library is free software; you can redistribute it and/or         *
+ * modify it under the terms of EITHER:                                  *
+ *   (1) The GNU Lesser General Public License as published by the Free  *
+ *       Software Foundation; either version 2.1 of the License, or (at  *
+ *       your option) any later version. The text of the GNU Lesser      *
+ *       General Public License is included with this library in the     *
+ *       file LICENSE.TXT.                                               *
+ *   (2) The BSD-style license that is included with this library in     *
+ *       the file LICENSE-BSD.TXT.                                       *
+ *                                                                       *
+ * This library is distributed in the hope that it will be useful,       *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files    *
+ * LICENSE.TXT and LICENSE-BSD.TXT for more details.                     *
+ *                                                                       *
+ *************************************************************************/
+
+#ifndef _ODE_COLLISION_SPACE_H_
+#define _ODE_COLLISION_SPACE_H_
+
+#include <ode/common.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct dContactGeom;
+
+/**
+ * @brief User callback for geom-geom collision testing.
+ *
+ * @param data The user data object, as passed to dSpaceCollide.
+ * @param o1   The first geom being tested.
+ * @param o2   The second geom being test.
+ *
+ * @remarks The callback function can call dCollide on o1 and o2 to generate
+ * contact points between each pair. Then these contact points may be added
+ * to the simulation as contact joints. The user's callback function can of
+ * course chose not to call dCollide for any pair, e.g. if the user decides
+ * that those pairs should not interact.
+ *
+ * @ingroup collide
+ */
+typedef void dNearCallback (void *data, dGeomID o1, dGeomID o2);
+
+
+ODE_API dSpaceID dSimpleSpaceCreate (dSpaceID space);
+ODE_API dSpaceID dHashSpaceCreate (dSpaceID space);
+ODE_API dSpaceID dQuadTreeSpaceCreate (dSpaceID space, const dVector3 Center, const dVector3 Extents, int Depth);
+
+
+// SAP
+// Order XZY or ZXY usually works best, if your Y is up.
+#define dSAP_AXES_XYZ  ((0)|(1<<2)|(2<<4))
+#define dSAP_AXES_XZY  ((0)|(2<<2)|(1<<4))
+#define dSAP_AXES_YXZ  ((1)|(0<<2)|(2<<4))
+#define dSAP_AXES_YZX  ((1)|(2<<2)|(0<<4))
+#define dSAP_AXES_ZXY  ((2)|(0<<2)|(1<<4))
+#define dSAP_AXES_ZYX  ((2)|(1<<2)|(0<<4))
+
+ODE_API dSpaceID dSweepAndPruneSpaceCreate( dSpaceID space, int axisorder );
+
+
+
+ODE_API void dSpaceDestroy (dSpaceID);
+
+ODE_API void dHashSpaceSetLevels (dSpaceID space, int minlevel, int maxlevel);
+ODE_API void dHashSpaceGetLevels (dSpaceID space, int *minlevel, int *maxlevel);
+
+ODE_API void dSpaceSetCleanup (dSpaceID space, int mode);
+ODE_API int dSpaceGetCleanup (dSpaceID space);
+
+/**
+* @brief Sets sublevel value for a space.
+*
+* Sublevel affects how the space is handled in dSpaceCollide2 when it is collided
+* with another space. If sublevels of both spaces match, the function iterates 
+* geometries of both spaces and collides them with each other. If sublevel of one
+* space is greater than the sublevel of another one, only the geometries of the 
+* space with greater sublevel are iterated, another space is passed into 
+* collision callback as a geometry itself. By default all the spaces are assigned
+* zero sublevel.
+*
+* @note
+* The space sublevel @e IS @e NOT automatically updated when one space is inserted
+* into another or removed from one. It is a client's responsibility to update sublevel
+* value if necessary.
+*
+* @param space the space to modify
+* @param sublevel the sublevel value to be assigned
+* @ingroup collide
+* @see dSpaceGetSublevel
+* @see dSpaceCollide2
+*/
+ODE_API void dSpaceSetSublevel (dSpaceID space, int sublevel);
+
+/**
+* @brief Gets sublevel value of a space.
+*
+* Sublevel affects how the space is handled in dSpaceCollide2 when it is collided
+* with another space. See @c dSpaceSetSublevel for more details.
+*
+* @param space the space to query
+* @returns the sublevel value of the space
+* @ingroup collide
+* @see dSpaceSetSublevel
+* @see dSpaceCollide2
+*/
+ODE_API int dSpaceGetSublevel (dSpaceID space);
+
+
+/**
+* @brief Sets manual cleanup flag for a space.
+*
+* Manual cleanup flag marks a space as eligible for manual thread data cleanup.
+* This function should be called for every space object right after creation in 
+* case if ODE has been initialized with @c dInitFlagManualThreadCleanup flag.
+* 
+* Failure to set manual cleanup flag for a space may lead to some resources 
+* remaining leaked until the program exit.
+*
+* @param space the space to modify
+* @param mode 1 for manual cleanup mode and 0 for default cleanup mode
+* @ingroup collide
+* @see dSpaceGetManualCleanup
+* @see dInitODE2
+*/
+ODE_API void dSpaceSetManualCleanup (dSpaceID space, int mode);
+
+/**
+* @brief Get manual cleanup flag of a space.
+*
+* Manual cleanup flag marks a space space as eligible for manual thread data cleanup.
+* See @c dSpaceSetManualCleanup for more details.
+* 
+* @param space the space to query
+* @returns 1 for manual cleanup mode and 0 for default cleanup mode of the space
+* @ingroup collide
+* @see dSpaceSetManualCleanup
+* @see dInitODE2
+*/
+ODE_API int dSpaceGetManualCleanup (dSpaceID space);
+
+ODE_API void dSpaceAdd (dSpaceID, dGeomID);
+ODE_API void dSpaceRemove (dSpaceID, dGeomID);
+ODE_API int dSpaceQuery (dSpaceID, dGeomID);
+ODE_API void dSpaceClean (dSpaceID);
+ODE_API int dSpaceGetNumGeoms (dSpaceID);
+ODE_API dGeomID dSpaceGetGeom (dSpaceID, int i);
+
+/**
+ * @brief Given a space, this returns its class.
+ *
+ * The ODE classes are:
+ *  @li dSimpleSpaceClass
+ *  @li dHashSpaceClass
+ *  @li dSweepAndPruneSpaceClass
+ *  @li dQuadTreeSpaceClass
+ *  @li dFirstUserClass
+ *  @li dLastUserClass
+ *
+ * The class id not defined by the user should be between
+ * dFirstSpaceClass and dLastSpaceClass.
+ *
+ * User-defined class will return their own number.
+ *
+ * @param space the space to query
+ * @returns The space class ID.
+ * @ingroup collide
+ */
+ODE_API int dSpaceGetClass(dSpaceID space);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/misc/builddeps/dp.linux32/include/ode/collision_trimesh.h b/misc/builddeps/dp.linux32/include/ode/collision_trimesh.h
new file mode 100644 (file)
index 0000000..f263a9e
--- /dev/null
@@ -0,0 +1,216 @@
+/*************************************************************************
+ *                                                                       *
+ * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith.       *
+ * All rights reserved.  Email: russ@q12.org   Web: www.q12.org          *
+ *                                                                       *
+ * This library is free software; you can redistribute it and/or         *
+ * modify it under the terms of EITHER:                                  *
+ *   (1) The GNU Lesser General Public License as published by the Free  *
+ *       Software Foundation; either version 2.1 of the License, or (at  *
+ *       your option) any later version. The text of the GNU Lesser      *
+ *       General Public License is included with this library in the     *
+ *       file LICENSE.TXT.                                               *
+ *   (2) The BSD-style license that is included with this library in     *
+ *       the file LICENSE-BSD.TXT.                                       *
+ *                                                                       *
+ * This library is distributed in the hope that it will be useful,       *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files    *
+ * LICENSE.TXT and LICENSE-BSD.TXT for more details.                     *
+ *                                                                       *
+ *************************************************************************/
+
+/*
+ * TriMesh code by Erwin de Vries.
+ *
+ * Trimesh data.
+ * This is where the actual vertexdata (pointers), and BV tree is stored.
+ * Vertices should be single precision!
+ * This should be more sophisticated, so that the user can easyly implement
+ * another collision library, but this is a lot of work, and also costs some
+ * performance because some data has to be copied.
+ */
+
+#ifndef _ODE_COLLISION_TRIMESH_H_
+#define _ODE_COLLISION_TRIMESH_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Data storage for triangle meshes.
+ */
+struct dxTriMeshData;
+typedef struct dxTriMeshData* dTriMeshDataID;
+
+/*
+ * These dont make much sense now, but they will later when we add more
+ * features.
+ */
+ODE_API dTriMeshDataID dGeomTriMeshDataCreate(void);
+ODE_API void dGeomTriMeshDataDestroy(dTriMeshDataID g);
+
+
+
+enum { TRIMESH_FACE_NORMALS };
+ODE_API void dGeomTriMeshDataSet(dTriMeshDataID g, int data_id, void* in_data);
+ODE_API void* dGeomTriMeshDataGet(dTriMeshDataID g, int data_id);
+
+
+
+/**
+ * We need to set the last transform after each time step for 
+ * accurate collision response. These functions get and set that transform.
+ * It is stored per geom instance, rather than per dTriMeshDataID.
+ */
+ODE_API void dGeomTriMeshSetLastTransform( dGeomID g, dMatrix4 last_trans );
+ODE_API dReal* dGeomTriMeshGetLastTransform( dGeomID g );
+
+/*
+ * Build a TriMesh data object with single precision vertex data.
+ */
+ODE_API void dGeomTriMeshDataBuildSingle(dTriMeshDataID g,
+                                 const void* Vertices, int VertexStride, int VertexCount, 
+                                 const void* Indices, int IndexCount, int TriStride);
+/* same again with a normals array (used as trimesh-trimesh optimization) */
+ODE_API void dGeomTriMeshDataBuildSingle1(dTriMeshDataID g,
+                                  const void* Vertices, int VertexStride, int VertexCount, 
+                                  const void* Indices, int IndexCount, int TriStride,
+                                  const void* Normals);
+/*
+* Build a TriMesh data object with double precision vertex data.
+*/
+ODE_API void dGeomTriMeshDataBuildDouble(dTriMeshDataID g, 
+                                 const void* Vertices,  int VertexStride, int VertexCount, 
+                                 const void* Indices, int IndexCount, int TriStride);
+/* same again with a normals array (used as trimesh-trimesh optimization) */
+ODE_API void dGeomTriMeshDataBuildDouble1(dTriMeshDataID g, 
+                                  const void* Vertices,  int VertexStride, int VertexCount, 
+                                  const void* Indices, int IndexCount, int TriStride,
+                                  const void* Normals);
+
+/*
+ * Simple build. Single/double precision based on dSINGLE/dDOUBLE!
+ */
+ODE_API void dGeomTriMeshDataBuildSimple(dTriMeshDataID g,
+                                 const dReal* Vertices, int VertexCount,
+                                 const dTriIndex* Indices, int IndexCount);
+/* same again with a normals array (used as trimesh-trimesh optimization) */
+ODE_API void dGeomTriMeshDataBuildSimple1(dTriMeshDataID g,
+                                  const dReal* Vertices, int VertexCount,
+                                  const dTriIndex* Indices, int IndexCount,
+                                  const int* Normals);
+
+/* Preprocess the trimesh data to remove mark unnecessary edges and vertices */
+ODE_API void dGeomTriMeshDataPreprocess(dTriMeshDataID g);
+/* Get and set the internal preprocessed trimesh data buffer, for loading and saving */
+ODE_API void dGeomTriMeshDataGetBuffer(dTriMeshDataID g, unsigned char** buf, int* bufLen);
+ODE_API void dGeomTriMeshDataSetBuffer(dTriMeshDataID g, unsigned char* buf);
+
+
+/*
+ * Per triangle callback. Allows the user to say if he wants a collision with
+ * a particular triangle.
+ */
+typedef int dTriCallback(dGeomID TriMesh, dGeomID RefObject, int TriangleIndex);
+ODE_API void dGeomTriMeshSetCallback(dGeomID g, dTriCallback* Callback);
+ODE_API dTriCallback* dGeomTriMeshGetCallback(dGeomID g);
+
+/*
+ * Per object callback. Allows the user to get the list of triangles in 1
+ * shot. Maybe we should remove this one.
+ */
+typedef void dTriArrayCallback(dGeomID TriMesh, dGeomID RefObject, const int* TriIndices, int TriCount);
+ODE_API void dGeomTriMeshSetArrayCallback(dGeomID g, dTriArrayCallback* ArrayCallback);
+ODE_API dTriArrayCallback* dGeomTriMeshGetArrayCallback(dGeomID g);
+
+/*
+ * Ray callback.
+ * 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 transparency
+ * to determine if a collision should occur.
+ */
+typedef int dTriRayCallback(dGeomID TriMesh, dGeomID Ray, int TriangleIndex, dReal u, dReal v);
+ODE_API void dGeomTriMeshSetRayCallback(dGeomID g, dTriRayCallback* Callback);
+ODE_API dTriRayCallback* dGeomTriMeshGetRayCallback(dGeomID g);
+
+/*
+ * Triangle merging callback.
+ * Allows the user to generate a fake triangle index for a new contact generated
+ * from merging of two other contacts. That index could later be used by the 
+ * user to determine attributes of original triangles used as sources for a 
+ * merged contact.
+ */
+typedef int dTriTriMergeCallback(dGeomID TriMesh, int FirstTriangleIndex, int SecondTriangleIndex);
+ODE_API void dGeomTriMeshSetTriMergeCallback(dGeomID g, dTriTriMergeCallback* Callback);
+ODE_API dTriTriMergeCallback* dGeomTriMeshGetTriMergeCallback(dGeomID g);
+
+/*
+ * Trimesh class
+ * Construction. Callbacks are optional.
+ */
+ODE_API dGeomID dCreateTriMesh(dSpaceID space, dTriMeshDataID Data, dTriCallback* Callback, dTriArrayCallback* ArrayCallback, dTriRayCallback* RayCallback);
+
+ODE_API void dGeomTriMeshSetData(dGeomID g, dTriMeshDataID Data);
+ODE_API dTriMeshDataID dGeomTriMeshGetData(dGeomID g);
+
+
+// enable/disable/check temporal coherence
+ODE_API void dGeomTriMeshEnableTC(dGeomID g, int geomClass, int enable);
+ODE_API int dGeomTriMeshIsTCEnabled(dGeomID g, int geomClass);
+
+/*
+ * Clears the internal temporal coherence caches. When a geom has its
+ * 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.
+ * We should be able to do this automagically.
+ */
+ODE_API void dGeomTriMeshClearTCCache(dGeomID g);
+
+
+/*
+ * returns the TriMeshDataID
+ */
+ODE_API dTriMeshDataID dGeomTriMeshGetTriMeshDataID(dGeomID g);
+
+/*
+ * Gets a triangle.
+ */
+ODE_API void dGeomTriMeshGetTriangle(dGeomID g, int Index, dVector3* v0, dVector3* v1, dVector3* v2);
+
+/*
+ * Gets the point on the requested triangle and the given barycentric
+ * coordinates.
+ */
+ODE_API void dGeomTriMeshGetPoint(dGeomID g, int Index, dReal u, dReal v, dVector3 Out);
+
+/*
+
+This is how the strided data works:
+
+struct StridedVertex{
+       dVector3 Vertex;
+       // Userdata
+};
+int VertexStride = sizeof(StridedVertex);
+
+struct StridedTri{
+       int Indices[3];
+       // Userdata
+};
+int TriStride = sizeof(StridedTri);
+
+*/
+
+
+ODE_API int dGeomTriMeshGetTriangleCount (dGeomID g);
+
+ODE_API void dGeomTriMeshDataUpdate(dTriMeshDataID g);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _ODE_COLLISION_TRIMESH_H_ */
+
diff --git a/misc/builddeps/dp.linux32/include/ode/common.h b/misc/builddeps/dp.linux32/include/ode/common.h
new file mode 100644 (file)
index 0000000..d7b2bba
--- /dev/null
@@ -0,0 +1,420 @@
+/*************************************************************************
+ *                                                                       *
+ * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith.       *
+ * All rights reserved.  Email: russ@q12.org   Web: www.q12.org          *
+ *                                                                       *
+ * This library is free software; you can redistribute it and/or         *
+ * modify it under the terms of EITHER:                                  *
+ *   (1) The GNU Lesser General Public License as published by the Free  *
+ *       Software Foundation; either version 2.1 of the License, or (at  *
+ *       your option) any later version. The text of the GNU Lesser      *
+ *       General Public License is included with this library in the     *
+ *       file LICENSE.TXT.                                               *
+ *   (2) The BSD-style license that is included with this library in     *
+ *       the file LICENSE-BSD.TXT.                                       *
+ *                                                                       *
+ * This library is distributed in the hope that it will be useful,       *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files    *
+ * LICENSE.TXT and LICENSE-BSD.TXT for more details.                     *
+ *                                                                       *
+ *************************************************************************/
+
+#ifndef _ODE_COMMON_H_
+#define _ODE_COMMON_H_
+#include <ode/odeconfig.h>
+#include <ode/error.h>
+#include <math.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#define PURE_INLINE static __inline
+
+
+/* configuration stuff */
+
+/* constants */
+
+/* pi and 1/sqrt(2) are defined here if necessary because they don't get
+ * defined in <math.h> on some platforms (like MS-Windows)
+ */
+
+#ifndef M_PI
+#define M_PI REAL(3.1415926535897932384626433832795029)
+#endif
+#ifndef M_SQRT1_2
+#define M_SQRT1_2 REAL(0.7071067811865475244008443621048490)
+#endif
+
+
+/* debugging:
+ *   IASSERT  is an internal assertion, i.e. a consistency check. if it fails
+ *            we want to know where.
+ *   UASSERT  is a user assertion, i.e. if it fails a nice error message
+ *            should be printed for the user.
+ *   AASSERT  is an arguments assertion, i.e. if it fails "bad argument(s)"
+ *            is printed.
+ *   DEBUGMSG just prints out a message
+ */
+
+#  if defined(__STDC__) && __STDC_VERSION__ >= 199901L
+#    define __FUNCTION__ __func__
+#  endif
+#ifndef dNODEBUG
+#  ifdef __GNUC__
+#    define dIASSERT(a) { if (!(a)) { dDebug (d_ERR_IASSERT, \
+      "assertion \"" #a "\" failed in %s() [%s:%u]",__FUNCTION__,__FILE__,__LINE__); } }
+#    define dUASSERT(a,msg) { if (!(a)) { dDebug (d_ERR_UASSERT, \
+      msg " in %s()", __FUNCTION__); } }
+#    define dDEBUGMSG(msg) { dMessage (d_ERR_UASSERT,                          \
+  msg " in %s() [%s:%u]", __FUNCTION__,__FILE__,__LINE__); }
+#  else // not __GNUC__
+#    define dIASSERT(a) { if (!(a)) { dDebug (d_ERR_IASSERT, \
+      "assertion \"" #a "\" failed in %s:%u",__FILE__,__LINE__); } }
+#    define dUASSERT(a,msg) { if (!(a)) { dDebug (d_ERR_UASSERT, \
+      msg " (%s:%u)", __FILE__,__LINE__); } }
+#    define dDEBUGMSG(msg) { dMessage (d_ERR_UASSERT, \
+      msg " (%s:%u)", __FILE__,__LINE__); }
+#  endif
+#  define dIVERIFY(a) dIASSERT(a)
+#else
+#  define dIASSERT(a) ((void)0)
+#  define dUASSERT(a,msg) ((void)0)
+#  define dDEBUGMSG(msg) ((void)0)
+#  define dIVERIFY(a) ((void)(a))
+#endif
+
+#  ifdef __GNUC__
+#    define dICHECK(a) { if (!(a)) { dDebug (d_ERR_IASSERT, \
+      "assertion \"" #a "\" failed in %s() [%s:%u]",__FUNCTION__,__FILE__,__LINE__); *(int *)0 = 0; } }
+#  else // not __GNUC__
+#    define dICHECK(a) { if (!(a)) { dDebug (d_ERR_IASSERT, \
+      "assertion \"" #a "\" failed in %s:%u",__FILE__,__LINE__); *(int *)0 = 0; } }
+#  endif
+
+// Argument assert is a special case of user assert
+#define dAASSERT(a) dUASSERT(a,"Bad argument(s)")
+
+/* floating point data type, vector, matrix and quaternion types */
+
+#if defined(dSINGLE)
+typedef float dReal;
+#ifdef dDOUBLE
+#error You can only #define dSINGLE or dDOUBLE, not both.
+#endif // dDOUBLE
+#elif defined(dDOUBLE)
+typedef double dReal;
+#else
+#error You must #define dSINGLE or dDOUBLE
+#endif
+
+// Detect if we've got both trimesh engines enabled.
+#if dTRIMESH_ENABLED
+#if dTRIMESH_OPCODE && dTRIMESH_GIMPACT
+#error You can only #define dTRIMESH_OPCODE or dTRIMESH_GIMPACT, not both.
+#endif
+#endif // dTRIMESH_ENABLED
+
+// Define a type for indices, either 16 or 32 bit, based on build option
+// TODO: Currently GIMPACT only supports 32 bit indices.
+#if dTRIMESH_16BIT_INDICES
+#if dTRIMESH_GIMPACT
+typedef uint32 dTriIndex;
+#else // dTRIMESH_GIMPACT
+typedef uint16 dTriIndex;
+#endif // dTRIMESH_GIMPACT
+#else // dTRIMESH_16BIT_INDICES
+typedef uint32 dTriIndex;
+#endif // dTRIMESH_16BIT_INDICES
+
+/* round an integer up to a multiple of 4, except that 0 and 1 are unmodified
+ * (used to compute matrix leading dimensions)
+ */
+#define dPAD(a) (((a) > 1) ? ((((a)-1)|3)+1) : (a))
+
+/* these types are mainly just used in headers */
+typedef dReal dVector3[4];
+typedef dReal dVector4[4];
+typedef dReal dMatrix3[4*3];
+typedef dReal dMatrix4[4*4];
+typedef dReal dMatrix6[8*6];
+typedef dReal dQuaternion[4];
+
+
+/* precision dependent scalar math functions */
+
+#if defined(dSINGLE)
+
+#define REAL(x) (x ## f)                                       /* form a constant */
+#define dRecip(x) ((1.0f/(x)))                         /* reciprocal */
+#define dSqrt(x) (sqrtf(x))                    /* square root */
+#define dRecipSqrt(x) ((1.0f/sqrtf(x)))                /* reciprocal square root */
+#define dSin(x) (sinf(x))                              /* sine */
+#define dCos(x) (cosf(x))                              /* cosine */
+#define dFabs(x) (fabsf(x))                    /* absolute value */
+#define dAtan2(y,x) (atan2f(y,x))              /* arc tangent with 2 args */
+#define dFMod(a,b) (fmodf(a,b))                /* modulo */
+#define dFloor(x) floorf(x)                    /* floor */
+#define dCeil(x) ceilf(x)                      /* floor */
+#define dCopySign(a,b) ((dReal)copysignf(a,b)) /* copy value sign */
+#define dNextAfter(x, y) nextafterf(x, y) /* next value after */
+
+#if defined(_ODE__NEXTAFTERF_REQUIRED)
+float _nextafterf(float x, float y);
+#endif
+
+#ifdef HAVE___ISNANF
+#define dIsNan(x) (__isnanf(x))
+#elif defined(HAVE__ISNANF)
+#define dIsNan(x) (_isnanf(x))
+#elif defined(HAVE_ISNANF)
+#define dIsNan(x) (isnanf(x))
+#else
+  /*
+     fall back to _isnan which is the VC way,
+     this may seem redundant since we already checked
+     for _isnan before, but if isnan is detected by
+     configure but is not found during compilation
+     we should always make sure we check for __isnanf,
+     _isnanf and isnanf in that order before falling
+     back to a default
+  */
+#define dIsNan(x) (_isnan(x))
+#endif
+
+#elif defined(dDOUBLE)
+
+#define REAL(x) (x)
+#define dRecip(x) (1.0/(x))
+#define dSqrt(x) sqrt(x)
+#define dRecipSqrt(x) (1.0/sqrt(x))
+#define dSin(x) sin(x)
+#define dCos(x) cos(x)
+#define dFabs(x) fabs(x)
+#define dAtan2(y,x) atan2((y),(x))
+#define dFMod(a,b) (fmod((a),(b)))
+#define dFloor(x) floor(x)
+#define dCeil(x) ceil(x)
+#define dCopySign(a,b) (copysign((a),(b)))
+#define dNextAfter(x, y) nextafter(x, y)
+
+#undef _ODE__NEXTAFTERF_REQUIRED
+
+#ifdef HAVE___ISNAN
+#define dIsNan(x) (__isnan(x))
+#elif defined(HAVE__ISNAN)
+#define dIsNan(x) (_isnan(x))
+#elif defined(HAVE_ISNAN)
+#define dIsNan(x) (isnan(x))
+#else
+#define dIsNan(x) (_isnan(x))
+#endif
+
+#else
+#error You must #define dSINGLE or dDOUBLE
+#endif
+
+/* internal object types (all prefixed with `dx') */
+
+struct dxWorld;                /* dynamics world */
+struct dxSpace;                /* collision space */
+struct dxBody;         /* rigid body (dynamics object) */
+struct dxGeom;         /* geometry (collision object) */
+struct dxJoint;
+struct dxJointNode;
+struct dxJointGroup;
+struct dxWorldProcessThreadingManager;
+
+typedef struct dxWorld *dWorldID;
+typedef struct dxSpace *dSpaceID;
+typedef struct dxBody *dBodyID;
+typedef struct dxGeom *dGeomID;
+typedef struct dxJoint *dJointID;
+typedef struct dxJointGroup *dJointGroupID;
+typedef struct dxWorldProcessThreadingManager *dWorldStepThreadingManagerID;
+
+/* error numbers */
+
+enum {
+  d_ERR_UNKNOWN = 0,           /* unknown error */
+  d_ERR_IASSERT,               /* internal assertion failed */
+  d_ERR_UASSERT,               /* user assertion failed */
+  d_ERR_LCP                    /* user assertion failed */
+};
+
+
+/* joint type numbers */
+
+typedef enum {
+  dJointTypeNone = 0,          /* or "unknown" */
+  dJointTypeBall,
+  dJointTypeHinge,
+  dJointTypeSlider,
+  dJointTypeContact,
+  dJointTypeUniversal,
+  dJointTypeHinge2,
+  dJointTypeFixed,
+  dJointTypeNull,
+  dJointTypeAMotor,
+  dJointTypeLMotor,
+  dJointTypePlane2D,
+  dJointTypePR,
+  dJointTypePU,
+  dJointTypePiston
+} dJointType;
+
+
+/* an alternative way of setting joint parameters, using joint parameter
+ * structures and member constants. we don't actually do this yet.
+ */
+
+/*
+typedef struct dLimot {
+  int mode;
+  dReal lostop, histop;
+  dReal vel, fmax;
+  dReal fudge_factor;
+  dReal bounce, soft;
+  dReal suspension_erp, suspension_cfm;
+} dLimot;
+
+enum {
+  dLimotLoStop         = 0x0001,
+  dLimotHiStop         = 0x0002,
+  dLimotVel            = 0x0004,
+  dLimotFMax           = 0x0008,
+  dLimotFudgeFactor    = 0x0010,
+  dLimotBounce         = 0x0020,
+  dLimotSoft           = 0x0040
+};
+*/
+
+
+/* standard joint parameter names. why are these here? - because we don't want
+ * to include all the joint function definitions in joint.cpp. hmmmm.
+ * MSVC complains if we call D_ALL_PARAM_NAMES_X with a blank second argument,
+ * which is why we have the D_ALL_PARAM_NAMES macro as well. please copy and
+ * paste between these two.
+ */
+
+#define D_ALL_PARAM_NAMES(start) \
+  /* parameters for limits and motors */ \
+  dParamLoStop = start, \
+  dParamHiStop, \
+  dParamVel, \
+  dParamFMax, \
+  dParamFudgeFactor, \
+  dParamBounce, \
+  dParamCFM, \
+  dParamStopERP, \
+  dParamStopCFM, \
+  /* parameters for suspension */ \
+  dParamSuspensionERP, \
+  dParamSuspensionCFM, \
+  dParamERP, \
+
+  //////////////////////////////////////////////////////////////////////////////
+  /// \enum  D_ALL_PARAM_NAMES_X
+  ///
+  /// \var dParamGroup This is the starting value of the different group
+  ///                  (i.e. dParamGroup1, dParamGroup2, dParamGroup3)
+  ///                  It also helps in the use of parameter
+  ///                  (dParamGroup2 | dParamFMax) == dParamFMax2
+  //////////////////////////////////////////////////////////////////////////////
+#define D_ALL_PARAM_NAMES_X(start,x) \
+  dParamGroup ## x = start, \
+  /* parameters for limits and motors */ \
+  dParamLoStop ## x = start, \
+  dParamHiStop ## x, \
+  dParamVel ## x, \
+  dParamFMax ## x, \
+  dParamFudgeFactor ## x, \
+  dParamBounce ## x, \
+  dParamCFM ## x, \
+  dParamStopERP ## x, \
+  dParamStopCFM ## x, \
+  /* parameters for suspension */ \
+  dParamSuspensionERP ## x, \
+  dParamSuspensionCFM ## x, \
+  dParamERP ## x,
+
+enum {
+  D_ALL_PARAM_NAMES(0)
+  dParamsInGroup,     ///< Number of parameter in a group
+  D_ALL_PARAM_NAMES_X(0x000,1)
+  D_ALL_PARAM_NAMES_X(0x100,2)
+  D_ALL_PARAM_NAMES_X(0x200,3)
+
+  /* add a multiple of this constant to the basic parameter numbers to get
+   * the parameters for the second, third etc axes.
+   */
+  dParamGroup=0x100
+};
+
+
+/* angular motor mode numbers */
+
+enum {
+  dAMotorUser = 0,
+  dAMotorEuler = 1
+};
+
+
+/* joint force feedback information */
+
+typedef struct dJointFeedback {
+  dVector3 f1;         /* force applied to body 1 */
+  dVector3 t1;         /* torque applied to body 1 */
+  dVector3 f2;         /* force applied to body 2 */
+  dVector3 t2;         /* torque applied to body 2 */
+} dJointFeedback;
+
+
+/* private functions that must be implemented by the collision library:
+ * (1) indicate that a geom has moved, (2) get the next geom in a body list.
+ * these functions are called whenever the position of geoms connected to a
+ * body have changed, e.g. with dBodySetPosition(), dBodySetRotation(), or
+ * when the ODE step function updates the body state.
+ */
+
+void dGeomMoved (dGeomID);
+dGeomID dGeomGetBodyNext (dGeomID);
+
+/**
+ * dGetConfiguration returns the specific ODE build configuration as
+ * a string of tokens. The string can be parsed in a similar way to
+ * the OpenGL extension mechanism, the naming convention should be
+ * familiar too. The following extensions are reported:
+ *
+ * ODE
+ * ODE_single_precision
+ * ODE_double_precision
+ * ODE_EXT_no_debug
+ * ODE_EXT_trimesh
+ * ODE_EXT_opcode
+ * ODE_EXT_gimpact
+ * ODE_EXT_malloc_not_alloca
+ * ODE_EXT_gyroscopic
+ * ODE_OPC_16bit_indices
+ * ODE_OPC_new_collider
+*/
+ODE_API const char* dGetConfiguration (void);
+
+/**
+ * Helper to check for a token in the ODE configuration string.
+ * Caution, this function is case sensitive.
+ *
+ * @param token A configuration token, see dGetConfiguration for details
+ *
+ * @return 1 if exact token is present, 0 if not present
+ */
+ODE_API int dCheckConfiguration( const char* token );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/misc/builddeps/dp.linux32/include/ode/compatibility.h b/misc/builddeps/dp.linux32/include/ode/compatibility.h
new file mode 100644 (file)
index 0000000..b370986
--- /dev/null
@@ -0,0 +1,40 @@
+/*************************************************************************
+ *                                                                       *
+ * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith.       *
+ * All rights reserved.  Email: russ@q12.org   Web: www.q12.org          *
+ *                                                                       *
+ * This library is free software; you can redistribute it and/or         *
+ * modify it under the terms of EITHER:                                  *
+ *   (1) The GNU Lesser General Public License as published by the Free  *
+ *       Software Foundation; either version 2.1 of the License, or (at  *
+ *       your option) any later version. The text of the GNU Lesser      *
+ *       General Public License is included with this library in the     *
+ *       file LICENSE.TXT.                                               *
+ *   (2) The BSD-style license that is included with this library in     *
+ *       the file LICENSE-BSD.TXT.                                       *
+ *                                                                       *
+ * This library is distributed in the hope that it will be useful,       *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files    *
+ * LICENSE.TXT and LICENSE-BSD.TXT for more details.                     *
+ *                                                                       *
+ *************************************************************************/
+
+#ifndef _ODE_COMPATIBILITY_H_
+#define _ODE_COMPATIBILITY_H_
+
+/*
+ * ODE's backward compatibility system ensures that as ODE's API
+ * evolves, user code will not break.
+ */
+
+/*
+ * These new rotation function names are more consistent with the
+ * rest of the API.
+ */
+#define dQtoR(q,R) dRfromQ((R),(q))
+#define dRtoQ(R,q) dQfromR((q),(R))
+#define dWtoDQ(w,q,dq) dDQfromW((dq),(w),(q))
+
+
+#endif
diff --git a/misc/builddeps/dp.linux32/include/ode/contact.h b/misc/builddeps/dp.linux32/include/ode/contact.h
new file mode 100644 (file)
index 0000000..8bb810f
--- /dev/null
@@ -0,0 +1,104 @@
+/*************************************************************************
+ *                                                                       *
+ * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith.       *
+ * All rights reserved.  Email: russ@q12.org   Web: www.q12.org          *
+ *                                                                       *
+ * This library is free software; you can redistribute it and/or         *
+ * modify it under the terms of EITHER:                                  *
+ *   (1) The GNU Lesser General Public License as published by the Free  *
+ *       Software Foundation; either version 2.1 of the License, or (at  *
+ *       your option) any later version. The text of the GNU Lesser      *
+ *       General Public License is included with this library in the     *
+ *       file LICENSE.TXT.                                               *
+ *   (2) The BSD-style license that is included with this library in     *
+ *       the file LICENSE-BSD.TXT.                                       *
+ *                                                                       *
+ * This library is distributed in the hope that it will be useful,       *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files    *
+ * LICENSE.TXT and LICENSE-BSD.TXT for more details.                     *
+ *                                                                       *
+ *************************************************************************/
+
+#ifndef _ODE_CONTACT_H_
+#define _ODE_CONTACT_H_
+
+#include <ode/common.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+enum {
+  dContactMu2          = 0x001,
+  dContactFDir1                = 0x002,
+  dContactBounce       = 0x004,
+  dContactSoftERP      = 0x008,
+  dContactSoftCFM      = 0x010,
+  dContactMotion1      = 0x020,
+  dContactMotion2      = 0x040,
+  dContactMotionN      = 0x080,
+  dContactSlip1                = 0x100,
+  dContactSlip2                = 0x200,
+
+  dContactApprox0      = 0x0000,
+  dContactApprox1_1    = 0x1000,
+  dContactApprox1_2    = 0x2000,
+  dContactApprox1      = 0x3000
+};
+
+
+typedef struct dSurfaceParameters {
+  /* must always be defined */
+  int mode;
+  dReal mu;
+
+  /* only defined if the corresponding flag is set in mode */
+  dReal mu2;
+  dReal bounce;
+  dReal bounce_vel;
+  dReal soft_erp;
+  dReal soft_cfm;
+  dReal motion1,motion2,motionN;
+  dReal slip1,slip2;
+} dSurfaceParameters;
+
+
+/**
+ * @brief Describe the contact point between two geoms.
+ *
+ * If two bodies touch, or if a body touches a static feature in its 
+ * environment, the contact is represented by one or more "contact 
+ * points", described by dContactGeom.
+ *
+ * The convention is that if body 1 is moved along the normal vector by 
+ * a distance depth (or equivalently if body 2 is moved the same distance 
+ * in the opposite direction) then the contact depth will be reduced to 
+ * zero. This means that the normal vector points "in" to body 1.
+ *
+ * @ingroup collide
+ */
+typedef struct dContactGeom {
+  dVector3 pos;          ///< contact position
+  dVector3 normal;       ///< normal vector
+  dReal depth;           ///< penetration depth
+  dGeomID g1,g2;         ///< the colliding geoms
+  int side1,side2;       ///< (to be documented)
+} dContactGeom;
+
+
+/* contact info used by contact joint */
+
+typedef struct dContact {
+  dSurfaceParameters surface;
+  dContactGeom geom;
+  dVector3 fdir1;
+} dContact;
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/misc/builddeps/dp.linux32/include/ode/error.h b/misc/builddeps/dp.linux32/include/ode/error.h
new file mode 100644 (file)
index 0000000..20b9ba4
--- /dev/null
@@ -0,0 +1,63 @@
+/*************************************************************************
+ *                                                                       *
+ * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith.       *
+ * All rights reserved.  Email: russ@q12.org   Web: www.q12.org          *
+ *                                                                       *
+ * This library is free software; you can redistribute it and/or         *
+ * modify it under the terms of EITHER:                                  *
+ *   (1) The GNU Lesser General Public License as published by the Free  *
+ *       Software Foundation; either version 2.1 of the License, or (at  *
+ *       your option) any later version. The text of the GNU Lesser      *
+ *       General Public License is included with this library in the     *
+ *       file LICENSE.TXT.                                               *
+ *   (2) The BSD-style license that is included with this library in     *
+ *       the file LICENSE-BSD.TXT.                                       *
+ *                                                                       *
+ * This library is distributed in the hope that it will be useful,       *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files    *
+ * LICENSE.TXT and LICENSE-BSD.TXT for more details.                     *
+ *                                                                       *
+ *************************************************************************/
+
+/* this comes from the `reuse' library. copy any changes back to the source */
+
+#ifndef _ODE_ERROR_H_
+#define _ODE_ERROR_H_
+
+#include <ode/odeconfig.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* all user defined error functions have this type. error and debug functions
+ * should not return.
+ */
+typedef void dMessageFunction (int errnum, const char *msg, va_list ap);
+
+/* set a new error, debug or warning handler. if fn is 0, the default handlers
+ * are used.
+ */
+ODE_API void dSetErrorHandler (dMessageFunction *fn);
+ODE_API void dSetDebugHandler (dMessageFunction *fn);
+ODE_API void dSetMessageHandler (dMessageFunction *fn);
+
+/* return the current error, debug or warning handler. if the return value is
+ * 0, the default handlers are in place.
+ */
+ODE_API dMessageFunction *dGetErrorHandler(void);
+ODE_API dMessageFunction *dGetDebugHandler(void);
+ODE_API dMessageFunction *dGetMessageHandler(void);
+
+/* generate a fatal error, debug trap or a message. */
+ODE_API void dError (int num, const char *msg, ...);
+ODE_API void dDebug (int num, const char *msg, ...);
+ODE_API void dMessage (int num, const char *msg, ...);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/misc/builddeps/dp.linux32/include/ode/export-dif.h b/misc/builddeps/dp.linux32/include/ode/export-dif.h
new file mode 100644 (file)
index 0000000..f6578ac
--- /dev/null
@@ -0,0 +1,40 @@
+/*************************************************************************
+ *                                                                       *
+ * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith.       *
+ * All rights reserved.  Email: russ@q12.org   Web: www.q12.org          *
+ *                                                                       *
+ * This library is free software; you can redistribute it and/or         *
+ * modify it under the terms of EITHER:                                  *
+ *   (1) The GNU Lesser General Public License as published by the Free  *
+ *       Software Foundation; either version 2.1 of the License, or (at  *
+ *       your option) any later version. The text of the GNU Lesser      *
+ *       General Public License is included with this library in the     *
+ *       file LICENSE.TXT.                                               *
+ *   (2) The BSD-style license that is included with this library in     *
+ *       the file LICENSE-BSD.TXT.                                       *
+ *                                                                       *
+ * This library is distributed in the hope that it will be useful,       *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files    *
+ * LICENSE.TXT and LICENSE-BSD.TXT for more details.                     *
+ *                                                                       *
+ *************************************************************************/
+
+#ifndef _ODE_EXPORT_DIF_
+#define _ODE_EXPORT_DIF_
+
+#include <ode/common.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ODE_API void dWorldExportDIF (dWorldID w, FILE *file, const char *world_name);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/misc/builddeps/dp.linux32/include/ode/mass.h b/misc/builddeps/dp.linux32/include/ode/mass.h
new file mode 100644 (file)
index 0000000..d74500c
--- /dev/null
@@ -0,0 +1,144 @@
+/*************************************************************************
+ *                                                                       *
+ * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith.       *
+ * All rights reserved.  Email: russ@q12.org   Web: www.q12.org          *
+ *                                                                       *
+ * This library is free software; you can redistribute it and/or         *
+ * modify it under the terms of EITHER:                                  *
+ *   (1) The GNU Lesser General Public License as published by the Free  *
+ *       Software Foundation; either version 2.1 of the License, or (at  *
+ *       your option) any later version. The text of the GNU Lesser      *
+ *       General Public License is included with this library in the     *
+ *       file LICENSE.TXT.                                               *
+ *   (2) The BSD-style license that is included with this library in     *
+ *       the file LICENSE-BSD.TXT.                                       *
+ *                                                                       *
+ * This library is distributed in the hope that it will be useful,       *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files    *
+ * LICENSE.TXT and LICENSE-BSD.TXT for more details.                     *
+ *                                                                       *
+ *************************************************************************/
+
+#ifndef _ODE_MASS_H_
+#define _ODE_MASS_H_
+
+#include <ode/common.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct dMass;
+typedef struct dMass dMass;
+
+/**
+ * Check if a mass structure has valid value.
+ * The function check if the mass and innertia matrix are positive definits
+ *
+ * @param m A mass structure to check
+ *
+ * @return 1 if both codition are met
+ */
+ODE_API int dMassCheck(const dMass *m);
+
+ODE_API void dMassSetZero (dMass *);
+
+ODE_API void dMassSetParameters (dMass *, dReal themass,
+                        dReal cgx, dReal cgy, dReal cgz,
+                        dReal I11, dReal I22, dReal I33,
+                        dReal I12, dReal I13, dReal I23);
+
+ODE_API void dMassSetSphere (dMass *, dReal density, dReal radius);
+ODE_API void dMassSetSphereTotal (dMass *, dReal total_mass, dReal radius);
+
+ODE_API void dMassSetCapsule (dMass *, dReal density, int direction,
+                       dReal radius, dReal length);
+ODE_API void dMassSetCapsuleTotal (dMass *, dReal total_mass, int direction,
+                       dReal radius, dReal length);
+
+ODE_API void dMassSetCylinder (dMass *, dReal density, int direction,
+                      dReal radius, dReal length);
+ODE_API void dMassSetCylinderTotal (dMass *, dReal total_mass, int direction,
+                           dReal radius, dReal length);
+
+ODE_API void dMassSetBox (dMass *, dReal density,
+                 dReal lx, dReal ly, dReal lz);
+ODE_API void dMassSetBoxTotal (dMass *, dReal total_mass,
+                      dReal lx, dReal ly, dReal lz);
+
+ODE_API void dMassSetTrimesh (dMass *, dReal density, dGeomID g);
+
+ODE_API void dMassSetTrimeshTotal (dMass *m, dReal total_mass, dGeomID g);
+
+ODE_API void dMassAdjust (dMass *, dReal newmass);
+
+ODE_API void dMassTranslate (dMass *, dReal x, dReal y, dReal z);
+
+ODE_API void dMassRotate (dMass *, const dMatrix3 R);
+
+ODE_API void dMassAdd (dMass *a, const dMass *b);
+
+
+// Backwards compatible API
+ODE_API ODE_API_DEPRECATED void dMassSetCappedCylinder(dMass *a, dReal b, int c, dReal d, dReal e);
+ODE_API ODE_API_DEPRECATED void dMassSetCappedCylinderTotal(dMass *a, dReal b, int c, dReal d, dReal e);
+
+
+struct dMass {
+  dReal mass;
+  dVector3 c;
+  dMatrix3 I;
+
+#ifdef __cplusplus
+  dMass()
+    { dMassSetZero (this); }
+  void setZero()
+    { dMassSetZero (this); }
+  void setParameters (dReal themass, dReal cgx, dReal cgy, dReal cgz,
+                     dReal I11, dReal I22, dReal I33,
+                     dReal I12, dReal I13, dReal I23)
+    { dMassSetParameters (this,themass,cgx,cgy,cgz,I11,I22,I33,I12,I13,I23); }
+
+  void setSphere (dReal density, dReal radius)
+    { dMassSetSphere (this,density,radius); }
+  void setSphereTotal (dReal total, dReal radius)
+    { dMassSetSphereTotal (this,total,radius); }
+
+  void setCapsule (dReal density, int direction, dReal radius, dReal length)
+    { dMassSetCapsule (this,density,direction,radius,length); }
+  void setCapsuleTotal (dReal total, int direction, dReal radius, dReal length)
+    { dMassSetCapsule (this,total,direction,radius,length); }
+
+  void setCylinder(dReal density, int direction, dReal radius, dReal length)
+    { dMassSetCylinder (this,density,direction,radius,length); }
+  void setCylinderTotal(dReal total, int direction, dReal radius, dReal length)
+    { dMassSetCylinderTotal (this,total,direction,radius,length); }
+
+  void setBox (dReal density, dReal lx, dReal ly, dReal lz)
+    { dMassSetBox (this,density,lx,ly,lz); }
+  void setBoxTotal (dReal total, dReal lx, dReal ly, dReal lz)
+    { dMassSetBoxTotal (this,total,lx,ly,lz); }
+
+  void setTrimesh(dReal density, dGeomID g)
+    { dMassSetTrimesh (this, density, g); }
+  void setTrimeshTotal(dReal total, dGeomID g)
+    { dMassSetTrimeshTotal (this, total, g); }
+
+  void adjust (dReal newmass)
+    { dMassAdjust (this,newmass); }
+  void translate (dReal x, dReal y, dReal z)
+    { dMassTranslate (this,x,y,z); }
+  void rotate (const dMatrix3 R)
+    { dMassRotate (this,R); }
+  void add (const dMass *b)
+    { dMassAdd (this,b); }
+#endif
+};
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/misc/builddeps/dp.linux32/include/ode/matrix.h b/misc/builddeps/dp.linux32/include/ode/matrix.h
new file mode 100644 (file)
index 0000000..e177f44
--- /dev/null
@@ -0,0 +1,280 @@
+/*************************************************************************
+ *                                                                       *
+ * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith.       *
+ * All rights reserved.  Email: russ@q12.org   Web: www.q12.org          *
+ *                                                                       *
+ * This library is free software; you can redistribute it and/or         *
+ * modify it under the terms of EITHER:                                  *
+ *   (1) The GNU Lesser General Public License as published by the Free  *
+ *       Software Foundation; either version 2.1 of the License, or (at  *
+ *       your option) any later version. The text of the GNU Lesser      *
+ *       General Public License is included with this library in the     *
+ *       file LICENSE.TXT.                                               *
+ *   (2) The BSD-style license that is included with this library in     *
+ *       the file LICENSE-BSD.TXT.                                       *
+ *                                                                       *
+ * This library is distributed in the hope that it will be useful,       *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files    *
+ * LICENSE.TXT and LICENSE-BSD.TXT for more details.                     *
+ *                                                                       *
+ *************************************************************************/
+
+/* optimized and unoptimized vector and matrix functions */
+
+#ifndef _ODE_MATRIX_H_
+#define _ODE_MATRIX_H_
+
+#include <ode/common.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/* set a vector/matrix of size n to all zeros, or to a specific value. */
+
+ODE_API void dSetZero (dReal *a, int n);
+ODE_API void dSetValue (dReal *a, int n, dReal value);
+
+
+/* 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).
+ */
+
+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.
+ * all vectors are n*1. if n <= 0 then zeroes will be returned (in which case
+ * the input vectors need not be valid). this function is somewhat faster
+ * than calling dDot() for all of the combinations separately.
+ */
+
+/* NOT INCLUDED in the library for now.
+void dMultidot2 (const dReal *a0, const dReal *a1,
+                const dReal *b, dReal *outsum, int n);
+*/
+
+
+/* matrix multiplication. all matrices are stored in standard row format.
+ * the digit refers to the argument that is transposed:
+ *   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)
+ *   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
+ * B or C are stored in standard column format.
+ */
+
+ODE_API void dMultiply0 (dReal *A, const dReal *B, const dReal *C, int p,int q,int r);
+ODE_API void dMultiply1 (dReal *A, const dReal *B, const dReal *C, int p,int q,int r);
+ODE_API void dMultiply2 (dReal *A, const dReal *B, const dReal *C, int p,int q,int r);
+
+
+/* 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 triangle
+ * will be such that L*L'=A. return 1 on success and 0 on failure (on failure
+ * the matrix is not positive definite).
+ */
+
+ODE_API int dFactorCholesky (dReal *A, int n);
+
+
+/* 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.
+ */
+
+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
+ * Ainv. this is not especially fast. this returns 1 on success (A was
+ * positive definite) or 0 on failure (not PD).
+ */
+
+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).
+ * 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
+ * is not positive definite. A is stored by rows. A is not altered.
+ */
+
+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
+ * the diagonal, and D is diagonal.
+ * 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
+ * written) and the reciprocal of the diagonal elements of D are written into
+ * d.
+ */
+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,
+ * and x,b are n*1. b is overwritten with x.
+ * the leading dimension of L is `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,
+ * and x,b are n*1. b is overwritten with x.
+ * the leading dimension of L is `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) */
+
+ODE_API void dVectorScale (dReal *a, const dReal *d, int n);
+
+
+/* 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 matrix
+ * D, solve L*D*L'*x=b where x,b are n*1. x overwrites b.
+ * the leading dimension of L is `nskip'.
+ */
+
+ODE_API void dSolveLDLT (const dReal *L, const dReal *d, dReal *b, int n, int nskip);
+
+
+/* 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:
+ *
+ *    [ b a' ]     <-- b is a[0]
+ *    [ a 0  ]     <-- a is a[1..n-1]
+ *
+ *   - L has size n*n, its leading dimension is nskip. L is lower triangular
+ *     with ones on the diagonal. only the lower triangle of L is referenced.
+ *   - d has size n. d contains the reciprocal diagonal elements of D.
+ *   - a has size n.
+ * 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. 
+ */
+ODE_API void dLDLTAddTL (dReal *L, dReal *d, const dReal *a, int n, int nskip);
+
+
+/* given an L*D*L' factorization of a permuted matrix A, produce a new
+ * factorization for row and column `r' removed.
+ *   - A has size n1*n1, its leading dimension in nskip. A is symmetric and
+ *     positive definite. only the lower triangle of A is referenced.
+ *     A itself may actually be an array of row pointers.
+ *   - L has size n2*n2, its leading dimension in nskip. L is lower triangular
+ *     with ones on the diagonal. only the lower triangle of L is referenced.
+ *   - 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
+ *     must be in the range 0..n1-1.
+ *   - 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 leading
+ * dimension. the last row and column of L, and the last element of d, are
+ * undefined on exit.
+ *
+ * a fast O(n^2) algorithm is used. see ldltremove.m for further comments.
+ */
+ODE_API void dLDLTRemove (dReal **A, const int *p, dReal *L, dReal *d,
+                 int n1, int n2, int r, int nskip);
+
+
+/* given an n*n matrix A (with leading dimension nskip), remove the r'th row
+ * 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.
+ */
+ODE_API void dRemoveRowCol (dReal *A, int n, int nskip, int r);
+
+
+#if defined(__ODE__)
+
+void _dSetZero (dReal *a, size_t n);
+void _dSetValue (dReal *a, size_t n, dReal value);
+dReal _dDot (const dReal *a, const dReal *b, int n);
+void _dMultiply0 (dReal *A, const dReal *B, const dReal *C, int p,int q,int r);
+void _dMultiply1 (dReal *A, const dReal *B, const dReal *C, int p,int q,int r);
+void _dMultiply2 (dReal *A, const dReal *B, const dReal *C, int p,int q,int r);
+int _dFactorCholesky (dReal *A, int n, void *tmpbuf);
+void _dSolveCholesky (const dReal *L, dReal *b, int n, void *tmpbuf);
+int _dInvertPDMatrix (const dReal *A, dReal *Ainv, int n, void *tmpbuf);
+int _dIsPositiveDefinite (const dReal *A, int n, void *tmpbuf);
+void _dFactorLDLT (dReal *A, dReal *d, int n, int nskip);
+void _dSolveL1 (const dReal *L, dReal *b, int n, int nskip);
+void _dSolveL1T (const dReal *L, dReal *b, int n, int nskip);
+void _dVectorScale (dReal *a, const dReal *d, int n);
+void _dSolveLDLT (const dReal *L, const dReal *d, dReal *b, int n, int nskip);
+void _dLDLTAddTL (dReal *L, dReal *d, const dReal *a, int n, int nskip, void *tmpbuf);
+void _dLDLTRemove (dReal **A, const int *p, dReal *L, dReal *d, int n1, int n2, int r, int nskip, void *tmpbuf);
+void _dRemoveRowCol (dReal *A, int n, int nskip, int r);
+
+PURE_INLINE size_t _dEstimateFactorCholeskyTmpbufSize(int n)
+{
+  return dPAD(n) * sizeof(dReal);
+}
+
+PURE_INLINE size_t _dEstimateSolveCholeskyTmpbufSize(int n)
+{
+  return dPAD(n) * sizeof(dReal);
+}
+
+PURE_INLINE size_t _dEstimateInvertPDMatrixTmpbufSize(int n)
+{
+  size_t FactorCholesky_size = _dEstimateFactorCholeskyTmpbufSize(n);
+  size_t SolveCholesky_size = _dEstimateSolveCholeskyTmpbufSize(n);
+  size_t MaxCholesky_size = FactorCholesky_size > SolveCholesky_size ? FactorCholesky_size : SolveCholesky_size;
+  return dPAD(n) * (n + 1) * sizeof(dReal) + MaxCholesky_size;
+}
+
+PURE_INLINE size_t _dEstimateIsPositiveDefiniteTmpbufSize(int n)
+{
+  return dPAD(n) * n * sizeof(dReal) + _dEstimateFactorCholeskyTmpbufSize(n);
+}
+
+PURE_INLINE size_t _dEstimateLDLTAddTLTmpbufSize(int nskip)
+{
+  return nskip * 2 * sizeof(dReal);
+}
+
+PURE_INLINE size_t _dEstimateLDLTRemoveTmpbufSize(int n2, int nskip)
+{
+  return n2 * sizeof(dReal) + _dEstimateLDLTAddTLTmpbufSize(nskip);
+}
+
+// For internal use
+#define dSetZero(a, n) _dSetZero(a, n)
+#define dSetValue(a, n, value) _dSetValue(a, n, value)
+#define dDot(a, b, n) _dDot(a, b, n)
+#define dMultiply0(A, B, C, p, q, r) _dMultiply0(A, B, C, p, q, r)
+#define dMultiply1(A, B, C, p, q, r) _dMultiply1(A, B, C, p, q, r)
+#define dMultiply2(A, B, C, p, q, r) _dMultiply2(A, B, C, p, q, r)
+#define dFactorCholesky(A, n, tmpbuf) _dFactorCholesky(A, n, tmpbuf)
+#define dSolveCholesky(L, b, n, tmpbuf) _dSolveCholesky(L, b, n, tmpbuf)
+#define dInvertPDMatrix(A, Ainv, n, tmpbuf) _dInvertPDMatrix(A, Ainv, n, tmpbuf)
+#define dIsPositiveDefinite(A, n, tmpbuf) _dIsPositiveDefinite(A, n, tmpbuf)
+#define dFactorLDLT(A, d, n, nskip) _dFactorLDLT(A, d, n, nskip)
+#define dSolveL1(L, b, n, nskip) _dSolveL1(L, b, n, nskip)
+#define dSolveL1T(L, b, n, nskip) _dSolveL1T(L, b, n, nskip)
+#define dVectorScale(a, d, n) _dVectorScale(a, d, n)
+#define dSolveLDLT(L, d, b, n, nskip) _dSolveLDLT(L, d, b, n, nskip)
+#define dLDLTAddTL(L, d, a, n, nskip, tmpbuf) _dLDLTAddTL(L, d, a, n, nskip, tmpbuf)
+#define dLDLTRemove(A, p, L, d, n1, n2, r, nskip, tmpbuf) _dLDLTRemove(A, p, L, d, n1, n2, r, nskip, tmpbuf)
+#define dRemoveRowCol(A, n, nskip, r) _dRemoveRowCol(A, n, nskip, r)
+
+
+#define dEstimateFactorCholeskyTmpbufSize(n) _dEstimateFactorCholeskyTmpbufSize(n)
+#define dEstimateSolveCholeskyTmpbufSize(n) _dEstimateSolveCholeskyTmpbufSize(n)
+#define dEstimateInvertPDMatrixTmpbufSize(n) _dEstimateInvertPDMatrixTmpbufSize(n)
+#define dEstimateIsPositiveDefiniteTmpbufSize(n) _dEstimateIsPositiveDefiniteTmpbufSize(n)
+#define dEstimateLDLTAddTLTmpbufSize(nskip) _dEstimateLDLTAddTLTmpbufSize(nskip)
+#define dEstimateLDLTRemoveTmpbufSize(n2, nskip) _dEstimateLDLTRemoveTmpbufSize(n2, nskip)
+
+
+#endif // defined(__ODE__)
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/misc/builddeps/dp.linux32/include/ode/memory.h b/misc/builddeps/dp.linux32/include/ode/memory.h
new file mode 100644 (file)
index 0000000..361061c
--- /dev/null
@@ -0,0 +1,59 @@
+/*************************************************************************
+ *                                                                       *
+ * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith.       *
+ * All rights reserved.  Email: russ@q12.org   Web: www.q12.org          *
+ *                                                                       *
+ * This library is free software; you can redistribute it and/or         *
+ * modify it under the terms of EITHER:                                  *
+ *   (1) The GNU Lesser General Public License as published by the Free  *
+ *       Software Foundation; either version 2.1 of the License, or (at  *
+ *       your option) any later version. The text of the GNU Lesser      *
+ *       General Public License is included with this library in the     *
+ *       file LICENSE.TXT.                                               *
+ *   (2) The BSD-style license that is included with this library in     *
+ *       the file LICENSE-BSD.TXT.                                       *
+ *                                                                       *
+ * This library is distributed in the hope that it will be useful,       *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files    *
+ * LICENSE.TXT and LICENSE-BSD.TXT for more details.                     *
+ *                                                                       *
+ *************************************************************************/
+
+/* this comes from the `reuse' library. copy any changes back to the source */
+
+#ifndef _ODE_MEMORY_H_
+#define _ODE_MEMORY_H_
+
+#include <ode/odeconfig.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* function types to allocate and free memory */
+typedef void * dAllocFunction (size_t size);
+typedef void * dReallocFunction (void *ptr, size_t oldsize, size_t newsize);
+typedef void dFreeFunction (void *ptr, size_t size);
+
+/* set new memory management functions. if fn is 0, the default handlers are
+ * used. */
+ODE_API void dSetAllocHandler (dAllocFunction *fn);
+ODE_API void dSetReallocHandler (dReallocFunction *fn);
+ODE_API void dSetFreeHandler (dFreeFunction *fn);
+
+/* get current memory management functions */
+ODE_API dAllocFunction *dGetAllocHandler (void);
+ODE_API dReallocFunction *dGetReallocHandler (void);
+ODE_API dFreeFunction *dGetFreeHandler (void);
+
+/* allocate and free memory. */
+ODE_API void * dAlloc (size_t size);
+ODE_API void * dRealloc (void *ptr, size_t oldsize, size_t newsize);
+ODE_API void dFree (void *ptr, size_t size);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/misc/builddeps/dp.linux32/include/ode/misc.h b/misc/builddeps/dp.linux32/include/ode/misc.h
new file mode 100644 (file)
index 0000000..0c55fc5
--- /dev/null
@@ -0,0 +1,85 @@
+/*************************************************************************
+ *                                                                       *
+ * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith.       *
+ * All rights reserved.  Email: russ@q12.org   Web: www.q12.org          *
+ *                                                                       *
+ * This library is free software; you can redistribute it and/or         *
+ * modify it under the terms of EITHER:                                  *
+ *   (1) The GNU Lesser General Public License as published by the Free  *
+ *       Software Foundation; either version 2.1 of the License, or (at  *
+ *       your option) any later version. The text of the GNU Lesser      *
+ *       General Public License is included with this library in the     *
+ *       file LICENSE.TXT.                                               *
+ *   (2) The BSD-style license that is included with this library in     *
+ *       the file LICENSE-BSD.TXT.                                       *
+ *                                                                       *
+ * This library is distributed in the hope that it will be useful,       *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files    *
+ * LICENSE.TXT and LICENSE-BSD.TXT for more details.                     *
+ *                                                                       *
+ *************************************************************************/
+
+/* miscellaneous math functions. these are mostly useful for testing */
+
+#ifndef _ODE_MISC_H_
+#define _ODE_MISC_H_
+
+#include <ode/common.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/* return 1 if the random number generator is working. */
+ODE_API int dTestRand(void);
+
+/* return next 32 bit random number. this uses a not-very-random linear
+ * congruential method.
+ */
+ODE_API unsigned long dRand(void);
+
+/* get and set the current random number seed. */
+ODE_API unsigned long  dRandGetSeed(void);
+ODE_API void dRandSetSeed (unsigned long s);
+
+/* return a random integer between 0..n-1. the distribution will get worse
+ * as n approaches 2^32.
+ */
+ODE_API int dRandInt (int n);
+
+/* return a random real number between 0..1 */
+ODE_API dReal dRandReal(void);
+
+/* print out a matrix */
+#ifdef __cplusplus
+ODE_API void dPrintMatrix (const dReal *A, int n, int m, char *fmt = "%10.4f ",
+                  FILE *f=stdout);
+#else
+ODE_API void dPrintMatrix (const dReal *A, int n, int m, char *fmt, FILE *f);
+#endif
+
+/* make a random vector with entries between +/- range. A has n elements. */
+ODE_API void dMakeRandomVector (dReal *A, int n, dReal range);
+
+/* make a random matrix with entries between +/- range. A has size n*m. */
+ODE_API void dMakeRandomMatrix (dReal *A, int n, int m, dReal range);
+
+/* clear the upper triangle of a square matrix */
+ODE_API void dClearUpperTriangle (dReal *A, int n);
+
+/* return the maximum element difference between the two n*m matrices */
+ODE_API dReal dMaxDifference (const dReal *A, const dReal *B, int n, int m);
+
+/* return the maximum element difference between the lower triangle of two
+ * n*n matrices */
+ODE_API dReal dMaxDifferenceLowerTriangle (const dReal *A, const dReal *B, int n);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/misc/builddeps/dp.linux32/include/ode/objects.h b/misc/builddeps/dp.linux32/include/ode/objects.h
new file mode 100644 (file)
index 0000000..379de01
--- /dev/null
@@ -0,0 +1,2975 @@
+
+
+/*************************************************************************
+ *                                                                       *
+ * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith.       *
+ * All rights reserved.  Email: russ@q12.org   Web: www.q12.org          *
+ *                                                                       *
+ * This library is free software; you can redistribute it and/or         *
+ * modify it under the terms of EITHER:                                  *
+ *   (1) The GNU Lesser General Public License as published by the Free  *
+ *       Software Foundation; either version 2.1 of the License, or (at  *
+ *       your option) any later version. The text of the GNU Lesser      *
+ *       General Public License is included with this library in the     *
+ *       file LICENSE.TXT.                                               *
+ *   (2) The BSD-style license that is included with this library in     *
+ *       the file LICENSE-BSD.TXT.                                       *
+ *                                                                       *
+ * This library is distributed in the hope that it will be useful,       *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files    *
+ * LICENSE.TXT and LICENSE-BSD.TXT for more details.                     *
+ *                                                                       *
+ *************************************************************************/
+
+#ifndef _ODE_OBJECTS_H_
+#define _ODE_OBJECTS_H_
+
+#include <ode/common.h>
+#include <ode/mass.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 Set the world to use shared working memory along with another world.
+ *
+ * The worlds allocate working memory internally for simulation stepping. This
+ * memory is cached among the calls to @c dWordStep and @c dWorldQuickStep. 
+ * Similarly, several worlds can be set up to share this memory caches thus 
+ * reducing overall memory usage by cost of making worlds inappropriate for 
+ * simultaneous simulation in multiple threads.
+ *
+ * If null value is passed for @a from_world parameter the world is detached from 
+ * sharing and returns to defaults for working memory, reservation policy and 
+ * memory manager as if just created. This can also be used to enable use of shared 
+ * memory for a world that has already had working memory allocated privately.
+ * Normally using shared memory after a world has its private working memory allocated
+ * is prohibited.
+ *
+ * Allocation policy used can only increase world's internal reserved memory size
+ * and never decreases it. @c dWorldCleanupWorkingMemory can be used to release 
+ * working memory for a world in case if number of objects/joint decreases 
+ * significantly in it.
+ *
+ * With sharing working memory worlds also automatically share memory reservation 
+ * policy and memory manager. Thus, these parameters need to be customized for
+ * initial world to be used as sharing source only.
+ *
+ * Failure result status means a memory allocation failure.
+ *
+ * @param w The world to use the shared memory with.
+ * @param from_world Null or the world the shared memory is to be used from.
+ * @returns 1 for success and 0 for failure.
+ *
+ * @ingroup world
+ * @see dWorldCleanupWorkingMemory
+ * @see dWorldSetStepMemoryReservationPolicy
+ * @see dWorldSetStepMemoryManager
+ */
+ODE_API int dWorldUseSharedWorkingMemory(dWorldID w, dWorldID from_world/*=NULL*/);
+
+/**
+ * @brief Release internal working memory allocated for world
+ *
+ * The worlds allocate working memory internally for simulation stepping. This 
+ * function can be used to free world's internal memory cache in case if number of
+ * objects/joints in the world decreases significantly. By default, internal 
+ * allocation policy is used to only increase cache size as necessary and never 
+ * decrease it.
+ *
+ * If a world shares its working memory with other worlds the cache deletion 
+ * affects all the linked worlds. However the shared status itself remains intact.
+ *
+ * The function call does affect neither memory reservation policy nor memory manager.
+ *
+ * @param w The world to release working memory for.
+ *
+ * @ingroup world
+ * @see dWorldUseSharedWorkingMemory
+ * @see dWorldSetStepMemoryReservationPolicy
+ * @see dWorldSetStepMemoryManager
+ */
+ODE_API void dWorldCleanupWorkingMemory(dWorldID w);
+
+#define dWORLDSTEP_RESERVEFACTOR_DEFAULT    1.2f
+#define dWORLDSTEP_RESERVESIZE_DEFAULT      65536U
+
+/**
+ * @struct dWorldStepReserveInfo
+ * @brief Memory reservation policy descriptor structure for world stepping functions.
+ *
+ * @c struct_size should be assigned the size of the structure.
+ *
+ * @c reserve_factor is a quotient that is multiplied by required memory size
+ *  to allocate extra reserve whenever reallocation is needed.
+ *
+ * @c reserve_minimum is a minimum size that is checked against whenever reallocation 
+ * is needed to allocate expected working memory minimum at once without extra 
+ * reallocations as number of bodies/joints grows.
+ *
+ * @ingroup world
+ * @see dWorldSetStepMemoryReservationPolicy
+ */
+typedef struct
+{
+  unsigned struct_size;
+  float reserve_factor; // Use float as precision does not matter here
+  unsigned reserve_minimum;
+
+} dWorldStepReserveInfo;
+
+/**
+ * @brief Set memory reservation policy for world to be used with simulation stepping functions
+ *
+ * The function allows to customize reservation policy to be used for internal
+ * memory which is allocated to aid simulation for a world. By default, values
+ * of @c dWORLDSTEP_RESERVEFACTOR_DEFAULT and @c dWORLDSTEP_RESERVESIZE_DEFAULT
+ * are used.
+ *
+ * Passing @a policyinfo argument as NULL results in reservation policy being
+ * reset to defaults as if the world has been just created. The content of 
+ * @a policyinfo structure is copied internally and does not need to remain valid
+ * after the call returns.
+ *
+ * If the world uses working memory sharing, changing memory reservation policy
+ * affects all the worlds linked together.
+ *
+ * Failure result status means a memory allocation failure.
+ *
+ * @param w The world to change memory reservation policy for.
+ * @param policyinfo Null or a pointer to policy descriptor structure.
+ * @returns 1 for success and 0 for failure.
+ *
+ * @ingroup world
+ * @see dWorldUseSharedWorkingMemory
+ */
+ODE_API int dWorldSetStepMemoryReservationPolicy(dWorldID w, const dWorldStepReserveInfo *policyinfo/*=NULL*/);
+
+/**
+* @struct dWorldStepMemoryFunctionsInfo
+* @brief World stepping memory manager descriptor structure
+*
+* This structure is intended to define the functions of memory manager to be used
+* with world stepping functions.
+*
+* @c struct_size should be assigned the size of the structure
+*
+* @c alloc_block is a function to allocate memory block of given size.
+*
+* @c shrink_block is a function to shrink existing memory block to a smaller size.
+* It must preserve the contents of block head while shrinking. The new block size
+* is guaranteed to be always less than the existing one.
+*
+* @c free_block is a function to delete existing memory block.
+*
+* @ingroup init
+* @see dWorldSetStepMemoryManager
+*/
+typedef struct 
+{
+  unsigned struct_size;
+  void *(*alloc_block)(size_t block_size);
+  void *(*shrink_block)(void *block_pointer, size_t block_current_size, size_t block_smaller_size);
+  void (*free_block)(void *block_pointer, size_t block_current_size);
+
+} dWorldStepMemoryFunctionsInfo;
+
+/**
+* @brief Set memory manager for world to be used with simulation stepping functions
+*
+* The function allows to customize memory manager to be used for internal
+* memory allocation during simulation for a world. By default, @c dAlloc/@c dRealloc/@c dFree
+* based memory manager is used.
+*
+* Passing @a memfuncs argument as NULL results in memory manager being
+* reset to default one as if the world has been just created. The content of 
+* @a memfuncs structure is copied internally and does not need to remain valid
+* after the call returns.
+*
+* If the world uses working memory sharing, changing memory manager
+* affects all the worlds linked together. 
+*
+* Failure result status means a memory allocation failure.
+*
+* @param w The world to change memory reservation policy for.
+* @param memfuncs Null or a pointer to memory manager descriptor structure.
+* @returns 1 for success and 0 for failure.
+*
+* @ingroup world
+* @see dWorldUseSharedWorkingMemory
+*/
+ODE_API int dWorldSetStepMemoryManager(dWorldID w, const dWorldStepMemoryFunctionsInfo *memfuncs);
+
+/**
+ * @brief Step the world.
+ *
+ * This uses a "big matrix" method that takes time on the order of m^3
+ * and memory on the order of m^2, where m is the total number of constraint
+ * rows. For large systems this will use a lot of memory and can be very slow,
+ * but this is currently the most accurate method.
+ *
+ * Failure result status means that the memory allocation has failed for operation.
+ * In such a case all the objects remain in unchanged state and simulation can be
+ * retried as soon as more memory is available.
+ *
+ * @param w The world to be stepped
+ * @param stepsize The number of seconds that the simulation has to advance.
+ * @returns 1 for success and 0 for failure
+ *
+ * @ingroup world
+ */
+ODE_API int dWorldStep (dWorldID w, dReal stepsize);
+
+/**
+ * @brief Quick-step the world.
+ *
+ * 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.
+ *
+ * QuickStep is great for stacks of objects especially when the
+ * auto-disable feature is used as well.
+ * However, it has poor accuracy for near-singular systems.
+ * Near-singular systems can occur when using high-friction contacts, motors,
+ * or certain articulated structures. For example, a robot with multiple legs
+ * sitting on the ground may be near-singular.
+ *
+ * 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.
+ *
+ * Failure result status means that the memory allocation has failed for operation.
+ * In such a case all the objects remain in unchanged state and simulation can be
+ * retried as soon as more memory is available.
+ *
+ * @param w The world to be stepped
+ * @param stepsize The number of seconds that the simulation has to advance.
+ * @returns 1 for success and 0 for failure
+ *
+ * @ingroup world
+ */
+ODE_API int dWorldQuickStep (dWorldID w, 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 convert
+* the desired impulse into a force/torque vector before calling the
+* BodyAdd... function.
+* The current algorithm simply scales the impulse by 1/stepsize,
+* where stepsize is the step size for the next step that will be taken.
+* This function is given a dWorldID because, in the future, the force
+* computation may depend on integrator parameters that are set as
+* properties of the world.
+*/
+ODE_API void dWorldImpulseToForce
+(
+ dWorldID, dReal stepsize,
+ dReal ix, dReal iy, dReal iz, dVector3 force
+ );
+
+
+/**
+ * @brief Set the number of iterations that the QuickStep method performs per
+ *        step.
+ * @ingroup world
+ * @remarks
+ * More iterations will give a more accurate solution, but will take
+ * longer to compute.
+ * @param num The default is 20 iterations.
+ */
+ODE_API void dWorldSetQuickStepNumIterations (dWorldID, int num);
+
+
+/**
+ * @brief Get the number of iterations that the QuickStep method performs per
+ *        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 objects.
+ */
+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);
+
+
+/**
+ * @defgroup disable Automatic Enabling and Disabling
+ * @ingroup world bodies
+ *
+ * Every body can be enabled or disabled. Enabled bodies participate in the
+ * simulation, while disabled bodies are turned off and do not get updated
+ * during a simulation step. New bodies are always created in the enabled state.
+ *
+ * A disabled body that is connected through a joint to an enabled body will be
+ * automatically re-enabled at the next simulation step.
+ *
+ * Disabled bodies do not consume CPU time, therefore to speed up the simulation
+ * bodies should be disabled when they come to rest. This can be done automatically
+ * with the auto-disable feature.
+ *
+ * If a body has its auto-disable flag turned on, it will automatically disable
+ * itself when
+ *   @li It has been idle for a given number of simulation steps.
+ *   @li It has also been idle for a given amount of simulation time.
+ *
+ * A body is considered to be idle when the magnitudes of both its
+ * linear average velocity and angular average velocity are below given thresholds.
+ * The sample size for the average defaults to one and can be disabled by setting
+ * to zero with 
+ *
+ * Thus, every body has six auto-disable parameters: an enabled flag, a idle step
+ * count, an idle time, linear/angular average velocity thresholds, and the
+ * average samples count.
+ *
+ * Newly created bodies get these parameters from world.
+ */
+
+/**
+ * @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_threshold);
+
+/**
+ * @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 linear average threshold for newly created bodies.
+ * @ingroup disable
+ * @return the threshold
+ */
+ODE_API dReal dWorldGetAutoDisableLinearAverageThreshold (dWorldID);
+
+/**
+ * @brief Set auto disable linear average threshold for newly created bodies.
+ * @param linear_average_threshold default is 0.01
+ * @ingroup disable
+ */
+ODE_API void  dWorldSetAutoDisableLinearAverageThreshold (dWorldID, dReal linear_average_threshold);
+
+/**
+ * @brief Get auto disable angular average threshold for newly created bodies.
+ * @ingroup disable
+ * @return the threshold
+ */
+ODE_API dReal dWorldGetAutoDisableAngularAverageThreshold (dWorldID);
+
+/**
+ * @brief Set auto disable angular average threshold for newly created bodies.
+ * @param linear_average_threshold default is 0.01
+ * @ingroup disable
+ */
+ODE_API void dWorldSetAutoDisableAngularAverageThreshold (dWorldID, dReal angular_average_threshold);
+
+/**
+ * @brief Get auto disable sample count for newly created bodies.
+ * @ingroup disable
+ * @return number of samples used
+ */
+ODE_API int dWorldGetAutoDisableAverageSamplesCount (dWorldID);
+
+/**
+ * @brief Set auto disable average sample count for newly created bodies.
+ * @ingroup disable
+ * @param average_samples_count Default is 1, meaning only instantaneous velocity is used.
+ * Set to zero to disable sampling and thus prevent any body from auto-disabling.
+ */
+ODE_API void dWorldSetAutoDisableAverageSamplesCount (dWorldID, unsigned int average_samples_count );
+
+/**
+ * @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 damping Damping
+ * @ingroup bodies world
+ *
+ * Damping serves two purposes: reduce simulation instability, and to allow
+ * the bodies to come to rest (and possibly auto-disabling them).
+ *
+ * Bodies are constructed using the world's current damping parameters. Setting
+ * the scales to 0 disables the damping.
+ *
+ * Here is how it is done: after every time step linear and angular
+ * velocities are tested against the corresponding thresholds. If they
+ * are above, they are multiplied by (1 - scale). So a negative scale value
+ * will actually increase the speed, and values greater than one will
+ * make the object oscillate every step; both can make the simulation unstable.
+ *
+ * To disable damping just set the damping scale to zero.
+ *
+ * You can also limit the maximum angular velocity. In contrast to the damping
+ * functions, the angular velocity is affected before the body is moved.
+ * This means that it will introduce errors in joints that are forcing the body
+ * to rotate too fast. Some bodies have naturally high angular velocities
+ * (like cars' wheels), so you may want to give them a very high (like the default,
+ * dInfinity) limit.
+ *
+ * @note The velocities are damped after the stepper function has moved the
+ * object. Otherwise the damping could introduce errors in joints. First the
+ * joint constraints are processed by the stepper (moving the body), then
+ * the damping is applied.
+ *
+ * @note The damping happens right after the moved callback is called; this way 
+ * it still possible use the exact velocities the body has acquired during the
+ * step. You can even use the callback to create your own customized damping.
+ */
+
+/**
+ * @brief Get the world's linear damping threshold.
+ * @ingroup damping
+ */
+ODE_API dReal dWorldGetLinearDampingThreshold (dWorldID w);
+
+/**
+ * @brief Set the world's linear damping threshold.
+ * @param threshold The damping won't be applied if the linear speed is
+ *        below this threshold. Default is 0.01.
+ * @ingroup damping
+ */
+ODE_API void dWorldSetLinearDampingThreshold(dWorldID w, dReal threshold);
+
+/**
+ * @brief Get the world's angular damping threshold.
+ * @ingroup damping
+ */
+ODE_API dReal dWorldGetAngularDampingThreshold (dWorldID w);
+
+/**
+ * @brief Set the world's angular damping threshold.
+ * @param threshold The damping won't be applied if the angular speed is
+ *        below this threshold. Default is 0.01.
+ * @ingroup damping
+ */
+ODE_API void dWorldSetAngularDampingThreshold(dWorldID w, dReal threshold);
+
+/**
+ * @brief Get the world's linear damping scale.
+ * @ingroup damping
+ */
+ODE_API dReal dWorldGetLinearDamping (dWorldID w);
+
+/**
+ * @brief Set the world's linear damping scale.
+ * @param scale The linear damping scale that is to be applied to bodies.
+ * Default is 0 (no damping). Should be in the interval [0, 1].
+ * @ingroup damping
+ */
+ODE_API void dWorldSetLinearDamping (dWorldID w, dReal scale);
+
+/**
+ * @brief Get the world's angular damping scale.
+ * @ingroup damping
+ */
+ODE_API dReal dWorldGetAngularDamping (dWorldID w);
+
+/**
+ * @brief Set the world's angular damping scale.
+ * @param scale The angular damping scale that is to be applied to bodies.
+ * Default is 0 (no damping). Should be in the interval [0, 1].
+ * @ingroup damping
+ */
+ODE_API void dWorldSetAngularDamping(dWorldID w, dReal scale);
+
+/**
+ * @brief Convenience function to set body linear and angular scales.
+ * @param linear_scale The linear damping scale that is to be applied to bodies.
+ * @param angular_scale The angular damping scale that is to be applied to bodies.
+ * @ingroup damping
+ */
+ODE_API void dWorldSetDamping(dWorldID w,
+                                dReal linear_scale,
+                                dReal angular_scale);
+
+/**
+ * @brief Get the default maximum angular speed.
+ * @ingroup damping
+ * @sa dBodyGetMaxAngularSpeed()
+ */
+ODE_API dReal dWorldGetMaxAngularSpeed (dWorldID w);
+
+
+/**
+ * @brief Set the default maximum angular speed for new bodies.
+ * @ingroup damping
+ * @sa dBodySetMaxAngularSpeed()
+ */
+ODE_API void dWorldSetMaxAngularSpeed (dWorldID w, dReal max_speed);
+
+
+
+/**
+ * @defgroup bodies Rigid Bodies
+ *
+ * A rigid body has various properties from the point of view of the
+ * simulation. Some properties change over time:
+ *
+ *  @li Position vector (x,y,z) of the body's point of reference.
+ *      Currently the point of reference must correspond to the body's center of mass.
+ *  @li Linear velocity of the point of reference, a vector (vx,vy,vz).
+ *  @li Orientation of a body, represented by a quaternion (qs,qx,qy,qz) or
+ *      a 3x3 rotation matrix.
+ *  @li Angular velocity vector (wx,wy,wz) which describes how the orientation
+ *      changes over time.
+ *
+ * Other body properties are usually constant over time:
+ *
+ *  @li Mass of the body.
+ *  @li Position of the center of mass with respect to the point of reference.
+ *      In the current implementation the center of mass and the point of
+ *      reference must coincide.
+ *  @li Inertia matrix. This is a 3x3 matrix that describes how the body's mass
+ *      is distributed around the center of mass. Conceptually each body has an
+ *      x-y-z coordinate frame embedded in it that moves and rotates with the body.
+ *
+ * The origin of this coordinate frame is the body's point of reference. Some values
+ * in ODE (vectors, matrices etc) are relative to the body coordinate frame, and others
+ * are relative to the global coordinate frame.
+ *
+ * Note that the shape of a rigid body is not a dynamical property (except insofar as
+ * it influences the various mass properties). It is only collision detection that cares
+ * about the detailed shape of the body.
+ */
+
+
+/**
+ * @brief Get auto disable linear average threshold.
+ * @ingroup bodies disable
+ * @return the threshold
+ */
+ODE_API dReal dBodyGetAutoDisableLinearThreshold (dBodyID);
+
+/**
+ * @brief Set auto disable linear average threshold.
+ * @ingroup bodies disable
+ * @return the threshold
+ */
+ODE_API void  dBodySetAutoDisableLinearThreshold (dBodyID, dReal linear_average_threshold);
+
+/**
+ * @brief Get auto disable angular average threshold.
+ * @ingroup bodies disable
+ * @return the threshold
+ */
+ODE_API dReal dBodyGetAutoDisableAngularThreshold (dBodyID);
+
+/**
+ * @brief Set auto disable angular average threshold.
+ * @ingroup bodies disable
+ * @return the threshold
+ */
+ODE_API void  dBodySetAutoDisableAngularThreshold (dBodyID, dReal angular_average_threshold);
+
+/**
+ * @brief Get auto disable average size (samples count).
+ * @ingroup bodies disable
+ * @return the nr of steps/size.
+ */
+ODE_API int dBodyGetAutoDisableAverageSamplesCount (dBodyID);
+
+/**
+ * @brief Set auto disable average buffer size (average steps).
+ * @ingroup bodies disable
+ * @param average_samples_count the nr of samples to review.
+ */
+ODE_API void dBodySetAutoDisableAverageSamplesCount (dBodyID, unsigned int average_samples_count);
+
+
+/**
+ * @brief Get auto steps a body must be thought of as idle to disable
+ * @ingroup bodies disable
+ * @return the nr of steps
+ */
+ODE_API int dBodyGetAutoDisableSteps (dBodyID);
+
+/**
+ * @brief Set auto disable steps.
+ * @ingroup bodies disable
+ * @param steps the nr of steps.
+ */
+ODE_API void dBodySetAutoDisableSteps (dBodyID, int steps);
+
+/**
+ * @brief Get auto disable time.
+ * @ingroup bodies disable
+ * @return nr of seconds
+ */
+ODE_API dReal dBodyGetAutoDisableTime (dBodyID);
+
+/**
+ * @brief Set auto disable time.
+ * @ingroup bodies disable
+ * @param time nr of seconds.
+ */
+ODE_API void  dBodySetAutoDisableTime (dBodyID, dReal time);
+
+/**
+ * @brief Get auto disable flag.
+ * @ingroup bodies disable
+ * @return 0 or 1
+ */
+ODE_API int dBodyGetAutoDisableFlag (dBodyID);
+
+/**
+ * @brief Set auto disable flag.
+ * @ingroup bodies disable
+ * @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 disable
+ */
+ODE_API void  dBodySetAutoDisableDefaults (dBodyID);
+
+
+/**
+ * @brief Retrieves the world attached to te given body.
+ * @remarks
+ * 
+ * @ingroup bodies
+ */
+ODE_API dWorldID dBodyGetWorld (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 structures,
+ * so the vectors are valid until any changes are made to the rigid body
+ * system structure.
+ * @sa dBodyCopyPosition
+ */
+ODE_API const dReal * dBodyGetPosition (dBodyID);
+
+
+/**
+ * @brief Copy the position of a body into a vector.
+ * @ingroup bodies
+ * @param body  the body to query
+ * @param pos   a copy of the body position
+ * @sa dBodyGetPosition
+ */
+ODE_API void dBodyCopyPosition (dBodyID body, dVector3 pos);
+
+
+/**
+ * @brief Get the rotation of a body.
+ * @ingroup bodies
+ * @return pointer to a 4x3 rotation matrix.
+ */
+ODE_API const dReal * dBodyGetRotation (dBodyID);
+
+
+/**
+ * @brief Copy the rotation of a body.
+ * @ingroup bodies
+ * @param body   the body to query
+ * @param R      a copy of the rotation matrix
+ * @sa dBodyGetRotation
+ */
+ODE_API void dBodyCopyRotation (dBodyID, dMatrix3 R);
+
+
+/**
+ * @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 Copy the orientation of a body into a quaternion.
+ * @ingroup bodies
+ * @param body  the body to query
+ * @param quat  a copy of the orientation quaternion
+ * @sa dBodyGetQuaternion
+ */
+ODE_API void dBodyCopyQuaternion(dBodyID body, dQuaternion quat);
+
+
+/**
+ * @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 fz);
+
+/**
+ * @brief Add torque at centre of mass of body in absolute coordinates.
+ * @ingroup bodies
+ */
+ODE_API void dBodyAddTorque           (dBodyID, dReal fx, dReal fy, dReal fz);
+
+/**
+ * @brief Add force at centre of mass of body in coordinates relative to body.
+ * @ingroup bodies
+ */
+ODE_API void dBodyAddRelForce         (dBodyID, dReal fx, dReal fy, dReal fz);
+
+/**
+ * @brief Add torque at centre of mass of body in coordinates relative to body.
+ * @ingroup bodies
+ */
+ODE_API void dBodyAddRelTorque        (dBodyID, dReal fx, dReal fy, dReal fz);
+
+/**
+ * @brief Add force at specified point in body in global coordinates.
+ * @ingroup bodies
+ */
+ODE_API void dBodyAddForceAtPos       (dBodyID, dReal fx, dReal fy, dReal fz,
+                                       dReal px, dReal py, dReal pz);
+/**
+ * @brief Add force at specified point in body in local coordinates.
+ * @ingroup bodies
+ */
+ODE_API void dBodyAddForceAtRelPos    (dBodyID, dReal fx, dReal fy, dReal fz,
+                                       dReal px, dReal py, dReal pz);
+/**
+ * @brief Add force at specified point in body in global coordinates.
+ * @ingroup bodies
+ */
+ODE_API void dBodyAddRelForceAtPos    (dBodyID, dReal fx, dReal fy, dReal fz,
+                                       dReal px, dReal py, dReal pz);
+/**
+ * @brief Add force at specified point in body in local coordinates.
+ * @ingroup bodies
+ */
+ODE_API void dBodyAddRelForceAtRelPos (dBodyID, dReal fx, dReal fy, dReal fz,
+                                       dReal px, dReal py, dReal pz);
+
+/**
+ * @brief Return the current accumulated force vector.
+ * @return points to an array of 3 reals.
+ * @remarks
+ * The returned values are pointers to internal data structures, so
+ * the vectors are only valid until any changes are made to the rigid
+ * body system.
+ * @ingroup bodies
+ */
+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 bodies
+ * before they are reactivated, in the case where the force-adding functions
+ * 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 bodies
+ * before they are reactivated, in the case where the force-adding functions
+ * 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 finite
+ * rotation along the axis direction followed by an infinitesimal rotation
+ * along an orthogonal direction.
+ * @remarks
+ * This can be useful to alleviate certain sources of error caused by quickly
+ * spinning bodies. For example, if a car wheel is rotating at high speed
+ * you can call this function with the wheel's hinge axis as the argument to
+ * try and improve its behavior.
+ */
+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 Set rigid body to dynamic state (default).
+ * @param dBodyID identification of body.
+ * @ingroup bodies
+ */
+ODE_API void dBodySetDynamic (dBodyID);
+
+/**
+ * @brief Set rigid body to kinematic state.
+ * When in kinematic state the body isn't simulated as a dynamic
+ * body (it's "unstoppable", doesn't respond to forces),
+ * but can still affect dynamic bodies (e.g. in joints).
+ * Kinematic bodies can be controlled by position and velocity.
+ * @note A kinematic body has infinite mass. If you set its mass
+ * to something else, it loses the kinematic state and behaves
+ * as a normal dynamic body.
+ * @param dBodyID identification of body.
+ * @ingroup bodies
+ */
+ODE_API void dBodySetKinematic (dBodyID);
+
+/**
+ * @brief Check wether a body is in kinematic state.
+ * @ingroup bodies
+ * @return 1 if a body is kinematic or 0 if it is dynamic.
+ */
+ODE_API int dBodyIsKinematic (dBodyID);
+
+/**
+ * @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 will
+ * 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);
+
+/**
+ * @brief Set the 'moved' callback of a body.
+ *
+ * Whenever a body has its position or rotation changed during the
+ * timestep, the callback will be called (with body as the argument).
+ * Use it to know which body may need an update in an external
+ * structure (like a 3D engine).
+ *
+ * @param b the body that needs to be watched.
+ * @param callback the callback to be invoked when the body moves. Set to zero
+ * to disable.
+ * @ingroup bodies
+ */
+ODE_API void dBodySetMovedCallback(dBodyID b, void (*callback)(dBodyID));
+
+
+/**
+ * @brief Return the first geom associated with the body.
+ * 
+ * You can traverse through the geoms by repeatedly calling
+ * dBodyGetNextGeom().
+ *
+ * @return the first geom attached to this body, or 0.
+ * @ingroup bodies
+ */
+ODE_API dGeomID dBodyGetFirstGeom (dBodyID b);
+
+
+/**
+ * @brief returns the next geom associated with the same body.
+ * @param g a geom attached to some body.
+ * @return the next geom attached to the same body, or 0.
+ * @sa dBodyGetFirstGeom
+ * @ingroup bodies
+ */
+ODE_API dGeomID dBodyGetNextGeom (dGeomID g);
+
+
+/**
+ * @brief Resets the damping settings to the current world's settings.
+ * @ingroup bodies damping
+ */
+ODE_API void dBodySetDampingDefaults(dBodyID b);
+
+/**
+ * @brief Get the body's linear damping scale.
+ * @ingroup bodies damping
+ */
+ODE_API dReal dBodyGetLinearDamping (dBodyID b);
+
+/**
+ * @brief Set the body's linear damping scale.
+ * @param scale The linear damping scale. Should be in the interval [0, 1].
+ * @ingroup bodies damping
+ * @remarks From now on the body will not use the world's linear damping
+ * scale until dBodySetDampingDefaults() is called.
+ * @sa dBodySetDampingDefaults()
+ */
+ODE_API void dBodySetLinearDamping(dBodyID b, dReal scale);
+
+/**
+ * @brief Get the body's angular damping scale.
+ * @ingroup bodies damping
+ * @remarks If the body's angular damping scale was not set, this function
+ * returns the world's angular damping scale.
+ */
+ODE_API dReal dBodyGetAngularDamping (dBodyID b);
+
+/**
+ * @brief Set the body's angular damping scale.
+ * @param scale The angular damping scale. Should be in the interval [0, 1].
+ * @ingroup bodies damping
+ * @remarks From now on the body will not use the world's angular damping
+ * scale until dBodyResetAngularDamping() is called.
+ * @sa dBodyResetAngularDamping()
+ */
+ODE_API void dBodySetAngularDamping(dBodyID b, dReal scale);
+
+/**
+ * @brief Convenience function to set linear and angular scales at once.
+ * @param linear_scale The linear damping scale. Should be in the interval [0, 1].
+ * @param angular_scale The angular damping scale. Should be in the interval [0, 1].
+ * @ingroup bodies damping
+ * @sa dBodySetLinearDamping() dBodySetAngularDamping()
+ */
+ODE_API void dBodySetDamping(dBodyID b, dReal linear_scale, dReal angular_scale);
+
+/**
+ * @brief Get the body's linear damping threshold.
+ * @ingroup bodies damping
+ */
+ODE_API dReal dBodyGetLinearDampingThreshold (dBodyID b);
+
+/**
+ * @brief Set the body's linear damping threshold.
+ * @param threshold The linear threshold to be used. Damping
+ *      is only applied if the linear speed is above this limit.
+ * @ingroup bodies damping
+ */
+ODE_API void dBodySetLinearDampingThreshold(dBodyID b, dReal threshold);
+
+/**
+ * @brief Get the body's angular damping threshold.
+ * @ingroup bodies damping
+ */
+ODE_API dReal dBodyGetAngularDampingThreshold (dBodyID b);
+
+/**
+ * @brief Set the body's angular damping threshold.
+ * @param threshold The angular threshold to be used. Damping is
+ *      only used if the angular speed is above this limit.
+ * @ingroup bodies damping
+ */
+ODE_API void dBodySetAngularDampingThreshold(dBodyID b, dReal threshold);
+
+/**
+ * @brief Get the body's maximum angular speed.
+ * @ingroup damping bodies
+ * @sa dWorldGetMaxAngularSpeed()
+ */
+ODE_API dReal dBodyGetMaxAngularSpeed (dBodyID b);
+
+/**
+ * @brief Set the body's maximum angular speed.
+ * @ingroup damping bodies
+ * @sa dWorldSetMaxAngularSpeed() dBodyResetMaxAngularSpeed()
+ * The default value is dInfinity, but it's a good idea to limit
+ * it at less than 500 if the body has the gyroscopic term
+ * enabled.
+ */
+ODE_API void dBodySetMaxAngularSpeed(dBodyID b, dReal max_speed);
+
+
+
+/**
+ * @brief Get the body's gyroscopic state.
+ *
+ * @return nonzero if gyroscopic term computation is enabled (default),
+ * zero otherwise.
+ * @ingroup bodies
+ */
+ODE_API int dBodyGetGyroscopicMode(dBodyID b);
+
+
+/**
+ * @brief Enable/disable the body's gyroscopic term.
+ *
+ * Disabling the gyroscopic term of a body usually improves
+ * stability. It also helps turning spining objects, like cars'
+ * wheels.
+ *
+ * @param enabled   nonzero (default) to enable gyroscopic term, 0
+ * to disable.
+ * @ingroup bodies
+ */
+ODE_API void dBodySetGyroscopicMode(dBodyID b, int enabled);
+
+
+
+
+/**
+ * @defgroup joints Joints
+ *
+ * In real life a joint is something like a hinge, that is used to connect two
+ * objects.
+ * In ODE a joint is very similar: It is a relationship that is enforced between
+ * two bodies so that they can only have certain positions and orientations
+ * relative to each other.
+ * This relationship is called a constraint -- the words joint and
+ * constraint are often used interchangeably.
+ *
+ * A joint has a set of parameters that can be set. These include:
+ *
+ *
+ * \li  dParamLoStop Low stop angle or position. Setting this to
+ *     -dInfinity (the default value) turns off the low stop.
+ *     For rotational joints, this stop must be greater than -pi to be
+ *     effective.
+ * \li  dParamHiStop High stop angle or position. Setting this to
+ *     dInfinity (the default value) turns off the high stop.
+ *     For rotational joints, this stop must be less than pi to be
+ *     effective.
+ *     If the high stop is less than the low stop then both stops will
+ *     be ineffective.
+ * \li  dParamVel Desired motor velocity (this will be an angular or
+ *     linear velocity).
+ * \li  dParamFMax The maximum force or torque that the motor will use to
+ *     achieve the desired velocity.
+ *     This must always be greater than or equal to zero.
+ *     Setting this to zero (the default value) turns off the motor.
+ * \li  dParamFudgeFactor The current joint stop/motor implementation has
+ *     a small problem:
+ *     when the joint is at one stop and the motor is set to move it away
+ *     from the stop, too much force may be applied for one time step,
+ *     causing a ``jumping'' motion.
+ *     This fudge factor is used to scale this excess force.
+ *     It should have a value between zero and one (the default value).
+ *     If the jumping motion is too visible in a joint, the value can be
+ *     reduced.
+ *     Making this value too small can prevent the motor from being able to
+ *     move the joint away from a stop.
+ * \li  dParamBounce The bouncyness of the stops.
+ *     This is a restitution parameter in the range 0..1.
+ *     0 means the stops are not bouncy at all, 1 means maximum bouncyness.
+ * \li  dParamCFM The constraint force mixing (CFM) value used when not
+ *     at a stop.
+ * \li  dParamStopERP The error reduction parameter (ERP) used by the
+ *     stops.
+ * \li  dParamStopCFM The constraint force mixing (CFM) value used by the
+ *     stops. Together with the ERP value this can be used to get spongy or
+ *     soft stops.
+ *     Note that this is intended for unpowered joints, it does not really
+ *     work as expected when a powered joint reaches its limit.
+ * \li  dParamSuspensionERP Suspension error reduction parameter (ERP).
+ *     Currently this is only implemented on the hinge-2 joint.
+ * \li  dParamSuspensionCFM Suspension constraint force mixing (CFM) value.
+ *     Currently this is only implemented on the hinge-2 joint.
+ *
+ * If a particular parameter is not implemented by a given joint, setting it
+ * will have no effect.
+ * These parameter names can be optionally followed by a digit (2 or 3)
+ * to indicate the second or third set of parameters, e.g. for the second axis
+ * in a hinge-2 joint, or the third axis in an AMotor joint.
+ */
+
+
+/**
+ * @brief Create a new joint of the ball type.
+ * @ingroup joints
+ * @remarks
+ * The joint is initially in "limbo" (i.e. it has no effect on the simulation)
+ * because it does not connect to any bodies.
+ * @param dJointGroupID set to 0 to allocate the joint normally.
+ * If it is nonzero the joint is allocated in the given joint group.
+ */
+ODE_API dJointID dJointCreateBall (dWorldID, dJointGroupID);
+
+/**
+ * @brief Create a new joint of the hinge type.
+ * @ingroup joints
+ * @param dJointGroupID set to 0 to allocate the joint normally.
+ * If it is nonzero the joint is allocated in the given joint group.
+ */
+ODE_API dJointID dJointCreateHinge (dWorldID, dJointGroupID);
+
+/**
+ * @brief Create a new joint of the slider type.
+ * @ingroup joints
+ * @param dJointGroupID set to 0 to allocate the joint normally.
+ * If it is nonzero the joint is allocated in the given joint group.
+ */
+ODE_API dJointID dJointCreateSlider (dWorldID, dJointGroupID);
+
+/**
+ * @brief Create a new joint of the contact type.
+ * @ingroup joints
+ * @param dJointGroupID set to 0 to allocate the joint normally.
+ * If it is nonzero the joint is allocated in the given joint group.
+ */
+ODE_API dJointID dJointCreateContact (dWorldID, dJointGroupID, const dContact *);
+
+/**
+ * @brief Create a new joint of the hinge2 type.
+ * @ingroup joints
+ * @param dJointGroupID set to 0 to allocate the joint normally.
+ * If it is nonzero the joint is allocated in the given joint group.
+ */
+ODE_API dJointID dJointCreateHinge2 (dWorldID, dJointGroupID);
+
+/**
+ * @brief Create a new joint of the universal type.
+ * @ingroup joints
+ * @param dJointGroupID set to 0 to allocate the joint normally.
+ * If it is nonzero the joint is allocated in the given joint group.
+ */
+ODE_API dJointID dJointCreateUniversal (dWorldID, dJointGroupID);
+
+/**
+ * @brief Create a new joint of the PR (Prismatic and Rotoide) 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 dJointCreatePR (dWorldID, dJointGroupID);
+
+  /**
+   * @brief Create a new joint of the PU (Prismatic and Universal) type.
+   * @ingroup joints
+   * @param dJointGroupID set to 0 to allocate the joint normally.
+   * If it is nonzero the joint is allocated in the given joint group.
+   */
+  ODE_API dJointID dJointCreatePU (dWorldID, dJointGroupID);
+
+  /**
+   * @brief Create a new joint of the Piston 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 dJointCreatePiston (dWorldID, dJointGroupID);
+
+/**
+ * @brief Create a new joint of the fixed type.
+ * @ingroup joints
+ * @param dJointGroupID set to 0 to allocate the joint normally.
+ * If it is nonzero the joint is allocated in the given joint group.
+ */
+ODE_API dJointID dJointCreateFixed (dWorldID, dJointGroupID);
+
+ODE_API dJointID dJointCreateNull (dWorldID, dJointGroupID);
+
+/**
+ * @brief Create a new joint of the A-motor type.
+ * @ingroup joints
+ * @param dJointGroupID set to 0 to allocate the joint normally.
+ * If it is nonzero the joint is allocated in the given joint group.
+ */
+ODE_API dJointID dJointCreateAMotor (dWorldID, dJointGroupID);
+
+/**
+ * @brief Create a new joint of the L-motor type.
+ * @ingroup joints
+ * @param dJointGroupID set to 0 to allocate the joint normally.
+ * If it is nonzero the joint is allocated in the given joint group.
+ */
+ODE_API dJointID dJointCreateLMotor (dWorldID, dJointGroupID);
+
+/**
+ * @brief Create a new joint of the plane-2d 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 dJointCreatePlane2D (dWorldID, dJointGroupID);
+
+/**
+ * @brief Destroy a joint.
+ * @ingroup joints
+ *
+ * disconnects it from its attached bodies and removing it from the world.
+ * However, if the joint is a member of a group then this function has no
+ * effect - to destroy that joint the group must be emptied or destroyed.
+ */
+ODE_API void dJointDestroy (dJointID);
+
+
+/**
+ * @brief Create a joint group
+ * @ingroup joints
+ * @param max_size deprecated. Set to 0.
+ */
+ODE_API dJointGroupID dJointGroupCreate (int max_size);
+
+/**
+ * @brief Destroy a joint group.
+ * @ingroup joints
+ *
+ * All joints in the joint group will be destroyed.
+ */
+ODE_API void dJointGroupDestroy (dJointGroupID);
+
+/**
+ * @brief Empty a joint group.
+ * @ingroup joints
+ *
+ * All joints in the joint group will be destroyed,
+ * but the joint group itself will not be destroyed.
+ */
+ODE_API void dJointGroupEmpty (dJointGroupID);
+
+/**
+ * @brief Return the number of bodies attached to the joint
+ * @ingroup joints
+ */
+ODE_API int dJointGetNumBodies(dJointID);
+
+/**
+ * @brief Attach the joint to some new bodies.
+ * @ingroup joints
+ *
+ * If the joint is already attached, it will be detached from the old bodies
+ * first.
+ * To attach this joint to only one body, set body1 or body2 to zero - a zero
+ * body refers to the static environment.
+ * Setting both bodies to zero puts the joint into "limbo", i.e. it will
+ * have no effect on the simulation.
+ * @remarks
+ * Some joints, like hinge-2 need to be attached to two bodies to work.
+ */
+ODE_API void dJointAttach (dJointID, dBodyID body1, dBodyID body2);
+
+/**
+ * @brief Manually enable a joint.
+ * @param dJointID identification of joint.
+ * @ingroup joints
+ */
+ODE_API void dJointEnable (dJointID);
+
+/**
+ * @brief Manually disable a joint.
+ * @ingroup joints
+ * @remarks
+ * A disabled joint will not affect the simulation, but will maintain the anchors and
+ * axes so it can be enabled later.
+ */
+ODE_API void dJointDisable (dJointID);
+
+/**
+ * @brief Check wether a joint is enabled.
+ * @ingroup joints
+ * @return 1 if a joint is currently enabled or 0 if it is disabled.
+ */
+ODE_API int dJointIsEnabled (dJointID);
+
+/**
+ * @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 dJointTypeBall
+ * \li dJointTypeHinge
+ * \li dJointTypeSlider
+ * \li dJointTypeContact
+ * \li dJointTypeUniversal
+ * \li dJointTypeHinge2
+ * \li dJointTypeFixed
+ * \li dJointTypeNull
+ * \li dJointTypeAMotor
+ * \li dJointTypeLMotor
+ * \li dJointTypePlane2D
+ * \li dJointTypePR
+ * \li dJointTypePU
+ * \li dJointTypePiston
+ */
+ODE_API dJointType dJointGetType (dJointID);
+
+/**
+ * @brief Return the bodies that this joint connects.
+ * @ingroup joints
+ * @param index return the first (0) or second (1) body.
+ * @remarks
+ * If one of these returned body IDs is zero, the joint connects the other body
+ * to the static environment.
+ * If both body IDs are zero, the joint is in ``limbo'' and has no effect on
+ * the simulation.
+ */
+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 Param setting for Ball joints
+ * @ingroup joints
+ */
+ODE_API void dJointSetBallParam (dJointID, int parameter, dReal value);
+
+/**
+ * @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 the Hinge axis as if the 2 bodies were already at angle appart.
+ * @ingroup joints
+ *
+ * This function initialize the Axis and the relative orientation of each body
+ * as if body1 was rotated around the axis by the angle value. \br
+ * Ex:
+ * <PRE>
+ * dJointSetHingeAxis(jId, 1, 0, 0);
+ * // If you request the position you will have: dJointGetHingeAngle(jId) == 0
+ * dJointSetHingeAxisDelta(jId, 1, 0, 0, 0.23);
+ * // If you request the position you will have: dJointGetHingeAngle(jId) == 0.23
+ * </PRE>
+
+ * @param j The Hinge joint ID for which the axis will be set
+ * @param x The X component of the axis in world frame
+ * @param y The Y component of the axis in world frame
+ * @param z The Z component of the axis in world frame
+ * @param angle The angle for the offset of the relative orientation.
+ *              As if body1 was rotated by angle when the Axis was set (see below).
+ *              The rotation is around the new Hinge axis.
+ *
+ * @note Usually the function dJointSetHingeAxis set the current position of body1
+ *       and body2 as the zero angle position. This function set the current position
+ *       as the if the 2 bodies where \b angle appart.
+ * @warning Calling dJointSetHingeAnchor or dJointSetHingeAxis will reset the "zero"
+ *          angle position.
+ */
+ODE_API void dJointSetHingeAxisOffset (dJointID j, dReal x, dReal y, dReal z, dReal angle);
+
+/**
+ * @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 opposite
+ * 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 of
+ * slider's axis, to body1, and with the same magnitude but opposite
+ * direction to body2.  This function is just a wrapper for dBodyAddForce().
+ * @ingroup joints
+ */
+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 torque2);
+
+/**
+ * @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 the Universal axis1 as if the 2 bodies were already at 
+ *        offset1 and offset2 appart with respect to axis1 and axis2.
+ * @ingroup joints
+ *
+ * This function initialize the axis1 and the relative orientation of 
+ * each body as if body1 was rotated around the new axis1 by the offset1 
+ * value and as if body2 was rotated around the axis2 by offset2. \br
+ * Ex:
+* <PRE>
+ * dJointSetHuniversalAxis1(jId, 1, 0, 0);
+ * // If you request the position you will have: dJointGetUniversalAngle1(jId) == 0
+ * // If you request the position you will have: dJointGetUniversalAngle2(jId) == 0
+ * dJointSetHuniversalAxis1Offset(jId, 1, 0, 0, 0.2, 0.17);
+ * // If you request the position you will have: dJointGetUniversalAngle1(jId) == 0.2
+ * // If you request the position you will have: dJointGetUniversalAngle2(jId) == 0.17
+ * </PRE>
+ *
+ * @param j The Hinge joint ID for which the axis will be set
+ * @param x The X component of the axis in world frame
+ * @param y The Y component of the axis in world frame
+ * @param z The Z component of the axis in world frame
+ * @param angle The angle for the offset of the relative orientation.
+ *              As if body1 was rotated by angle when the Axis was set (see below).
+ *              The rotation is around the new Hinge axis.
+ *
+ * @note Usually the function dJointSetHingeAxis set the current position of body1
+ *       and body2 as the zero angle position. This function set the current position
+ *       as the if the 2 bodies where \b offsets appart.
+ *
+ * @note Any previous offsets are erased.
+ *
+ * @warning Calling dJointSetUniversalAnchor, dJointSetUnivesalAxis1, 
+ *          dJointSetUniversalAxis2, dJointSetUniversalAxis2Offset 
+ *          will reset the "zero" angle position.
+ */
+ODE_API void dJointSetUniversalAxis1Offset (dJointID, dReal x, dReal y, dReal z,
+                                            dReal offset1, dReal offset2);
+
+/**
+ * @brief set axis
+ * @ingroup joints
+ */
+ODE_API void dJointSetUniversalAxis2 (dJointID, dReal x, dReal y, dReal z);
+
+/**
+ * @brief Set the Universal axis2 as if the 2 bodies were already at 
+ *        offset1 and offset2 appart with respect to axis1 and axis2.
+ * @ingroup joints
+ *
+ * This function initialize the axis2 and the relative orientation of 
+ * each body as if body1 was rotated around the axis1 by the offset1 
+ * value and as if body2 was rotated around the new axis2 by offset2. \br
+ * Ex:
+ * <PRE>
+ * dJointSetHuniversalAxis2(jId, 0, 1, 0);
+ * // If you request the position you will have: dJointGetUniversalAngle1(jId) == 0
+ * // If you request the position you will have: dJointGetUniversalAngle2(jId) == 0
+ * dJointSetHuniversalAxis2Offset(jId, 0, 1, 0, 0.2, 0.17);
+ * // If you request the position you will have: dJointGetUniversalAngle1(jId) == 0.2
+ * // If you request the position you will have: dJointGetUniversalAngle2(jId) == 0.17
+ * </PRE>
+
+ * @param j The Hinge joint ID for which the axis will be set
+ * @param x The X component of the axis in world frame
+ * @param y The Y component of the axis in world frame
+ * @param z The Z component of the axis in world frame
+ * @param angle The angle for the offset of the relative orientation.
+ *              As if body1 was rotated by angle when the Axis was set (see below).
+ *              The rotation is around the new Hinge axis.
+ *
+ * @note Usually the function dJointSetHingeAxis set the current position of body1
+ *       and body2 as the zero angle position. This function set the current position
+ *       as the if the 2 bodies where \b offsets appart.
+ *
+ * @note Any previous offsets are erased.
+ *
+ * @warning Calling dJointSetUniversalAnchor, dJointSetUnivesalAxis1, 
+ *          dJointSetUniversalAxis2, dJointSetUniversalAxis2Offset 
+ *          will reset the "zero" angle position.
+ */
+
+
+ODE_API void dJointSetUniversalAxis2Offset (dJointID, dReal x, dReal y, dReal z,
+                                            dReal offset1, dReal offset2);
+
+/**
+ * @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 set anchor
+ * @ingroup joints
+ */
+ODE_API void dJointSetPRAnchor (dJointID, dReal x, dReal y, dReal z);
+
+/**
+ * @brief set the axis for the prismatic articulation
+ * @ingroup joints
+ */
+ODE_API void dJointSetPRAxis1 (dJointID, dReal x, dReal y, dReal z);
+
+/**
+ * @brief set the axis for the rotoide articulation
+ * @ingroup joints
+ */
+ODE_API void dJointSetPRAxis2 (dJointID, dReal x, dReal y, dReal z);
+
+/**
+ * @brief set joint parameter
+ * @ingroup joints
+ *
+ * @note parameterX where X equal 2 refer to parameter for the rotoide articulation
+ */
+ODE_API void dJointSetPRParam (dJointID, int parameter, dReal value);
+
+/**
+ * @brief Applies the torque about the rotoide axis of the PR joint
+ *
+ * That is, it applies a torque with specified magnitude in the direction 
+ * of the rotoide axis, to body 1, and with the same magnitude but in opposite
+ * direction to body 2. This function is just a wrapper for dBodyAddTorque()}
+ * @ingroup joints
+ */
+ODE_API void dJointAddPRTorque (dJointID j, dReal torque);
+
+
+  /**
+  * @brief set anchor
+  * @ingroup joints
+  */
+  ODE_API void dJointSetPUAnchor (dJointID, dReal x, dReal y, dReal z);
+
+  /**
+   * @brief set anchor
+   * @ingroup joints
+   */
+  ODE_API_DEPRECATED ODE_API void dJointSetPUAnchorDelta (dJointID, dReal x, dReal y, dReal z,
+                                                          dReal dx, dReal dy, dReal dz);
+
+  /**
+   * @brief Set the PU anchor as if the 2 bodies were already at [dx, dy, dz] appart.
+   * @ingroup joints
+   *
+   * This function initialize the anchor and the relative position of each body
+   * as if the position between body1 and body2 was already the projection of [dx, dy, dz]
+   * along the Piston axis. (i.e as if the body1 was at its current position - [dx,dy,dy] when the
+   * axis is set).
+   * Ex:
+   * <PRE>
+   * dReal offset = 3;
+   * dVector3 axis;
+   * dJointGetPUAxis(jId, axis);
+   * dJointSetPUAnchor(jId, 0, 0, 0);
+   * // If you request the position you will have: dJointGetPUPosition(jId) == 0
+   * dJointSetPUAnchorOffset(jId, 0, 0, 0, axis[X]*offset, axis[Y]*offset, axis[Z]*offset);
+   * // If you request the position you will have: dJointGetPUPosition(jId) == offset
+   * </PRE>
+   * @param j The PU joint for which the anchor point will be set
+   * @param x The X position of the anchor point in world frame
+   * @param y The Y position of the anchor point in world frame
+   * @param z The Z position of the anchor point in world frame
+   * @param dx A delta to be substracted to the X position as if the anchor was set
+   *           when body1 was at current_position[X] - dx
+   * @param dx A delta to be substracted to the Y position as if the anchor was set
+   *           when body1 was at current_position[Y] - dy
+   * @param dx A delta to be substracted to the Z position as if the anchor was set
+   *           when body1 was at current_position[Z] - dz
+   */
+  ODE_API void dJointSetPUAnchorOffset (dJointID, dReal x, dReal y, dReal z,
+                                       dReal dx, dReal dy, dReal dz);
+
+  /**
+   * @brief set the axis for the first axis or the universal articulation
+   * @ingroup joints
+   */
+  ODE_API void dJointSetPUAxis1 (dJointID, dReal x, dReal y, dReal z);
+
+  /**
+   * @brief set the axis for the second axis or the universal articulation
+   * @ingroup joints
+   */
+  ODE_API void dJointSetPUAxis2 (dJointID, dReal x, dReal y, dReal z);
+
+  /**
+   * @brief set the axis for the prismatic articulation
+   * @ingroup joints
+   */
+  ODE_API void dJointSetPUAxis3 (dJointID, dReal x, dReal y, dReal z);
+
+  /**
+   * @brief set the axis for the prismatic articulation
+   * @ingroup joints
+   * @note This function was added for convenience it is the same as
+   *       dJointSetPUAxis3
+   */
+  ODE_API void dJointSetPUAxisP (dJointID id, dReal x, dReal y, dReal z);
+
+
+
+  /**
+   * @brief set joint parameter
+   * @ingroup joints
+   *
+   * @note parameterX where X equal 2 refer to parameter for second axis of the
+   *       universal articulation
+   * @note parameterX where X equal 3 refer to parameter for prismatic
+   *       articulation
+   */
+  ODE_API void dJointSetPUParam (dJointID, int parameter, dReal value);
+
+  /**
+   * @brief Applies the torque about the rotoide axis of the PU joint
+   *
+   * That is, it applies a torque with specified magnitude in the direction
+   * of the rotoide axis, to body 1, and with the same magnitude but in opposite
+   * direction to body 2. This function is just a wrapper for dBodyAddTorque()}
+   * @ingroup joints
+   */
+  ODE_API void dJointAddPUTorque (dJointID j, dReal torque);
+
+
+
+
+  /**
+   * @brief set the joint anchor
+   * @ingroup joints
+   */
+  ODE_API void dJointSetPistonAnchor (dJointID, dReal x, dReal y, dReal z);
+
+  /**
+   * @brief Set the Piston anchor as if the 2 bodies were already at [dx,dy, dz] appart.
+   * @ingroup joints
+   *
+   * This function initialize the anchor and the relative position of each body
+   * as if the position between body1 and body2 was already the projection of [dx, dy, dz]
+   * along the Piston axis. (i.e as if the body1 was at its current position - [dx,dy,dy] when the
+   * axis is set).
+   * Ex:
+   * <PRE>
+   * dReal offset = 3;
+   * dVector3 axis;
+   * dJointGetPistonAxis(jId, axis);
+   * dJointSetPistonAnchor(jId, 0, 0, 0);
+   * // If you request the position you will have: dJointGetPistonPosition(jId) == 0
+   * dJointSetPistonAnchorOffset(jId, 0, 0, 0, axis[X]*offset, axis[Y]*offset, axis[Z]*offset);
+   * // If you request the position you will have: dJointGetPistonPosition(jId) == offset
+   * </PRE>
+   * @param j The Piston joint for which the anchor point will be set
+   * @param x The X position of the anchor point in world frame
+   * @param y The Y position of the anchor point in world frame
+   * @param z The Z position of the anchor point in world frame
+   * @param dx A delta to be substracted to the X position as if the anchor was set
+   *           when body1 was at current_position[X] - dx
+   * @param dx A delta to be substracted to the Y position as if the anchor was set
+   *           when body1 was at current_position[Y] - dy
+   * @param dx A delta to be substracted to the Z position as if the anchor was set
+   *           when body1 was at current_position[Z] - dz
+   */
+  ODE_API void dJointSetPistonAnchorOffset(dJointID j, dReal x, dReal y, dReal z,
+                                           dReal dx, dReal dy, dReal dz);
+
+    /**
+     * @brief set the joint axis
+   * @ingroup joints
+   */
+  ODE_API void dJointSetPistonAxis (dJointID, dReal x, dReal y, dReal z);
+
+  /**
+   * This function set prismatic axis of the joint and also set the position
+   * of the joint.
+   *
+   * @ingroup joints
+   * @param j The joint affected by this function
+   * @param x The x component of the axis
+   * @param y The y component of the axis
+   * @param z The z component of the axis
+   * @param dx The Initial position of the prismatic join in the x direction
+   * @param dy The Initial position of the prismatic join in the y direction
+   * @param dz The Initial position of the prismatic join in the z direction
+   */
+  ODE_API_DEPRECATED ODE_API void dJointSetPistonAxisDelta (dJointID j, dReal x, dReal y, dReal z, dReal ax, dReal ay, dReal az);
+
+  /**
+   * @brief set joint parameter
+   * @ingroup joints
+   */
+  ODE_API void dJointSetPistonParam (dJointID, int parameter, dReal value);
+
+  /**
+   * @brief Applies the given force in the slider's direction.
+   *
+   * That is, it applies a force with specified magnitude, in the direction of
+   * prismatic'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 dJointAddPistonForce (dJointID joint, dReal force);
+
+
+/**
+ * @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 Sets joint parameter
+ *
+ * @ingroup joints
+ */
+ODE_API void dJointSetFixedParam (dJointID, int parameter, dReal value);
+
+/**
+ * @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'' modes
+ * \li 0: The axis is anchored to the global frame.
+ * \li 1: The axis is anchored to the first body.
+ * \li 2: The axis is anchored to the second body.
+ * @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, dReal y, dReal z);
+
+/**
+ * @brief set joint parameter
+ * @ingroup joints
+ */
+ODE_API void dJointSetLMotorParam (dJointID, int parameter, dReal value);
+
+/**
+ * @ingroup joints
+ */
+ODE_API void dJointSetPlane2DXParam (dJointID, int parameter, dReal value);
+
+/**
+ * @ingroup joints
+ */
+
+ODE_API void dJointSetPlane2DYParam (dJointID, int parameter, dReal value);
+
+/**
+ * @ingroup joints
+ */
+ODE_API void dJointSetPlane2DAngleParam (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 joint parameter
+ * @ingroup joints
+ */
+ODE_API dReal dJointGetBallParam (dJointID, int parameter);
+
+/**
+ * @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.
+ * Give the relative rotation with respect to the Hinge axis of Body 1 with
+ * respect to Body 2.
+ * When the hinge anchor or axis is set, the current position of the attached
+ * bodies is examined and that position will be the zero angle.
+ * @ingroup joints
+ */
+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.
+
+ * The position is the distance, with respect to the zero position,
+ * along the slider axis of body 1 with respect to
+ * body 2. (A NULL body is replaced by the world).
+ * @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 both angles at the same time.
+ * @ingroup joints
+ *
+ * @param joint   The universal joint for which we want to calculate the angles
+ * @param angle1  The angle between the body1 and the axis 1
+ * @param angle2  The angle between the body2 and the axis 2
+ *
+ * @note This function combine getUniversalAngle1 and getUniversalAngle2 together
+ *       and try to avoid redundant calculation
+ */
+ODE_API void dJointGetUniversalAngles (dJointID, dReal *angle1, dReal *angle2);
+
+/**
+ * @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 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 dJointGetPRAnchor (dJointID, dVector3 result);
+
+/**
+ * @brief Get the PR linear position (i.e. the prismatic's extension)
+ *
+ * When the axis is set, the current position of the attached bodies is
+ * examined and that position will be the zero position.
+ *
+ * The position is the "oriented" length between the
+ * position = (Prismatic axis) dot_product [(body1 + offset) - (body2 + anchor2)]
+ *
+ * @ingroup joints
+ */
+ODE_API dReal dJointGetPRPosition (dJointID);
+
+/**
+ * @brief Get the PR linear position's time derivative
+ *
+ * @ingroup joints
+ */
+ODE_API dReal dJointGetPRPositionRate (dJointID);
+
+
+/**
+   * @brief Get the PR angular position (i.e. the  twist between the 2 bodies)
+   *
+   * 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 dJointGetPRAngle (dJointID);
+
+/**
+ * @brief Get the PR angular position's time derivative
+ *
+ * @ingroup joints
+ */
+ODE_API dReal dJointGetPRAngleRate (dJointID);
+
+
+/**
+ * @brief Get the prismatic axis
+ * @ingroup joints
+ */
+ODE_API void dJointGetPRAxis1 (dJointID, dVector3 result);
+
+/**
+ * @brief Get the Rotoide axis
+ * @ingroup joints
+ */
+ODE_API void dJointGetPRAxis2 (dJointID, dVector3 result);
+
+/**
+ * @brief get joint parameter
+ * @ingroup joints
+ */
+ODE_API dReal dJointGetPRParam (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 dJointGetPUAnchor (dJointID, dVector3 result);
+
+  /**
+   * @brief Get the PU linear position (i.e. the prismatic's extension)
+   *
+   * When the axis is set, the current position of the attached bodies is
+   * examined and that position will be the zero position.
+   *
+   * The position is the "oriented" length between the
+   * position = (Prismatic axis) dot_product [(body1 + offset) - (body2 + anchor2)]
+   *
+   * @ingroup joints
+   */
+  ODE_API dReal dJointGetPUPosition (dJointID);
+
+  /**
+   * @brief Get the PR linear position's time derivative
+   *
+   * @ingroup joints
+   */
+  ODE_API dReal dJointGetPUPositionRate (dJointID);
+
+  /**
+   * @brief Get the first axis of the universal component of the joint
+   * @ingroup joints
+   */
+  ODE_API void dJointGetPUAxis1 (dJointID, dVector3 result);
+
+  /**
+   * @brief Get the second axis of the Universal component of the joint
+   * @ingroup joints
+   */
+  ODE_API void dJointGetPUAxis2 (dJointID, dVector3 result);
+
+  /**
+   * @brief Get the prismatic axis
+   * @ingroup joints
+   */
+  ODE_API void dJointGetPUAxis3 (dJointID, dVector3 result);
+
+  /**
+   * @brief Get the prismatic axis
+   * @ingroup joints
+   *
+   * @note This function was added for convenience it is the same as
+   *       dJointGetPUAxis3
+   */
+  ODE_API void dJointGetPUAxisP (dJointID id, dVector3 result);
+
+
+
+
+  /**
+   * @brief Get both angles at the same time.
+   * @ingroup joints
+   *
+   * @param joint   The Prismatic universal joint for which we want to calculate the angles
+   * @param angle1  The angle between the body1 and the axis 1
+   * @param angle2  The angle between the body2 and the axis 2
+   *
+   * @note This function combine dJointGetPUAngle1 and dJointGetPUAngle2 together
+   *       and try to avoid redundant calculation
+   */
+  ODE_API void dJointGetPUAngles (dJointID, dReal *angle1, dReal *angle2);
+
+  /**
+   * @brief Get angle
+   * @ingroup joints
+   */
+  ODE_API dReal dJointGetPUAngle1 (dJointID);
+
+  /**
+   * @brief * @brief Get time derivative of angle1
+   *
+   * @ingroup joints
+   */
+  ODE_API dReal dJointGetPUAngle1Rate (dJointID);
+
+
+  /**
+   * @brief Get angle
+   * @ingroup joints
+   */
+  ODE_API dReal dJointGetPUAngle2 (dJointID);
+
+  /**
+   * @brief * @brief Get time derivative of angle2
+   *
+   * @ingroup joints
+   */
+  ODE_API dReal dJointGetPUAngle2Rate (dJointID);
+
+  /**
+   * @brief get joint parameter
+   * @ingroup joints
+   */
+  ODE_API dReal dJointGetPUParam (dJointID, int parameter);
+
+
+
+
+
+/**
+   * @brief Get the Piston linear position (i.e. the piston'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 dJointGetPistonPosition (dJointID);
+
+  /**
+   * @brief Get the piston linear position's time derivative.
+   * @ingroup joints
+   */
+  ODE_API dReal dJointGetPistonPositionRate (dJointID);
+
+/**
+   * @brief Get the Piston angular position (i.e. the  twist between the 2 bodies)
+   *
+   * 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 dJointGetPistonAngle (dJointID);
+
+  /**
+   * @brief Get the piston angular position's time derivative.
+   * @ingroup joints
+   */
+  ODE_API dReal dJointGetPistonAngleRate (dJointID);
+
+
+  /**
+   * @brief Get the joint anchor
+   *
+   * This returns the point on body 1. If the joint is perfectly satisfied,
+   * this will be the same as the point on body 2 in direction perpendicular
+   * to the prismatic axis.
+   *
+   * @ingroup joints
+   */
+  ODE_API void dJointGetPistonAnchor (dJointID, dVector3 result);
+
+  /**
+   * @brief Get the joint anchor w.r.t. body 2
+   *
+   * This returns the point on body 2. You can think of a Piston
+   * joint as trying to keep the result of dJointGetPistonAnchor() and
+   * dJointGetPistonAnchor2() the same in the direction perpendicular to the
+   * pirsmatic axis. If the joint is perfectly satisfied,
+   * this function will return the same value as dJointGetPistonAnchor() to
+   * within roundoff errors. dJointGetPistonAnchor2() can be used, along with
+   * dJointGetPistonAnchor(), to see how far the joint has come apart.
+   *
+   * @ingroup joints
+   */
+  ODE_API void dJointGetPistonAnchor2 (dJointID, dVector3 result);
+
+  /**
+   * @brief Get the prismatic axis (This is also the rotoide axis.
+   * @ingroup joints
+   */
+  ODE_API void dJointGetPistonAxis (dJointID, dVector3 result);
+
+  /**
+   * @brief get joint parameter
+   * @ingroup joints
+   */
+  ODE_API dReal dJointGetPistonParam (dJointID, int parameter);
+
+
+  /**
+ * @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'' modes.
+ * \li 0: The axis is anchored to the global frame.
+ * \li 1: The axis is anchored to the first body.
+ * \li 2: The axis is anchored to the second body.
+ * @ingroup joints
+ */
+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);
+
+/**
+ * @brief get joint parameter
+ * @ingroup joints
+ */
+ODE_API dReal dJointGetFixedParam (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 body1 A body to check.
+ * @param body2 A body to check.
+ * @param joint_type is a dJointTypeXXX constant.
+ * This is useful for deciding whether to add contact joints between two bodies:
+ * if they are already connected by non-contact joints then it may not be
+ * appropriate to add contacts, however it is okay to add more contact between-
+ * bodies that already have contacts.
+ * @ingroup joints
+ */
+ODE_API int dAreConnectedExcluding (dBodyID body1, dBodyID body2, int joint_type);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/misc/builddeps/dp.linux32/include/ode/ode.h b/misc/builddeps/dp.linux32/include/ode/ode.h
new file mode 100644 (file)
index 0000000..af74e50
--- /dev/null
@@ -0,0 +1,48 @@
+/*************************************************************************
+ *                                                                       *
+ * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith.       *
+ * All rights reserved.  Email: russ@q12.org   Web: www.q12.org          *
+ *                                                                       *
+ * This library is free software; you can redistribute it and/or         *
+ * modify it under the terms of EITHER:                                  *
+ *   (1) The GNU Lesser General Public License as published by the Free  *
+ *       Software Foundation; either version 2.1 of the License, or (at  *
+ *       your option) any later version. The text of the GNU Lesser      *
+ *       General Public License is included with this library in the     *
+ *       file LICENSE.TXT.                                               *
+ *   (2) The BSD-style license that is included with this library in     *
+ *       the file LICENSE-BSD.TXT.                                       *
+ *                                                                       *
+ * This library is distributed in the hope that it will be useful,       *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files    *
+ * LICENSE.TXT and LICENSE-BSD.TXT for more details.                     *
+ *                                                                       *
+ *************************************************************************/
+
+#ifndef _ODE_ODE_H_
+#define _ODE_ODE_H_
+
+/* include *everything* here */
+
+#include <ode/odeconfig.h>
+#include <ode/compatibility.h>
+#include <ode/common.h>
+#include <ode/odeinit.h>
+#include <ode/contact.h>
+#include <ode/error.h>
+#include <ode/memory.h>
+#include <ode/odemath.h>
+#include <ode/matrix.h>
+#include <ode/timer.h>
+#include <ode/rotation.h>
+#include <ode/mass.h>
+#include <ode/misc.h>
+#include <ode/objects.h>
+#include <ode/odecpp.h>
+#include <ode/collision_space.h>
+#include <ode/collision.h>
+#include <ode/odecpp_collision.h>
+#include <ode/export-dif.h>
+
+#endif
diff --git a/misc/builddeps/dp.linux32/include/ode/odeconfig.h b/misc/builddeps/dp.linux32/include/ode/odeconfig.h
new file mode 100644 (file)
index 0000000..6e32fc6
--- /dev/null
@@ -0,0 +1,93 @@
+#ifndef ODECONFIG_H
+#define ODECONFIG_H
+
+/* Pull in the standard headers */
+#include <stddef.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <math.h>
+#include <string.h>
+#include <float.h>
+
+
+#if defined(ODE_DLL) || defined(ODE_LIB)
+#define __ODE__
+#endif
+
+/* Define a DLL export symbol for those platforms that need it */
+#if defined(_MSC_VER)
+  #if defined(ODE_DLL)
+    #define ODE_API __declspec(dllexport)
+  #elif !defined(ODE_LIB)
+    #define ODE_DLL_API __declspec(dllimport)
+  #endif
+#endif
+
+#if !defined(ODE_API)
+  #define ODE_API
+#endif
+
+#if defined(_MSC_VER)
+#  define ODE_API_DEPRECATED __declspec(deprecated)
+#elif defined (__GNUC__) && ( (__GNUC__ > 3) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 1)) )
+#  define ODE_API_DEPRECATED __attribute__((__deprecated__))
+#else
+#  define ODE_API_DEPRECATED
+#endif
+
+/* Well-defined common data types...need to define for 64 bit systems */
+#if defined(_M_IA64) || defined(__ia64__) || defined(_M_AMD64) || defined(__x86_64__)
+  #define X86_64_SYSTEM   1
+  typedef int             int32;
+  typedef unsigned int    uint32;
+  typedef short           int16;
+  typedef unsigned short  uint16;
+  typedef signed char     int8;
+  typedef unsigned char   uint8;
+#else
+  typedef int             int32;
+  typedef unsigned int    uint32;
+  typedef short           int16;
+  typedef unsigned short  uint16;
+  typedef signed char     int8;
+  typedef unsigned char   uint8;
+#endif
+
+/* Visual C does not define these functions */
+#if defined(_MSC_VER)
+  #define copysignf(x, y) ((float)_copysign(x, y))
+  #define copysign(x, y) _copysign(x, y)
+  #define nextafterf(x, y) _nextafterf(x, y)
+  #define nextafter(x, y) _nextafter(x, y)
+  #if !defined(_WIN64)
+    #define _ODE__NEXTAFTERF_REQUIRED
+  #endif
+#endif
+
+
+
+/* Define the dInfinity macro */
+#ifdef INFINITY
+  #define dInfinity INFINITY
+#elif defined(HUGE_VAL)
+  #ifdef dSINGLE
+    #ifdef HUGE_VALF
+      #define dInfinity HUGE_VALF
+    #else
+      #define dInfinity ((float)HUGE_VAL)
+    #endif
+  #else
+    #define dInfinity HUGE_VAL
+  #endif
+#else
+  #ifdef dSINGLE
+    #define dInfinity ((float)(1.0/0.0))
+  #else
+    #define dInfinity (1.0/0.0)
+  #endif
+#endif
+
+
+#endif
diff --git a/misc/builddeps/dp.linux32/include/ode/odecpp.h b/misc/builddeps/dp.linux32/include/ode/odecpp.h
new file mode 100644 (file)
index 0000000..f734892
--- /dev/null
@@ -0,0 +1,1353 @@
+/*************************************************************************
+ *                                                                      *
+ * Open Dynamics Engine, Copyright (C) 2001, 2002 Russell L. Smith.     *
+ * All rights reserved.  Email: russ@q12.org   Web: www.q12.org         *
+ *                                                                      *
+ * This library is free software; you can redistribute it and/or        *
+ * modify it under the terms of EITHER:                                 *
+ *   (1) The GNU Lesser General Public License as published by the Free  *
+ *      Software Foundation; either version 2.1 of the License, or (at  *
+ *      your option) any later version. The text of the GNU Lesser      *
+ *      General Public License is included with this library in the     *
+ *      file LICENSE.TXT.                                               *
+ *   (2) The BSD-style license that is included with this library in    *
+ *      the file LICENSE-BSD.TXT.                                       *
+ *                                                                      *
+ * This library is distributed in the hope that it will be useful,      *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of       *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files   *
+ * LICENSE.TXT and LICENSE-BSD.TXT for more details.                    *
+ *                                                                      *
+ *************************************************************************/
+
+/* C++ interface for non-collision stuff */
+
+
+#ifndef _ODE_ODECPP_H_
+#define _ODE_ODECPP_H_
+#ifdef __cplusplus
+
+
+
+
+//namespace ode {
+
+
+class dWorldSimpleIDContainer {
+protected:
+       dWorldID _id;
+
+       dWorldSimpleIDContainer(): _id(0) {}
+       ~dWorldSimpleIDContainer() { destroy(); }
+
+       void destroy() { 
+               if (_id) {
+                       dWorldDestroy(_id); 
+                       _id = 0;
+               }
+       }
+};
+
+class dWorldDynamicIDContainer: public dWorldSimpleIDContainer {
+protected:
+       virtual ~dWorldDynamicIDContainer() {}
+};
+
+template <class dWorldTemplateBase>
+class dWorldTemplate: public dWorldTemplateBase {
+  // intentionally undefined, don't use these
+  dWorldTemplate (const dWorldTemplate<dWorldTemplateBase> &);
+  void operator= (const dWorldTemplate<dWorldTemplateBase> &);
+
+protected:
+  dWorldID get_id() const { return dWorldTemplateBase::_id; }
+  void set_id(dWorldID value) { dWorldTemplateBase::_id = value; }
+
+public:
+  dWorldTemplate()
+    { set_id(dWorldCreate()); }
+
+  dWorldID id() const
+    { return get_id(); }
+  operator dWorldID() const
+    { return get_id(); }
+
+  void setGravity (dReal x, dReal y, dReal z)
+    { dWorldSetGravity (get_id(), x, y, z); }
+  void setGravity (const dVector3 g)
+    { setGravity (g[0], g[1], g[2]); }
+  void getGravity (dVector3 g) const
+    { dWorldGetGravity (get_id(), g); }
+
+  void setERP (dReal erp)
+    { dWorldSetERP(get_id(), erp); }
+  dReal getERP() const
+    { return dWorldGetERP(get_id()); }
+
+  void setCFM (dReal cfm)
+    { dWorldSetCFM(get_id(), cfm); }
+  dReal getCFM() const
+    { return dWorldGetCFM(get_id()); }
+
+  void step (dReal stepsize)
+    { dWorldStep (get_id(), stepsize); }
+
+  void quickStep(dReal stepsize)
+    { dWorldQuickStep (get_id(), stepsize); }
+  void setQuickStepNumIterations(int num)
+    { dWorldSetQuickStepNumIterations (get_id(), num); }
+  int getQuickStepNumIterations() const
+    { return dWorldGetQuickStepNumIterations (get_id()); }
+  void setQuickStepW(dReal over_relaxation)
+    { dWorldSetQuickStepW (get_id(), over_relaxation); }
+  dReal getQuickStepW() const
+    { return dWorldGetQuickStepW (get_id()); }
+
+  void  setAutoDisableLinearThreshold (dReal threshold) 
+    { dWorldSetAutoDisableLinearThreshold (get_id(), threshold); }
+  dReal getAutoDisableLinearThreshold() const
+    { return dWorldGetAutoDisableLinearThreshold (get_id()); }
+  void setAutoDisableAngularThreshold (dReal threshold)
+    { dWorldSetAutoDisableAngularThreshold (get_id(), threshold); }
+  dReal getAutoDisableAngularThreshold() const
+    { return dWorldGetAutoDisableAngularThreshold (get_id()); }
+  void setAutoDisableSteps (int steps)
+    { dWorldSetAutoDisableSteps (get_id(), steps); }
+  int getAutoDisableSteps() const
+    { return dWorldGetAutoDisableSteps (get_id()); }
+  void setAutoDisableTime (dReal time)
+    { dWorldSetAutoDisableTime (get_id(), time); }
+  dReal getAutoDisableTime() const
+    { return dWorldGetAutoDisableTime (get_id()); }
+  void setAutoDisableFlag (int do_auto_disable)
+    { dWorldSetAutoDisableFlag (get_id(), do_auto_disable); }
+  int getAutoDisableFlag() const
+    { return dWorldGetAutoDisableFlag (get_id()); }
+
+  dReal getLinearDampingThreshold() const
+    { return dWorldGetLinearDampingThreshold(get_id()); }
+  void setLinearDampingThreshold(dReal threshold)
+    { dWorldSetLinearDampingThreshold(get_id(), threshold); }
+  dReal getAngularDampingThreshold() const
+    { return dWorldGetAngularDampingThreshold(get_id()); }
+  void setAngularDampingThreshold(dReal threshold)
+    { dWorldSetAngularDampingThreshold(get_id(), threshold); }
+  dReal getLinearDamping() const
+    { return dWorldGetLinearDamping(get_id()); }
+  void setLinearDamping(dReal scale)
+    { dWorldSetLinearDamping(get_id(), scale); }
+  dReal getAngularDamping() const
+    { return dWorldGetAngularDamping(get_id()); }
+  void setAngularDamping(dReal scale)
+    { dWorldSetAngularDamping(get_id(), scale); }
+  void setDamping(dReal linear_scale, dReal angular_scale)
+    { dWorldSetDamping(get_id(), linear_scale, angular_scale); }
+
+  dReal getMaxAngularSpeed() const
+    { return dWorldGetMaxAngularSpeed(get_id()); }
+  void setMaxAngularSpeed(dReal max_speed)
+    { dWorldSetMaxAngularSpeed(get_id(), max_speed); }
+
+  void setContactSurfaceLayer(dReal depth)
+    { dWorldSetContactSurfaceLayer (get_id(), depth); }
+  dReal getContactSurfaceLayer() const
+    { return dWorldGetContactSurfaceLayer (get_id()); }
+
+  void impulseToForce (dReal stepsize, dReal ix, dReal iy, dReal iz, 
+                      dVector3 force)
+    { dWorldImpulseToForce (get_id(), stepsize, ix, iy, iz, force); }
+};
+
+
+class dBodySimpleIDContainer {
+protected:
+       dBodyID _id;
+
+       dBodySimpleIDContainer(): _id(0) {}
+       ~dBodySimpleIDContainer() { destroy(); }
+
+       void destroy() { 
+               if (_id) {
+                       dBodyDestroy(_id); 
+                       _id = 0;
+               }
+       }
+};
+
+class dBodyDynamicIDContainer: public dBodySimpleIDContainer {
+protected:
+       virtual ~dBodyDynamicIDContainer() {}
+};
+
+template <class dBodyTemplateBase, class dWorldTemplateBase>
+class dBodyTemplate: public dBodyTemplateBase {
+  // intentionally undefined, don't use these
+  dBodyTemplate (const dBodyTemplate<dBodyTemplateBase, dWorldTemplateBase> &);
+  void operator= (const dBodyTemplate<dBodyTemplateBase, dWorldTemplateBase> &);
+
+protected:
+  dBodyID get_id() const { return dBodyTemplateBase::_id; }
+  void set_id(dBodyID value) { dBodyTemplateBase::_id = value; }
+
+  void destroy() { dBodyTemplateBase::destroy(); }
+
+public:
+  dBodyTemplate()
+    { }
+  dBodyTemplate (dWorldID world)
+    { set_id(dBodyCreate(world)); }
+  dBodyTemplate (dWorldTemplate<dWorldTemplateBase>& world)
+    { set_id(dBodyCreate(world.id())); }
+
+  void create (dWorldID world) {
+    destroy();
+    set_id(dBodyCreate(world));
+  }
+  void create (dWorldTemplate<dWorldTemplateBase>& world) {
+    create(world.id());
+  }
+
+  dBodyID id() const
+    { return get_id(); }
+  operator dBodyID() const
+    { return get_id(); }
+
+  void setData (void *data)
+    { dBodySetData (get_id(), data); }
+  void *getData() const
+    { return dBodyGetData (get_id()); }
+
+  void setPosition (dReal x, dReal y, dReal z)
+    { dBodySetPosition (get_id(), x, y, z); }
+  void setPosition (const dVector3 p)
+    { setPosition(p[0], p[1], p[2]); }
+
+  void setRotation (const dMatrix3 R)
+    { dBodySetRotation (get_id(), R); }
+  void setQuaternion (const dQuaternion q)
+    { dBodySetQuaternion (get_id(), q); }
+  void setLinearVel (dReal x, dReal y, dReal z)
+    { dBodySetLinearVel (get_id(), x, y, z); }
+  void setLinearVel (const dVector3 v)
+    { setLinearVel(v[0], v[1], v[2]); }
+  void setAngularVel (dReal x, dReal y, dReal z)
+    { dBodySetAngularVel (get_id(), x, y, z); }
+  void setAngularVel (const dVector3 v)
+    { setAngularVel (v[0], v[1], v[2]); }
+
+  const dReal * getPosition() const
+    { return dBodyGetPosition (get_id()); }
+  const dReal * getRotation() const
+    { return dBodyGetRotation (get_id()); }
+  const dReal * getQuaternion() const
+    { return dBodyGetQuaternion (get_id()); }
+  const dReal * getLinearVel() const
+    { return dBodyGetLinearVel (get_id()); }
+  const dReal * getAngularVel() const
+    { return dBodyGetAngularVel (get_id()); }
+
+  void setMass (const dMass *mass)
+    { dBodySetMass (get_id(), mass); }
+  void setMass (const dMass &mass)
+    { setMass (&mass); }
+  dMass getMass () const
+    { dMass mass; dBodyGetMass (get_id(), &mass); return mass; }
+
+  void addForce (dReal fx, dReal fy, dReal fz)
+    { dBodyAddForce (get_id(), fx, fy, fz); }
+  void addForce (const dVector3 f)
+    { addForce (f[0], f[1], f[2]); }
+  void addTorque (dReal fx, dReal fy, dReal fz)
+    { dBodyAddTorque (get_id(), fx, fy, fz); }
+  void addTorque (const dVector3 t)
+    { addTorque(t[0], t[1], t[2]); }
+
+  void addRelForce (dReal fx, dReal fy, dReal fz)
+    { dBodyAddRelForce (get_id(), fx, fy, fz); }
+  void addRelForce (const dVector3 f)
+    { addRelForce (f[0], f[1], f[2]); }
+  void addRelTorque (dReal fx, dReal fy, dReal fz)
+    { dBodyAddRelTorque (get_id(), fx, fy, fz); }
+  void addRelTorque (const dVector3 t)
+    { addRelTorque (t[0], t[1], t[2]); }
+
+  void addForceAtPos (dReal fx, dReal fy, dReal fz, 
+                     dReal px, dReal py, dReal pz)
+    { dBodyAddForceAtPos (get_id(), fx, fy, fz, px, py, pz); }
+  void addForceAtPos (const dVector3 f, const dVector3 p)
+    { addForceAtPos (f[0], f[1], f[2], p[0], p[1], p[2]); }
+
+  void addForceAtRelPos (dReal fx, dReal fy, dReal fz, 
+                         dReal px, dReal py, dReal pz)
+    { dBodyAddForceAtRelPos (get_id(), fx, fy, fz, px, py, pz); }
+  void addForceAtRelPos (const dVector3 f, const dVector3 p)
+    { addForceAtRelPos (f[0], f[1], f[2], p[0], p[1], p[2]); }
+
+  void addRelForceAtPos (dReal fx, dReal fy, dReal fz, 
+                        dReal px, dReal py, dReal pz)
+    { dBodyAddRelForceAtPos (get_id(), fx, fy, fz, px, py, pz); }
+  void addRelForceAtPos (const dVector3 f, const dVector3 p)
+    { addRelForceAtPos (f[0], f[1], f[2], p[0], p[1], p[2]); }
+
+  void addRelForceAtRelPos (dReal fx, dReal fy, dReal fz, 
+                           dReal px, dReal py, dReal pz)
+    { dBodyAddRelForceAtRelPos (get_id(), fx, fy, fz, px, py, pz); }
+  void addRelForceAtRelPos (const dVector3 f, const dVector3 p)
+    { addRelForceAtRelPos (f[0], f[1], f[2], p[0], p[1], p[2]); }
+
+  const dReal * getForce() const
+    { return dBodyGetForce(get_id()); }
+  const dReal * getTorque() const
+    { return dBodyGetTorque(get_id()); }
+  void setForce (dReal x, dReal y, dReal z)
+    { dBodySetForce (get_id(), x, y, z); }
+  void setForce (const dVector3 f)
+    { setForce (f[0], f[1], f[2]); }
+  void setTorque (dReal x, dReal y, dReal z)
+    { dBodySetTorque (get_id(), x, y, z); }
+  void setTorque (const dVector3 t)
+  { setTorque (t[0], t[1], t[2]); }
+
+  void setDynamic()
+    { dBodySetDynamic (get_id()); }
+  void setKinematic()
+    { dBodySetKinematic (get_id()); }
+  bool isKinematic() const
+    { return dBodyIsKinematic (get_id()) != 0; }
+
+  void enable()
+    { dBodyEnable (get_id()); }
+  void disable()
+    { dBodyDisable (get_id()); }
+  bool isEnabled() const
+    { return dBodyIsEnabled (get_id()) != 0; }
+
+  void getRelPointPos (dReal px, dReal py, dReal pz, dVector3 result) const
+    { dBodyGetRelPointPos (get_id(), px, py, pz, result); }
+  void getRelPointPos (const dVector3 p, dVector3 result) const
+    { getRelPointPos (p[0], p[1], p[2], result); }
+
+  void getRelPointVel (dReal px, dReal py, dReal pz, dVector3 result) const
+    { dBodyGetRelPointVel (get_id(), px, py, pz, result); }
+  void getRelPointVel (const dVector3 p, dVector3 result) const
+    { getRelPointVel (p[0], p[1], p[2], result); }
+
+  void getPointVel (dReal px, dReal py, dReal pz, dVector3 result) const
+    { dBodyGetPointVel (get_id(), px, py, pz, result); }
+  void getPointVel (const dVector3 p, dVector3 result) const
+    { getPointVel (p[0], p[1], p[2], result); }
+
+  void getPosRelPoint (dReal px, dReal py, dReal pz, dVector3 result) const
+    { dBodyGetPosRelPoint (get_id(), px, py, pz, result); }
+  void getPosRelPoint (const dVector3 p, dVector3 result) const
+    { getPosRelPoint (p[0], p[1], p[2], result); }
+
+  void vectorToWorld (dReal px, dReal py, dReal pz, dVector3 result) const
+    { dBodyVectorToWorld (get_id(), px, py, pz, result); }
+  void vectorToWorld (const dVector3 p, dVector3 result) const
+    { vectorToWorld (p[0], p[1], p[2], result); }
+
+  void vectorFromWorld (dReal px, dReal py, dReal pz, dVector3 result) const
+    { dBodyVectorFromWorld (get_id(), px, py, pz, result); }
+  void vectorFromWorld (const dVector3 p, dVector3 result) const
+    { vectorFromWorld (p[0], p[1], p[2], result); }
+
+  void setFiniteRotationMode (bool mode)
+    { dBodySetFiniteRotationMode (get_id(), mode); }
+
+  void setFiniteRotationAxis (dReal x, dReal y, dReal z)
+    { dBodySetFiniteRotationAxis (get_id(), x, y, z); }
+  void setFiniteRotationAxis (const dVector3 a)
+    { setFiniteRotationAxis (a[0], a[1], a[2]); }
+
+  bool getFiniteRotationMode() const
+    { return dBodyGetFiniteRotationMode (get_id()) != 0; }
+  void getFiniteRotationAxis (dVector3 result) const
+    { dBodyGetFiniteRotationAxis (get_id(), result); }
+
+  int getNumJoints() const
+    { return dBodyGetNumJoints (get_id()); }
+  dJointID getJoint (int index) const
+    { return dBodyGetJoint (get_id(), index); }
+
+  void setGravityMode (bool mode)
+    { dBodySetGravityMode (get_id(), mode); }
+  bool getGravityMode() const
+    { return dBodyGetGravityMode (get_id()) != 0; }
+
+  bool isConnectedTo (dBodyID body) const
+    { return dAreConnected (get_id(), body) != 0; }
+
+  void  setAutoDisableLinearThreshold (dReal threshold) 
+    { dBodySetAutoDisableLinearThreshold (get_id(), threshold); }
+  dReal getAutoDisableLinearThreshold() const
+    { return dBodyGetAutoDisableLinearThreshold (get_id()); }
+  void setAutoDisableAngularThreshold (dReal threshold)
+    { dBodySetAutoDisableAngularThreshold (get_id(), threshold); }
+  dReal getAutoDisableAngularThreshold() const
+    { return dBodyGetAutoDisableAngularThreshold (get_id()); }
+  void setAutoDisableSteps (int steps)
+    { dBodySetAutoDisableSteps (get_id(), steps); }
+  int getAutoDisableSteps() const
+    { return dBodyGetAutoDisableSteps (get_id()); }
+  void setAutoDisableTime (dReal time)
+    { dBodySetAutoDisableTime (get_id(), time); }
+  dReal getAutoDisableTime() const
+    { return dBodyGetAutoDisableTime (get_id()); }
+  void setAutoDisableFlag (bool do_auto_disable)
+    { dBodySetAutoDisableFlag (get_id(), do_auto_disable); }
+  bool getAutoDisableFlag() const
+    { return dBodyGetAutoDisableFlag (get_id()) != 0; }
+
+  dReal getLinearDamping() const
+    { return dBodyGetLinearDamping(get_id()); }
+  void setLinearDamping(dReal scale)
+    { dBodySetLinearDamping(get_id(), scale); }
+  dReal getAngularDamping() const
+    { return dBodyGetAngularDamping(get_id()); }
+  void setAngularDamping(dReal scale)
+    { dBodySetAngularDamping(get_id(), scale); }
+  void setDamping(dReal linear_scale, dReal angular_scale)
+    { dBodySetDamping(get_id(), linear_scale, angular_scale); }
+  dReal getLinearDampingThreshold() const
+    { return dBodyGetLinearDampingThreshold(get_id()); }
+  void setLinearDampingThreshold(dReal threshold) const
+    { dBodySetLinearDampingThreshold(get_id(), threshold); }
+  dReal getAngularDampingThreshold() const
+    { return dBodyGetAngularDampingThreshold(get_id()); }
+  void setAngularDampingThreshold(dReal threshold)
+    { dBodySetAngularDampingThreshold(get_id(), threshold); }
+  void setDampingDefaults()
+    { dBodySetDampingDefaults(get_id()); }
+
+  dReal getMaxAngularSpeed() const
+    { return dBodyGetMaxAngularSpeed(get_id()); }
+  void setMaxAngularSpeed(dReal max_speed)
+    { dBodySetMaxAngularSpeed(get_id(), max_speed); }
+
+  bool getGyroscopicMode() const
+    { return dBodyGetGyroscopicMode(get_id()) != 0; }
+  void setGyroscopicMode(bool mode)
+    { dBodySetGyroscopicMode(get_id(), mode); }
+
+};
+
+
+class dJointGroupSimpleIDContainer {
+protected:
+       dJointGroupID _id;
+
+       dJointGroupSimpleIDContainer(): _id(0) {}
+       ~dJointGroupSimpleIDContainer() { destroy(); }
+
+       void destroy() { 
+               if (_id) {
+                       dJointGroupDestroy(_id); 
+                       _id = 0;
+               }
+       }
+};
+
+class dJointGroupDynamicIDContainer: public dJointGroupSimpleIDContainer {
+protected:
+       virtual ~dJointGroupDynamicIDContainer() {}
+};
+
+template <class dJointGroupTemplateBase>
+class dJointGroupTemplate: public dJointGroupTemplateBase {
+  // intentionally undefined, don't use these
+  dJointGroupTemplate (const dJointGroupTemplate<dJointGroupTemplateBase> &);
+  void operator= (const dJointGroupTemplate<dJointGroupTemplateBase> &);
+
+protected:
+  dJointGroupID get_id() const { return dJointGroupTemplateBase::_id; }
+  void set_id(dJointGroupID value) { dJointGroupTemplateBase::_id = value; }
+
+  void destroy() { dJointGroupTemplateBase::destroy(); }
+
+public:
+  dJointGroupTemplate ()
+    { set_id(dJointGroupCreate(0)); }
+  
+  void create () {
+    destroy();
+    set_id(dJointGroupCreate(0));
+  }
+
+  dJointGroupID id() const
+    { return get_id(); }
+  operator dJointGroupID() const
+    { return get_id(); }
+
+  void empty()
+    { dJointGroupEmpty (get_id()); }
+  void clear()
+    { empty(); }
+};
+
+
+class dJointSimpleIDContainer {
+protected:
+       dJointID _id;
+
+       dJointSimpleIDContainer(): _id(0) {}
+       ~dJointSimpleIDContainer() { destroy(); }
+
+       void destroy() { 
+               if (_id) {
+                       dJointDestroy (_id); 
+                       _id = 0;
+               }
+       }
+};
+
+class dJointDynamicIDContainer: public dJointSimpleIDContainer {
+protected:
+       virtual ~dJointDynamicIDContainer() {}
+};
+
+template <class dJointTemplateBase, class dWorldTemplateBase, class dBodyTemplateBase>
+class dJointTemplate: public dJointTemplateBase {
+private:
+  // intentionally undefined, don't use these
+  dJointTemplate (const dJointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase> &) ;
+  void operator= (const dJointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase> &);
+
+protected:
+  dJointID get_id() const { return dJointTemplateBase::_id; }
+  void set_id(dJointID value) { dJointTemplateBase::_id = value; }
+
+  void destroy() { dJointTemplateBase::destroy(); }
+
+protected:
+  dJointTemplate() // don't let user construct pure dJointTemplate objects
+    { }
+
+public:
+  dJointID id() const
+    { return get_id(); }
+  operator dJointID() const
+    { return get_id(); }
+
+  int getNumBodies() const
+    { return dJointGetNumBodies(get_id()); }
+
+  void attach (dBodyID body1, dBodyID body2)
+    { dJointAttach (get_id(), body1, body2); }
+  void attach (dBodyTemplate<dBodyTemplateBase, dWorldTemplateBase>& body1, dBodyTemplate<dBodyTemplateBase, dWorldTemplateBase>& body2)
+    { attach(body1.id(), body2.id()); }
+
+  void enable()
+    { dJointEnable (get_id()); }
+  void disable()
+    { dJointDisable (get_id()); }
+  bool isEnabled() const
+    { return dJointIsEnabled (get_id()) != 0; }
+
+  void setData (void *data)
+    { dJointSetData (get_id(), data); }
+  void *getData() const
+    { return dJointGetData (get_id()); }
+
+  dJointType getType() const
+    { return dJointGetType (get_id()); }
+
+  dBodyID getBody (int index) const
+    { return dJointGetBody (get_id(), index); }
+
+  void setFeedback(dJointFeedback *fb)
+    { dJointSetFeedback(get_id(), fb); }
+  dJointFeedback *getFeedback() const
+    { return dJointGetFeedback(get_id()); }
+
+  // If not implemented it will do nothing as describe in the doc
+  virtual void setParam (int, dReal) {};
+  virtual dReal getParam (int) const { return 0; }
+};
+
+
+template <class dJointTemplateBase, class dWorldTemplateBase, class dBodyTemplateBase>
+class dBallJointTemplate : public dJointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase> {
+private:
+  // intentionally undefined, don't use these
+  dBallJointTemplate (const dBallJointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase> &);
+  void operator= (const dBallJointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase> &);
+
+protected:
+  typedef dJointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase> dBaseTemplate;
+
+  dJointID get_id() const { return dBaseTemplate::get_id(); }
+  void set_id(dJointID value) { dBaseTemplate::set_id(value); }
+
+  void destroy() { dBaseTemplate::destroy(); }
+
+public:
+  dBallJointTemplate() { }
+  dBallJointTemplate (dWorldID world, dJointGroupID group=0)
+    { set_id(dJointCreateBall(world, group)); }
+  dBallJointTemplate (dWorldTemplate<dWorldTemplateBase>& world, dJointGroupID group=0)
+    { set_id(dJointCreateBall(world.id(), group)); }
+
+  void create (dWorldID world, dJointGroupID group=0) {
+    destroy();
+    set_id(dJointCreateBall(world, group));
+  }
+  void create (dWorldTemplate<dWorldTemplateBase>& world, dJointGroupID group=0)
+    { create(world.id(), group); }
+
+  void setAnchor (dReal x, dReal y, dReal z)
+    { dJointSetBallAnchor (get_id(), x, y, z); }
+  void setAnchor (const dVector3 a)
+    { setAnchor (a[0], a[1], a[2]); }
+  void getAnchor (dVector3 result) const
+    { dJointGetBallAnchor (get_id(), result); }
+  void getAnchor2 (dVector3 result) const
+    { dJointGetBallAnchor2 (get_id(), result); }
+  virtual void setParam (int parameter, dReal value)
+    { dJointSetBallParam (get_id(), parameter, value); }
+  virtual dReal getParam (int parameter) const
+    { return dJointGetBallParam (get_id(), parameter); }
+  // TODO: expose params through methods
+} ;
+
+
+template <class dJointTemplateBase, class dWorldTemplateBase, class dBodyTemplateBase>
+class dHingeJointTemplate : public dJointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase> {
+private:
+  // intentionally undefined, don't use these
+  dHingeJointTemplate (const dHingeJointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase> &);
+  void operator = (const dHingeJointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase> &);
+
+protected:
+  typedef dJointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase> dBaseTemplate;
+
+  dJointID get_id() const { return dBaseTemplate::get_id(); }
+  void set_id(dJointID value) { dBaseTemplate::set_id(value); }
+
+  void destroy() { dBaseTemplate::destroy(); }
+
+public:
+  dHingeJointTemplate() { }
+  dHingeJointTemplate (dWorldID world, dJointGroupID group=0)
+    { set_id(dJointCreateHinge(world, group)); }
+  dHingeJointTemplate (dWorldTemplate<dWorldTemplateBase>& world, dJointGroupID group=0)
+    { set_id(dJointCreateHinge(world.id(), group)); }
+
+  void create (dWorldID world, dJointGroupID group=0) {
+    destroy();
+    set_id(dJointCreateHinge (world, group));
+  }
+  void create (dWorldTemplate<dWorldTemplateBase>& world, dJointGroupID group=0)
+    { create(world.id(), group); }
+  
+  void setAnchor (dReal x, dReal y, dReal z)
+    { dJointSetHingeAnchor (get_id(), x, y, z); }
+  void setAnchor (const dVector3 a)
+    { setAnchor (a[0], a[1], a[2]); }
+  void getAnchor (dVector3 result) const
+    { dJointGetHingeAnchor (get_id(), result); }
+  void getAnchor2 (dVector3 result) const
+    { dJointGetHingeAnchor2 (get_id(), result); }
+
+  void setAxis (dReal x, dReal y, dReal z)
+    { dJointSetHingeAxis (get_id(), x, y, z); }
+  void setAxis (const dVector3 a)
+    { setAxis(a[0], a[1], a[2]); }
+  void getAxis (dVector3 result) const
+    { dJointGetHingeAxis (get_id(), result); }
+
+  dReal getAngle() const
+    { return dJointGetHingeAngle (get_id()); }
+  dReal getAngleRate() const
+    { return dJointGetHingeAngleRate (get_id()); }
+
+  virtual void setParam (int parameter, dReal value)
+    { dJointSetHingeParam (get_id(), parameter, value); }
+  virtual dReal getParam (int parameter) const
+    { return dJointGetHingeParam (get_id(), parameter); }
+  // TODO: expose params through methods
+
+  void addTorque (dReal torque)
+       { dJointAddHingeTorque(get_id(), torque); }
+};
+
+
+template <class dJointTemplateBase, class dWorldTemplateBase, class dBodyTemplateBase>
+class dSliderJointTemplate : public dJointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase> {
+private:
+  // intentionally undefined, don't use these
+  dSliderJointTemplate (const dSliderJointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase> &);
+  void operator = (const dSliderJointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase> &);
+
+protected:
+  typedef dJointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase> dBaseTemplate;
+
+  dJointID get_id() const { return dBaseTemplate::get_id(); }
+  void set_id(dJointID value) { dBaseTemplate::set_id(value); }
+
+  void destroy() { dBaseTemplate::destroy(); }
+
+public:
+  dSliderJointTemplate() { }
+  dSliderJointTemplate (dWorldID world, dJointGroupID group=0)
+    { set_id(dJointCreateSlider(world, group)); }
+  dSliderJointTemplate (dWorldTemplate<dWorldTemplateBase>& world, dJointGroupID group=0)
+    { set_id(dJointCreateSlider(world.id(), group)); }
+
+  void create (dWorldID world, dJointGroupID group=0) {
+    destroy();
+    set_id(dJointCreateSlider(world, group));
+  }
+  void create (dWorldTemplate<dWorldTemplateBase>& world, dJointGroupID group=0)
+    { create(world.id(), group); }
+
+  void setAxis (dReal x, dReal y, dReal z)
+    { dJointSetSliderAxis (get_id(), x, y, z); }
+  void setAxis (const dVector3 a)
+    { setAxis (a[0], a[1], a[2]); }
+  void getAxis (dVector3 result) const
+    { dJointGetSliderAxis (get_id(), result); }
+
+  dReal getPosition() const
+    { return dJointGetSliderPosition (get_id()); }
+  dReal getPositionRate() const
+    { return dJointGetSliderPositionRate (get_id()); }
+
+  virtual void setParam (int parameter, dReal value)
+    { dJointSetSliderParam (get_id(), parameter, value); }
+  virtual dReal getParam (int parameter) const
+    { return dJointGetSliderParam (get_id(), parameter); }
+  // TODO: expose params through methods
+
+  void addForce (dReal force)
+       { dJointAddSliderForce(get_id(), force); }
+};
+
+
+template <class dJointTemplateBase, class dWorldTemplateBase, class dBodyTemplateBase>
+class dUniversalJointTemplate : public dJointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase> {
+private:
+  // intentionally undefined, don't use these
+  dUniversalJointTemplate (const dUniversalJointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase> &);
+  void operator = (const dUniversalJointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase> &);
+
+protected:
+  typedef dJointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase> dBaseTemplate;
+
+  dJointID get_id() const { return dBaseTemplate::get_id(); }
+  void set_id(dJointID value) { dBaseTemplate::set_id(value); }
+
+  void destroy() { dBaseTemplate::destroy(); }
+
+public:
+  dUniversalJointTemplate() { }
+  dUniversalJointTemplate (dWorldID world, dJointGroupID group=0)
+    { set_id(dJointCreateUniversal(world, group)); }
+  dUniversalJointTemplate (dWorldTemplate<dWorldTemplateBase>& world, dJointGroupID group=0)
+    { set_id(dJointCreateUniversal(world.id(), group)); }
+
+  void create (dWorldID world, dJointGroupID group=0) {
+    destroy();
+    set_id(dJointCreateUniversal(world, group));
+  }
+  void create (dWorldTemplate<dWorldTemplateBase>& world, dJointGroupID group=0)
+    { create(world.id(), group); }
+
+  void setAnchor (dReal x, dReal y, dReal z)
+    { dJointSetUniversalAnchor (get_id(), x, y, z); }
+  void setAnchor (const dVector3 a)
+    { setAnchor(a[0], a[1], a[2]); }
+  void setAxis1 (dReal x, dReal y, dReal z)
+    { dJointSetUniversalAxis1 (get_id(), x, y, z); }
+  void setAxis1 (const dVector3 a)
+    { setAxis1 (a[0], a[1], a[2]); }
+  void setAxis2 (dReal x, dReal y, dReal z)
+    { dJointSetUniversalAxis2 (get_id(), x, y, z); }
+  void setAxis2 (const dVector3 a)
+    { setAxis2 (a[0], a[1], a[2]); }
+
+  void getAnchor (dVector3 result) const
+    { dJointGetUniversalAnchor (get_id(), result); }
+  void getAnchor2 (dVector3 result) const
+    { dJointGetUniversalAnchor2 (get_id(), result); }
+  void getAxis1 (dVector3 result) const
+    { dJointGetUniversalAxis1 (get_id(), result); }
+  void getAxis2 (dVector3 result) const
+    { dJointGetUniversalAxis2 (get_id(), result); }
+
+  virtual void setParam (int parameter, dReal value)
+    { dJointSetUniversalParam (get_id(), parameter, value); }
+  virtual dReal getParam (int parameter) const
+    { return dJointGetUniversalParam (get_id(), parameter); }
+  // TODO: expose params through methods
+  
+  void getAngles(dReal *angle1, dReal *angle2) const
+    { dJointGetUniversalAngles (get_id(), angle1, angle2); }
+
+  dReal getAngle1() const
+    { return dJointGetUniversalAngle1 (get_id()); }
+  dReal getAngle1Rate() const
+    { return dJointGetUniversalAngle1Rate (get_id()); }
+  dReal getAngle2() const
+    { return dJointGetUniversalAngle2 (get_id()); }
+  dReal getAngle2Rate() const
+    { return dJointGetUniversalAngle2Rate (get_id()); }
+
+  void addTorques (dReal torque1, dReal torque2)
+       { dJointAddUniversalTorques(get_id(), torque1, torque2); }
+};
+
+
+template <class dJointTemplateBase, class dWorldTemplateBase, class dBodyTemplateBase>
+class dHinge2JointTemplate : public dJointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase> {
+private:
+  // intentionally undefined, don't use these
+  dHinge2JointTemplate (const dHinge2JointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase> &);
+  void operator = (const dHinge2JointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase> &);
+
+protected:
+  typedef dJointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase> dBaseTemplate;
+
+  dJointID get_id() const { return dBaseTemplate::get_id(); }
+  void set_id(dJointID value) { dBaseTemplate::set_id(value); }
+
+  void destroy() { dBaseTemplate::destroy(); }
+
+public:
+  dHinge2JointTemplate() { }
+  dHinge2JointTemplate (dWorldID world, dJointGroupID group=0)
+    { set_id(dJointCreateHinge2(world, group)); }
+  dHinge2JointTemplate (dWorldTemplate<dWorldTemplateBase>& world, dJointGroupID group=0)
+    { set_id(dJointCreateHinge2(world.id(), group)); }
+
+  void create (dWorldID world, dJointGroupID group=0) {
+    destroy();
+    set_id(dJointCreateHinge2(world, group));
+  }
+  void create (dWorldTemplate<dWorldTemplateBase>& world, dJointGroupID group=0)
+    { create(world.id(), group); }
+
+  void setAnchor (dReal x, dReal y, dReal z)
+    { dJointSetHinge2Anchor (get_id(), x, y, z); }
+  void setAnchor (const dVector3 a)
+    { setAnchor(a[0], a[1], a[2]); }
+  void setAxis1 (dReal x, dReal y, dReal z)
+    { dJointSetHinge2Axis1 (get_id(), x, y, z); }
+  void setAxis1 (const dVector3 a)
+    { setAxis1 (a[0], a[1], a[2]); }
+  void setAxis2 (dReal x, dReal y, dReal z)
+    { dJointSetHinge2Axis2 (get_id(), x, y, z); }
+  void setAxis2 (const dVector3 a)
+    { setAxis2 (a[0], a[1], a[2]); }
+    
+  void getAnchor (dVector3 result) const
+    { dJointGetHinge2Anchor (get_id(), result); }
+  void getAnchor2 (dVector3 result) const
+    { dJointGetHinge2Anchor2 (get_id(), result); }
+  void getAxis1 (dVector3 result) const
+    { dJointGetHinge2Axis1 (get_id(), result); }
+  void getAxis2 (dVector3 result) const
+    { dJointGetHinge2Axis2 (get_id(), result); }
+
+  dReal getAngle1() const
+    { return dJointGetHinge2Angle1 (get_id()); }
+  dReal getAngle1Rate() const
+    { return dJointGetHinge2Angle1Rate (get_id()); }
+  dReal getAngle2Rate() const
+    { return dJointGetHinge2Angle2Rate (get_id()); }
+
+  virtual void setParam (int parameter, dReal value)
+    { dJointSetHinge2Param (get_id(), parameter, value); }
+  virtual dReal getParam (int parameter) const
+    { return dJointGetHinge2Param (get_id(), parameter); }
+  // TODO: expose params through methods
+
+  void addTorques(dReal torque1, dReal torque2)
+       { dJointAddHinge2Torques(get_id(), torque1, torque2); }
+};
+
+
+template <class dJointTemplateBase, class dWorldTemplateBase, class dBodyTemplateBase>
+class dPRJointTemplate : public dJointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase> {
+private:
+  // intentionally undefined, don't use these
+  dPRJointTemplate (const dPRJointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase> &);
+  void operator = (const dPRJointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase> &);
+
+protected:
+  typedef dJointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase> dBaseTemplate;
+
+  dJointID get_id() const { return dBaseTemplate::get_id(); }
+  void set_id(dJointID value) { dBaseTemplate::set_id(value); }
+
+  void destroy() { dBaseTemplate::destroy(); }
+
+public:
+  dPRJointTemplate() { }
+  dPRJointTemplate (dWorldID world, dJointGroupID group=0)
+    { set_id(dJointCreatePR(world, group)); }
+  dPRJointTemplate (dWorldTemplate<dWorldTemplateBase>& world, dJointGroupID group=0)
+    { set_id(dJointCreatePR(world.id(), group)); }
+
+  void create (dWorldID world, dJointGroupID group=0) {
+    destroy();
+    set_id(dJointCreatePR(world, group));
+  }
+  void create (dWorldTemplate<dWorldTemplateBase>& world, dJointGroupID group=0)
+    { create(world.id(), group); }
+
+  void setAnchor (dReal x, dReal y, dReal z)
+    { dJointSetPRAnchor (get_id(), x, y, z); }
+  void setAnchor (const dVector3 a)
+    { setAnchor (a[0], a[1], a[2]); }
+  void setAxis1 (dReal x, dReal y, dReal z)
+    { dJointSetPRAxis1 (get_id(), x, y, z); }
+  void setAxis1 (const dVector3 a)
+    { setAxis1(a[0], a[1], a[2]); }
+  void setAxis2 (dReal x, dReal y, dReal z)
+    { dJointSetPRAxis2 (get_id(), x, y, z); }
+  void setAxis2 (const dVector3 a)
+    { setAxis2(a[0], a[1], a[2]); }
+
+  void getAnchor (dVector3 result) const
+    { dJointGetPRAnchor (get_id(), result); }
+  void getAxis1 (dVector3 result) const
+    { dJointGetPRAxis1 (get_id(), result); }
+  void getAxis2 (dVector3 result) const
+    { dJointGetPRAxis2 (get_id(), result); }
+
+  dReal getPosition() const
+    { return dJointGetPRPosition (get_id()); }
+  dReal getPositionRate() const
+    { return dJointGetPRPositionRate (get_id()); }
+
+  dReal getAngle() const
+    { return dJointGetPRAngle (get_id()); }
+  dReal getAngleRate() const
+    { return dJointGetPRAngleRate (get_id()); }
+
+  virtual void setParam (int parameter, dReal value)
+    { dJointSetPRParam (get_id(), parameter, value); }
+  virtual dReal getParam (int parameter) const
+    { return dJointGetPRParam (get_id(), parameter); }
+};
+
+
+
+template <class dJointTemplateBase, class dWorldTemplateBase, class dBodyTemplateBase>
+class dPUJointTemplate : public dJointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase>
+{
+private:
+  // intentionally undefined, don't use these
+  dPUJointTemplate (const dPUJointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase> &);
+  void operator = (const dPUJointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase> &);
+
+protected:
+  typedef dJointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase> dBaseTemplate;
+
+  dJointID get_id() const { return dBaseTemplate::get_id(); }
+  void set_id(dJointID value) { dBaseTemplate::set_id(value); }
+
+  void destroy() { dBaseTemplate::destroy(); }
+
+public:
+  dPUJointTemplate() { }
+  dPUJointTemplate (dWorldID world, dJointGroupID group=0)
+    { set_id(dJointCreatePU(world, group)); }
+  dPUJointTemplate (dWorldTemplate<dWorldTemplateBase>& world, dJointGroupID group=0)
+    { set_id(dJointCreatePU(world.id(), group)); }
+
+  void create (dWorldID world, dJointGroupID group=0)
+  {
+    destroy();
+    set_id(dJointCreatePU(world, group));
+  }
+  void create (dWorldTemplate<dWorldTemplateBase>& world, dJointGroupID group=0)
+  { create(world.id(), group); }
+
+  void setAnchor (dReal x, dReal y, dReal z)
+    { dJointSetPUAnchor (get_id(), x, y, z); }
+  void setAnchor (const dVector3 a)
+    { setAnchor (a[0], a[1], a[2]); }
+  void setAxis1 (dReal x, dReal y, dReal z)
+    { dJointSetPUAxis1 (get_id(), x, y, z); }
+  void setAxis1 (const dVector3 a)
+    { setAxis1(a[0], a[1], a[2]); }
+  void setAxis2 (dReal x, dReal y, dReal z)
+  { dJointSetPUAxis2 (get_id(), x, y, z); }
+  void setAxis3 (dReal x, dReal y, dReal z)
+  { dJointSetPUAxis3 (get_id(), x, y, z); }
+  void setAxis3 (const dVector3 a)
+    { setAxis3(a[0], a[1], a[2]); }
+  void setAxisP (dReal x, dReal y, dReal z)
+  { dJointSetPUAxis3 (get_id(), x, y, z); }
+  void setAxisP (const dVector3 a)
+    { setAxisP(a[0], a[1], a[2]); }
+
+  virtual void getAnchor (dVector3 result) const
+    { dJointGetPUAnchor (get_id(), result); }
+  void getAxis1 (dVector3 result) const
+    { dJointGetPUAxis1 (get_id(), result); }
+  void getAxis2 (dVector3 result) const
+    { dJointGetPUAxis2 (get_id(), result); }
+  void getAxis3 (dVector3 result) const
+    { dJointGetPUAxis3 (get_id(), result); }
+  void getAxisP (dVector3 result) const
+    { dJointGetPUAxis3 (get_id(), result); }
+
+  dReal getAngle1() const
+    { return dJointGetPUAngle1 (get_id()); }
+  dReal getAngle1Rate() const
+    { return dJointGetPUAngle1Rate (get_id()); }
+  dReal getAngle2() const
+    { return dJointGetPUAngle2 (get_id()); }
+  dReal getAngle2Rate() const
+    { return dJointGetPUAngle2Rate (get_id()); }
+
+  dReal getPosition() const
+    { return dJointGetPUPosition (get_id()); }
+  dReal getPositionRate() const
+    { return dJointGetPUPositionRate (get_id()); }
+
+  virtual void setParam (int parameter, dReal value)
+  { dJointSetPUParam (get_id(), parameter, value); }
+  virtual dReal getParam (int parameter) const
+    { return dJointGetPUParam (get_id(), parameter); }
+  // TODO: expose params through methods
+};
+
+
+
+
+
+template <class dJointTemplateBase, class dWorldTemplateBase, class dBodyTemplateBase>
+class dPistonJointTemplate : public dJointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase>
+{
+private:
+  // intentionally undefined, don't use these
+  dPistonJointTemplate (const dPistonJointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase> &);
+  void operator = (const dPistonJointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase> &);
+
+protected:
+  typedef dJointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase> dBaseTemplate;
+
+  dJointID get_id() const { return dBaseTemplate::get_id(); }
+  void set_id(dJointID value) { dBaseTemplate::set_id(value); }
+
+  void destroy() { dBaseTemplate::destroy(); }
+
+public:
+  dPistonJointTemplate() { }
+  dPistonJointTemplate (dWorldID world, dJointGroupID group=0)
+    { set_id(dJointCreatePiston(world, group)); }
+  dPistonJointTemplate (dWorldTemplate<dWorldTemplateBase>& world, dJointGroupID group=0)
+    { set_id(dJointCreatePiston(world, group)); }
+
+  void create (dWorldID world, dJointGroupID group=0)
+  {
+    destroy();
+    set_id(dJointCreatePiston(world, group));
+  }
+  void create (dWorldTemplate<dWorldTemplateBase>& world, dJointGroupID group=0)
+    { create(world.id(), group); }
+
+  void setAnchor (dReal x, dReal y, dReal z)
+    { dJointSetPistonAnchor (get_id(), x, y, z); }
+  void setAnchor (const dVector3 a)
+    { setAnchor (a[0], a[1], a[2]); }
+  void getAnchor (dVector3 result) const
+    { dJointGetPistonAnchor (get_id(), result); }
+  void getAnchor2 (dVector3 result) const
+    { dJointGetPistonAnchor2 (get_id(), result); }
+
+  void setAxis (dReal x, dReal y, dReal z)
+    { dJointSetPistonAxis (get_id(), x, y, z); }
+  void setAxis (const dVector3 a)
+    { setAxis(a[0], a[1], a[2]); }
+  void getAxis (dVector3 result) const
+    { dJointGetPistonAxis (get_id(), result); }
+
+  dReal getPosition() const
+    { return dJointGetPistonPosition (get_id()); }
+  dReal getPositionRate() const
+    { return dJointGetPistonPositionRate (get_id()); }
+
+  virtual void setParam (int parameter, dReal value)
+  { dJointSetPistonParam (get_id(), parameter, value); }
+  virtual dReal getParam (int parameter) const
+    { return dJointGetPistonParam (get_id(), parameter); }
+  // TODO: expose params through methods
+
+  void addForce (dReal force)
+  { dJointAddPistonForce (get_id(), force); }
+};
+
+
+
+template <class dJointTemplateBase, class dWorldTemplateBase, class dBodyTemplateBase>
+class dFixedJointTemplate : public dJointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase>
+{
+private:
+  // intentionally undefined, don't use these
+  dFixedJointTemplate (const dFixedJointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase> &);
+  void operator = (const dFixedJointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase> &);
+
+protected:
+  typedef dJointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase> dBaseTemplate;
+
+  dJointID get_id() const { return dBaseTemplate::get_id(); }
+  void set_id(dJointID value) { dBaseTemplate::set_id(value); }
+
+  void destroy() { dBaseTemplate::destroy(); }
+
+public:
+  dFixedJointTemplate() { }
+  dFixedJointTemplate (dWorldID world, dJointGroupID group=0)
+    { set_id(dJointCreateFixed(world, group)); }
+  dFixedJointTemplate (dWorldTemplate<dWorldTemplateBase>& world, dJointGroupID group=0)
+    { set_id(dJointCreateFixed(world, group)); }
+
+  void create (dWorldID world, dJointGroupID group=0) {
+    destroy();
+    set_id(dJointCreateFixed(world, group));
+  }
+  void create (dWorldTemplate<dWorldTemplateBase>& world, dJointGroupID group=0)
+    { create(world.id(), group); }
+
+  void set()
+    { dJointSetFixed (get_id()); }
+
+  virtual void setParam (int parameter, dReal value)
+    { dJointSetFixedParam (get_id(), parameter, value); }
+
+  virtual dReal getParam (int parameter) const
+    { return dJointGetFixedParam (get_id(), parameter); }
+  // TODO: expose params through methods
+};
+
+
+template <class dJointTemplateBase, class dWorldTemplateBase, class dBodyTemplateBase>
+class dContactJointTemplate : public dJointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase> {
+private:
+  // intentionally undefined, don't use these
+  dContactJointTemplate (const dContactJointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase> &);
+  void operator = (const dContactJointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase> &);
+
+protected:
+  typedef dJointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase> dBaseTemplate;
+
+  dJointID get_id() const { return dBaseTemplate::get_id(); }
+  void set_id(dJointID value) { dBaseTemplate::set_id(value); }
+
+  void destroy() { dBaseTemplate::destroy(); }
+
+public:
+  dContactJointTemplate() { }
+  dContactJointTemplate (dWorldID world, dJointGroupID group, dContact *contact)
+    { set_id(dJointCreateContact(world, group, contact)); }
+  dContactJointTemplate (dWorldTemplate<dWorldTemplateBase>& world, dJointGroupID group, dContact *contact)
+    { set_id(dJointCreateContact(world.id(), group, contact)); }
+
+  void create (dWorldID world, dJointGroupID group, dContact *contact) {
+    destroy();
+    set_id(dJointCreateContact(world, group, contact));
+  }
+  
+  void create (dWorldTemplate<dWorldTemplateBase>& world, dJointGroupID group, dContact *contact)
+    { create(world.id(), group, contact); }
+};
+
+
+template <class dJointTemplateBase, class dWorldTemplateBase, class dBodyTemplateBase>
+class dNullJointTemplate : public dJointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase> {
+private:
+  // intentionally undefined, don't use these
+  dNullJointTemplate (const dNullJointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase> &);
+  void operator = (const dNullJointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase> &);
+
+protected:
+  typedef dJointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase> dBaseTemplate;
+
+  dJointID get_id() const { return dBaseTemplate::get_id(); }
+  void set_id(dJointID value) { dBaseTemplate::set_id(value); }
+
+  void destroy() { dBaseTemplate::destroy(); }
+
+public:
+  dNullJointTemplate() { }
+  dNullJointTemplate (dWorldID world, dJointGroupID group=0)
+    { set_id(dJointCreateNull(world, group)); }
+  dNullJointTemplate (dWorldTemplate<dWorldTemplateBase>& world, dJointGroupID group=0)
+    { set_id(dJointCreateNull (world.id(), group)); }
+
+  void create (dWorldID world, dJointGroupID group=0) {
+    destroy();
+    set_id(dJointCreateNull(world, group));
+  }
+  void create (dWorldTemplate<dWorldTemplateBase>& world, dJointGroupID group=0)
+    { create(world.id(), group); }
+};
+
+
+template <class dJointTemplateBase, class dWorldTemplateBase, class dBodyTemplateBase>
+class dAMotorJointTemplate : public dJointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase> {
+private:
+  // intentionally undefined, don't use these
+  dAMotorJointTemplate (const dAMotorJointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase> &);
+  void operator = (const dAMotorJointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase> &);
+
+protected:
+  typedef dJointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase> dBaseTemplate;
+
+  dJointID get_id() const { return dBaseTemplate::get_id(); }
+  void set_id(dJointID value) { dBaseTemplate::set_id(value); }
+
+  void destroy() { dBaseTemplate::destroy(); }
+
+public:
+  dAMotorJointTemplate() { }
+  dAMotorJointTemplate (dWorldID world, dJointGroupID group=0)
+    { set_id(dJointCreateAMotor(world, group)); }
+  dAMotorJointTemplate (dWorldTemplate<dWorldTemplateBase>& world, dJointGroupID group=0)
+    { set_id(dJointCreateAMotor(world.id(), group)); }
+
+  void create (dWorldID world, dJointGroupID group=0) {
+    destroy();
+    set_id(dJointCreateAMotor(world, group));
+  }
+  void create (dWorldTemplate<dWorldTemplateBase>& world, dJointGroupID group=0)
+    { create(world.id(), group); }
+
+  void setMode (int mode)
+    { dJointSetAMotorMode (get_id(), mode); }
+  int getMode() const
+    { return dJointGetAMotorMode (get_id()); }
+
+  void setNumAxes (int num)
+    { dJointSetAMotorNumAxes (get_id(), num); }
+  int getNumAxes() const
+    { return dJointGetAMotorNumAxes (get_id()); }
+
+  void setAxis (int anum, int rel, dReal x, dReal y, dReal z)
+    { dJointSetAMotorAxis (get_id(), anum, rel, x, y, z); }
+  void setAxis (int anum, int rel, const dVector3 a)
+    { setAxis(anum, rel, a[0], a[1], a[2]); }
+  void getAxis (int anum, dVector3 result) const
+    { dJointGetAMotorAxis (get_id(), anum, result); }
+  int getAxisRel (int anum) const
+    { return dJointGetAMotorAxisRel (get_id(), anum); }
+
+  void setAngle (int anum, dReal angle)
+    { dJointSetAMotorAngle (get_id(), anum, angle); }
+  dReal getAngle (int anum) const
+    { return dJointGetAMotorAngle (get_id(), anum); }
+  dReal getAngleRate (int anum)
+    { return dJointGetAMotorAngleRate (get_id(), anum); }
+
+  void setParam (int parameter, dReal value)
+    { dJointSetAMotorParam (get_id(), parameter, value); }
+  dReal getParam (int parameter) const
+    { return dJointGetAMotorParam (get_id(), parameter); }
+  // TODO: expose params through methods
+
+  void addTorques(dReal torque1, dReal torque2, dReal torque3)
+       { dJointAddAMotorTorques(get_id(), torque1, torque2, torque3); }
+};
+
+
+template <class dJointTemplateBase, class dWorldTemplateBase, class dBodyTemplateBase>
+class dLMotorJointTemplate : public dJointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase> {
+private:
+  // intentionally undefined, don't use these
+  dLMotorJointTemplate (const dLMotorJointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase> &);
+  void operator = (const dLMotorJointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase> &);
+
+protected:
+  typedef dJointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase> dBaseTemplate;
+
+  dJointID get_id() const { return dBaseTemplate::get_id(); }
+  void set_id(dJointID value) { dBaseTemplate::set_id(value); }
+
+  void destroy() { dBaseTemplate::destroy(); }
+
+public:
+  dLMotorJointTemplate() { }
+  dLMotorJointTemplate (dWorldID world, dJointGroupID group=0)
+    { set_id(dJointCreateLMotor(world, group)); }
+  dLMotorJointTemplate (dWorldTemplate<dWorldTemplateBase>& world, dJointGroupID group=0)
+    { set_id(dJointCreateLMotor(world.id(), group)); }
+
+  void create (dWorldID world, dJointGroupID group=0) {
+    destroy();
+    set_id(dJointCreateLMotor(world, group));
+  }
+  void create (dWorldTemplate<dWorldTemplateBase>& world, dJointGroupID group=0)
+    { create(world.id(), group); }
+
+  void setNumAxes (int num)
+    { dJointSetLMotorNumAxes (get_id(), num); }
+  int getNumAxes() const
+    { return dJointGetLMotorNumAxes (get_id()); }
+
+  void setAxis (int anum, int rel, dReal x, dReal y, dReal z)
+    { dJointSetLMotorAxis (get_id(), anum, rel, x, y, z); }
+  void setAxis (int anum, int rel, const dVector3 a)
+    { setAxis(anum, rel, a[0], a[1], a[2]); }
+  void getAxis (int anum, dVector3 result) const
+    { dJointGetLMotorAxis (get_id(), anum, result); }
+
+  void setParam (int parameter, dReal value)
+    { dJointSetLMotorParam (get_id(), parameter, value); }
+  dReal getParam (int parameter) const
+    { return dJointGetLMotorParam (get_id(), parameter); }
+  // TODO: expose params through methods
+};
+
+//}
+
+#if !defined(dODECPP_WORLD_TEMPLATE_BASE)
+
+#if defined(dODECPP_BODY_TEMPLATE_BASE) || defined(dODECPP_JOINTGROUP_TEMPLATE_BASE) || defined(dODECPP_JOINT_TEMPLATE_BASE)
+#error All the odecpp template bases must be defined or not defined together
+#endif
+
+#define dODECPP_WORLD_TEMPLATE_BASE dWorldDynamicIDContainer
+#define dODECPP_BODY_TEMPLATE_BASE dBodyDynamicIDContainer
+#define dODECPP_JOINTGROUP_TEMPLATE_BASE dJointGroupDynamicIDContainer
+#define dODECPP_JOINT_TEMPLATE_BASE dJointDynamicIDContainer
+
+#else // #if defined(dODECPP_WORLD_TEMPLATE_BASE)
+
+#if !defined(dODECPP_BODY_TEMPLATE_BASE) || !defined(dODECPP_JOINTGROUP_TEMPLATE_BASE) || !defined(dODECPP_JOINT_TEMPLATE_BASE)
+#error All the odecpp template bases must be defined or not defined together
+#endif
+
+#endif // #if defined(dODECPP_WORLD_TEMPLATE_BASE)
+
+
+typedef dWorldTemplate<dODECPP_WORLD_TEMPLATE_BASE> dWorld;
+typedef dBodyTemplate<dODECPP_BODY_TEMPLATE_BASE, dODECPP_WORLD_TEMPLATE_BASE> dBody;
+typedef dJointGroupTemplate<dODECPP_JOINTGROUP_TEMPLATE_BASE> dJointGroup;
+typedef dJointTemplate<dODECPP_JOINT_TEMPLATE_BASE, dODECPP_WORLD_TEMPLATE_BASE, dODECPP_BODY_TEMPLATE_BASE> dJoint;
+typedef dBallJointTemplate<dODECPP_JOINT_TEMPLATE_BASE, dODECPP_WORLD_TEMPLATE_BASE, dODECPP_BODY_TEMPLATE_BASE> dBallJoint;
+typedef dHingeJointTemplate<dODECPP_JOINT_TEMPLATE_BASE, dODECPP_WORLD_TEMPLATE_BASE, dODECPP_BODY_TEMPLATE_BASE> dHingeJoint;
+typedef dSliderJointTemplate<dODECPP_JOINT_TEMPLATE_BASE, dODECPP_WORLD_TEMPLATE_BASE, dODECPP_BODY_TEMPLATE_BASE> dSliderJoint;
+typedef dUniversalJointTemplate<dODECPP_JOINT_TEMPLATE_BASE, dODECPP_WORLD_TEMPLATE_BASE, dODECPP_BODY_TEMPLATE_BASE> dUniversalJoint;
+typedef dHinge2JointTemplate<dODECPP_JOINT_TEMPLATE_BASE, dODECPP_WORLD_TEMPLATE_BASE, dODECPP_BODY_TEMPLATE_BASE> dHinge2Joint;
+typedef dPRJointTemplate<dODECPP_JOINT_TEMPLATE_BASE, dODECPP_WORLD_TEMPLATE_BASE, dODECPP_BODY_TEMPLATE_BASE> dPRJoint;
+typedef dPUJointTemplate<dODECPP_JOINT_TEMPLATE_BASE, dODECPP_WORLD_TEMPLATE_BASE, dODECPP_BODY_TEMPLATE_BASE> dPUJoint;
+typedef dPistonJointTemplate<dODECPP_JOINT_TEMPLATE_BASE, dODECPP_WORLD_TEMPLATE_BASE, dODECPP_BODY_TEMPLATE_BASE> dPistonJoint;
+typedef dFixedJointTemplate<dODECPP_JOINT_TEMPLATE_BASE, dODECPP_WORLD_TEMPLATE_BASE, dODECPP_BODY_TEMPLATE_BASE> dFixedJoint;
+typedef dContactJointTemplate<dODECPP_JOINT_TEMPLATE_BASE, dODECPP_WORLD_TEMPLATE_BASE, dODECPP_BODY_TEMPLATE_BASE> dContactJoint;
+typedef dNullJointTemplate<dODECPP_JOINT_TEMPLATE_BASE, dODECPP_WORLD_TEMPLATE_BASE, dODECPP_BODY_TEMPLATE_BASE> dNullJoint;
+typedef dAMotorJointTemplate<dODECPP_JOINT_TEMPLATE_BASE, dODECPP_WORLD_TEMPLATE_BASE, dODECPP_BODY_TEMPLATE_BASE> dAMotorJoint;
+typedef dLMotorJointTemplate<dODECPP_JOINT_TEMPLATE_BASE, dODECPP_WORLD_TEMPLATE_BASE, dODECPP_BODY_TEMPLATE_BASE> dLMotorJoint;
+
+
+#endif
+#endif
+
+// Local variables:
+// mode:c++
+// c-basic-offset:2
+// End:
diff --git a/misc/builddeps/dp.linux32/include/ode/odecpp_collision.h b/misc/builddeps/dp.linux32/include/ode/odecpp_collision.h
new file mode 100644 (file)
index 0000000..2377a5e
--- /dev/null
@@ -0,0 +1,429 @@
+/*************************************************************************
+ *                                                                      *
+ * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith.      *
+ * All rights reserved.  Email: russ@q12.org   Web: www.q12.org         *
+ *                                                                      *
+ * This library is free software; you can redistribute it and/or        *
+ * modify it under the terms of EITHER:                                 *
+ *   (1) The GNU Lesser General Public License as published by the Free  *
+ *      Software Foundation; either version 2.1 of the License, or (at  *
+ *      your option) any later version. The text of the GNU Lesser      *
+ *      General Public License is included with this library in the     *
+ *      file LICENSE.TXT.                                               *
+ *   (2) The BSD-style license that is included with this library in    *
+ *      the file LICENSE-BSD.TXT.                                       *
+ *                                                                      *
+ * This library is distributed in the hope that it will be useful,      *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of       *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files   *
+ * LICENSE.TXT and LICENSE-BSD.TXT for more details.                    *
+ *                                                                      *
+ *************************************************************************/
+
+/* C++ interface for new collision API */
+
+
+#ifndef _ODE_ODECPP_COLLISION_H_
+#define _ODE_ODECPP_COLLISION_H_
+#ifdef __cplusplus
+
+//#include <ode/error.h>
+
+//namespace ode {
+
+class dGeom {
+  // intentionally undefined, don't use these
+  dGeom (dGeom &);
+  void operator= (dGeom &);
+
+protected:
+  dGeomID _id;
+
+  dGeom()
+    { _id = 0; }
+public:
+  ~dGeom()
+    { if (_id) dGeomDestroy (_id); }
+
+  dGeomID id() const
+    { return _id; }
+  operator dGeomID() const
+    { return _id; }
+
+  void destroy() {
+    if (_id) dGeomDestroy (_id);
+    _id = 0;
+  }
+
+  int getClass() const
+    { return dGeomGetClass (_id); }
+
+  dSpaceID getSpace() const
+    { return dGeomGetSpace (_id); }
+
+  void setData (void *data)
+    { dGeomSetData (_id,data); }
+  void *getData() const
+    { return dGeomGetData (_id); }
+
+  void setBody (dBodyID b)
+    { dGeomSetBody (_id,b); }
+  dBodyID getBody() const
+    { return dGeomGetBody (_id); }
+
+  void setPosition (dReal x, dReal y, dReal z)
+    { dGeomSetPosition (_id,x,y,z); }
+  const dReal * getPosition() const
+    { return dGeomGetPosition (_id); }
+
+  void setRotation (const dMatrix3 R)
+    { dGeomSetRotation (_id,R); }
+  const dReal * getRotation() const
+    { return dGeomGetRotation (_id); }
+    
+  void setQuaternion (const dQuaternion quat)
+    { dGeomSetQuaternion (_id,quat); }
+  void getQuaternion (dQuaternion quat) const
+    { dGeomGetQuaternion (_id,quat); }
+
+  void getAABB (dReal aabb[6]) const
+    { dGeomGetAABB (_id, aabb); }
+
+  int isSpace()
+    { return dGeomIsSpace (_id); }
+
+  void setCategoryBits (unsigned long bits)
+    { dGeomSetCategoryBits (_id, bits); }
+  void setCollideBits (unsigned long bits)
+    { dGeomSetCollideBits (_id, bits); }
+  unsigned long getCategoryBits()
+    { return dGeomGetCategoryBits (_id); }
+  unsigned long getCollideBits()
+    { return dGeomGetCollideBits (_id); }
+
+  void enable()
+    { dGeomEnable (_id); }
+  void disable()
+    { dGeomDisable (_id); }
+  int isEnabled()
+    { return dGeomIsEnabled (_id); }
+  
+  void getRelPointPos (dReal px, dReal py, dReal pz, dVector3 result) const
+    { dGeomGetRelPointPos (_id, px, py, pz, result); }
+  void getRelPointPos (const dVector3 p, dVector3 result) const
+    { getRelPointPos (p[0], p[1], p[2], result); }
+
+  void getPosRelPoint (dReal px, dReal py, dReal pz, dVector3 result) const
+    { dGeomGetPosRelPoint (_id, px, py, pz, result); }
+  void getPosRelPoint (const dVector3 p, dVector3 result) const
+    { getPosRelPoint (p[0], p[1], p[2], result); }
+
+  void vectorToWorld (dReal px, dReal py, dReal pz, dVector3 result) const
+    { dGeomVectorToWorld (_id, px, py, pz, result); }
+  void vectorToWorld (const dVector3 p, dVector3 result) const
+    { vectorToWorld (p[0], p[1], p[2], result); }
+
+  void vectorFromWorld (dReal px, dReal py, dReal pz, dVector3 result) const
+    { dGeomVectorFromWorld (_id, px, py, pz, result); }
+  void vectorFromWorld (const dVector3 p, dVector3 result) const
+    { vectorFromWorld (p[0], p[1], p[2], result); }
+  
+  void collide2 (dGeomID g, void *data, dNearCallback *callback)
+    { dSpaceCollide2 (_id,g,data,callback); }
+};
+
+
+class dSpace : public dGeom {
+  // intentionally undefined, don't use these
+  dSpace (dSpace &);
+  void operator= (dSpace &);
+
+protected:
+  // the default constructor is protected so that you
+  // can't instance this class. you must instance one
+  // of its subclasses instead.
+  dSpace () { _id = 0; }
+
+public:
+  dSpaceID id() const
+    { return (dSpaceID) _id; }
+  operator dSpaceID() const
+    { return (dSpaceID) _id; }
+
+  void setCleanup (int mode)
+    { dSpaceSetCleanup (id(), mode); }
+  int getCleanup()
+    { return dSpaceGetCleanup (id()); }
+
+  void add (dGeomID x)
+    { dSpaceAdd (id(), x); }
+  void remove (dGeomID x)
+    { dSpaceRemove (id(), x); }
+  int query (dGeomID x)
+    { return dSpaceQuery (id(),x); }
+
+  int getNumGeoms()
+    { return dSpaceGetNumGeoms (id()); }
+  dGeomID getGeom (int i)
+    { return dSpaceGetGeom (id(),i); }
+
+  void collide (void *data, dNearCallback *callback)
+    { dSpaceCollide (id(),data,callback); }
+};
+
+
+class dSimpleSpace : public dSpace {
+  // intentionally undefined, don't use these
+  dSimpleSpace (dSimpleSpace &);
+  void operator= (dSimpleSpace &);
+
+public:
+  dSimpleSpace ()
+    { _id = (dGeomID) dSimpleSpaceCreate (0); }
+  dSimpleSpace (dSpace &space)
+    { _id = (dGeomID) dSimpleSpaceCreate (space.id()); }
+  dSimpleSpace (dSpaceID space)
+    { _id = (dGeomID) dSimpleSpaceCreate (space); }
+};
+
+
+class dHashSpace : public dSpace {
+  // intentionally undefined, don't use these
+  dHashSpace (dHashSpace &);
+  void operator= (dHashSpace &);
+
+public:
+  dHashSpace ()
+    { _id = (dGeomID) dHashSpaceCreate (0); }
+  dHashSpace (dSpace &space)
+    { _id = (dGeomID) dHashSpaceCreate (space.id()); }
+  dHashSpace (dSpaceID space)
+    { _id = (dGeomID) dHashSpaceCreate (space); }
+
+  void setLevels (int minlevel, int maxlevel)
+    { dHashSpaceSetLevels (id(),minlevel,maxlevel); }
+};
+
+
+class dQuadTreeSpace : public dSpace {
+  // intentionally undefined, don't use these
+  dQuadTreeSpace (dQuadTreeSpace &);
+  void operator= (dQuadTreeSpace &);
+
+public:
+  dQuadTreeSpace (const dVector3 center, const dVector3 extents, int depth)
+    { _id = (dGeomID) dQuadTreeSpaceCreate (0,center,extents,depth); }
+  dQuadTreeSpace (dSpace &space, const dVector3 center, const dVector3 extents, int depth)
+    { _id = (dGeomID) dQuadTreeSpaceCreate (space.id(),center,extents,depth); }
+  dQuadTreeSpace (dSpaceID space, const dVector3 center, const dVector3 extents, int depth)
+    { _id = (dGeomID) dQuadTreeSpaceCreate (space,center,extents,depth); }
+};
+
+
+class dSphere : public dGeom {
+  // intentionally undefined, don't use these
+  dSphere (dSphere &);
+  void operator= (dSphere &);
+
+public:
+  dSphere () { }
+  dSphere (dReal radius)
+    { _id = dCreateSphere (0, radius); }
+  dSphere (dSpace &space, dReal radius)
+    { _id = dCreateSphere (space.id(), radius); }
+  dSphere (dSpaceID space, dReal radius)
+    { _id = dCreateSphere (space, radius); }
+
+  void create (dSpaceID space, dReal radius) {
+    if (_id) dGeomDestroy (_id);
+    _id = dCreateSphere (space, radius);
+  }
+
+  void setRadius (dReal radius)
+    { dGeomSphereSetRadius (_id, radius); }
+  dReal getRadius() const
+    { return dGeomSphereGetRadius (_id); }
+};
+
+
+class dBox : public dGeom {
+  // intentionally undefined, don't use these
+  dBox (dBox &);
+  void operator= (dBox &);
+
+public:
+  dBox () { }
+  dBox (dReal lx, dReal ly, dReal lz)
+    { _id = dCreateBox (0,lx,ly,lz); }
+  dBox (dSpace &space, dReal lx, dReal ly, dReal lz)
+    { _id = dCreateBox (space,lx,ly,lz); }
+  dBox (dSpaceID space, dReal lx, dReal ly, dReal lz)
+    { _id = dCreateBox (space,lx,ly,lz); }
+
+  void create (dSpaceID space, dReal lx, dReal ly, dReal lz) {
+    if (_id) dGeomDestroy (_id);
+    _id = dCreateBox (space,lx,ly,lz);
+  }
+
+  void setLengths (dReal lx, dReal ly, dReal lz)
+    { dGeomBoxSetLengths (_id, lx, ly, lz); }
+  void getLengths (dVector3 result) const
+    { dGeomBoxGetLengths (_id,result); }
+};
+
+
+class dPlane : public dGeom {
+  // intentionally undefined, don't use these
+  dPlane (dPlane &);
+  void operator= (dPlane &);
+
+public:
+  dPlane() { }
+  dPlane (dReal a, dReal b, dReal c, dReal d)
+    { _id = dCreatePlane (0,a,b,c,d); }
+  dPlane (dSpace &space, dReal a, dReal b, dReal c, dReal d)
+    { _id = dCreatePlane (space.id(),a,b,c,d); }
+  dPlane (dSpaceID space, dReal a, dReal b, dReal c, dReal d)
+    { _id = dCreatePlane (space,a,b,c,d); }
+
+  void create (dSpaceID space, dReal a, dReal b, dReal c, dReal d) {
+    if (_id) dGeomDestroy (_id);
+    _id = dCreatePlane (space,a,b,c,d);
+  }
+
+  void setParams (dReal a, dReal b, dReal c, dReal d)
+    { dGeomPlaneSetParams (_id, a, b, c, d); }
+  void getParams (dVector4 result) const
+    { dGeomPlaneGetParams (_id,result); }
+};
+
+
+class dCapsule : public dGeom {
+  // intentionally undefined, don't use these
+  dCapsule (dCapsule &);
+  void operator= (dCapsule &);
+
+public:
+  dCapsule() { }
+  dCapsule (dReal radius, dReal length)
+    { _id = dCreateCapsule (0,radius,length); }
+  dCapsule (dSpace &space, dReal radius, dReal length)
+    { _id = dCreateCapsule (space.id(),radius,length); }
+  dCapsule (dSpaceID space, dReal radius, dReal length)
+    { _id = dCreateCapsule (space,radius,length); }
+
+  void create (dSpaceID space, dReal radius, dReal length) {
+    if (_id) dGeomDestroy (_id);
+    _id = dCreateCapsule (space,radius,length);
+  }
+
+  void setParams (dReal radius, dReal length)
+    { dGeomCapsuleSetParams (_id, radius, length); }
+  void getParams (dReal *radius, dReal *length) const
+    { dGeomCapsuleGetParams (_id,radius,length); }
+};
+
+
+class dCylinder : public dGeom {
+  // intentionally undefined, don't use these
+  dCylinder (dCylinder &);
+  void operator= (dCylinder &);
+
+public:
+  dCylinder() { }
+  dCylinder (dReal radius, dReal length)
+    { _id = dCreateCylinder (0,radius,length); }
+  dCylinder (dSpace &space, dReal radius, dReal length)
+    { _id = dCreateCylinder (space.id(),radius,length); }
+  dCylinder (dSpaceID space, dReal radius, dReal length)
+    { _id = dCreateCylinder (space,radius,length); }
+
+  void create (dSpaceID space, dReal radius, dReal length) {
+    if (_id) dGeomDestroy (_id);
+    _id = dCreateCylinder (space,radius,length);
+  }
+
+  void setParams (dReal radius, dReal length)
+    { dGeomCylinderSetParams (_id, radius, length); }
+  void getParams (dReal *radius, dReal *length) const
+    { dGeomCylinderGetParams (_id,radius,length); }
+};
+
+
+class dRay : public dGeom {
+  // intentionally undefined, don't use these
+  dRay (dRay &);
+  void operator= (dRay &);
+
+public:
+  dRay() { }
+  dRay (dReal length)
+    { _id = dCreateRay (0,length); }
+  dRay (dSpace &space, dReal length)
+    { _id = dCreateRay (space.id(),length); }
+  dRay (dSpaceID space, dReal length)
+    { _id = dCreateRay (space,length); }
+
+  void create (dSpaceID space, dReal length) {
+    if (_id) dGeomDestroy (_id);
+    _id = dCreateRay (space,length);
+  }
+
+  void setLength (dReal length)
+    { dGeomRaySetLength (_id, length); }
+  dReal getLength()
+    { return dGeomRayGetLength (_id); }
+
+  void set (dReal px, dReal py, dReal pz, dReal dx, dReal dy, dReal dz)
+    { dGeomRaySet (_id, px, py, pz, dx, dy, dz); }
+  void get (dVector3 start, dVector3 dir)
+    { dGeomRayGet (_id, start, dir); }
+
+  void setParams (int firstContact, int backfaceCull)
+    { dGeomRaySetParams (_id, firstContact, backfaceCull); }
+  void getParams (int *firstContact, int *backfaceCull)
+    { dGeomRayGetParams (_id, firstContact, backfaceCull); }
+  void setClosestHit (int closestHit)
+    { dGeomRaySetClosestHit (_id, closestHit); }
+  int getClosestHit()
+    { return dGeomRayGetClosestHit (_id); }
+};
+
+
+class dGeomTransform : public dGeom {
+  // intentionally undefined, don't use these
+  dGeomTransform (dGeomTransform &);
+  void operator= (dGeomTransform &);
+
+public:
+  dGeomTransform() { }
+  dGeomTransform (dSpace &space)
+    { _id = dCreateGeomTransform (space.id()); }
+  dGeomTransform (dSpaceID space)
+    { _id = dCreateGeomTransform (space); }
+
+  void create (dSpaceID space=0) {
+    if (_id) dGeomDestroy (_id);
+    _id = dCreateGeomTransform (space);
+  }
+
+  void setGeom (dGeomID geom)
+    { dGeomTransformSetGeom (_id, geom); }
+  dGeomID getGeom() const
+    { return dGeomTransformGetGeom (_id); }
+
+  void setCleanup (int mode)
+    { dGeomTransformSetCleanup (_id,mode); }
+  int getCleanup ()
+    { return dGeomTransformGetCleanup (_id); }
+
+  void setInfo (int mode)
+    { dGeomTransformSetInfo (_id,mode); }
+  int getInfo()
+    { return dGeomTransformGetInfo (_id); }
+};
+
+//}
+
+#endif
+#endif
diff --git a/misc/builddeps/dp.linux32/include/ode/odeinit.h b/misc/builddeps/dp.linux32/include/ode/odeinit.h
new file mode 100644 (file)
index 0000000..bb430c8
--- /dev/null
@@ -0,0 +1,236 @@
+/*************************************************************************
+*                                                                       *
+* Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith.       *
+* All rights reserved.  Email: russ@q12.org   Web: www.q12.org          *
+*                                                                       *
+* This library is free software; you can redistribute it and/or         *
+* modify it under the terms of EITHER:                                  *
+*   (1) The GNU Lesser General Public License as published by the Free  *
+*       Software Foundation; either version 2.1 of the License, or (at  *
+*       your option) any later version. The text of the GNU Lesser      *
+*       General Public License is included with this library in the     *
+*       file LICENSE.TXT.                                               *
+*   (2) The BSD-style license that is included with this library in     *
+*       the file LICENSE-BSD.TXT.                                       *
+*                                                                       *
+* This library is distributed in the hope that it will be useful,       *
+* but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files    *
+* LICENSE.TXT and LICENSE-BSD.TXT for more details.                     *
+*                                                                       *
+*************************************************************************/
+
+/* Library initialization/finalization functions. */
+
+#ifndef _ODE_ODEINIT_H_
+#define _ODE_ODEINIT_H_
+
+#include <ode/common.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/* ************************************************************************ */
+/* Library initialization */
+
+/**
+ * @defgroup init Library Initialization
+ *
+ * Library initialization functions prepare ODE internal data structures for use
+ * and release allocated resources after ODE is not needed any more.
+ */
+
+
+/**
+ * @brief Library initialization flags.
+ *
+ * These flags define ODE library initialization options.
+ *
+ * @c dInitFlagManualThreadCleanup indicates that resources allocated in TLS for threads
+ * using ODE are to be cleared by library client with explicit call to @c dCleanupODEAllDataForThread.
+ * If this flag is not specified the automatic resource tracking algorithm is used.
+ *
+ * With automatic resource tracking, On Windows, memory allocated for a thread may 
+ * remain not freed for some time after the thread exits. The resources may be 
+ * released when one of other threads calls @c dAllocateODEDataForThread. Ultimately,
+ * the resources are released when library is closed with @c dCloseODE. On other 
+ * operating systems resources are always released by the thread itself on its exit
+ * or on library closure with @c dCloseODE.
+ *
+ * With manual thread data cleanup mode every collision space object must be 
+ * explicitly switched to manual cleanup mode with @c dSpaceSetManualCleanup
+ * after creation. See description of the function for more details.
+ *
+ * If @c dInitFlagManualThreadCleanup was not specified during initialization,
+ * calls to @c dCleanupODEAllDataForThread are not allowed.
+ *
+ * @see dInitODE2
+ * @see dAllocateODEDataForThread
+ * @see dSpaceSetManualCleanup
+ * @see dCloseODE
+ * @ingroup init
+ */
+enum dInitODEFlags {
+       dInitFlagManualThreadCleanup = 0x00000001 //@< Thread local data is to be cleared explicitly on @c dCleanupODEAllDataForThread function call
+};
+
+/**
+ * @brief Initializes ODE library.
+ *
+ * @c dInitODE is obsolete. @c dInitODE2 is to be used for library initialization.
+ *
+ * A call to @c dInitODE is equal to the following initialization sequence
+ * @code
+ *     dInitODE2(0);
+ *     dAllocateODEDataForThread(dAllocateMaskAll);
+ * @endcode
+ *
+ * @see dInitODE2
+ * @see dAllocateODEDataForThread
+ * @ingroup init
+ */
+ODE_API void dInitODE(void);
+
+/**
+ * @brief Initializes ODE library.
+ * @param uiInitFlags Initialization options bitmask
+ * @return A nonzero if initialization succeeded and zero otherwise.
+ *
+ * This function must be called to initialize ODE library before first use. If 
+ * initialization succeeds the function may not be called again until library is 
+ * closed with a call to @c dCloseODE.
+ *
+ * The @a uiInitFlags parameter specifies initialization options to be used. These
+ * can be combination of zero or more @c dInitODEFlags flags.
+ *
+ * @note
+ * If @c dInitFlagManualThreadCleanup flag is used for initialization, 
+ * @c dSpaceSetManualCleanup must be called to set manual cleanup mode for every
+ * space object right after creation. Failure to do so may lead to resource leaks.
+ *
+ * @see dInitODEFlags
+ * @see dCloseODE
+ * @see dSpaceSetManualCleanup
+ * @ingroup init
+ */
+ODE_API int dInitODE2(unsigned int uiInitFlags/*=0*/);
+
+
+/**
+ * @brief ODE data allocation flags.
+ *
+ * These flags are used to indicate which data is to be pre-allocated in call to
+ * @c dAllocateODEDataForThread.
+ *
+ * @c dAllocateFlagBasicData tells to allocate the basic data set required for
+ * normal library operation. This flag is equal to zero and is always implicitly 
+ * included.
+ *
+ * @c dAllocateFlagCollisionData tells that collision detection data is to be allocated.
+ * Collision detection functions may not be called if the data has not be allocated 
+ * in advance. If collision detection is not going to be used, it is not necessary
+ * to specify this flag.
+ *
+ * @c dAllocateMaskAll is a mask that can be used for for allocating all possible 
+ * data in cases when it is not known what exactly features of ODE will be used.
+ * The mask may not be used in combination with other flags. It is guaranteed to
+ * include all the current and future legal allocation flags. However, mature 
+ * applications should use explicit flags they need rather than allocating everything.
+ *
+ * @see dAllocateODEDataForThread
+ * @ingroup init
+ */
+enum dAllocateODEDataFlags {
+       dAllocateFlagBasicData = 0, //@< Allocate basic data required for library to operate
+
+       dAllocateFlagCollisionData = 0x00000001, //@< Allocate data for collision detection
+
+       dAllocateMaskAll = ~0U //@< Allocate all the possible data that is currently defined or will be defined in the future.
+};
+
+/**
+ * @brief Allocate thread local data to allow the thread calling ODE.
+ * @param uiAllocateFlags Allocation options bitmask.
+ * @return A nonzero if allocation succeeded and zero otherwise.
+ * 
+ * The function is required to be called for every thread that is going to use
+ * ODE. This function allocates the data that is required for accessing ODE from 
+ * current thread along with optional data required for particular ODE subsystems.
+ *
+ * @a uiAllocateFlags parameter can contain zero or more flags from @c dAllocateODEDataFlags
+ * enumerated type. Multiple calls with different allocation flags are allowed.
+ * The flags that are already allocated are ignored in subsequent calls. If zero
+ * is passed as the parameter, it means to only allocate the set of most important
+ * data the library can not operate without.
+ *
+ * If the function returns failure status it means that none of the requested 
+ * data has been allocated. The client may retry allocation attempt with the same 
+ * flags when more system resources are available.
+ *
+ * @see dAllocateODEDataFlags
+ * @see dCleanupODEAllDataForThread
+ * @ingroup init
+ */
+ODE_API int dAllocateODEDataForThread(unsigned int uiAllocateFlags);
+
+/**
+ * @brief Free thread local data that was allocated for current thread.
+ *
+ * If library was initialized with @c dInitFlagManualThreadCleanup flag the function 
+ * is required to be called on exit of every thread that was calling @c dAllocateODEDataForThread.
+ * Failure to call @c dCleanupODEAllDataForThread may result in some resources remaining 
+ * not freed until program exit. The function may also be called when ODE is still 
+ * being used to release resources allocated for all the current subsystems and 
+ * possibly proceed with data pre-allocation for other subsystems.
+ *
+ * The function can safely be called several times in a row. The function can be 
+ * called without prior invocation of @c dAllocateODEDataForThread. The function 
+ * may not be called before ODE is initialized with @c dInitODE2 or after library 
+ * has been closed with @c dCloseODE. A call to @c dCloseODE implicitly releases 
+ * all the thread local resources that might be allocated for all the threads that 
+ * were using ODE.
+ *
+ * If library was initialized without @c dInitFlagManualThreadCleanup flag 
+ * @c dCleanupODEAllDataForThread must not be called.
+ *
+ * @see dAllocateODEDataForThread
+ * @see dInitODE2
+ * @see dCloseODE
+ * @ingroup init
+ */
+ODE_API void dCleanupODEAllDataForThread();
+
+
+/**
+ * @brief Close ODE after it is not needed any more.
+ *
+ * The function is required to be called when program does not need ODE features any more.
+ * The call to @c dCloseODE releases all the resources allocated for library
+ * including all the thread local data that might be allocated for all the threads
+ * that were using ODE.
+ *
+ * @c dCloseODE is a paired function for @c dInitODE2 and must only be called
+ * after successful library initialization.
+ *
+ * @note Important!
+ * Make sure that all the threads that were using ODE have already terminated 
+ * before calling @c dCloseODE. In particular it is not allowed to call
+ * @c dCleanupODEAllDataForThread after @c dCloseODE.
+ *
+ * @see dInitODE2
+ * @see dCleanupODEAllDataForThread
+ * @ingroup init
+ */
+ODE_API void dCloseODE(void);
+
+
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+
+#endif // _ODE_ODEINIT_H_
diff --git a/misc/builddeps/dp.linux32/include/ode/odemath.h b/misc/builddeps/dp.linux32/include/ode/odemath.h
new file mode 100644 (file)
index 0000000..2e689db
--- /dev/null
@@ -0,0 +1,473 @@
+/*************************************************************************
+ *                                                                       *
+ * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith.       *
+ * All rights reserved.  Email: russ@q12.org   Web: www.q12.org          *
+ *                                                                       *
+ * This library is free software; you can redistribute it and/or         *
+ * modify it under the terms of EITHER:                                  *
+ *   (1) The GNU Lesser General Public License as published by the Free  *
+ *       Software Foundation; either version 2.1 of the License, or (at  *
+ *       your option) any later version. The text of the GNU Lesser      *
+ *       General Public License is included with this library in the     *
+ *       file LICENSE.TXT.                                               *
+ *   (2) The BSD-style license that is included with this library in     *
+ *       the file LICENSE-BSD.TXT.                                       *
+ *                                                                       *
+ * This library is distributed in the hope that it will be useful,       *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files    *
+ * LICENSE.TXT and LICENSE-BSD.TXT for more details.                     *
+ *                                                                       *
+ *************************************************************************/
+
+#ifndef _ODE_ODEMATH_H_
+#define _ODE_ODEMATH_H_
+
+#include <ode/common.h>
+
+/*
+ * macro to access elements i,j in an NxM matrix A, independent of the
+ * matrix storage convention.
+ */
+#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[1]) || dIsNan(v[2]) || dIsNan(v[3])))
+#define dVALIDMAT3(m) (!(dIsNan(m[0]) || dIsNan(m[1]) || 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])))
+#define dVALIDMAT4(m) (!(dIsNan(m[0]) || dIsNan(m[1]) || 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]) || dIsNan(m[12]) || dIsNan(m[13]) || dIsNan(m[14]) || dIsNan(m[15]) ))
+
+
+
+// Some vector math
+PURE_INLINE void dAddVectors3(dReal *res, const dReal *a, const dReal *b)
+{
+  dReal res_0, res_1, res_2;
+  res_0 = a[0] + b[0];
+  res_1 = a[1] + b[1];
+  res_2 = a[2] + b[2];
+  // Only assign after all the calculations are over to avoid incurring memory aliasing
+  res[0] = res_0; res[1] = res_1; res[2] = res_2;
+}
+
+PURE_INLINE void dSubtractVectors3(dReal *res, const dReal *a, const dReal *b)
+{
+  dReal res_0, res_1, res_2;
+  res_0 = a[0] - b[0];
+  res_1 = a[1] - b[1];
+  res_2 = a[2] - b[2];
+  // Only assign after all the calculations are over to avoid incurring memory aliasing
+  res[0] = res_0; res[1] = res_1; res[2] = res_2;
+}
+
+PURE_INLINE void dAddScaledVectors3(dReal *res, const dReal *a, const dReal *b, dReal a_scale, dReal b_scale)
+{
+  dReal res_0, res_1, res_2;
+  res_0 = a_scale * a[0] + b_scale * b[0];
+  res_1 = a_scale * a[1] + b_scale * b[1];
+  res_2 = a_scale * a[2] + b_scale * b[2];
+  // Only assign after all the calculations are over to avoid incurring memory aliasing
+  res[0] = res_0; res[1] = res_1; res[2] = res_2;
+}
+
+PURE_INLINE void dScaleVector3(dReal *res, dReal nScale)
+{
+  res[0] *= nScale ;
+  res[1] *= nScale ;
+  res[2] *= nScale ;
+}
+
+PURE_INLINE void dNegateVector3(dReal *res)
+{
+  res[0] = -res[0];
+  res[1] = -res[1];
+  res[2] = -res[2];
+}
+
+PURE_INLINE void dCopyVector3(dReal *res, const dReal *a)
+{
+  dReal res_0, res_1, res_2;
+  res_0 = a[0];
+  res_1 = a[1];
+  res_2 = a[2];
+  // Only assign after all the calculations are over to avoid incurring memory aliasing
+  res[0] = res_0; res[1] = res_1; res[2] = res_2;
+}
+
+PURE_INLINE void dCopyScaledVector3(dReal *res, const dReal *a, dReal nScale)
+{
+  dReal res_0, res_1, res_2;
+  res_0 = a[0] * nScale;
+  res_1 = a[1] * nScale;
+  res_2 = a[2] * nScale;
+  // Only assign after all the calculations are over to avoid incurring memory aliasing
+  res[0] = res_0; res[1] = res_1; res[2] = res_2;
+}
+
+PURE_INLINE void dCopyNegatedVector3(dReal *res, const dReal *a)
+{
+  dReal res_0, res_1, res_2;
+  res_0 = -a[0];
+  res_1 = -a[1];
+  res_2 = -a[2];
+  // Only assign after all the calculations are over to avoid incurring memory aliasing
+  res[0] = res_0; res[1] = res_1; res[2] = res_2;
+}
+
+PURE_INLINE void dCopyVector4(dReal *res, const dReal *a)
+{
+  dReal res_0, res_1, res_2, res_3;
+  res_0 = a[0];
+  res_1 = a[1];
+  res_2 = a[2];
+  res_3 = a[3];
+  // Only assign after all the calculations are over to avoid incurring memory aliasing
+  res[0] = res_0; res[1] = res_1; res[2] = res_2; res[3] = res_3;
+}
+
+PURE_INLINE void dCopyMatrix4x4(dReal *res, const dReal *a)
+{
+  dCopyVector4(res + 0, a + 0);
+  dCopyVector4(res + 4, a + 4);
+  dCopyVector4(res + 8, a + 8);
+}
+
+PURE_INLINE void dCopyMatrix4x3(dReal *res, const dReal *a)
+{
+  dCopyVector3(res + 0, a + 0);
+  dCopyVector3(res + 4, a + 4);
+  dCopyVector3(res + 8, a + 8);
+}
+
+PURE_INLINE void dGetMatrixColumn3(dReal *res, const dReal *a, unsigned n)
+{
+  dReal res_0, res_1, res_2;
+  res_0 = a[n + 0];
+  res_1 = a[n + 4];
+  res_2 = a[n + 8];
+  // Only assign after all the calculations are over to avoid incurring memory aliasing
+  res[0] = res_0; res[1] = res_1; res[2] = res_2;
+}
+
+PURE_INLINE dReal dCalcVectorLength3(const dReal *a)
+{
+  return dSqrt(a[0] * a[0] + a[1] * a[1] + a[2] * a[2]);
+}
+
+PURE_INLINE dReal dCalcVectorLengthSquare3(const dReal *a)
+{
+  return (a[0] * a[0] + a[1] * a[1] + a[2] * a[2]);
+}
+
+PURE_INLINE dReal dCalcPointDepth3(const dReal *test_p, const dReal *plane_p, const dReal *plane_n)
+{
+  return (plane_p[0] - test_p[0]) * plane_n[0] + (plane_p[1] - test_p[1]) * plane_n[1] + (plane_p[2] - test_p[2]) * plane_n[2];
+}
+
+
+/*
+* 3-way dot product. _dCalcVectorDot3 means that elements of `a' and `b' are spaced
+* step_a and step_b indexes apart respectively. dCalcVectorDot3() means dDot311.
+*/
+
+PURE_INLINE dReal _dCalcVectorDot3(const dReal *a, const dReal *b, unsigned step_a, unsigned step_b)
+{
+  return a[0] * b[0] + a[step_a] * b[step_b] + a[2 * step_a] * b[2 * step_b];
+}
+
+
+PURE_INLINE dReal dCalcVectorDot3    (const dReal *a, const dReal *b) { return _dCalcVectorDot3(a,b,1,1); }
+PURE_INLINE dReal dCalcVectorDot3_13 (const dReal *a, const dReal *b) { return _dCalcVectorDot3(a,b,1,3); }
+PURE_INLINE dReal dCalcVectorDot3_31 (const dReal *a, const dReal *b) { return _dCalcVectorDot3(a,b,3,1); }
+PURE_INLINE dReal dCalcVectorDot3_33 (const dReal *a, const dReal *b) { return _dCalcVectorDot3(a,b,3,3); }
+PURE_INLINE dReal dCalcVectorDot3_14 (const dReal *a, const dReal *b) { return _dCalcVectorDot3(a,b,1,4); }
+PURE_INLINE dReal dCalcVectorDot3_41 (const dReal *a, const dReal *b) { return _dCalcVectorDot3(a,b,4,1); }
+PURE_INLINE dReal dCalcVectorDot3_44 (const dReal *a, const dReal *b) { return _dCalcVectorDot3(a,b,4,4); }
+
+
+/*
+ * cross product, set res = a x b. _dCalcVectorCross3 means that elements of `res', `a'
+ * and `b' are spaced step_res, step_a and step_b indexes apart respectively.
+ * dCalcVectorCross3() means dCross3111. 
+ */
+
+PURE_INLINE void _dCalcVectorCross3(dReal *res, const dReal *a, const dReal *b, unsigned step_res, unsigned step_a, unsigned step_b)
+{
+  dReal res_0, res_1, res_2;
+  res_0 = a[  step_a]*b[2*step_b] - a[2*step_a]*b[  step_b];
+  res_1 = a[2*step_a]*b[       0] - a[       0]*b[2*step_b];
+  res_2 = a[       0]*b[  step_b] - a[  step_a]*b[       0];
+  // Only assign after all the calculations are over to avoid incurring memory aliasing
+  res[         0] = res_0;
+  res[  step_res] = res_1;
+  res[2*step_res] = res_2;
+}
+
+PURE_INLINE void dCalcVectorCross3    (dReal *res, const dReal *a, const dReal *b) { _dCalcVectorCross3(res, a, b, 1, 1, 1); }
+PURE_INLINE void dCalcVectorCross3_114(dReal *res, const dReal *a, const dReal *b) { _dCalcVectorCross3(res, a, b, 1, 1, 4); }
+PURE_INLINE void dCalcVectorCross3_141(dReal *res, const dReal *a, const dReal *b) { _dCalcVectorCross3(res, a, b, 1, 4, 1); }
+PURE_INLINE void dCalcVectorCross3_144(dReal *res, const dReal *a, const dReal *b) { _dCalcVectorCross3(res, a, b, 1, 4, 4); }
+PURE_INLINE void dCalcVectorCross3_411(dReal *res, const dReal *a, const dReal *b) { _dCalcVectorCross3(res, a, b, 4, 1, 1); }
+PURE_INLINE void dCalcVectorCross3_414(dReal *res, const dReal *a, const dReal *b) { _dCalcVectorCross3(res, a, b, 4, 1, 4); }
+PURE_INLINE void dCalcVectorCross3_441(dReal *res, const dReal *a, const dReal *b) { _dCalcVectorCross3(res, a, b, 4, 4, 1); }
+PURE_INLINE void dCalcVectorCross3_444(dReal *res, const dReal *a, const dReal *b) { _dCalcVectorCross3(res, a, b, 4, 4, 4); }
+
+PURE_INLINE void dAddVectorCross3(dReal *res, const dReal *a, const dReal *b)
+{
+  dReal tmp[3];
+  dCalcVectorCross3(tmp, a, b);
+  dAddVectors3(res, res, tmp);
+}
+
+PURE_INLINE void dSubtractVectorCross3(dReal *res, const dReal *a, const dReal *b)
+{
+  dReal tmp[3];
+  dCalcVectorCross3(tmp, a, b);
+  dSubtractVectors3(res, res, tmp);
+}
+
+
+/*
+ * 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
+ * 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 negative version will be written.
+ */
+
+PURE_INLINE void dSetCrossMatrixPlus(dReal *res, const dReal *a, unsigned skip)
+{
+  const dReal a_0 = a[0], a_1 = a[1], a_2 = a[2];
+  res[1] = -a_2;
+  res[2] = +a_1;
+  res[skip+0] = +a_2;
+  res[skip+2] = -a_0;
+  res[2*skip+0] = -a_1;
+  res[2*skip+1] = +a_0;
+}
+
+PURE_INLINE void dSetCrossMatrixMinus(dReal *res, const dReal *a, unsigned skip)
+{
+  const dReal a_0 = a[0], a_1 = a[1], a_2 = a[2];
+  res[1] = +a_2;
+  res[2] = -a_1;
+  res[skip+0] = -a_2;
+  res[skip+2] = +a_0;
+  res[2*skip+0] = +a_1;
+  res[2*skip+1] = -a_0;
+}
+
+
+/*
+ * compute the distance between two 3D-vectors
+ */
+
+PURE_INLINE dReal dCalcPointsDistance3(const dReal *a, const dReal *b)
+{
+  dReal res;
+  dReal tmp[3];
+  dSubtractVectors3(tmp, a, b);
+  res = dCalcVectorLength3(tmp);
+  return res;
+}
+
+/*
+ * special case matrix multiplication, with operator selection
+ */
+
+PURE_INLINE void dMultiplyHelper0_331(dReal *res, const dReal *a, const dReal *b)
+{
+  dReal res_0, res_1, res_2;
+  res_0 = dCalcVectorDot3(a, b);
+  res_1 = dCalcVectorDot3(a + 4, b);
+  res_2 = dCalcVectorDot3(a + 8, b);
+  // Only assign after all the calculations are over to avoid incurring memory aliasing
+  res[0] = res_0; res[1] = res_1; res[2] = res_2;
+}
+
+PURE_INLINE void dMultiplyHelper1_331(dReal *res, const dReal *a, const dReal *b)
+{
+  dReal res_0, res_1, res_2;
+  res_0 = dCalcVectorDot3_41(a, b);
+  res_1 = dCalcVectorDot3_41(a + 1, b);
+  res_2 = dCalcVectorDot3_41(a + 2, b);
+  // Only assign after all the calculations are over to avoid incurring memory aliasing
+  res[0] = res_0; res[1] = res_1; res[2] = res_2;
+}
+
+PURE_INLINE void dMultiplyHelper0_133(dReal *res, const dReal *a, const dReal *b)
+{
+  dMultiplyHelper1_331(res, b, a);
+}
+
+PURE_INLINE void dMultiplyHelper1_133(dReal *res, const dReal *a, const dReal *b)
+{
+  dReal res_0, res_1, res_2;
+  res_0 = dCalcVectorDot3_44(a, b);
+  res_1 = dCalcVectorDot3_44(a + 1, b);
+  res_2 = dCalcVectorDot3_44(a + 2, b);
+  // Only assign after all the calculations are over to avoid incurring memory aliasing
+  res[0] = res_0; res[1] = res_1; res[2] = res_2;
+}
+
+/* 
+Note: NEVER call any of these functions/macros with the same variable for A and C, 
+it is not equivalent to A*=B.
+*/
+
+PURE_INLINE void dMultiply0_331(dReal *res, const dReal *a, const dReal *b)
+{
+  dMultiplyHelper0_331(res, a, b);
+}
+
+PURE_INLINE void dMultiply1_331(dReal *res, const dReal *a, const dReal *b)
+{
+  dMultiplyHelper1_331(res, a, b);
+}
+
+PURE_INLINE void dMultiply0_133(dReal *res, const dReal *a, const dReal *b)
+{
+  dMultiplyHelper0_133(res, a, b);
+}
+
+PURE_INLINE void dMultiply0_333(dReal *res, const dReal *a, const dReal *b)
+{
+  dMultiplyHelper0_133(res + 0, a + 0, b);
+  dMultiplyHelper0_133(res + 4, a + 4, b);
+  dMultiplyHelper0_133(res + 8, a + 8, b);
+}
+
+PURE_INLINE void dMultiply1_333(dReal *res, const dReal *a, const dReal *b)
+{
+  dMultiplyHelper1_133(res + 0, b, a + 0);
+  dMultiplyHelper1_133(res + 4, b, a + 1);
+  dMultiplyHelper1_133(res + 8, b, a + 2);
+}
+
+PURE_INLINE void dMultiply2_333(dReal *res, const dReal *a, const dReal *b)
+{
+  dMultiplyHelper0_331(res + 0, b, a + 0);
+  dMultiplyHelper0_331(res + 4, b, a + 4);
+  dMultiplyHelper0_331(res + 8, b, a + 8);
+}
+
+PURE_INLINE void dMultiplyAdd0_331(dReal *res, const dReal *a, const dReal *b)
+{
+  dReal tmp[3];
+  dMultiplyHelper0_331(tmp, a, b);
+  dAddVectors3(res, res, tmp);
+}
+
+PURE_INLINE void dMultiplyAdd1_331(dReal *res, const dReal *a, const dReal *b)
+{
+  dReal tmp[3];
+  dMultiplyHelper1_331(tmp, a, b);
+  dAddVectors3(res, res, tmp);
+}
+
+PURE_INLINE void dMultiplyAdd0_133(dReal *res, const dReal *a, const dReal *b)
+{
+  dReal tmp[3];
+  dMultiplyHelper0_133(tmp, a, b);
+  dAddVectors3(res, res, tmp);
+}
+
+PURE_INLINE void dMultiplyAdd0_333(dReal *res, const dReal *a, const dReal *b)
+{
+  dReal tmp[3];
+  dMultiplyHelper0_133(tmp, a + 0, b);
+  dAddVectors3(res+ 0, res + 0, tmp);
+  dMultiplyHelper0_133(tmp, a + 4, b);
+  dAddVectors3(res + 4, res + 4, tmp);
+  dMultiplyHelper0_133(tmp, a + 8, b);
+  dAddVectors3(res + 8, res + 8, tmp);
+}
+
+PURE_INLINE void dMultiplyAdd1_333(dReal *res, const dReal *a, const dReal *b)
+{
+  dReal tmp[3];
+  dMultiplyHelper1_133(tmp, b, a + 0);
+  dAddVectors3(res + 0, res + 0, tmp);
+  dMultiplyHelper1_133(tmp, b, a + 1);
+  dAddVectors3(res + 4, res + 4, tmp);
+  dMultiplyHelper1_133(tmp, b, a + 2);
+  dAddVectors3(res + 8, res + 8, tmp);
+}
+
+PURE_INLINE void dMultiplyAdd2_333(dReal *res, const dReal *a, const dReal *b)
+{
+  dReal tmp[3];
+  dMultiplyHelper0_331(tmp, b, a + 0);
+  dAddVectors3(res + 0, res + 0, tmp);
+  dMultiplyHelper0_331(tmp, b, a + 4);
+  dAddVectors3(res + 4, res + 4, tmp);
+  dMultiplyHelper0_331(tmp, b, a + 8);
+  dAddVectors3(res + 8, res + 8, tmp);
+}
+
+
+// Include legacy macros here
+#include <ode/odemath_legacy.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * normalize 3x1 and 4x1 vectors (i.e. scale them to unit length)
+ */
+
+// For DLL export
+ODE_API int  dSafeNormalize3 (dVector3 a);
+ODE_API int  dSafeNormalize4 (dVector4 a);
+ODE_API void dNormalize3 (dVector3 a); // Potentially asserts on zero vec
+ODE_API void dNormalize4 (dVector4 a); // Potentially asserts on zero vec
+
+#if defined(__ODE__)
+
+int  _dSafeNormalize3 (dVector3 a);
+int  _dSafeNormalize4 (dVector4 a);
+
+PURE_INLINE void _dNormalize3(dVector3 a)
+{
+  int bNormalizationResult = _dSafeNormalize3(a);
+  dIVERIFY(bNormalizationResult);
+}
+
+PURE_INLINE void _dNormalize4(dVector4 a)
+{
+  int bNormalizationResult = _dSafeNormalize4(a);
+  dIVERIFY(bNormalizationResult);
+}
+
+// For internal use
+#define dSafeNormalize3(a) _dSafeNormalize3(a)
+#define dSafeNormalize4(a) _dSafeNormalize4(a)
+#define dNormalize3(a) _dNormalize3(a)
+#define dNormalize4(a) _dNormalize4(a)
+
+#endif // defined(__ODE__)
+
+/*
+ * 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.
+ * 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 but
+ * q wont be.
+ */
+
+ODE_API void dPlaneSpace (const dVector3 n, dVector3 p, dVector3 q);
+/* Makes sure the matrix is a proper rotation */
+ODE_API void dOrthogonalizeR(dMatrix3 m);
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/misc/builddeps/dp.linux32/include/ode/odemath_legacy.h b/misc/builddeps/dp.linux32/include/ode/odemath_legacy.h
new file mode 100644 (file)
index 0000000..b742638
--- /dev/null
@@ -0,0 +1,181 @@
+/*************************************************************************
+ *                                                                       *
+ * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith.       *
+ * All rights reserved.  Email: russ@q12.org   Web: www.q12.org          *
+ *                                                                       *
+ * This library is free software; you can redistribute it and/or         *
+ * modify it under the terms of EITHER:                                  *
+ *   (1) The GNU Lesser General Public License as published by the Free  *
+ *       Software Foundation; either version 2.1 of the License, or (at  *
+ *       your option) any later version. The text of the GNU Lesser      *
+ *       General Public License is included with this library in the     *
+ *       file LICENSE.TXT.                                               *
+ *   (2) The BSD-style license that is included with this library in     *
+ *       the file LICENSE-BSD.TXT.                                       *
+ *                                                                       *
+ * This library is distributed in the hope that it will be useful,       *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files    *
+ * LICENSE.TXT and LICENSE-BSD.TXT for more details.                     *
+ *                                                                       *
+ *************************************************************************/
+
+#ifndef _ODE_ODEMATH_LEGACY_H_
+#define _ODE_ODEMATH_LEGACY_H_
+
+
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+/*
+*      These macros are not used any more inside of ODE
+*  They are kept for backward compatibility with external code that
+*  might still be using them.
+*/
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+
+/*
+* General purpose vector operations with other vectors or constants.
+*/
+
+#define dOP(a,op,b,c) do { \
+  (a)[0] = ((b)[0]) op ((c)[0]); \
+  (a)[1] = ((b)[1]) op ((c)[1]); \
+  (a)[2] = ((b)[2]) op ((c)[2]); \
+} while (0)
+#define dOPC(a,op,b,c) do { \
+  (a)[0] = ((b)[0]) op (c); \
+  (a)[1] = ((b)[1]) op (c); \
+  (a)[2] = ((b)[2]) op (c); \
+} while (0)
+#define dOPE(a,op,b) do {\
+  (a)[0] op ((b)[0]); \
+  (a)[1] op ((b)[1]); \
+  (a)[2] op ((b)[2]); \
+} while (0)
+#define dOPEC(a,op,c) do { \
+  (a)[0] op (c); \
+  (a)[1] op (c); \
+  (a)[2] op (c); \
+} while (0)
+
+/// Define an equation with operators
+/// For example this function can be used to replace
+/// <PRE>
+/// for (int i=0; i<3; ++i)
+///   a[i] += b[i] + c[i];
+/// </PRE>
+#define dOPE2(a,op1,b,op2,c) do { \
+  (a)[0] op1 ((b)[0]) op2 ((c)[0]); \
+  (a)[1] op1 ((b)[1]) op2 ((c)[1]); \
+  (a)[2] op1 ((b)[2]) op2 ((c)[2]); \
+} while (0)
+
+
+#define dLENGTHSQUARED(a) dCalcVectorLengthSquare3(a)
+#define dLENGTH(a) dCalcVectorLength3(a)
+#define dDISTANCE(a, b) dCalcPointsDistance3(a, b)
+
+
+#define dDOT(a, b) dCalcVectorDot3(a, b)
+#define dDOT13(a, b) dCalcVectorDot3_13(a, b)
+#define dDOT31(a, b) dCalcVectorDot3_31(a, b)
+#define dDOT33(a, b) dCalcVectorDot3_33(a, b)
+#define dDOT14(a, b) dCalcVectorDot3_14(a, b)
+#define dDOT41(a, b) dCalcVectorDot3_41(a, b)
+#define dDOT44(a, b) dCalcVectorDot3_44(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.
+* dCROSS() means dCROSS111. `op' is normally `=', but you can set it to
+* +=, -= etc to get other effects.
+*/
+
+#define dCROSS(a,op,b,c) \
+  do { \
+  (a)[0] op ((b)[1]*(c)[2] - (b)[2]*(c)[1]); \
+  (a)[1] op ((b)[2]*(c)[0] - (b)[0]*(c)[2]); \
+  (a)[2] op ((b)[0]*(c)[1] - (b)[1]*(c)[0]); \
+  } while(0)
+#define dCROSSpqr(a,op,b,c,p,q,r) \
+  do { \
+  (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)[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 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 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 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)
+
+
+/*
+* 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
+* 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 negative version will be written.
+*/
+
+#define dCROSSMAT(A,a,skip,plus,minus) \
+  do { \
+  (A)[1] = minus (a)[2]; \
+  (A)[2] = plus (a)[1]; \
+  (A)[(skip)+0] = plus (a)[2]; \
+  (A)[(skip)+2] = minus (a)[0]; \
+  (A)[2*(skip)+0] = minus (a)[1]; \
+  (A)[2*(skip)+1] = plus (a)[0]; \
+  } while(0)
+
+
+
+
+/* 
+Note: NEVER call any of these functions/macros with the same variable for A and C, 
+it is not equivalent to A*=B.
+*/
+
+#define dMULTIPLY0_331(A, B, C) dMultiply0_331(A, B, C)
+#define dMULTIPLY1_331(A, B, C) dMultiply1_331(A, B, C)
+#define dMULTIPLY0_133(A, B, C) dMultiply0_133(A, B, C)
+#define dMULTIPLY0_333(A, B, C) dMultiply0_333(A, B, C)
+#define dMULTIPLY1_333(A, B, C) dMultiply1_333(A, B, C)
+#define dMULTIPLY2_333(A, B, C) dMultiply2_333(A, B, C)
+
+#define dMULTIPLYADD0_331(A, B, C) dMultiplyAdd0_331(A, B, C)
+#define dMULTIPLYADD1_331(A, B, C) dMultiplyAdd1_331(A, B, C)
+#define dMULTIPLYADD0_133(A, B, C) dMultiplyAdd0_133(A, B, C)
+#define dMULTIPLYADD0_333(A, B, C) dMultiplyAdd0_333(A, B, C)
+#define dMULTIPLYADD1_333(A, B, C) dMultiplyAdd1_333(A, B, C)
+#define dMULTIPLYADD2_333(A, B, C) dMultiplyAdd2_333(A, B, C)
+
+
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+/*
+*      These macros are not used any more inside of ODE
+*  They are kept for backward compatibility with external code that
+*  might still be using them.
+*/
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+
+
+#endif // #ifndef _ODE_ODEMATH_LEGACY_H_
diff --git a/misc/builddeps/dp.linux32/include/ode/rotation.h b/misc/builddeps/dp.linux32/include/ode/rotation.h
new file mode 100644 (file)
index 0000000..a72be27
--- /dev/null
@@ -0,0 +1,70 @@
+/*************************************************************************
+ *                                                                       *
+ * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith.       *
+ * All rights reserved.  Email: russ@q12.org   Web: www.q12.org          *
+ *                                                                       *
+ * This library is free software; you can redistribute it and/or         *
+ * modify it under the terms of EITHER:                                  *
+ *   (1) The GNU Lesser General Public License as published by the Free  *
+ *       Software Foundation; either version 2.1 of the License, or (at  *
+ *       your option) any later version. The text of the GNU Lesser      *
+ *       General Public License is included with this library in the     *
+ *       file LICENSE.TXT.                                               *
+ *   (2) The BSD-style license that is included with this library in     *
+ *       the file LICENSE-BSD.TXT.                                       *
+ *                                                                       *
+ * This library is distributed in the hope that it will be useful,       *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files    *
+ * LICENSE.TXT and LICENSE-BSD.TXT for more details.                     *
+ *                                                                       *
+ *************************************************************************/
+
+#ifndef _ODE_ROTATION_H_
+#define _ODE_ROTATION_H_
+
+#include <ode/common.h>
+#include <ode/compatibility.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+ODE_API void dRSetIdentity (dMatrix3 R);
+
+ODE_API void dRFromAxisAndAngle (dMatrix3 R, dReal ax, dReal ay, dReal az,
+                        dReal angle);
+
+ODE_API void dRFromEulerAngles (dMatrix3 R, dReal phi, dReal theta, dReal psi);
+
+ODE_API void dRFrom2Axes (dMatrix3 R, dReal ax, dReal ay, dReal az,
+                 dReal bx, dReal by, dReal bz);
+
+ODE_API void dRFromZAxis (dMatrix3 R, dReal ax, dReal ay, dReal az);
+
+ODE_API void dQSetIdentity (dQuaternion q);
+
+ODE_API void dQFromAxisAndAngle (dQuaternion q, dReal ax, dReal ay, dReal az,
+                        dReal angle);
+
+/* Quaternion multiplication, analogous to the matrix multiplication routines. */
+/* qa = rotate by qc, then qb */
+ODE_API void dQMultiply0 (dQuaternion qa, const dQuaternion qb, const dQuaternion qc);
+/* qa = rotate by qc, then by inverse of qb */
+ODE_API void dQMultiply1 (dQuaternion qa, const dQuaternion qb, const dQuaternion qc);
+/* qa = rotate by inverse of qc, then by qb */
+ODE_API void dQMultiply2 (dQuaternion qa, const dQuaternion qb, const dQuaternion qc);
+/* qa = rotate by inverse of qc, then by inverse of qb */
+ODE_API void dQMultiply3 (dQuaternion qa, const dQuaternion qb, const dQuaternion qc);
+
+ODE_API void dRfromQ (dMatrix3 R, const dQuaternion q);
+ODE_API void dQfromR (dQuaternion q, const dMatrix3 R);
+ODE_API void dDQfromW (dReal dq[4], const dVector3 w, const dQuaternion q);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/misc/builddeps/dp.linux32/include/ode/timer.h b/misc/builddeps/dp.linux32/include/ode/timer.h
new file mode 100644 (file)
index 0000000..fe1483f
--- /dev/null
@@ -0,0 +1,76 @@
+/*************************************************************************
+ *                                                                       *
+ * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith.       *
+ * All rights reserved.  Email: russ@q12.org   Web: www.q12.org          *
+ *                                                                       *
+ * This library is free software; you can redistribute it and/or         *
+ * modify it under the terms of EITHER:                                  *
+ *   (1) The GNU Lesser General Public License as published by the Free  *
+ *       Software Foundation; either version 2.1 of the License, or (at  *
+ *       your option) any later version. The text of the GNU Lesser      *
+ *       General Public License is included with this library in the     *
+ *       file LICENSE.TXT.                                               *
+ *   (2) The BSD-style license that is included with this library in     *
+ *       the file LICENSE-BSD.TXT.                                       *
+ *                                                                       *
+ * This library is distributed in the hope that it will be useful,       *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files    *
+ * LICENSE.TXT and LICENSE-BSD.TXT for more details.                     *
+ *                                                                       *
+ *************************************************************************/
+
+#ifndef _ODE_TIMER_H_
+#define _ODE_TIMER_H_
+
+#include <ode/odeconfig.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/* stop watch objects */
+
+typedef struct dStopwatch {
+  double time;                 /* total clock count */
+  unsigned long cc[2];         /* clock count since last `start' */
+} dStopwatch;
+
+ODE_API void dStopwatchReset (dStopwatch *);
+ODE_API void dStopwatchStart (dStopwatch *);
+ODE_API void dStopwatchStop  (dStopwatch *);
+ODE_API double dStopwatchTime (dStopwatch *);  /* returns total time in secs */
+
+
+/* code timers */
+
+ODE_API void dTimerStart (const char *description);    /* pass a static string here */
+ODE_API void dTimerNow (const char *description);      /* pass a static string here */
+ODE_API void dTimerEnd(void);
+
+/* print out a timer report. if `average' is nonzero, print out the average
+ * time for each slot (this is only meaningful if the same start-now-end
+ * calls are being made repeatedly.
+ */
+ODE_API void dTimerReport (FILE *fout, int average);
+
+
+/* resolution */
+
+/* returns the timer ticks per second implied by the timing hardware or API.
+ * the actual timer resolution may not be this great.
+ */
+ODE_API double dTimerTicksPerSecond(void);
+
+/* returns an estimate of the actual timer resolution, in seconds. this may
+ * be greater than 1/ticks_per_second.
+ */
+ODE_API double dTimerResolution(void);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
index c3bbbb6f219c698e7bbc7da021fd49f7dfbbdaca..8945205862514864bf7e286ae9eea4cdb797f5ae 100644 (file)
Binary files a/misc/builddeps/dp.linux32/lib/libd0_blind_id.a and b/misc/builddeps/dp.linux32/lib/libd0_blind_id.a differ
index 539839410302bfb06f33db93121311e7739d6d30..58897695527c4bbcd305fd40accf54c0c3022e2e 100644 (file)
Binary files a/misc/builddeps/dp.linux32/lib/libd0_rijndael.a and b/misc/builddeps/dp.linux32/lib/libd0_rijndael.a differ
index 1dd2be66eacbb62c6f60bd318eee1a618b0627c7..4caea1f8379496abe89d6e3bbd244789c080d196 100644 (file)
Binary files a/misc/builddeps/dp.linux32/lib/libmodplug.a and b/misc/builddeps/dp.linux32/lib/libmodplug.a differ
index 19a7883658048db0ba9395f9da722ac5c438837e..b4974101b6774fba0db0b846ff1d0799b194b090 100755 (executable)
@@ -17,7 +17,7 @@ old_library='libmodplug.a'
 inherited_linker_flags=''
 
 # Libraries that this one depends upon.
-dependency_libs=''
+dependency_libs=' -L/tmp/libmodplug-0.8.8.4.deps/lib/'
 
 # Names of additional weak libraries provided by this library
 weak_library_names=''
diff --git a/misc/builddeps/dp.linux32/lib/libode.a b/misc/builddeps/dp.linux32/lib/libode.a
new file mode 100644 (file)
index 0000000..71abadd
Binary files /dev/null and b/misc/builddeps/dp.linux32/lib/libode.a differ
diff --git a/misc/builddeps/dp.linux32/lib/libode.la b/misc/builddeps/dp.linux32/lib/libode.la
new file mode 100755 (executable)
index 0000000..7cabb97
--- /dev/null
@@ -0,0 +1,41 @@
+# libode.la - a libtool library file
+# Generated by libtool (GNU libtool) 2.4
+#
+# Please DO NOT delete this file!
+# It is necessary for linking the library.
+
+# The name that we can dlopen(3).
+dlname=''
+
+# Names of this library.
+library_names=''
+
+# The name of the static archive.
+old_library='libode.a'
+
+# Linker flags that can not go in dependency_libs.
+inherited_linker_flags=''
+
+# Libraries that this one depends upon.
+dependency_libs=' -L/tmp/ode-0.12.deps/lib/ -lpthread'
+
+# Names of additional weak libraries provided by this library
+weak_library_names=''
+
+# Version information for libode.
+current=3
+age=0
+revision=0
+
+# Is this an already installed library?
+installed=yes
+
+# Should we warn about portability when linking against -modules?
+shouldnotlink=no
+
+# Files to dlopen/dlpreopen
+dlopen=''
+dlpreopen=''
+
+# Directory that this library needs to be installed in:
+libdir='/usr/local/lib'
diff --git a/misc/builddeps/dp.linux32/lib/pkgconfig/ode.pc b/misc/builddeps/dp.linux32/lib/pkgconfig/ode.pc
new file mode 100644 (file)
index 0000000..7be9daa
--- /dev/null
@@ -0,0 +1,11 @@
+prefix=/usr/local
+exec_prefix=${prefix}
+libdir=${exec_prefix}/lib
+includedir=${prefix}/include
+
+Name: ode
+Description: Open Dynamics Engine
+Version: 0.12
+Libs: -L${libdir} -lode
+Libs.private: -lstdc++ -lm
+Cflags: -I${includedir} -DdDOUBLE
index 40472ca15eb10f4bd4f8001ae1ae49a0a489eb17..775836cda4ca32deee385cf415fc6819d969f15c 100755 (executable)
Binary files a/misc/builddeps/dp.linux64/bin/blind_id and b/misc/builddeps/dp.linux64/bin/blind_id differ
diff --git a/misc/builddeps/dp.linux64/bin/ode-config b/misc/builddeps/dp.linux64/bin/ode-config
new file mode 100755 (executable)
index 0000000..dddc75d
--- /dev/null
@@ -0,0 +1,53 @@
+#!/bin/sh
+
+prefix=/usr/local
+exec_prefix=${prefix}
+exec_prefix_set=no
+
+usage="\
+Usage: ode-config [--prefix[=DIR]] [--exec-prefix[=DIR]] [--version] [--cflags] [--libs]"
+
+if test $# -eq 0; then
+      echo "${usage}" 1>&2
+      exit 1
+fi
+
+while test $# -gt 0; do
+  case "$1" in
+  -*=*) optarg=`echo "$1" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
+  *) optarg= ;;
+  esac
+
+  case $1 in
+    --prefix=*)
+      prefix=$optarg
+      if test $exec_prefix_set = no ; then
+        exec_prefix=$optarg
+      fi
+      ;;
+    --prefix)
+      echo $prefix
+      ;;
+    --exec-prefix=*)
+      exec_prefix=$optarg
+      exec_prefix_set=yes
+      ;;
+    --exec-prefix)
+      echo $exec_prefix
+      ;;
+    --version)
+      echo 0.12
+      ;;
+    --cflags)
+      echo  -I${prefix}/include -DdDOUBLE
+      ;;
+    --libs)
+      echo  -L${exec_prefix}/lib -lode
+      ;;
+    *)
+      echo "${usage}" 1>&2
+      exit 1
+      ;;
+  esac
+  shift
+done
index 89d86fe5182345a2177c6dc8f99f5353afa26b78..4c8708e32a513a92a5d46a17b702f5d8a3f7e2b0 100644 (file)
@@ -30,7 +30,7 @@
  * SUCH DAMAGE.
  *
  * $Format:commit %H$
- * $Id: 0f9b41999f2a57f07067272a8b89919394c4b04f $
+ * $Id: 6c55afeb50f24bd316079ae46582e65f8020b19b $
  */
 
 #ifndef __D0_H__
@@ -39,6 +39,7 @@
 #include <unistd.h> // size_t
 
 #define D0_EXPORT __attribute__((__visibility__("default")))
+#define D0_USED __attribute__((used))
 #define D0_WARN_UNUSED_RESULT __attribute__((warn_unused_result))
 #define D0_BOOL int
 
diff --git a/misc/builddeps/dp.linux64/include/ode/collision.h b/misc/builddeps/dp.linux64/include/ode/collision.h
new file mode 100644 (file)
index 0000000..e89726c
--- /dev/null
@@ -0,0 +1,1523 @@
+/*************************************************************************
+ *                                                                       *
+ * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith.       *
+ * All rights reserved.  Email: russ@q12.org   Web: www.q12.org          *
+ *                                                                       *
+ * This library is free software; you can redistribute it and/or         *
+ * modify it under the terms of EITHER:                                  *
+ *   (1) The GNU Lesser General Public License as published by the Free  *
+ *       Software Foundation; either version 2.1 of the License, or (at  *
+ *       your option) any later version. The text of the GNU Lesser      *
+ *       General Public License is included with this library in the     *
+ *       file LICENSE.TXT.                                               *
+ *   (2) The BSD-style license that is included with this library in     *
+ *       the file LICENSE-BSD.TXT.                                       *
+ *                                                                       *
+ * This library is distributed in the hope that it will be useful,       *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files    *
+ * LICENSE.TXT and LICENSE-BSD.TXT for more details.                     *
+ *                                                                       *
+ *************************************************************************/
+
+#ifndef _ODE_COLLISION_H_
+#define _ODE_COLLISION_H_
+
+#include <ode/common.h>
+#include <ode/collision_space.h>
+#include <ode/contact.h>
+// Include odeinit.h for backward compatibility as some of initialization APIs 
+// were initally declared in current header.
+#include <ode/odeinit.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup collide Collision Detection
+ *
+ * ODE has two main components: a dynamics simulation engine and a collision
+ * detection engine. The collision engine is given information about the
+ * shape of each body. At each time step it figures out which bodies touch
+ * each other and passes the resulting contact point information to the user.
+ * The user in turn creates contact joints between bodies.
+ *
+ * Using ODE's collision detection is optional - an alternative collision
+ * detection system can be used as long as it can supply the right kinds of
+ * contact information.
+ */
+
+
+/* ************************************************************************ */
+/* general functions */
+
+/**
+ * @brief Destroy a geom, removing it from any space.
+ *
+ * Destroy a geom, removing it from any space it is in first. This one
+ * function destroys a geom of any type, but to create a geom you must call
+ * a creation function for that type.
+ *
+ * When a space is destroyed, if its cleanup mode is 1 (the default) then all
+ * the geoms in that space are automatically destroyed as well.
+ *
+ * @param geom the geom to be destroyed.
+ * @ingroup collide
+ */
+ODE_API void dGeomDestroy (dGeomID geom);
+
+
+/**
+ * @brief Set the user-defined data pointer stored in the geom.
+ *
+ * @param geom the geom to hold the data
+ * @param data the data pointer to be stored
+ * @ingroup collide
+ */
+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/rotation
+ * of the body.
+ *
+ * Calling these functions on a non-placeable geom results in a runtime
+ * error in the debug build of ODE.
+ *
+ * @param geom the geom to connect
+ * @param body the body to attach to the geom
+ * @ingroup collide
+ */
+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 changed.
+ * Calling this function on a non-placeable geom results in a runtime error in
+ * the debug build of ODE.
+ *
+ * @param geom the geom to set.
+ * @param x the new X coordinate.
+ * @param y the new Y coordinate.
+ * @param z the new Z coordinate.
+ * @sa dBodySetPosition
+ * @ingroup collide
+ */
+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 changed.
+ * Calling this function on a non-placeable geom results in a runtime error in
+ * the debug build of ODE.
+ *
+ * @param geom the geom to set.
+ * @param R the new rotation matrix.
+ * @sa dBodySetRotation
+ * @ingroup collide
+ */
+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 changed.
+ *
+ * Calling this function on a non-placeable geom results in a runtime error in
+ * the debug build of ODE.
+ *
+ * @param geom the geom to set.
+ * @param Q the new rotation.
+ * @sa dBodySetQuaternion
+ * @ingroup collide
+ */
+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 Copy the position of a geom into a vector.
+ * @ingroup collide
+ * @param geom  the geom to query
+ * @param pos   a copy of the geom position
+ * @sa dGeomGetPosition
+ */
+ODE_API void dGeomCopyPosition (dGeomID geom, dVector3 pos);
+
+
+/**
+ * @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 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.
+ * @param R      a copy of the geom rotation
+ * @sa dGeomGetRotation
+ * @ingroup collide
+ */
+ODE_API void dGeomCopyRotation(dGeomID geom, dMatrix3 R);
+
+
+/**
+ * @brief Get the rotation quaternion of a placeable geom.
+ *
+ * If the geom is attached to a body, the body's quaternion will be returned.
+ *
+ * Calling this function on a non-placeable geom results in a runtime error in
+ * the debug build of ODE.
+ *
+ * @param geom the geom to query.
+ * @param result a copy of the rotation quaternion.
+ * @sa dBodyGetQuaternion
+ * @ingroup collide
+ */
+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 geom.
+ * The aabb array has elements (minx, maxx, miny, maxy, minz, maxz). If the
+ * geom is a space, a bounding box that surrounds all contained geoms is
+ * returned.
+ *
+ * This function may return a pre-computed cached bounding box, if it can
+ * determine that the geom has not moved since the last time the bounding
+ * box was computed.
+ *
+ * @param geom the geom to query
+ * @param aabb the returned bounding box
+ * @ingroup collide
+ */
+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 dSpaceCollide2,
+ * although they can still be members of a space. New geoms are created in
+ * the enabled state.
+ *
+ * @param geom   the geom to enable
+ * @sa dGeomDisable
+ * @sa dGeomIsEnabled
+ * @ingroup collide
+ */
+ODE_API void dGeomEnable (dGeomID geom);
+
+
+/**
+ * @brief Disable a geom.
+ *
+ * Disabled geoms are completely ignored by dSpaceCollide and dSpaceCollide2,
+ * although they can still be members of a space. New geoms are created in
+ * the enabled state.
+ *
+ * @param geom   the geom to disable
+ * @sa dGeomDisable
+ * @sa dGeomIsEnabled
+ * @ingroup collide
+ */
+ODE_API void dGeomDisable (dGeomID geom);
+
+
+/**
+ * @brief Check to see if a geom is enabled.
+ *
+ * Disabled geoms are completely ignored by dSpaceCollide and dSpaceCollide2,
+ * although they can still be members of a space. New geoms are created in
+ * the enabled state.
+ *
+ * @param geom   the geom to query
+ * @returns Non-zero if the geom is enabled, zero otherwise.
+ * @sa dGeomDisable
+ * @sa dGeomIsEnabled
+ * @ingroup collide
+ */
+ODE_API int dGeomIsEnabled (dGeomID geom);
+
+
+enum
+{
+       dGeomCommonControlClass = 0,
+       dGeomColliderControlClass = 1
+};
+
+enum
+{
+       dGeomCommonAnyControlCode = 0,
+
+       dGeomColliderSetMergeSphereContactsControlCode = 1,
+       dGeomColliderGetMergeSphereContactsControlCode = 2
+};
+
+enum
+{
+       dGeomColliderMergeContactsValue__Default = 0, // Used with Set... to restore default value
+       dGeomColliderMergeContactsValue_None = 1,
+       dGeomColliderMergeContactsValue_Normals = 2,
+       dGeomColliderMergeContactsValue_Full = 3
+};
+
+/**
+ * @brief Execute low level control operation for geometry.
+ *
+ * The variable the dataSize points to must be initialized before the call.
+ * If the size does not match the one expected for the control class/code function
+ * changes it to the size expected and returns failure. This implies the function 
+ * can be called with NULL data and zero size to test if control class/code is supported
+ * and obtain required data size for it.
+ *
+ * dGeomCommonAnyControlCode applies to any control class and returns success if 
+ * at least one control code is available for the given class with given geom.
+ *
+ * Currently there are the folliwing control classes supported:
+ *  @li dGeomColliderControlClass
+ *
+ * For dGeomColliderControlClass there are the following codes available:
+ *  @li dGeomColliderSetMergeSphereContactsControlCode (arg of type int, dGeomColliderMergeContactsValue_*)
+ *  @li dGeomColliderGetMergeSphereContactsControlCode (arg of type int, dGeomColliderMergeContactsValue_*)
+ *
+ * @param geom   the geom to control
+ * @param controlClass   the control class
+ * @param controlCode   the control code for the class
+ * @param dataValue   the control argument pointer
+ * @param dataSize   the control argument size provided or expected
+ * @returns Boolean execution status
+ * @ingroup collide
+ */
+ODE_API int dGeomLowLevelControl (dGeomID geom, int controlClass, int controlCode, void *dataValue, int *dataSize);
+
+
+/**
+ * @brief Get world position of a relative point on geom.
+ *
+ * Calling this function on a non-placeable geom results in the same point being
+ * returned.
+ *
+ * @ingroup collide
+ * @param result will contain the result.
+ */
+ODE_API void dGeomGetRelPointPos
+(
+  dGeomID geom, dReal px, dReal py, dReal pz,
+  dVector3 result
+);
+
+/**
+ * @brief takes a point in global coordinates and returns
+ * the point's position in geom-relative coordinates.
+ *
+ * Calling this function on a non-placeable geom results in the same point being
+ * returned.
+ *
+ * @remarks
+ * This is the inverse of dGeomGetRelPointPos()
+ * @ingroup collide
+ * @param result will contain the result.
+ */
+ODE_API void dGeomGetPosRelPoint
+(
+  dGeomID geom, dReal px, dReal py, dReal pz,
+  dVector3 result
+);
+
+/**
+ * @brief Convert from geom-local to world coordinates.
+ *
+ * Calling this function on a non-placeable geom results in the same vector being
+ * returned.
+ *
+ * @ingroup collide
+ * @param result will contain the result.
+ */
+ODE_API void dGeomVectorToWorld
+(
+  dGeomID geom, dReal px, dReal py, dReal pz,
+  dVector3 result
+);
+
+/**
+ * @brief Convert from world to geom-local coordinates.
+ *
+ * Calling this function on a non-placeable geom results in the same vector being
+ * returned.
+ *
+ * @ingroup collide
+ * @param result will contain the result.
+ */
+ODE_API void dGeomVectorFromWorld
+(
+  dGeomID geom, dReal px, dReal py, dReal pz,
+  dVector3 result
+);
+
+
+/* ************************************************************************ */
+/* 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, dReal 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 Copy 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.
+ * @param pos    returns the offset position
+ * @ingroup collide
+ */
+ODE_API void dGeomCopyOffsetPosition (dGeomID geom, dVector3 pos);
+
+
+/**
+ * @brief Get the offset rotation matrix of a geom.
+ *
+ * Returns the rotational offset of the geom in local coordinates.
+ * If the geom has no offset, this function returns the identity
+ * matrix.
+ *
+ * @param geom the geom to query.
+ * @returns A pointer to the geom's offset 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.
+ * @ingroup collide
+ */
+ODE_API const dReal * dGeomGetOffsetRotation (dGeomID geom);
+
+
+/**
+ * @brief Copy the offset rotation matrix of a geom.
+ *
+ * Returns the rotational offset of the geom in local coordinates.
+ * If the geom has no offset, this function returns the identity
+ * matrix.
+ *
+ * @param geom   the geom to query.
+ * @param R      returns the rotation matrix.
+ * @ingroup collide
+ */
+ODE_API void dGeomCopyOffsetRotation (dGeomID geom, dMatrix3 R);
+
+
+/**
+ * @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 */
+
+/*
+ *     Just generate any contacts (disables any contact refining).
+ */
+#define CONTACTS_UNIMPORTANT                   0x80000000
+
+/**
+ *
+ * @brief Given two geoms o1 and o2 that potentially intersect,
+ * generate contact information for them.
+ *
+ * Internally, this just calls the correct class-specific collision
+ * functions for o1 and o2.
+ *
+ * @param o1 The first geom to test.
+ * @param o2 The second geom to test.
+ *
+ * @param flags The flags specify how contacts should be generated if
+ * the geoms touch. The lower 16 bits of flags is an integer that
+ * specifies the maximum number of contact points to generate. You must
+ * ask for at least one contact. 
+ * Additionally, following bits may be set:
+ * CONTACTS_UNIMPORTANT -- just generate any contacts (skip contact refining).
+ * All other bits in flags must be set to zero. In the future the other bits 
+ * may be used to select from different contact generation strategies.
+ *
+ * @param contact Points to an array of dContactGeom structures. The array
+ * must be able to hold at least the maximum number of contacts. These
+ * dContactGeom structures may be embedded within larger structures in the
+ * array -- the skip parameter is the byte offset from one dContactGeom to
+ * the next in the array. If skip is sizeof(dContactGeom) then contact
+ * points to a normal (C-style) array. It is an error for skip to be smaller
+ * than sizeof(dContactGeom).
+ *
+ * @returns If the geoms intersect, this function returns the number of contact
+ * points generated (and updates the contact array), otherwise it returns 0
+ * (and the contact array is not touched).
+ *
+ * @remarks If a space is passed as o1 or o2 then this function will collide
+ * all objects contained in o1 with all objects contained in o2, and return
+ * the resulting contact points. This method for colliding spaces with geoms
+ * (or spaces with spaces) provides no user control over the individual
+ * collisions. To get that control, use dSpaceCollide or dSpaceCollide2 instead.
+ *
+ * @remarks If o1 and o2 are the same geom then this function will do nothing
+ * and return 0. Technically speaking an object intersects with itself, but it
+ * is not useful to find contact points in this case.
+ *
+ * @remarks This function does not care if o1 and o2 are in the same space or not
+ * (or indeed if they are in any space at all).
+ *
+ * @ingroup collide
+ */
+ODE_API int dCollide (dGeomID o1, dGeomID o2, int flags, dContactGeom *contact,
+             int skip);
+
+/**
+ * @brief Determines which pairs of geoms in a space may potentially intersect,
+ * and calls the callback function for each candidate pair.
+ *
+ * @param space The space to test.
+ *
+ * @param data Passed from dSpaceCollide directly to the callback
+ * function. Its meaning is user defined. The o1 and o2 arguments are the
+ * geoms that may be near each other.
+ *
+ * @param callback A callback function is of type @ref dNearCallback.
+ *
+ * @remarks Other spaces that are contained within the colliding space are
+ * not treated specially, i.e. they are not recursed into. The callback
+ * function may be passed these contained spaces as one or both geom
+ * arguments.
+ *
+ * @remarks dSpaceCollide() is guaranteed to pass all intersecting geom
+ * pairs to the callback function, but may also pass close but
+ * non-intersecting pairs. The number of these calls depends on the
+ * internal algorithms used by the space. Thus you should not expect
+ * that dCollide will return contacts for every pair passed to the
+ * callback.
+ *
+ * @sa dSpaceCollide2
+ * @ingroup collide
+ */
+ODE_API void dSpaceCollide (dSpaceID space, void *data, dNearCallback *callback);
+
+
+/**
+ * @brief Determines which geoms from one space may potentially intersect with 
+ * geoms from another space, and calls the callback function for each candidate 
+ * pair. 
+ *
+ * @param space1 The first space to test.
+ *
+ * @param space2 The second space to test.
+ *
+ * @param data Passed from dSpaceCollide directly to the callback
+ * function. Its meaning is user defined. The o1 and o2 arguments are the
+ * geoms that may be near each other.
+ *
+ * @param callback A callback function is of type @ref dNearCallback.
+ *
+ * @remarks This function can also test a single non-space geom against a 
+ * space. This function is useful when there is a collision hierarchy, i.e. 
+ * when there are spaces that contain other spaces.
+ *
+ * @remarks Other spaces that are contained within the colliding space are
+ * not treated specially, i.e. they are not recursed into. The callback
+ * function may be passed these contained spaces as one or both geom
+ * arguments.
+ *
+ * @remarks Sublevel value of space affects how the spaces are iterated.
+ * Both spaces are recursed only if their sublevels match. Otherwise, only
+ * the space with greater sublevel is recursed and the one with lesser sublevel
+ * is used as a geom itself.
+ *
+ * @remarks dSpaceCollide2() is guaranteed to pass all intersecting geom
+ * pairs to the callback function, but may also pass close but
+ * non-intersecting pairs. The number of these calls depends on the
+ * internal algorithms used by the space. Thus you should not expect
+ * that dCollide will return contacts for every pair passed to the
+ * callback.
+ *
+ * @sa dSpaceCollide
+ * @sa dSpaceSetSublevel
+ * @ingroup collide
+ */
+ODE_API void dSpaceCollide2 (dGeomID space1, dGeomID space2, void *data, dNearCallback *callback);
+
+
+/* ************************************************************************ */
+/* standard classes */
+
+/* the maximum number of user classes that are supported */
+enum {
+  dMaxUserClasses = 4
+};
+
+/* class numbers - each geometry object needs a unique number */
+enum {
+  dSphereClass = 0,
+  dBoxClass,
+  dCapsuleClass,
+  dCylinderClass,
+  dPlaneClass,
+  dRayClass,
+  dConvexClass,
+  dGeomTransformClass,
+  dTriMeshClass,
+  dHeightfieldClass,
+
+  dFirstSpaceClass,
+  dSimpleSpaceClass = dFirstSpaceClass,
+  dHashSpaceClass,
+  dSweepAndPruneSpaceClass, // SAP
+  dQuadTreeSpaceClass,
+  dLastSpaceClass = dQuadTreeSpaceClass,
+
+  dFirstUserClass,
+  dLastUserClass = dFirstUserClass + dMaxUserClasses - 1,
+  dGeomNumClasses
+};
+
+
+/**
+ * @defgroup collide_sphere Sphere Class
+ * @ingroup collide
+ */
+
+/**
+ * @brief Create a sphere geom of the given radius, and return its ID. 
+ *
+ * @param space   a space to contain the new geom. May be null.
+ * @param radius  the radius of the sphere.
+ *
+ * @returns A new sphere geom.
+ *
+ * @remarks The point of reference for a sphere is its center.
+ *
+ * @sa dGeomDestroy
+ * @sa dGeomSphereSetRadius
+ * @ingroup collide_sphere
+ */
+ODE_API dGeomID dCreateSphere (dSpaceID space, dReal radius);
+
+
+/**
+ * @brief Set the radius of a sphere geom.
+ *
+ * @param sphere  the sphere to set.
+ * @param radius  the new radius.
+ *
+ * @sa dGeomSphereGetRadius
+ * @ingroup collide_sphere
+ */
+ODE_API void dGeomSphereSetRadius (dGeomID sphere, dReal radius);
+
+
+/**
+ * @brief Retrieves the radius of a sphere geom.
+ *
+ * @param sphere  the sphere to query.
+ *
+ * @sa dGeomSphereSetRadius
+ * @ingroup collide_sphere
+ */
+ODE_API dReal dGeomSphereGetRadius (dGeomID sphere);
+
+
+/**
+ * @brief Calculate the depth of the a given point within a sphere.
+ *
+ * @param sphere  the sphere to query.
+ * @param x       the X coordinate of the point.
+ * @param y       the Y coordinate of the point.
+ * @param z       the Z coordinate of the point.
+ *
+ * @returns The depth of the point. Points inside the sphere will have a 
+ * positive depth, points outside it will have a negative depth, and points
+ * on the surface will have a depth of zero.
+ *
+ * @ingroup collide_sphere
+ */
+ODE_API dReal dGeomSpherePointDepth (dGeomID sphere, dReal x, dReal y, dReal z);
+
+
+//--> Convex Functions
+ODE_API dGeomID dCreateConvex (dSpaceID space,
+                              dReal *_planes,
+                              unsigned int _planecount,
+                              dReal *_points,
+                              unsigned int _pointcount,unsigned int *_polygons);
+
+ODE_API void dGeomSetConvex (dGeomID g,
+                            dReal *_planes,
+                            unsigned int _count,
+                            dReal *_points,
+                            unsigned int _pointcount,unsigned int *_polygons);
+//<-- Convex Functions
+
+/**
+ * @defgroup collide_box Box Class
+ * @ingroup collide
+ */
+
+/**
+ * @brief Create a box geom with the provided side lengths.
+ *
+ * @param space   a space to contain the new geom. May be null.
+ * @param lx      the length of the box along the X axis
+ * @param ly      the length of the box along the Y axis
+ * @param lz      the length of the box along the Z axis
+ *
+ * @returns A new box geom.
+ *
+ * @remarks The point of reference for a box is its center.
+ *
+ * @sa dGeomDestroy
+ * @sa dGeomBoxSetLengths
+ * @ingroup collide_box
+ */
+ODE_API dGeomID dCreateBox (dSpaceID space, dReal lx, dReal ly, dReal lz);
+
+
+/**
+ * @brief Set the side lengths of the given box.
+ *
+ * @param box  the box to set
+ * @param lx      the length of the box along the X axis
+ * @param ly      the length of the box along the Y axis
+ * @param lz      the length of the box along the Z axis
+ *
+ * @sa dGeomBoxGetLengths
+ * @ingroup collide_box
+ */
+ODE_API void dGeomBoxSetLengths (dGeomID box, dReal lx, dReal ly, dReal lz);
+
+
+/**
+ * @brief Get the side lengths of a box.
+ *
+ * @param box     the box to query
+ * @param result  the returned side lengths
+ *
+ * @sa dGeomBoxSetLengths
+ * @ingroup collide_box
+ */
+ODE_API void dGeomBoxGetLengths (dGeomID box, dVector3 result);
+
+
+/**
+ * @brief Return the depth of a point in a box.
+ * 
+ * @param box  the box to query
+ * @param x    the X coordinate of the point to test.
+ * @param y    the Y coordinate of the point to test.
+ * @param z    the Z coordinate of the point to test.
+ *
+ * @returns The depth of the point. Points inside the box will have a 
+ * positive depth, points outside it will have a negative depth, and points
+ * on the surface will have a depth of zero.
+ */
+ODE_API dReal dGeomBoxPointDepth (dGeomID box, dReal x, dReal y, dReal z);
+
+
+ODE_API dGeomID dCreatePlane (dSpaceID space, dReal a, dReal b, dReal c, dReal 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 not.
+#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);
+ODE_API void dGeomRayGet (dGeomID ray, dVector3 start, dVector3 dir);
+
+/*
+ * Set/get ray flags that influence ray collision detection.
+ * These flags are currently only noticed by the trimesh collider, because
+ * they can make a major differences there.
+ */
+ODE_API void dGeomRaySetParams (dGeomID g, int FirstContact, int BackfaceCull);
+ODE_API void dGeomRayGetParams (dGeomID g, int *FirstContact, int *BackfaceCull);
+ODE_API void dGeomRaySetClosestHit (dGeomID g, int closestHit);
+ODE_API int dGeomRayGetClosestHit (dGeomID g);
+
+#include "collision_trimesh.h"
+
+ODE_API dGeomID dCreateGeomTransform (dSpaceID space);
+ODE_API void dGeomTransformSetGeom (dGeomID g, dGeomID obj);
+ODE_API dGeomID dGeomTransformGetGeom (dGeomID g);
+ODE_API void dGeomTransformSetCleanup (dGeomID g, int mode);
+ODE_API int dGeomTransformGetCleanup (dGeomID g);
+ODE_API void dGeomTransformSetInfo (dGeomID g, int mode);
+ODE_API int dGeomTransformGetInfo (dGeomID g);
+
+
+/* ************************************************************************ */
+/* heightfield functions */
+
+
+// Data storage for heightfield data.
+struct dxHeightfieldData;
+typedef struct dxHeightfieldData* dHeightfieldDataID;
+
+
+/**
+ * @brief Callback prototype
+ *
+ * Used by the callback heightfield data type to sample a height for a
+ * given cell position.
+ *
+ * @param p_user_data User data specified when creating the dHeightfieldDataID
+ * @param x The index of a sample in the local x axis. It is a value
+ * in the range zero to ( nWidthSamples - 1 ).
+ * @param x The index of a sample in the local z axis. It is a value
+ * in the range zero to ( nDepthSamples - 1 ).
+ *
+ * @return The sample height which is then scaled and offset using the
+ * values specified when the heightfield data was created.
+ *
+ * @ingroup collide
+ */
+typedef dReal dHeightfieldGetHeight( void* p_user_data, int x, int z );
+
+
+
+/**
+ * @brief Creates a heightfield geom.
+ *
+ * Uses the information in the given dHeightfieldDataID to construct
+ * a geom representing a heightfield in a collision space.
+ *
+ * @param space The space to add the geom to.
+ * @param data The dHeightfieldDataID created by dGeomHeightfieldDataCreate and
+ * setup by dGeomHeightfieldDataBuildCallback, dGeomHeightfieldDataBuildByte,
+ * dGeomHeightfieldDataBuildShort or dGeomHeightfieldDataBuildFloat.
+ * @param bPlaceable If non-zero this geom can be transformed in the world using the
+ * usual functions such as dGeomSetPosition and dGeomSetRotation. If the geom is
+ * not set as placeable, then it uses a fixed orientation where the global y axis
+ * represents the dynamic 'height' of the heightfield.
+ *
+ * @return A geom id to reference this geom in other calls.
+ *
+ * @ingroup collide
+ */
+ODE_API dGeomID dCreateHeightfield( dSpaceID space,
+                                       dHeightfieldDataID data, int bPlaceable );
+
+
+/**
+ * @brief Creates a new empty dHeightfieldDataID.
+ *
+ * Allocates a new dHeightfieldDataID and returns it. You must call
+ * dGeomHeightfieldDataDestroy to destroy it after the geom has been removed.
+ * The dHeightfieldDataID value is used when specifying a data format type.
+ *
+ * @return A dHeightfieldDataID for use with dGeomHeightfieldDataBuildCallback,
+ * dGeomHeightfieldDataBuildByte, dGeomHeightfieldDataBuildShort or
+ * dGeomHeightfieldDataBuildFloat.
+ * @ingroup collide
+ */
+ODE_API dHeightfieldDataID dGeomHeightfieldDataCreate(void);
+
+
+/**
+ * @brief Destroys a dHeightfieldDataID.
+ *
+ * Deallocates a given dHeightfieldDataID and all managed resources.
+ *
+ * @param d A dHeightfieldDataID created by dGeomHeightfieldDataCreate
+ * @ingroup collide
+ */
+ODE_API void dGeomHeightfieldDataDestroy( dHeightfieldDataID d );
+
+
+
+/**
+ * @brief Configures a dHeightfieldDataID to use a callback to
+ * retrieve height data.
+ *
+ * Before a dHeightfieldDataID can be used by a geom it must be
+ * configured to specify the format of the height data.
+ * This call specifies that the heightfield data is computed by
+ * the user and it should use the given callback when determining
+ * the height of a given element of it's shape.
+ *
+ * @param d A new dHeightfieldDataID created by dGeomHeightfieldDataCreate
+ *
+ * @param width Specifies the total 'width' of the heightfield along
+ * the geom's local x axis.
+ * @param depth Specifies the total 'depth' of the heightfield along
+ * the geom's local z axis.
+ *
+ * @param widthSamples Specifies the number of vertices to sample
+ * along the width of the heightfield. Each vertex has a corresponding
+ * height value which forms the overall shape.
+ * Naturally this value must be at least two or more.
+ * @param depthSamples Specifies the number of vertices to sample
+ * along the depth of the heightfield.
+ *
+ * @param scale A uniform scale applied to all raw height data.
+ * @param offset An offset applied to the scaled height data.
+ *
+ * @param thickness A value subtracted from the lowest height
+ * value which in effect adds an additional cuboid to the base of the
+ * heightfield. This is used to prevent geoms from looping under the
+ * desired terrain and not registering as a collision. Note that the
+ * thickness is not affected by the scale or offset parameters.
+ *
+ * @param bWrap If non-zero the heightfield will infinitely tile in both
+ * directions along the local x and z axes. If zero the heightfield is
+ * bounded from zero to width in the local x axis, and zero to depth in
+ * the local z axis.
+ *
+ * @ingroup collide
+ */
+ODE_API void dGeomHeightfieldDataBuildCallback( dHeightfieldDataID d,
+                               void* pUserData, dHeightfieldGetHeight* pCallback,
+                               dReal width, dReal depth, int widthSamples, int depthSamples,
+                               dReal scale, dReal offset, dReal thickness, int bWrap );
+
+/**
+ * @brief Configures a dHeightfieldDataID to use height data in byte format.
+ *
+ * Before a dHeightfieldDataID can be used by a geom it must be
+ * configured to specify the format of the height data.
+ * This call specifies that the heightfield data is stored as a rectangular
+ * array of bytes (8 bit unsigned) representing the height at each sample point.
+ *
+ * @param d A new dHeightfieldDataID created by dGeomHeightfieldDataCreate
+ *
+ * @param pHeightData A pointer to the height data.
+ * @param bCopyHeightData When non-zero the height data is copied to an
+ * internal store. When zero the height data is accessed by reference and
+ * so must persist throughout the lifetime of the heightfield.
+ *
+ * @param width Specifies the total 'width' of the heightfield along
+ * the geom's local x axis.
+ * @param depth Specifies the total 'depth' of the heightfield along
+ * the geom's local z axis.
+ *
+ * @param widthSamples Specifies the number of vertices to sample
+ * along the width of the heightfield. Each vertex has a corresponding
+ * height value which forms the overall shape.
+ * Naturally this value must be at least two or more.
+ * @param depthSamples Specifies the number of vertices to sample
+ * along the depth of the heightfield.
+ *
+ * @param scale A uniform scale applied to all raw height data.
+ * @param offset An offset applied to the scaled height data.
+ *
+ * @param thickness A value subtracted from the lowest height
+ * value which in effect adds an additional cuboid to the base of the
+ * heightfield. This is used to prevent geoms from looping under the
+ * desired terrain and not registering as a collision. Note that the
+ * thickness is not affected by the scale or offset parameters.
+ *
+ * @param bWrap If non-zero the heightfield will infinitely tile in both
+ * directions along the local x and z axes. If zero the heightfield is
+ * bounded from zero to width in the local x axis, and zero to depth in
+ * the local z axis.
+ *
+ * @ingroup collide
+ */
+ODE_API void dGeomHeightfieldDataBuildByte( dHeightfieldDataID d,
+                               const unsigned char* pHeightData, int bCopyHeightData,
+                               dReal width, dReal depth, int widthSamples, int depthSamples,
+                               dReal scale, dReal offset, dReal thickness,     int bWrap );
+
+/**
+ * @brief Configures a dHeightfieldDataID to use height data in short format.
+ *
+ * Before a dHeightfieldDataID can be used by a geom it must be
+ * configured to specify the format of the height data.
+ * This call specifies that the heightfield data is stored as a rectangular
+ * array of shorts (16 bit signed) representing the height at each sample point.
+ *
+ * @param d A new dHeightfieldDataID created by dGeomHeightfieldDataCreate
+ *
+ * @param pHeightData A pointer to the height data.
+ * @param bCopyHeightData When non-zero the height data is copied to an
+ * internal store. When zero the height data is accessed by reference and
+ * so must persist throughout the lifetime of the heightfield.
+ *
+ * @param width Specifies the total 'width' of the heightfield along
+ * the geom's local x axis.
+ * @param depth Specifies the total 'depth' of the heightfield along
+ * the geom's local z axis.
+ *
+ * @param widthSamples Specifies the number of vertices to sample
+ * along the width of the heightfield. Each vertex has a corresponding
+ * height value which forms the overall shape.
+ * Naturally this value must be at least two or more.
+ * @param depthSamples Specifies the number of vertices to sample
+ * along the depth of the heightfield.
+ *
+ * @param scale A uniform scale applied to all raw height data.
+ * @param offset An offset applied to the scaled height data.
+ *
+ * @param thickness A value subtracted from the lowest height
+ * value which in effect adds an additional cuboid to the base of the
+ * heightfield. This is used to prevent geoms from looping under the
+ * desired terrain and not registering as a collision. Note that the
+ * thickness is not affected by the scale or offset parameters.
+ *
+ * @param bWrap If non-zero the heightfield will infinitely tile in both
+ * directions along the local x and z axes. If zero the heightfield is
+ * bounded from zero to width in the local x axis, and zero to depth in
+ * the local z axis.
+ *
+ * @ingroup collide
+ */
+ODE_API void dGeomHeightfieldDataBuildShort( dHeightfieldDataID d,
+                               const short* pHeightData, int bCopyHeightData,
+                               dReal width, dReal depth, int widthSamples, int depthSamples,
+                               dReal scale, dReal offset, dReal thickness, int bWrap );
+
+/**
+ * @brief Configures a dHeightfieldDataID to use height data in 
+ * single precision floating point format.
+ *
+ * Before a dHeightfieldDataID can be used by a geom it must be
+ * configured to specify the format of the height data.
+ * This call specifies that the heightfield data is stored as a rectangular
+ * array of single precision floats representing the height at each
+ * sample point.
+ *
+ * @param d A new dHeightfieldDataID created by dGeomHeightfieldDataCreate
+ *
+ * @param pHeightData A pointer to the height data.
+ * @param bCopyHeightData When non-zero the height data is copied to an
+ * internal store. When zero the height data is accessed by reference and
+ * so must persist throughout the lifetime of the heightfield.
+ *
+ * @param width Specifies the total 'width' of the heightfield along
+ * the geom's local x axis.
+ * @param depth Specifies the total 'depth' of the heightfield along
+ * the geom's local z axis.
+ *
+ * @param widthSamples Specifies the number of vertices to sample
+ * along the width of the heightfield. Each vertex has a corresponding
+ * height value which forms the overall shape.
+ * Naturally this value must be at least two or more.
+ * @param depthSamples Specifies the number of vertices to sample
+ * along the depth of the heightfield.
+ *
+ * @param scale A uniform scale applied to all raw height data.
+ * @param offset An offset applied to the scaled height data.
+ *
+ * @param thickness A value subtracted from the lowest height
+ * value which in effect adds an additional cuboid to the base of the
+ * heightfield. This is used to prevent geoms from looping under the
+ * desired terrain and not registering as a collision. Note that the
+ * thickness is not affected by the scale or offset parameters.
+ *
+ * @param bWrap If non-zero the heightfield will infinitely tile in both
+ * directions along the local x and z axes. If zero the heightfield is
+ * bounded from zero to width in the local x axis, and zero to depth in
+ * the local z axis.
+ *
+ * @ingroup collide
+ */
+ODE_API void dGeomHeightfieldDataBuildSingle( dHeightfieldDataID d,
+                               const float* pHeightData, int bCopyHeightData,
+                               dReal width, dReal depth, int widthSamples, int depthSamples,
+                               dReal scale, dReal offset, dReal thickness, int bWrap );
+
+/**
+ * @brief Configures a dHeightfieldDataID to use height data in 
+ * double precision floating point format.
+ *
+ * Before a dHeightfieldDataID can be used by a geom it must be
+ * configured to specify the format of the height data.
+ * This call specifies that the heightfield data is stored as a rectangular
+ * array of double precision floats representing the height at each
+ * sample point.
+ *
+ * @param d A new dHeightfieldDataID created by dGeomHeightfieldDataCreate
+ *
+ * @param pHeightData A pointer to the height data.
+ * @param bCopyHeightData When non-zero the height data is copied to an
+ * internal store. When zero the height data is accessed by reference and
+ * so must persist throughout the lifetime of the heightfield.
+ *
+ * @param width Specifies the total 'width' of the heightfield along
+ * the geom's local x axis.
+ * @param depth Specifies the total 'depth' of the heightfield along
+ * the geom's local z axis.
+ *
+ * @param widthSamples Specifies the number of vertices to sample
+ * along the width of the heightfield. Each vertex has a corresponding
+ * height value which forms the overall shape.
+ * Naturally this value must be at least two or more.
+ * @param depthSamples Specifies the number of vertices to sample
+ * along the depth of the heightfield.
+ *
+ * @param scale A uniform scale applied to all raw height data.
+ * @param offset An offset applied to the scaled height data.
+ *
+ * @param thickness A value subtracted from the lowest height
+ * value which in effect adds an additional cuboid to the base of the
+ * heightfield. This is used to prevent geoms from looping under the
+ * desired terrain and not registering as a collision. Note that the
+ * thickness is not affected by the scale or offset parameters.
+ *
+ * @param bWrap If non-zero the heightfield will infinitely tile in both
+ * directions along the local x and z axes. If zero the heightfield is
+ * bounded from zero to width in the local x axis, and zero to depth in
+ * the local z axis.
+ *
+ * @ingroup collide
+ */
+ODE_API void dGeomHeightfieldDataBuildDouble( dHeightfieldDataID d,
+                               const double* pHeightData, int bCopyHeightData,
+                               dReal width, dReal depth, int widthSamples, int depthSamples,
+                               dReal scale, dReal offset, dReal thickness, int bWrap );
+
+/**
+ * @brief Manually set the minimum and maximum height bounds.
+ *
+ * This call allows you to set explicit min / max values after initial
+ * creation typically for callback heightfields which default to +/- infinity,
+ * or those whose data has changed. This must be set prior to binding with a
+ * geom, as the the AABB is not recomputed after it's first generation.
+ *
+ * @remarks The minimum and maximum values are used to compute the AABB
+ * for the heightfield which is used for early rejection of collisions.
+ * A close fit will yield a more efficient collision check.
+ *
+ * @param d A dHeightfieldDataID created by dGeomHeightfieldDataCreate
+ * @param min_height The new minimum height value. Scale, offset and thickness is then applied.
+ * @param max_height The new maximum height value. Scale and offset is then applied.
+ * @ingroup collide
+ */
+ODE_API void dGeomHeightfieldDataSetBounds( dHeightfieldDataID d,
+                               dReal minHeight, dReal maxHeight );
+
+
+/**
+ * @brief Assigns a dHeightfieldDataID to a heightfield geom.
+ *
+ * Associates the given dHeightfieldDataID with a heightfield geom.
+ * This is done without affecting the GEOM_PLACEABLE flag.
+ *
+ * @param g A geom created by dCreateHeightfield
+ * @param d A dHeightfieldDataID created by dGeomHeightfieldDataCreate
+ * @ingroup collide
+ */
+ODE_API void dGeomHeightfieldSetHeightfieldData( dGeomID g, dHeightfieldDataID d );
+
+
+/**
+ * @brief Gets the dHeightfieldDataID bound to a heightfield geom.
+ *
+ * Returns the dHeightfieldDataID associated with a heightfield geom.
+ *
+ * @param g A geom created by dCreateHeightfield
+ * @return The dHeightfieldDataID which may be NULL if none was assigned.
+ * @ingroup collide
+ */
+ODE_API dHeightfieldDataID dGeomHeightfieldGetHeightfieldData( dGeomID g );
+
+
+
+/* ************************************************************************ */
+/* utility functions */
+
+ODE_API void dClosestLineSegmentPoints (const dVector3 a1, const dVector3 a2,
+                               const dVector3 b1, const dVector3 b2,
+                               dVector3 cp1, dVector3 cp2);
+
+ODE_API int dBoxTouchesBox (const dVector3 _p1, const dMatrix3 R1,
+                   const dVector3 side1, const dVector3 _p2,
+                   const dMatrix3 R2, const dVector3 side2);
+
+// The meaning of flags parameter is the same as in dCollide()
+ODE_API int dBoxBox (const dVector3 p1, const dMatrix3 R1,
+            const dVector3 side1, const dVector3 p2,
+            const dMatrix3 R2, const dVector3 side2,
+            dVector3 normal, dReal *depth, int *return_code,
+            int flags, dContactGeom *contact, int skip);
+
+ODE_API void dInfiniteAABB (dGeomID geom, dReal aabb[6]);
+
+
+/* ************************************************************************ */
+/* custom classes */
+
+typedef void dGetAABBFn (dGeomID, dReal aabb[6]);
+typedef int dColliderFn (dGeomID o1, dGeomID o2,
+                        int flags, dContactGeom *contact, int skip);
+typedef dColliderFn * dGetColliderFnFn (int num);
+typedef void dGeomDtorFn (dGeomID o);
+typedef int dAABBTestFn (dGeomID o1, dGeomID o2, dReal aabb[6]);
+
+typedef struct dGeomClass {
+  int bytes;
+  dGetColliderFnFn *collider;
+  dGetAABBFn *aabb;
+  dAABBTestFn *aabb_test;
+  dGeomDtorFn *dtor;
+} dGeomClass;
+
+ODE_API int dCreateGeomClass (const dGeomClass *classptr);
+ODE_API void * dGeomGetClassData (dGeomID);
+ODE_API dGeomID dCreateGeom (int classnum);
+
+/**
+ * @brief Sets a custom collider function for two geom classes. 
+ *
+ * @param i The first geom class handled by this collider
+ * @param j The second geom class handled by this collider
+ * @param fn The collider function to use to determine collisions.
+ * @ingroup collide
+ */
+ODE_API void dSetColliderOverride (int i, int j, dColliderFn *fn);
+
+
+/* ************************************************************************ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/misc/builddeps/dp.linux64/include/ode/collision_space.h b/misc/builddeps/dp.linux64/include/ode/collision_space.h
new file mode 100644 (file)
index 0000000..bf7ef9b
--- /dev/null
@@ -0,0 +1,182 @@
+/*************************************************************************
+ *                                                                       *
+ * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith.       *
+ * All rights reserved.  Email: russ@q12.org   Web: www.q12.org          *
+ *                                                                       *
+ * This library is free software; you can redistribute it and/or         *
+ * modify it under the terms of EITHER:                                  *
+ *   (1) The GNU Lesser General Public License as published by the Free  *
+ *       Software Foundation; either version 2.1 of the License, or (at  *
+ *       your option) any later version. The text of the GNU Lesser      *
+ *       General Public License is included with this library in the     *
+ *       file LICENSE.TXT.                                               *
+ *   (2) The BSD-style license that is included with this library in     *
+ *       the file LICENSE-BSD.TXT.                                       *
+ *                                                                       *
+ * This library is distributed in the hope that it will be useful,       *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files    *
+ * LICENSE.TXT and LICENSE-BSD.TXT for more details.                     *
+ *                                                                       *
+ *************************************************************************/
+
+#ifndef _ODE_COLLISION_SPACE_H_
+#define _ODE_COLLISION_SPACE_H_
+
+#include <ode/common.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct dContactGeom;
+
+/**
+ * @brief User callback for geom-geom collision testing.
+ *
+ * @param data The user data object, as passed to dSpaceCollide.
+ * @param o1   The first geom being tested.
+ * @param o2   The second geom being test.
+ *
+ * @remarks The callback function can call dCollide on o1 and o2 to generate
+ * contact points between each pair. Then these contact points may be added
+ * to the simulation as contact joints. The user's callback function can of
+ * course chose not to call dCollide for any pair, e.g. if the user decides
+ * that those pairs should not interact.
+ *
+ * @ingroup collide
+ */
+typedef void dNearCallback (void *data, dGeomID o1, dGeomID o2);
+
+
+ODE_API dSpaceID dSimpleSpaceCreate (dSpaceID space);
+ODE_API dSpaceID dHashSpaceCreate (dSpaceID space);
+ODE_API dSpaceID dQuadTreeSpaceCreate (dSpaceID space, const dVector3 Center, const dVector3 Extents, int Depth);
+
+
+// SAP
+// Order XZY or ZXY usually works best, if your Y is up.
+#define dSAP_AXES_XYZ  ((0)|(1<<2)|(2<<4))
+#define dSAP_AXES_XZY  ((0)|(2<<2)|(1<<4))
+#define dSAP_AXES_YXZ  ((1)|(0<<2)|(2<<4))
+#define dSAP_AXES_YZX  ((1)|(2<<2)|(0<<4))
+#define dSAP_AXES_ZXY  ((2)|(0<<2)|(1<<4))
+#define dSAP_AXES_ZYX  ((2)|(1<<2)|(0<<4))
+
+ODE_API dSpaceID dSweepAndPruneSpaceCreate( dSpaceID space, int axisorder );
+
+
+
+ODE_API void dSpaceDestroy (dSpaceID);
+
+ODE_API void dHashSpaceSetLevels (dSpaceID space, int minlevel, int maxlevel);
+ODE_API void dHashSpaceGetLevels (dSpaceID space, int *minlevel, int *maxlevel);
+
+ODE_API void dSpaceSetCleanup (dSpaceID space, int mode);
+ODE_API int dSpaceGetCleanup (dSpaceID space);
+
+/**
+* @brief Sets sublevel value for a space.
+*
+* Sublevel affects how the space is handled in dSpaceCollide2 when it is collided
+* with another space. If sublevels of both spaces match, the function iterates 
+* geometries of both spaces and collides them with each other. If sublevel of one
+* space is greater than the sublevel of another one, only the geometries of the 
+* space with greater sublevel are iterated, another space is passed into 
+* collision callback as a geometry itself. By default all the spaces are assigned
+* zero sublevel.
+*
+* @note
+* The space sublevel @e IS @e NOT automatically updated when one space is inserted
+* into another or removed from one. It is a client's responsibility to update sublevel
+* value if necessary.
+*
+* @param space the space to modify
+* @param sublevel the sublevel value to be assigned
+* @ingroup collide
+* @see dSpaceGetSublevel
+* @see dSpaceCollide2
+*/
+ODE_API void dSpaceSetSublevel (dSpaceID space, int sublevel);
+
+/**
+* @brief Gets sublevel value of a space.
+*
+* Sublevel affects how the space is handled in dSpaceCollide2 when it is collided
+* with another space. See @c dSpaceSetSublevel for more details.
+*
+* @param space the space to query
+* @returns the sublevel value of the space
+* @ingroup collide
+* @see dSpaceSetSublevel
+* @see dSpaceCollide2
+*/
+ODE_API int dSpaceGetSublevel (dSpaceID space);
+
+
+/**
+* @brief Sets manual cleanup flag for a space.
+*
+* Manual cleanup flag marks a space as eligible for manual thread data cleanup.
+* This function should be called for every space object right after creation in 
+* case if ODE has been initialized with @c dInitFlagManualThreadCleanup flag.
+* 
+* Failure to set manual cleanup flag for a space may lead to some resources 
+* remaining leaked until the program exit.
+*
+* @param space the space to modify
+* @param mode 1 for manual cleanup mode and 0 for default cleanup mode
+* @ingroup collide
+* @see dSpaceGetManualCleanup
+* @see dInitODE2
+*/
+ODE_API void dSpaceSetManualCleanup (dSpaceID space, int mode);
+
+/**
+* @brief Get manual cleanup flag of a space.
+*
+* Manual cleanup flag marks a space space as eligible for manual thread data cleanup.
+* See @c dSpaceSetManualCleanup for more details.
+* 
+* @param space the space to query
+* @returns 1 for manual cleanup mode and 0 for default cleanup mode of the space
+* @ingroup collide
+* @see dSpaceSetManualCleanup
+* @see dInitODE2
+*/
+ODE_API int dSpaceGetManualCleanup (dSpaceID space);
+
+ODE_API void dSpaceAdd (dSpaceID, dGeomID);
+ODE_API void dSpaceRemove (dSpaceID, dGeomID);
+ODE_API int dSpaceQuery (dSpaceID, dGeomID);
+ODE_API void dSpaceClean (dSpaceID);
+ODE_API int dSpaceGetNumGeoms (dSpaceID);
+ODE_API dGeomID dSpaceGetGeom (dSpaceID, int i);
+
+/**
+ * @brief Given a space, this returns its class.
+ *
+ * The ODE classes are:
+ *  @li dSimpleSpaceClass
+ *  @li dHashSpaceClass
+ *  @li dSweepAndPruneSpaceClass
+ *  @li dQuadTreeSpaceClass
+ *  @li dFirstUserClass
+ *  @li dLastUserClass
+ *
+ * The class id not defined by the user should be between
+ * dFirstSpaceClass and dLastSpaceClass.
+ *
+ * User-defined class will return their own number.
+ *
+ * @param space the space to query
+ * @returns The space class ID.
+ * @ingroup collide
+ */
+ODE_API int dSpaceGetClass(dSpaceID space);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/misc/builddeps/dp.linux64/include/ode/collision_trimesh.h b/misc/builddeps/dp.linux64/include/ode/collision_trimesh.h
new file mode 100644 (file)
index 0000000..f263a9e
--- /dev/null
@@ -0,0 +1,216 @@
+/*************************************************************************
+ *                                                                       *
+ * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith.       *
+ * All rights reserved.  Email: russ@q12.org   Web: www.q12.org          *
+ *                                                                       *
+ * This library is free software; you can redistribute it and/or         *
+ * modify it under the terms of EITHER:                                  *
+ *   (1) The GNU Lesser General Public License as published by the Free  *
+ *       Software Foundation; either version 2.1 of the License, or (at  *
+ *       your option) any later version. The text of the GNU Lesser      *
+ *       General Public License is included with this library in the     *
+ *       file LICENSE.TXT.                                               *
+ *   (2) The BSD-style license that is included with this library in     *
+ *       the file LICENSE-BSD.TXT.                                       *
+ *                                                                       *
+ * This library is distributed in the hope that it will be useful,       *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files    *
+ * LICENSE.TXT and LICENSE-BSD.TXT for more details.                     *
+ *                                                                       *
+ *************************************************************************/
+
+/*
+ * TriMesh code by Erwin de Vries.
+ *
+ * Trimesh data.
+ * This is where the actual vertexdata (pointers), and BV tree is stored.
+ * Vertices should be single precision!
+ * This should be more sophisticated, so that the user can easyly implement
+ * another collision library, but this is a lot of work, and also costs some
+ * performance because some data has to be copied.
+ */
+
+#ifndef _ODE_COLLISION_TRIMESH_H_
+#define _ODE_COLLISION_TRIMESH_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Data storage for triangle meshes.
+ */
+struct dxTriMeshData;
+typedef struct dxTriMeshData* dTriMeshDataID;
+
+/*
+ * These dont make much sense now, but they will later when we add more
+ * features.
+ */
+ODE_API dTriMeshDataID dGeomTriMeshDataCreate(void);
+ODE_API void dGeomTriMeshDataDestroy(dTriMeshDataID g);
+
+
+
+enum { TRIMESH_FACE_NORMALS };
+ODE_API void dGeomTriMeshDataSet(dTriMeshDataID g, int data_id, void* in_data);
+ODE_API void* dGeomTriMeshDataGet(dTriMeshDataID g, int data_id);
+
+
+
+/**
+ * We need to set the last transform after each time step for 
+ * accurate collision response. These functions get and set that transform.
+ * It is stored per geom instance, rather than per dTriMeshDataID.
+ */
+ODE_API void dGeomTriMeshSetLastTransform( dGeomID g, dMatrix4 last_trans );
+ODE_API dReal* dGeomTriMeshGetLastTransform( dGeomID g );
+
+/*
+ * Build a TriMesh data object with single precision vertex data.
+ */
+ODE_API void dGeomTriMeshDataBuildSingle(dTriMeshDataID g,
+                                 const void* Vertices, int VertexStride, int VertexCount, 
+                                 const void* Indices, int IndexCount, int TriStride);
+/* same again with a normals array (used as trimesh-trimesh optimization) */
+ODE_API void dGeomTriMeshDataBuildSingle1(dTriMeshDataID g,
+                                  const void* Vertices, int VertexStride, int VertexCount, 
+                                  const void* Indices, int IndexCount, int TriStride,
+                                  const void* Normals);
+/*
+* Build a TriMesh data object with double precision vertex data.
+*/
+ODE_API void dGeomTriMeshDataBuildDouble(dTriMeshDataID g, 
+                                 const void* Vertices,  int VertexStride, int VertexCount, 
+                                 const void* Indices, int IndexCount, int TriStride);
+/* same again with a normals array (used as trimesh-trimesh optimization) */
+ODE_API void dGeomTriMeshDataBuildDouble1(dTriMeshDataID g, 
+                                  const void* Vertices,  int VertexStride, int VertexCount, 
+                                  const void* Indices, int IndexCount, int TriStride,
+                                  const void* Normals);
+
+/*
+ * Simple build. Single/double precision based on dSINGLE/dDOUBLE!
+ */
+ODE_API void dGeomTriMeshDataBuildSimple(dTriMeshDataID g,
+                                 const dReal* Vertices, int VertexCount,
+                                 const dTriIndex* Indices, int IndexCount);
+/* same again with a normals array (used as trimesh-trimesh optimization) */
+ODE_API void dGeomTriMeshDataBuildSimple1(dTriMeshDataID g,
+                                  const dReal* Vertices, int VertexCount,
+                                  const dTriIndex* Indices, int IndexCount,
+                                  const int* Normals);
+
+/* Preprocess the trimesh data to remove mark unnecessary edges and vertices */
+ODE_API void dGeomTriMeshDataPreprocess(dTriMeshDataID g);
+/* Get and set the internal preprocessed trimesh data buffer, for loading and saving */
+ODE_API void dGeomTriMeshDataGetBuffer(dTriMeshDataID g, unsigned char** buf, int* bufLen);
+ODE_API void dGeomTriMeshDataSetBuffer(dTriMeshDataID g, unsigned char* buf);
+
+
+/*
+ * Per triangle callback. Allows the user to say if he wants a collision with
+ * a particular triangle.
+ */
+typedef int dTriCallback(dGeomID TriMesh, dGeomID RefObject, int TriangleIndex);
+ODE_API void dGeomTriMeshSetCallback(dGeomID g, dTriCallback* Callback);
+ODE_API dTriCallback* dGeomTriMeshGetCallback(dGeomID g);
+
+/*
+ * Per object callback. Allows the user to get the list of triangles in 1
+ * shot. Maybe we should remove this one.
+ */
+typedef void dTriArrayCallback(dGeomID TriMesh, dGeomID RefObject, const int* TriIndices, int TriCount);
+ODE_API void dGeomTriMeshSetArrayCallback(dGeomID g, dTriArrayCallback* ArrayCallback);
+ODE_API dTriArrayCallback* dGeomTriMeshGetArrayCallback(dGeomID g);
+
+/*
+ * Ray callback.
+ * 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 transparency
+ * to determine if a collision should occur.
+ */
+typedef int dTriRayCallback(dGeomID TriMesh, dGeomID Ray, int TriangleIndex, dReal u, dReal v);
+ODE_API void dGeomTriMeshSetRayCallback(dGeomID g, dTriRayCallback* Callback);
+ODE_API dTriRayCallback* dGeomTriMeshGetRayCallback(dGeomID g);
+
+/*
+ * Triangle merging callback.
+ * Allows the user to generate a fake triangle index for a new contact generated
+ * from merging of two other contacts. That index could later be used by the 
+ * user to determine attributes of original triangles used as sources for a 
+ * merged contact.
+ */
+typedef int dTriTriMergeCallback(dGeomID TriMesh, int FirstTriangleIndex, int SecondTriangleIndex);
+ODE_API void dGeomTriMeshSetTriMergeCallback(dGeomID g, dTriTriMergeCallback* Callback);
+ODE_API dTriTriMergeCallback* dGeomTriMeshGetTriMergeCallback(dGeomID g);
+
+/*
+ * Trimesh class
+ * Construction. Callbacks are optional.
+ */
+ODE_API dGeomID dCreateTriMesh(dSpaceID space, dTriMeshDataID Data, dTriCallback* Callback, dTriArrayCallback* ArrayCallback, dTriRayCallback* RayCallback);
+
+ODE_API void dGeomTriMeshSetData(dGeomID g, dTriMeshDataID Data);
+ODE_API dTriMeshDataID dGeomTriMeshGetData(dGeomID g);
+
+
+// enable/disable/check temporal coherence
+ODE_API void dGeomTriMeshEnableTC(dGeomID g, int geomClass, int enable);
+ODE_API int dGeomTriMeshIsTCEnabled(dGeomID g, int geomClass);
+
+/*
+ * Clears the internal temporal coherence caches. When a geom has its
+ * 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.
+ * We should be able to do this automagically.
+ */
+ODE_API void dGeomTriMeshClearTCCache(dGeomID g);
+
+
+/*
+ * returns the TriMeshDataID
+ */
+ODE_API dTriMeshDataID dGeomTriMeshGetTriMeshDataID(dGeomID g);
+
+/*
+ * Gets a triangle.
+ */
+ODE_API void dGeomTriMeshGetTriangle(dGeomID g, int Index, dVector3* v0, dVector3* v1, dVector3* v2);
+
+/*
+ * Gets the point on the requested triangle and the given barycentric
+ * coordinates.
+ */
+ODE_API void dGeomTriMeshGetPoint(dGeomID g, int Index, dReal u, dReal v, dVector3 Out);
+
+/*
+
+This is how the strided data works:
+
+struct StridedVertex{
+       dVector3 Vertex;
+       // Userdata
+};
+int VertexStride = sizeof(StridedVertex);
+
+struct StridedTri{
+       int Indices[3];
+       // Userdata
+};
+int TriStride = sizeof(StridedTri);
+
+*/
+
+
+ODE_API int dGeomTriMeshGetTriangleCount (dGeomID g);
+
+ODE_API void dGeomTriMeshDataUpdate(dTriMeshDataID g);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _ODE_COLLISION_TRIMESH_H_ */
+
diff --git a/misc/builddeps/dp.linux64/include/ode/common.h b/misc/builddeps/dp.linux64/include/ode/common.h
new file mode 100644 (file)
index 0000000..d7b2bba
--- /dev/null
@@ -0,0 +1,420 @@
+/*************************************************************************
+ *                                                                       *
+ * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith.       *
+ * All rights reserved.  Email: russ@q12.org   Web: www.q12.org          *
+ *                                                                       *
+ * This library is free software; you can redistribute it and/or         *
+ * modify it under the terms of EITHER:                                  *
+ *   (1) The GNU Lesser General Public License as published by the Free  *
+ *       Software Foundation; either version 2.1 of the License, or (at  *
+ *       your option) any later version. The text of the GNU Lesser      *
+ *       General Public License is included with this library in the     *
+ *       file LICENSE.TXT.                                               *
+ *   (2) The BSD-style license that is included with this library in     *
+ *       the file LICENSE-BSD.TXT.                                       *
+ *                                                                       *
+ * This library is distributed in the hope that it will be useful,       *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files    *
+ * LICENSE.TXT and LICENSE-BSD.TXT for more details.                     *
+ *                                                                       *
+ *************************************************************************/
+
+#ifndef _ODE_COMMON_H_
+#define _ODE_COMMON_H_
+#include <ode/odeconfig.h>
+#include <ode/error.h>
+#include <math.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#define PURE_INLINE static __inline
+
+
+/* configuration stuff */
+
+/* constants */
+
+/* pi and 1/sqrt(2) are defined here if necessary because they don't get
+ * defined in <math.h> on some platforms (like MS-Windows)
+ */
+
+#ifndef M_PI
+#define M_PI REAL(3.1415926535897932384626433832795029)
+#endif
+#ifndef M_SQRT1_2
+#define M_SQRT1_2 REAL(0.7071067811865475244008443621048490)
+#endif
+
+
+/* debugging:
+ *   IASSERT  is an internal assertion, i.e. a consistency check. if it fails
+ *            we want to know where.
+ *   UASSERT  is a user assertion, i.e. if it fails a nice error message
+ *            should be printed for the user.
+ *   AASSERT  is an arguments assertion, i.e. if it fails "bad argument(s)"
+ *            is printed.
+ *   DEBUGMSG just prints out a message
+ */
+
+#  if defined(__STDC__) && __STDC_VERSION__ >= 199901L
+#    define __FUNCTION__ __func__
+#  endif
+#ifndef dNODEBUG
+#  ifdef __GNUC__
+#    define dIASSERT(a) { if (!(a)) { dDebug (d_ERR_IASSERT, \
+      "assertion \"" #a "\" failed in %s() [%s:%u]",__FUNCTION__,__FILE__,__LINE__); } }
+#    define dUASSERT(a,msg) { if (!(a)) { dDebug (d_ERR_UASSERT, \
+      msg " in %s()", __FUNCTION__); } }
+#    define dDEBUGMSG(msg) { dMessage (d_ERR_UASSERT,                          \
+  msg " in %s() [%s:%u]", __FUNCTION__,__FILE__,__LINE__); }
+#  else // not __GNUC__
+#    define dIASSERT(a) { if (!(a)) { dDebug (d_ERR_IASSERT, \
+      "assertion \"" #a "\" failed in %s:%u",__FILE__,__LINE__); } }
+#    define dUASSERT(a,msg) { if (!(a)) { dDebug (d_ERR_UASSERT, \
+      msg " (%s:%u)", __FILE__,__LINE__); } }
+#    define dDEBUGMSG(msg) { dMessage (d_ERR_UASSERT, \
+      msg " (%s:%u)", __FILE__,__LINE__); }
+#  endif
+#  define dIVERIFY(a) dIASSERT(a)
+#else
+#  define dIASSERT(a) ((void)0)
+#  define dUASSERT(a,msg) ((void)0)
+#  define dDEBUGMSG(msg) ((void)0)
+#  define dIVERIFY(a) ((void)(a))
+#endif
+
+#  ifdef __GNUC__
+#    define dICHECK(a) { if (!(a)) { dDebug (d_ERR_IASSERT, \
+      "assertion \"" #a "\" failed in %s() [%s:%u]",__FUNCTION__,__FILE__,__LINE__); *(int *)0 = 0; } }
+#  else // not __GNUC__
+#    define dICHECK(a) { if (!(a)) { dDebug (d_ERR_IASSERT, \
+      "assertion \"" #a "\" failed in %s:%u",__FILE__,__LINE__); *(int *)0 = 0; } }
+#  endif
+
+// Argument assert is a special case of user assert
+#define dAASSERT(a) dUASSERT(a,"Bad argument(s)")
+
+/* floating point data type, vector, matrix and quaternion types */
+
+#if defined(dSINGLE)
+typedef float dReal;
+#ifdef dDOUBLE
+#error You can only #define dSINGLE or dDOUBLE, not both.
+#endif // dDOUBLE
+#elif defined(dDOUBLE)
+typedef double dReal;
+#else
+#error You must #define dSINGLE or dDOUBLE
+#endif
+
+// Detect if we've got both trimesh engines enabled.
+#if dTRIMESH_ENABLED
+#if dTRIMESH_OPCODE && dTRIMESH_GIMPACT
+#error You can only #define dTRIMESH_OPCODE or dTRIMESH_GIMPACT, not both.
+#endif
+#endif // dTRIMESH_ENABLED
+
+// Define a type for indices, either 16 or 32 bit, based on build option
+// TODO: Currently GIMPACT only supports 32 bit indices.
+#if dTRIMESH_16BIT_INDICES
+#if dTRIMESH_GIMPACT
+typedef uint32 dTriIndex;
+#else // dTRIMESH_GIMPACT
+typedef uint16 dTriIndex;
+#endif // dTRIMESH_GIMPACT
+#else // dTRIMESH_16BIT_INDICES
+typedef uint32 dTriIndex;
+#endif // dTRIMESH_16BIT_INDICES
+
+/* round an integer up to a multiple of 4, except that 0 and 1 are unmodified
+ * (used to compute matrix leading dimensions)
+ */
+#define dPAD(a) (((a) > 1) ? ((((a)-1)|3)+1) : (a))
+
+/* these types are mainly just used in headers */
+typedef dReal dVector3[4];
+typedef dReal dVector4[4];
+typedef dReal dMatrix3[4*3];
+typedef dReal dMatrix4[4*4];
+typedef dReal dMatrix6[8*6];
+typedef dReal dQuaternion[4];
+
+
+/* precision dependent scalar math functions */
+
+#if defined(dSINGLE)
+
+#define REAL(x) (x ## f)                                       /* form a constant */
+#define dRecip(x) ((1.0f/(x)))                         /* reciprocal */
+#define dSqrt(x) (sqrtf(x))                    /* square root */
+#define dRecipSqrt(x) ((1.0f/sqrtf(x)))                /* reciprocal square root */
+#define dSin(x) (sinf(x))                              /* sine */
+#define dCos(x) (cosf(x))                              /* cosine */
+#define dFabs(x) (fabsf(x))                    /* absolute value */
+#define dAtan2(y,x) (atan2f(y,x))              /* arc tangent with 2 args */
+#define dFMod(a,b) (fmodf(a,b))                /* modulo */
+#define dFloor(x) floorf(x)                    /* floor */
+#define dCeil(x) ceilf(x)                      /* floor */
+#define dCopySign(a,b) ((dReal)copysignf(a,b)) /* copy value sign */
+#define dNextAfter(x, y) nextafterf(x, y) /* next value after */
+
+#if defined(_ODE__NEXTAFTERF_REQUIRED)
+float _nextafterf(float x, float y);
+#endif
+
+#ifdef HAVE___ISNANF
+#define dIsNan(x) (__isnanf(x))
+#elif defined(HAVE__ISNANF)
+#define dIsNan(x) (_isnanf(x))
+#elif defined(HAVE_ISNANF)
+#define dIsNan(x) (isnanf(x))
+#else
+  /*
+     fall back to _isnan which is the VC way,
+     this may seem redundant since we already checked
+     for _isnan before, but if isnan is detected by
+     configure but is not found during compilation
+     we should always make sure we check for __isnanf,
+     _isnanf and isnanf in that order before falling
+     back to a default
+  */
+#define dIsNan(x) (_isnan(x))
+#endif
+
+#elif defined(dDOUBLE)
+
+#define REAL(x) (x)
+#define dRecip(x) (1.0/(x))
+#define dSqrt(x) sqrt(x)
+#define dRecipSqrt(x) (1.0/sqrt(x))
+#define dSin(x) sin(x)
+#define dCos(x) cos(x)
+#define dFabs(x) fabs(x)
+#define dAtan2(y,x) atan2((y),(x))
+#define dFMod(a,b) (fmod((a),(b)))
+#define dFloor(x) floor(x)
+#define dCeil(x) ceil(x)
+#define dCopySign(a,b) (copysign((a),(b)))
+#define dNextAfter(x, y) nextafter(x, y)
+
+#undef _ODE__NEXTAFTERF_REQUIRED
+
+#ifdef HAVE___ISNAN
+#define dIsNan(x) (__isnan(x))
+#elif defined(HAVE__ISNAN)
+#define dIsNan(x) (_isnan(x))
+#elif defined(HAVE_ISNAN)
+#define dIsNan(x) (isnan(x))
+#else
+#define dIsNan(x) (_isnan(x))
+#endif
+
+#else
+#error You must #define dSINGLE or dDOUBLE
+#endif
+
+/* internal object types (all prefixed with `dx') */
+
+struct dxWorld;                /* dynamics world */
+struct dxSpace;                /* collision space */
+struct dxBody;         /* rigid body (dynamics object) */
+struct dxGeom;         /* geometry (collision object) */
+struct dxJoint;
+struct dxJointNode;
+struct dxJointGroup;
+struct dxWorldProcessThreadingManager;
+
+typedef struct dxWorld *dWorldID;
+typedef struct dxSpace *dSpaceID;
+typedef struct dxBody *dBodyID;
+typedef struct dxGeom *dGeomID;
+typedef struct dxJoint *dJointID;
+typedef struct dxJointGroup *dJointGroupID;
+typedef struct dxWorldProcessThreadingManager *dWorldStepThreadingManagerID;
+
+/* error numbers */
+
+enum {
+  d_ERR_UNKNOWN = 0,           /* unknown error */
+  d_ERR_IASSERT,               /* internal assertion failed */
+  d_ERR_UASSERT,               /* user assertion failed */
+  d_ERR_LCP                    /* user assertion failed */
+};
+
+
+/* joint type numbers */
+
+typedef enum {
+  dJointTypeNone = 0,          /* or "unknown" */
+  dJointTypeBall,
+  dJointTypeHinge,
+  dJointTypeSlider,
+  dJointTypeContact,
+  dJointTypeUniversal,
+  dJointTypeHinge2,
+  dJointTypeFixed,
+  dJointTypeNull,
+  dJointTypeAMotor,
+  dJointTypeLMotor,
+  dJointTypePlane2D,
+  dJointTypePR,
+  dJointTypePU,
+  dJointTypePiston
+} dJointType;
+
+
+/* an alternative way of setting joint parameters, using joint parameter
+ * structures and member constants. we don't actually do this yet.
+ */
+
+/*
+typedef struct dLimot {
+  int mode;
+  dReal lostop, histop;
+  dReal vel, fmax;
+  dReal fudge_factor;
+  dReal bounce, soft;
+  dReal suspension_erp, suspension_cfm;
+} dLimot;
+
+enum {
+  dLimotLoStop         = 0x0001,
+  dLimotHiStop         = 0x0002,
+  dLimotVel            = 0x0004,
+  dLimotFMax           = 0x0008,
+  dLimotFudgeFactor    = 0x0010,
+  dLimotBounce         = 0x0020,
+  dLimotSoft           = 0x0040
+};
+*/
+
+
+/* standard joint parameter names. why are these here? - because we don't want
+ * to include all the joint function definitions in joint.cpp. hmmmm.
+ * MSVC complains if we call D_ALL_PARAM_NAMES_X with a blank second argument,
+ * which is why we have the D_ALL_PARAM_NAMES macro as well. please copy and
+ * paste between these two.
+ */
+
+#define D_ALL_PARAM_NAMES(start) \
+  /* parameters for limits and motors */ \
+  dParamLoStop = start, \
+  dParamHiStop, \
+  dParamVel, \
+  dParamFMax, \
+  dParamFudgeFactor, \
+  dParamBounce, \
+  dParamCFM, \
+  dParamStopERP, \
+  dParamStopCFM, \
+  /* parameters for suspension */ \
+  dParamSuspensionERP, \
+  dParamSuspensionCFM, \
+  dParamERP, \
+
+  //////////////////////////////////////////////////////////////////////////////
+  /// \enum  D_ALL_PARAM_NAMES_X
+  ///
+  /// \var dParamGroup This is the starting value of the different group
+  ///                  (i.e. dParamGroup1, dParamGroup2, dParamGroup3)
+  ///                  It also helps in the use of parameter
+  ///                  (dParamGroup2 | dParamFMax) == dParamFMax2
+  //////////////////////////////////////////////////////////////////////////////
+#define D_ALL_PARAM_NAMES_X(start,x) \
+  dParamGroup ## x = start, \
+  /* parameters for limits and motors */ \
+  dParamLoStop ## x = start, \
+  dParamHiStop ## x, \
+  dParamVel ## x, \
+  dParamFMax ## x, \
+  dParamFudgeFactor ## x, \
+  dParamBounce ## x, \
+  dParamCFM ## x, \
+  dParamStopERP ## x, \
+  dParamStopCFM ## x, \
+  /* parameters for suspension */ \
+  dParamSuspensionERP ## x, \
+  dParamSuspensionCFM ## x, \
+  dParamERP ## x,
+
+enum {
+  D_ALL_PARAM_NAMES(0)
+  dParamsInGroup,     ///< Number of parameter in a group
+  D_ALL_PARAM_NAMES_X(0x000,1)
+  D_ALL_PARAM_NAMES_X(0x100,2)
+  D_ALL_PARAM_NAMES_X(0x200,3)
+
+  /* add a multiple of this constant to the basic parameter numbers to get
+   * the parameters for the second, third etc axes.
+   */
+  dParamGroup=0x100
+};
+
+
+/* angular motor mode numbers */
+
+enum {
+  dAMotorUser = 0,
+  dAMotorEuler = 1
+};
+
+
+/* joint force feedback information */
+
+typedef struct dJointFeedback {
+  dVector3 f1;         /* force applied to body 1 */
+  dVector3 t1;         /* torque applied to body 1 */
+  dVector3 f2;         /* force applied to body 2 */
+  dVector3 t2;         /* torque applied to body 2 */
+} dJointFeedback;
+
+
+/* private functions that must be implemented by the collision library:
+ * (1) indicate that a geom has moved, (2) get the next geom in a body list.
+ * these functions are called whenever the position of geoms connected to a
+ * body have changed, e.g. with dBodySetPosition(), dBodySetRotation(), or
+ * when the ODE step function updates the body state.
+ */
+
+void dGeomMoved (dGeomID);
+dGeomID dGeomGetBodyNext (dGeomID);
+
+/**
+ * dGetConfiguration returns the specific ODE build configuration as
+ * a string of tokens. The string can be parsed in a similar way to
+ * the OpenGL extension mechanism, the naming convention should be
+ * familiar too. The following extensions are reported:
+ *
+ * ODE
+ * ODE_single_precision
+ * ODE_double_precision
+ * ODE_EXT_no_debug
+ * ODE_EXT_trimesh
+ * ODE_EXT_opcode
+ * ODE_EXT_gimpact
+ * ODE_EXT_malloc_not_alloca
+ * ODE_EXT_gyroscopic
+ * ODE_OPC_16bit_indices
+ * ODE_OPC_new_collider
+*/
+ODE_API const char* dGetConfiguration (void);
+
+/**
+ * Helper to check for a token in the ODE configuration string.
+ * Caution, this function is case sensitive.
+ *
+ * @param token A configuration token, see dGetConfiguration for details
+ *
+ * @return 1 if exact token is present, 0 if not present
+ */
+ODE_API int dCheckConfiguration( const char* token );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/misc/builddeps/dp.linux64/include/ode/compatibility.h b/misc/builddeps/dp.linux64/include/ode/compatibility.h
new file mode 100644 (file)
index 0000000..b370986
--- /dev/null
@@ -0,0 +1,40 @@
+/*************************************************************************
+ *                                                                       *
+ * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith.       *
+ * All rights reserved.  Email: russ@q12.org   Web: www.q12.org          *
+ *                                                                       *
+ * This library is free software; you can redistribute it and/or         *
+ * modify it under the terms of EITHER:                                  *
+ *   (1) The GNU Lesser General Public License as published by the Free  *
+ *       Software Foundation; either version 2.1 of the License, or (at  *
+ *       your option) any later version. The text of the GNU Lesser      *
+ *       General Public License is included with this library in the     *
+ *       file LICENSE.TXT.                                               *
+ *   (2) The BSD-style license that is included with this library in     *
+ *       the file LICENSE-BSD.TXT.                                       *
+ *                                                                       *
+ * This library is distributed in the hope that it will be useful,       *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files    *
+ * LICENSE.TXT and LICENSE-BSD.TXT for more details.                     *
+ *                                                                       *
+ *************************************************************************/
+
+#ifndef _ODE_COMPATIBILITY_H_
+#define _ODE_COMPATIBILITY_H_
+
+/*
+ * ODE's backward compatibility system ensures that as ODE's API
+ * evolves, user code will not break.
+ */
+
+/*
+ * These new rotation function names are more consistent with the
+ * rest of the API.
+ */
+#define dQtoR(q,R) dRfromQ((R),(q))
+#define dRtoQ(R,q) dQfromR((q),(R))
+#define dWtoDQ(w,q,dq) dDQfromW((dq),(w),(q))
+
+
+#endif
diff --git a/misc/builddeps/dp.linux64/include/ode/contact.h b/misc/builddeps/dp.linux64/include/ode/contact.h
new file mode 100644 (file)
index 0000000..8bb810f
--- /dev/null
@@ -0,0 +1,104 @@
+/*************************************************************************
+ *                                                                       *
+ * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith.       *
+ * All rights reserved.  Email: russ@q12.org   Web: www.q12.org          *
+ *                                                                       *
+ * This library is free software; you can redistribute it and/or         *
+ * modify it under the terms of EITHER:                                  *
+ *   (1) The GNU Lesser General Public License as published by the Free  *
+ *       Software Foundation; either version 2.1 of the License, or (at  *
+ *       your option) any later version. The text of the GNU Lesser      *
+ *       General Public License is included with this library in the     *
+ *       file LICENSE.TXT.                                               *
+ *   (2) The BSD-style license that is included with this library in     *
+ *       the file LICENSE-BSD.TXT.                                       *
+ *                                                                       *
+ * This library is distributed in the hope that it will be useful,       *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files    *
+ * LICENSE.TXT and LICENSE-BSD.TXT for more details.                     *
+ *                                                                       *
+ *************************************************************************/
+
+#ifndef _ODE_CONTACT_H_
+#define _ODE_CONTACT_H_
+
+#include <ode/common.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+enum {
+  dContactMu2          = 0x001,
+  dContactFDir1                = 0x002,
+  dContactBounce       = 0x004,
+  dContactSoftERP      = 0x008,
+  dContactSoftCFM      = 0x010,
+  dContactMotion1      = 0x020,
+  dContactMotion2      = 0x040,
+  dContactMotionN      = 0x080,
+  dContactSlip1                = 0x100,
+  dContactSlip2                = 0x200,
+
+  dContactApprox0      = 0x0000,
+  dContactApprox1_1    = 0x1000,
+  dContactApprox1_2    = 0x2000,
+  dContactApprox1      = 0x3000
+};
+
+
+typedef struct dSurfaceParameters {
+  /* must always be defined */
+  int mode;
+  dReal mu;
+
+  /* only defined if the corresponding flag is set in mode */
+  dReal mu2;
+  dReal bounce;
+  dReal bounce_vel;
+  dReal soft_erp;
+  dReal soft_cfm;
+  dReal motion1,motion2,motionN;
+  dReal slip1,slip2;
+} dSurfaceParameters;
+
+
+/**
+ * @brief Describe the contact point between two geoms.
+ *
+ * If two bodies touch, or if a body touches a static feature in its 
+ * environment, the contact is represented by one or more "contact 
+ * points", described by dContactGeom.
+ *
+ * The convention is that if body 1 is moved along the normal vector by 
+ * a distance depth (or equivalently if body 2 is moved the same distance 
+ * in the opposite direction) then the contact depth will be reduced to 
+ * zero. This means that the normal vector points "in" to body 1.
+ *
+ * @ingroup collide
+ */
+typedef struct dContactGeom {
+  dVector3 pos;          ///< contact position
+  dVector3 normal;       ///< normal vector
+  dReal depth;           ///< penetration depth
+  dGeomID g1,g2;         ///< the colliding geoms
+  int side1,side2;       ///< (to be documented)
+} dContactGeom;
+
+
+/* contact info used by contact joint */
+
+typedef struct dContact {
+  dSurfaceParameters surface;
+  dContactGeom geom;
+  dVector3 fdir1;
+} dContact;
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/misc/builddeps/dp.linux64/include/ode/error.h b/misc/builddeps/dp.linux64/include/ode/error.h
new file mode 100644 (file)
index 0000000..20b9ba4
--- /dev/null
@@ -0,0 +1,63 @@
+/*************************************************************************
+ *                                                                       *
+ * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith.       *
+ * All rights reserved.  Email: russ@q12.org   Web: www.q12.org          *
+ *                                                                       *
+ * This library is free software; you can redistribute it and/or         *
+ * modify it under the terms of EITHER:                                  *
+ *   (1) The GNU Lesser General Public License as published by the Free  *
+ *       Software Foundation; either version 2.1 of the License, or (at  *
+ *       your option) any later version. The text of the GNU Lesser      *
+ *       General Public License is included with this library in the     *
+ *       file LICENSE.TXT.                                               *
+ *   (2) The BSD-style license that is included with this library in     *
+ *       the file LICENSE-BSD.TXT.                                       *
+ *                                                                       *
+ * This library is distributed in the hope that it will be useful,       *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files    *
+ * LICENSE.TXT and LICENSE-BSD.TXT for more details.                     *
+ *                                                                       *
+ *************************************************************************/
+
+/* this comes from the `reuse' library. copy any changes back to the source */
+
+#ifndef _ODE_ERROR_H_
+#define _ODE_ERROR_H_
+
+#include <ode/odeconfig.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* all user defined error functions have this type. error and debug functions
+ * should not return.
+ */
+typedef void dMessageFunction (int errnum, const char *msg, va_list ap);
+
+/* set a new error, debug or warning handler. if fn is 0, the default handlers
+ * are used.
+ */
+ODE_API void dSetErrorHandler (dMessageFunction *fn);
+ODE_API void dSetDebugHandler (dMessageFunction *fn);
+ODE_API void dSetMessageHandler (dMessageFunction *fn);
+
+/* return the current error, debug or warning handler. if the return value is
+ * 0, the default handlers are in place.
+ */
+ODE_API dMessageFunction *dGetErrorHandler(void);
+ODE_API dMessageFunction *dGetDebugHandler(void);
+ODE_API dMessageFunction *dGetMessageHandler(void);
+
+/* generate a fatal error, debug trap or a message. */
+ODE_API void dError (int num, const char *msg, ...);
+ODE_API void dDebug (int num, const char *msg, ...);
+ODE_API void dMessage (int num, const char *msg, ...);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/misc/builddeps/dp.linux64/include/ode/export-dif.h b/misc/builddeps/dp.linux64/include/ode/export-dif.h
new file mode 100644 (file)
index 0000000..f6578ac
--- /dev/null
@@ -0,0 +1,40 @@
+/*************************************************************************
+ *                                                                       *
+ * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith.       *
+ * All rights reserved.  Email: russ@q12.org   Web: www.q12.org          *
+ *                                                                       *
+ * This library is free software; you can redistribute it and/or         *
+ * modify it under the terms of EITHER:                                  *
+ *   (1) The GNU Lesser General Public License as published by the Free  *
+ *       Software Foundation; either version 2.1 of the License, or (at  *
+ *       your option) any later version. The text of the GNU Lesser      *
+ *       General Public License is included with this library in the     *
+ *       file LICENSE.TXT.                                               *
+ *   (2) The BSD-style license that is included with this library in     *
+ *       the file LICENSE-BSD.TXT.                                       *
+ *                                                                       *
+ * This library is distributed in the hope that it will be useful,       *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files    *
+ * LICENSE.TXT and LICENSE-BSD.TXT for more details.                     *
+ *                                                                       *
+ *************************************************************************/
+
+#ifndef _ODE_EXPORT_DIF_
+#define _ODE_EXPORT_DIF_
+
+#include <ode/common.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ODE_API void dWorldExportDIF (dWorldID w, FILE *file, const char *world_name);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/misc/builddeps/dp.linux64/include/ode/mass.h b/misc/builddeps/dp.linux64/include/ode/mass.h
new file mode 100644 (file)
index 0000000..d74500c
--- /dev/null
@@ -0,0 +1,144 @@
+/*************************************************************************
+ *                                                                       *
+ * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith.       *
+ * All rights reserved.  Email: russ@q12.org   Web: www.q12.org          *
+ *                                                                       *
+ * This library is free software; you can redistribute it and/or         *
+ * modify it under the terms of EITHER:                                  *
+ *   (1) The GNU Lesser General Public License as published by the Free  *
+ *       Software Foundation; either version 2.1 of the License, or (at  *
+ *       your option) any later version. The text of the GNU Lesser      *
+ *       General Public License is included with this library in the     *
+ *       file LICENSE.TXT.                                               *
+ *   (2) The BSD-style license that is included with this library in     *
+ *       the file LICENSE-BSD.TXT.                                       *
+ *                                                                       *
+ * This library is distributed in the hope that it will be useful,       *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files    *
+ * LICENSE.TXT and LICENSE-BSD.TXT for more details.                     *
+ *                                                                       *
+ *************************************************************************/
+
+#ifndef _ODE_MASS_H_
+#define _ODE_MASS_H_
+
+#include <ode/common.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct dMass;
+typedef struct dMass dMass;
+
+/**
+ * Check if a mass structure has valid value.
+ * The function check if the mass and innertia matrix are positive definits
+ *
+ * @param m A mass structure to check
+ *
+ * @return 1 if both codition are met
+ */
+ODE_API int dMassCheck(const dMass *m);
+
+ODE_API void dMassSetZero (dMass *);
+
+ODE_API void dMassSetParameters (dMass *, dReal themass,
+                        dReal cgx, dReal cgy, dReal cgz,
+                        dReal I11, dReal I22, dReal I33,
+                        dReal I12, dReal I13, dReal I23);
+
+ODE_API void dMassSetSphere (dMass *, dReal density, dReal radius);
+ODE_API void dMassSetSphereTotal (dMass *, dReal total_mass, dReal radius);
+
+ODE_API void dMassSetCapsule (dMass *, dReal density, int direction,
+                       dReal radius, dReal length);
+ODE_API void dMassSetCapsuleTotal (dMass *, dReal total_mass, int direction,
+                       dReal radius, dReal length);
+
+ODE_API void dMassSetCylinder (dMass *, dReal density, int direction,
+                      dReal radius, dReal length);
+ODE_API void dMassSetCylinderTotal (dMass *, dReal total_mass, int direction,
+                           dReal radius, dReal length);
+
+ODE_API void dMassSetBox (dMass *, dReal density,
+                 dReal lx, dReal ly, dReal lz);
+ODE_API void dMassSetBoxTotal (dMass *, dReal total_mass,
+                      dReal lx, dReal ly, dReal lz);
+
+ODE_API void dMassSetTrimesh (dMass *, dReal density, dGeomID g);
+
+ODE_API void dMassSetTrimeshTotal (dMass *m, dReal total_mass, dGeomID g);
+
+ODE_API void dMassAdjust (dMass *, dReal newmass);
+
+ODE_API void dMassTranslate (dMass *, dReal x, dReal y, dReal z);
+
+ODE_API void dMassRotate (dMass *, const dMatrix3 R);
+
+ODE_API void dMassAdd (dMass *a, const dMass *b);
+
+
+// Backwards compatible API
+ODE_API ODE_API_DEPRECATED void dMassSetCappedCylinder(dMass *a, dReal b, int c, dReal d, dReal e);
+ODE_API ODE_API_DEPRECATED void dMassSetCappedCylinderTotal(dMass *a, dReal b, int c, dReal d, dReal e);
+
+
+struct dMass {
+  dReal mass;
+  dVector3 c;
+  dMatrix3 I;
+
+#ifdef __cplusplus
+  dMass()
+    { dMassSetZero (this); }
+  void setZero()
+    { dMassSetZero (this); }
+  void setParameters (dReal themass, dReal cgx, dReal cgy, dReal cgz,
+                     dReal I11, dReal I22, dReal I33,
+                     dReal I12, dReal I13, dReal I23)
+    { dMassSetParameters (this,themass,cgx,cgy,cgz,I11,I22,I33,I12,I13,I23); }
+
+  void setSphere (dReal density, dReal radius)
+    { dMassSetSphere (this,density,radius); }
+  void setSphereTotal (dReal total, dReal radius)
+    { dMassSetSphereTotal (this,total,radius); }
+
+  void setCapsule (dReal density, int direction, dReal radius, dReal length)
+    { dMassSetCapsule (this,density,direction,radius,length); }
+  void setCapsuleTotal (dReal total, int direction, dReal radius, dReal length)
+    { dMassSetCapsule (this,total,direction,radius,length); }
+
+  void setCylinder(dReal density, int direction, dReal radius, dReal length)
+    { dMassSetCylinder (this,density,direction,radius,length); }
+  void setCylinderTotal(dReal total, int direction, dReal radius, dReal length)
+    { dMassSetCylinderTotal (this,total,direction,radius,length); }
+
+  void setBox (dReal density, dReal lx, dReal ly, dReal lz)
+    { dMassSetBox (this,density,lx,ly,lz); }
+  void setBoxTotal (dReal total, dReal lx, dReal ly, dReal lz)
+    { dMassSetBoxTotal (this,total,lx,ly,lz); }
+
+  void setTrimesh(dReal density, dGeomID g)
+    { dMassSetTrimesh (this, density, g); }
+  void setTrimeshTotal(dReal total, dGeomID g)
+    { dMassSetTrimeshTotal (this, total, g); }
+
+  void adjust (dReal newmass)
+    { dMassAdjust (this,newmass); }
+  void translate (dReal x, dReal y, dReal z)
+    { dMassTranslate (this,x,y,z); }
+  void rotate (const dMatrix3 R)
+    { dMassRotate (this,R); }
+  void add (const dMass *b)
+    { dMassAdd (this,b); }
+#endif
+};
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/misc/builddeps/dp.linux64/include/ode/matrix.h b/misc/builddeps/dp.linux64/include/ode/matrix.h
new file mode 100644 (file)
index 0000000..e177f44
--- /dev/null
@@ -0,0 +1,280 @@
+/*************************************************************************
+ *                                                                       *
+ * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith.       *
+ * All rights reserved.  Email: russ@q12.org   Web: www.q12.org          *
+ *                                                                       *
+ * This library is free software; you can redistribute it and/or         *
+ * modify it under the terms of EITHER:                                  *
+ *   (1) The GNU Lesser General Public License as published by the Free  *
+ *       Software Foundation; either version 2.1 of the License, or (at  *
+ *       your option) any later version. The text of the GNU Lesser      *
+ *       General Public License is included with this library in the     *
+ *       file LICENSE.TXT.                                               *
+ *   (2) The BSD-style license that is included with this library in     *
+ *       the file LICENSE-BSD.TXT.                                       *
+ *                                                                       *
+ * This library is distributed in the hope that it will be useful,       *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files    *
+ * LICENSE.TXT and LICENSE-BSD.TXT for more details.                     *
+ *                                                                       *
+ *************************************************************************/
+
+/* optimized and unoptimized vector and matrix functions */
+
+#ifndef _ODE_MATRIX_H_
+#define _ODE_MATRIX_H_
+
+#include <ode/common.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/* set a vector/matrix of size n to all zeros, or to a specific value. */
+
+ODE_API void dSetZero (dReal *a, int n);
+ODE_API void dSetValue (dReal *a, int n, dReal value);
+
+
+/* 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).
+ */
+
+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.
+ * all vectors are n*1. if n <= 0 then zeroes will be returned (in which case
+ * the input vectors need not be valid). this function is somewhat faster
+ * than calling dDot() for all of the combinations separately.
+ */
+
+/* NOT INCLUDED in the library for now.
+void dMultidot2 (const dReal *a0, const dReal *a1,
+                const dReal *b, dReal *outsum, int n);
+*/
+
+
+/* matrix multiplication. all matrices are stored in standard row format.
+ * the digit refers to the argument that is transposed:
+ *   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)
+ *   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
+ * B or C are stored in standard column format.
+ */
+
+ODE_API void dMultiply0 (dReal *A, const dReal *B, const dReal *C, int p,int q,int r);
+ODE_API void dMultiply1 (dReal *A, const dReal *B, const dReal *C, int p,int q,int r);
+ODE_API void dMultiply2 (dReal *A, const dReal *B, const dReal *C, int p,int q,int r);
+
+
+/* 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 triangle
+ * will be such that L*L'=A. return 1 on success and 0 on failure (on failure
+ * the matrix is not positive definite).
+ */
+
+ODE_API int dFactorCholesky (dReal *A, int n);
+
+
+/* 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.
+ */
+
+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
+ * Ainv. this is not especially fast. this returns 1 on success (A was
+ * positive definite) or 0 on failure (not PD).
+ */
+
+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).
+ * 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
+ * is not positive definite. A is stored by rows. A is not altered.
+ */
+
+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
+ * the diagonal, and D is diagonal.
+ * 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
+ * written) and the reciprocal of the diagonal elements of D are written into
+ * d.
+ */
+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,
+ * and x,b are n*1. b is overwritten with x.
+ * the leading dimension of L is `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,
+ * and x,b are n*1. b is overwritten with x.
+ * the leading dimension of L is `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) */
+
+ODE_API void dVectorScale (dReal *a, const dReal *d, int n);
+
+
+/* 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 matrix
+ * D, solve L*D*L'*x=b where x,b are n*1. x overwrites b.
+ * the leading dimension of L is `nskip'.
+ */
+
+ODE_API void dSolveLDLT (const dReal *L, const dReal *d, dReal *b, int n, int nskip);
+
+
+/* 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:
+ *
+ *    [ b a' ]     <-- b is a[0]
+ *    [ a 0  ]     <-- a is a[1..n-1]
+ *
+ *   - L has size n*n, its leading dimension is nskip. L is lower triangular
+ *     with ones on the diagonal. only the lower triangle of L is referenced.
+ *   - d has size n. d contains the reciprocal diagonal elements of D.
+ *   - a has size n.
+ * 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. 
+ */
+ODE_API void dLDLTAddTL (dReal *L, dReal *d, const dReal *a, int n, int nskip);
+
+
+/* given an L*D*L' factorization of a permuted matrix A, produce a new
+ * factorization for row and column `r' removed.
+ *   - A has size n1*n1, its leading dimension in nskip. A is symmetric and
+ *     positive definite. only the lower triangle of A is referenced.
+ *     A itself may actually be an array of row pointers.
+ *   - L has size n2*n2, its leading dimension in nskip. L is lower triangular
+ *     with ones on the diagonal. only the lower triangle of L is referenced.
+ *   - 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
+ *     must be in the range 0..n1-1.
+ *   - 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 leading
+ * dimension. the last row and column of L, and the last element of d, are
+ * undefined on exit.
+ *
+ * a fast O(n^2) algorithm is used. see ldltremove.m for further comments.
+ */
+ODE_API void dLDLTRemove (dReal **A, const int *p, dReal *L, dReal *d,
+                 int n1, int n2, int r, int nskip);
+
+
+/* given an n*n matrix A (with leading dimension nskip), remove the r'th row
+ * 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.
+ */
+ODE_API void dRemoveRowCol (dReal *A, int n, int nskip, int r);
+
+
+#if defined(__ODE__)
+
+void _dSetZero (dReal *a, size_t n);
+void _dSetValue (dReal *a, size_t n, dReal value);
+dReal _dDot (const dReal *a, const dReal *b, int n);
+void _dMultiply0 (dReal *A, const dReal *B, const dReal *C, int p,int q,int r);
+void _dMultiply1 (dReal *A, const dReal *B, const dReal *C, int p,int q,int r);
+void _dMultiply2 (dReal *A, const dReal *B, const dReal *C, int p,int q,int r);
+int _dFactorCholesky (dReal *A, int n, void *tmpbuf);
+void _dSolveCholesky (const dReal *L, dReal *b, int n, void *tmpbuf);
+int _dInvertPDMatrix (const dReal *A, dReal *Ainv, int n, void *tmpbuf);
+int _dIsPositiveDefinite (const dReal *A, int n, void *tmpbuf);
+void _dFactorLDLT (dReal *A, dReal *d, int n, int nskip);
+void _dSolveL1 (const dReal *L, dReal *b, int n, int nskip);
+void _dSolveL1T (const dReal *L, dReal *b, int n, int nskip);
+void _dVectorScale (dReal *a, const dReal *d, int n);
+void _dSolveLDLT (const dReal *L, const dReal *d, dReal *b, int n, int nskip);
+void _dLDLTAddTL (dReal *L, dReal *d, const dReal *a, int n, int nskip, void *tmpbuf);
+void _dLDLTRemove (dReal **A, const int *p, dReal *L, dReal *d, int n1, int n2, int r, int nskip, void *tmpbuf);
+void _dRemoveRowCol (dReal *A, int n, int nskip, int r);
+
+PURE_INLINE size_t _dEstimateFactorCholeskyTmpbufSize(int n)
+{
+  return dPAD(n) * sizeof(dReal);
+}
+
+PURE_INLINE size_t _dEstimateSolveCholeskyTmpbufSize(int n)
+{
+  return dPAD(n) * sizeof(dReal);
+}
+
+PURE_INLINE size_t _dEstimateInvertPDMatrixTmpbufSize(int n)
+{
+  size_t FactorCholesky_size = _dEstimateFactorCholeskyTmpbufSize(n);
+  size_t SolveCholesky_size = _dEstimateSolveCholeskyTmpbufSize(n);
+  size_t MaxCholesky_size = FactorCholesky_size > SolveCholesky_size ? FactorCholesky_size : SolveCholesky_size;
+  return dPAD(n) * (n + 1) * sizeof(dReal) + MaxCholesky_size;
+}
+
+PURE_INLINE size_t _dEstimateIsPositiveDefiniteTmpbufSize(int n)
+{
+  return dPAD(n) * n * sizeof(dReal) + _dEstimateFactorCholeskyTmpbufSize(n);
+}
+
+PURE_INLINE size_t _dEstimateLDLTAddTLTmpbufSize(int nskip)
+{
+  return nskip * 2 * sizeof(dReal);
+}
+
+PURE_INLINE size_t _dEstimateLDLTRemoveTmpbufSize(int n2, int nskip)
+{
+  return n2 * sizeof(dReal) + _dEstimateLDLTAddTLTmpbufSize(nskip);
+}
+
+// For internal use
+#define dSetZero(a, n) _dSetZero(a, n)
+#define dSetValue(a, n, value) _dSetValue(a, n, value)
+#define dDot(a, b, n) _dDot(a, b, n)
+#define dMultiply0(A, B, C, p, q, r) _dMultiply0(A, B, C, p, q, r)
+#define dMultiply1(A, B, C, p, q, r) _dMultiply1(A, B, C, p, q, r)
+#define dMultiply2(A, B, C, p, q, r) _dMultiply2(A, B, C, p, q, r)
+#define dFactorCholesky(A, n, tmpbuf) _dFactorCholesky(A, n, tmpbuf)
+#define dSolveCholesky(L, b, n, tmpbuf) _dSolveCholesky(L, b, n, tmpbuf)
+#define dInvertPDMatrix(A, Ainv, n, tmpbuf) _dInvertPDMatrix(A, Ainv, n, tmpbuf)
+#define dIsPositiveDefinite(A, n, tmpbuf) _dIsPositiveDefinite(A, n, tmpbuf)
+#define dFactorLDLT(A, d, n, nskip) _dFactorLDLT(A, d, n, nskip)
+#define dSolveL1(L, b, n, nskip) _dSolveL1(L, b, n, nskip)
+#define dSolveL1T(L, b, n, nskip) _dSolveL1T(L, b, n, nskip)
+#define dVectorScale(a, d, n) _dVectorScale(a, d, n)
+#define dSolveLDLT(L, d, b, n, nskip) _dSolveLDLT(L, d, b, n, nskip)
+#define dLDLTAddTL(L, d, a, n, nskip, tmpbuf) _dLDLTAddTL(L, d, a, n, nskip, tmpbuf)
+#define dLDLTRemove(A, p, L, d, n1, n2, r, nskip, tmpbuf) _dLDLTRemove(A, p, L, d, n1, n2, r, nskip, tmpbuf)
+#define dRemoveRowCol(A, n, nskip, r) _dRemoveRowCol(A, n, nskip, r)
+
+
+#define dEstimateFactorCholeskyTmpbufSize(n) _dEstimateFactorCholeskyTmpbufSize(n)
+#define dEstimateSolveCholeskyTmpbufSize(n) _dEstimateSolveCholeskyTmpbufSize(n)
+#define dEstimateInvertPDMatrixTmpbufSize(n) _dEstimateInvertPDMatrixTmpbufSize(n)
+#define dEstimateIsPositiveDefiniteTmpbufSize(n) _dEstimateIsPositiveDefiniteTmpbufSize(n)
+#define dEstimateLDLTAddTLTmpbufSize(nskip) _dEstimateLDLTAddTLTmpbufSize(nskip)
+#define dEstimateLDLTRemoveTmpbufSize(n2, nskip) _dEstimateLDLTRemoveTmpbufSize(n2, nskip)
+
+
+#endif // defined(__ODE__)
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/misc/builddeps/dp.linux64/include/ode/memory.h b/misc/builddeps/dp.linux64/include/ode/memory.h
new file mode 100644 (file)
index 0000000..361061c
--- /dev/null
@@ -0,0 +1,59 @@
+/*************************************************************************
+ *                                                                       *
+ * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith.       *
+ * All rights reserved.  Email: russ@q12.org   Web: www.q12.org          *
+ *                                                                       *
+ * This library is free software; you can redistribute it and/or         *
+ * modify it under the terms of EITHER:                                  *
+ *   (1) The GNU Lesser General Public License as published by the Free  *
+ *       Software Foundation; either version 2.1 of the License, or (at  *
+ *       your option) any later version. The text of the GNU Lesser      *
+ *       General Public License is included with this library in the     *
+ *       file LICENSE.TXT.                                               *
+ *   (2) The BSD-style license that is included with this library in     *
+ *       the file LICENSE-BSD.TXT.                                       *
+ *                                                                       *
+ * This library is distributed in the hope that it will be useful,       *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files    *
+ * LICENSE.TXT and LICENSE-BSD.TXT for more details.                     *
+ *                                                                       *
+ *************************************************************************/
+
+/* this comes from the `reuse' library. copy any changes back to the source */
+
+#ifndef _ODE_MEMORY_H_
+#define _ODE_MEMORY_H_
+
+#include <ode/odeconfig.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* function types to allocate and free memory */
+typedef void * dAllocFunction (size_t size);
+typedef void * dReallocFunction (void *ptr, size_t oldsize, size_t newsize);
+typedef void dFreeFunction (void *ptr, size_t size);
+
+/* set new memory management functions. if fn is 0, the default handlers are
+ * used. */
+ODE_API void dSetAllocHandler (dAllocFunction *fn);
+ODE_API void dSetReallocHandler (dReallocFunction *fn);
+ODE_API void dSetFreeHandler (dFreeFunction *fn);
+
+/* get current memory management functions */
+ODE_API dAllocFunction *dGetAllocHandler (void);
+ODE_API dReallocFunction *dGetReallocHandler (void);
+ODE_API dFreeFunction *dGetFreeHandler (void);
+
+/* allocate and free memory. */
+ODE_API void * dAlloc (size_t size);
+ODE_API void * dRealloc (void *ptr, size_t oldsize, size_t newsize);
+ODE_API void dFree (void *ptr, size_t size);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/misc/builddeps/dp.linux64/include/ode/misc.h b/misc/builddeps/dp.linux64/include/ode/misc.h
new file mode 100644 (file)
index 0000000..0c55fc5
--- /dev/null
@@ -0,0 +1,85 @@
+/*************************************************************************
+ *                                                                       *
+ * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith.       *
+ * All rights reserved.  Email: russ@q12.org   Web: www.q12.org          *
+ *                                                                       *
+ * This library is free software; you can redistribute it and/or         *
+ * modify it under the terms of EITHER:                                  *
+ *   (1) The GNU Lesser General Public License as published by the Free  *
+ *       Software Foundation; either version 2.1 of the License, or (at  *
+ *       your option) any later version. The text of the GNU Lesser      *
+ *       General Public License is included with this library in the     *
+ *       file LICENSE.TXT.                                               *
+ *   (2) The BSD-style license that is included with this library in     *
+ *       the file LICENSE-BSD.TXT.                                       *
+ *                                                                       *
+ * This library is distributed in the hope that it will be useful,       *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files    *
+ * LICENSE.TXT and LICENSE-BSD.TXT for more details.                     *
+ *                                                                       *
+ *************************************************************************/
+
+/* miscellaneous math functions. these are mostly useful for testing */
+
+#ifndef _ODE_MISC_H_
+#define _ODE_MISC_H_
+
+#include <ode/common.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/* return 1 if the random number generator is working. */
+ODE_API int dTestRand(void);
+
+/* return next 32 bit random number. this uses a not-very-random linear
+ * congruential method.
+ */
+ODE_API unsigned long dRand(void);
+
+/* get and set the current random number seed. */
+ODE_API unsigned long  dRandGetSeed(void);
+ODE_API void dRandSetSeed (unsigned long s);
+
+/* return a random integer between 0..n-1. the distribution will get worse
+ * as n approaches 2^32.
+ */
+ODE_API int dRandInt (int n);
+
+/* return a random real number between 0..1 */
+ODE_API dReal dRandReal(void);
+
+/* print out a matrix */
+#ifdef __cplusplus
+ODE_API void dPrintMatrix (const dReal *A, int n, int m, char *fmt = "%10.4f ",
+                  FILE *f=stdout);
+#else
+ODE_API void dPrintMatrix (const dReal *A, int n, int m, char *fmt, FILE *f);
+#endif
+
+/* make a random vector with entries between +/- range. A has n elements. */
+ODE_API void dMakeRandomVector (dReal *A, int n, dReal range);
+
+/* make a random matrix with entries between +/- range. A has size n*m. */
+ODE_API void dMakeRandomMatrix (dReal *A, int n, int m, dReal range);
+
+/* clear the upper triangle of a square matrix */
+ODE_API void dClearUpperTriangle (dReal *A, int n);
+
+/* return the maximum element difference between the two n*m matrices */
+ODE_API dReal dMaxDifference (const dReal *A, const dReal *B, int n, int m);
+
+/* return the maximum element difference between the lower triangle of two
+ * n*n matrices */
+ODE_API dReal dMaxDifferenceLowerTriangle (const dReal *A, const dReal *B, int n);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/misc/builddeps/dp.linux64/include/ode/objects.h b/misc/builddeps/dp.linux64/include/ode/objects.h
new file mode 100644 (file)
index 0000000..379de01
--- /dev/null
@@ -0,0 +1,2975 @@
+
+
+/*************************************************************************
+ *                                                                       *
+ * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith.       *
+ * All rights reserved.  Email: russ@q12.org   Web: www.q12.org          *
+ *                                                                       *
+ * This library is free software; you can redistribute it and/or         *
+ * modify it under the terms of EITHER:                                  *
+ *   (1) The GNU Lesser General Public License as published by the Free  *
+ *       Software Foundation; either version 2.1 of the License, or (at  *
+ *       your option) any later version. The text of the GNU Lesser      *
+ *       General Public License is included with this library in the     *
+ *       file LICENSE.TXT.                                               *
+ *   (2) The BSD-style license that is included with this library in     *
+ *       the file LICENSE-BSD.TXT.                                       *
+ *                                                                       *
+ * This library is distributed in the hope that it will be useful,       *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files    *
+ * LICENSE.TXT and LICENSE-BSD.TXT for more details.                     *
+ *                                                                       *
+ *************************************************************************/
+
+#ifndef _ODE_OBJECTS_H_
+#define _ODE_OBJECTS_H_
+
+#include <ode/common.h>
+#include <ode/mass.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 Set the world to use shared working memory along with another world.
+ *
+ * The worlds allocate working memory internally for simulation stepping. This
+ * memory is cached among the calls to @c dWordStep and @c dWorldQuickStep. 
+ * Similarly, several worlds can be set up to share this memory caches thus 
+ * reducing overall memory usage by cost of making worlds inappropriate for 
+ * simultaneous simulation in multiple threads.
+ *
+ * If null value is passed for @a from_world parameter the world is detached from 
+ * sharing and returns to defaults for working memory, reservation policy and 
+ * memory manager as if just created. This can also be used to enable use of shared 
+ * memory for a world that has already had working memory allocated privately.
+ * Normally using shared memory after a world has its private working memory allocated
+ * is prohibited.
+ *
+ * Allocation policy used can only increase world's internal reserved memory size
+ * and never decreases it. @c dWorldCleanupWorkingMemory can be used to release 
+ * working memory for a world in case if number of objects/joint decreases 
+ * significantly in it.
+ *
+ * With sharing working memory worlds also automatically share memory reservation 
+ * policy and memory manager. Thus, these parameters need to be customized for
+ * initial world to be used as sharing source only.
+ *
+ * Failure result status means a memory allocation failure.
+ *
+ * @param w The world to use the shared memory with.
+ * @param from_world Null or the world the shared memory is to be used from.
+ * @returns 1 for success and 0 for failure.
+ *
+ * @ingroup world
+ * @see dWorldCleanupWorkingMemory
+ * @see dWorldSetStepMemoryReservationPolicy
+ * @see dWorldSetStepMemoryManager
+ */
+ODE_API int dWorldUseSharedWorkingMemory(dWorldID w, dWorldID from_world/*=NULL*/);
+
+/**
+ * @brief Release internal working memory allocated for world
+ *
+ * The worlds allocate working memory internally for simulation stepping. This 
+ * function can be used to free world's internal memory cache in case if number of
+ * objects/joints in the world decreases significantly. By default, internal 
+ * allocation policy is used to only increase cache size as necessary and never 
+ * decrease it.
+ *
+ * If a world shares its working memory with other worlds the cache deletion 
+ * affects all the linked worlds. However the shared status itself remains intact.
+ *
+ * The function call does affect neither memory reservation policy nor memory manager.
+ *
+ * @param w The world to release working memory for.
+ *
+ * @ingroup world
+ * @see dWorldUseSharedWorkingMemory
+ * @see dWorldSetStepMemoryReservationPolicy
+ * @see dWorldSetStepMemoryManager
+ */
+ODE_API void dWorldCleanupWorkingMemory(dWorldID w);
+
+#define dWORLDSTEP_RESERVEFACTOR_DEFAULT    1.2f
+#define dWORLDSTEP_RESERVESIZE_DEFAULT      65536U
+
+/**
+ * @struct dWorldStepReserveInfo
+ * @brief Memory reservation policy descriptor structure for world stepping functions.
+ *
+ * @c struct_size should be assigned the size of the structure.
+ *
+ * @c reserve_factor is a quotient that is multiplied by required memory size
+ *  to allocate extra reserve whenever reallocation is needed.
+ *
+ * @c reserve_minimum is a minimum size that is checked against whenever reallocation 
+ * is needed to allocate expected working memory minimum at once without extra 
+ * reallocations as number of bodies/joints grows.
+ *
+ * @ingroup world
+ * @see dWorldSetStepMemoryReservationPolicy
+ */
+typedef struct
+{
+  unsigned struct_size;
+  float reserve_factor; // Use float as precision does not matter here
+  unsigned reserve_minimum;
+
+} dWorldStepReserveInfo;
+
+/**
+ * @brief Set memory reservation policy for world to be used with simulation stepping functions
+ *
+ * The function allows to customize reservation policy to be used for internal
+ * memory which is allocated to aid simulation for a world. By default, values
+ * of @c dWORLDSTEP_RESERVEFACTOR_DEFAULT and @c dWORLDSTEP_RESERVESIZE_DEFAULT
+ * are used.
+ *
+ * Passing @a policyinfo argument as NULL results in reservation policy being
+ * reset to defaults as if the world has been just created. The content of 
+ * @a policyinfo structure is copied internally and does not need to remain valid
+ * after the call returns.
+ *
+ * If the world uses working memory sharing, changing memory reservation policy
+ * affects all the worlds linked together.
+ *
+ * Failure result status means a memory allocation failure.
+ *
+ * @param w The world to change memory reservation policy for.
+ * @param policyinfo Null or a pointer to policy descriptor structure.
+ * @returns 1 for success and 0 for failure.
+ *
+ * @ingroup world
+ * @see dWorldUseSharedWorkingMemory
+ */
+ODE_API int dWorldSetStepMemoryReservationPolicy(dWorldID w, const dWorldStepReserveInfo *policyinfo/*=NULL*/);
+
+/**
+* @struct dWorldStepMemoryFunctionsInfo
+* @brief World stepping memory manager descriptor structure
+*
+* This structure is intended to define the functions of memory manager to be used
+* with world stepping functions.
+*
+* @c struct_size should be assigned the size of the structure
+*
+* @c alloc_block is a function to allocate memory block of given size.
+*
+* @c shrink_block is a function to shrink existing memory block to a smaller size.
+* It must preserve the contents of block head while shrinking. The new block size
+* is guaranteed to be always less than the existing one.
+*
+* @c free_block is a function to delete existing memory block.
+*
+* @ingroup init
+* @see dWorldSetStepMemoryManager
+*/
+typedef struct 
+{
+  unsigned struct_size;
+  void *(*alloc_block)(size_t block_size);
+  void *(*shrink_block)(void *block_pointer, size_t block_current_size, size_t block_smaller_size);
+  void (*free_block)(void *block_pointer, size_t block_current_size);
+
+} dWorldStepMemoryFunctionsInfo;
+
+/**
+* @brief Set memory manager for world to be used with simulation stepping functions
+*
+* The function allows to customize memory manager to be used for internal
+* memory allocation during simulation for a world. By default, @c dAlloc/@c dRealloc/@c dFree
+* based memory manager is used.
+*
+* Passing @a memfuncs argument as NULL results in memory manager being
+* reset to default one as if the world has been just created. The content of 
+* @a memfuncs structure is copied internally and does not need to remain valid
+* after the call returns.
+*
+* If the world uses working memory sharing, changing memory manager
+* affects all the worlds linked together. 
+*
+* Failure result status means a memory allocation failure.
+*
+* @param w The world to change memory reservation policy for.
+* @param memfuncs Null or a pointer to memory manager descriptor structure.
+* @returns 1 for success and 0 for failure.
+*
+* @ingroup world
+* @see dWorldUseSharedWorkingMemory
+*/
+ODE_API int dWorldSetStepMemoryManager(dWorldID w, const dWorldStepMemoryFunctionsInfo *memfuncs);
+
+/**
+ * @brief Step the world.
+ *
+ * This uses a "big matrix" method that takes time on the order of m^3
+ * and memory on the order of m^2, where m is the total number of constraint
+ * rows. For large systems this will use a lot of memory and can be very slow,
+ * but this is currently the most accurate method.
+ *
+ * Failure result status means that the memory allocation has failed for operation.
+ * In such a case all the objects remain in unchanged state and simulation can be
+ * retried as soon as more memory is available.
+ *
+ * @param w The world to be stepped
+ * @param stepsize The number of seconds that the simulation has to advance.
+ * @returns 1 for success and 0 for failure
+ *
+ * @ingroup world
+ */
+ODE_API int dWorldStep (dWorldID w, dReal stepsize);
+
+/**
+ * @brief Quick-step the world.
+ *
+ * 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.
+ *
+ * QuickStep is great for stacks of objects especially when the
+ * auto-disable feature is used as well.
+ * However, it has poor accuracy for near-singular systems.
+ * Near-singular systems can occur when using high-friction contacts, motors,
+ * or certain articulated structures. For example, a robot with multiple legs
+ * sitting on the ground may be near-singular.
+ *
+ * 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.
+ *
+ * Failure result status means that the memory allocation has failed for operation.
+ * In such a case all the objects remain in unchanged state and simulation can be
+ * retried as soon as more memory is available.
+ *
+ * @param w The world to be stepped
+ * @param stepsize The number of seconds that the simulation has to advance.
+ * @returns 1 for success and 0 for failure
+ *
+ * @ingroup world
+ */
+ODE_API int dWorldQuickStep (dWorldID w, 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 convert
+* the desired impulse into a force/torque vector before calling the
+* BodyAdd... function.
+* The current algorithm simply scales the impulse by 1/stepsize,
+* where stepsize is the step size for the next step that will be taken.
+* This function is given a dWorldID because, in the future, the force
+* computation may depend on integrator parameters that are set as
+* properties of the world.
+*/
+ODE_API void dWorldImpulseToForce
+(
+ dWorldID, dReal stepsize,
+ dReal ix, dReal iy, dReal iz, dVector3 force
+ );
+
+
+/**
+ * @brief Set the number of iterations that the QuickStep method performs per
+ *        step.
+ * @ingroup world
+ * @remarks
+ * More iterations will give a more accurate solution, but will take
+ * longer to compute.
+ * @param num The default is 20 iterations.
+ */
+ODE_API void dWorldSetQuickStepNumIterations (dWorldID, int num);
+
+
+/**
+ * @brief Get the number of iterations that the QuickStep method performs per
+ *        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 objects.
+ */
+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);
+
+
+/**
+ * @defgroup disable Automatic Enabling and Disabling
+ * @ingroup world bodies
+ *
+ * Every body can be enabled or disabled. Enabled bodies participate in the
+ * simulation, while disabled bodies are turned off and do not get updated
+ * during a simulation step. New bodies are always created in the enabled state.
+ *
+ * A disabled body that is connected through a joint to an enabled body will be
+ * automatically re-enabled at the next simulation step.
+ *
+ * Disabled bodies do not consume CPU time, therefore to speed up the simulation
+ * bodies should be disabled when they come to rest. This can be done automatically
+ * with the auto-disable feature.
+ *
+ * If a body has its auto-disable flag turned on, it will automatically disable
+ * itself when
+ *   @li It has been idle for a given number of simulation steps.
+ *   @li It has also been idle for a given amount of simulation time.
+ *
+ * A body is considered to be idle when the magnitudes of both its
+ * linear average velocity and angular average velocity are below given thresholds.
+ * The sample size for the average defaults to one and can be disabled by setting
+ * to zero with 
+ *
+ * Thus, every body has six auto-disable parameters: an enabled flag, a idle step
+ * count, an idle time, linear/angular average velocity thresholds, and the
+ * average samples count.
+ *
+ * Newly created bodies get these parameters from world.
+ */
+
+/**
+ * @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_threshold);
+
+/**
+ * @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 linear average threshold for newly created bodies.
+ * @ingroup disable
+ * @return the threshold
+ */
+ODE_API dReal dWorldGetAutoDisableLinearAverageThreshold (dWorldID);
+
+/**
+ * @brief Set auto disable linear average threshold for newly created bodies.
+ * @param linear_average_threshold default is 0.01
+ * @ingroup disable
+ */
+ODE_API void  dWorldSetAutoDisableLinearAverageThreshold (dWorldID, dReal linear_average_threshold);
+
+/**
+ * @brief Get auto disable angular average threshold for newly created bodies.
+ * @ingroup disable
+ * @return the threshold
+ */
+ODE_API dReal dWorldGetAutoDisableAngularAverageThreshold (dWorldID);
+
+/**
+ * @brief Set auto disable angular average threshold for newly created bodies.
+ * @param linear_average_threshold default is 0.01
+ * @ingroup disable
+ */
+ODE_API void dWorldSetAutoDisableAngularAverageThreshold (dWorldID, dReal angular_average_threshold);
+
+/**
+ * @brief Get auto disable sample count for newly created bodies.
+ * @ingroup disable
+ * @return number of samples used
+ */
+ODE_API int dWorldGetAutoDisableAverageSamplesCount (dWorldID);
+
+/**
+ * @brief Set auto disable average sample count for newly created bodies.
+ * @ingroup disable
+ * @param average_samples_count Default is 1, meaning only instantaneous velocity is used.
+ * Set to zero to disable sampling and thus prevent any body from auto-disabling.
+ */
+ODE_API void dWorldSetAutoDisableAverageSamplesCount (dWorldID, unsigned int average_samples_count );
+
+/**
+ * @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 damping Damping
+ * @ingroup bodies world
+ *
+ * Damping serves two purposes: reduce simulation instability, and to allow
+ * the bodies to come to rest (and possibly auto-disabling them).
+ *
+ * Bodies are constructed using the world's current damping parameters. Setting
+ * the scales to 0 disables the damping.
+ *
+ * Here is how it is done: after every time step linear and angular
+ * velocities are tested against the corresponding thresholds. If they
+ * are above, they are multiplied by (1 - scale). So a negative scale value
+ * will actually increase the speed, and values greater than one will
+ * make the object oscillate every step; both can make the simulation unstable.
+ *
+ * To disable damping just set the damping scale to zero.
+ *
+ * You can also limit the maximum angular velocity. In contrast to the damping
+ * functions, the angular velocity is affected before the body is moved.
+ * This means that it will introduce errors in joints that are forcing the body
+ * to rotate too fast. Some bodies have naturally high angular velocities
+ * (like cars' wheels), so you may want to give them a very high (like the default,
+ * dInfinity) limit.
+ *
+ * @note The velocities are damped after the stepper function has moved the
+ * object. Otherwise the damping could introduce errors in joints. First the
+ * joint constraints are processed by the stepper (moving the body), then
+ * the damping is applied.
+ *
+ * @note The damping happens right after the moved callback is called; this way 
+ * it still possible use the exact velocities the body has acquired during the
+ * step. You can even use the callback to create your own customized damping.
+ */
+
+/**
+ * @brief Get the world's linear damping threshold.
+ * @ingroup damping
+ */
+ODE_API dReal dWorldGetLinearDampingThreshold (dWorldID w);
+
+/**
+ * @brief Set the world's linear damping threshold.
+ * @param threshold The damping won't be applied if the linear speed is
+ *        below this threshold. Default is 0.01.
+ * @ingroup damping
+ */
+ODE_API void dWorldSetLinearDampingThreshold(dWorldID w, dReal threshold);
+
+/**
+ * @brief Get the world's angular damping threshold.
+ * @ingroup damping
+ */
+ODE_API dReal dWorldGetAngularDampingThreshold (dWorldID w);
+
+/**
+ * @brief Set the world's angular damping threshold.
+ * @param threshold The damping won't be applied if the angular speed is
+ *        below this threshold. Default is 0.01.
+ * @ingroup damping
+ */
+ODE_API void dWorldSetAngularDampingThreshold(dWorldID w, dReal threshold);
+
+/**
+ * @brief Get the world's linear damping scale.
+ * @ingroup damping
+ */
+ODE_API dReal dWorldGetLinearDamping (dWorldID w);
+
+/**
+ * @brief Set the world's linear damping scale.
+ * @param scale The linear damping scale that is to be applied to bodies.
+ * Default is 0 (no damping). Should be in the interval [0, 1].
+ * @ingroup damping
+ */
+ODE_API void dWorldSetLinearDamping (dWorldID w, dReal scale);
+
+/**
+ * @brief Get the world's angular damping scale.
+ * @ingroup damping
+ */
+ODE_API dReal dWorldGetAngularDamping (dWorldID w);
+
+/**
+ * @brief Set the world's angular damping scale.
+ * @param scale The angular damping scale that is to be applied to bodies.
+ * Default is 0 (no damping). Should be in the interval [0, 1].
+ * @ingroup damping
+ */
+ODE_API void dWorldSetAngularDamping(dWorldID w, dReal scale);
+
+/**
+ * @brief Convenience function to set body linear and angular scales.
+ * @param linear_scale The linear damping scale that is to be applied to bodies.
+ * @param angular_scale The angular damping scale that is to be applied to bodies.
+ * @ingroup damping
+ */
+ODE_API void dWorldSetDamping(dWorldID w,
+                                dReal linear_scale,
+                                dReal angular_scale);
+
+/**
+ * @brief Get the default maximum angular speed.
+ * @ingroup damping
+ * @sa dBodyGetMaxAngularSpeed()
+ */
+ODE_API dReal dWorldGetMaxAngularSpeed (dWorldID w);
+
+
+/**
+ * @brief Set the default maximum angular speed for new bodies.
+ * @ingroup damping
+ * @sa dBodySetMaxAngularSpeed()
+ */
+ODE_API void dWorldSetMaxAngularSpeed (dWorldID w, dReal max_speed);
+
+
+
+/**
+ * @defgroup bodies Rigid Bodies
+ *
+ * A rigid body has various properties from the point of view of the
+ * simulation. Some properties change over time:
+ *
+ *  @li Position vector (x,y,z) of the body's point of reference.
+ *      Currently the point of reference must correspond to the body's center of mass.
+ *  @li Linear velocity of the point of reference, a vector (vx,vy,vz).
+ *  @li Orientation of a body, represented by a quaternion (qs,qx,qy,qz) or
+ *      a 3x3 rotation matrix.
+ *  @li Angular velocity vector (wx,wy,wz) which describes how the orientation
+ *      changes over time.
+ *
+ * Other body properties are usually constant over time:
+ *
+ *  @li Mass of the body.
+ *  @li Position of the center of mass with respect to the point of reference.
+ *      In the current implementation the center of mass and the point of
+ *      reference must coincide.
+ *  @li Inertia matrix. This is a 3x3 matrix that describes how the body's mass
+ *      is distributed around the center of mass. Conceptually each body has an
+ *      x-y-z coordinate frame embedded in it that moves and rotates with the body.
+ *
+ * The origin of this coordinate frame is the body's point of reference. Some values
+ * in ODE (vectors, matrices etc) are relative to the body coordinate frame, and others
+ * are relative to the global coordinate frame.
+ *
+ * Note that the shape of a rigid body is not a dynamical property (except insofar as
+ * it influences the various mass properties). It is only collision detection that cares
+ * about the detailed shape of the body.
+ */
+
+
+/**
+ * @brief Get auto disable linear average threshold.
+ * @ingroup bodies disable
+ * @return the threshold
+ */
+ODE_API dReal dBodyGetAutoDisableLinearThreshold (dBodyID);
+
+/**
+ * @brief Set auto disable linear average threshold.
+ * @ingroup bodies disable
+ * @return the threshold
+ */
+ODE_API void  dBodySetAutoDisableLinearThreshold (dBodyID, dReal linear_average_threshold);
+
+/**
+ * @brief Get auto disable angular average threshold.
+ * @ingroup bodies disable
+ * @return the threshold
+ */
+ODE_API dReal dBodyGetAutoDisableAngularThreshold (dBodyID);
+
+/**
+ * @brief Set auto disable angular average threshold.
+ * @ingroup bodies disable
+ * @return the threshold
+ */
+ODE_API void  dBodySetAutoDisableAngularThreshold (dBodyID, dReal angular_average_threshold);
+
+/**
+ * @brief Get auto disable average size (samples count).
+ * @ingroup bodies disable
+ * @return the nr of steps/size.
+ */
+ODE_API int dBodyGetAutoDisableAverageSamplesCount (dBodyID);
+
+/**
+ * @brief Set auto disable average buffer size (average steps).
+ * @ingroup bodies disable
+ * @param average_samples_count the nr of samples to review.
+ */
+ODE_API void dBodySetAutoDisableAverageSamplesCount (dBodyID, unsigned int average_samples_count);
+
+
+/**
+ * @brief Get auto steps a body must be thought of as idle to disable
+ * @ingroup bodies disable
+ * @return the nr of steps
+ */
+ODE_API int dBodyGetAutoDisableSteps (dBodyID);
+
+/**
+ * @brief Set auto disable steps.
+ * @ingroup bodies disable
+ * @param steps the nr of steps.
+ */
+ODE_API void dBodySetAutoDisableSteps (dBodyID, int steps);
+
+/**
+ * @brief Get auto disable time.
+ * @ingroup bodies disable
+ * @return nr of seconds
+ */
+ODE_API dReal dBodyGetAutoDisableTime (dBodyID);
+
+/**
+ * @brief Set auto disable time.
+ * @ingroup bodies disable
+ * @param time nr of seconds.
+ */
+ODE_API void  dBodySetAutoDisableTime (dBodyID, dReal time);
+
+/**
+ * @brief Get auto disable flag.
+ * @ingroup bodies disable
+ * @return 0 or 1
+ */
+ODE_API int dBodyGetAutoDisableFlag (dBodyID);
+
+/**
+ * @brief Set auto disable flag.
+ * @ingroup bodies disable
+ * @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 disable
+ */
+ODE_API void  dBodySetAutoDisableDefaults (dBodyID);
+
+
+/**
+ * @brief Retrieves the world attached to te given body.
+ * @remarks
+ * 
+ * @ingroup bodies
+ */
+ODE_API dWorldID dBodyGetWorld (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 structures,
+ * so the vectors are valid until any changes are made to the rigid body
+ * system structure.
+ * @sa dBodyCopyPosition
+ */
+ODE_API const dReal * dBodyGetPosition (dBodyID);
+
+
+/**
+ * @brief Copy the position of a body into a vector.
+ * @ingroup bodies
+ * @param body  the body to query
+ * @param pos   a copy of the body position
+ * @sa dBodyGetPosition
+ */
+ODE_API void dBodyCopyPosition (dBodyID body, dVector3 pos);
+
+
+/**
+ * @brief Get the rotation of a body.
+ * @ingroup bodies
+ * @return pointer to a 4x3 rotation matrix.
+ */
+ODE_API const dReal * dBodyGetRotation (dBodyID);
+
+
+/**
+ * @brief Copy the rotation of a body.
+ * @ingroup bodies
+ * @param body   the body to query
+ * @param R      a copy of the rotation matrix
+ * @sa dBodyGetRotation
+ */
+ODE_API void dBodyCopyRotation (dBodyID, dMatrix3 R);
+
+
+/**
+ * @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 Copy the orientation of a body into a quaternion.
+ * @ingroup bodies
+ * @param body  the body to query
+ * @param quat  a copy of the orientation quaternion
+ * @sa dBodyGetQuaternion
+ */
+ODE_API void dBodyCopyQuaternion(dBodyID body, dQuaternion quat);
+
+
+/**
+ * @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 fz);
+
+/**
+ * @brief Add torque at centre of mass of body in absolute coordinates.
+ * @ingroup bodies
+ */
+ODE_API void dBodyAddTorque           (dBodyID, dReal fx, dReal fy, dReal fz);
+
+/**
+ * @brief Add force at centre of mass of body in coordinates relative to body.
+ * @ingroup bodies
+ */
+ODE_API void dBodyAddRelForce         (dBodyID, dReal fx, dReal fy, dReal fz);
+
+/**
+ * @brief Add torque at centre of mass of body in coordinates relative to body.
+ * @ingroup bodies
+ */
+ODE_API void dBodyAddRelTorque        (dBodyID, dReal fx, dReal fy, dReal fz);
+
+/**
+ * @brief Add force at specified point in body in global coordinates.
+ * @ingroup bodies
+ */
+ODE_API void dBodyAddForceAtPos       (dBodyID, dReal fx, dReal fy, dReal fz,
+                                       dReal px, dReal py, dReal pz);
+/**
+ * @brief Add force at specified point in body in local coordinates.
+ * @ingroup bodies
+ */
+ODE_API void dBodyAddForceAtRelPos    (dBodyID, dReal fx, dReal fy, dReal fz,
+                                       dReal px, dReal py, dReal pz);
+/**
+ * @brief Add force at specified point in body in global coordinates.
+ * @ingroup bodies
+ */
+ODE_API void dBodyAddRelForceAtPos    (dBodyID, dReal fx, dReal fy, dReal fz,
+                                       dReal px, dReal py, dReal pz);
+/**
+ * @brief Add force at specified point in body in local coordinates.
+ * @ingroup bodies
+ */
+ODE_API void dBodyAddRelForceAtRelPos (dBodyID, dReal fx, dReal fy, dReal fz,
+                                       dReal px, dReal py, dReal pz);
+
+/**
+ * @brief Return the current accumulated force vector.
+ * @return points to an array of 3 reals.
+ * @remarks
+ * The returned values are pointers to internal data structures, so
+ * the vectors are only valid until any changes are made to the rigid
+ * body system.
+ * @ingroup bodies
+ */
+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 bodies
+ * before they are reactivated, in the case where the force-adding functions
+ * 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 bodies
+ * before they are reactivated, in the case where the force-adding functions
+ * 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 finite
+ * rotation along the axis direction followed by an infinitesimal rotation
+ * along an orthogonal direction.
+ * @remarks
+ * This can be useful to alleviate certain sources of error caused by quickly
+ * spinning bodies. For example, if a car wheel is rotating at high speed
+ * you can call this function with the wheel's hinge axis as the argument to
+ * try and improve its behavior.
+ */
+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 Set rigid body to dynamic state (default).
+ * @param dBodyID identification of body.
+ * @ingroup bodies
+ */
+ODE_API void dBodySetDynamic (dBodyID);
+
+/**
+ * @brief Set rigid body to kinematic state.
+ * When in kinematic state the body isn't simulated as a dynamic
+ * body (it's "unstoppable", doesn't respond to forces),
+ * but can still affect dynamic bodies (e.g. in joints).
+ * Kinematic bodies can be controlled by position and velocity.
+ * @note A kinematic body has infinite mass. If you set its mass
+ * to something else, it loses the kinematic state and behaves
+ * as a normal dynamic body.
+ * @param dBodyID identification of body.
+ * @ingroup bodies
+ */
+ODE_API void dBodySetKinematic (dBodyID);
+
+/**
+ * @brief Check wether a body is in kinematic state.
+ * @ingroup bodies
+ * @return 1 if a body is kinematic or 0 if it is dynamic.
+ */
+ODE_API int dBodyIsKinematic (dBodyID);
+
+/**
+ * @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 will
+ * 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);
+
+/**
+ * @brief Set the 'moved' callback of a body.
+ *
+ * Whenever a body has its position or rotation changed during the
+ * timestep, the callback will be called (with body as the argument).
+ * Use it to know which body may need an update in an external
+ * structure (like a 3D engine).
+ *
+ * @param b the body that needs to be watched.
+ * @param callback the callback to be invoked when the body moves. Set to zero
+ * to disable.
+ * @ingroup bodies
+ */
+ODE_API void dBodySetMovedCallback(dBodyID b, void (*callback)(dBodyID));
+
+
+/**
+ * @brief Return the first geom associated with the body.
+ * 
+ * You can traverse through the geoms by repeatedly calling
+ * dBodyGetNextGeom().
+ *
+ * @return the first geom attached to this body, or 0.
+ * @ingroup bodies
+ */
+ODE_API dGeomID dBodyGetFirstGeom (dBodyID b);
+
+
+/**
+ * @brief returns the next geom associated with the same body.
+ * @param g a geom attached to some body.
+ * @return the next geom attached to the same body, or 0.
+ * @sa dBodyGetFirstGeom
+ * @ingroup bodies
+ */
+ODE_API dGeomID dBodyGetNextGeom (dGeomID g);
+
+
+/**
+ * @brief Resets the damping settings to the current world's settings.
+ * @ingroup bodies damping
+ */
+ODE_API void dBodySetDampingDefaults(dBodyID b);
+
+/**
+ * @brief Get the body's linear damping scale.
+ * @ingroup bodies damping
+ */
+ODE_API dReal dBodyGetLinearDamping (dBodyID b);
+
+/**
+ * @brief Set the body's linear damping scale.
+ * @param scale The linear damping scale. Should be in the interval [0, 1].
+ * @ingroup bodies damping
+ * @remarks From now on the body will not use the world's linear damping
+ * scale until dBodySetDampingDefaults() is called.
+ * @sa dBodySetDampingDefaults()
+ */
+ODE_API void dBodySetLinearDamping(dBodyID b, dReal scale);
+
+/**
+ * @brief Get the body's angular damping scale.
+ * @ingroup bodies damping
+ * @remarks If the body's angular damping scale was not set, this function
+ * returns the world's angular damping scale.
+ */
+ODE_API dReal dBodyGetAngularDamping (dBodyID b);
+
+/**
+ * @brief Set the body's angular damping scale.
+ * @param scale The angular damping scale. Should be in the interval [0, 1].
+ * @ingroup bodies damping
+ * @remarks From now on the body will not use the world's angular damping
+ * scale until dBodyResetAngularDamping() is called.
+ * @sa dBodyResetAngularDamping()
+ */
+ODE_API void dBodySetAngularDamping(dBodyID b, dReal scale);
+
+/**
+ * @brief Convenience function to set linear and angular scales at once.
+ * @param linear_scale The linear damping scale. Should be in the interval [0, 1].
+ * @param angular_scale The angular damping scale. Should be in the interval [0, 1].
+ * @ingroup bodies damping
+ * @sa dBodySetLinearDamping() dBodySetAngularDamping()
+ */
+ODE_API void dBodySetDamping(dBodyID b, dReal linear_scale, dReal angular_scale);
+
+/**
+ * @brief Get the body's linear damping threshold.
+ * @ingroup bodies damping
+ */
+ODE_API dReal dBodyGetLinearDampingThreshold (dBodyID b);
+
+/**
+ * @brief Set the body's linear damping threshold.
+ * @param threshold The linear threshold to be used. Damping
+ *      is only applied if the linear speed is above this limit.
+ * @ingroup bodies damping
+ */
+ODE_API void dBodySetLinearDampingThreshold(dBodyID b, dReal threshold);
+
+/**
+ * @brief Get the body's angular damping threshold.
+ * @ingroup bodies damping
+ */
+ODE_API dReal dBodyGetAngularDampingThreshold (dBodyID b);
+
+/**
+ * @brief Set the body's angular damping threshold.
+ * @param threshold The angular threshold to be used. Damping is
+ *      only used if the angular speed is above this limit.
+ * @ingroup bodies damping
+ */
+ODE_API void dBodySetAngularDampingThreshold(dBodyID b, dReal threshold);
+
+/**
+ * @brief Get the body's maximum angular speed.
+ * @ingroup damping bodies
+ * @sa dWorldGetMaxAngularSpeed()
+ */
+ODE_API dReal dBodyGetMaxAngularSpeed (dBodyID b);
+
+/**
+ * @brief Set the body's maximum angular speed.
+ * @ingroup damping bodies
+ * @sa dWorldSetMaxAngularSpeed() dBodyResetMaxAngularSpeed()
+ * The default value is dInfinity, but it's a good idea to limit
+ * it at less than 500 if the body has the gyroscopic term
+ * enabled.
+ */
+ODE_API void dBodySetMaxAngularSpeed(dBodyID b, dReal max_speed);
+
+
+
+/**
+ * @brief Get the body's gyroscopic state.
+ *
+ * @return nonzero if gyroscopic term computation is enabled (default),
+ * zero otherwise.
+ * @ingroup bodies
+ */
+ODE_API int dBodyGetGyroscopicMode(dBodyID b);
+
+
+/**
+ * @brief Enable/disable the body's gyroscopic term.
+ *
+ * Disabling the gyroscopic term of a body usually improves
+ * stability. It also helps turning spining objects, like cars'
+ * wheels.
+ *
+ * @param enabled   nonzero (default) to enable gyroscopic term, 0
+ * to disable.
+ * @ingroup bodies
+ */
+ODE_API void dBodySetGyroscopicMode(dBodyID b, int enabled);
+
+
+
+
+/**
+ * @defgroup joints Joints
+ *
+ * In real life a joint is something like a hinge, that is used to connect two
+ * objects.
+ * In ODE a joint is very similar: It is a relationship that is enforced between
+ * two bodies so that they can only have certain positions and orientations
+ * relative to each other.
+ * This relationship is called a constraint -- the words joint and
+ * constraint are often used interchangeably.
+ *
+ * A joint has a set of parameters that can be set. These include:
+ *
+ *
+ * \li  dParamLoStop Low stop angle or position. Setting this to
+ *     -dInfinity (the default value) turns off the low stop.
+ *     For rotational joints, this stop must be greater than -pi to be
+ *     effective.
+ * \li  dParamHiStop High stop angle or position. Setting this to
+ *     dInfinity (the default value) turns off the high stop.
+ *     For rotational joints, this stop must be less than pi to be
+ *     effective.
+ *     If the high stop is less than the low stop then both stops will
+ *     be ineffective.
+ * \li  dParamVel Desired motor velocity (this will be an angular or
+ *     linear velocity).
+ * \li  dParamFMax The maximum force or torque that the motor will use to
+ *     achieve the desired velocity.
+ *     This must always be greater than or equal to zero.
+ *     Setting this to zero (the default value) turns off the motor.
+ * \li  dParamFudgeFactor The current joint stop/motor implementation has
+ *     a small problem:
+ *     when the joint is at one stop and the motor is set to move it away
+ *     from the stop, too much force may be applied for one time step,
+ *     causing a ``jumping'' motion.
+ *     This fudge factor is used to scale this excess force.
+ *     It should have a value between zero and one (the default value).
+ *     If the jumping motion is too visible in a joint, the value can be
+ *     reduced.
+ *     Making this value too small can prevent the motor from being able to
+ *     move the joint away from a stop.
+ * \li  dParamBounce The bouncyness of the stops.
+ *     This is a restitution parameter in the range 0..1.
+ *     0 means the stops are not bouncy at all, 1 means maximum bouncyness.
+ * \li  dParamCFM The constraint force mixing (CFM) value used when not
+ *     at a stop.
+ * \li  dParamStopERP The error reduction parameter (ERP) used by the
+ *     stops.
+ * \li  dParamStopCFM The constraint force mixing (CFM) value used by the
+ *     stops. Together with the ERP value this can be used to get spongy or
+ *     soft stops.
+ *     Note that this is intended for unpowered joints, it does not really
+ *     work as expected when a powered joint reaches its limit.
+ * \li  dParamSuspensionERP Suspension error reduction parameter (ERP).
+ *     Currently this is only implemented on the hinge-2 joint.
+ * \li  dParamSuspensionCFM Suspension constraint force mixing (CFM) value.
+ *     Currently this is only implemented on the hinge-2 joint.
+ *
+ * If a particular parameter is not implemented by a given joint, setting it
+ * will have no effect.
+ * These parameter names can be optionally followed by a digit (2 or 3)
+ * to indicate the second or third set of parameters, e.g. for the second axis
+ * in a hinge-2 joint, or the third axis in an AMotor joint.
+ */
+
+
+/**
+ * @brief Create a new joint of the ball type.
+ * @ingroup joints
+ * @remarks
+ * The joint is initially in "limbo" (i.e. it has no effect on the simulation)
+ * because it does not connect to any bodies.
+ * @param dJointGroupID set to 0 to allocate the joint normally.
+ * If it is nonzero the joint is allocated in the given joint group.
+ */
+ODE_API dJointID dJointCreateBall (dWorldID, dJointGroupID);
+
+/**
+ * @brief Create a new joint of the hinge type.
+ * @ingroup joints
+ * @param dJointGroupID set to 0 to allocate the joint normally.
+ * If it is nonzero the joint is allocated in the given joint group.
+ */
+ODE_API dJointID dJointCreateHinge (dWorldID, dJointGroupID);
+
+/**
+ * @brief Create a new joint of the slider type.
+ * @ingroup joints
+ * @param dJointGroupID set to 0 to allocate the joint normally.
+ * If it is nonzero the joint is allocated in the given joint group.
+ */
+ODE_API dJointID dJointCreateSlider (dWorldID, dJointGroupID);
+
+/**
+ * @brief Create a new joint of the contact type.
+ * @ingroup joints
+ * @param dJointGroupID set to 0 to allocate the joint normally.
+ * If it is nonzero the joint is allocated in the given joint group.
+ */
+ODE_API dJointID dJointCreateContact (dWorldID, dJointGroupID, const dContact *);
+
+/**
+ * @brief Create a new joint of the hinge2 type.
+ * @ingroup joints
+ * @param dJointGroupID set to 0 to allocate the joint normally.
+ * If it is nonzero the joint is allocated in the given joint group.
+ */
+ODE_API dJointID dJointCreateHinge2 (dWorldID, dJointGroupID);
+
+/**
+ * @brief Create a new joint of the universal type.
+ * @ingroup joints
+ * @param dJointGroupID set to 0 to allocate the joint normally.
+ * If it is nonzero the joint is allocated in the given joint group.
+ */
+ODE_API dJointID dJointCreateUniversal (dWorldID, dJointGroupID);
+
+/**
+ * @brief Create a new joint of the PR (Prismatic and Rotoide) 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 dJointCreatePR (dWorldID, dJointGroupID);
+
+  /**
+   * @brief Create a new joint of the PU (Prismatic and Universal) type.
+   * @ingroup joints
+   * @param dJointGroupID set to 0 to allocate the joint normally.
+   * If it is nonzero the joint is allocated in the given joint group.
+   */
+  ODE_API dJointID dJointCreatePU (dWorldID, dJointGroupID);
+
+  /**
+   * @brief Create a new joint of the Piston 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 dJointCreatePiston (dWorldID, dJointGroupID);
+
+/**
+ * @brief Create a new joint of the fixed type.
+ * @ingroup joints
+ * @param dJointGroupID set to 0 to allocate the joint normally.
+ * If it is nonzero the joint is allocated in the given joint group.
+ */
+ODE_API dJointID dJointCreateFixed (dWorldID, dJointGroupID);
+
+ODE_API dJointID dJointCreateNull (dWorldID, dJointGroupID);
+
+/**
+ * @brief Create a new joint of the A-motor type.
+ * @ingroup joints
+ * @param dJointGroupID set to 0 to allocate the joint normally.
+ * If it is nonzero the joint is allocated in the given joint group.
+ */
+ODE_API dJointID dJointCreateAMotor (dWorldID, dJointGroupID);
+
+/**
+ * @brief Create a new joint of the L-motor type.
+ * @ingroup joints
+ * @param dJointGroupID set to 0 to allocate the joint normally.
+ * If it is nonzero the joint is allocated in the given joint group.
+ */
+ODE_API dJointID dJointCreateLMotor (dWorldID, dJointGroupID);
+
+/**
+ * @brief Create a new joint of the plane-2d 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 dJointCreatePlane2D (dWorldID, dJointGroupID);
+
+/**
+ * @brief Destroy a joint.
+ * @ingroup joints
+ *
+ * disconnects it from its attached bodies and removing it from the world.
+ * However, if the joint is a member of a group then this function has no
+ * effect - to destroy that joint the group must be emptied or destroyed.
+ */
+ODE_API void dJointDestroy (dJointID);
+
+
+/**
+ * @brief Create a joint group
+ * @ingroup joints
+ * @param max_size deprecated. Set to 0.
+ */
+ODE_API dJointGroupID dJointGroupCreate (int max_size);
+
+/**
+ * @brief Destroy a joint group.
+ * @ingroup joints
+ *
+ * All joints in the joint group will be destroyed.
+ */
+ODE_API void dJointGroupDestroy (dJointGroupID);
+
+/**
+ * @brief Empty a joint group.
+ * @ingroup joints
+ *
+ * All joints in the joint group will be destroyed,
+ * but the joint group itself will not be destroyed.
+ */
+ODE_API void dJointGroupEmpty (dJointGroupID);
+
+/**
+ * @brief Return the number of bodies attached to the joint
+ * @ingroup joints
+ */
+ODE_API int dJointGetNumBodies(dJointID);
+
+/**
+ * @brief Attach the joint to some new bodies.
+ * @ingroup joints
+ *
+ * If the joint is already attached, it will be detached from the old bodies
+ * first.
+ * To attach this joint to only one body, set body1 or body2 to zero - a zero
+ * body refers to the static environment.
+ * Setting both bodies to zero puts the joint into "limbo", i.e. it will
+ * have no effect on the simulation.
+ * @remarks
+ * Some joints, like hinge-2 need to be attached to two bodies to work.
+ */
+ODE_API void dJointAttach (dJointID, dBodyID body1, dBodyID body2);
+
+/**
+ * @brief Manually enable a joint.
+ * @param dJointID identification of joint.
+ * @ingroup joints
+ */
+ODE_API void dJointEnable (dJointID);
+
+/**
+ * @brief Manually disable a joint.
+ * @ingroup joints
+ * @remarks
+ * A disabled joint will not affect the simulation, but will maintain the anchors and
+ * axes so it can be enabled later.
+ */
+ODE_API void dJointDisable (dJointID);
+
+/**
+ * @brief Check wether a joint is enabled.
+ * @ingroup joints
+ * @return 1 if a joint is currently enabled or 0 if it is disabled.
+ */
+ODE_API int dJointIsEnabled (dJointID);
+
+/**
+ * @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 dJointTypeBall
+ * \li dJointTypeHinge
+ * \li dJointTypeSlider
+ * \li dJointTypeContact
+ * \li dJointTypeUniversal
+ * \li dJointTypeHinge2
+ * \li dJointTypeFixed
+ * \li dJointTypeNull
+ * \li dJointTypeAMotor
+ * \li dJointTypeLMotor
+ * \li dJointTypePlane2D
+ * \li dJointTypePR
+ * \li dJointTypePU
+ * \li dJointTypePiston
+ */
+ODE_API dJointType dJointGetType (dJointID);
+
+/**
+ * @brief Return the bodies that this joint connects.
+ * @ingroup joints
+ * @param index return the first (0) or second (1) body.
+ * @remarks
+ * If one of these returned body IDs is zero, the joint connects the other body
+ * to the static environment.
+ * If both body IDs are zero, the joint is in ``limbo'' and has no effect on
+ * the simulation.
+ */
+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 Param setting for Ball joints
+ * @ingroup joints
+ */
+ODE_API void dJointSetBallParam (dJointID, int parameter, dReal value);
+
+/**
+ * @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 the Hinge axis as if the 2 bodies were already at angle appart.
+ * @ingroup joints
+ *
+ * This function initialize the Axis and the relative orientation of each body
+ * as if body1 was rotated around the axis by the angle value. \br
+ * Ex:
+ * <PRE>
+ * dJointSetHingeAxis(jId, 1, 0, 0);
+ * // If you request the position you will have: dJointGetHingeAngle(jId) == 0
+ * dJointSetHingeAxisDelta(jId, 1, 0, 0, 0.23);
+ * // If you request the position you will have: dJointGetHingeAngle(jId) == 0.23
+ * </PRE>
+
+ * @param j The Hinge joint ID for which the axis will be set
+ * @param x The X component of the axis in world frame
+ * @param y The Y component of the axis in world frame
+ * @param z The Z component of the axis in world frame
+ * @param angle The angle for the offset of the relative orientation.
+ *              As if body1 was rotated by angle when the Axis was set (see below).
+ *              The rotation is around the new Hinge axis.
+ *
+ * @note Usually the function dJointSetHingeAxis set the current position of body1
+ *       and body2 as the zero angle position. This function set the current position
+ *       as the if the 2 bodies where \b angle appart.
+ * @warning Calling dJointSetHingeAnchor or dJointSetHingeAxis will reset the "zero"
+ *          angle position.
+ */
+ODE_API void dJointSetHingeAxisOffset (dJointID j, dReal x, dReal y, dReal z, dReal angle);
+
+/**
+ * @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 opposite
+ * 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 of
+ * slider's axis, to body1, and with the same magnitude but opposite
+ * direction to body2.  This function is just a wrapper for dBodyAddForce().
+ * @ingroup joints
+ */
+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 torque2);
+
+/**
+ * @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 the Universal axis1 as if the 2 bodies were already at 
+ *        offset1 and offset2 appart with respect to axis1 and axis2.
+ * @ingroup joints
+ *
+ * This function initialize the axis1 and the relative orientation of 
+ * each body as if body1 was rotated around the new axis1 by the offset1 
+ * value and as if body2 was rotated around the axis2 by offset2. \br
+ * Ex:
+* <PRE>
+ * dJointSetHuniversalAxis1(jId, 1, 0, 0);
+ * // If you request the position you will have: dJointGetUniversalAngle1(jId) == 0
+ * // If you request the position you will have: dJointGetUniversalAngle2(jId) == 0
+ * dJointSetHuniversalAxis1Offset(jId, 1, 0, 0, 0.2, 0.17);
+ * // If you request the position you will have: dJointGetUniversalAngle1(jId) == 0.2
+ * // If you request the position you will have: dJointGetUniversalAngle2(jId) == 0.17
+ * </PRE>
+ *
+ * @param j The Hinge joint ID for which the axis will be set
+ * @param x The X component of the axis in world frame
+ * @param y The Y component of the axis in world frame
+ * @param z The Z component of the axis in world frame
+ * @param angle The angle for the offset of the relative orientation.
+ *              As if body1 was rotated by angle when the Axis was set (see below).
+ *              The rotation is around the new Hinge axis.
+ *
+ * @note Usually the function dJointSetHingeAxis set the current position of body1
+ *       and body2 as the zero angle position. This function set the current position
+ *       as the if the 2 bodies where \b offsets appart.
+ *
+ * @note Any previous offsets are erased.
+ *
+ * @warning Calling dJointSetUniversalAnchor, dJointSetUnivesalAxis1, 
+ *          dJointSetUniversalAxis2, dJointSetUniversalAxis2Offset 
+ *          will reset the "zero" angle position.
+ */
+ODE_API void dJointSetUniversalAxis1Offset (dJointID, dReal x, dReal y, dReal z,
+                                            dReal offset1, dReal offset2);
+
+/**
+ * @brief set axis
+ * @ingroup joints
+ */
+ODE_API void dJointSetUniversalAxis2 (dJointID, dReal x, dReal y, dReal z);
+
+/**
+ * @brief Set the Universal axis2 as if the 2 bodies were already at 
+ *        offset1 and offset2 appart with respect to axis1 and axis2.
+ * @ingroup joints
+ *
+ * This function initialize the axis2 and the relative orientation of 
+ * each body as if body1 was rotated around the axis1 by the offset1 
+ * value and as if body2 was rotated around the new axis2 by offset2. \br
+ * Ex:
+ * <PRE>
+ * dJointSetHuniversalAxis2(jId, 0, 1, 0);
+ * // If you request the position you will have: dJointGetUniversalAngle1(jId) == 0
+ * // If you request the position you will have: dJointGetUniversalAngle2(jId) == 0
+ * dJointSetHuniversalAxis2Offset(jId, 0, 1, 0, 0.2, 0.17);
+ * // If you request the position you will have: dJointGetUniversalAngle1(jId) == 0.2
+ * // If you request the position you will have: dJointGetUniversalAngle2(jId) == 0.17
+ * </PRE>
+
+ * @param j The Hinge joint ID for which the axis will be set
+ * @param x The X component of the axis in world frame
+ * @param y The Y component of the axis in world frame
+ * @param z The Z component of the axis in world frame
+ * @param angle The angle for the offset of the relative orientation.
+ *              As if body1 was rotated by angle when the Axis was set (see below).
+ *              The rotation is around the new Hinge axis.
+ *
+ * @note Usually the function dJointSetHingeAxis set the current position of body1
+ *       and body2 as the zero angle position. This function set the current position
+ *       as the if the 2 bodies where \b offsets appart.
+ *
+ * @note Any previous offsets are erased.
+ *
+ * @warning Calling dJointSetUniversalAnchor, dJointSetUnivesalAxis1, 
+ *          dJointSetUniversalAxis2, dJointSetUniversalAxis2Offset 
+ *          will reset the "zero" angle position.
+ */
+
+
+ODE_API void dJointSetUniversalAxis2Offset (dJointID, dReal x, dReal y, dReal z,
+                                            dReal offset1, dReal offset2);
+
+/**
+ * @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 set anchor
+ * @ingroup joints
+ */
+ODE_API void dJointSetPRAnchor (dJointID, dReal x, dReal y, dReal z);
+
+/**
+ * @brief set the axis for the prismatic articulation
+ * @ingroup joints
+ */
+ODE_API void dJointSetPRAxis1 (dJointID, dReal x, dReal y, dReal z);
+
+/**
+ * @brief set the axis for the rotoide articulation
+ * @ingroup joints
+ */
+ODE_API void dJointSetPRAxis2 (dJointID, dReal x, dReal y, dReal z);
+
+/**
+ * @brief set joint parameter
+ * @ingroup joints
+ *
+ * @note parameterX where X equal 2 refer to parameter for the rotoide articulation
+ */
+ODE_API void dJointSetPRParam (dJointID, int parameter, dReal value);
+
+/**
+ * @brief Applies the torque about the rotoide axis of the PR joint
+ *
+ * That is, it applies a torque with specified magnitude in the direction 
+ * of the rotoide axis, to body 1, and with the same magnitude but in opposite
+ * direction to body 2. This function is just a wrapper for dBodyAddTorque()}
+ * @ingroup joints
+ */
+ODE_API void dJointAddPRTorque (dJointID j, dReal torque);
+
+
+  /**
+  * @brief set anchor
+  * @ingroup joints
+  */
+  ODE_API void dJointSetPUAnchor (dJointID, dReal x, dReal y, dReal z);
+
+  /**
+   * @brief set anchor
+   * @ingroup joints
+   */
+  ODE_API_DEPRECATED ODE_API void dJointSetPUAnchorDelta (dJointID, dReal x, dReal y, dReal z,
+                                                          dReal dx, dReal dy, dReal dz);
+
+  /**
+   * @brief Set the PU anchor as if the 2 bodies were already at [dx, dy, dz] appart.
+   * @ingroup joints
+   *
+   * This function initialize the anchor and the relative position of each body
+   * as if the position between body1 and body2 was already the projection of [dx, dy, dz]
+   * along the Piston axis. (i.e as if the body1 was at its current position - [dx,dy,dy] when the
+   * axis is set).
+   * Ex:
+   * <PRE>
+   * dReal offset = 3;
+   * dVector3 axis;
+   * dJointGetPUAxis(jId, axis);
+   * dJointSetPUAnchor(jId, 0, 0, 0);
+   * // If you request the position you will have: dJointGetPUPosition(jId) == 0
+   * dJointSetPUAnchorOffset(jId, 0, 0, 0, axis[X]*offset, axis[Y]*offset, axis[Z]*offset);
+   * // If you request the position you will have: dJointGetPUPosition(jId) == offset
+   * </PRE>
+   * @param j The PU joint for which the anchor point will be set
+   * @param x The X position of the anchor point in world frame
+   * @param y The Y position of the anchor point in world frame
+   * @param z The Z position of the anchor point in world frame
+   * @param dx A delta to be substracted to the X position as if the anchor was set
+   *           when body1 was at current_position[X] - dx
+   * @param dx A delta to be substracted to the Y position as if the anchor was set
+   *           when body1 was at current_position[Y] - dy
+   * @param dx A delta to be substracted to the Z position as if the anchor was set
+   *           when body1 was at current_position[Z] - dz
+   */
+  ODE_API void dJointSetPUAnchorOffset (dJointID, dReal x, dReal y, dReal z,
+                                       dReal dx, dReal dy, dReal dz);
+
+  /**
+   * @brief set the axis for the first axis or the universal articulation
+   * @ingroup joints
+   */
+  ODE_API void dJointSetPUAxis1 (dJointID, dReal x, dReal y, dReal z);
+
+  /**
+   * @brief set the axis for the second axis or the universal articulation
+   * @ingroup joints
+   */
+  ODE_API void dJointSetPUAxis2 (dJointID, dReal x, dReal y, dReal z);
+
+  /**
+   * @brief set the axis for the prismatic articulation
+   * @ingroup joints
+   */
+  ODE_API void dJointSetPUAxis3 (dJointID, dReal x, dReal y, dReal z);
+
+  /**
+   * @brief set the axis for the prismatic articulation
+   * @ingroup joints
+   * @note This function was added for convenience it is the same as
+   *       dJointSetPUAxis3
+   */
+  ODE_API void dJointSetPUAxisP (dJointID id, dReal x, dReal y, dReal z);
+
+
+
+  /**
+   * @brief set joint parameter
+   * @ingroup joints
+   *
+   * @note parameterX where X equal 2 refer to parameter for second axis of the
+   *       universal articulation
+   * @note parameterX where X equal 3 refer to parameter for prismatic
+   *       articulation
+   */
+  ODE_API void dJointSetPUParam (dJointID, int parameter, dReal value);
+
+  /**
+   * @brief Applies the torque about the rotoide axis of the PU joint
+   *
+   * That is, it applies a torque with specified magnitude in the direction
+   * of the rotoide axis, to body 1, and with the same magnitude but in opposite
+   * direction to body 2. This function is just a wrapper for dBodyAddTorque()}
+   * @ingroup joints
+   */
+  ODE_API void dJointAddPUTorque (dJointID j, dReal torque);
+
+
+
+
+  /**
+   * @brief set the joint anchor
+   * @ingroup joints
+   */
+  ODE_API void dJointSetPistonAnchor (dJointID, dReal x, dReal y, dReal z);
+
+  /**
+   * @brief Set the Piston anchor as if the 2 bodies were already at [dx,dy, dz] appart.
+   * @ingroup joints
+   *
+   * This function initialize the anchor and the relative position of each body
+   * as if the position between body1 and body2 was already the projection of [dx, dy, dz]
+   * along the Piston axis. (i.e as if the body1 was at its current position - [dx,dy,dy] when the
+   * axis is set).
+   * Ex:
+   * <PRE>
+   * dReal offset = 3;
+   * dVector3 axis;
+   * dJointGetPistonAxis(jId, axis);
+   * dJointSetPistonAnchor(jId, 0, 0, 0);
+   * // If you request the position you will have: dJointGetPistonPosition(jId) == 0
+   * dJointSetPistonAnchorOffset(jId, 0, 0, 0, axis[X]*offset, axis[Y]*offset, axis[Z]*offset);
+   * // If you request the position you will have: dJointGetPistonPosition(jId) == offset
+   * </PRE>
+   * @param j The Piston joint for which the anchor point will be set
+   * @param x The X position of the anchor point in world frame
+   * @param y The Y position of the anchor point in world frame
+   * @param z The Z position of the anchor point in world frame
+   * @param dx A delta to be substracted to the X position as if the anchor was set
+   *           when body1 was at current_position[X] - dx
+   * @param dx A delta to be substracted to the Y position as if the anchor was set
+   *           when body1 was at current_position[Y] - dy
+   * @param dx A delta to be substracted to the Z position as if the anchor was set
+   *           when body1 was at current_position[Z] - dz
+   */
+  ODE_API void dJointSetPistonAnchorOffset(dJointID j, dReal x, dReal y, dReal z,
+                                           dReal dx, dReal dy, dReal dz);
+
+    /**
+     * @brief set the joint axis
+   * @ingroup joints
+   */
+  ODE_API void dJointSetPistonAxis (dJointID, dReal x, dReal y, dReal z);
+
+  /**
+   * This function set prismatic axis of the joint and also set the position
+   * of the joint.
+   *
+   * @ingroup joints
+   * @param j The joint affected by this function
+   * @param x The x component of the axis
+   * @param y The y component of the axis
+   * @param z The z component of the axis
+   * @param dx The Initial position of the prismatic join in the x direction
+   * @param dy The Initial position of the prismatic join in the y direction
+   * @param dz The Initial position of the prismatic join in the z direction
+   */
+  ODE_API_DEPRECATED ODE_API void dJointSetPistonAxisDelta (dJointID j, dReal x, dReal y, dReal z, dReal ax, dReal ay, dReal az);
+
+  /**
+   * @brief set joint parameter
+   * @ingroup joints
+   */
+  ODE_API void dJointSetPistonParam (dJointID, int parameter, dReal value);
+
+  /**
+   * @brief Applies the given force in the slider's direction.
+   *
+   * That is, it applies a force with specified magnitude, in the direction of
+   * prismatic'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 dJointAddPistonForce (dJointID joint, dReal force);
+
+
+/**
+ * @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 Sets joint parameter
+ *
+ * @ingroup joints
+ */
+ODE_API void dJointSetFixedParam (dJointID, int parameter, dReal value);
+
+/**
+ * @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'' modes
+ * \li 0: The axis is anchored to the global frame.
+ * \li 1: The axis is anchored to the first body.
+ * \li 2: The axis is anchored to the second body.
+ * @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, dReal y, dReal z);
+
+/**
+ * @brief set joint parameter
+ * @ingroup joints
+ */
+ODE_API void dJointSetLMotorParam (dJointID, int parameter, dReal value);
+
+/**
+ * @ingroup joints
+ */
+ODE_API void dJointSetPlane2DXParam (dJointID, int parameter, dReal value);
+
+/**
+ * @ingroup joints
+ */
+
+ODE_API void dJointSetPlane2DYParam (dJointID, int parameter, dReal value);
+
+/**
+ * @ingroup joints
+ */
+ODE_API void dJointSetPlane2DAngleParam (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 joint parameter
+ * @ingroup joints
+ */
+ODE_API dReal dJointGetBallParam (dJointID, int parameter);
+
+/**
+ * @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.
+ * Give the relative rotation with respect to the Hinge axis of Body 1 with
+ * respect to Body 2.
+ * When the hinge anchor or axis is set, the current position of the attached
+ * bodies is examined and that position will be the zero angle.
+ * @ingroup joints
+ */
+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.
+
+ * The position is the distance, with respect to the zero position,
+ * along the slider axis of body 1 with respect to
+ * body 2. (A NULL body is replaced by the world).
+ * @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 both angles at the same time.
+ * @ingroup joints
+ *
+ * @param joint   The universal joint for which we want to calculate the angles
+ * @param angle1  The angle between the body1 and the axis 1
+ * @param angle2  The angle between the body2 and the axis 2
+ *
+ * @note This function combine getUniversalAngle1 and getUniversalAngle2 together
+ *       and try to avoid redundant calculation
+ */
+ODE_API void dJointGetUniversalAngles (dJointID, dReal *angle1, dReal *angle2);
+
+/**
+ * @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 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 dJointGetPRAnchor (dJointID, dVector3 result);
+
+/**
+ * @brief Get the PR linear position (i.e. the prismatic's extension)
+ *
+ * When the axis is set, the current position of the attached bodies is
+ * examined and that position will be the zero position.
+ *
+ * The position is the "oriented" length between the
+ * position = (Prismatic axis) dot_product [(body1 + offset) - (body2 + anchor2)]
+ *
+ * @ingroup joints
+ */
+ODE_API dReal dJointGetPRPosition (dJointID);
+
+/**
+ * @brief Get the PR linear position's time derivative
+ *
+ * @ingroup joints
+ */
+ODE_API dReal dJointGetPRPositionRate (dJointID);
+
+
+/**
+   * @brief Get the PR angular position (i.e. the  twist between the 2 bodies)
+   *
+   * 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 dJointGetPRAngle (dJointID);
+
+/**
+ * @brief Get the PR angular position's time derivative
+ *
+ * @ingroup joints
+ */
+ODE_API dReal dJointGetPRAngleRate (dJointID);
+
+
+/**
+ * @brief Get the prismatic axis
+ * @ingroup joints
+ */
+ODE_API void dJointGetPRAxis1 (dJointID, dVector3 result);
+
+/**
+ * @brief Get the Rotoide axis
+ * @ingroup joints
+ */
+ODE_API void dJointGetPRAxis2 (dJointID, dVector3 result);
+
+/**
+ * @brief get joint parameter
+ * @ingroup joints
+ */
+ODE_API dReal dJointGetPRParam (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 dJointGetPUAnchor (dJointID, dVector3 result);
+
+  /**
+   * @brief Get the PU linear position (i.e. the prismatic's extension)
+   *
+   * When the axis is set, the current position of the attached bodies is
+   * examined and that position will be the zero position.
+   *
+   * The position is the "oriented" length between the
+   * position = (Prismatic axis) dot_product [(body1 + offset) - (body2 + anchor2)]
+   *
+   * @ingroup joints
+   */
+  ODE_API dReal dJointGetPUPosition (dJointID);
+
+  /**
+   * @brief Get the PR linear position's time derivative
+   *
+   * @ingroup joints
+   */
+  ODE_API dReal dJointGetPUPositionRate (dJointID);
+
+  /**
+   * @brief Get the first axis of the universal component of the joint
+   * @ingroup joints
+   */
+  ODE_API void dJointGetPUAxis1 (dJointID, dVector3 result);
+
+  /**
+   * @brief Get the second axis of the Universal component of the joint
+   * @ingroup joints
+   */
+  ODE_API void dJointGetPUAxis2 (dJointID, dVector3 result);
+
+  /**
+   * @brief Get the prismatic axis
+   * @ingroup joints
+   */
+  ODE_API void dJointGetPUAxis3 (dJointID, dVector3 result);
+
+  /**
+   * @brief Get the prismatic axis
+   * @ingroup joints
+   *
+   * @note This function was added for convenience it is the same as
+   *       dJointGetPUAxis3
+   */
+  ODE_API void dJointGetPUAxisP (dJointID id, dVector3 result);
+
+
+
+
+  /**
+   * @brief Get both angles at the same time.
+   * @ingroup joints
+   *
+   * @param joint   The Prismatic universal joint for which we want to calculate the angles
+   * @param angle1  The angle between the body1 and the axis 1
+   * @param angle2  The angle between the body2 and the axis 2
+   *
+   * @note This function combine dJointGetPUAngle1 and dJointGetPUAngle2 together
+   *       and try to avoid redundant calculation
+   */
+  ODE_API void dJointGetPUAngles (dJointID, dReal *angle1, dReal *angle2);
+
+  /**
+   * @brief Get angle
+   * @ingroup joints
+   */
+  ODE_API dReal dJointGetPUAngle1 (dJointID);
+
+  /**
+   * @brief * @brief Get time derivative of angle1
+   *
+   * @ingroup joints
+   */
+  ODE_API dReal dJointGetPUAngle1Rate (dJointID);
+
+
+  /**
+   * @brief Get angle
+   * @ingroup joints
+   */
+  ODE_API dReal dJointGetPUAngle2 (dJointID);
+
+  /**
+   * @brief * @brief Get time derivative of angle2
+   *
+   * @ingroup joints
+   */
+  ODE_API dReal dJointGetPUAngle2Rate (dJointID);
+
+  /**
+   * @brief get joint parameter
+   * @ingroup joints
+   */
+  ODE_API dReal dJointGetPUParam (dJointID, int parameter);
+
+
+
+
+
+/**
+   * @brief Get the Piston linear position (i.e. the piston'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 dJointGetPistonPosition (dJointID);
+
+  /**
+   * @brief Get the piston linear position's time derivative.
+   * @ingroup joints
+   */
+  ODE_API dReal dJointGetPistonPositionRate (dJointID);
+
+/**
+   * @brief Get the Piston angular position (i.e. the  twist between the 2 bodies)
+   *
+   * 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 dJointGetPistonAngle (dJointID);
+
+  /**
+   * @brief Get the piston angular position's time derivative.
+   * @ingroup joints
+   */
+  ODE_API dReal dJointGetPistonAngleRate (dJointID);
+
+
+  /**
+   * @brief Get the joint anchor
+   *
+   * This returns the point on body 1. If the joint is perfectly satisfied,
+   * this will be the same as the point on body 2 in direction perpendicular
+   * to the prismatic axis.
+   *
+   * @ingroup joints
+   */
+  ODE_API void dJointGetPistonAnchor (dJointID, dVector3 result);
+
+  /**
+   * @brief Get the joint anchor w.r.t. body 2
+   *
+   * This returns the point on body 2. You can think of a Piston
+   * joint as trying to keep the result of dJointGetPistonAnchor() and
+   * dJointGetPistonAnchor2() the same in the direction perpendicular to the
+   * pirsmatic axis. If the joint is perfectly satisfied,
+   * this function will return the same value as dJointGetPistonAnchor() to
+   * within roundoff errors. dJointGetPistonAnchor2() can be used, along with
+   * dJointGetPistonAnchor(), to see how far the joint has come apart.
+   *
+   * @ingroup joints
+   */
+  ODE_API void dJointGetPistonAnchor2 (dJointID, dVector3 result);
+
+  /**
+   * @brief Get the prismatic axis (This is also the rotoide axis.
+   * @ingroup joints
+   */
+  ODE_API void dJointGetPistonAxis (dJointID, dVector3 result);
+
+  /**
+   * @brief get joint parameter
+   * @ingroup joints
+   */
+  ODE_API dReal dJointGetPistonParam (dJointID, int parameter);
+
+
+  /**
+ * @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'' modes.
+ * \li 0: The axis is anchored to the global frame.
+ * \li 1: The axis is anchored to the first body.
+ * \li 2: The axis is anchored to the second body.
+ * @ingroup joints
+ */
+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);
+
+/**
+ * @brief get joint parameter
+ * @ingroup joints
+ */
+ODE_API dReal dJointGetFixedParam (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 body1 A body to check.
+ * @param body2 A body to check.
+ * @param joint_type is a dJointTypeXXX constant.
+ * This is useful for deciding whether to add contact joints between two bodies:
+ * if they are already connected by non-contact joints then it may not be
+ * appropriate to add contacts, however it is okay to add more contact between-
+ * bodies that already have contacts.
+ * @ingroup joints
+ */
+ODE_API int dAreConnectedExcluding (dBodyID body1, dBodyID body2, int joint_type);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/misc/builddeps/dp.linux64/include/ode/ode.h b/misc/builddeps/dp.linux64/include/ode/ode.h
new file mode 100644 (file)
index 0000000..af74e50
--- /dev/null
@@ -0,0 +1,48 @@
+/*************************************************************************
+ *                                                                       *
+ * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith.       *
+ * All rights reserved.  Email: russ@q12.org   Web: www.q12.org          *
+ *                                                                       *
+ * This library is free software; you can redistribute it and/or         *
+ * modify it under the terms of EITHER:                                  *
+ *   (1) The GNU Lesser General Public License as published by the Free  *
+ *       Software Foundation; either version 2.1 of the License, or (at  *
+ *       your option) any later version. The text of the GNU Lesser      *
+ *       General Public License is included with this library in the     *
+ *       file LICENSE.TXT.                                               *
+ *   (2) The BSD-style license that is included with this library in     *
+ *       the file LICENSE-BSD.TXT.                                       *
+ *                                                                       *
+ * This library is distributed in the hope that it will be useful,       *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files    *
+ * LICENSE.TXT and LICENSE-BSD.TXT for more details.                     *
+ *                                                                       *
+ *************************************************************************/
+
+#ifndef _ODE_ODE_H_
+#define _ODE_ODE_H_
+
+/* include *everything* here */
+
+#include <ode/odeconfig.h>
+#include <ode/compatibility.h>
+#include <ode/common.h>
+#include <ode/odeinit.h>
+#include <ode/contact.h>
+#include <ode/error.h>
+#include <ode/memory.h>
+#include <ode/odemath.h>
+#include <ode/matrix.h>
+#include <ode/timer.h>
+#include <ode/rotation.h>
+#include <ode/mass.h>
+#include <ode/misc.h>
+#include <ode/objects.h>
+#include <ode/odecpp.h>
+#include <ode/collision_space.h>
+#include <ode/collision.h>
+#include <ode/odecpp_collision.h>
+#include <ode/export-dif.h>
+
+#endif
diff --git a/misc/builddeps/dp.linux64/include/ode/odeconfig.h b/misc/builddeps/dp.linux64/include/ode/odeconfig.h
new file mode 100644 (file)
index 0000000..6e32fc6
--- /dev/null
@@ -0,0 +1,93 @@
+#ifndef ODECONFIG_H
+#define ODECONFIG_H
+
+/* Pull in the standard headers */
+#include <stddef.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <math.h>
+#include <string.h>
+#include <float.h>
+
+
+#if defined(ODE_DLL) || defined(ODE_LIB)
+#define __ODE__
+#endif
+
+/* Define a DLL export symbol for those platforms that need it */
+#if defined(_MSC_VER)
+  #if defined(ODE_DLL)
+    #define ODE_API __declspec(dllexport)
+  #elif !defined(ODE_LIB)
+    #define ODE_DLL_API __declspec(dllimport)
+  #endif
+#endif
+
+#if !defined(ODE_API)
+  #define ODE_API
+#endif
+
+#if defined(_MSC_VER)
+#  define ODE_API_DEPRECATED __declspec(deprecated)
+#elif defined (__GNUC__) && ( (__GNUC__ > 3) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 1)) )
+#  define ODE_API_DEPRECATED __attribute__((__deprecated__))
+#else
+#  define ODE_API_DEPRECATED
+#endif
+
+/* Well-defined common data types...need to define for 64 bit systems */
+#if defined(_M_IA64) || defined(__ia64__) || defined(_M_AMD64) || defined(__x86_64__)
+  #define X86_64_SYSTEM   1
+  typedef int             int32;
+  typedef unsigned int    uint32;
+  typedef short           int16;
+  typedef unsigned short  uint16;
+  typedef signed char     int8;
+  typedef unsigned char   uint8;
+#else
+  typedef int             int32;
+  typedef unsigned int    uint32;
+  typedef short           int16;
+  typedef unsigned short  uint16;
+  typedef signed char     int8;
+  typedef unsigned char   uint8;
+#endif
+
+/* Visual C does not define these functions */
+#if defined(_MSC_VER)
+  #define copysignf(x, y) ((float)_copysign(x, y))
+  #define copysign(x, y) _copysign(x, y)
+  #define nextafterf(x, y) _nextafterf(x, y)
+  #define nextafter(x, y) _nextafter(x, y)
+  #if !defined(_WIN64)
+    #define _ODE__NEXTAFTERF_REQUIRED
+  #endif
+#endif
+
+
+
+/* Define the dInfinity macro */
+#ifdef INFINITY
+  #define dInfinity INFINITY
+#elif defined(HUGE_VAL)
+  #ifdef dSINGLE
+    #ifdef HUGE_VALF
+      #define dInfinity HUGE_VALF
+    #else
+      #define dInfinity ((float)HUGE_VAL)
+    #endif
+  #else
+    #define dInfinity HUGE_VAL
+  #endif
+#else
+  #ifdef dSINGLE
+    #define dInfinity ((float)(1.0/0.0))
+  #else
+    #define dInfinity (1.0/0.0)
+  #endif
+#endif
+
+
+#endif
diff --git a/misc/builddeps/dp.linux64/include/ode/odecpp.h b/misc/builddeps/dp.linux64/include/ode/odecpp.h
new file mode 100644 (file)
index 0000000..f734892
--- /dev/null
@@ -0,0 +1,1353 @@
+/*************************************************************************
+ *                                                                      *
+ * Open Dynamics Engine, Copyright (C) 2001, 2002 Russell L. Smith.     *
+ * All rights reserved.  Email: russ@q12.org   Web: www.q12.org         *
+ *                                                                      *
+ * This library is free software; you can redistribute it and/or        *
+ * modify it under the terms of EITHER:                                 *
+ *   (1) The GNU Lesser General Public License as published by the Free  *
+ *      Software Foundation; either version 2.1 of the License, or (at  *
+ *      your option) any later version. The text of the GNU Lesser      *
+ *      General Public License is included with this library in the     *
+ *      file LICENSE.TXT.                                               *
+ *   (2) The BSD-style license that is included with this library in    *
+ *      the file LICENSE-BSD.TXT.                                       *
+ *                                                                      *
+ * This library is distributed in the hope that it will be useful,      *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of       *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files   *
+ * LICENSE.TXT and LICENSE-BSD.TXT for more details.                    *
+ *                                                                      *
+ *************************************************************************/
+
+/* C++ interface for non-collision stuff */
+
+
+#ifndef _ODE_ODECPP_H_
+#define _ODE_ODECPP_H_
+#ifdef __cplusplus
+
+
+
+
+//namespace ode {
+
+
+class dWorldSimpleIDContainer {
+protected:
+       dWorldID _id;
+
+       dWorldSimpleIDContainer(): _id(0) {}
+       ~dWorldSimpleIDContainer() { destroy(); }
+
+       void destroy() { 
+               if (_id) {
+                       dWorldDestroy(_id); 
+                       _id = 0;
+               }
+       }
+};
+
+class dWorldDynamicIDContainer: public dWorldSimpleIDContainer {
+protected:
+       virtual ~dWorldDynamicIDContainer() {}
+};
+
+template <class dWorldTemplateBase>
+class dWorldTemplate: public dWorldTemplateBase {
+  // intentionally undefined, don't use these
+  dWorldTemplate (const dWorldTemplate<dWorldTemplateBase> &);
+  void operator= (const dWorldTemplate<dWorldTemplateBase> &);
+
+protected:
+  dWorldID get_id() const { return dWorldTemplateBase::_id; }
+  void set_id(dWorldID value) { dWorldTemplateBase::_id = value; }
+
+public:
+  dWorldTemplate()
+    { set_id(dWorldCreate()); }
+
+  dWorldID id() const
+    { return get_id(); }
+  operator dWorldID() const
+    { return get_id(); }
+
+  void setGravity (dReal x, dReal y, dReal z)
+    { dWorldSetGravity (get_id(), x, y, z); }
+  void setGravity (const dVector3 g)
+    { setGravity (g[0], g[1], g[2]); }
+  void getGravity (dVector3 g) const
+    { dWorldGetGravity (get_id(), g); }
+
+  void setERP (dReal erp)
+    { dWorldSetERP(get_id(), erp); }
+  dReal getERP() const
+    { return dWorldGetERP(get_id()); }
+
+  void setCFM (dReal cfm)
+    { dWorldSetCFM(get_id(), cfm); }
+  dReal getCFM() const
+    { return dWorldGetCFM(get_id()); }
+
+  void step (dReal stepsize)
+    { dWorldStep (get_id(), stepsize); }
+
+  void quickStep(dReal stepsize)
+    { dWorldQuickStep (get_id(), stepsize); }
+  void setQuickStepNumIterations(int num)
+    { dWorldSetQuickStepNumIterations (get_id(), num); }
+  int getQuickStepNumIterations() const
+    { return dWorldGetQuickStepNumIterations (get_id()); }
+  void setQuickStepW(dReal over_relaxation)
+    { dWorldSetQuickStepW (get_id(), over_relaxation); }
+  dReal getQuickStepW() const
+    { return dWorldGetQuickStepW (get_id()); }
+
+  void  setAutoDisableLinearThreshold (dReal threshold) 
+    { dWorldSetAutoDisableLinearThreshold (get_id(), threshold); }
+  dReal getAutoDisableLinearThreshold() const
+    { return dWorldGetAutoDisableLinearThreshold (get_id()); }
+  void setAutoDisableAngularThreshold (dReal threshold)
+    { dWorldSetAutoDisableAngularThreshold (get_id(), threshold); }
+  dReal getAutoDisableAngularThreshold() const
+    { return dWorldGetAutoDisableAngularThreshold (get_id()); }
+  void setAutoDisableSteps (int steps)
+    { dWorldSetAutoDisableSteps (get_id(), steps); }
+  int getAutoDisableSteps() const
+    { return dWorldGetAutoDisableSteps (get_id()); }
+  void setAutoDisableTime (dReal time)
+    { dWorldSetAutoDisableTime (get_id(), time); }
+  dReal getAutoDisableTime() const
+    { return dWorldGetAutoDisableTime (get_id()); }
+  void setAutoDisableFlag (int do_auto_disable)
+    { dWorldSetAutoDisableFlag (get_id(), do_auto_disable); }
+  int getAutoDisableFlag() const
+    { return dWorldGetAutoDisableFlag (get_id()); }
+
+  dReal getLinearDampingThreshold() const
+    { return dWorldGetLinearDampingThreshold(get_id()); }
+  void setLinearDampingThreshold(dReal threshold)
+    { dWorldSetLinearDampingThreshold(get_id(), threshold); }
+  dReal getAngularDampingThreshold() const
+    { return dWorldGetAngularDampingThreshold(get_id()); }
+  void setAngularDampingThreshold(dReal threshold)
+    { dWorldSetAngularDampingThreshold(get_id(), threshold); }
+  dReal getLinearDamping() const
+    { return dWorldGetLinearDamping(get_id()); }
+  void setLinearDamping(dReal scale)
+    { dWorldSetLinearDamping(get_id(), scale); }
+  dReal getAngularDamping() const
+    { return dWorldGetAngularDamping(get_id()); }
+  void setAngularDamping(dReal scale)
+    { dWorldSetAngularDamping(get_id(), scale); }
+  void setDamping(dReal linear_scale, dReal angular_scale)
+    { dWorldSetDamping(get_id(), linear_scale, angular_scale); }
+
+  dReal getMaxAngularSpeed() const
+    { return dWorldGetMaxAngularSpeed(get_id()); }
+  void setMaxAngularSpeed(dReal max_speed)
+    { dWorldSetMaxAngularSpeed(get_id(), max_speed); }
+
+  void setContactSurfaceLayer(dReal depth)
+    { dWorldSetContactSurfaceLayer (get_id(), depth); }
+  dReal getContactSurfaceLayer() const
+    { return dWorldGetContactSurfaceLayer (get_id()); }
+
+  void impulseToForce (dReal stepsize, dReal ix, dReal iy, dReal iz, 
+                      dVector3 force)
+    { dWorldImpulseToForce (get_id(), stepsize, ix, iy, iz, force); }
+};
+
+
+class dBodySimpleIDContainer {
+protected:
+       dBodyID _id;
+
+       dBodySimpleIDContainer(): _id(0) {}
+       ~dBodySimpleIDContainer() { destroy(); }
+
+       void destroy() { 
+               if (_id) {
+                       dBodyDestroy(_id); 
+                       _id = 0;
+               }
+       }
+};
+
+class dBodyDynamicIDContainer: public dBodySimpleIDContainer {
+protected:
+       virtual ~dBodyDynamicIDContainer() {}
+};
+
+template <class dBodyTemplateBase, class dWorldTemplateBase>
+class dBodyTemplate: public dBodyTemplateBase {
+  // intentionally undefined, don't use these
+  dBodyTemplate (const dBodyTemplate<dBodyTemplateBase, dWorldTemplateBase> &);
+  void operator= (const dBodyTemplate<dBodyTemplateBase, dWorldTemplateBase> &);
+
+protected:
+  dBodyID get_id() const { return dBodyTemplateBase::_id; }
+  void set_id(dBodyID value) { dBodyTemplateBase::_id = value; }
+
+  void destroy() { dBodyTemplateBase::destroy(); }
+
+public:
+  dBodyTemplate()
+    { }
+  dBodyTemplate (dWorldID world)
+    { set_id(dBodyCreate(world)); }
+  dBodyTemplate (dWorldTemplate<dWorldTemplateBase>& world)
+    { set_id(dBodyCreate(world.id())); }
+
+  void create (dWorldID world) {
+    destroy();
+    set_id(dBodyCreate(world));
+  }
+  void create (dWorldTemplate<dWorldTemplateBase>& world) {
+    create(world.id());
+  }
+
+  dBodyID id() const
+    { return get_id(); }
+  operator dBodyID() const
+    { return get_id(); }
+
+  void setData (void *data)
+    { dBodySetData (get_id(), data); }
+  void *getData() const
+    { return dBodyGetData (get_id()); }
+
+  void setPosition (dReal x, dReal y, dReal z)
+    { dBodySetPosition (get_id(), x, y, z); }
+  void setPosition (const dVector3 p)
+    { setPosition(p[0], p[1], p[2]); }
+
+  void setRotation (const dMatrix3 R)
+    { dBodySetRotation (get_id(), R); }
+  void setQuaternion (const dQuaternion q)
+    { dBodySetQuaternion (get_id(), q); }
+  void setLinearVel (dReal x, dReal y, dReal z)
+    { dBodySetLinearVel (get_id(), x, y, z); }
+  void setLinearVel (const dVector3 v)
+    { setLinearVel(v[0], v[1], v[2]); }
+  void setAngularVel (dReal x, dReal y, dReal z)
+    { dBodySetAngularVel (get_id(), x, y, z); }
+  void setAngularVel (const dVector3 v)
+    { setAngularVel (v[0], v[1], v[2]); }
+
+  const dReal * getPosition() const
+    { return dBodyGetPosition (get_id()); }
+  const dReal * getRotation() const
+    { return dBodyGetRotation (get_id()); }
+  const dReal * getQuaternion() const
+    { return dBodyGetQuaternion (get_id()); }
+  const dReal * getLinearVel() const
+    { return dBodyGetLinearVel (get_id()); }
+  const dReal * getAngularVel() const
+    { return dBodyGetAngularVel (get_id()); }
+
+  void setMass (const dMass *mass)
+    { dBodySetMass (get_id(), mass); }
+  void setMass (const dMass &mass)
+    { setMass (&mass); }
+  dMass getMass () const
+    { dMass mass; dBodyGetMass (get_id(), &mass); return mass; }
+
+  void addForce (dReal fx, dReal fy, dReal fz)
+    { dBodyAddForce (get_id(), fx, fy, fz); }
+  void addForce (const dVector3 f)
+    { addForce (f[0], f[1], f[2]); }
+  void addTorque (dReal fx, dReal fy, dReal fz)
+    { dBodyAddTorque (get_id(), fx, fy, fz); }
+  void addTorque (const dVector3 t)
+    { addTorque(t[0], t[1], t[2]); }
+
+  void addRelForce (dReal fx, dReal fy, dReal fz)
+    { dBodyAddRelForce (get_id(), fx, fy, fz); }
+  void addRelForce (const dVector3 f)
+    { addRelForce (f[0], f[1], f[2]); }
+  void addRelTorque (dReal fx, dReal fy, dReal fz)
+    { dBodyAddRelTorque (get_id(), fx, fy, fz); }
+  void addRelTorque (const dVector3 t)
+    { addRelTorque (t[0], t[1], t[2]); }
+
+  void addForceAtPos (dReal fx, dReal fy, dReal fz, 
+                     dReal px, dReal py, dReal pz)
+    { dBodyAddForceAtPos (get_id(), fx, fy, fz, px, py, pz); }
+  void addForceAtPos (const dVector3 f, const dVector3 p)
+    { addForceAtPos (f[0], f[1], f[2], p[0], p[1], p[2]); }
+
+  void addForceAtRelPos (dReal fx, dReal fy, dReal fz, 
+                         dReal px, dReal py, dReal pz)
+    { dBodyAddForceAtRelPos (get_id(), fx, fy, fz, px, py, pz); }
+  void addForceAtRelPos (const dVector3 f, const dVector3 p)
+    { addForceAtRelPos (f[0], f[1], f[2], p[0], p[1], p[2]); }
+
+  void addRelForceAtPos (dReal fx, dReal fy, dReal fz, 
+                        dReal px, dReal py, dReal pz)
+    { dBodyAddRelForceAtPos (get_id(), fx, fy, fz, px, py, pz); }
+  void addRelForceAtPos (const dVector3 f, const dVector3 p)
+    { addRelForceAtPos (f[0], f[1], f[2], p[0], p[1], p[2]); }
+
+  void addRelForceAtRelPos (dReal fx, dReal fy, dReal fz, 
+                           dReal px, dReal py, dReal pz)
+    { dBodyAddRelForceAtRelPos (get_id(), fx, fy, fz, px, py, pz); }
+  void addRelForceAtRelPos (const dVector3 f, const dVector3 p)
+    { addRelForceAtRelPos (f[0], f[1], f[2], p[0], p[1], p[2]); }
+
+  const dReal * getForce() const
+    { return dBodyGetForce(get_id()); }
+  const dReal * getTorque() const
+    { return dBodyGetTorque(get_id()); }
+  void setForce (dReal x, dReal y, dReal z)
+    { dBodySetForce (get_id(), x, y, z); }
+  void setForce (const dVector3 f)
+    { setForce (f[0], f[1], f[2]); }
+  void setTorque (dReal x, dReal y, dReal z)
+    { dBodySetTorque (get_id(), x, y, z); }
+  void setTorque (const dVector3 t)
+  { setTorque (t[0], t[1], t[2]); }
+
+  void setDynamic()
+    { dBodySetDynamic (get_id()); }
+  void setKinematic()
+    { dBodySetKinematic (get_id()); }
+  bool isKinematic() const
+    { return dBodyIsKinematic (get_id()) != 0; }
+
+  void enable()
+    { dBodyEnable (get_id()); }
+  void disable()
+    { dBodyDisable (get_id()); }
+  bool isEnabled() const
+    { return dBodyIsEnabled (get_id()) != 0; }
+
+  void getRelPointPos (dReal px, dReal py, dReal pz, dVector3 result) const
+    { dBodyGetRelPointPos (get_id(), px, py, pz, result); }
+  void getRelPointPos (const dVector3 p, dVector3 result) const
+    { getRelPointPos (p[0], p[1], p[2], result); }
+
+  void getRelPointVel (dReal px, dReal py, dReal pz, dVector3 result) const
+    { dBodyGetRelPointVel (get_id(), px, py, pz, result); }
+  void getRelPointVel (const dVector3 p, dVector3 result) const
+    { getRelPointVel (p[0], p[1], p[2], result); }
+
+  void getPointVel (dReal px, dReal py, dReal pz, dVector3 result) const
+    { dBodyGetPointVel (get_id(), px, py, pz, result); }
+  void getPointVel (const dVector3 p, dVector3 result) const
+    { getPointVel (p[0], p[1], p[2], result); }
+
+  void getPosRelPoint (dReal px, dReal py, dReal pz, dVector3 result) const
+    { dBodyGetPosRelPoint (get_id(), px, py, pz, result); }
+  void getPosRelPoint (const dVector3 p, dVector3 result) const
+    { getPosRelPoint (p[0], p[1], p[2], result); }
+
+  void vectorToWorld (dReal px, dReal py, dReal pz, dVector3 result) const
+    { dBodyVectorToWorld (get_id(), px, py, pz, result); }
+  void vectorToWorld (const dVector3 p, dVector3 result) const
+    { vectorToWorld (p[0], p[1], p[2], result); }
+
+  void vectorFromWorld (dReal px, dReal py, dReal pz, dVector3 result) const
+    { dBodyVectorFromWorld (get_id(), px, py, pz, result); }
+  void vectorFromWorld (const dVector3 p, dVector3 result) const
+    { vectorFromWorld (p[0], p[1], p[2], result); }
+
+  void setFiniteRotationMode (bool mode)
+    { dBodySetFiniteRotationMode (get_id(), mode); }
+
+  void setFiniteRotationAxis (dReal x, dReal y, dReal z)
+    { dBodySetFiniteRotationAxis (get_id(), x, y, z); }
+  void setFiniteRotationAxis (const dVector3 a)
+    { setFiniteRotationAxis (a[0], a[1], a[2]); }
+
+  bool getFiniteRotationMode() const
+    { return dBodyGetFiniteRotationMode (get_id()) != 0; }
+  void getFiniteRotationAxis (dVector3 result) const
+    { dBodyGetFiniteRotationAxis (get_id(), result); }
+
+  int getNumJoints() const
+    { return dBodyGetNumJoints (get_id()); }
+  dJointID getJoint (int index) const
+    { return dBodyGetJoint (get_id(), index); }
+
+  void setGravityMode (bool mode)
+    { dBodySetGravityMode (get_id(), mode); }
+  bool getGravityMode() const
+    { return dBodyGetGravityMode (get_id()) != 0; }
+
+  bool isConnectedTo (dBodyID body) const
+    { return dAreConnected (get_id(), body) != 0; }
+
+  void  setAutoDisableLinearThreshold (dReal threshold) 
+    { dBodySetAutoDisableLinearThreshold (get_id(), threshold); }
+  dReal getAutoDisableLinearThreshold() const
+    { return dBodyGetAutoDisableLinearThreshold (get_id()); }
+  void setAutoDisableAngularThreshold (dReal threshold)
+    { dBodySetAutoDisableAngularThreshold (get_id(), threshold); }
+  dReal getAutoDisableAngularThreshold() const
+    { return dBodyGetAutoDisableAngularThreshold (get_id()); }
+  void setAutoDisableSteps (int steps)
+    { dBodySetAutoDisableSteps (get_id(), steps); }
+  int getAutoDisableSteps() const
+    { return dBodyGetAutoDisableSteps (get_id()); }
+  void setAutoDisableTime (dReal time)
+    { dBodySetAutoDisableTime (get_id(), time); }
+  dReal getAutoDisableTime() const
+    { return dBodyGetAutoDisableTime (get_id()); }
+  void setAutoDisableFlag (bool do_auto_disable)
+    { dBodySetAutoDisableFlag (get_id(), do_auto_disable); }
+  bool getAutoDisableFlag() const
+    { return dBodyGetAutoDisableFlag (get_id()) != 0; }
+
+  dReal getLinearDamping() const
+    { return dBodyGetLinearDamping(get_id()); }
+  void setLinearDamping(dReal scale)
+    { dBodySetLinearDamping(get_id(), scale); }
+  dReal getAngularDamping() const
+    { return dBodyGetAngularDamping(get_id()); }
+  void setAngularDamping(dReal scale)
+    { dBodySetAngularDamping(get_id(), scale); }
+  void setDamping(dReal linear_scale, dReal angular_scale)
+    { dBodySetDamping(get_id(), linear_scale, angular_scale); }
+  dReal getLinearDampingThreshold() const
+    { return dBodyGetLinearDampingThreshold(get_id()); }
+  void setLinearDampingThreshold(dReal threshold) const
+    { dBodySetLinearDampingThreshold(get_id(), threshold); }
+  dReal getAngularDampingThreshold() const
+    { return dBodyGetAngularDampingThreshold(get_id()); }
+  void setAngularDampingThreshold(dReal threshold)
+    { dBodySetAngularDampingThreshold(get_id(), threshold); }
+  void setDampingDefaults()
+    { dBodySetDampingDefaults(get_id()); }
+
+  dReal getMaxAngularSpeed() const
+    { return dBodyGetMaxAngularSpeed(get_id()); }
+  void setMaxAngularSpeed(dReal max_speed)
+    { dBodySetMaxAngularSpeed(get_id(), max_speed); }
+
+  bool getGyroscopicMode() const
+    { return dBodyGetGyroscopicMode(get_id()) != 0; }
+  void setGyroscopicMode(bool mode)
+    { dBodySetGyroscopicMode(get_id(), mode); }
+
+};
+
+
+class dJointGroupSimpleIDContainer {
+protected:
+       dJointGroupID _id;
+
+       dJointGroupSimpleIDContainer(): _id(0) {}
+       ~dJointGroupSimpleIDContainer() { destroy(); }
+
+       void destroy() { 
+               if (_id) {
+                       dJointGroupDestroy(_id); 
+                       _id = 0;
+               }
+       }
+};
+
+class dJointGroupDynamicIDContainer: public dJointGroupSimpleIDContainer {
+protected:
+       virtual ~dJointGroupDynamicIDContainer() {}
+};
+
+template <class dJointGroupTemplateBase>
+class dJointGroupTemplate: public dJointGroupTemplateBase {
+  // intentionally undefined, don't use these
+  dJointGroupTemplate (const dJointGroupTemplate<dJointGroupTemplateBase> &);
+  void operator= (const dJointGroupTemplate<dJointGroupTemplateBase> &);
+
+protected:
+  dJointGroupID get_id() const { return dJointGroupTemplateBase::_id; }
+  void set_id(dJointGroupID value) { dJointGroupTemplateBase::_id = value; }
+
+  void destroy() { dJointGroupTemplateBase::destroy(); }
+
+public:
+  dJointGroupTemplate ()
+    { set_id(dJointGroupCreate(0)); }
+  
+  void create () {
+    destroy();
+    set_id(dJointGroupCreate(0));
+  }
+
+  dJointGroupID id() const
+    { return get_id(); }
+  operator dJointGroupID() const
+    { return get_id(); }
+
+  void empty()
+    { dJointGroupEmpty (get_id()); }
+  void clear()
+    { empty(); }
+};
+
+
+class dJointSimpleIDContainer {
+protected:
+       dJointID _id;
+
+       dJointSimpleIDContainer(): _id(0) {}
+       ~dJointSimpleIDContainer() { destroy(); }
+
+       void destroy() { 
+               if (_id) {
+                       dJointDestroy (_id); 
+                       _id = 0;
+               }
+       }
+};
+
+class dJointDynamicIDContainer: public dJointSimpleIDContainer {
+protected:
+       virtual ~dJointDynamicIDContainer() {}
+};
+
+template <class dJointTemplateBase, class dWorldTemplateBase, class dBodyTemplateBase>
+class dJointTemplate: public dJointTemplateBase {
+private:
+  // intentionally undefined, don't use these
+  dJointTemplate (const dJointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase> &) ;
+  void operator= (const dJointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase> &);
+
+protected:
+  dJointID get_id() const { return dJointTemplateBase::_id; }
+  void set_id(dJointID value) { dJointTemplateBase::_id = value; }
+
+  void destroy() { dJointTemplateBase::destroy(); }
+
+protected:
+  dJointTemplate() // don't let user construct pure dJointTemplate objects
+    { }
+
+public:
+  dJointID id() const
+    { return get_id(); }
+  operator dJointID() const
+    { return get_id(); }
+
+  int getNumBodies() const
+    { return dJointGetNumBodies(get_id()); }
+
+  void attach (dBodyID body1, dBodyID body2)
+    { dJointAttach (get_id(), body1, body2); }
+  void attach (dBodyTemplate<dBodyTemplateBase, dWorldTemplateBase>& body1, dBodyTemplate<dBodyTemplateBase, dWorldTemplateBase>& body2)
+    { attach(body1.id(), body2.id()); }
+
+  void enable()
+    { dJointEnable (get_id()); }
+  void disable()
+    { dJointDisable (get_id()); }
+  bool isEnabled() const
+    { return dJointIsEnabled (get_id()) != 0; }
+
+  void setData (void *data)
+    { dJointSetData (get_id(), data); }
+  void *getData() const
+    { return dJointGetData (get_id()); }
+
+  dJointType getType() const
+    { return dJointGetType (get_id()); }
+
+  dBodyID getBody (int index) const
+    { return dJointGetBody (get_id(), index); }
+
+  void setFeedback(dJointFeedback *fb)
+    { dJointSetFeedback(get_id(), fb); }
+  dJointFeedback *getFeedback() const
+    { return dJointGetFeedback(get_id()); }
+
+  // If not implemented it will do nothing as describe in the doc
+  virtual void setParam (int, dReal) {};
+  virtual dReal getParam (int) const { return 0; }
+};
+
+
+template <class dJointTemplateBase, class dWorldTemplateBase, class dBodyTemplateBase>
+class dBallJointTemplate : public dJointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase> {
+private:
+  // intentionally undefined, don't use these
+  dBallJointTemplate (const dBallJointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase> &);
+  void operator= (const dBallJointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase> &);
+
+protected:
+  typedef dJointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase> dBaseTemplate;
+
+  dJointID get_id() const { return dBaseTemplate::get_id(); }
+  void set_id(dJointID value) { dBaseTemplate::set_id(value); }
+
+  void destroy() { dBaseTemplate::destroy(); }
+
+public:
+  dBallJointTemplate() { }
+  dBallJointTemplate (dWorldID world, dJointGroupID group=0)
+    { set_id(dJointCreateBall(world, group)); }
+  dBallJointTemplate (dWorldTemplate<dWorldTemplateBase>& world, dJointGroupID group=0)
+    { set_id(dJointCreateBall(world.id(), group)); }
+
+  void create (dWorldID world, dJointGroupID group=0) {
+    destroy();
+    set_id(dJointCreateBall(world, group));
+  }
+  void create (dWorldTemplate<dWorldTemplateBase>& world, dJointGroupID group=0)
+    { create(world.id(), group); }
+
+  void setAnchor (dReal x, dReal y, dReal z)
+    { dJointSetBallAnchor (get_id(), x, y, z); }
+  void setAnchor (const dVector3 a)
+    { setAnchor (a[0], a[1], a[2]); }
+  void getAnchor (dVector3 result) const
+    { dJointGetBallAnchor (get_id(), result); }
+  void getAnchor2 (dVector3 result) const
+    { dJointGetBallAnchor2 (get_id(), result); }
+  virtual void setParam (int parameter, dReal value)
+    { dJointSetBallParam (get_id(), parameter, value); }
+  virtual dReal getParam (int parameter) const
+    { return dJointGetBallParam (get_id(), parameter); }
+  // TODO: expose params through methods
+} ;
+
+
+template <class dJointTemplateBase, class dWorldTemplateBase, class dBodyTemplateBase>
+class dHingeJointTemplate : public dJointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase> {
+private:
+  // intentionally undefined, don't use these
+  dHingeJointTemplate (const dHingeJointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase> &);
+  void operator = (const dHingeJointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase> &);
+
+protected:
+  typedef dJointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase> dBaseTemplate;
+
+  dJointID get_id() const { return dBaseTemplate::get_id(); }
+  void set_id(dJointID value) { dBaseTemplate::set_id(value); }
+
+  void destroy() { dBaseTemplate::destroy(); }
+
+public:
+  dHingeJointTemplate() { }
+  dHingeJointTemplate (dWorldID world, dJointGroupID group=0)
+    { set_id(dJointCreateHinge(world, group)); }
+  dHingeJointTemplate (dWorldTemplate<dWorldTemplateBase>& world, dJointGroupID group=0)
+    { set_id(dJointCreateHinge(world.id(), group)); }
+
+  void create (dWorldID world, dJointGroupID group=0) {
+    destroy();
+    set_id(dJointCreateHinge (world, group));
+  }
+  void create (dWorldTemplate<dWorldTemplateBase>& world, dJointGroupID group=0)
+    { create(world.id(), group); }
+  
+  void setAnchor (dReal x, dReal y, dReal z)
+    { dJointSetHingeAnchor (get_id(), x, y, z); }
+  void setAnchor (const dVector3 a)
+    { setAnchor (a[0], a[1], a[2]); }
+  void getAnchor (dVector3 result) const
+    { dJointGetHingeAnchor (get_id(), result); }
+  void getAnchor2 (dVector3 result) const
+    { dJointGetHingeAnchor2 (get_id(), result); }
+
+  void setAxis (dReal x, dReal y, dReal z)
+    { dJointSetHingeAxis (get_id(), x, y, z); }
+  void setAxis (const dVector3 a)
+    { setAxis(a[0], a[1], a[2]); }
+  void getAxis (dVector3 result) const
+    { dJointGetHingeAxis (get_id(), result); }
+
+  dReal getAngle() const
+    { return dJointGetHingeAngle (get_id()); }
+  dReal getAngleRate() const
+    { return dJointGetHingeAngleRate (get_id()); }
+
+  virtual void setParam (int parameter, dReal value)
+    { dJointSetHingeParam (get_id(), parameter, value); }
+  virtual dReal getParam (int parameter) const
+    { return dJointGetHingeParam (get_id(), parameter); }
+  // TODO: expose params through methods
+
+  void addTorque (dReal torque)
+       { dJointAddHingeTorque(get_id(), torque); }
+};
+
+
+template <class dJointTemplateBase, class dWorldTemplateBase, class dBodyTemplateBase>
+class dSliderJointTemplate : public dJointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase> {
+private:
+  // intentionally undefined, don't use these
+  dSliderJointTemplate (const dSliderJointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase> &);
+  void operator = (const dSliderJointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase> &);
+
+protected:
+  typedef dJointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase> dBaseTemplate;
+
+  dJointID get_id() const { return dBaseTemplate::get_id(); }
+  void set_id(dJointID value) { dBaseTemplate::set_id(value); }
+
+  void destroy() { dBaseTemplate::destroy(); }
+
+public:
+  dSliderJointTemplate() { }
+  dSliderJointTemplate (dWorldID world, dJointGroupID group=0)
+    { set_id(dJointCreateSlider(world, group)); }
+  dSliderJointTemplate (dWorldTemplate<dWorldTemplateBase>& world, dJointGroupID group=0)
+    { set_id(dJointCreateSlider(world.id(), group)); }
+
+  void create (dWorldID world, dJointGroupID group=0) {
+    destroy();
+    set_id(dJointCreateSlider(world, group));
+  }
+  void create (dWorldTemplate<dWorldTemplateBase>& world, dJointGroupID group=0)
+    { create(world.id(), group); }
+
+  void setAxis (dReal x, dReal y, dReal z)
+    { dJointSetSliderAxis (get_id(), x, y, z); }
+  void setAxis (const dVector3 a)
+    { setAxis (a[0], a[1], a[2]); }
+  void getAxis (dVector3 result) const
+    { dJointGetSliderAxis (get_id(), result); }
+
+  dReal getPosition() const
+    { return dJointGetSliderPosition (get_id()); }
+  dReal getPositionRate() const
+    { return dJointGetSliderPositionRate (get_id()); }
+
+  virtual void setParam (int parameter, dReal value)
+    { dJointSetSliderParam (get_id(), parameter, value); }
+  virtual dReal getParam (int parameter) const
+    { return dJointGetSliderParam (get_id(), parameter); }
+  // TODO: expose params through methods
+
+  void addForce (dReal force)
+       { dJointAddSliderForce(get_id(), force); }
+};
+
+
+template <class dJointTemplateBase, class dWorldTemplateBase, class dBodyTemplateBase>
+class dUniversalJointTemplate : public dJointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase> {
+private:
+  // intentionally undefined, don't use these
+  dUniversalJointTemplate (const dUniversalJointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase> &);
+  void operator = (const dUniversalJointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase> &);
+
+protected:
+  typedef dJointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase> dBaseTemplate;
+
+  dJointID get_id() const { return dBaseTemplate::get_id(); }
+  void set_id(dJointID value) { dBaseTemplate::set_id(value); }
+
+  void destroy() { dBaseTemplate::destroy(); }
+
+public:
+  dUniversalJointTemplate() { }
+  dUniversalJointTemplate (dWorldID world, dJointGroupID group=0)
+    { set_id(dJointCreateUniversal(world, group)); }
+  dUniversalJointTemplate (dWorldTemplate<dWorldTemplateBase>& world, dJointGroupID group=0)
+    { set_id(dJointCreateUniversal(world.id(), group)); }
+
+  void create (dWorldID world, dJointGroupID group=0) {
+    destroy();
+    set_id(dJointCreateUniversal(world, group));
+  }
+  void create (dWorldTemplate<dWorldTemplateBase>& world, dJointGroupID group=0)
+    { create(world.id(), group); }
+
+  void setAnchor (dReal x, dReal y, dReal z)
+    { dJointSetUniversalAnchor (get_id(), x, y, z); }
+  void setAnchor (const dVector3 a)
+    { setAnchor(a[0], a[1], a[2]); }
+  void setAxis1 (dReal x, dReal y, dReal z)
+    { dJointSetUniversalAxis1 (get_id(), x, y, z); }
+  void setAxis1 (const dVector3 a)
+    { setAxis1 (a[0], a[1], a[2]); }
+  void setAxis2 (dReal x, dReal y, dReal z)
+    { dJointSetUniversalAxis2 (get_id(), x, y, z); }
+  void setAxis2 (const dVector3 a)
+    { setAxis2 (a[0], a[1], a[2]); }
+
+  void getAnchor (dVector3 result) const
+    { dJointGetUniversalAnchor (get_id(), result); }
+  void getAnchor2 (dVector3 result) const
+    { dJointGetUniversalAnchor2 (get_id(), result); }
+  void getAxis1 (dVector3 result) const
+    { dJointGetUniversalAxis1 (get_id(), result); }
+  void getAxis2 (dVector3 result) const
+    { dJointGetUniversalAxis2 (get_id(), result); }
+
+  virtual void setParam (int parameter, dReal value)
+    { dJointSetUniversalParam (get_id(), parameter, value); }
+  virtual dReal getParam (int parameter) const
+    { return dJointGetUniversalParam (get_id(), parameter); }
+  // TODO: expose params through methods
+  
+  void getAngles(dReal *angle1, dReal *angle2) const
+    { dJointGetUniversalAngles (get_id(), angle1, angle2); }
+
+  dReal getAngle1() const
+    { return dJointGetUniversalAngle1 (get_id()); }
+  dReal getAngle1Rate() const
+    { return dJointGetUniversalAngle1Rate (get_id()); }
+  dReal getAngle2() const
+    { return dJointGetUniversalAngle2 (get_id()); }
+  dReal getAngle2Rate() const
+    { return dJointGetUniversalAngle2Rate (get_id()); }
+
+  void addTorques (dReal torque1, dReal torque2)
+       { dJointAddUniversalTorques(get_id(), torque1, torque2); }
+};
+
+
+template <class dJointTemplateBase, class dWorldTemplateBase, class dBodyTemplateBase>
+class dHinge2JointTemplate : public dJointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase> {
+private:
+  // intentionally undefined, don't use these
+  dHinge2JointTemplate (const dHinge2JointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase> &);
+  void operator = (const dHinge2JointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase> &);
+
+protected:
+  typedef dJointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase> dBaseTemplate;
+
+  dJointID get_id() const { return dBaseTemplate::get_id(); }
+  void set_id(dJointID value) { dBaseTemplate::set_id(value); }
+
+  void destroy() { dBaseTemplate::destroy(); }
+
+public:
+  dHinge2JointTemplate() { }
+  dHinge2JointTemplate (dWorldID world, dJointGroupID group=0)
+    { set_id(dJointCreateHinge2(world, group)); }
+  dHinge2JointTemplate (dWorldTemplate<dWorldTemplateBase>& world, dJointGroupID group=0)
+    { set_id(dJointCreateHinge2(world.id(), group)); }
+
+  void create (dWorldID world, dJointGroupID group=0) {
+    destroy();
+    set_id(dJointCreateHinge2(world, group));
+  }
+  void create (dWorldTemplate<dWorldTemplateBase>& world, dJointGroupID group=0)
+    { create(world.id(), group); }
+
+  void setAnchor (dReal x, dReal y, dReal z)
+    { dJointSetHinge2Anchor (get_id(), x, y, z); }
+  void setAnchor (const dVector3 a)
+    { setAnchor(a[0], a[1], a[2]); }
+  void setAxis1 (dReal x, dReal y, dReal z)
+    { dJointSetHinge2Axis1 (get_id(), x, y, z); }
+  void setAxis1 (const dVector3 a)
+    { setAxis1 (a[0], a[1], a[2]); }
+  void setAxis2 (dReal x, dReal y, dReal z)
+    { dJointSetHinge2Axis2 (get_id(), x, y, z); }
+  void setAxis2 (const dVector3 a)
+    { setAxis2 (a[0], a[1], a[2]); }
+    
+  void getAnchor (dVector3 result) const
+    { dJointGetHinge2Anchor (get_id(), result); }
+  void getAnchor2 (dVector3 result) const
+    { dJointGetHinge2Anchor2 (get_id(), result); }
+  void getAxis1 (dVector3 result) const
+    { dJointGetHinge2Axis1 (get_id(), result); }
+  void getAxis2 (dVector3 result) const
+    { dJointGetHinge2Axis2 (get_id(), result); }
+
+  dReal getAngle1() const
+    { return dJointGetHinge2Angle1 (get_id()); }
+  dReal getAngle1Rate() const
+    { return dJointGetHinge2Angle1Rate (get_id()); }
+  dReal getAngle2Rate() const
+    { return dJointGetHinge2Angle2Rate (get_id()); }
+
+  virtual void setParam (int parameter, dReal value)
+    { dJointSetHinge2Param (get_id(), parameter, value); }
+  virtual dReal getParam (int parameter) const
+    { return dJointGetHinge2Param (get_id(), parameter); }
+  // TODO: expose params through methods
+
+  void addTorques(dReal torque1, dReal torque2)
+       { dJointAddHinge2Torques(get_id(), torque1, torque2); }
+};
+
+
+template <class dJointTemplateBase, class dWorldTemplateBase, class dBodyTemplateBase>
+class dPRJointTemplate : public dJointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase> {
+private:
+  // intentionally undefined, don't use these
+  dPRJointTemplate (const dPRJointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase> &);
+  void operator = (const dPRJointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase> &);
+
+protected:
+  typedef dJointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase> dBaseTemplate;
+
+  dJointID get_id() const { return dBaseTemplate::get_id(); }
+  void set_id(dJointID value) { dBaseTemplate::set_id(value); }
+
+  void destroy() { dBaseTemplate::destroy(); }
+
+public:
+  dPRJointTemplate() { }
+  dPRJointTemplate (dWorldID world, dJointGroupID group=0)
+    { set_id(dJointCreatePR(world, group)); }
+  dPRJointTemplate (dWorldTemplate<dWorldTemplateBase>& world, dJointGroupID group=0)
+    { set_id(dJointCreatePR(world.id(), group)); }
+
+  void create (dWorldID world, dJointGroupID group=0) {
+    destroy();
+    set_id(dJointCreatePR(world, group));
+  }
+  void create (dWorldTemplate<dWorldTemplateBase>& world, dJointGroupID group=0)
+    { create(world.id(), group); }
+
+  void setAnchor (dReal x, dReal y, dReal z)
+    { dJointSetPRAnchor (get_id(), x, y, z); }
+  void setAnchor (const dVector3 a)
+    { setAnchor (a[0], a[1], a[2]); }
+  void setAxis1 (dReal x, dReal y, dReal z)
+    { dJointSetPRAxis1 (get_id(), x, y, z); }
+  void setAxis1 (const dVector3 a)
+    { setAxis1(a[0], a[1], a[2]); }
+  void setAxis2 (dReal x, dReal y, dReal z)
+    { dJointSetPRAxis2 (get_id(), x, y, z); }
+  void setAxis2 (const dVector3 a)
+    { setAxis2(a[0], a[1], a[2]); }
+
+  void getAnchor (dVector3 result) const
+    { dJointGetPRAnchor (get_id(), result); }
+  void getAxis1 (dVector3 result) const
+    { dJointGetPRAxis1 (get_id(), result); }
+  void getAxis2 (dVector3 result) const
+    { dJointGetPRAxis2 (get_id(), result); }
+
+  dReal getPosition() const
+    { return dJointGetPRPosition (get_id()); }
+  dReal getPositionRate() const
+    { return dJointGetPRPositionRate (get_id()); }
+
+  dReal getAngle() const
+    { return dJointGetPRAngle (get_id()); }
+  dReal getAngleRate() const
+    { return dJointGetPRAngleRate (get_id()); }
+
+  virtual void setParam (int parameter, dReal value)
+    { dJointSetPRParam (get_id(), parameter, value); }
+  virtual dReal getParam (int parameter) const
+    { return dJointGetPRParam (get_id(), parameter); }
+};
+
+
+
+template <class dJointTemplateBase, class dWorldTemplateBase, class dBodyTemplateBase>
+class dPUJointTemplate : public dJointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase>
+{
+private:
+  // intentionally undefined, don't use these
+  dPUJointTemplate (const dPUJointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase> &);
+  void operator = (const dPUJointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase> &);
+
+protected:
+  typedef dJointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase> dBaseTemplate;
+
+  dJointID get_id() const { return dBaseTemplate::get_id(); }
+  void set_id(dJointID value) { dBaseTemplate::set_id(value); }
+
+  void destroy() { dBaseTemplate::destroy(); }
+
+public:
+  dPUJointTemplate() { }
+  dPUJointTemplate (dWorldID world, dJointGroupID group=0)
+    { set_id(dJointCreatePU(world, group)); }
+  dPUJointTemplate (dWorldTemplate<dWorldTemplateBase>& world, dJointGroupID group=0)
+    { set_id(dJointCreatePU(world.id(), group)); }
+
+  void create (dWorldID world, dJointGroupID group=0)
+  {
+    destroy();
+    set_id(dJointCreatePU(world, group));
+  }
+  void create (dWorldTemplate<dWorldTemplateBase>& world, dJointGroupID group=0)
+  { create(world.id(), group); }
+
+  void setAnchor (dReal x, dReal y, dReal z)
+    { dJointSetPUAnchor (get_id(), x, y, z); }
+  void setAnchor (const dVector3 a)
+    { setAnchor (a[0], a[1], a[2]); }
+  void setAxis1 (dReal x, dReal y, dReal z)
+    { dJointSetPUAxis1 (get_id(), x, y, z); }
+  void setAxis1 (const dVector3 a)
+    { setAxis1(a[0], a[1], a[2]); }
+  void setAxis2 (dReal x, dReal y, dReal z)
+  { dJointSetPUAxis2 (get_id(), x, y, z); }
+  void setAxis3 (dReal x, dReal y, dReal z)
+  { dJointSetPUAxis3 (get_id(), x, y, z); }
+  void setAxis3 (const dVector3 a)
+    { setAxis3(a[0], a[1], a[2]); }
+  void setAxisP (dReal x, dReal y, dReal z)
+  { dJointSetPUAxis3 (get_id(), x, y, z); }
+  void setAxisP (const dVector3 a)
+    { setAxisP(a[0], a[1], a[2]); }
+
+  virtual void getAnchor (dVector3 result) const
+    { dJointGetPUAnchor (get_id(), result); }
+  void getAxis1 (dVector3 result) const
+    { dJointGetPUAxis1 (get_id(), result); }
+  void getAxis2 (dVector3 result) const
+    { dJointGetPUAxis2 (get_id(), result); }
+  void getAxis3 (dVector3 result) const
+    { dJointGetPUAxis3 (get_id(), result); }
+  void getAxisP (dVector3 result) const
+    { dJointGetPUAxis3 (get_id(), result); }
+
+  dReal getAngle1() const
+    { return dJointGetPUAngle1 (get_id()); }
+  dReal getAngle1Rate() const
+    { return dJointGetPUAngle1Rate (get_id()); }
+  dReal getAngle2() const
+    { return dJointGetPUAngle2 (get_id()); }
+  dReal getAngle2Rate() const
+    { return dJointGetPUAngle2Rate (get_id()); }
+
+  dReal getPosition() const
+    { return dJointGetPUPosition (get_id()); }
+  dReal getPositionRate() const
+    { return dJointGetPUPositionRate (get_id()); }
+
+  virtual void setParam (int parameter, dReal value)
+  { dJointSetPUParam (get_id(), parameter, value); }
+  virtual dReal getParam (int parameter) const
+    { return dJointGetPUParam (get_id(), parameter); }
+  // TODO: expose params through methods
+};
+
+
+
+
+
+template <class dJointTemplateBase, class dWorldTemplateBase, class dBodyTemplateBase>
+class dPistonJointTemplate : public dJointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase>
+{
+private:
+  // intentionally undefined, don't use these
+  dPistonJointTemplate (const dPistonJointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase> &);
+  void operator = (const dPistonJointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase> &);
+
+protected:
+  typedef dJointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase> dBaseTemplate;
+
+  dJointID get_id() const { return dBaseTemplate::get_id(); }
+  void set_id(dJointID value) { dBaseTemplate::set_id(value); }
+
+  void destroy() { dBaseTemplate::destroy(); }
+
+public:
+  dPistonJointTemplate() { }
+  dPistonJointTemplate (dWorldID world, dJointGroupID group=0)
+    { set_id(dJointCreatePiston(world, group)); }
+  dPistonJointTemplate (dWorldTemplate<dWorldTemplateBase>& world, dJointGroupID group=0)
+    { set_id(dJointCreatePiston(world, group)); }
+
+  void create (dWorldID world, dJointGroupID group=0)
+  {
+    destroy();
+    set_id(dJointCreatePiston(world, group));
+  }
+  void create (dWorldTemplate<dWorldTemplateBase>& world, dJointGroupID group=0)
+    { create(world.id(), group); }
+
+  void setAnchor (dReal x, dReal y, dReal z)
+    { dJointSetPistonAnchor (get_id(), x, y, z); }
+  void setAnchor (const dVector3 a)
+    { setAnchor (a[0], a[1], a[2]); }
+  void getAnchor (dVector3 result) const
+    { dJointGetPistonAnchor (get_id(), result); }
+  void getAnchor2 (dVector3 result) const
+    { dJointGetPistonAnchor2 (get_id(), result); }
+
+  void setAxis (dReal x, dReal y, dReal z)
+    { dJointSetPistonAxis (get_id(), x, y, z); }
+  void setAxis (const dVector3 a)
+    { setAxis(a[0], a[1], a[2]); }
+  void getAxis (dVector3 result) const
+    { dJointGetPistonAxis (get_id(), result); }
+
+  dReal getPosition() const
+    { return dJointGetPistonPosition (get_id()); }
+  dReal getPositionRate() const
+    { return dJointGetPistonPositionRate (get_id()); }
+
+  virtual void setParam (int parameter, dReal value)
+  { dJointSetPistonParam (get_id(), parameter, value); }
+  virtual dReal getParam (int parameter) const
+    { return dJointGetPistonParam (get_id(), parameter); }
+  // TODO: expose params through methods
+
+  void addForce (dReal force)
+  { dJointAddPistonForce (get_id(), force); }
+};
+
+
+
+template <class dJointTemplateBase, class dWorldTemplateBase, class dBodyTemplateBase>
+class dFixedJointTemplate : public dJointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase>
+{
+private:
+  // intentionally undefined, don't use these
+  dFixedJointTemplate (const dFixedJointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase> &);
+  void operator = (const dFixedJointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase> &);
+
+protected:
+  typedef dJointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase> dBaseTemplate;
+
+  dJointID get_id() const { return dBaseTemplate::get_id(); }
+  void set_id(dJointID value) { dBaseTemplate::set_id(value); }
+
+  void destroy() { dBaseTemplate::destroy(); }
+
+public:
+  dFixedJointTemplate() { }
+  dFixedJointTemplate (dWorldID world, dJointGroupID group=0)
+    { set_id(dJointCreateFixed(world, group)); }
+  dFixedJointTemplate (dWorldTemplate<dWorldTemplateBase>& world, dJointGroupID group=0)
+    { set_id(dJointCreateFixed(world, group)); }
+
+  void create (dWorldID world, dJointGroupID group=0) {
+    destroy();
+    set_id(dJointCreateFixed(world, group));
+  }
+  void create (dWorldTemplate<dWorldTemplateBase>& world, dJointGroupID group=0)
+    { create(world.id(), group); }
+
+  void set()
+    { dJointSetFixed (get_id()); }
+
+  virtual void setParam (int parameter, dReal value)
+    { dJointSetFixedParam (get_id(), parameter, value); }
+
+  virtual dReal getParam (int parameter) const
+    { return dJointGetFixedParam (get_id(), parameter); }
+  // TODO: expose params through methods
+};
+
+
+template <class dJointTemplateBase, class dWorldTemplateBase, class dBodyTemplateBase>
+class dContactJointTemplate : public dJointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase> {
+private:
+  // intentionally undefined, don't use these
+  dContactJointTemplate (const dContactJointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase> &);
+  void operator = (const dContactJointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase> &);
+
+protected:
+  typedef dJointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase> dBaseTemplate;
+
+  dJointID get_id() const { return dBaseTemplate::get_id(); }
+  void set_id(dJointID value) { dBaseTemplate::set_id(value); }
+
+  void destroy() { dBaseTemplate::destroy(); }
+
+public:
+  dContactJointTemplate() { }
+  dContactJointTemplate (dWorldID world, dJointGroupID group, dContact *contact)
+    { set_id(dJointCreateContact(world, group, contact)); }
+  dContactJointTemplate (dWorldTemplate<dWorldTemplateBase>& world, dJointGroupID group, dContact *contact)
+    { set_id(dJointCreateContact(world.id(), group, contact)); }
+
+  void create (dWorldID world, dJointGroupID group, dContact *contact) {
+    destroy();
+    set_id(dJointCreateContact(world, group, contact));
+  }
+  
+  void create (dWorldTemplate<dWorldTemplateBase>& world, dJointGroupID group, dContact *contact)
+    { create(world.id(), group, contact); }
+};
+
+
+template <class dJointTemplateBase, class dWorldTemplateBase, class dBodyTemplateBase>
+class dNullJointTemplate : public dJointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase> {
+private:
+  // intentionally undefined, don't use these
+  dNullJointTemplate (const dNullJointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase> &);
+  void operator = (const dNullJointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase> &);
+
+protected:
+  typedef dJointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase> dBaseTemplate;
+
+  dJointID get_id() const { return dBaseTemplate::get_id(); }
+  void set_id(dJointID value) { dBaseTemplate::set_id(value); }
+
+  void destroy() { dBaseTemplate::destroy(); }
+
+public:
+  dNullJointTemplate() { }
+  dNullJointTemplate (dWorldID world, dJointGroupID group=0)
+    { set_id(dJointCreateNull(world, group)); }
+  dNullJointTemplate (dWorldTemplate<dWorldTemplateBase>& world, dJointGroupID group=0)
+    { set_id(dJointCreateNull (world.id(), group)); }
+
+  void create (dWorldID world, dJointGroupID group=0) {
+    destroy();
+    set_id(dJointCreateNull(world, group));
+  }
+  void create (dWorldTemplate<dWorldTemplateBase>& world, dJointGroupID group=0)
+    { create(world.id(), group); }
+};
+
+
+template <class dJointTemplateBase, class dWorldTemplateBase, class dBodyTemplateBase>
+class dAMotorJointTemplate : public dJointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase> {
+private:
+  // intentionally undefined, don't use these
+  dAMotorJointTemplate (const dAMotorJointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase> &);
+  void operator = (const dAMotorJointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase> &);
+
+protected:
+  typedef dJointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase> dBaseTemplate;
+
+  dJointID get_id() const { return dBaseTemplate::get_id(); }
+  void set_id(dJointID value) { dBaseTemplate::set_id(value); }
+
+  void destroy() { dBaseTemplate::destroy(); }
+
+public:
+  dAMotorJointTemplate() { }
+  dAMotorJointTemplate (dWorldID world, dJointGroupID group=0)
+    { set_id(dJointCreateAMotor(world, group)); }
+  dAMotorJointTemplate (dWorldTemplate<dWorldTemplateBase>& world, dJointGroupID group=0)
+    { set_id(dJointCreateAMotor(world.id(), group)); }
+
+  void create (dWorldID world, dJointGroupID group=0) {
+    destroy();
+    set_id(dJointCreateAMotor(world, group));
+  }
+  void create (dWorldTemplate<dWorldTemplateBase>& world, dJointGroupID group=0)
+    { create(world.id(), group); }
+
+  void setMode (int mode)
+    { dJointSetAMotorMode (get_id(), mode); }
+  int getMode() const
+    { return dJointGetAMotorMode (get_id()); }
+
+  void setNumAxes (int num)
+    { dJointSetAMotorNumAxes (get_id(), num); }
+  int getNumAxes() const
+    { return dJointGetAMotorNumAxes (get_id()); }
+
+  void setAxis (int anum, int rel, dReal x, dReal y, dReal z)
+    { dJointSetAMotorAxis (get_id(), anum, rel, x, y, z); }
+  void setAxis (int anum, int rel, const dVector3 a)
+    { setAxis(anum, rel, a[0], a[1], a[2]); }
+  void getAxis (int anum, dVector3 result) const
+    { dJointGetAMotorAxis (get_id(), anum, result); }
+  int getAxisRel (int anum) const
+    { return dJointGetAMotorAxisRel (get_id(), anum); }
+
+  void setAngle (int anum, dReal angle)
+    { dJointSetAMotorAngle (get_id(), anum, angle); }
+  dReal getAngle (int anum) const
+    { return dJointGetAMotorAngle (get_id(), anum); }
+  dReal getAngleRate (int anum)
+    { return dJointGetAMotorAngleRate (get_id(), anum); }
+
+  void setParam (int parameter, dReal value)
+    { dJointSetAMotorParam (get_id(), parameter, value); }
+  dReal getParam (int parameter) const
+    { return dJointGetAMotorParam (get_id(), parameter); }
+  // TODO: expose params through methods
+
+  void addTorques(dReal torque1, dReal torque2, dReal torque3)
+       { dJointAddAMotorTorques(get_id(), torque1, torque2, torque3); }
+};
+
+
+template <class dJointTemplateBase, class dWorldTemplateBase, class dBodyTemplateBase>
+class dLMotorJointTemplate : public dJointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase> {
+private:
+  // intentionally undefined, don't use these
+  dLMotorJointTemplate (const dLMotorJointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase> &);
+  void operator = (const dLMotorJointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase> &);
+
+protected:
+  typedef dJointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase> dBaseTemplate;
+
+  dJointID get_id() const { return dBaseTemplate::get_id(); }
+  void set_id(dJointID value) { dBaseTemplate::set_id(value); }
+
+  void destroy() { dBaseTemplate::destroy(); }
+
+public:
+  dLMotorJointTemplate() { }
+  dLMotorJointTemplate (dWorldID world, dJointGroupID group=0)
+    { set_id(dJointCreateLMotor(world, group)); }
+  dLMotorJointTemplate (dWorldTemplate<dWorldTemplateBase>& world, dJointGroupID group=0)
+    { set_id(dJointCreateLMotor(world.id(), group)); }
+
+  void create (dWorldID world, dJointGroupID group=0) {
+    destroy();
+    set_id(dJointCreateLMotor(world, group));
+  }
+  void create (dWorldTemplate<dWorldTemplateBase>& world, dJointGroupID group=0)
+    { create(world.id(), group); }
+
+  void setNumAxes (int num)
+    { dJointSetLMotorNumAxes (get_id(), num); }
+  int getNumAxes() const
+    { return dJointGetLMotorNumAxes (get_id()); }
+
+  void setAxis (int anum, int rel, dReal x, dReal y, dReal z)
+    { dJointSetLMotorAxis (get_id(), anum, rel, x, y, z); }
+  void setAxis (int anum, int rel, const dVector3 a)
+    { setAxis(anum, rel, a[0], a[1], a[2]); }
+  void getAxis (int anum, dVector3 result) const
+    { dJointGetLMotorAxis (get_id(), anum, result); }
+
+  void setParam (int parameter, dReal value)
+    { dJointSetLMotorParam (get_id(), parameter, value); }
+  dReal getParam (int parameter) const
+    { return dJointGetLMotorParam (get_id(), parameter); }
+  // TODO: expose params through methods
+};
+
+//}
+
+#if !defined(dODECPP_WORLD_TEMPLATE_BASE)
+
+#if defined(dODECPP_BODY_TEMPLATE_BASE) || defined(dODECPP_JOINTGROUP_TEMPLATE_BASE) || defined(dODECPP_JOINT_TEMPLATE_BASE)
+#error All the odecpp template bases must be defined or not defined together
+#endif
+
+#define dODECPP_WORLD_TEMPLATE_BASE dWorldDynamicIDContainer
+#define dODECPP_BODY_TEMPLATE_BASE dBodyDynamicIDContainer
+#define dODECPP_JOINTGROUP_TEMPLATE_BASE dJointGroupDynamicIDContainer
+#define dODECPP_JOINT_TEMPLATE_BASE dJointDynamicIDContainer
+
+#else // #if defined(dODECPP_WORLD_TEMPLATE_BASE)
+
+#if !defined(dODECPP_BODY_TEMPLATE_BASE) || !defined(dODECPP_JOINTGROUP_TEMPLATE_BASE) || !defined(dODECPP_JOINT_TEMPLATE_BASE)
+#error All the odecpp template bases must be defined or not defined together
+#endif
+
+#endif // #if defined(dODECPP_WORLD_TEMPLATE_BASE)
+
+
+typedef dWorldTemplate<dODECPP_WORLD_TEMPLATE_BASE> dWorld;
+typedef dBodyTemplate<dODECPP_BODY_TEMPLATE_BASE, dODECPP_WORLD_TEMPLATE_BASE> dBody;
+typedef dJointGroupTemplate<dODECPP_JOINTGROUP_TEMPLATE_BASE> dJointGroup;
+typedef dJointTemplate<dODECPP_JOINT_TEMPLATE_BASE, dODECPP_WORLD_TEMPLATE_BASE, dODECPP_BODY_TEMPLATE_BASE> dJoint;
+typedef dBallJointTemplate<dODECPP_JOINT_TEMPLATE_BASE, dODECPP_WORLD_TEMPLATE_BASE, dODECPP_BODY_TEMPLATE_BASE> dBallJoint;
+typedef dHingeJointTemplate<dODECPP_JOINT_TEMPLATE_BASE, dODECPP_WORLD_TEMPLATE_BASE, dODECPP_BODY_TEMPLATE_BASE> dHingeJoint;
+typedef dSliderJointTemplate<dODECPP_JOINT_TEMPLATE_BASE, dODECPP_WORLD_TEMPLATE_BASE, dODECPP_BODY_TEMPLATE_BASE> dSliderJoint;
+typedef dUniversalJointTemplate<dODECPP_JOINT_TEMPLATE_BASE, dODECPP_WORLD_TEMPLATE_BASE, dODECPP_BODY_TEMPLATE_BASE> dUniversalJoint;
+typedef dHinge2JointTemplate<dODECPP_JOINT_TEMPLATE_BASE, dODECPP_WORLD_TEMPLATE_BASE, dODECPP_BODY_TEMPLATE_BASE> dHinge2Joint;
+typedef dPRJointTemplate<dODECPP_JOINT_TEMPLATE_BASE, dODECPP_WORLD_TEMPLATE_BASE, dODECPP_BODY_TEMPLATE_BASE> dPRJoint;
+typedef dPUJointTemplate<dODECPP_JOINT_TEMPLATE_BASE, dODECPP_WORLD_TEMPLATE_BASE, dODECPP_BODY_TEMPLATE_BASE> dPUJoint;
+typedef dPistonJointTemplate<dODECPP_JOINT_TEMPLATE_BASE, dODECPP_WORLD_TEMPLATE_BASE, dODECPP_BODY_TEMPLATE_BASE> dPistonJoint;
+typedef dFixedJointTemplate<dODECPP_JOINT_TEMPLATE_BASE, dODECPP_WORLD_TEMPLATE_BASE, dODECPP_BODY_TEMPLATE_BASE> dFixedJoint;
+typedef dContactJointTemplate<dODECPP_JOINT_TEMPLATE_BASE, dODECPP_WORLD_TEMPLATE_BASE, dODECPP_BODY_TEMPLATE_BASE> dContactJoint;
+typedef dNullJointTemplate<dODECPP_JOINT_TEMPLATE_BASE, dODECPP_WORLD_TEMPLATE_BASE, dODECPP_BODY_TEMPLATE_BASE> dNullJoint;
+typedef dAMotorJointTemplate<dODECPP_JOINT_TEMPLATE_BASE, dODECPP_WORLD_TEMPLATE_BASE, dODECPP_BODY_TEMPLATE_BASE> dAMotorJoint;
+typedef dLMotorJointTemplate<dODECPP_JOINT_TEMPLATE_BASE, dODECPP_WORLD_TEMPLATE_BASE, dODECPP_BODY_TEMPLATE_BASE> dLMotorJoint;
+
+
+#endif
+#endif
+
+// Local variables:
+// mode:c++
+// c-basic-offset:2
+// End:
diff --git a/misc/builddeps/dp.linux64/include/ode/odecpp_collision.h b/misc/builddeps/dp.linux64/include/ode/odecpp_collision.h
new file mode 100644 (file)
index 0000000..2377a5e
--- /dev/null
@@ -0,0 +1,429 @@
+/*************************************************************************
+ *                                                                      *
+ * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith.      *
+ * All rights reserved.  Email: russ@q12.org   Web: www.q12.org         *
+ *                                                                      *
+ * This library is free software; you can redistribute it and/or        *
+ * modify it under the terms of EITHER:                                 *
+ *   (1) The GNU Lesser General Public License as published by the Free  *
+ *      Software Foundation; either version 2.1 of the License, or (at  *
+ *      your option) any later version. The text of the GNU Lesser      *
+ *      General Public License is included with this library in the     *
+ *      file LICENSE.TXT.                                               *
+ *   (2) The BSD-style license that is included with this library in    *
+ *      the file LICENSE-BSD.TXT.                                       *
+ *                                                                      *
+ * This library is distributed in the hope that it will be useful,      *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of       *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files   *
+ * LICENSE.TXT and LICENSE-BSD.TXT for more details.                    *
+ *                                                                      *
+ *************************************************************************/
+
+/* C++ interface for new collision API */
+
+
+#ifndef _ODE_ODECPP_COLLISION_H_
+#define _ODE_ODECPP_COLLISION_H_
+#ifdef __cplusplus
+
+//#include <ode/error.h>
+
+//namespace ode {
+
+class dGeom {
+  // intentionally undefined, don't use these
+  dGeom (dGeom &);
+  void operator= (dGeom &);
+
+protected:
+  dGeomID _id;
+
+  dGeom()
+    { _id = 0; }
+public:
+  ~dGeom()
+    { if (_id) dGeomDestroy (_id); }
+
+  dGeomID id() const
+    { return _id; }
+  operator dGeomID() const
+    { return _id; }
+
+  void destroy() {
+    if (_id) dGeomDestroy (_id);
+    _id = 0;
+  }
+
+  int getClass() const
+    { return dGeomGetClass (_id); }
+
+  dSpaceID getSpace() const
+    { return dGeomGetSpace (_id); }
+
+  void setData (void *data)
+    { dGeomSetData (_id,data); }
+  void *getData() const
+    { return dGeomGetData (_id); }
+
+  void setBody (dBodyID b)
+    { dGeomSetBody (_id,b); }
+  dBodyID getBody() const
+    { return dGeomGetBody (_id); }
+
+  void setPosition (dReal x, dReal y, dReal z)
+    { dGeomSetPosition (_id,x,y,z); }
+  const dReal * getPosition() const
+    { return dGeomGetPosition (_id); }
+
+  void setRotation (const dMatrix3 R)
+    { dGeomSetRotation (_id,R); }
+  const dReal * getRotation() const
+    { return dGeomGetRotation (_id); }
+    
+  void setQuaternion (const dQuaternion quat)
+    { dGeomSetQuaternion (_id,quat); }
+  void getQuaternion (dQuaternion quat) const
+    { dGeomGetQuaternion (_id,quat); }
+
+  void getAABB (dReal aabb[6]) const
+    { dGeomGetAABB (_id, aabb); }
+
+  int isSpace()
+    { return dGeomIsSpace (_id); }
+
+  void setCategoryBits (unsigned long bits)
+    { dGeomSetCategoryBits (_id, bits); }
+  void setCollideBits (unsigned long bits)
+    { dGeomSetCollideBits (_id, bits); }
+  unsigned long getCategoryBits()
+    { return dGeomGetCategoryBits (_id); }
+  unsigned long getCollideBits()
+    { return dGeomGetCollideBits (_id); }
+
+  void enable()
+    { dGeomEnable (_id); }
+  void disable()
+    { dGeomDisable (_id); }
+  int isEnabled()
+    { return dGeomIsEnabled (_id); }
+  
+  void getRelPointPos (dReal px, dReal py, dReal pz, dVector3 result) const
+    { dGeomGetRelPointPos (_id, px, py, pz, result); }
+  void getRelPointPos (const dVector3 p, dVector3 result) const
+    { getRelPointPos (p[0], p[1], p[2], result); }
+
+  void getPosRelPoint (dReal px, dReal py, dReal pz, dVector3 result) const
+    { dGeomGetPosRelPoint (_id, px, py, pz, result); }
+  void getPosRelPoint (const dVector3 p, dVector3 result) const
+    { getPosRelPoint (p[0], p[1], p[2], result); }
+
+  void vectorToWorld (dReal px, dReal py, dReal pz, dVector3 result) const
+    { dGeomVectorToWorld (_id, px, py, pz, result); }
+  void vectorToWorld (const dVector3 p, dVector3 result) const
+    { vectorToWorld (p[0], p[1], p[2], result); }
+
+  void vectorFromWorld (dReal px, dReal py, dReal pz, dVector3 result) const
+    { dGeomVectorFromWorld (_id, px, py, pz, result); }
+  void vectorFromWorld (const dVector3 p, dVector3 result) const
+    { vectorFromWorld (p[0], p[1], p[2], result); }
+  
+  void collide2 (dGeomID g, void *data, dNearCallback *callback)
+    { dSpaceCollide2 (_id,g,data,callback); }
+};
+
+
+class dSpace : public dGeom {
+  // intentionally undefined, don't use these
+  dSpace (dSpace &);
+  void operator= (dSpace &);
+
+protected:
+  // the default constructor is protected so that you
+  // can't instance this class. you must instance one
+  // of its subclasses instead.
+  dSpace () { _id = 0; }
+
+public:
+  dSpaceID id() const
+    { return (dSpaceID) _id; }
+  operator dSpaceID() const
+    { return (dSpaceID) _id; }
+
+  void setCleanup (int mode)
+    { dSpaceSetCleanup (id(), mode); }
+  int getCleanup()
+    { return dSpaceGetCleanup (id()); }
+
+  void add (dGeomID x)
+    { dSpaceAdd (id(), x); }
+  void remove (dGeomID x)
+    { dSpaceRemove (id(), x); }
+  int query (dGeomID x)
+    { return dSpaceQuery (id(),x); }
+
+  int getNumGeoms()
+    { return dSpaceGetNumGeoms (id()); }
+  dGeomID getGeom (int i)
+    { return dSpaceGetGeom (id(),i); }
+
+  void collide (void *data, dNearCallback *callback)
+    { dSpaceCollide (id(),data,callback); }
+};
+
+
+class dSimpleSpace : public dSpace {
+  // intentionally undefined, don't use these
+  dSimpleSpace (dSimpleSpace &);
+  void operator= (dSimpleSpace &);
+
+public:
+  dSimpleSpace ()
+    { _id = (dGeomID) dSimpleSpaceCreate (0); }
+  dSimpleSpace (dSpace &space)
+    { _id = (dGeomID) dSimpleSpaceCreate (space.id()); }
+  dSimpleSpace (dSpaceID space)
+    { _id = (dGeomID) dSimpleSpaceCreate (space); }
+};
+
+
+class dHashSpace : public dSpace {
+  // intentionally undefined, don't use these
+  dHashSpace (dHashSpace &);
+  void operator= (dHashSpace &);
+
+public:
+  dHashSpace ()
+    { _id = (dGeomID) dHashSpaceCreate (0); }
+  dHashSpace (dSpace &space)
+    { _id = (dGeomID) dHashSpaceCreate (space.id()); }
+  dHashSpace (dSpaceID space)
+    { _id = (dGeomID) dHashSpaceCreate (space); }
+
+  void setLevels (int minlevel, int maxlevel)
+    { dHashSpaceSetLevels (id(),minlevel,maxlevel); }
+};
+
+
+class dQuadTreeSpace : public dSpace {
+  // intentionally undefined, don't use these
+  dQuadTreeSpace (dQuadTreeSpace &);
+  void operator= (dQuadTreeSpace &);
+
+public:
+  dQuadTreeSpace (const dVector3 center, const dVector3 extents, int depth)
+    { _id = (dGeomID) dQuadTreeSpaceCreate (0,center,extents,depth); }
+  dQuadTreeSpace (dSpace &space, const dVector3 center, const dVector3 extents, int depth)
+    { _id = (dGeomID) dQuadTreeSpaceCreate (space.id(),center,extents,depth); }
+  dQuadTreeSpace (dSpaceID space, const dVector3 center, const dVector3 extents, int depth)
+    { _id = (dGeomID) dQuadTreeSpaceCreate (space,center,extents,depth); }
+};
+
+
+class dSphere : public dGeom {
+  // intentionally undefined, don't use these
+  dSphere (dSphere &);
+  void operator= (dSphere &);
+
+public:
+  dSphere () { }
+  dSphere (dReal radius)
+    { _id = dCreateSphere (0, radius); }
+  dSphere (dSpace &space, dReal radius)
+    { _id = dCreateSphere (space.id(), radius); }
+  dSphere (dSpaceID space, dReal radius)
+    { _id = dCreateSphere (space, radius); }
+
+  void create (dSpaceID space, dReal radius) {
+    if (_id) dGeomDestroy (_id);
+    _id = dCreateSphere (space, radius);
+  }
+
+  void setRadius (dReal radius)
+    { dGeomSphereSetRadius (_id, radius); }
+  dReal getRadius() const
+    { return dGeomSphereGetRadius (_id); }
+};
+
+
+class dBox : public dGeom {
+  // intentionally undefined, don't use these
+  dBox (dBox &);
+  void operator= (dBox &);
+
+public:
+  dBox () { }
+  dBox (dReal lx, dReal ly, dReal lz)
+    { _id = dCreateBox (0,lx,ly,lz); }
+  dBox (dSpace &space, dReal lx, dReal ly, dReal lz)
+    { _id = dCreateBox (space,lx,ly,lz); }
+  dBox (dSpaceID space, dReal lx, dReal ly, dReal lz)
+    { _id = dCreateBox (space,lx,ly,lz); }
+
+  void create (dSpaceID space, dReal lx, dReal ly, dReal lz) {
+    if (_id) dGeomDestroy (_id);
+    _id = dCreateBox (space,lx,ly,lz);
+  }
+
+  void setLengths (dReal lx, dReal ly, dReal lz)
+    { dGeomBoxSetLengths (_id, lx, ly, lz); }
+  void getLengths (dVector3 result) const
+    { dGeomBoxGetLengths (_id,result); }
+};
+
+
+class dPlane : public dGeom {
+  // intentionally undefined, don't use these
+  dPlane (dPlane &);
+  void operator= (dPlane &);
+
+public:
+  dPlane() { }
+  dPlane (dReal a, dReal b, dReal c, dReal d)
+    { _id = dCreatePlane (0,a,b,c,d); }
+  dPlane (dSpace &space, dReal a, dReal b, dReal c, dReal d)
+    { _id = dCreatePlane (space.id(),a,b,c,d); }
+  dPlane (dSpaceID space, dReal a, dReal b, dReal c, dReal d)
+    { _id = dCreatePlane (space,a,b,c,d); }
+
+  void create (dSpaceID space, dReal a, dReal b, dReal c, dReal d) {
+    if (_id) dGeomDestroy (_id);
+    _id = dCreatePlane (space,a,b,c,d);
+  }
+
+  void setParams (dReal a, dReal b, dReal c, dReal d)
+    { dGeomPlaneSetParams (_id, a, b, c, d); }
+  void getParams (dVector4 result) const
+    { dGeomPlaneGetParams (_id,result); }
+};
+
+
+class dCapsule : public dGeom {
+  // intentionally undefined, don't use these
+  dCapsule (dCapsule &);
+  void operator= (dCapsule &);
+
+public:
+  dCapsule() { }
+  dCapsule (dReal radius, dReal length)
+    { _id = dCreateCapsule (0,radius,length); }
+  dCapsule (dSpace &space, dReal radius, dReal length)
+    { _id = dCreateCapsule (space.id(),radius,length); }
+  dCapsule (dSpaceID space, dReal radius, dReal length)
+    { _id = dCreateCapsule (space,radius,length); }
+
+  void create (dSpaceID space, dReal radius, dReal length) {
+    if (_id) dGeomDestroy (_id);
+    _id = dCreateCapsule (space,radius,length);
+  }
+
+  void setParams (dReal radius, dReal length)
+    { dGeomCapsuleSetParams (_id, radius, length); }
+  void getParams (dReal *radius, dReal *length) const
+    { dGeomCapsuleGetParams (_id,radius,length); }
+};
+
+
+class dCylinder : public dGeom {
+  // intentionally undefined, don't use these
+  dCylinder (dCylinder &);
+  void operator= (dCylinder &);
+
+public:
+  dCylinder() { }
+  dCylinder (dReal radius, dReal length)
+    { _id = dCreateCylinder (0,radius,length); }
+  dCylinder (dSpace &space, dReal radius, dReal length)
+    { _id = dCreateCylinder (space.id(),radius,length); }
+  dCylinder (dSpaceID space, dReal radius, dReal length)
+    { _id = dCreateCylinder (space,radius,length); }
+
+  void create (dSpaceID space, dReal radius, dReal length) {
+    if (_id) dGeomDestroy (_id);
+    _id = dCreateCylinder (space,radius,length);
+  }
+
+  void setParams (dReal radius, dReal length)
+    { dGeomCylinderSetParams (_id, radius, length); }
+  void getParams (dReal *radius, dReal *length) const
+    { dGeomCylinderGetParams (_id,radius,length); }
+};
+
+
+class dRay : public dGeom {
+  // intentionally undefined, don't use these
+  dRay (dRay &);
+  void operator= (dRay &);
+
+public:
+  dRay() { }
+  dRay (dReal length)
+    { _id = dCreateRay (0,length); }
+  dRay (dSpace &space, dReal length)
+    { _id = dCreateRay (space.id(),length); }
+  dRay (dSpaceID space, dReal length)
+    { _id = dCreateRay (space,length); }
+
+  void create (dSpaceID space, dReal length) {
+    if (_id) dGeomDestroy (_id);
+    _id = dCreateRay (space,length);
+  }
+
+  void setLength (dReal length)
+    { dGeomRaySetLength (_id, length); }
+  dReal getLength()
+    { return dGeomRayGetLength (_id); }
+
+  void set (dReal px, dReal py, dReal pz, dReal dx, dReal dy, dReal dz)
+    { dGeomRaySet (_id, px, py, pz, dx, dy, dz); }
+  void get (dVector3 start, dVector3 dir)
+    { dGeomRayGet (_id, start, dir); }
+
+  void setParams (int firstContact, int backfaceCull)
+    { dGeomRaySetParams (_id, firstContact, backfaceCull); }
+  void getParams (int *firstContact, int *backfaceCull)
+    { dGeomRayGetParams (_id, firstContact, backfaceCull); }
+  void setClosestHit (int closestHit)
+    { dGeomRaySetClosestHit (_id, closestHit); }
+  int getClosestHit()
+    { return dGeomRayGetClosestHit (_id); }
+};
+
+
+class dGeomTransform : public dGeom {
+  // intentionally undefined, don't use these
+  dGeomTransform (dGeomTransform &);
+  void operator= (dGeomTransform &);
+
+public:
+  dGeomTransform() { }
+  dGeomTransform (dSpace &space)
+    { _id = dCreateGeomTransform (space.id()); }
+  dGeomTransform (dSpaceID space)
+    { _id = dCreateGeomTransform (space); }
+
+  void create (dSpaceID space=0) {
+    if (_id) dGeomDestroy (_id);
+    _id = dCreateGeomTransform (space);
+  }
+
+  void setGeom (dGeomID geom)
+    { dGeomTransformSetGeom (_id, geom); }
+  dGeomID getGeom() const
+    { return dGeomTransformGetGeom (_id); }
+
+  void setCleanup (int mode)
+    { dGeomTransformSetCleanup (_id,mode); }
+  int getCleanup ()
+    { return dGeomTransformGetCleanup (_id); }
+
+  void setInfo (int mode)
+    { dGeomTransformSetInfo (_id,mode); }
+  int getInfo()
+    { return dGeomTransformGetInfo (_id); }
+};
+
+//}
+
+#endif
+#endif
diff --git a/misc/builddeps/dp.linux64/include/ode/odeinit.h b/misc/builddeps/dp.linux64/include/ode/odeinit.h
new file mode 100644 (file)
index 0000000..bb430c8
--- /dev/null
@@ -0,0 +1,236 @@
+/*************************************************************************
+*                                                                       *
+* Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith.       *
+* All rights reserved.  Email: russ@q12.org   Web: www.q12.org          *
+*                                                                       *
+* This library is free software; you can redistribute it and/or         *
+* modify it under the terms of EITHER:                                  *
+*   (1) The GNU Lesser General Public License as published by the Free  *
+*       Software Foundation; either version 2.1 of the License, or (at  *
+*       your option) any later version. The text of the GNU Lesser      *
+*       General Public License is included with this library in the     *
+*       file LICENSE.TXT.                                               *
+*   (2) The BSD-style license that is included with this library in     *
+*       the file LICENSE-BSD.TXT.                                       *
+*                                                                       *
+* This library is distributed in the hope that it will be useful,       *
+* but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files    *
+* LICENSE.TXT and LICENSE-BSD.TXT for more details.                     *
+*                                                                       *
+*************************************************************************/
+
+/* Library initialization/finalization functions. */
+
+#ifndef _ODE_ODEINIT_H_
+#define _ODE_ODEINIT_H_
+
+#include <ode/common.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/* ************************************************************************ */
+/* Library initialization */
+
+/**
+ * @defgroup init Library Initialization
+ *
+ * Library initialization functions prepare ODE internal data structures for use
+ * and release allocated resources after ODE is not needed any more.
+ */
+
+
+/**
+ * @brief Library initialization flags.
+ *
+ * These flags define ODE library initialization options.
+ *
+ * @c dInitFlagManualThreadCleanup indicates that resources allocated in TLS for threads
+ * using ODE are to be cleared by library client with explicit call to @c dCleanupODEAllDataForThread.
+ * If this flag is not specified the automatic resource tracking algorithm is used.
+ *
+ * With automatic resource tracking, On Windows, memory allocated for a thread may 
+ * remain not freed for some time after the thread exits. The resources may be 
+ * released when one of other threads calls @c dAllocateODEDataForThread. Ultimately,
+ * the resources are released when library is closed with @c dCloseODE. On other 
+ * operating systems resources are always released by the thread itself on its exit
+ * or on library closure with @c dCloseODE.
+ *
+ * With manual thread data cleanup mode every collision space object must be 
+ * explicitly switched to manual cleanup mode with @c dSpaceSetManualCleanup
+ * after creation. See description of the function for more details.
+ *
+ * If @c dInitFlagManualThreadCleanup was not specified during initialization,
+ * calls to @c dCleanupODEAllDataForThread are not allowed.
+ *
+ * @see dInitODE2
+ * @see dAllocateODEDataForThread
+ * @see dSpaceSetManualCleanup
+ * @see dCloseODE
+ * @ingroup init
+ */
+enum dInitODEFlags {
+       dInitFlagManualThreadCleanup = 0x00000001 //@< Thread local data is to be cleared explicitly on @c dCleanupODEAllDataForThread function call
+};
+
+/**
+ * @brief Initializes ODE library.
+ *
+ * @c dInitODE is obsolete. @c dInitODE2 is to be used for library initialization.
+ *
+ * A call to @c dInitODE is equal to the following initialization sequence
+ * @code
+ *     dInitODE2(0);
+ *     dAllocateODEDataForThread(dAllocateMaskAll);
+ * @endcode
+ *
+ * @see dInitODE2
+ * @see dAllocateODEDataForThread
+ * @ingroup init
+ */
+ODE_API void dInitODE(void);
+
+/**
+ * @brief Initializes ODE library.
+ * @param uiInitFlags Initialization options bitmask
+ * @return A nonzero if initialization succeeded and zero otherwise.
+ *
+ * This function must be called to initialize ODE library before first use. If 
+ * initialization succeeds the function may not be called again until library is 
+ * closed with a call to @c dCloseODE.
+ *
+ * The @a uiInitFlags parameter specifies initialization options to be used. These
+ * can be combination of zero or more @c dInitODEFlags flags.
+ *
+ * @note
+ * If @c dInitFlagManualThreadCleanup flag is used for initialization, 
+ * @c dSpaceSetManualCleanup must be called to set manual cleanup mode for every
+ * space object right after creation. Failure to do so may lead to resource leaks.
+ *
+ * @see dInitODEFlags
+ * @see dCloseODE
+ * @see dSpaceSetManualCleanup
+ * @ingroup init
+ */
+ODE_API int dInitODE2(unsigned int uiInitFlags/*=0*/);
+
+
+/**
+ * @brief ODE data allocation flags.
+ *
+ * These flags are used to indicate which data is to be pre-allocated in call to
+ * @c dAllocateODEDataForThread.
+ *
+ * @c dAllocateFlagBasicData tells to allocate the basic data set required for
+ * normal library operation. This flag is equal to zero and is always implicitly 
+ * included.
+ *
+ * @c dAllocateFlagCollisionData tells that collision detection data is to be allocated.
+ * Collision detection functions may not be called if the data has not be allocated 
+ * in advance. If collision detection is not going to be used, it is not necessary
+ * to specify this flag.
+ *
+ * @c dAllocateMaskAll is a mask that can be used for for allocating all possible 
+ * data in cases when it is not known what exactly features of ODE will be used.
+ * The mask may not be used in combination with other flags. It is guaranteed to
+ * include all the current and future legal allocation flags. However, mature 
+ * applications should use explicit flags they need rather than allocating everything.
+ *
+ * @see dAllocateODEDataForThread
+ * @ingroup init
+ */
+enum dAllocateODEDataFlags {
+       dAllocateFlagBasicData = 0, //@< Allocate basic data required for library to operate
+
+       dAllocateFlagCollisionData = 0x00000001, //@< Allocate data for collision detection
+
+       dAllocateMaskAll = ~0U //@< Allocate all the possible data that is currently defined or will be defined in the future.
+};
+
+/**
+ * @brief Allocate thread local data to allow the thread calling ODE.
+ * @param uiAllocateFlags Allocation options bitmask.
+ * @return A nonzero if allocation succeeded and zero otherwise.
+ * 
+ * The function is required to be called for every thread that is going to use
+ * ODE. This function allocates the data that is required for accessing ODE from 
+ * current thread along with optional data required for particular ODE subsystems.
+ *
+ * @a uiAllocateFlags parameter can contain zero or more flags from @c dAllocateODEDataFlags
+ * enumerated type. Multiple calls with different allocation flags are allowed.
+ * The flags that are already allocated are ignored in subsequent calls. If zero
+ * is passed as the parameter, it means to only allocate the set of most important
+ * data the library can not operate without.
+ *
+ * If the function returns failure status it means that none of the requested 
+ * data has been allocated. The client may retry allocation attempt with the same 
+ * flags when more system resources are available.
+ *
+ * @see dAllocateODEDataFlags
+ * @see dCleanupODEAllDataForThread
+ * @ingroup init
+ */
+ODE_API int dAllocateODEDataForThread(unsigned int uiAllocateFlags);
+
+/**
+ * @brief Free thread local data that was allocated for current thread.
+ *
+ * If library was initialized with @c dInitFlagManualThreadCleanup flag the function 
+ * is required to be called on exit of every thread that was calling @c dAllocateODEDataForThread.
+ * Failure to call @c dCleanupODEAllDataForThread may result in some resources remaining 
+ * not freed until program exit. The function may also be called when ODE is still 
+ * being used to release resources allocated for all the current subsystems and 
+ * possibly proceed with data pre-allocation for other subsystems.
+ *
+ * The function can safely be called several times in a row. The function can be 
+ * called without prior invocation of @c dAllocateODEDataForThread. The function 
+ * may not be called before ODE is initialized with @c dInitODE2 or after library 
+ * has been closed with @c dCloseODE. A call to @c dCloseODE implicitly releases 
+ * all the thread local resources that might be allocated for all the threads that 
+ * were using ODE.
+ *
+ * If library was initialized without @c dInitFlagManualThreadCleanup flag 
+ * @c dCleanupODEAllDataForThread must not be called.
+ *
+ * @see dAllocateODEDataForThread
+ * @see dInitODE2
+ * @see dCloseODE
+ * @ingroup init
+ */
+ODE_API void dCleanupODEAllDataForThread();
+
+
+/**
+ * @brief Close ODE after it is not needed any more.
+ *
+ * The function is required to be called when program does not need ODE features any more.
+ * The call to @c dCloseODE releases all the resources allocated for library
+ * including all the thread local data that might be allocated for all the threads
+ * that were using ODE.
+ *
+ * @c dCloseODE is a paired function for @c dInitODE2 and must only be called
+ * after successful library initialization.
+ *
+ * @note Important!
+ * Make sure that all the threads that were using ODE have already terminated 
+ * before calling @c dCloseODE. In particular it is not allowed to call
+ * @c dCleanupODEAllDataForThread after @c dCloseODE.
+ *
+ * @see dInitODE2
+ * @see dCleanupODEAllDataForThread
+ * @ingroup init
+ */
+ODE_API void dCloseODE(void);
+
+
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+
+#endif // _ODE_ODEINIT_H_
diff --git a/misc/builddeps/dp.linux64/include/ode/odemath.h b/misc/builddeps/dp.linux64/include/ode/odemath.h
new file mode 100644 (file)
index 0000000..2e689db
--- /dev/null
@@ -0,0 +1,473 @@
+/*************************************************************************
+ *                                                                       *
+ * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith.       *
+ * All rights reserved.  Email: russ@q12.org   Web: www.q12.org          *
+ *                                                                       *
+ * This library is free software; you can redistribute it and/or         *
+ * modify it under the terms of EITHER:                                  *
+ *   (1) The GNU Lesser General Public License as published by the Free  *
+ *       Software Foundation; either version 2.1 of the License, or (at  *
+ *       your option) any later version. The text of the GNU Lesser      *
+ *       General Public License is included with this library in the     *
+ *       file LICENSE.TXT.                                               *
+ *   (2) The BSD-style license that is included with this library in     *
+ *       the file LICENSE-BSD.TXT.                                       *
+ *                                                                       *
+ * This library is distributed in the hope that it will be useful,       *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files    *
+ * LICENSE.TXT and LICENSE-BSD.TXT for more details.                     *
+ *                                                                       *
+ *************************************************************************/
+
+#ifndef _ODE_ODEMATH_H_
+#define _ODE_ODEMATH_H_
+
+#include <ode/common.h>
+
+/*
+ * macro to access elements i,j in an NxM matrix A, independent of the
+ * matrix storage convention.
+ */
+#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[1]) || dIsNan(v[2]) || dIsNan(v[3])))
+#define dVALIDMAT3(m) (!(dIsNan(m[0]) || dIsNan(m[1]) || 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])))
+#define dVALIDMAT4(m) (!(dIsNan(m[0]) || dIsNan(m[1]) || 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]) || dIsNan(m[12]) || dIsNan(m[13]) || dIsNan(m[14]) || dIsNan(m[15]) ))
+
+
+
+// Some vector math
+PURE_INLINE void dAddVectors3(dReal *res, const dReal *a, const dReal *b)
+{
+  dReal res_0, res_1, res_2;
+  res_0 = a[0] + b[0];
+  res_1 = a[1] + b[1];
+  res_2 = a[2] + b[2];
+  // Only assign after all the calculations are over to avoid incurring memory aliasing
+  res[0] = res_0; res[1] = res_1; res[2] = res_2;
+}
+
+PURE_INLINE void dSubtractVectors3(dReal *res, const dReal *a, const dReal *b)
+{
+  dReal res_0, res_1, res_2;
+  res_0 = a[0] - b[0];
+  res_1 = a[1] - b[1];
+  res_2 = a[2] - b[2];
+  // Only assign after all the calculations are over to avoid incurring memory aliasing
+  res[0] = res_0; res[1] = res_1; res[2] = res_2;
+}
+
+PURE_INLINE void dAddScaledVectors3(dReal *res, const dReal *a, const dReal *b, dReal a_scale, dReal b_scale)
+{
+  dReal res_0, res_1, res_2;
+  res_0 = a_scale * a[0] + b_scale * b[0];
+  res_1 = a_scale * a[1] + b_scale * b[1];
+  res_2 = a_scale * a[2] + b_scale * b[2];
+  // Only assign after all the calculations are over to avoid incurring memory aliasing
+  res[0] = res_0; res[1] = res_1; res[2] = res_2;
+}
+
+PURE_INLINE void dScaleVector3(dReal *res, dReal nScale)
+{
+  res[0] *= nScale ;
+  res[1] *= nScale ;
+  res[2] *= nScale ;
+}
+
+PURE_INLINE void dNegateVector3(dReal *res)
+{
+  res[0] = -res[0];
+  res[1] = -res[1];
+  res[2] = -res[2];
+}
+
+PURE_INLINE void dCopyVector3(dReal *res, const dReal *a)
+{
+  dReal res_0, res_1, res_2;
+  res_0 = a[0];
+  res_1 = a[1];
+  res_2 = a[2];
+  // Only assign after all the calculations are over to avoid incurring memory aliasing
+  res[0] = res_0; res[1] = res_1; res[2] = res_2;
+}
+
+PURE_INLINE void dCopyScaledVector3(dReal *res, const dReal *a, dReal nScale)
+{
+  dReal res_0, res_1, res_2;
+  res_0 = a[0] * nScale;
+  res_1 = a[1] * nScale;
+  res_2 = a[2] * nScale;
+  // Only assign after all the calculations are over to avoid incurring memory aliasing
+  res[0] = res_0; res[1] = res_1; res[2] = res_2;
+}
+
+PURE_INLINE void dCopyNegatedVector3(dReal *res, const dReal *a)
+{
+  dReal res_0, res_1, res_2;
+  res_0 = -a[0];
+  res_1 = -a[1];
+  res_2 = -a[2];
+  // Only assign after all the calculations are over to avoid incurring memory aliasing
+  res[0] = res_0; res[1] = res_1; res[2] = res_2;
+}
+
+PURE_INLINE void dCopyVector4(dReal *res, const dReal *a)
+{
+  dReal res_0, res_1, res_2, res_3;
+  res_0 = a[0];
+  res_1 = a[1];
+  res_2 = a[2];
+  res_3 = a[3];
+  // Only assign after all the calculations are over to avoid incurring memory aliasing
+  res[0] = res_0; res[1] = res_1; res[2] = res_2; res[3] = res_3;
+}
+
+PURE_INLINE void dCopyMatrix4x4(dReal *res, const dReal *a)
+{
+  dCopyVector4(res + 0, a + 0);
+  dCopyVector4(res + 4, a + 4);
+  dCopyVector4(res + 8, a + 8);
+}
+
+PURE_INLINE void dCopyMatrix4x3(dReal *res, const dReal *a)
+{
+  dCopyVector3(res + 0, a + 0);
+  dCopyVector3(res + 4, a + 4);
+  dCopyVector3(res + 8, a + 8);
+}
+
+PURE_INLINE void dGetMatrixColumn3(dReal *res, const dReal *a, unsigned n)
+{
+  dReal res_0, res_1, res_2;
+  res_0 = a[n + 0];
+  res_1 = a[n + 4];
+  res_2 = a[n + 8];
+  // Only assign after all the calculations are over to avoid incurring memory aliasing
+  res[0] = res_0; res[1] = res_1; res[2] = res_2;
+}
+
+PURE_INLINE dReal dCalcVectorLength3(const dReal *a)
+{
+  return dSqrt(a[0] * a[0] + a[1] * a[1] + a[2] * a[2]);
+}
+
+PURE_INLINE dReal dCalcVectorLengthSquare3(const dReal *a)
+{
+  return (a[0] * a[0] + a[1] * a[1] + a[2] * a[2]);
+}
+
+PURE_INLINE dReal dCalcPointDepth3(const dReal *test_p, const dReal *plane_p, const dReal *plane_n)
+{
+  return (plane_p[0] - test_p[0]) * plane_n[0] + (plane_p[1] - test_p[1]) * plane_n[1] + (plane_p[2] - test_p[2]) * plane_n[2];
+}
+
+
+/*
+* 3-way dot product. _dCalcVectorDot3 means that elements of `a' and `b' are spaced
+* step_a and step_b indexes apart respectively. dCalcVectorDot3() means dDot311.
+*/
+
+PURE_INLINE dReal _dCalcVectorDot3(const dReal *a, const dReal *b, unsigned step_a, unsigned step_b)
+{
+  return a[0] * b[0] + a[step_a] * b[step_b] + a[2 * step_a] * b[2 * step_b];
+}
+
+
+PURE_INLINE dReal dCalcVectorDot3    (const dReal *a, const dReal *b) { return _dCalcVectorDot3(a,b,1,1); }
+PURE_INLINE dReal dCalcVectorDot3_13 (const dReal *a, const dReal *b) { return _dCalcVectorDot3(a,b,1,3); }
+PURE_INLINE dReal dCalcVectorDot3_31 (const dReal *a, const dReal *b) { return _dCalcVectorDot3(a,b,3,1); }
+PURE_INLINE dReal dCalcVectorDot3_33 (const dReal *a, const dReal *b) { return _dCalcVectorDot3(a,b,3,3); }
+PURE_INLINE dReal dCalcVectorDot3_14 (const dReal *a, const dReal *b) { return _dCalcVectorDot3(a,b,1,4); }
+PURE_INLINE dReal dCalcVectorDot3_41 (const dReal *a, const dReal *b) { return _dCalcVectorDot3(a,b,4,1); }
+PURE_INLINE dReal dCalcVectorDot3_44 (const dReal *a, const dReal *b) { return _dCalcVectorDot3(a,b,4,4); }
+
+
+/*
+ * cross product, set res = a x b. _dCalcVectorCross3 means that elements of `res', `a'
+ * and `b' are spaced step_res, step_a and step_b indexes apart respectively.
+ * dCalcVectorCross3() means dCross3111. 
+ */
+
+PURE_INLINE void _dCalcVectorCross3(dReal *res, const dReal *a, const dReal *b, unsigned step_res, unsigned step_a, unsigned step_b)
+{
+  dReal res_0, res_1, res_2;
+  res_0 = a[  step_a]*b[2*step_b] - a[2*step_a]*b[  step_b];
+  res_1 = a[2*step_a]*b[       0] - a[       0]*b[2*step_b];
+  res_2 = a[       0]*b[  step_b] - a[  step_a]*b[       0];
+  // Only assign after all the calculations are over to avoid incurring memory aliasing
+  res[         0] = res_0;
+  res[  step_res] = res_1;
+  res[2*step_res] = res_2;
+}
+
+PURE_INLINE void dCalcVectorCross3    (dReal *res, const dReal *a, const dReal *b) { _dCalcVectorCross3(res, a, b, 1, 1, 1); }
+PURE_INLINE void dCalcVectorCross3_114(dReal *res, const dReal *a, const dReal *b) { _dCalcVectorCross3(res, a, b, 1, 1, 4); }
+PURE_INLINE void dCalcVectorCross3_141(dReal *res, const dReal *a, const dReal *b) { _dCalcVectorCross3(res, a, b, 1, 4, 1); }
+PURE_INLINE void dCalcVectorCross3_144(dReal *res, const dReal *a, const dReal *b) { _dCalcVectorCross3(res, a, b, 1, 4, 4); }
+PURE_INLINE void dCalcVectorCross3_411(dReal *res, const dReal *a, const dReal *b) { _dCalcVectorCross3(res, a, b, 4, 1, 1); }
+PURE_INLINE void dCalcVectorCross3_414(dReal *res, const dReal *a, const dReal *b) { _dCalcVectorCross3(res, a, b, 4, 1, 4); }
+PURE_INLINE void dCalcVectorCross3_441(dReal *res, const dReal *a, const dReal *b) { _dCalcVectorCross3(res, a, b, 4, 4, 1); }
+PURE_INLINE void dCalcVectorCross3_444(dReal *res, const dReal *a, const dReal *b) { _dCalcVectorCross3(res, a, b, 4, 4, 4); }
+
+PURE_INLINE void dAddVectorCross3(dReal *res, const dReal *a, const dReal *b)
+{
+  dReal tmp[3];
+  dCalcVectorCross3(tmp, a, b);
+  dAddVectors3(res, res, tmp);
+}
+
+PURE_INLINE void dSubtractVectorCross3(dReal *res, const dReal *a, const dReal *b)
+{
+  dReal tmp[3];
+  dCalcVectorCross3(tmp, a, b);
+  dSubtractVectors3(res, res, tmp);
+}
+
+
+/*
+ * 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
+ * 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 negative version will be written.
+ */
+
+PURE_INLINE void dSetCrossMatrixPlus(dReal *res, const dReal *a, unsigned skip)
+{
+  const dReal a_0 = a[0], a_1 = a[1], a_2 = a[2];
+  res[1] = -a_2;
+  res[2] = +a_1;
+  res[skip+0] = +a_2;
+  res[skip+2] = -a_0;
+  res[2*skip+0] = -a_1;
+  res[2*skip+1] = +a_0;
+}
+
+PURE_INLINE void dSetCrossMatrixMinus(dReal *res, const dReal *a, unsigned skip)
+{
+  const dReal a_0 = a[0], a_1 = a[1], a_2 = a[2];
+  res[1] = +a_2;
+  res[2] = -a_1;
+  res[skip+0] = -a_2;
+  res[skip+2] = +a_0;
+  res[2*skip+0] = +a_1;
+  res[2*skip+1] = -a_0;
+}
+
+
+/*
+ * compute the distance between two 3D-vectors
+ */
+
+PURE_INLINE dReal dCalcPointsDistance3(const dReal *a, const dReal *b)
+{
+  dReal res;
+  dReal tmp[3];
+  dSubtractVectors3(tmp, a, b);
+  res = dCalcVectorLength3(tmp);
+  return res;
+}
+
+/*
+ * special case matrix multiplication, with operator selection
+ */
+
+PURE_INLINE void dMultiplyHelper0_331(dReal *res, const dReal *a, const dReal *b)
+{
+  dReal res_0, res_1, res_2;
+  res_0 = dCalcVectorDot3(a, b);
+  res_1 = dCalcVectorDot3(a + 4, b);
+  res_2 = dCalcVectorDot3(a + 8, b);
+  // Only assign after all the calculations are over to avoid incurring memory aliasing
+  res[0] = res_0; res[1] = res_1; res[2] = res_2;
+}
+
+PURE_INLINE void dMultiplyHelper1_331(dReal *res, const dReal *a, const dReal *b)
+{
+  dReal res_0, res_1, res_2;
+  res_0 = dCalcVectorDot3_41(a, b);
+  res_1 = dCalcVectorDot3_41(a + 1, b);
+  res_2 = dCalcVectorDot3_41(a + 2, b);
+  // Only assign after all the calculations are over to avoid incurring memory aliasing
+  res[0] = res_0; res[1] = res_1; res[2] = res_2;
+}
+
+PURE_INLINE void dMultiplyHelper0_133(dReal *res, const dReal *a, const dReal *b)
+{
+  dMultiplyHelper1_331(res, b, a);
+}
+
+PURE_INLINE void dMultiplyHelper1_133(dReal *res, const dReal *a, const dReal *b)
+{
+  dReal res_0, res_1, res_2;
+  res_0 = dCalcVectorDot3_44(a, b);
+  res_1 = dCalcVectorDot3_44(a + 1, b);
+  res_2 = dCalcVectorDot3_44(a + 2, b);
+  // Only assign after all the calculations are over to avoid incurring memory aliasing
+  res[0] = res_0; res[1] = res_1; res[2] = res_2;
+}
+
+/* 
+Note: NEVER call any of these functions/macros with the same variable for A and C, 
+it is not equivalent to A*=B.
+*/
+
+PURE_INLINE void dMultiply0_331(dReal *res, const dReal *a, const dReal *b)
+{
+  dMultiplyHelper0_331(res, a, b);
+}
+
+PURE_INLINE void dMultiply1_331(dReal *res, const dReal *a, const dReal *b)
+{
+  dMultiplyHelper1_331(res, a, b);
+}
+
+PURE_INLINE void dMultiply0_133(dReal *res, const dReal *a, const dReal *b)
+{
+  dMultiplyHelper0_133(res, a, b);
+}
+
+PURE_INLINE void dMultiply0_333(dReal *res, const dReal *a, const dReal *b)
+{
+  dMultiplyHelper0_133(res + 0, a + 0, b);
+  dMultiplyHelper0_133(res + 4, a + 4, b);
+  dMultiplyHelper0_133(res + 8, a + 8, b);
+}
+
+PURE_INLINE void dMultiply1_333(dReal *res, const dReal *a, const dReal *b)
+{
+  dMultiplyHelper1_133(res + 0, b, a + 0);
+  dMultiplyHelper1_133(res + 4, b, a + 1);
+  dMultiplyHelper1_133(res + 8, b, a + 2);
+}
+
+PURE_INLINE void dMultiply2_333(dReal *res, const dReal *a, const dReal *b)
+{
+  dMultiplyHelper0_331(res + 0, b, a + 0);
+  dMultiplyHelper0_331(res + 4, b, a + 4);
+  dMultiplyHelper0_331(res + 8, b, a + 8);
+}
+
+PURE_INLINE void dMultiplyAdd0_331(dReal *res, const dReal *a, const dReal *b)
+{
+  dReal tmp[3];
+  dMultiplyHelper0_331(tmp, a, b);
+  dAddVectors3(res, res, tmp);
+}
+
+PURE_INLINE void dMultiplyAdd1_331(dReal *res, const dReal *a, const dReal *b)
+{
+  dReal tmp[3];
+  dMultiplyHelper1_331(tmp, a, b);
+  dAddVectors3(res, res, tmp);
+}
+
+PURE_INLINE void dMultiplyAdd0_133(dReal *res, const dReal *a, const dReal *b)
+{
+  dReal tmp[3];
+  dMultiplyHelper0_133(tmp, a, b);
+  dAddVectors3(res, res, tmp);
+}
+
+PURE_INLINE void dMultiplyAdd0_333(dReal *res, const dReal *a, const dReal *b)
+{
+  dReal tmp[3];
+  dMultiplyHelper0_133(tmp, a + 0, b);
+  dAddVectors3(res+ 0, res + 0, tmp);
+  dMultiplyHelper0_133(tmp, a + 4, b);
+  dAddVectors3(res + 4, res + 4, tmp);
+  dMultiplyHelper0_133(tmp, a + 8, b);
+  dAddVectors3(res + 8, res + 8, tmp);
+}
+
+PURE_INLINE void dMultiplyAdd1_333(dReal *res, const dReal *a, const dReal *b)
+{
+  dReal tmp[3];
+  dMultiplyHelper1_133(tmp, b, a + 0);
+  dAddVectors3(res + 0, res + 0, tmp);
+  dMultiplyHelper1_133(tmp, b, a + 1);
+  dAddVectors3(res + 4, res + 4, tmp);
+  dMultiplyHelper1_133(tmp, b, a + 2);
+  dAddVectors3(res + 8, res + 8, tmp);
+}
+
+PURE_INLINE void dMultiplyAdd2_333(dReal *res, const dReal *a, const dReal *b)
+{
+  dReal tmp[3];
+  dMultiplyHelper0_331(tmp, b, a + 0);
+  dAddVectors3(res + 0, res + 0, tmp);
+  dMultiplyHelper0_331(tmp, b, a + 4);
+  dAddVectors3(res + 4, res + 4, tmp);
+  dMultiplyHelper0_331(tmp, b, a + 8);
+  dAddVectors3(res + 8, res + 8, tmp);
+}
+
+
+// Include legacy macros here
+#include <ode/odemath_legacy.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * normalize 3x1 and 4x1 vectors (i.e. scale them to unit length)
+ */
+
+// For DLL export
+ODE_API int  dSafeNormalize3 (dVector3 a);
+ODE_API int  dSafeNormalize4 (dVector4 a);
+ODE_API void dNormalize3 (dVector3 a); // Potentially asserts on zero vec
+ODE_API void dNormalize4 (dVector4 a); // Potentially asserts on zero vec
+
+#if defined(__ODE__)
+
+int  _dSafeNormalize3 (dVector3 a);
+int  _dSafeNormalize4 (dVector4 a);
+
+PURE_INLINE void _dNormalize3(dVector3 a)
+{
+  int bNormalizationResult = _dSafeNormalize3(a);
+  dIVERIFY(bNormalizationResult);
+}
+
+PURE_INLINE void _dNormalize4(dVector4 a)
+{
+  int bNormalizationResult = _dSafeNormalize4(a);
+  dIVERIFY(bNormalizationResult);
+}
+
+// For internal use
+#define dSafeNormalize3(a) _dSafeNormalize3(a)
+#define dSafeNormalize4(a) _dSafeNormalize4(a)
+#define dNormalize3(a) _dNormalize3(a)
+#define dNormalize4(a) _dNormalize4(a)
+
+#endif // defined(__ODE__)
+
+/*
+ * 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.
+ * 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 but
+ * q wont be.
+ */
+
+ODE_API void dPlaneSpace (const dVector3 n, dVector3 p, dVector3 q);
+/* Makes sure the matrix is a proper rotation */
+ODE_API void dOrthogonalizeR(dMatrix3 m);
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/misc/builddeps/dp.linux64/include/ode/odemath_legacy.h b/misc/builddeps/dp.linux64/include/ode/odemath_legacy.h
new file mode 100644 (file)
index 0000000..b742638
--- /dev/null
@@ -0,0 +1,181 @@
+/*************************************************************************
+ *                                                                       *
+ * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith.       *
+ * All rights reserved.  Email: russ@q12.org   Web: www.q12.org          *
+ *                                                                       *
+ * This library is free software; you can redistribute it and/or         *
+ * modify it under the terms of EITHER:                                  *
+ *   (1) The GNU Lesser General Public License as published by the Free  *
+ *       Software Foundation; either version 2.1 of the License, or (at  *
+ *       your option) any later version. The text of the GNU Lesser      *
+ *       General Public License is included with this library in the     *
+ *       file LICENSE.TXT.                                               *
+ *   (2) The BSD-style license that is included with this library in     *
+ *       the file LICENSE-BSD.TXT.                                       *
+ *                                                                       *
+ * This library is distributed in the hope that it will be useful,       *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files    *
+ * LICENSE.TXT and LICENSE-BSD.TXT for more details.                     *
+ *                                                                       *
+ *************************************************************************/
+
+#ifndef _ODE_ODEMATH_LEGACY_H_
+#define _ODE_ODEMATH_LEGACY_H_
+
+
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+/*
+*      These macros are not used any more inside of ODE
+*  They are kept for backward compatibility with external code that
+*  might still be using them.
+*/
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+
+/*
+* General purpose vector operations with other vectors or constants.
+*/
+
+#define dOP(a,op,b,c) do { \
+  (a)[0] = ((b)[0]) op ((c)[0]); \
+  (a)[1] = ((b)[1]) op ((c)[1]); \
+  (a)[2] = ((b)[2]) op ((c)[2]); \
+} while (0)
+#define dOPC(a,op,b,c) do { \
+  (a)[0] = ((b)[0]) op (c); \
+  (a)[1] = ((b)[1]) op (c); \
+  (a)[2] = ((b)[2]) op (c); \
+} while (0)
+#define dOPE(a,op,b) do {\
+  (a)[0] op ((b)[0]); \
+  (a)[1] op ((b)[1]); \
+  (a)[2] op ((b)[2]); \
+} while (0)
+#define dOPEC(a,op,c) do { \
+  (a)[0] op (c); \
+  (a)[1] op (c); \
+  (a)[2] op (c); \
+} while (0)
+
+/// Define an equation with operators
+/// For example this function can be used to replace
+/// <PRE>
+/// for (int i=0; i<3; ++i)
+///   a[i] += b[i] + c[i];
+/// </PRE>
+#define dOPE2(a,op1,b,op2,c) do { \
+  (a)[0] op1 ((b)[0]) op2 ((c)[0]); \
+  (a)[1] op1 ((b)[1]) op2 ((c)[1]); \
+  (a)[2] op1 ((b)[2]) op2 ((c)[2]); \
+} while (0)
+
+
+#define dLENGTHSQUARED(a) dCalcVectorLengthSquare3(a)
+#define dLENGTH(a) dCalcVectorLength3(a)
+#define dDISTANCE(a, b) dCalcPointsDistance3(a, b)
+
+
+#define dDOT(a, b) dCalcVectorDot3(a, b)
+#define dDOT13(a, b) dCalcVectorDot3_13(a, b)
+#define dDOT31(a, b) dCalcVectorDot3_31(a, b)
+#define dDOT33(a, b) dCalcVectorDot3_33(a, b)
+#define dDOT14(a, b) dCalcVectorDot3_14(a, b)
+#define dDOT41(a, b) dCalcVectorDot3_41(a, b)
+#define dDOT44(a, b) dCalcVectorDot3_44(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.
+* dCROSS() means dCROSS111. `op' is normally `=', but you can set it to
+* +=, -= etc to get other effects.
+*/
+
+#define dCROSS(a,op,b,c) \
+  do { \
+  (a)[0] op ((b)[1]*(c)[2] - (b)[2]*(c)[1]); \
+  (a)[1] op ((b)[2]*(c)[0] - (b)[0]*(c)[2]); \
+  (a)[2] op ((b)[0]*(c)[1] - (b)[1]*(c)[0]); \
+  } while(0)
+#define dCROSSpqr(a,op,b,c,p,q,r) \
+  do { \
+  (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)[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 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 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 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)
+
+
+/*
+* 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
+* 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 negative version will be written.
+*/
+
+#define dCROSSMAT(A,a,skip,plus,minus) \
+  do { \
+  (A)[1] = minus (a)[2]; \
+  (A)[2] = plus (a)[1]; \
+  (A)[(skip)+0] = plus (a)[2]; \
+  (A)[(skip)+2] = minus (a)[0]; \
+  (A)[2*(skip)+0] = minus (a)[1]; \
+  (A)[2*(skip)+1] = plus (a)[0]; \
+  } while(0)
+
+
+
+
+/* 
+Note: NEVER call any of these functions/macros with the same variable for A and C, 
+it is not equivalent to A*=B.
+*/
+
+#define dMULTIPLY0_331(A, B, C) dMultiply0_331(A, B, C)
+#define dMULTIPLY1_331(A, B, C) dMultiply1_331(A, B, C)
+#define dMULTIPLY0_133(A, B, C) dMultiply0_133(A, B, C)
+#define dMULTIPLY0_333(A, B, C) dMultiply0_333(A, B, C)
+#define dMULTIPLY1_333(A, B, C) dMultiply1_333(A, B, C)
+#define dMULTIPLY2_333(A, B, C) dMultiply2_333(A, B, C)
+
+#define dMULTIPLYADD0_331(A, B, C) dMultiplyAdd0_331(A, B, C)
+#define dMULTIPLYADD1_331(A, B, C) dMultiplyAdd1_331(A, B, C)
+#define dMULTIPLYADD0_133(A, B, C) dMultiplyAdd0_133(A, B, C)
+#define dMULTIPLYADD0_333(A, B, C) dMultiplyAdd0_333(A, B, C)
+#define dMULTIPLYADD1_333(A, B, C) dMultiplyAdd1_333(A, B, C)
+#define dMULTIPLYADD2_333(A, B, C) dMultiplyAdd2_333(A, B, C)
+
+
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+/*
+*      These macros are not used any more inside of ODE
+*  They are kept for backward compatibility with external code that
+*  might still be using them.
+*/
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+
+
+#endif // #ifndef _ODE_ODEMATH_LEGACY_H_
diff --git a/misc/builddeps/dp.linux64/include/ode/rotation.h b/misc/builddeps/dp.linux64/include/ode/rotation.h
new file mode 100644 (file)
index 0000000..a72be27
--- /dev/null
@@ -0,0 +1,70 @@
+/*************************************************************************
+ *                                                                       *
+ * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith.       *
+ * All rights reserved.  Email: russ@q12.org   Web: www.q12.org          *
+ *                                                                       *
+ * This library is free software; you can redistribute it and/or         *
+ * modify it under the terms of EITHER:                                  *
+ *   (1) The GNU Lesser General Public License as published by the Free  *
+ *       Software Foundation; either version 2.1 of the License, or (at  *
+ *       your option) any later version. The text of the GNU Lesser      *
+ *       General Public License is included with this library in the     *
+ *       file LICENSE.TXT.                                               *
+ *   (2) The BSD-style license that is included with this library in     *
+ *       the file LICENSE-BSD.TXT.                                       *
+ *                                                                       *
+ * This library is distributed in the hope that it will be useful,       *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files    *
+ * LICENSE.TXT and LICENSE-BSD.TXT for more details.                     *
+ *                                                                       *
+ *************************************************************************/
+
+#ifndef _ODE_ROTATION_H_
+#define _ODE_ROTATION_H_
+
+#include <ode/common.h>
+#include <ode/compatibility.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+ODE_API void dRSetIdentity (dMatrix3 R);
+
+ODE_API void dRFromAxisAndAngle (dMatrix3 R, dReal ax, dReal ay, dReal az,
+                        dReal angle);
+
+ODE_API void dRFromEulerAngles (dMatrix3 R, dReal phi, dReal theta, dReal psi);
+
+ODE_API void dRFrom2Axes (dMatrix3 R, dReal ax, dReal ay, dReal az,
+                 dReal bx, dReal by, dReal bz);
+
+ODE_API void dRFromZAxis (dMatrix3 R, dReal ax, dReal ay, dReal az);
+
+ODE_API void dQSetIdentity (dQuaternion q);
+
+ODE_API void dQFromAxisAndAngle (dQuaternion q, dReal ax, dReal ay, dReal az,
+                        dReal angle);
+
+/* Quaternion multiplication, analogous to the matrix multiplication routines. */
+/* qa = rotate by qc, then qb */
+ODE_API void dQMultiply0 (dQuaternion qa, const dQuaternion qb, const dQuaternion qc);
+/* qa = rotate by qc, then by inverse of qb */
+ODE_API void dQMultiply1 (dQuaternion qa, const dQuaternion qb, const dQuaternion qc);
+/* qa = rotate by inverse of qc, then by qb */
+ODE_API void dQMultiply2 (dQuaternion qa, const dQuaternion qb, const dQuaternion qc);
+/* qa = rotate by inverse of qc, then by inverse of qb */
+ODE_API void dQMultiply3 (dQuaternion qa, const dQuaternion qb, const dQuaternion qc);
+
+ODE_API void dRfromQ (dMatrix3 R, const dQuaternion q);
+ODE_API void dQfromR (dQuaternion q, const dMatrix3 R);
+ODE_API void dDQfromW (dReal dq[4], const dVector3 w, const dQuaternion q);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/misc/builddeps/dp.linux64/include/ode/timer.h b/misc/builddeps/dp.linux64/include/ode/timer.h
new file mode 100644 (file)
index 0000000..fe1483f
--- /dev/null
@@ -0,0 +1,76 @@
+/*************************************************************************
+ *                                                                       *
+ * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith.       *
+ * All rights reserved.  Email: russ@q12.org   Web: www.q12.org          *
+ *                                                                       *
+ * This library is free software; you can redistribute it and/or         *
+ * modify it under the terms of EITHER:                                  *
+ *   (1) The GNU Lesser General Public License as published by the Free  *
+ *       Software Foundation; either version 2.1 of the License, or (at  *
+ *       your option) any later version. The text of the GNU Lesser      *
+ *       General Public License is included with this library in the     *
+ *       file LICENSE.TXT.                                               *
+ *   (2) The BSD-style license that is included with this library in     *
+ *       the file LICENSE-BSD.TXT.                                       *
+ *                                                                       *
+ * This library is distributed in the hope that it will be useful,       *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files    *
+ * LICENSE.TXT and LICENSE-BSD.TXT for more details.                     *
+ *                                                                       *
+ *************************************************************************/
+
+#ifndef _ODE_TIMER_H_
+#define _ODE_TIMER_H_
+
+#include <ode/odeconfig.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/* stop watch objects */
+
+typedef struct dStopwatch {
+  double time;                 /* total clock count */
+  unsigned long cc[2];         /* clock count since last `start' */
+} dStopwatch;
+
+ODE_API void dStopwatchReset (dStopwatch *);
+ODE_API void dStopwatchStart (dStopwatch *);
+ODE_API void dStopwatchStop  (dStopwatch *);
+ODE_API double dStopwatchTime (dStopwatch *);  /* returns total time in secs */
+
+
+/* code timers */
+
+ODE_API void dTimerStart (const char *description);    /* pass a static string here */
+ODE_API void dTimerNow (const char *description);      /* pass a static string here */
+ODE_API void dTimerEnd(void);
+
+/* print out a timer report. if `average' is nonzero, print out the average
+ * time for each slot (this is only meaningful if the same start-now-end
+ * calls are being made repeatedly.
+ */
+ODE_API void dTimerReport (FILE *fout, int average);
+
+
+/* resolution */
+
+/* returns the timer ticks per second implied by the timing hardware or API.
+ * the actual timer resolution may not be this great.
+ */
+ODE_API double dTimerTicksPerSecond(void);
+
+/* returns an estimate of the actual timer resolution, in seconds. this may
+ * be greater than 1/ticks_per_second.
+ */
+ODE_API double dTimerResolution(void);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
index 75657d6e815e38109922874ff37581613cbd7de2..4f0fedab87c3f6383c897382bbe493b47353fa9e 100644 (file)
Binary files a/misc/builddeps/dp.linux64/lib/libd0_blind_id.a and b/misc/builddeps/dp.linux64/lib/libd0_blind_id.a differ
index 1004e973b25da01e953ad528602eb4ba2b51e2f6..4e5930225b3b19d0a552435027c8d3c8dfb96171 100644 (file)
Binary files a/misc/builddeps/dp.linux64/lib/libd0_rijndael.a and b/misc/builddeps/dp.linux64/lib/libd0_rijndael.a differ
index 855386e8776fd616753be1c8a0ba715bdbd63d09..c237c7ce2196da35eb61ee678e349d1786c84f04 100644 (file)
Binary files a/misc/builddeps/dp.linux64/lib/libmodplug.a and b/misc/builddeps/dp.linux64/lib/libmodplug.a differ
index 19a7883658048db0ba9395f9da722ac5c438837e..b4974101b6774fba0db0b846ff1d0799b194b090 100755 (executable)
@@ -17,7 +17,7 @@ old_library='libmodplug.a'
 inherited_linker_flags=''
 
 # Libraries that this one depends upon.
-dependency_libs=''
+dependency_libs=' -L/tmp/libmodplug-0.8.8.4.deps/lib/'
 
 # Names of additional weak libraries provided by this library
 weak_library_names=''
diff --git a/misc/builddeps/dp.linux64/lib/libode.a b/misc/builddeps/dp.linux64/lib/libode.a
new file mode 100644 (file)
index 0000000..7da69ea
Binary files /dev/null and b/misc/builddeps/dp.linux64/lib/libode.a differ
diff --git a/misc/builddeps/dp.linux64/lib/libode.la b/misc/builddeps/dp.linux64/lib/libode.la
new file mode 100755 (executable)
index 0000000..7cabb97
--- /dev/null
@@ -0,0 +1,41 @@
+# libode.la - a libtool library file
+# Generated by libtool (GNU libtool) 2.4
+#
+# Please DO NOT delete this file!
+# It is necessary for linking the library.
+
+# The name that we can dlopen(3).
+dlname=''
+
+# Names of this library.
+library_names=''
+
+# The name of the static archive.
+old_library='libode.a'
+
+# Linker flags that can not go in dependency_libs.
+inherited_linker_flags=''
+
+# Libraries that this one depends upon.
+dependency_libs=' -L/tmp/ode-0.12.deps/lib/ -lpthread'
+
+# Names of additional weak libraries provided by this library
+weak_library_names=''
+
+# Version information for libode.
+current=3
+age=0
+revision=0
+
+# Is this an already installed library?
+installed=yes
+
+# Should we warn about portability when linking against -modules?
+shouldnotlink=no
+
+# Files to dlopen/dlpreopen
+dlopen=''
+dlpreopen=''
+
+# Directory that this library needs to be installed in:
+libdir='/usr/local/lib'
diff --git a/misc/builddeps/dp.linux64/lib/pkgconfig/ode.pc b/misc/builddeps/dp.linux64/lib/pkgconfig/ode.pc
new file mode 100644 (file)
index 0000000..7be9daa
--- /dev/null
@@ -0,0 +1,11 @@
+prefix=/usr/local
+exec_prefix=${prefix}
+libdir=${exec_prefix}/lib
+includedir=${prefix}/include
+
+Name: ode
+Description: Open Dynamics Engine
+Version: 0.12
+Libs: -L${libdir} -lode
+Libs.private: -lstdc++ -lm
+Cflags: -I${includedir} -DdDOUBLE
index 6a2d3890f8e5b829ca0f7f20b463e7572f9d4c4c..1ced00e0ef9457fb25042a9cc6c0b4da49c7f5f9 100755 (executable)
Binary files a/misc/builddeps/dp.win32/bin/zlib1.dll and b/misc/builddeps/dp.win32/bin/zlib1.dll differ
index 02ce56c4313b7e7490c0416ed52bfd9c65694553..51c80ac144306f547ae7d10a02f9dc41d67572a0 100644 (file)
@@ -1,5 +1,5 @@
 /* zconf.h -- configuration of the zlib compression library
- * Copyright (C) 1995-2010 Jean-loup Gailly.
+ * Copyright (C) 1995-2011 Jean-loup Gailly.
  * For conditions of distribution and use, see copyright notice in zlib.h
  */
 
@@ -15,6 +15,7 @@
  * this permanently in zconf.h using "./configure --zprefix".
  */
 #ifdef Z_PREFIX     /* may be set to #if 1 by ./configure */
+#  define Z_PREFIX_SET
 
 /* all linked symbols */
 #  define _dist_code            z__dist_code
 #  define adler32               z_adler32
 #  define adler32_combine       z_adler32_combine
 #  define adler32_combine64     z_adler32_combine64
-#  define compress              z_compress
-#  define compress2             z_compress2
-#  define compressBound         z_compressBound
+#  ifndef Z_SOLO
+#    define compress              z_compress
+#    define compress2             z_compress2
+#    define compressBound         z_compressBound
+#  endif
 #  define crc32                 z_crc32
 #  define crc32_combine         z_crc32_combine
 #  define crc32_combine64       z_crc32_combine64
 #  define deflateInit2_         z_deflateInit2_
 #  define deflateInit_          z_deflateInit_
 #  define deflateParams         z_deflateParams
+#  define deflatePending        z_deflatePending
 #  define deflatePrime          z_deflatePrime
 #  define deflateReset          z_deflateReset
+#  define deflateResetKeep      z_deflateResetKeep
 #  define deflateSetDictionary  z_deflateSetDictionary
 #  define deflateSetHeader      z_deflateSetHeader
 #  define deflateTune           z_deflateTune
 #  define deflate_copyright     z_deflate_copyright
 #  define get_crc_table         z_get_crc_table
-#  define gz_error              z_gz_error
-#  define gz_intmax             z_gz_intmax
-#  define gz_strwinerror        z_gz_strwinerror
-#  define gzbuffer              z_gzbuffer
-#  define gzclearerr            z_gzclearerr
-#  define gzclose               z_gzclose
-#  define gzclose_r             z_gzclose_r
-#  define gzclose_w             z_gzclose_w
-#  define gzdirect              z_gzdirect
-#  define gzdopen               z_gzdopen
-#  define gzeof                 z_gzeof
-#  define gzerror               z_gzerror
-#  define gzflush               z_gzflush
-#  define gzgetc                z_gzgetc
-#  define gzgets                z_gzgets
-#  define gzoffset              z_gzoffset
-#  define gzoffset64            z_gzoffset64
-#  define gzopen                z_gzopen
-#  define gzopen64              z_gzopen64
-#  define gzprintf              z_gzprintf
-#  define gzputc                z_gzputc
-#  define gzputs                z_gzputs
-#  define gzread                z_gzread
-#  define gzrewind              z_gzrewind
-#  define gzseek                z_gzseek
-#  define gzseek64              z_gzseek64
-#  define gzsetparams           z_gzsetparams
-#  define gztell                z_gztell
-#  define gztell64              z_gztell64
-#  define gzungetc              z_gzungetc
-#  define gzwrite               z_gzwrite
+#  ifndef Z_SOLO
+#    define gz_error              z_gz_error
+#    define gz_intmax             z_gz_intmax
+#    define gz_strwinerror        z_gz_strwinerror
+#    define gzbuffer              z_gzbuffer
+#    define gzclearerr            z_gzclearerr
+#    define gzclose               z_gzclose
+#    define gzclose_r             z_gzclose_r
+#    define gzclose_w             z_gzclose_w
+#    define gzdirect              z_gzdirect
+#    define gzdopen               z_gzdopen
+#    define gzeof                 z_gzeof
+#    define gzerror               z_gzerror
+#    define gzflags               z_gzflags
+#    define gzflush               z_gzflush
+#    define gzgetc                z_gzgetc
+#    define gzgetc_               z_gzgetc_
+#    define gzgets                z_gzgets
+#    define gzoffset              z_gzoffset
+#    define gzoffset64            z_gzoffset64
+#    define gzopen                z_gzopen
+#    define gzopen64              z_gzopen64
+#    define gzprintf              z_gzprintf
+#    define gzputc                z_gzputc
+#    define gzputs                z_gzputs
+#    define gzread                z_gzread
+#    define gzrewind              z_gzrewind
+#    define gzseek                z_gzseek
+#    define gzseek64              z_gzseek64
+#    define gzsetparams           z_gzsetparams
+#    define gztell                z_gztell
+#    define gztell64              z_gztell64
+#    define gzungetc              z_gzungetc
+#    define gzwrite               z_gzwrite
+#  endif
 #  define inflate               z_inflate
 #  define inflateBack           z_inflateBack
 #  define inflateBackEnd        z_inflateBackEnd
 #  define inflateSync           z_inflateSync
 #  define inflateSyncPoint      z_inflateSyncPoint
 #  define inflateUndermine      z_inflateUndermine
+#  define inflateResetKeep      z_inflateResetKeep
 #  define inflate_copyright     z_inflate_copyright
 #  define inflate_fast          z_inflate_fast
 #  define inflate_table         z_inflate_table
-#  define uncompress            z_uncompress
+#  ifndef Z_SOLO
+#    define uncompress            z_uncompress
+#  endif
 #  define zError                z_zError
-#  define zcalloc               z_zcalloc
-#  define zcfree                z_zcfree
+#  ifndef Z_SOLO
+#    define zcalloc               z_zcalloc
+#    define zcfree                z_zcfree
+#  endif
 #  define zlibCompileFlags      z_zlibCompileFlags
 #  define zlibVersion           z_zlibVersion
 
 #  define alloc_func            z_alloc_func
 #  define charf                 z_charf
 #  define free_func             z_free_func
-#  define gzFile                z_gzFile
-#  define gz_header             z_gz_header
-#  define gz_headerp            z_gz_headerp
+#  ifndef Z_SOLO
+#    define gzFile                z_gzFile
+#    define gz_header             z_gz_header
+#    define gz_headerp            z_gz_headerp
+#  endif
 #  define in_func               z_in_func
 #  define intf                  z_intf
 #  define out_func              z_out_func
 #  define voidpf                z_voidpf
 
 /* all zlib structs in zlib.h and zconf.h */
-#  define gz_header_s           z_gz_header_s
+#  ifndef Z_SOLO
+#    define gz_header_s           z_gz_header_s
+#  endif
 #  define internal_state        z_internal_state
 
 #endif
 #  endif
 #endif
 
+#if defined(ZLIB_CONST) && !defined(z_const)
+#  define z_const const
+#else
+#  define z_const
+#endif
+
 /* Some Mac compilers merge all .h files incorrectly: */
 #if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__)
 #  define NO_DUMMY_DECL
 #  endif
 #endif
 
+#ifndef Z_ARG /* function prototypes for stdarg */
+#  if defined(STDC) || defined(Z_HAVE_STDARG_H)
+#    define Z_ARG(args)  args
+#  else
+#    define Z_ARG(args)  ()
+#  endif
+#endif
+
 /* The following definitions for FAR are needed only for MSDOS mixed
  * model programming (small or medium model with some far allocations).
  * This was tested only with MSC; for other MSDOS compilers you may have
@@ -360,8 +392,14 @@ typedef uLong FAR uLongf;
 #  define Z_HAVE_UNISTD_H
 #endif
 
+#ifdef HAVE_STDARG_H    /* may be set to #if 1 by ./configure */
+#  define Z_HAVE_STDARG_H
+#endif
+
 #ifdef STDC
-#  include <sys/types.h>    /* for off_t */
+#  ifndef Z_SOLO
+#    include <sys/types.h>      /* for off_t */
+#  endif
 #endif
 
 /* a little trick to accommodate both "#define _LARGEFILE64_SOURCE" and
@@ -374,7 +412,11 @@ typedef uLong FAR uLongf;
 #  undef _LARGEFILE64_SOURCE
 #endif
 
-#if defined(Z_HAVE_UNISTD_H) || defined(_LARGEFILE64_SOURCE)
+#if defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0
+#  define Z_LARGE
+#endif
+
+#if (defined(Z_HAVE_UNISTD_H) || defined(Z_LARGE)) && !defined(Z_SOLO)
 #  include <unistd.h>       /* for SEEK_* and off_t */
 #  ifdef VMS
 #    include <unixio.h>     /* for off_t */
@@ -384,7 +426,7 @@ typedef uLong FAR uLongf;
 #  endif
 #endif
 
-#ifndef SEEK_SET
+#if !defined(SEEK_SET) && !defined(Z_SOLO)
 #  define SEEK_SET        0       /* Seek from beginning of file.  */
 #  define SEEK_CUR        1       /* Seek from current position.  */
 #  define SEEK_END        2       /* Set file pointer to EOF plus "offset" */
@@ -394,18 +436,14 @@ typedef uLong FAR uLongf;
 #  define z_off_t long
 #endif
 
-#if defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0
+#if !defined(_WIN32) && (defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0)
 #  define z_off64_t off64_t
 #else
+#  if defined(_WIN32)
+#    define z_off64_t __int64
+#  else
 #  define z_off64_t z_off_t
 #endif
-
-#if defined(__OS400__)
-#  define NO_vsnprintf
-#endif
-
-#if defined(__MVS__)
-#  define NO_vsnprintf
 #endif
 
 /* MVS linker does not support external names larger than 8 bytes */
index bfbba83e8ee0902abe8bcbfab8bdebbbc07dca69..79142d1172e8760ac89ac7b2ad92a79928af737c 100644 (file)
@@ -1,7 +1,7 @@
 /* zlib.h -- interface of the 'zlib' general purpose compression library
-  version 1.2.5, April 19th, 2010
+  version 1.2.6, January 29th, 2012
 
-  Copyright (C) 1995-2010 Jean-loup Gailly and Mark Adler
+  Copyright (C) 1995-2012 Jean-loup Gailly and Mark Adler
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
@@ -24,8 +24,8 @@
 
 
   The data format used by the zlib library is described by RFCs (Request for
-  Comments) 1950 to 1952 in the files http://www.ietf.org/rfc/rfc1950.txt
-  (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format).
+  Comments) 1950 to 1952 in the files http://tools.ietf.org/html/rfc1950
+  (zlib format), rfc1951 (deflate format) and rfc1952 (gzip format).
 */
 
 #ifndef ZLIB_H
 extern "C" {
 #endif
 
-#define ZLIB_VERSION "1.2.5"
-#define ZLIB_VERNUM 0x1250
+#define ZLIB_VERSION "1.2.6"
+#define ZLIB_VERNUM 0x1260
 #define ZLIB_VER_MAJOR 1
 #define ZLIB_VER_MINOR 2
-#define ZLIB_VER_REVISION 5
+#define ZLIB_VER_REVISION 6
 #define ZLIB_VER_SUBREVISION 0
 
 /*
@@ -83,15 +83,15 @@ typedef void   (*free_func)  OF((voidpf opaque, voidpf address));
 struct internal_state;
 
 typedef struct z_stream_s {
-    Bytef    *next_in;  /* next input byte */
+    z_const Bytef *next_in;     /* next input byte */
     uInt     avail_in;  /* number of bytes available at next_in */
-    uLong    total_in;  /* total nb of input bytes read so far */
+    uLong    total_in;  /* total number of input bytes read so far */
 
     Bytef    *next_out; /* next output byte should be put there */
     uInt     avail_out; /* remaining free space at next_out */
-    uLong    total_out; /* total nb of bytes output so far */
+    uLong    total_out; /* total number of bytes output so far */
 
-    char     *msg;      /* last error message, NULL if no error */
+    z_const char *msg;  /* last error message, NULL if no error */
     struct internal_state FAR *state; /* not visible by applications */
 
     alloc_func zalloc;  /* used to allocate the internal state */
@@ -327,8 +327,9 @@ ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush));
 
     Z_FINISH can be used immediately after deflateInit if all the compression
   is to be done in a single step.  In this case, avail_out must be at least the
-  value returned by deflateBound (see below).  If deflate does not return
-  Z_STREAM_END, then it must be called again as described above.
+  value returned by deflateBound (see below).  Then deflate is guaranteed to
+  return Z_STREAM_END.  If not enough output space is provided, deflate will
+  not return Z_STREAM_END, and it must be called again as described above.
 
     deflate() sets strm->adler to the adler32 checksum of all input read
   so far (that is, total_in bytes).
@@ -454,20 +455,23 @@ ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush));
   avail_out must be large enough to hold all the uncompressed data.  (The size
   of the uncompressed data may have been saved by the compressor for this
   purpose.) The next operation on this stream must be inflateEnd to deallocate
-  the decompression state.  The use of Z_FINISH is never required, but can be
-  used to inform inflate that a faster approach may be used for the single
-  inflate() call.
+  the decompression state.  The use of Z_FINISH is not required to perform an
+  inflation in one step.  However it may be used to inform inflate that a
+  faster approach can be used for the single inflate() call.  Z_FINISH also
+  informs inflate to not maintain a sliding window if the stream completes,
+  which reduces inflate's memory footprint.
 
      In this implementation, inflate() always flushes as much output as
   possible to the output buffer, and always uses the faster approach on the
-  first call.  So the only effect of the flush parameter in this implementation
-  is on the return value of inflate(), as noted below, or when it returns early
-  because Z_BLOCK or Z_TREES is used.
+  first call.  So the effects of the flush parameter in this implementation are
+  on the return value of inflate() as noted below, when inflate() returns early
+  when Z_BLOCK or Z_TREES is used, and when inflate() avoids the allocation of
+  memory for a sliding window when Z_FINISH is used.
 
      If a preset dictionary is needed after this call (see inflateSetDictionary
-  below), inflate sets strm->adler to the adler32 checksum of the dictionary
+  below), inflate sets strm->adler to the Adler-32 checksum of the dictionary
   chosen by the compressor and returns Z_NEED_DICT; otherwise it sets
-  strm->adler to the adler32 checksum of all output produced so far (that is,
+  strm->adler to the Adler-32 checksum of all output produced so far (that is,
   total_out bytes) and returns Z_OK, Z_STREAM_END or an error code as described
   below.  At the end of the stream, inflate() checks that its computed adler32
   checksum is equal to that saved by the compressor and returns Z_STREAM_END
@@ -478,7 +482,9 @@ ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush));
   initializing with inflateInit2().  Any information contained in the gzip
   header is not retained, so applications that need that information should
   instead use raw inflate, see inflateInit2() below, or inflateBack() and
-  perform their own processing of the gzip header and trailer.
+  perform their own processing of the gzip header and trailer.  When processing
+  gzip-wrapped deflate data, strm->adler32 is set to the CRC-32 of the output
+  producted so far.  The CRC-32 is checked against the gzip trailer.
 
     inflate() returns Z_OK if some progress has been made (more input processed
   or more output produced), Z_STREAM_END if the end of the compressed data has
@@ -580,10 +586,15 @@ ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm,
                                              uInt  dictLength));
 /*
      Initializes the compression dictionary from the given byte sequence
-   without producing any compressed output.  This function must be called
-   immediately after deflateInit, deflateInit2 or deflateReset, before any call
-   of deflate.  The compressor and decompressor must use exactly the same
-   dictionary (see inflateSetDictionary).
+   without producing any compressed output.  When using the zlib format, this
+   function must be called immediately after deflateInit, deflateInit2 or
+   deflateReset, and before any call of deflate.  When doing raw deflate, this
+   function must be called either before any call of deflate, or immediately
+   after the completion of a deflate block, i.e. after all input has been
+   consumed and all output has been delivered when using any of the flush
+   options Z_BLOCK, Z_PARTIAL_FLUSH, Z_SYNC_FLUSH, or Z_FULL_FLUSH.  The
+   compressor and decompressor must use exactly the same dictionary (see
+   inflateSetDictionary).
 
      The dictionary should consist of strings (byte sequences) that are likely
    to be encountered later in the data to be compressed, with the most commonly
@@ -610,8 +621,8 @@ ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm,
      deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a
    parameter is invalid (e.g.  dictionary being Z_NULL) or the stream state is
    inconsistent (for example if deflate has already been called for this stream
-   or if the compression method is bsort).  deflateSetDictionary does not
-   perform any compression: this will be done by deflate().
+   or if not at a block boundary for raw deflate).  deflateSetDictionary does
+   not perform any compression: this will be done by deflate().
 */
 
 ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest,
@@ -688,8 +699,28 @@ ZEXTERN uLong ZEXPORT deflateBound OF((z_streamp strm,
    deflation of sourceLen bytes.  It must be called after deflateInit() or
    deflateInit2(), and after deflateSetHeader(), if used.  This would be used
    to allocate an output buffer for deflation in a single pass, and so would be
-   called before deflate().
-*/
+   called before deflate().  If that first deflate() call is provided the
+   sourceLen input bytes, an output buffer allocated to the size returned by
+   deflateBound(), and the flush value Z_FINISH, then deflate() is guaranteed
+   to return Z_STREAM_END.  Note that it is possible for the compressed size to
+   be larger than the value returned by deflateBound() if flush options other
+   than Z_FINISH or Z_NO_FLUSH are used.
+*/
+
+ZEXTERN int ZEXPORT deflatePending OF((z_streamp strm,
+                                       unsigned *pending,
+                                       int *bits));
+/*
+     deflatePending() returns the number of bytes and bits of output that have
+   been generated, but not yet provided in the available output.  The bytes not
+   provided would be due to the available output space having being consumed.
+   The number of bits of output not provided are between 0 and 7, where they
+   await more bits to join them in order to fill out a full byte.  If pending
+   or bits are Z_NULL, then those values are not set.
+
+     deflatePending returns Z_OK if success, or Z_STREAM_ERROR if the source
+   stream state was inconsistent.
+ */
 
 ZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm,
                                      int bits,
@@ -703,8 +734,9 @@ ZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm,
    than or equal to 16, and that many of the least significant bits of value
    will be inserted in the output.
 
-     deflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source
-   stream state was inconsistent.
+     deflatePrime returns Z_OK if success, Z_BUF_ERROR if there was not enough
+   room in the internal buffer to insert the bits, or Z_STREAM_ERROR if the
+   source stream state was inconsistent.
 */
 
 ZEXTERN int ZEXPORT deflateSetHeader OF((z_streamp strm,
@@ -790,10 +822,11 @@ ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm,
    if that call returned Z_NEED_DICT.  The dictionary chosen by the compressor
    can be determined from the adler32 value returned by that call of inflate.
    The compressor and decompressor must use exactly the same dictionary (see
-   deflateSetDictionary).  For raw inflate, this function can be called
-   immediately after inflateInit2() or inflateReset() and before any call of
-   inflate() to set the dictionary.  The application must insure that the
-   dictionary that was used for compression is provided.
+   deflateSetDictionary).  For raw inflate, this function can be called at any
+   time to set the dictionary.  If the provided dictionary is smaller than the
+   window and there is already data in the window, then the provided dictionary
+   will amend what's there.  The application must insure that the dictionary
+   that was used for compression is provided.
 
      inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a
    parameter is invalid (e.g.  dictionary being Z_NULL) or the stream state is
@@ -805,17 +838,21 @@ ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm,
 
 ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm));
 /*
-     Skips invalid compressed data until a full flush point (see above the
-   description of deflate with Z_FULL_FLUSH) can be found, or until all
+     Skips invalid compressed data until a possible full flush point (see above
+   for the description of deflate with Z_FULL_FLUSH) can be found, or until all
    available input is skipped.  No output is provided.
 
-     inflateSync returns Z_OK if a full flush point has been found, Z_BUF_ERROR
-   if no more input was provided, Z_DATA_ERROR if no flush point has been
-   found, or Z_STREAM_ERROR if the stream structure was inconsistent.  In the
-   success case, the application may save the current current value of total_in
-   which indicates where valid compressed data was found.  In the error case,
-   the application may repeatedly call inflateSync, providing more input each
-   time, until success or end of the input data.
+     inflateSync searches for a 00 00 FF FF pattern in the compressed data.
+   All full flush points have this pattern, but not all occurences of this
+   pattern are full flush points.
+
+     inflateSync returns Z_OK if a possible full flush point has been found,
+   Z_BUF_ERROR if no more input was provided, Z_DATA_ERROR if no flush point
+   has been found, or Z_STREAM_ERROR if the stream structure was inconsistent.
+   In the success case, the application may save the current current value of
+   total_in which indicates where valid compressed data was found.  In the
+   error case, the application may repeatedly call inflateSync, providing more
+   input each time, until success or end of the input data.
 */
 
 ZEXTERN int ZEXPORT inflateCopy OF((z_streamp dest,
@@ -962,7 +999,7 @@ ZEXTERN int ZEXPORT inflateBackInit OF((z_streamp strm, int windowBits,
      See inflateBack() for the usage of these routines.
 
      inflateBackInit will return Z_OK on success, Z_STREAM_ERROR if any of
-   the paramaters are invalid, Z_MEM_ERROR if the internal state could not be
+   the parameters are invalid, Z_MEM_ERROR if the internal state could not be
    allocated, or Z_VERSION_ERROR if the version of the library does not match
    the version of the header file.
 */
@@ -1088,6 +1125,7 @@ ZEXTERN uLong ZEXPORT zlibCompileFlags OF((void));
      27-31: 0 (reserved)
  */
 
+#ifndef Z_SOLO
 
                         /* utility functions */
 
@@ -1149,10 +1187,11 @@ ZEXTERN int ZEXPORT uncompress OF((Bytef *dest,   uLongf *destLen,
 
      uncompress returns Z_OK if success, Z_MEM_ERROR if there was not
    enough memory, Z_BUF_ERROR if there was not enough room in the output
-   buffer, or Z_DATA_ERROR if the input data was corrupted or incomplete.
+   buffer, or Z_DATA_ERROR if the input data was corrupted or incomplete.  In
+   the case where there is not enough room, uncompress() will fill the output
+   buffer with the uncompressed data up to that point.
 */
 
-
                         /* gzip file access functions */
 
 /*
@@ -1162,7 +1201,7 @@ ZEXTERN int ZEXPORT uncompress OF((Bytef *dest,   uLongf *destLen,
    wrapper, documented in RFC 1952, wrapped around a deflate stream.
 */
 
-typedef voidp gzFile;       /* opaque gzip file descriptor */
+typedef struct gzFile_s *gzFile;    /* semi-opaque gzip file descriptor */
 
 /*
 ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode));
@@ -1172,13 +1211,25 @@ ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode));
    a strategy: 'f' for filtered data as in "wb6f", 'h' for Huffman-only
    compression as in "wb1h", 'R' for run-length encoding as in "wb1R", or 'F'
    for fixed code compression as in "wb9F".  (See the description of
-   deflateInit2 for more information about the strategy parameter.) Also "a"
-   can be used instead of "w" to request that the gzip stream that will be
-   written be appended to the file.  "+" will result in an error, since reading
-   and writing to the same gzip file is not supported.
+   deflateInit2 for more information about the strategy parameter.)  'T' will
+   request transparent writing or appending with no compression and not using
+   the gzip format.
+
+     "a" can be used instead of "w" to request that the gzip stream that will
+   be written be appended to the file.  "+" will result in an error, since
+   reading and writing to the same gzip file is not supported.
+
+     These functions, as well as gzip, will read and decode a sequence of gzip
+   streams in a file.  The append function of gzopen() can be used to create
+   such a file.  (Also see gzflush() for another way to do this.)  When
+   appending, gzopen does not test whether the file begins with a gzip stream,
+   nor does it look for the end of the gzip streams to begin appending.  gzopen
+   will simply append a gzip stream to the existing file.
 
      gzopen can be used to read a file which is not in gzip format; in this
-   case gzread will directly read from the file without decompression.
+   case gzread will directly read from the file without decompression.  When
+   reading, this will be detected automatically by looking for the magic two-
+   byte gzip header.
 
      gzopen returns NULL if the file could not be opened, if there was
    insufficient memory to allocate the gzFile state, or if an invalid mode was
@@ -1197,7 +1248,11 @@ ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode));
    descriptor fd, just like fclose(fdopen(fd, mode)) closes the file descriptor
    fd.  If you want to keep fd open, use fd = dup(fd_keep); gz = gzdopen(fd,
    mode);.  The duplicated descriptor should be saved to avoid a leak, since
-   gzdopen does not close fd if it fails.
+   gzdopen does not close fd if it fails.  If you are using fileno() to get the
+   file descriptor from a FILE *, then you will have to use dup() to avoid
+   double-close()ing the file descriptor.  Both gzclose() and fclose() will
+   close the associated file descriptor, so they need to have different file
+   descriptors.
 
      gzdopen returns NULL if there was insufficient memory to allocate the
    gzFile state, if an invalid mode was specified (an 'r', 'w', or 'a' was not
@@ -1235,14 +1290,26 @@ ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy));
 ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len));
 /*
      Reads the given number of uncompressed bytes from the compressed file.  If
-   the input file was not in gzip format, gzread copies the given number of
-   bytes into the buffer.
+   the input file is not in gzip format, gzread copies the given number of
+   bytes into the buffer directly from the file.
 
      After reaching the end of a gzip stream in the input, gzread will continue
-   to read, looking for another gzip stream, or failing that, reading the rest
-   of the input file directly without decompression.  The entire input file
-   will be read if gzread is called until it returns less than the requested
-   len.
+   to read, looking for another gzip stream.  Any number of gzip streams may be
+   concatenated in the input file, and will all be decompressed by gzread().
+   If something other than a gzip stream is encountered after a gzip stream,
+   that remaining trailing garbage is ignored (and no error is returned).
+
+     gzread can be used to read a gzip file that is being concurrently written.
+   Upon reaching the end of the input, gzread will return with the available
+   data.  If the error code returned by gzerror is Z_OK or Z_BUF_ERROR, then
+   gzclearerr can be used to clear the end of file indicator in order to permit
+   gzread to be tried again.  Z_OK indicates that a gzip stream was completed
+   on the last gzread.  Z_BUF_ERROR indicates that the input file ended in the
+   middle of a gzip stream.  Note that gzread does not return -1 in the event
+   of an incomplete gzip stream.  This error is deferred until gzclose(), which
+   will return Z_BUF_ERROR if the last gzread ended in the middle of a gzip
+   stream.  Alternatively, gzerror can be used before gzclose to detect this
+   case.
 
      gzread returns the number of uncompressed bytes actually read, less than
    len for end of file, or -1 for error.
@@ -1256,7 +1323,7 @@ ZEXTERN int ZEXPORT gzwrite OF((gzFile file,
    error.
 */
 
-ZEXTERN int ZEXPORTVA gzprintf OF((gzFile file, const char *format, ...));
+ZEXTERN int ZEXPORTVA gzprintf Z_ARG((gzFile file, const char *format, ...));
 /*
      Converts, formats, and writes the arguments to the compressed file under
    control of the format string, as in fprintf.  gzprintf returns the number of
@@ -1301,7 +1368,10 @@ ZEXTERN int ZEXPORT gzputc OF((gzFile file, int c));
 ZEXTERN int ZEXPORT gzgetc OF((gzFile file));
 /*
      Reads one byte from the compressed file.  gzgetc returns this byte or -1
-   in case of end of file or error.
+   in case of end of file or error.  This is implemented as a macro for speed.
+   As such, it does not do all of the checking the other functions do.  I.e.
+   it does not check to see if file is NULL, nor whether the structure file
+   points to has been clobbered or not.
 */
 
 ZEXTERN int ZEXPORT gzungetc OF((int c, gzFile file));
@@ -1397,9 +1467,7 @@ ZEXTERN int ZEXPORT gzeof OF((gzFile file));
 ZEXTERN int ZEXPORT gzdirect OF((gzFile file));
 /*
      Returns true (1) if file is being copied directly while reading, or false
-   (0) if file is a gzip stream being decompressed.  This state can change from
-   false to true while reading the input file if the end of a gzip stream is
-   reached, but is followed by data that is not another gzip stream.
+   (0) if file is a gzip stream being decompressed.
 
      If the input file is empty, gzdirect() will return true, since the input
    does not contain a gzip stream.
@@ -1408,6 +1476,13 @@ ZEXTERN int ZEXPORT gzdirect OF((gzFile file));
    cause buffers to be allocated to allow reading the file to determine if it
    is a gzip file.  Therefore if gzbuffer() is used, it should be called before
    gzdirect().
+
+     When writing, gzdirect() returns true (1) if transparent writing was
+   requested ("wT" for the gzopen() mode), or false (0) otherwise.  (Note:
+   gzdirect() is not needed when writing.  Transparent writing must be
+   explicitly requested, so the application already knows the answer.  When
+   linking statically, using gzdirect() will include all of the zlib code for
+   gzip file reading and decompression, which may not be desired.)
 */
 
 ZEXTERN int ZEXPORT    gzclose OF((gzFile file));
@@ -1419,7 +1494,8 @@ ZEXTERN int ZEXPORT    gzclose OF((gzFile file));
    must not be called more than once on the same allocation.
 
      gzclose will return Z_STREAM_ERROR if file is not valid, Z_ERRNO on a
-   file operation error, or Z_OK on success.
+   file operation error, Z_MEM_ERROR if out of memory, Z_BUF_ERROR if the
+   last read ended in the middle of a gzip stream, or Z_OK on success.
 */
 
 ZEXTERN int ZEXPORT gzclose_r OF((gzFile file));
@@ -1457,6 +1533,7 @@ ZEXTERN void ZEXPORT gzclearerr OF((gzFile file));
    file that is being written concurrently.
 */
 
+#endif /* !Z_SOLO */
 
                         /* checksum functions */
 
@@ -1492,7 +1569,9 @@ ZEXTERN uLong ZEXPORT adler32_combine OF((uLong adler1, uLong adler2,
      Combine two Adler-32 checksums into one.  For two sequences of bytes, seq1
    and seq2 with lengths len1 and len2, Adler-32 checksums were calculated for
    each, adler1 and adler2.  adler32_combine() returns the Adler-32 checksum of
-   seq1 and seq2 concatenated, requiring only adler1, adler2, and len2.
+   seq1 and seq2 concatenated, requiring only adler1, adler2, and len2.  Note
+   that the z_off_t type (like off_t) is a signed integer.  If len2 is
+   negative, the result has no meaning or utility.
 */
 
 ZEXTERN uLong ZEXPORT crc32   OF((uLong crc, const Bytef *buf, uInt len));
@@ -1544,17 +1623,36 @@ ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits,
                                          const char *version,
                                          int stream_size));
 #define deflateInit(strm, level) \
-        deflateInit_((strm), (level),       ZLIB_VERSION, sizeof(z_stream))
+        deflateInit_((strm), (level), ZLIB_VERSION, (int)sizeof(z_stream))
 #define inflateInit(strm) \
-        inflateInit_((strm),                ZLIB_VERSION, sizeof(z_stream))
+        inflateInit_((strm), ZLIB_VERSION, (int)sizeof(z_stream))
 #define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \
         deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\
-                      (strategy),           ZLIB_VERSION, sizeof(z_stream))
+                      (strategy), ZLIB_VERSION, (int)sizeof(z_stream))
 #define inflateInit2(strm, windowBits) \
-        inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream))
+        inflateInit2_((strm), (windowBits), ZLIB_VERSION, \
+                      (int)sizeof(z_stream))
 #define inflateBackInit(strm, windowBits, window) \
         inflateBackInit_((strm), (windowBits), (window), \
-                                            ZLIB_VERSION, sizeof(z_stream))
+                      ZLIB_VERSION, (int)sizeof(z_stream))
+
+#ifndef Z_SOLO
+
+/* gzgetc() macro and its supporting function and exposed data structure.  Note
+ * that the real internal state is much larger than the exposed structure.
+ * This abbreviated structure exposes just enough for the gzgetc() macro.  The
+ * user should not mess with these exposed elements, since their names or
+ * behavior could change in the future, perhaps even capriciously.  They can
+ * only be used by the gzgetc() macro.  You have been warned.
+ */
+struct gzFile_s {
+    unsigned have;
+    unsigned char *next;
+    z_off64_t pos;
+};
+ZEXTERN int ZEXPORT gzgetc_ OF((gzFile file));
+#define gzgetc(g) \
+    ((g)->have ? ((g)->have--, (g)->pos++, *((g)->next)++) : gzgetc_(g))
 
 /* provide 64-bit offset functions if _LARGEFILE64_SOURCE defined, and/or
  * change the regular functions to 64 bits if _FILE_OFFSET_BITS is 64 (if
@@ -1572,13 +1670,22 @@ ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits,
 #endif
 
 #if !defined(ZLIB_INTERNAL) && _FILE_OFFSET_BITS-0 == 64 && _LFS64_LARGEFILE-0
-#  define gzopen gzopen64
-#  define gzseek gzseek64
-#  define gztell gztell64
-#  define gzoffset gzoffset64
-#  define adler32_combine adler32_combine64
-#  define crc32_combine crc32_combine64
-#  ifdef _LARGEFILE64_SOURCE
+#  ifdef Z_PREFIX_SET
+#    define z_gzopen z_gzopen64
+#    define z_gzseek z_gzseek64
+#    define z_gztell z_gztell64
+#    define z_gzoffset z_gzoffset64
+#    define z_adler32_combine z_adler32_combine64
+#    define z_crc32_combine z_crc32_combine64
+#  else
+#    define gzopen gzopen64
+#    define gzseek gzseek64
+#    define gztell gztell64
+#    define gzoffset gzoffset64
+#    define adler32_combine adler32_combine64
+#    define crc32_combine crc32_combine64
+#  endif
+#  ifndef _LARGEFILE64_SOURCE
      ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *));
      ZEXTERN z_off_t ZEXPORT gzseek64 OF((gzFile, z_off_t, int));
      ZEXTERN z_off_t ZEXPORT gztell64 OF((gzFile));
@@ -1595,6 +1702,13 @@ ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits,
    ZEXTERN uLong ZEXPORT crc32_combine OF((uLong, uLong, z_off_t));
 #endif
 
+#else /* Z_SOLO */
+
+   ZEXTERN uLong ZEXPORT adler32_combine OF((uLong, uLong, z_off_t));
+   ZEXTERN uLong ZEXPORT crc32_combine OF((uLong, uLong, z_off_t));
+
+#endif /* !Z_SOLO */
+
 /* hack for buggy compilers */
 #if !defined(ZUTIL_H) && !defined(NO_DUMMY_DECL)
     struct internal_state {int dummy;};
@@ -1605,6 +1719,11 @@ ZEXTERN const char   * ZEXPORT zError           OF((int));
 ZEXTERN int            ZEXPORT inflateSyncPoint OF((z_streamp));
 ZEXTERN const uLongf * ZEXPORT get_crc_table    OF((void));
 ZEXTERN int            ZEXPORT inflateUndermine OF((z_streamp, int));
+ZEXTERN int            ZEXPORT inflateResetKeep OF((z_streamp));
+ZEXTERN int            ZEXPORT deflateResetKeep OF((z_streamp));
+#ifndef Z_SOLO
+  ZEXTERN unsigned long  ZEXPORT gzflags          OF((void));
+#endif
 
 #ifdef __cplusplus
 }
index 6a6056d6d5de89c9684343252ab87a3db06912cc..9c193d29d280e4cc87ec5df8ede4595be9ad18c0 100644 (file)
Binary files a/misc/builddeps/dp.win32/lib/libz.a and b/misc/builddeps/dp.win32/lib/libz.a differ
diff --git a/misc/builddeps/dp.win32/lib/pkgconfig/zlib.pc b/misc/builddeps/dp.win32/lib/pkgconfig/zlib.pc
new file mode 100644 (file)
index 0000000..17626e1
--- /dev/null
@@ -0,0 +1,13 @@
+prefix=/usr/local
+exec_prefix=/usr/local
+libdir=/tmp/zlib-1.2.6.out/usr/local/lib
+sharedlibdir=/tmp/zlib-1.2.6.out/usr/local/lib
+includedir=/tmp/zlib-1.2.6.out/usr/local/include
+
+Name: zlib
+Description: zlib compression library
+Version: 1.2.6
+
+Requires:
+Libs: -L${libdir} -L${sharedlibdir} -lz
+Cflags: -I${includedir}
index 1ab7bdc3ef517dc171c7f84ed4ac9a4e499649d0..1e8317080fa231f44a88330d726503c7e3491d13 100755 (executable)
Binary files a/misc/builddeps/dp.win64/bin/zlib1.dll and b/misc/builddeps/dp.win64/bin/zlib1.dll differ
index 02ce56c4313b7e7490c0416ed52bfd9c65694553..51c80ac144306f547ae7d10a02f9dc41d67572a0 100644 (file)
@@ -1,5 +1,5 @@
 /* zconf.h -- configuration of the zlib compression library
- * Copyright (C) 1995-2010 Jean-loup Gailly.
+ * Copyright (C) 1995-2011 Jean-loup Gailly.
  * For conditions of distribution and use, see copyright notice in zlib.h
  */
 
@@ -15,6 +15,7 @@
  * this permanently in zconf.h using "./configure --zprefix".
  */
 #ifdef Z_PREFIX     /* may be set to #if 1 by ./configure */
+#  define Z_PREFIX_SET
 
 /* all linked symbols */
 #  define _dist_code            z__dist_code
 #  define adler32               z_adler32
 #  define adler32_combine       z_adler32_combine
 #  define adler32_combine64     z_adler32_combine64
-#  define compress              z_compress
-#  define compress2             z_compress2
-#  define compressBound         z_compressBound
+#  ifndef Z_SOLO
+#    define compress              z_compress
+#    define compress2             z_compress2
+#    define compressBound         z_compressBound
+#  endif
 #  define crc32                 z_crc32
 #  define crc32_combine         z_crc32_combine
 #  define crc32_combine64       z_crc32_combine64
 #  define deflateInit2_         z_deflateInit2_
 #  define deflateInit_          z_deflateInit_
 #  define deflateParams         z_deflateParams
+#  define deflatePending        z_deflatePending
 #  define deflatePrime          z_deflatePrime
 #  define deflateReset          z_deflateReset
+#  define deflateResetKeep      z_deflateResetKeep
 #  define deflateSetDictionary  z_deflateSetDictionary
 #  define deflateSetHeader      z_deflateSetHeader
 #  define deflateTune           z_deflateTune
 #  define deflate_copyright     z_deflate_copyright
 #  define get_crc_table         z_get_crc_table
-#  define gz_error              z_gz_error
-#  define gz_intmax             z_gz_intmax
-#  define gz_strwinerror        z_gz_strwinerror
-#  define gzbuffer              z_gzbuffer
-#  define gzclearerr            z_gzclearerr
-#  define gzclose               z_gzclose
-#  define gzclose_r             z_gzclose_r
-#  define gzclose_w             z_gzclose_w
-#  define gzdirect              z_gzdirect
-#  define gzdopen               z_gzdopen
-#  define gzeof                 z_gzeof
-#  define gzerror               z_gzerror
-#  define gzflush               z_gzflush
-#  define gzgetc                z_gzgetc
-#  define gzgets                z_gzgets
-#  define gzoffset              z_gzoffset
-#  define gzoffset64            z_gzoffset64
-#  define gzopen                z_gzopen
-#  define gzopen64              z_gzopen64
-#  define gzprintf              z_gzprintf
-#  define gzputc                z_gzputc
-#  define gzputs                z_gzputs
-#  define gzread                z_gzread
-#  define gzrewind              z_gzrewind
-#  define gzseek                z_gzseek
-#  define gzseek64              z_gzseek64
-#  define gzsetparams           z_gzsetparams
-#  define gztell                z_gztell
-#  define gztell64              z_gztell64
-#  define gzungetc              z_gzungetc
-#  define gzwrite               z_gzwrite
+#  ifndef Z_SOLO
+#    define gz_error              z_gz_error
+#    define gz_intmax             z_gz_intmax
+#    define gz_strwinerror        z_gz_strwinerror
+#    define gzbuffer              z_gzbuffer
+#    define gzclearerr            z_gzclearerr
+#    define gzclose               z_gzclose
+#    define gzclose_r             z_gzclose_r
+#    define gzclose_w             z_gzclose_w
+#    define gzdirect              z_gzdirect
+#    define gzdopen               z_gzdopen
+#    define gzeof                 z_gzeof
+#    define gzerror               z_gzerror
+#    define gzflags               z_gzflags
+#    define gzflush               z_gzflush
+#    define gzgetc                z_gzgetc
+#    define gzgetc_               z_gzgetc_
+#    define gzgets                z_gzgets
+#    define gzoffset              z_gzoffset
+#    define gzoffset64            z_gzoffset64
+#    define gzopen                z_gzopen
+#    define gzopen64              z_gzopen64
+#    define gzprintf              z_gzprintf
+#    define gzputc                z_gzputc
+#    define gzputs                z_gzputs
+#    define gzread                z_gzread
+#    define gzrewind              z_gzrewind
+#    define gzseek                z_gzseek
+#    define gzseek64              z_gzseek64
+#    define gzsetparams           z_gzsetparams
+#    define gztell                z_gztell
+#    define gztell64              z_gztell64
+#    define gzungetc              z_gzungetc
+#    define gzwrite               z_gzwrite
+#  endif
 #  define inflate               z_inflate
 #  define inflateBack           z_inflateBack
 #  define inflateBackEnd        z_inflateBackEnd
 #  define inflateSync           z_inflateSync
 #  define inflateSyncPoint      z_inflateSyncPoint
 #  define inflateUndermine      z_inflateUndermine
+#  define inflateResetKeep      z_inflateResetKeep
 #  define inflate_copyright     z_inflate_copyright
 #  define inflate_fast          z_inflate_fast
 #  define inflate_table         z_inflate_table
-#  define uncompress            z_uncompress
+#  ifndef Z_SOLO
+#    define uncompress            z_uncompress
+#  endif
 #  define zError                z_zError
-#  define zcalloc               z_zcalloc
-#  define zcfree                z_zcfree
+#  ifndef Z_SOLO
+#    define zcalloc               z_zcalloc
+#    define zcfree                z_zcfree
+#  endif
 #  define zlibCompileFlags      z_zlibCompileFlags
 #  define zlibVersion           z_zlibVersion
 
 #  define alloc_func            z_alloc_func
 #  define charf                 z_charf
 #  define free_func             z_free_func
-#  define gzFile                z_gzFile
-#  define gz_header             z_gz_header
-#  define gz_headerp            z_gz_headerp
+#  ifndef Z_SOLO
+#    define gzFile                z_gzFile
+#    define gz_header             z_gz_header
+#    define gz_headerp            z_gz_headerp
+#  endif
 #  define in_func               z_in_func
 #  define intf                  z_intf
 #  define out_func              z_out_func
 #  define voidpf                z_voidpf
 
 /* all zlib structs in zlib.h and zconf.h */
-#  define gz_header_s           z_gz_header_s
+#  ifndef Z_SOLO
+#    define gz_header_s           z_gz_header_s
+#  endif
 #  define internal_state        z_internal_state
 
 #endif
 #  endif
 #endif
 
+#if defined(ZLIB_CONST) && !defined(z_const)
+#  define z_const const
+#else
+#  define z_const
+#endif
+
 /* Some Mac compilers merge all .h files incorrectly: */
 #if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__)
 #  define NO_DUMMY_DECL
 #  endif
 #endif
 
+#ifndef Z_ARG /* function prototypes for stdarg */
+#  if defined(STDC) || defined(Z_HAVE_STDARG_H)
+#    define Z_ARG(args)  args
+#  else
+#    define Z_ARG(args)  ()
+#  endif
+#endif
+
 /* The following definitions for FAR are needed only for MSDOS mixed
  * model programming (small or medium model with some far allocations).
  * This was tested only with MSC; for other MSDOS compilers you may have
@@ -360,8 +392,14 @@ typedef uLong FAR uLongf;
 #  define Z_HAVE_UNISTD_H
 #endif
 
+#ifdef HAVE_STDARG_H    /* may be set to #if 1 by ./configure */
+#  define Z_HAVE_STDARG_H
+#endif
+
 #ifdef STDC
-#  include <sys/types.h>    /* for off_t */
+#  ifndef Z_SOLO
+#    include <sys/types.h>      /* for off_t */
+#  endif
 #endif
 
 /* a little trick to accommodate both "#define _LARGEFILE64_SOURCE" and
@@ -374,7 +412,11 @@ typedef uLong FAR uLongf;
 #  undef _LARGEFILE64_SOURCE
 #endif
 
-#if defined(Z_HAVE_UNISTD_H) || defined(_LARGEFILE64_SOURCE)
+#if defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0
+#  define Z_LARGE
+#endif
+
+#if (defined(Z_HAVE_UNISTD_H) || defined(Z_LARGE)) && !defined(Z_SOLO)
 #  include <unistd.h>       /* for SEEK_* and off_t */
 #  ifdef VMS
 #    include <unixio.h>     /* for off_t */
@@ -384,7 +426,7 @@ typedef uLong FAR uLongf;
 #  endif
 #endif
 
-#ifndef SEEK_SET
+#if !defined(SEEK_SET) && !defined(Z_SOLO)
 #  define SEEK_SET        0       /* Seek from beginning of file.  */
 #  define SEEK_CUR        1       /* Seek from current position.  */
 #  define SEEK_END        2       /* Set file pointer to EOF plus "offset" */
@@ -394,18 +436,14 @@ typedef uLong FAR uLongf;
 #  define z_off_t long
 #endif
 
-#if defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0
+#if !defined(_WIN32) && (defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0)
 #  define z_off64_t off64_t
 #else
+#  if defined(_WIN32)
+#    define z_off64_t __int64
+#  else
 #  define z_off64_t z_off_t
 #endif
-
-#if defined(__OS400__)
-#  define NO_vsnprintf
-#endif
-
-#if defined(__MVS__)
-#  define NO_vsnprintf
 #endif
 
 /* MVS linker does not support external names larger than 8 bytes */
index bfbba83e8ee0902abe8bcbfab8bdebbbc07dca69..79142d1172e8760ac89ac7b2ad92a79928af737c 100644 (file)
@@ -1,7 +1,7 @@
 /* zlib.h -- interface of the 'zlib' general purpose compression library
-  version 1.2.5, April 19th, 2010
+  version 1.2.6, January 29th, 2012
 
-  Copyright (C) 1995-2010 Jean-loup Gailly and Mark Adler
+  Copyright (C) 1995-2012 Jean-loup Gailly and Mark Adler
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
@@ -24,8 +24,8 @@
 
 
   The data format used by the zlib library is described by RFCs (Request for
-  Comments) 1950 to 1952 in the files http://www.ietf.org/rfc/rfc1950.txt
-  (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format).
+  Comments) 1950 to 1952 in the files http://tools.ietf.org/html/rfc1950
+  (zlib format), rfc1951 (deflate format) and rfc1952 (gzip format).
 */
 
 #ifndef ZLIB_H
 extern "C" {
 #endif
 
-#define ZLIB_VERSION "1.2.5"
-#define ZLIB_VERNUM 0x1250
+#define ZLIB_VERSION "1.2.6"
+#define ZLIB_VERNUM 0x1260
 #define ZLIB_VER_MAJOR 1
 #define ZLIB_VER_MINOR 2
-#define ZLIB_VER_REVISION 5
+#define ZLIB_VER_REVISION 6
 #define ZLIB_VER_SUBREVISION 0
 
 /*
@@ -83,15 +83,15 @@ typedef void   (*free_func)  OF((voidpf opaque, voidpf address));
 struct internal_state;
 
 typedef struct z_stream_s {
-    Bytef    *next_in;  /* next input byte */
+    z_const Bytef *next_in;     /* next input byte */
     uInt     avail_in;  /* number of bytes available at next_in */
-    uLong    total_in;  /* total nb of input bytes read so far */
+    uLong    total_in;  /* total number of input bytes read so far */
 
     Bytef    *next_out; /* next output byte should be put there */
     uInt     avail_out; /* remaining free space at next_out */
-    uLong    total_out; /* total nb of bytes output so far */
+    uLong    total_out; /* total number of bytes output so far */
 
-    char     *msg;      /* last error message, NULL if no error */
+    z_const char *msg;  /* last error message, NULL if no error */
     struct internal_state FAR *state; /* not visible by applications */
 
     alloc_func zalloc;  /* used to allocate the internal state */
@@ -327,8 +327,9 @@ ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush));
 
     Z_FINISH can be used immediately after deflateInit if all the compression
   is to be done in a single step.  In this case, avail_out must be at least the
-  value returned by deflateBound (see below).  If deflate does not return
-  Z_STREAM_END, then it must be called again as described above.
+  value returned by deflateBound (see below).  Then deflate is guaranteed to
+  return Z_STREAM_END.  If not enough output space is provided, deflate will
+  not return Z_STREAM_END, and it must be called again as described above.
 
     deflate() sets strm->adler to the adler32 checksum of all input read
   so far (that is, total_in bytes).
@@ -454,20 +455,23 @@ ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush));
   avail_out must be large enough to hold all the uncompressed data.  (The size
   of the uncompressed data may have been saved by the compressor for this
   purpose.) The next operation on this stream must be inflateEnd to deallocate
-  the decompression state.  The use of Z_FINISH is never required, but can be
-  used to inform inflate that a faster approach may be used for the single
-  inflate() call.
+  the decompression state.  The use of Z_FINISH is not required to perform an
+  inflation in one step.  However it may be used to inform inflate that a
+  faster approach can be used for the single inflate() call.  Z_FINISH also
+  informs inflate to not maintain a sliding window if the stream completes,
+  which reduces inflate's memory footprint.
 
      In this implementation, inflate() always flushes as much output as
   possible to the output buffer, and always uses the faster approach on the
-  first call.  So the only effect of the flush parameter in this implementation
-  is on the return value of inflate(), as noted below, or when it returns early
-  because Z_BLOCK or Z_TREES is used.
+  first call.  So the effects of the flush parameter in this implementation are
+  on the return value of inflate() as noted below, when inflate() returns early
+  when Z_BLOCK or Z_TREES is used, and when inflate() avoids the allocation of
+  memory for a sliding window when Z_FINISH is used.
 
      If a preset dictionary is needed after this call (see inflateSetDictionary
-  below), inflate sets strm->adler to the adler32 checksum of the dictionary
+  below), inflate sets strm->adler to the Adler-32 checksum of the dictionary
   chosen by the compressor and returns Z_NEED_DICT; otherwise it sets
-  strm->adler to the adler32 checksum of all output produced so far (that is,
+  strm->adler to the Adler-32 checksum of all output produced so far (that is,
   total_out bytes) and returns Z_OK, Z_STREAM_END or an error code as described
   below.  At the end of the stream, inflate() checks that its computed adler32
   checksum is equal to that saved by the compressor and returns Z_STREAM_END
@@ -478,7 +482,9 @@ ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush));
   initializing with inflateInit2().  Any information contained in the gzip
   header is not retained, so applications that need that information should
   instead use raw inflate, see inflateInit2() below, or inflateBack() and
-  perform their own processing of the gzip header and trailer.
+  perform their own processing of the gzip header and trailer.  When processing
+  gzip-wrapped deflate data, strm->adler32 is set to the CRC-32 of the output
+  producted so far.  The CRC-32 is checked against the gzip trailer.
 
     inflate() returns Z_OK if some progress has been made (more input processed
   or more output produced), Z_STREAM_END if the end of the compressed data has
@@ -580,10 +586,15 @@ ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm,
                                              uInt  dictLength));
 /*
      Initializes the compression dictionary from the given byte sequence
-   without producing any compressed output.  This function must be called
-   immediately after deflateInit, deflateInit2 or deflateReset, before any call
-   of deflate.  The compressor and decompressor must use exactly the same
-   dictionary (see inflateSetDictionary).
+   without producing any compressed output.  When using the zlib format, this
+   function must be called immediately after deflateInit, deflateInit2 or
+   deflateReset, and before any call of deflate.  When doing raw deflate, this
+   function must be called either before any call of deflate, or immediately
+   after the completion of a deflate block, i.e. after all input has been
+   consumed and all output has been delivered when using any of the flush
+   options Z_BLOCK, Z_PARTIAL_FLUSH, Z_SYNC_FLUSH, or Z_FULL_FLUSH.  The
+   compressor and decompressor must use exactly the same dictionary (see
+   inflateSetDictionary).
 
      The dictionary should consist of strings (byte sequences) that are likely
    to be encountered later in the data to be compressed, with the most commonly
@@ -610,8 +621,8 @@ ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm,
      deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a
    parameter is invalid (e.g.  dictionary being Z_NULL) or the stream state is
    inconsistent (for example if deflate has already been called for this stream
-   or if the compression method is bsort).  deflateSetDictionary does not
-   perform any compression: this will be done by deflate().
+   or if not at a block boundary for raw deflate).  deflateSetDictionary does
+   not perform any compression: this will be done by deflate().
 */
 
 ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest,
@@ -688,8 +699,28 @@ ZEXTERN uLong ZEXPORT deflateBound OF((z_streamp strm,
    deflation of sourceLen bytes.  It must be called after deflateInit() or
    deflateInit2(), and after deflateSetHeader(), if used.  This would be used
    to allocate an output buffer for deflation in a single pass, and so would be
-   called before deflate().
-*/
+   called before deflate().  If that first deflate() call is provided the
+   sourceLen input bytes, an output buffer allocated to the size returned by
+   deflateBound(), and the flush value Z_FINISH, then deflate() is guaranteed
+   to return Z_STREAM_END.  Note that it is possible for the compressed size to
+   be larger than the value returned by deflateBound() if flush options other
+   than Z_FINISH or Z_NO_FLUSH are used.
+*/
+
+ZEXTERN int ZEXPORT deflatePending OF((z_streamp strm,
+                                       unsigned *pending,
+                                       int *bits));
+/*
+     deflatePending() returns the number of bytes and bits of output that have
+   been generated, but not yet provided in the available output.  The bytes not
+   provided would be due to the available output space having being consumed.
+   The number of bits of output not provided are between 0 and 7, where they
+   await more bits to join them in order to fill out a full byte.  If pending
+   or bits are Z_NULL, then those values are not set.
+
+     deflatePending returns Z_OK if success, or Z_STREAM_ERROR if the source
+   stream state was inconsistent.
+ */
 
 ZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm,
                                      int bits,
@@ -703,8 +734,9 @@ ZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm,
    than or equal to 16, and that many of the least significant bits of value
    will be inserted in the output.
 
-     deflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source
-   stream state was inconsistent.
+     deflatePrime returns Z_OK if success, Z_BUF_ERROR if there was not enough
+   room in the internal buffer to insert the bits, or Z_STREAM_ERROR if the
+   source stream state was inconsistent.
 */
 
 ZEXTERN int ZEXPORT deflateSetHeader OF((z_streamp strm,
@@ -790,10 +822,11 @@ ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm,
    if that call returned Z_NEED_DICT.  The dictionary chosen by the compressor
    can be determined from the adler32 value returned by that call of inflate.
    The compressor and decompressor must use exactly the same dictionary (see
-   deflateSetDictionary).  For raw inflate, this function can be called
-   immediately after inflateInit2() or inflateReset() and before any call of
-   inflate() to set the dictionary.  The application must insure that the
-   dictionary that was used for compression is provided.
+   deflateSetDictionary).  For raw inflate, this function can be called at any
+   time to set the dictionary.  If the provided dictionary is smaller than the
+   window and there is already data in the window, then the provided dictionary
+   will amend what's there.  The application must insure that the dictionary
+   that was used for compression is provided.
 
      inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a
    parameter is invalid (e.g.  dictionary being Z_NULL) or the stream state is
@@ -805,17 +838,21 @@ ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm,
 
 ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm));
 /*
-     Skips invalid compressed data until a full flush point (see above the
-   description of deflate with Z_FULL_FLUSH) can be found, or until all
+     Skips invalid compressed data until a possible full flush point (see above
+   for the description of deflate with Z_FULL_FLUSH) can be found, or until all
    available input is skipped.  No output is provided.
 
-     inflateSync returns Z_OK if a full flush point has been found, Z_BUF_ERROR
-   if no more input was provided, Z_DATA_ERROR if no flush point has been
-   found, or Z_STREAM_ERROR if the stream structure was inconsistent.  In the
-   success case, the application may save the current current value of total_in
-   which indicates where valid compressed data was found.  In the error case,
-   the application may repeatedly call inflateSync, providing more input each
-   time, until success or end of the input data.
+     inflateSync searches for a 00 00 FF FF pattern in the compressed data.
+   All full flush points have this pattern, but not all occurences of this
+   pattern are full flush points.
+
+     inflateSync returns Z_OK if a possible full flush point has been found,
+   Z_BUF_ERROR if no more input was provided, Z_DATA_ERROR if no flush point
+   has been found, or Z_STREAM_ERROR if the stream structure was inconsistent.
+   In the success case, the application may save the current current value of
+   total_in which indicates where valid compressed data was found.  In the
+   error case, the application may repeatedly call inflateSync, providing more
+   input each time, until success or end of the input data.
 */
 
 ZEXTERN int ZEXPORT inflateCopy OF((z_streamp dest,
@@ -962,7 +999,7 @@ ZEXTERN int ZEXPORT inflateBackInit OF((z_streamp strm, int windowBits,
      See inflateBack() for the usage of these routines.
 
      inflateBackInit will return Z_OK on success, Z_STREAM_ERROR if any of
-   the paramaters are invalid, Z_MEM_ERROR if the internal state could not be
+   the parameters are invalid, Z_MEM_ERROR if the internal state could not be
    allocated, or Z_VERSION_ERROR if the version of the library does not match
    the version of the header file.
 */
@@ -1088,6 +1125,7 @@ ZEXTERN uLong ZEXPORT zlibCompileFlags OF((void));
      27-31: 0 (reserved)
  */
 
+#ifndef Z_SOLO
 
                         /* utility functions */
 
@@ -1149,10 +1187,11 @@ ZEXTERN int ZEXPORT uncompress OF((Bytef *dest,   uLongf *destLen,
 
      uncompress returns Z_OK if success, Z_MEM_ERROR if there was not
    enough memory, Z_BUF_ERROR if there was not enough room in the output
-   buffer, or Z_DATA_ERROR if the input data was corrupted or incomplete.
+   buffer, or Z_DATA_ERROR if the input data was corrupted or incomplete.  In
+   the case where there is not enough room, uncompress() will fill the output
+   buffer with the uncompressed data up to that point.
 */
 
-
                         /* gzip file access functions */
 
 /*
@@ -1162,7 +1201,7 @@ ZEXTERN int ZEXPORT uncompress OF((Bytef *dest,   uLongf *destLen,
    wrapper, documented in RFC 1952, wrapped around a deflate stream.
 */
 
-typedef voidp gzFile;       /* opaque gzip file descriptor */
+typedef struct gzFile_s *gzFile;    /* semi-opaque gzip file descriptor */
 
 /*
 ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode));
@@ -1172,13 +1211,25 @@ ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode));
    a strategy: 'f' for filtered data as in "wb6f", 'h' for Huffman-only
    compression as in "wb1h", 'R' for run-length encoding as in "wb1R", or 'F'
    for fixed code compression as in "wb9F".  (See the description of
-   deflateInit2 for more information about the strategy parameter.) Also "a"
-   can be used instead of "w" to request that the gzip stream that will be
-   written be appended to the file.  "+" will result in an error, since reading
-   and writing to the same gzip file is not supported.
+   deflateInit2 for more information about the strategy parameter.)  'T' will
+   request transparent writing or appending with no compression and not using
+   the gzip format.
+
+     "a" can be used instead of "w" to request that the gzip stream that will
+   be written be appended to the file.  "+" will result in an error, since
+   reading and writing to the same gzip file is not supported.
+
+     These functions, as well as gzip, will read and decode a sequence of gzip
+   streams in a file.  The append function of gzopen() can be used to create
+   such a file.  (Also see gzflush() for another way to do this.)  When
+   appending, gzopen does not test whether the file begins with a gzip stream,
+   nor does it look for the end of the gzip streams to begin appending.  gzopen
+   will simply append a gzip stream to the existing file.
 
      gzopen can be used to read a file which is not in gzip format; in this
-   case gzread will directly read from the file without decompression.
+   case gzread will directly read from the file without decompression.  When
+   reading, this will be detected automatically by looking for the magic two-
+   byte gzip header.
 
      gzopen returns NULL if the file could not be opened, if there was
    insufficient memory to allocate the gzFile state, or if an invalid mode was
@@ -1197,7 +1248,11 @@ ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode));
    descriptor fd, just like fclose(fdopen(fd, mode)) closes the file descriptor
    fd.  If you want to keep fd open, use fd = dup(fd_keep); gz = gzdopen(fd,
    mode);.  The duplicated descriptor should be saved to avoid a leak, since
-   gzdopen does not close fd if it fails.
+   gzdopen does not close fd if it fails.  If you are using fileno() to get the
+   file descriptor from a FILE *, then you will have to use dup() to avoid
+   double-close()ing the file descriptor.  Both gzclose() and fclose() will
+   close the associated file descriptor, so they need to have different file
+   descriptors.
 
      gzdopen returns NULL if there was insufficient memory to allocate the
    gzFile state, if an invalid mode was specified (an 'r', 'w', or 'a' was not
@@ -1235,14 +1290,26 @@ ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy));
 ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len));
 /*
      Reads the given number of uncompressed bytes from the compressed file.  If
-   the input file was not in gzip format, gzread copies the given number of
-   bytes into the buffer.
+   the input file is not in gzip format, gzread copies the given number of
+   bytes into the buffer directly from the file.
 
      After reaching the end of a gzip stream in the input, gzread will continue
-   to read, looking for another gzip stream, or failing that, reading the rest
-   of the input file directly without decompression.  The entire input file
-   will be read if gzread is called until it returns less than the requested
-   len.
+   to read, looking for another gzip stream.  Any number of gzip streams may be
+   concatenated in the input file, and will all be decompressed by gzread().
+   If something other than a gzip stream is encountered after a gzip stream,
+   that remaining trailing garbage is ignored (and no error is returned).
+
+     gzread can be used to read a gzip file that is being concurrently written.
+   Upon reaching the end of the input, gzread will return with the available
+   data.  If the error code returned by gzerror is Z_OK or Z_BUF_ERROR, then
+   gzclearerr can be used to clear the end of file indicator in order to permit
+   gzread to be tried again.  Z_OK indicates that a gzip stream was completed
+   on the last gzread.  Z_BUF_ERROR indicates that the input file ended in the
+   middle of a gzip stream.  Note that gzread does not return -1 in the event
+   of an incomplete gzip stream.  This error is deferred until gzclose(), which
+   will return Z_BUF_ERROR if the last gzread ended in the middle of a gzip
+   stream.  Alternatively, gzerror can be used before gzclose to detect this
+   case.
 
      gzread returns the number of uncompressed bytes actually read, less than
    len for end of file, or -1 for error.
@@ -1256,7 +1323,7 @@ ZEXTERN int ZEXPORT gzwrite OF((gzFile file,
    error.
 */
 
-ZEXTERN int ZEXPORTVA gzprintf OF((gzFile file, const char *format, ...));
+ZEXTERN int ZEXPORTVA gzprintf Z_ARG((gzFile file, const char *format, ...));
 /*
      Converts, formats, and writes the arguments to the compressed file under
    control of the format string, as in fprintf.  gzprintf returns the number of
@@ -1301,7 +1368,10 @@ ZEXTERN int ZEXPORT gzputc OF((gzFile file, int c));
 ZEXTERN int ZEXPORT gzgetc OF((gzFile file));
 /*
      Reads one byte from the compressed file.  gzgetc returns this byte or -1
-   in case of end of file or error.
+   in case of end of file or error.  This is implemented as a macro for speed.
+   As such, it does not do all of the checking the other functions do.  I.e.
+   it does not check to see if file is NULL, nor whether the structure file
+   points to has been clobbered or not.
 */
 
 ZEXTERN int ZEXPORT gzungetc OF((int c, gzFile file));
@@ -1397,9 +1467,7 @@ ZEXTERN int ZEXPORT gzeof OF((gzFile file));
 ZEXTERN int ZEXPORT gzdirect OF((gzFile file));
 /*
      Returns true (1) if file is being copied directly while reading, or false
-   (0) if file is a gzip stream being decompressed.  This state can change from
-   false to true while reading the input file if the end of a gzip stream is
-   reached, but is followed by data that is not another gzip stream.
+   (0) if file is a gzip stream being decompressed.
 
      If the input file is empty, gzdirect() will return true, since the input
    does not contain a gzip stream.
@@ -1408,6 +1476,13 @@ ZEXTERN int ZEXPORT gzdirect OF((gzFile file));
    cause buffers to be allocated to allow reading the file to determine if it
    is a gzip file.  Therefore if gzbuffer() is used, it should be called before
    gzdirect().
+
+     When writing, gzdirect() returns true (1) if transparent writing was
+   requested ("wT" for the gzopen() mode), or false (0) otherwise.  (Note:
+   gzdirect() is not needed when writing.  Transparent writing must be
+   explicitly requested, so the application already knows the answer.  When
+   linking statically, using gzdirect() will include all of the zlib code for
+   gzip file reading and decompression, which may not be desired.)
 */
 
 ZEXTERN int ZEXPORT    gzclose OF((gzFile file));
@@ -1419,7 +1494,8 @@ ZEXTERN int ZEXPORT    gzclose OF((gzFile file));
    must not be called more than once on the same allocation.
 
      gzclose will return Z_STREAM_ERROR if file is not valid, Z_ERRNO on a
-   file operation error, or Z_OK on success.
+   file operation error, Z_MEM_ERROR if out of memory, Z_BUF_ERROR if the
+   last read ended in the middle of a gzip stream, or Z_OK on success.
 */
 
 ZEXTERN int ZEXPORT gzclose_r OF((gzFile file));
@@ -1457,6 +1533,7 @@ ZEXTERN void ZEXPORT gzclearerr OF((gzFile file));
    file that is being written concurrently.
 */
 
+#endif /* !Z_SOLO */
 
                         /* checksum functions */
 
@@ -1492,7 +1569,9 @@ ZEXTERN uLong ZEXPORT adler32_combine OF((uLong adler1, uLong adler2,
      Combine two Adler-32 checksums into one.  For two sequences of bytes, seq1
    and seq2 with lengths len1 and len2, Adler-32 checksums were calculated for
    each, adler1 and adler2.  adler32_combine() returns the Adler-32 checksum of
-   seq1 and seq2 concatenated, requiring only adler1, adler2, and len2.
+   seq1 and seq2 concatenated, requiring only adler1, adler2, and len2.  Note
+   that the z_off_t type (like off_t) is a signed integer.  If len2 is
+   negative, the result has no meaning or utility.
 */
 
 ZEXTERN uLong ZEXPORT crc32   OF((uLong crc, const Bytef *buf, uInt len));
@@ -1544,17 +1623,36 @@ ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits,
                                          const char *version,
                                          int stream_size));
 #define deflateInit(strm, level) \
-        deflateInit_((strm), (level),       ZLIB_VERSION, sizeof(z_stream))
+        deflateInit_((strm), (level), ZLIB_VERSION, (int)sizeof(z_stream))
 #define inflateInit(strm) \
-        inflateInit_((strm),                ZLIB_VERSION, sizeof(z_stream))
+        inflateInit_((strm), ZLIB_VERSION, (int)sizeof(z_stream))
 #define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \
         deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\
-                      (strategy),           ZLIB_VERSION, sizeof(z_stream))
+                      (strategy), ZLIB_VERSION, (int)sizeof(z_stream))
 #define inflateInit2(strm, windowBits) \
-        inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream))
+        inflateInit2_((strm), (windowBits), ZLIB_VERSION, \
+                      (int)sizeof(z_stream))
 #define inflateBackInit(strm, windowBits, window) \
         inflateBackInit_((strm), (windowBits), (window), \
-                                            ZLIB_VERSION, sizeof(z_stream))
+                      ZLIB_VERSION, (int)sizeof(z_stream))
+
+#ifndef Z_SOLO
+
+/* gzgetc() macro and its supporting function and exposed data structure.  Note
+ * that the real internal state is much larger than the exposed structure.
+ * This abbreviated structure exposes just enough for the gzgetc() macro.  The
+ * user should not mess with these exposed elements, since their names or
+ * behavior could change in the future, perhaps even capriciously.  They can
+ * only be used by the gzgetc() macro.  You have been warned.
+ */
+struct gzFile_s {
+    unsigned have;
+    unsigned char *next;
+    z_off64_t pos;
+};
+ZEXTERN int ZEXPORT gzgetc_ OF((gzFile file));
+#define gzgetc(g) \
+    ((g)->have ? ((g)->have--, (g)->pos++, *((g)->next)++) : gzgetc_(g))
 
 /* provide 64-bit offset functions if _LARGEFILE64_SOURCE defined, and/or
  * change the regular functions to 64 bits if _FILE_OFFSET_BITS is 64 (if
@@ -1572,13 +1670,22 @@ ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits,
 #endif
 
 #if !defined(ZLIB_INTERNAL) && _FILE_OFFSET_BITS-0 == 64 && _LFS64_LARGEFILE-0
-#  define gzopen gzopen64
-#  define gzseek gzseek64
-#  define gztell gztell64
-#  define gzoffset gzoffset64
-#  define adler32_combine adler32_combine64
-#  define crc32_combine crc32_combine64
-#  ifdef _LARGEFILE64_SOURCE
+#  ifdef Z_PREFIX_SET
+#    define z_gzopen z_gzopen64
+#    define z_gzseek z_gzseek64
+#    define z_gztell z_gztell64
+#    define z_gzoffset z_gzoffset64
+#    define z_adler32_combine z_adler32_combine64
+#    define z_crc32_combine z_crc32_combine64
+#  else
+#    define gzopen gzopen64
+#    define gzseek gzseek64
+#    define gztell gztell64
+#    define gzoffset gzoffset64
+#    define adler32_combine adler32_combine64
+#    define crc32_combine crc32_combine64
+#  endif
+#  ifndef _LARGEFILE64_SOURCE
      ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *));
      ZEXTERN z_off_t ZEXPORT gzseek64 OF((gzFile, z_off_t, int));
      ZEXTERN z_off_t ZEXPORT gztell64 OF((gzFile));
@@ -1595,6 +1702,13 @@ ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits,
    ZEXTERN uLong ZEXPORT crc32_combine OF((uLong, uLong, z_off_t));
 #endif
 
+#else /* Z_SOLO */
+
+   ZEXTERN uLong ZEXPORT adler32_combine OF((uLong, uLong, z_off_t));
+   ZEXTERN uLong ZEXPORT crc32_combine OF((uLong, uLong, z_off_t));
+
+#endif /* !Z_SOLO */
+
 /* hack for buggy compilers */
 #if !defined(ZUTIL_H) && !defined(NO_DUMMY_DECL)
     struct internal_state {int dummy;};
@@ -1605,6 +1719,11 @@ ZEXTERN const char   * ZEXPORT zError           OF((int));
 ZEXTERN int            ZEXPORT inflateSyncPoint OF((z_streamp));
 ZEXTERN const uLongf * ZEXPORT get_crc_table    OF((void));
 ZEXTERN int            ZEXPORT inflateUndermine OF((z_streamp, int));
+ZEXTERN int            ZEXPORT inflateResetKeep OF((z_streamp));
+ZEXTERN int            ZEXPORT deflateResetKeep OF((z_streamp));
+#ifndef Z_SOLO
+  ZEXTERN unsigned long  ZEXPORT gzflags          OF((void));
+#endif
 
 #ifdef __cplusplus
 }
index ff95c744258315fd854cc9421058acbaae0c7834..93a0a6b3624ff7a0bcc6a319ff6d328b6849462f 100644 (file)
Binary files a/misc/builddeps/dp.win64/lib/libz.a and b/misc/builddeps/dp.win64/lib/libz.a differ
diff --git a/misc/builddeps/dp.win64/lib/pkgconfig/zlib.pc b/misc/builddeps/dp.win64/lib/pkgconfig/zlib.pc
new file mode 100644 (file)
index 0000000..17626e1
--- /dev/null
@@ -0,0 +1,13 @@
+prefix=/usr/local
+exec_prefix=/usr/local
+libdir=/tmp/zlib-1.2.6.out/usr/local/lib
+sharedlibdir=/tmp/zlib-1.2.6.out/usr/local/lib
+includedir=/tmp/zlib-1.2.6.out/usr/local/include
+
+Name: zlib
+Description: zlib compression library
+Version: 1.2.6
+
+Requires:
+Libs: -L${libdir} -L${sharedlibdir} -lz
+Cflags: -I${includedir}
index a74556f56595a473541bbdd0c9390230c1a1e105..73ea20bfc7cde03f1643cc8ff290a45786a4323b 100755 (executable)
Binary files a/misc/buildfiles/osx/Xonotic.app/Contents/MacOS/libd0_blind_id.0.dylib and b/misc/buildfiles/osx/Xonotic.app/Contents/MacOS/libd0_blind_id.0.dylib differ
diff --git a/misc/buildfiles/osx/Xonotic.app/Contents/MacOS/libd0_blind_id.dylib b/misc/buildfiles/osx/Xonotic.app/Contents/MacOS/libd0_blind_id.dylib
new file mode 120000 (symlink)
index 0000000..de56202
--- /dev/null
@@ -0,0 +1 @@
+libd0_blind_id.0.dylib
\ No newline at end of file
diff --git a/misc/buildfiles/osx/Xonotic.app/Contents/MacOS/libd0_rijndael.dylib b/misc/buildfiles/osx/Xonotic.app/Contents/MacOS/libd0_rijndael.dylib
new file mode 120000 (symlink)
index 0000000..4c976f9
--- /dev/null
@@ -0,0 +1 @@
+libd0_rijndael.0.dylib
\ No newline at end of file
diff --git a/misc/buildfiles/osx/Xonotic.app/Contents/MacOS/libode.3.dylib b/misc/buildfiles/osx/Xonotic.app/Contents/MacOS/libode.3.dylib
new file mode 100755 (executable)
index 0000000..0d2891e
Binary files /dev/null and b/misc/buildfiles/osx/Xonotic.app/Contents/MacOS/libode.3.dylib differ
diff --git a/misc/buildfiles/osx/Xonotic.app/Contents/MacOS/libode.dylib b/misc/buildfiles/osx/Xonotic.app/Contents/MacOS/libode.dylib
new file mode 120000 (symlink)
index 0000000..4821540
--- /dev/null
@@ -0,0 +1 @@
+libode.3.dylib
\ No newline at end of file
diff --git a/misc/buildfiles/osx/Xonotic.app/Contents/MacOS/libpng.dylib b/misc/buildfiles/osx/Xonotic.app/Contents/MacOS/libpng.dylib
new file mode 120000 (symlink)
index 0000000..61ee636
--- /dev/null
@@ -0,0 +1 @@
+libpng15.dylib
\ No newline at end of file
diff --git a/misc/buildfiles/osx/Xonotic.app/Contents/MacOS/libpng15.15.dylib b/misc/buildfiles/osx/Xonotic.app/Contents/MacOS/libpng15.15.dylib
new file mode 100755 (executable)
index 0000000..3bd63ce
Binary files /dev/null and b/misc/buildfiles/osx/Xonotic.app/Contents/MacOS/libpng15.15.dylib differ
diff --git a/misc/buildfiles/osx/Xonotic.app/Contents/MacOS/libpng15.dylib b/misc/buildfiles/osx/Xonotic.app/Contents/MacOS/libpng15.dylib
new file mode 120000 (symlink)
index 0000000..1259168
--- /dev/null
@@ -0,0 +1 @@
+libpng15.15.dylib
\ No newline at end of file
index 524b760277b3f2d443a0b83cd55f22162a7d8f23..6eebc42d10113024a5650decd9f66fb3d691a3dc 100755 (executable)
Binary files a/misc/buildfiles/win32/libd0_blind_id-0.dll and b/misc/buildfiles/win32/libd0_blind_id-0.dll differ
index cd6088694577fc4283cf45ffb634c340473226f0..d6934a6edbae89292f8c8b39056a0406a46ccafe 100755 (executable)
Binary files a/misc/buildfiles/win32/libd0_rijndael-0.dll and b/misc/buildfiles/win32/libd0_rijndael-0.dll differ
index fd8511a0082d2f78d525a31eaa67de75d6a4f349..e51892bba2c37b43848edb06cae12d41c92e62ab 100755 (executable)
Binary files a/misc/buildfiles/win32/libmodplug-1.dll and b/misc/buildfiles/win32/libmodplug-1.dll differ
diff --git a/misc/buildfiles/win32/libode-3.dll b/misc/buildfiles/win32/libode-3.dll
new file mode 100755 (executable)
index 0000000..b8a7bba
Binary files /dev/null and b/misc/buildfiles/win32/libode-3.dll differ
diff --git a/misc/buildfiles/win32/libpng12.dll b/misc/buildfiles/win32/libpng12.dll
deleted file mode 100755 (executable)
index 6e55f4c..0000000
Binary files a/misc/buildfiles/win32/libpng12.dll and /dev/null differ
diff --git a/misc/buildfiles/win32/libpng15-15.dll b/misc/buildfiles/win32/libpng15-15.dll
new file mode 100755 (executable)
index 0000000..956af87
Binary files /dev/null and b/misc/buildfiles/win32/libpng15-15.dll differ
index dbcbf1726045bfa6190cc34d25e27154fdb03a22..94fdb72fd25c771e0417ce40586eb009312c6917 100755 (executable)
Binary files a/misc/buildfiles/win64/libd0_blind_id-0.dll and b/misc/buildfiles/win64/libd0_blind_id-0.dll differ
index 13b9f41f84faa9801f6050f7166448e0bc113b89..e72d91e168bb5cbed86880c141c683fb3a5cd11a 100755 (executable)
Binary files a/misc/buildfiles/win64/libd0_rijndael-0.dll and b/misc/buildfiles/win64/libd0_rijndael-0.dll differ
index fbd7f709d12b36b61abce2b17970b72addd78771..a036c27a5cd243a52110594fa641abbd8c3c0a93 100755 (executable)
Binary files a/misc/buildfiles/win64/libmodplug-1.dll and b/misc/buildfiles/win64/libmodplug-1.dll differ
diff --git a/misc/buildfiles/win64/libode-3.dll b/misc/buildfiles/win64/libode-3.dll
new file mode 100755 (executable)
index 0000000..b1922c8
Binary files /dev/null and b/misc/buildfiles/win64/libode-3.dll differ
diff --git a/misc/buildfiles/win64/libpng12.dll b/misc/buildfiles/win64/libpng12.dll
deleted file mode 100755 (executable)
index 99a0a93..0000000
Binary files a/misc/buildfiles/win64/libpng12.dll and /dev/null differ
diff --git a/misc/buildfiles/win64/libpng15-15.dll b/misc/buildfiles/win64/libpng15-15.dll
new file mode 100755 (executable)
index 0000000..9f869db
Binary files /dev/null and b/misc/buildfiles/win64/libpng15-15.dll differ