summaryrefslogtreecommitdiff
path: root/libs/ode-0.16.1/include
diff options
context:
space:
mode:
authorsanine <sanine.not@pm.me>2022-10-01 20:59:36 -0500
committersanine <sanine.not@pm.me>2022-10-01 20:59:36 -0500
commitc5fc66ee58f2c60f2d226868bb1cf5b91badaf53 (patch)
tree277dd280daf10bf77013236b8edfa5f88708c7e0 /libs/ode-0.16.1/include
parent1cf9cc3408af7008451f9133fb95af66a9697d15 (diff)
add ode
Diffstat (limited to 'libs/ode-0.16.1/include')
-rw-r--r--libs/ode-0.16.1/include/Makefile.am1
-rw-r--r--libs/ode-0.16.1/include/Makefile.in640
-rw-r--r--libs/ode-0.16.1/include/drawstuff/Makefile.am2
-rw-r--r--libs/ode-0.16.1/include/drawstuff/Makefile.in528
-rw-r--r--libs/ode-0.16.1/include/drawstuff/drawstuff.h325
-rw-r--r--libs/ode-0.16.1/include/drawstuff/version.h29
-rw-r--r--libs/ode-0.16.1/include/ode/Makefile.am34
-rw-r--r--libs/ode-0.16.1/include/ode/Makefile.in642
-rw-r--r--libs/ode-0.16.1/include/ode/README18
-rw-r--r--libs/ode-0.16.1/include/ode/collision.h1526
-rw-r--r--libs/ode-0.16.1/include/ode/collision_space.h182
-rw-r--r--libs/ode-0.16.1/include/ode/collision_trimesh.h316
-rw-r--r--libs/ode-0.16.1/include/ode/common.h568
-rw-r--r--libs/ode-0.16.1/include/ode/compatibility.h40
-rw-r--r--libs/ode-0.16.1/include/ode/contact.h110
-rw-r--r--libs/ode-0.16.1/include/ode/cooperative.h229
-rw-r--r--libs/ode-0.16.1/include/ode/error.h63
-rw-r--r--libs/ode-0.16.1/include/ode/export-dif.h40
-rw-r--r--libs/ode-0.16.1/include/ode/mass.h144
-rw-r--r--libs/ode-0.16.1/include/ode/matrix.h200
-rw-r--r--libs/ode-0.16.1/include/ode/matrix_coop.h291
-rw-r--r--libs/ode-0.16.1/include/ode/memory.h59
-rw-r--r--libs/ode-0.16.1/include/ode/misc.h86
-rw-r--r--libs/ode-0.16.1/include/ode/objects.h3396
-rw-r--r--libs/ode-0.16.1/include/ode/ode.h56
-rw-r--r--libs/ode-0.16.1/include/ode/odeconfig.h218
-rw-r--r--libs/ode-0.16.1/include/ode/odecpp.h1355
-rw-r--r--libs/ode-0.16.1/include/ode/odecpp_collision.h467
-rw-r--r--libs/ode-0.16.1/include/ode/odeinit.h236
-rw-r--r--libs/ode-0.16.1/include/ode/odemath.h545
-rw-r--r--libs/ode-0.16.1/include/ode/odemath_legacy.h162
-rw-r--r--libs/ode-0.16.1/include/ode/precision.h16
-rw-r--r--libs/ode-0.16.1/include/ode/precision.h.in16
-rw-r--r--libs/ode-0.16.1/include/ode/rotation.h70
-rw-r--r--libs/ode-0.16.1/include/ode/threading.h412
-rw-r--r--libs/ode-0.16.1/include/ode/threading_impl.h292
-rw-r--r--libs/ode-0.16.1/include/ode/timer.h76
-rw-r--r--libs/ode-0.16.1/include/ode/version.h6
-rw-r--r--libs/ode-0.16.1/include/ode/version.h.in6
39 files changed, 13402 insertions, 0 deletions
diff --git a/libs/ode-0.16.1/include/Makefile.am b/libs/ode-0.16.1/include/Makefile.am
new file mode 100644
index 0000000..0a0830e
--- /dev/null
+++ b/libs/ode-0.16.1/include/Makefile.am
@@ -0,0 +1 @@
+SUBDIRS = ode drawstuff
diff --git a/libs/ode-0.16.1/include/Makefile.in b/libs/ode-0.16.1/include/Makefile.in
new file mode 100644
index 0000000..3a7f2b2
--- /dev/null
+++ b/libs/ode-0.16.1/include/Makefile.in
@@ -0,0 +1,640 @@
+# Makefile.in generated by automake 1.15 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2014 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+VPATH = @srcdir@
+am__is_gnu_make = { \
+ if test -z '$(MAKELEVEL)'; then \
+ false; \
+ elif test -n '$(MAKE_HOST)'; then \
+ true; \
+ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+ true; \
+ else \
+ false; \
+ fi; \
+}
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = include
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \
+ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
+ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
+ $(top_srcdir)/m4/pkg.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/ode/src/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 =
+SOURCES =
+DIST_SOURCES =
+RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \
+ ctags-recursive dvi-recursive html-recursive info-recursive \
+ install-data-recursive install-dvi-recursive \
+ install-exec-recursive install-html-recursive \
+ install-info-recursive install-pdf-recursive \
+ install-ps-recursive install-recursive installcheck-recursive \
+ installdirs-recursive pdf-recursive ps-recursive \
+ tags-recursive uninstall-recursive
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \
+ distclean-recursive maintainer-clean-recursive
+am__recursive_targets = \
+ $(RECURSIVE_TARGETS) \
+ $(RECURSIVE_CLEAN_TARGETS) \
+ $(am__extra_recursive_targets)
+AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \
+ distdir
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates. Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+ BEGIN { nonempty = 0; } \
+ { items[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique. This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+ list='$(am__tagged_files)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+DIST_SUBDIRS = $(SUBDIRS)
+am__DIST_COMMON = $(srcdir)/Makefile.in
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+am__relativize = \
+ dir0=`pwd`; \
+ sed_first='s,^\([^/]*\)/.*$$,\1,'; \
+ sed_rest='s,^[^/]*/*,,'; \
+ sed_last='s,^.*/\([^/]*\)$$,\1,'; \
+ sed_butlast='s,/*[^/]*$$,,'; \
+ while test -n "$$dir1"; do \
+ first=`echo "$$dir1" | sed -e "$$sed_first"`; \
+ if test "$$first" != "."; then \
+ if test "$$first" = ".."; then \
+ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \
+ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \
+ else \
+ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \
+ if test "$$first2" = "$$first"; then \
+ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \
+ else \
+ dir2="../$$dir2"; \
+ fi; \
+ dir0="$$dir0"/"$$first"; \
+ fi; \
+ fi; \
+ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \
+ done; \
+ reldir="$$dir2"
+ACLOCAL = @ACLOCAL@
+ALLOCA = @ALLOCA@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AS = @AS@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CCD_CFLAGS = @CCD_CFLAGS@
+CCD_LIBS = @CCD_LIBS@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DOXYGEN = @DOXYGEN@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+EXTRA_LIBTOOL_LDFLAGS = @EXTRA_LIBTOOL_LDFLAGS@
+FGREP = @FGREP@
+GL_LIBS = @GL_LIBS@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBSTDCXX = @LIBSTDCXX@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+ODE_PRECISION = @ODE_PRECISION@
+ODE_VERSION = @ODE_VERSION@
+ODE_VERSION_INFO = @ODE_VERSION_INFO@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+RANLIB = @RANLIB@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+VERSION = @VERSION@
+WINDRES = @WINDRES@
+X11_CFLAGS = @X11_CFLAGS@
+X11_LIBS = @X11_LIBS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+ac_ct_WINDRES = @ac_ct_WINDRES@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+runstatedir = @runstatedir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+subdirs = @subdirs@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+SUBDIRS = ode drawstuff
+all: all-recursive
+
+.SUFFIXES:
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign include/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --foreign include/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+# This directory's subdirectories are mostly independent; you can cd
+# into them and run 'make' without going through this Makefile.
+# To change the values of 'make' variables: instead of editing Makefiles,
+# (1) if the variable is set in 'config.status', edit 'config.status'
+# (which will cause the Makefiles to be regenerated when you run 'make');
+# (2) otherwise, pass the desired values on the 'make' command line.
+$(am__recursive_targets):
+ @fail=; \
+ if $(am__make_keepgoing); then \
+ failcom='fail=yes'; \
+ else \
+ failcom='exit 1'; \
+ fi; \
+ dot_seen=no; \
+ target=`echo $@ | sed s/-recursive//`; \
+ case "$@" in \
+ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
+ *) list='$(SUBDIRS)' ;; \
+ esac; \
+ for subdir in $$list; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ dot_seen=yes; \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || eval $$failcom; \
+ done; \
+ if test "$$dot_seen" = "no"; then \
+ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
+ fi; test -z "$$fail"
+
+ID: $(am__tagged_files)
+ $(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-recursive
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ set x; \
+ here=`pwd`; \
+ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
+ include_option=--etags-include; \
+ empty_fix=.; \
+ else \
+ include_option=--include; \
+ empty_fix=; \
+ fi; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ test ! -f $$subdir/TAGS || \
+ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \
+ fi; \
+ done; \
+ $(am__define_uniq_tagged_files); \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: ctags-recursive
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ $(am__define_uniq_tagged_files); \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-recursive
+
+cscopelist-am: $(am__tagged_files)
+ list='$(am__tagged_files)'; \
+ case "$(srcdir)" in \
+ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+ *) sdir=$(subdir)/$(srcdir) ;; \
+ esac; \
+ for i in $$list; do \
+ if test -f "$$i"; then \
+ echo "$(subdir)/$$i"; \
+ else \
+ echo "$$sdir/$$i"; \
+ fi; \
+ done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+ @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ $(am__make_dryrun) \
+ || test -d "$(distdir)/$$subdir" \
+ || $(MKDIR_P) "$(distdir)/$$subdir" \
+ || exit 1; \
+ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \
+ $(am__relativize); \
+ new_distdir=$$reldir; \
+ dir1=$$subdir; dir2="$(top_distdir)"; \
+ $(am__relativize); \
+ new_top_distdir=$$reldir; \
+ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \
+ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \
+ ($(am__cd) $$subdir && \
+ $(MAKE) $(AM_MAKEFLAGS) \
+ top_distdir="$$new_top_distdir" \
+ distdir="$$new_distdir" \
+ am__remove_distdir=: \
+ am__skip_length_check=: \
+ am__skip_mode_fix=: \
+ distdir) \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-recursive
+all-am: Makefile
+installdirs: installdirs-recursive
+installdirs-am:
+install: install-recursive
+install-exec: install-exec-recursive
+install-data: install-data-recursive
+uninstall: uninstall-recursive
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-recursive
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-recursive
+
+clean-am: clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-recursive
+ -rm -f Makefile
+distclean-am: clean-am distclean-generic distclean-tags
+
+dvi: dvi-recursive
+
+dvi-am:
+
+html: html-recursive
+
+html-am:
+
+info: info-recursive
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-recursive
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-recursive
+
+install-html-am:
+
+install-info: install-info-recursive
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-recursive
+
+install-pdf-am:
+
+install-ps: install-ps-recursive
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-recursive
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-recursive
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+pdf: pdf-recursive
+
+pdf-am:
+
+ps: ps-recursive
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: $(am__recursive_targets) install-am install-strip
+
+.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \
+ check-am clean clean-generic clean-libtool cscopelist-am ctags \
+ ctags-am distclean distclean-generic distclean-libtool \
+ distclean-tags distdir dvi dvi-am html html-am info info-am \
+ install install-am install-data install-data-am install-dvi \
+ install-dvi-am install-exec install-exec-am install-html \
+ install-html-am install-info install-info-am install-man \
+ install-pdf install-pdf-am install-ps install-ps-am \
+ install-strip installcheck installcheck-am installdirs \
+ installdirs-am maintainer-clean maintainer-clean-generic \
+ mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \
+ ps ps-am tags tags-am uninstall uninstall-am
+
+.PRECIOUS: Makefile
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/libs/ode-0.16.1/include/drawstuff/Makefile.am b/libs/ode-0.16.1/include/drawstuff/Makefile.am
new file mode 100644
index 0000000..14a9fb1
--- /dev/null
+++ b/libs/ode-0.16.1/include/drawstuff/Makefile.am
@@ -0,0 +1,2 @@
+noinst_HEADERS = drawstuff.h version.h
+
diff --git a/libs/ode-0.16.1/include/drawstuff/Makefile.in b/libs/ode-0.16.1/include/drawstuff/Makefile.in
new file mode 100644
index 0000000..3bc421d
--- /dev/null
+++ b/libs/ode-0.16.1/include/drawstuff/Makefile.in
@@ -0,0 +1,528 @@
+# Makefile.in generated by automake 1.15 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2014 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+VPATH = @srcdir@
+am__is_gnu_make = { \
+ if test -z '$(MAKELEVEL)'; then \
+ false; \
+ elif test -n '$(MAKE_HOST)'; then \
+ true; \
+ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+ true; \
+ else \
+ false; \
+ fi; \
+}
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = include/drawstuff
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \
+ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
+ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
+ $(top_srcdir)/m4/pkg.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(noinst_HEADERS) \
+ $(am__DIST_COMMON)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/ode/src/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 =
+SOURCES =
+DIST_SOURCES =
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+HEADERS = $(noinst_HEADERS)
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates. Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+ BEGIN { nonempty = 0; } \
+ { items[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique. This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+ list='$(am__tagged_files)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+am__DIST_COMMON = $(srcdir)/Makefile.in
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ALLOCA = @ALLOCA@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AS = @AS@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CCD_CFLAGS = @CCD_CFLAGS@
+CCD_LIBS = @CCD_LIBS@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DOXYGEN = @DOXYGEN@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+EXTRA_LIBTOOL_LDFLAGS = @EXTRA_LIBTOOL_LDFLAGS@
+FGREP = @FGREP@
+GL_LIBS = @GL_LIBS@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBSTDCXX = @LIBSTDCXX@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+ODE_PRECISION = @ODE_PRECISION@
+ODE_VERSION = @ODE_VERSION@
+ODE_VERSION_INFO = @ODE_VERSION_INFO@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+RANLIB = @RANLIB@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+VERSION = @VERSION@
+WINDRES = @WINDRES@
+X11_CFLAGS = @X11_CFLAGS@
+X11_LIBS = @X11_LIBS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+ac_ct_WINDRES = @ac_ct_WINDRES@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+runstatedir = @runstatedir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+subdirs = @subdirs@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+noinst_HEADERS = drawstuff.h version.h
+all: all-am
+
+.SUFFIXES:
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign include/drawstuff/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --foreign include/drawstuff/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+ID: $(am__tagged_files)
+ $(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ set x; \
+ here=`pwd`; \
+ $(am__define_uniq_tagged_files); \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ $(am__define_uniq_tagged_files); \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+ list='$(am__tagged_files)'; \
+ case "$(srcdir)" in \
+ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+ *) sdir=$(subdir)/$(srcdir) ;; \
+ esac; \
+ for i in $$list; do \
+ if test -f "$$i"; then \
+ echo "$(subdir)/$$i"; \
+ else \
+ echo "$$sdir/$$i"; \
+ fi; \
+ done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(HEADERS)
+installdirs:
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-am
+ -rm -f Makefile
+distclean-am: clean-am distclean-generic distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \
+ clean-libtool cscopelist-am ctags ctags-am distclean \
+ distclean-generic distclean-libtool distclean-tags distdir dvi \
+ dvi-am html html-am info info-am install install-am \
+ install-data install-data-am install-dvi install-dvi-am \
+ install-exec install-exec-am install-html install-html-am \
+ install-info install-info-am install-man install-pdf \
+ install-pdf-am install-ps install-ps-am install-strip \
+ installcheck installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-generic \
+ mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \
+ uninstall-am
+
+.PRECIOUS: Makefile
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/libs/ode-0.16.1/include/drawstuff/drawstuff.h b/libs/ode-0.16.1/include/drawstuff/drawstuff.h
new file mode 100644
index 0000000..9a3ac20
--- /dev/null
+++ b/libs/ode-0.16.1/include/drawstuff/drawstuff.h
@@ -0,0 +1,325 @@
+/*************************************************************************
+ * *
+ * 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. *
+ * *
+ *************************************************************************/
+
+/** @defgroup drawstuff DrawStuff
+
+DrawStuff is a library for rendering simple 3D objects in a virtual
+environment, for the purposes of demonstrating the features of ODE.
+It is provided for demonstration purposes and is not intended for
+production use.
+
+@section Notes
+
+In the virtual world, the z axis is "up" and z=0 is the floor.
+
+The user is able to click+drag in the main window to move the camera:
+ * left button - pan and tilt.
+ * right button - forward and sideways.
+ * left + right button (or middle button) - sideways and up.
+*/
+
+
+#ifndef __DRAWSTUFF_H__
+#define __DRAWSTUFF_H__
+
+/* Define a DLL export symbol for those platforms that need it */
+#if defined(ODE_PLATFORM_WINDOWS)
+ #if defined(DS_DLL)
+ #define DS_API __declspec(dllexport)
+ #elif !defined(DS_LIB)
+ #define DS_DLL_API __declspec(dllimport)
+ #endif
+#endif
+
+#if !defined(DS_API)
+ #define DS_API
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#include <drawstuff/version.h>
+
+
+/* texture numbers */
+ enum DS_TEXTURE_NUMBER
+ {
+ DS_NONE = 0, /* uses the current color instead of a texture */
+ DS_WOOD,
+ DS_CHECKERED,
+ DS_GROUND,
+ DS_SKY
+ };
+
+/* draw modes */
+
+#define DS_POLYFILL 0
+#define DS_WIREFRAME 1
+
+/**
+ * @struct dsFunctions
+ * @brief Set of functions to be used as callbacks by the simulation loop.
+ * @ingroup drawstuff
+ */
+typedef struct dsFunctions {
+ int version; /* put DS_VERSION here */
+ /* version 1 data */
+ void (*start)(); /* called before sim loop starts */
+ void (*step) (int pause); /* called before every frame */
+ void (*command) (int cmd); /* called if a command key is pressed */
+ void (*stop)(); /* called after sim loop exits */
+ /* version 2 data */
+ const char *path_to_textures; /* if nonzero, path to texture files */
+} dsFunctions;
+
+
+/**
+ * @brief Does the complete simulation.
+ * @ingroup drawstuff
+ * This function starts running the simulation, and only exits when the simulation is done.
+ * Function pointers should be provided for the callbacks.
+ * @param argv supports flags like '-notex' '-noshadow' '-pause'
+ * @param fn Callback functions.
+ */
+DS_API void dsSimulationLoop (int argc, char **argv,
+ int window_width, int window_height,
+ struct dsFunctions *fn);
+
+/**
+ * @brief exit with error message.
+ * @ingroup drawstuff
+ * This function displays an error message then exit.
+ * @param msg format strin, like printf, without the newline character.
+ */
+DS_API void dsError (const char *msg, ...);
+
+/**
+ * @brief exit with error message and core dump.
+ * @ingroup drawstuff
+ * this functions tries to dump core or start the debugger.
+ * @param msg format strin, like printf, without the newline character.
+ */
+DS_API void dsDebug (const char *msg, ...);
+
+/**
+ * @brief print log message
+ * @ingroup drawstuff
+ * @param msg format string, like printf, without the \n.
+ */
+DS_API void dsPrint (const char *msg, ...);
+
+/**
+ * @brief Sets the viewpoint
+ * @ingroup drawstuff
+ * @param xyz camera position.
+ * @param hpr contains heading, pitch and roll numbers in degrees. heading=0
+ * points along the x axis, pitch=0 is looking towards the horizon, and
+ * roll 0 is "unrotated".
+ */
+DS_API void dsSetViewpoint (float xyz[3], float hpr[3]);
+
+
+/**
+ * @brief Gets the viewpoint
+ * @ingroup drawstuff
+ * @param xyz position
+ * @param hpr heading,pitch,roll.
+ */
+DS_API void dsGetViewpoint (float xyz[3], float hpr[3]);
+
+/**
+ * @brief Stop the simulation loop.
+ * @ingroup drawstuff
+ * Calling this from within dsSimulationLoop()
+ * will cause it to exit and return to the caller. it is the same as if the
+ * user used the exit command. using this outside the loop will have no
+ * effect.
+ */
+DS_API void dsStop();
+
+/**
+ * @brief Get the elapsed time (on wall-clock)
+ * @ingroup drawstuff
+ * It returns the nr of seconds since the last call to this function.
+ */
+DS_API double dsElapsedTime();
+
+/**
+ * @brief Toggle the rendering of textures.
+ * @ingroup drawstuff
+ * It changes the way objects are drawn. these changes will apply to all further
+ * dsDrawXXX() functions.
+ * @param the texture number must be a DS_xxx texture constant.
+ * The current texture is colored according to the current color.
+ * At the start of each frame, the texture is reset to none and the color is
+ * reset to white.
+ */
+DS_API void dsSetTexture (int texture_number);
+
+/**
+ * @brief Set the color with which geometry is drawn.
+ * @ingroup drawstuff
+ * @param red Red component from 0 to 1
+ * @param green Green component from 0 to 1
+ * @param blue Blue component from 0 to 1
+ */
+DS_API void dsSetColor (float red, float green, float blue);
+
+/**
+ * @brief Set the color and transparency with which geometry is drawn.
+ * @ingroup drawstuff
+ * @param alpha Note that alpha transparency is a misnomer: it is alpha opacity.
+ * 1.0 means fully opaque, and 0.0 means fully transparent.
+ */
+DS_API void dsSetColorAlpha (float red, float green, float blue, float alpha);
+
+/**
+ * @brief Draw a box.
+ * @ingroup drawstuff
+ * @param pos is the x,y,z of the center of the object.
+ * @param R is a 3x3 rotation matrix for the object, stored by row like this:
+ * [ R11 R12 R13 0 ]
+ * [ R21 R22 R23 0 ]
+ * [ R31 R32 R33 0 ]
+ * @param sides[] is an array of x,y,z side lengths.
+ */
+DS_API void dsDrawBox (const float pos[3], const float R[12], const float sides[3]);
+
+/**
+ * @brief Draw a sphere.
+ * @ingroup drawstuff
+ * @param pos Position of center.
+ * @param R orientation.
+ * @param radius
+ */
+DS_API void dsDrawSphere (const float pos[3], const float R[12], float radius);
+
+/**
+ * @brief Draw a triangle.
+ * @ingroup drawstuff
+ * @param pos Position of center
+ * @param R orientation
+ * @param v0 first vertex
+ * @param v1 second
+ * @param v2 third vertex
+ * @param solid set to 0 for wireframe
+ */
+DS_API void dsDrawTriangle (const float pos[3], const float R[12],
+ const float *v0, const float *v1, const float *v2, int solid);
+
+/**
+ * @brief Draw triangles.
+ * @ingroup drawstuff
+ * @param pos Position of center
+ * @param R orientation
+ * @param v list of vertices (x0, y0, z0, x1, y1, z1, ...)
+ * @param n number of vertices
+ * @param solid set to 0 for wireframe
+ */
+DS_API void dsDrawTriangles (const float pos[3], const float R[12],
+ const float *v, const int n, int solid);
+
+/**
+ * @brief Draw a z-aligned cylinder
+ * @ingroup drawstuff
+ */
+DS_API void dsDrawCylinder (const float pos[3], const float R[12],
+ float length, float radius);
+
+/**
+ * @brief Draw a z-aligned capsule
+ * @ingroup drawstuff
+ */
+DS_API void dsDrawCapsule (const float pos[3], const float R[12],
+ float length, float radius);
+
+/**
+ * @brief Draw a line.
+ * @ingroup drawstuff
+ */
+DS_API void dsDrawLine (const float pos1[3], const float pos2[3]);
+
+/**
+ * @brief Draw a convex shape.
+ * @ingroup drawstuff
+ */
+DS_API void dsDrawConvex(const float pos[3], const float R[12],
+ const float *_planes,
+ unsigned int _planecount,
+ const float *_points,
+ unsigned int _pointcount,
+ const unsigned int *_polygons);
+
+ /* these drawing functions are identical to the ones above, except they take
+ * double arrays for `pos' and `R'.
+ */
+DS_API void dsDrawBoxD (const double pos[3], const double R[12],
+ const double sides[3]);
+DS_API void dsDrawSphereD (const double pos[3], const double R[12],
+ const float radius);
+DS_API void dsDrawTriangleD (const double pos[3], const double R[12],
+ const double *v0, const double *v1, const double *v2, int solid);
+DS_API void dsDrawTrianglesD (const double pos[3], const double R[12],
+ const double *v, const int n, int solid);
+DS_API void dsDrawCylinderD (const double pos[3], const double R[12],
+ float length, float radius);
+DS_API void dsDrawCapsuleD (const double pos[3], const double R[12],
+ float length, float radius);
+DS_API void dsDrawLineD (const double pos1[3], const double pos2[3]);
+DS_API void dsDrawConvexD(const double pos[3], const double R[12],
+ const double *_planes,
+ unsigned int _planecount,
+ const double *_points,
+ unsigned int _pointcount,
+ const unsigned int *_polygons);
+
+/**
+ * @brief Set the quality with which curved objects are rendered.
+ * @ingroup drawstuff
+ * Higher numbers are higher quality, but slower to draw.
+ * This must be set before the first objects are drawn to be effective.
+ * Default sphere quality is 1, default capsule quality is 3.
+ */
+DS_API void dsSetSphereQuality (int n); /* default = 1 */
+DS_API void dsSetCapsuleQuality (int n); /* default = 3 */
+
+/**
+ * @brief Set Drawmode 0=Polygon Fill,1=Wireframe).
+ * Use the DS_POLYFILL and DS_WIREFRAME macros.
+ * @ingroup drawstuff
+ */
+DS_API void dsSetDrawMode(int mode);
+
+/* Backwards compatible API */
+#define dsDrawCappedCylinder dsDrawCapsule
+#define dsDrawCappedCylinderD dsDrawCapsuleD
+#define dsSetCappedCylinderQuality dsSetCapsuleQuality
+
+/* closing bracket for extern "C" */
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/libs/ode-0.16.1/include/drawstuff/version.h b/libs/ode-0.16.1/include/drawstuff/version.h
new file mode 100644
index 0000000..71d95f4
--- /dev/null
+++ b/libs/ode-0.16.1/include/drawstuff/version.h
@@ -0,0 +1,29 @@
+/*************************************************************************
+ * *
+ * 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 __VERSION_H
+#define __VERSION_H
+
+/* high byte is major version, low byte is minor version */
+#define DS_VERSION 0x0002
+
+#endif
diff --git a/libs/ode-0.16.1/include/ode/Makefile.am b/libs/ode-0.16.1/include/ode/Makefile.am
new file mode 100644
index 0000000..ad06509
--- /dev/null
+++ b/libs/ode-0.16.1/include/ode/Makefile.am
@@ -0,0 +1,34 @@
+libode_la_includedir = $(includedir)/ode
+libode_la_include_HEADERS = \
+ collision.h \
+ collision_space.h \
+ collision_trimesh.h \
+ common.h \
+ compatibility.h \
+ contact.h \
+ cooperative.h \
+ error.h \
+ export-dif.h \
+ mass.h \
+ matrix.h matrix_coop.h \
+ memory.h \
+ misc.h \
+ objects.h \
+ ode.h \
+ odeconfig.h \
+ odecpp.h \
+ odecpp_collision.h \
+ odeinit.h \
+ odemath.h \
+ odemath_legacy.h \
+ rotation.h \
+ threading.h \
+ threading_impl.h \
+ timer.h
+
+
+EXTRA_DIST = README precision.h.in version.h.in
+
+dist_libode_la_include_HEADERS = precision.h version.h
+
+
diff --git a/libs/ode-0.16.1/include/ode/Makefile.in b/libs/ode-0.16.1/include/ode/Makefile.in
new file mode 100644
index 0000000..1dac65e
--- /dev/null
+++ b/libs/ode-0.16.1/include/ode/Makefile.in
@@ -0,0 +1,642 @@
+# Makefile.in generated by automake 1.15 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2014 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+VPATH = @srcdir@
+am__is_gnu_make = { \
+ if test -z '$(MAKELEVEL)'; then \
+ false; \
+ elif test -n '$(MAKE_HOST)'; then \
+ true; \
+ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+ true; \
+ else \
+ false; \
+ fi; \
+}
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = include/ode
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \
+ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
+ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
+ $(top_srcdir)/m4/pkg.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(dist_libode_la_include_HEADERS) \
+ $(libode_la_include_HEADERS) $(am__DIST_COMMON)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/ode/src/config.h
+CONFIG_CLEAN_FILES = version.h precision.h
+CONFIG_CLEAN_VPATH_FILES =
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 =
+SOURCES =
+DIST_SOURCES =
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+ test -z "$$files" \
+ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+ $(am__cd) "$$dir" && rm -f $$files; }; \
+ }
+am__installdirs = "$(DESTDIR)$(libode_la_includedir)" \
+ "$(DESTDIR)$(libode_la_includedir)"
+HEADERS = $(dist_libode_la_include_HEADERS) \
+ $(libode_la_include_HEADERS)
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates. Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+ BEGIN { nonempty = 0; } \
+ { items[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique. This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+ list='$(am__tagged_files)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/precision.h.in \
+ $(srcdir)/version.h.in README
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ALLOCA = @ALLOCA@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AS = @AS@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CCD_CFLAGS = @CCD_CFLAGS@
+CCD_LIBS = @CCD_LIBS@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DOXYGEN = @DOXYGEN@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+EXTRA_LIBTOOL_LDFLAGS = @EXTRA_LIBTOOL_LDFLAGS@
+FGREP = @FGREP@
+GL_LIBS = @GL_LIBS@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBSTDCXX = @LIBSTDCXX@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+ODE_PRECISION = @ODE_PRECISION@
+ODE_VERSION = @ODE_VERSION@
+ODE_VERSION_INFO = @ODE_VERSION_INFO@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+RANLIB = @RANLIB@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+VERSION = @VERSION@
+WINDRES = @WINDRES@
+X11_CFLAGS = @X11_CFLAGS@
+X11_LIBS = @X11_LIBS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+ac_ct_WINDRES = @ac_ct_WINDRES@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+runstatedir = @runstatedir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+subdirs = @subdirs@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+libode_la_includedir = $(includedir)/ode
+libode_la_include_HEADERS = \
+ collision.h \
+ collision_space.h \
+ collision_trimesh.h \
+ common.h \
+ compatibility.h \
+ contact.h \
+ cooperative.h \
+ error.h \
+ export-dif.h \
+ mass.h \
+ matrix.h matrix_coop.h \
+ memory.h \
+ misc.h \
+ objects.h \
+ ode.h \
+ odeconfig.h \
+ odecpp.h \
+ odecpp_collision.h \
+ odeinit.h \
+ odemath.h \
+ odemath_legacy.h \
+ rotation.h \
+ threading.h \
+ threading_impl.h \
+ timer.h
+
+EXTRA_DIST = README precision.h.in version.h.in
+dist_libode_la_include_HEADERS = precision.h version.h
+all: all-am
+
+.SUFFIXES:
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign include/ode/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --foreign include/ode/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+version.h: $(top_builddir)/config.status $(srcdir)/version.h.in
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+precision.h: $(top_builddir)/config.status $(srcdir)/precision.h.in
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+install-dist_libode_la_includeHEADERS: $(dist_libode_la_include_HEADERS)
+ @$(NORMAL_INSTALL)
+ @list='$(dist_libode_la_include_HEADERS)'; test -n "$(libode_la_includedir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(libode_la_includedir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(libode_la_includedir)" || exit 1; \
+ fi; \
+ for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; \
+ done | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(libode_la_includedir)'"; \
+ $(INSTALL_HEADER) $$files "$(DESTDIR)$(libode_la_includedir)" || exit $$?; \
+ done
+
+uninstall-dist_libode_la_includeHEADERS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(dist_libode_la_include_HEADERS)'; test -n "$(libode_la_includedir)" || list=; \
+ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+ dir='$(DESTDIR)$(libode_la_includedir)'; $(am__uninstall_files_from_dir)
+install-libode_la_includeHEADERS: $(libode_la_include_HEADERS)
+ @$(NORMAL_INSTALL)
+ @list='$(libode_la_include_HEADERS)'; test -n "$(libode_la_includedir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(libode_la_includedir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(libode_la_includedir)" || exit 1; \
+ fi; \
+ for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; \
+ done | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(libode_la_includedir)'"; \
+ $(INSTALL_HEADER) $$files "$(DESTDIR)$(libode_la_includedir)" || exit $$?; \
+ done
+
+uninstall-libode_la_includeHEADERS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(libode_la_include_HEADERS)'; test -n "$(libode_la_includedir)" || list=; \
+ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+ dir='$(DESTDIR)$(libode_la_includedir)'; $(am__uninstall_files_from_dir)
+
+ID: $(am__tagged_files)
+ $(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ set x; \
+ here=`pwd`; \
+ $(am__define_uniq_tagged_files); \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ $(am__define_uniq_tagged_files); \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+ list='$(am__tagged_files)'; \
+ case "$(srcdir)" in \
+ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+ *) sdir=$(subdir)/$(srcdir) ;; \
+ esac; \
+ for i in $$list; do \
+ if test -f "$$i"; then \
+ echo "$(subdir)/$$i"; \
+ else \
+ echo "$$sdir/$$i"; \
+ fi; \
+ done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(HEADERS)
+installdirs:
+ for dir in "$(DESTDIR)$(libode_la_includedir)" "$(DESTDIR)$(libode_la_includedir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-am
+ -rm -f Makefile
+distclean-am: clean-am distclean-generic distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-dist_libode_la_includeHEADERS \
+ install-libode_la_includeHEADERS
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-dist_libode_la_includeHEADERS \
+ uninstall-libode_la_includeHEADERS
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \
+ clean-libtool cscopelist-am ctags ctags-am distclean \
+ distclean-generic distclean-libtool distclean-tags distdir dvi \
+ dvi-am html html-am info info-am install install-am \
+ install-data install-data-am \
+ install-dist_libode_la_includeHEADERS install-dvi \
+ install-dvi-am install-exec install-exec-am install-html \
+ install-html-am install-info install-info-am \
+ install-libode_la_includeHEADERS install-man install-pdf \
+ install-pdf-am install-ps install-ps-am install-strip \
+ installcheck installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-generic \
+ mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \
+ uninstall-am uninstall-dist_libode_la_includeHEADERS \
+ uninstall-libode_la_includeHEADERS
+
+.PRECIOUS: Makefile
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/libs/ode-0.16.1/include/ode/README b/libs/ode-0.16.1/include/ode/README
new file mode 100644
index 0000000..9d7e99a
--- /dev/null
+++ b/libs/ode-0.16.1/include/ode/README
@@ -0,0 +1,18 @@
+
+this is the public C interface to the ODE library.
+
+all these files should be includable from C, i.e. they should not use any
+C++ features. everything should be protected with
+
+ #ifdef __cplusplus
+ extern "C" {
+ #endif
+
+ ...
+
+ #ifdef __cplusplus
+ }
+ #endif
+
+the only exceptions are the odecpp.h and odecpp_collisioh.h files, which define a C++ wrapper for
+the C interface. remember to keep this in sync!
diff --git a/libs/ode-0.16.1/include/ode/collision.h b/libs/ode-0.16.1/include/ode/collision.h
new file mode 100644
index 0000000..fef6e7b
--- /dev/null
+++ b/libs/ode-0.16.1/include/ode/collision.h
@@ -0,0 +1,1526 @@
+/*************************************************************************
+ * *
+ * 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>
+
+#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,
+ const dReal *_planes,
+ unsigned int _planecount,
+ const dReal *_points,
+ unsigned int _pointcount,
+ const unsigned int *_polygons);
+
+ODE_API void dGeomSetConvex (dGeomID g,
+ const dReal *_planes,
+ unsigned int _count,
+ const dReal *_points,
+ unsigned int _pointcount,
+ const 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_DEPRECATED ODE_API void dGeomRaySetParams (dGeomID g, int FirstContact, int BackfaceCull);
+ODE_API_DEPRECATED ODE_API void dGeomRayGetParams (dGeomID g, int *FirstContact, int *BackfaceCull);
+ODE_API void dGeomRaySetFirstContact (dGeomID g, int firstContact);
+ODE_API int dGeomRayGetFirstContact (dGeomID g);
+ODE_API void dGeomRaySetBackfaceCull (dGeomID g, int backfaceCull);
+ODE_API int dGeomRayGetBackfaceCull (dGeomID g);
+ODE_API void dGeomRaySetClosestHit (dGeomID g, int closestHit);
+ODE_API int dGeomRayGetClosestHit (dGeomID g);
+
+#include "collision_trimesh.h"
+
+ODE_API_DEPRECATED ODE_API dGeomID dCreateGeomTransform (dSpaceID space);
+ODE_API_DEPRECATED ODE_API void dGeomTransformSetGeom (dGeomID g, dGeomID obj);
+ODE_API_DEPRECATED ODE_API dGeomID dGeomTransformGetGeom (dGeomID g);
+ODE_API_DEPRECATED ODE_API void dGeomTransformSetCleanup (dGeomID g, int mode);
+ODE_API_DEPRECATED ODE_API int dGeomTransformGetCleanup (dGeomID g);
+ODE_API_DEPRECATED ODE_API void dGeomTransformSetInfo (dGeomID g, int mode);
+ODE_API_DEPRECATED 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/libs/ode-0.16.1/include/ode/collision_space.h b/libs/ode-0.16.1/include/ode/collision_space.h
new file mode 100644
index 0000000..30cc536
--- /dev/null
+++ b/libs/ode-0.16.1/include/ode/collision_space.h
@@ -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/libs/ode-0.16.1/include/ode/collision_trimesh.h b/libs/ode-0.16.1/include/ode/collision_trimesh.h
new file mode 100644
index 0000000..aa8f624
--- /dev/null
+++ b/libs/ode-0.16.1/include/ode/collision_trimesh.h
@@ -0,0 +1,316 @@
+/*************************************************************************
+ * *
+ * 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;
+
+
+typedef enum
+{
+ dMTV__MIN,
+
+ dMTV_FIRST = dMTV__MIN,
+ dMTV_SECOND,
+ dMTV_THIRD,
+
+ dMTV__MAX,
+
+} dMeshTriangleVertex;
+
+/*
+ * These don't make much sense now, but they will later when we add more
+ * features.
+ */
+ODE_API dTriMeshDataID dGeomTriMeshDataCreate(void);
+ODE_API void dGeomTriMeshDataDestroy(dTriMeshDataID g);
+
+
+/*
+ * The values of data_id that can be used with dGeomTriMeshDataSet/dGeomTriMeshDataGet
+ */
+enum
+{
+ dTRIMESHDATA__MIN,
+
+ dTRIMESHDATA_FACE_NORMALS = dTRIMESHDATA__MIN,
+ dTRIMESHDATA_USE_FLAGS,
+
+ dTRIMESHDATA__MAX,
+
+#ifndef TRIMESH_FACE_NORMALS // Define this name during the header inclusion if you need it for something else
+ // Included for backward compatibility -- please use the corrected name above. Sorry.
+ TRIMESH_FACE_NORMALS = dTRIMESHDATA_FACE_NORMALS,
+#endif
+};
+
+/*
+ * The flags of the dTRIMESHDATA_USE_FLAGS data elements
+ */
+enum
+{
+ dMESHDATAUSE_EDGE1 = 0x01,
+ dMESHDATAUSE_EDGE2 = 0x02,
+ dMESHDATAUSE_EDGE3 = 0x04,
+ dMESHDATAUSE_VERTEX1 = 0x08,
+ dMESHDATAUSE_VERTEX2 = 0x10,
+ dMESHDATAUSE_VERTEX3 = 0x20,
+};
+
+/*
+ * Set and get the TriMeshData additional data
+ * Note: The data is NOT COPIED on assignment
+ */
+ODE_API void dGeomTriMeshDataSet(dTriMeshDataID g, int data_id, void *in_data);
+ODE_API void *dGeomTriMeshDataGet(dTriMeshDataID g, int data_id);
+ODE_API void *dGeomTriMeshDataGet2(dTriMeshDataID g, int data_id, dsizeint *pout_size/*=NULL*/);
+
+
+
+/**
+ * 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, const dMatrix4 last_trans );
+ODE_API const 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);
+
+
+/*
+ * Data preprocessing build request flags.
+ */
+enum
+{
+ dTRIDATAPREPROCESS_BUILD__MIN,
+
+ dTRIDATAPREPROCESS_BUILD_CONCAVE_EDGES = dTRIDATAPREPROCESS_BUILD__MIN, // Used to optimize OPCODE trimesh-capsule collisions; allocates 1 byte per triangle; no extra data associated
+ dTRIDATAPREPROCESS_BUILD_FACE_ANGLES, // Used to aid trimesh-convex collisions; memory requirements depend on extra data
+
+ dTRIDATAPREPROCESS_BUILD__MAX,
+};
+
+/*
+ * Data preprocessing extra values for dTRIDATAPREPROCESS_BUILD_FACE_ANGLES.
+ */
+enum
+{
+ dTRIDATAPREPROCESS_FACE_ANGLES_EXTRA__MIN,
+
+ dTRIDATAPREPROCESS_FACE_ANGLES_EXTRA_BYTE_POSITIVE = dTRIDATAPREPROCESS_FACE_ANGLES_EXTRA__MIN, // Build angles for convex edges only and store as bytes; allocates 3 bytes per triangle; stores angles (0..180] in 1/254 fractions leaving two values for the flat and all the concaves
+ dTRIDATAPREPROCESS_FACE_ANGLES_EXTRA_BYTE_ALL, // Build angles for all the edges and store in bytes; allocates 3 bytes per triangle; stores angles [-180..0) and (0..180] in 1/127 fractions plus a value for the flat angle
+ dTRIDATAPREPROCESS_FACE_ANGLES_EXTRA_WORD_ALL, // Build angles for all the edges and store in words; allocates 6 bytes per triangle; stores angles [-180..0) and (0..180] in 1/32767 fractions plus a value for the flat angle
+
+ dTRIDATAPREPROCESS_FACE_ANGLES_EXTRA__MAX,
+
+ dTRIDATAPREPROCESS_FACE_ANGLES_EXTRA__DEFAULT = dTRIDATAPREPROCESS_FACE_ANGLES_EXTRA_BYTE_POSITIVE, // The default value assumed if the extra data is not provided
+};
+
+
+/*
+ * Pre-process the trimesh data according to the request flags.
+ *
+ * buildRequestFlags is a bitmask of 1U << dTRIDATAPREPROCESS_BUILD_...
+ * It is allowed to call the function multiple times provided the bitmasks are different each time.
+ *
+ * requestExtraData is an optional pointer to array of extra parameters per bitmask bits
+ * (only the elements indexed by positions of raised bits are examined;
+ * defaults are assumed if the pointer is NULL)
+ *
+ * The function returns a boolean status the only failure reason being insufficient memory.
+ */
+ODE_API int dGeomTriMeshDataPreprocess2(dTriMeshDataID g, unsigned int buildRequestFlags, const dintptr *requestExtraData/*=NULL | const dintptr (*)[dTRIDATAPREPROCESS_BUILD__MAX]*/);
+
+/*
+ * Obsolete. Equivalent to calling dGeomTriMeshDataPreprocess2(g, (1U << dTRIDATAPREPROCESS_BUILD_CONCAVE_EDGES), NULL)
+ */
+ODE_API int dGeomTriMeshDataPreprocess(dTriMeshDataID g);
+
+
+
+/*
+ * Get and set the internal preprocessed trimesh data buffer (see the enumerated type above), for loading and saving
+ * These functions are deprecated. Use dGeomTriMeshDataSet/dGeomTriMeshDataGet2 with dTRIMESHDATA_USE_FLAGS instead.
+ */
+ODE_API_DEPRECATED ODE_API void dGeomTriMeshDataGetBuffer(dTriMeshDataID g, unsigned char** buf, int* bufLen);
+ODE_API_DEPRECATED 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/libs/ode-0.16.1/include/ode/common.h b/libs/ode-0.16.1/include/ode/common.h
new file mode 100644
index 0000000..b0a5793
--- /dev/null
+++ b/libs/ode-0.16.1/include/ode/common.h
@@ -0,0 +1,568 @@
+/*************************************************************************
+ * *
+ * 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>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/* 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_PI_2
+#define M_PI_2 REAL(1.5707963267948966192313216916398)
+#endif
+#ifndef M_SQRT1_2
+#define M_SQRT1_2 REAL(0.7071067811865475244008443621048490)
+#endif
+
+
+/* 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 duint32 dTriIndex;
+#else /* dTRIMESH_GIMPACT */
+typedef duint16 dTriIndex;
+#endif /* dTRIMESH_GIMPACT */
+#else /* dTRIMESH_16BIT_INDICES */
+typedef duint32 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) + 3) & (int)(~3)) : (a))
+
+typedef enum {
+ dSA__MIN,
+
+ dSA_X = dSA__MIN,
+ dSA_Y,
+ dSA_Z,
+
+ dSA__MAX,
+} dSpaceAxis;
+
+typedef enum {
+ dMD__MIN,
+
+ dMD_LINEAR = dMD__MIN,
+ dMD_ANGULAR,
+
+ dMD__MAX,
+} dMotionDynamics;
+
+typedef enum {
+ dDA__MIN,
+
+ dDA__L_MIN = dDA__MIN + dMD_LINEAR * dSA__MAX,
+
+ dDA_LX = dDA__L_MIN + dSA_X,
+ dDA_LY = dDA__L_MIN + dSA_Y,
+ dDA_LZ = dDA__L_MIN + dSA_Z,
+
+ dDA__L_MAX = dDA__L_MIN + dSA__MAX,
+
+ dDA__A_MIN = dDA__MIN + dMD_ANGULAR * dSA__MAX,
+
+ dDA_AX = dDA__A_MIN + dSA_X,
+ dDA_AY = dDA__A_MIN + dSA_Y,
+ dDA_AZ = dDA__A_MIN + dSA_Z,
+
+ dDA__A_MAX = dDA__A_MIN + dSA__MAX,
+
+ dDA__MAX = dDA__MIN + dMD__MAX * dSA__MAX,
+} dDynamicsAxis;
+
+typedef enum {
+ dV3E__MIN,
+
+ dV3E__AXES_MIN = dV3E__MIN,
+
+ dV3E_X = dV3E__AXES_MIN + dSA_X,
+ dV3E_Y = dV3E__AXES_MIN + dSA_Y,
+ dV3E_Z = dV3E__AXES_MIN + dSA_Z,
+
+ dV3E__AXES_MAX = dV3E__AXES_MIN + dSA__MAX,
+
+ dV3E_PAD = dV3E__AXES_MAX,
+
+ dV3E__MAX,
+
+ dV3E__AXES_COUNT = dV3E__AXES_MAX - dV3E__AXES_MIN,
+} dVec3Element;
+
+typedef enum {
+ dV4E__MIN,
+
+ dV4E_X = dV4E__MIN + dSA_X,
+ dV4E_Y = dV4E__MIN + dSA_Y,
+ dV4E_Z = dV4E__MIN + dSA_Z,
+ dV4E_O = dV4E__MIN + dSA__MAX,
+
+ dV4E__MAX,
+} dVec4Element;
+
+typedef enum {
+ dM3E__MIN,
+
+ dM3E__X_MIN = dM3E__MIN + dSA_X * dV3E__MAX,
+
+ dM3E__X_AXES_MIN = dM3E__X_MIN + dV3E__AXES_MIN,
+
+ dM3E_XX = dM3E__X_MIN + dV3E_X,
+ dM3E_XY = dM3E__X_MIN + dV3E_Y,
+ dM3E_XZ = dM3E__X_MIN + dV3E_Z,
+
+ dM3E__X_AXES_MAX = dM3E__X_MIN + dV3E__AXES_MAX,
+
+ dM3E_XPAD = dM3E__X_MIN + dV3E_PAD,
+
+ dM3E__X_MAX = dM3E__X_MIN + dV3E__MAX,
+
+ dM3E__Y_MIN = dM3E__MIN + dSA_Y * dV3E__MAX,
+
+ dM3E__Y_AXES_MIN = dM3E__Y_MIN + dV3E__AXES_MIN,
+
+ dM3E_YX = dM3E__Y_MIN + dV3E_X,
+ dM3E_YY = dM3E__Y_MIN + dV3E_Y,
+ dM3E_YZ = dM3E__Y_MIN + dV3E_Z,
+
+ dM3E__Y_AXES_MAX = dM3E__Y_MIN + dV3E__AXES_MAX,
+
+ dM3E_YPAD = dM3E__Y_MIN + dV3E_PAD,
+
+ dM3E__Y_MAX = dM3E__Y_MIN + dV3E__MAX,
+
+ dM3E__Z_MIN = dM3E__MIN + dSA_Z * dV3E__MAX,
+
+ dM3E__Z_AXES_MIN = dM3E__Z_MIN + dV3E__AXES_MIN,
+
+ dM3E_ZX = dM3E__Z_MIN + dV3E_X,
+ dM3E_ZY = dM3E__Z_MIN + dV3E_Y,
+ dM3E_ZZ = dM3E__Z_MIN + dV3E_Z,
+
+ dM3E__Z_AXES_MAX = dM3E__Z_MIN + dV3E__AXES_MAX,
+
+ dM3E_ZPAD = dM3E__Z_MIN + dV3E_PAD,
+
+ dM3E__Z_MAX = dM3E__Z_MIN + dV3E__MAX,
+
+ dM3E__MAX = dM3E__MIN + dSA__MAX * dV3E__MAX,
+} dMat3Element;
+
+typedef enum {
+ dM4E__MIN,
+
+ dM4E__X_MIN = dM4E__MIN + dV4E_X * dV4E__MAX,
+
+ dM4E_XX = dM4E__X_MIN + dV4E_X,
+ dM4E_XY = dM4E__X_MIN + dV4E_Y,
+ dM4E_XZ = dM4E__X_MIN + dV4E_Z,
+ dM4E_XO = dM4E__X_MIN + dV4E_O,
+
+ dM4E__X_MAX = dM4E__X_MIN + dV4E__MAX,
+
+ dM4E__Y_MIN = dM4E__MIN + dV4E_Y * dV4E__MAX,
+
+ dM4E_YX = dM4E__Y_MIN + dV4E_X,
+ dM4E_YY = dM4E__Y_MIN + dV4E_Y,
+ dM4E_YZ = dM4E__Y_MIN + dV4E_Z,
+ dM4E_YO = dM4E__Y_MIN + dV4E_O,
+
+ dM4E__Y_MAX = dM4E__Y_MIN + dV4E__MAX,
+
+ dM4E__Z_MIN = dM4E__MIN + dV4E_Z * dV4E__MAX,
+
+ dM4E_ZX = dM4E__Z_MIN + dV4E_X,
+ dM4E_ZY = dM4E__Z_MIN + dV4E_Y,
+ dM4E_ZZ = dM4E__Z_MIN + dV4E_Z,
+ dM4E_ZO = dM4E__Z_MIN + dV4E_O,
+
+ dM4E__Z_MAX = dM4E__Z_MIN + dV4E__MAX,
+
+ dM4E__O_MIN = dM4E__MIN + dV4E_O * dV4E__MAX,
+
+ dM4E_OX = dM4E__O_MIN + dV4E_X,
+ dM4E_OY = dM4E__O_MIN + dV4E_Y,
+ dM4E_OZ = dM4E__O_MIN + dV4E_Z,
+ dM4E_OO = dM4E__O_MIN + dV4E_O,
+
+ dM4E__O_MAX = dM4E__O_MIN + dV4E__MAX,
+
+ dM4E__MAX = dM4E__MIN + dV4E__MAX * dV4E__MAX,
+} dMat4Element;
+
+typedef enum {
+ dQUE__MIN,
+
+ dQUE_R = dQUE__MIN,
+
+ dQUE__AXIS_MIN,
+
+ dQUE_I = dQUE__AXIS_MIN + dSA_X,
+ dQUE_J = dQUE__AXIS_MIN + dSA_Y,
+ dQUE_K = dQUE__AXIS_MIN + dSA_Z,
+
+ dQUE__AXIS_MAX = dQUE__AXIS_MIN + dSA__MAX,
+
+ dQUE__MAX = dQUE__AXIS_MAX,
+} dQuatElement;
+
+/* these types are mainly just used in headers */
+typedef dReal dVector3[dV3E__MAX];
+typedef dReal dVector4[dV4E__MAX];
+typedef dReal dMatrix3[dM3E__MAX];
+typedef dReal dMatrix4[dM4E__MAX];
+typedef dReal dMatrix6[(dMD__MAX * dV3E__MAX) * (dMD__MAX * dSA__MAX)];
+typedef dReal dQuaternion[dQUE__MAX];
+
+
+/* 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 dAsin(x) (asinf(x))
+#define dAcos(x) (acosf(x))
+#define dFMod(a,b) (fmodf(a,b)) /* modulo */
+#define dFloor(x) floorf(x) /* floor */
+#define dCeil(x) ceilf(x) /* ceil */
+#define dCopySign(a,b) _ode_copysignf(a, b) /* copy value sign */
+#define dNextAfter(x, y) _ode_nextafterf(x, y) /* next value after */
+
+#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 dAsin(x) asin(x)
+#define dAcos(x) acos(x)
+#define dFMod(a,b) (fmod((a),(b)))
+#define dFloor(x) floor(x)
+#define dCeil(x) ceil(x)
+#define dCopySign(a,b) _ode_copysign(a, b)
+#define dNextAfter(x, y) _ode_nextafter(x, y)
+
+#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
+
+ODE_PURE_INLINE dReal dMin(dReal x, dReal y) { return x <= y ? x : y; }
+ODE_PURE_INLINE dReal dMax(dReal x, dReal y) { return x <= y ? y : x; }
+
+
+/* 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; /* joint */
+struct dxJointGroup;/* joint group */
+
+
+typedef struct dxWorld *dWorldID;
+typedef struct dxSpace *dSpaceID;
+typedef struct dxBody *dBodyID;
+typedef struct dxGeom *dGeomID;
+typedef struct dxJoint *dJointID;
+typedef struct dxJointGroup *dJointGroupID;
+
+
+/* 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,
+ dJointTypeDBall,
+ dJointTypeDHinge,
+ dJointTypeTransmission,
+} 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, \
+ dParamLoVel, \
+ dParamHiVel, \
+ 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, \
+ dParamLoVel ## x, \
+ dParamHiVel ## 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
+};
+
+/* transmission joint mode numbers */
+
+enum {
+ dTransmissionParallelAxes = 0,
+ dTransmissionIntersectingAxes = 1,
+ dTransmissionChainDrive = 2
+};
+
+
+/* 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_OPC_16bit_indices
+ * ODE_OPC_new_collider
+ * ODE_EXT_mt_collisions
+ * ODE_EXT_threading
+ * ODE_THR_builtin_impl
+ */
+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/libs/ode-0.16.1/include/ode/compatibility.h b/libs/ode-0.16.1/include/ode/compatibility.h
new file mode 100644
index 0000000..b370986
--- /dev/null
+++ b/libs/ode-0.16.1/include/ode/compatibility.h
@@ -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/libs/ode-0.16.1/include/ode/contact.h b/libs/ode-0.16.1/include/ode/contact.h
new file mode 100644
index 0000000..9756f26
--- /dev/null
+++ b/libs/ode-0.16.1/include/ode/contact.h
@@ -0,0 +1,110 @@
+/*************************************************************************
+ * *
+ * 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, /**< Use axis dependent friction */
+ dContactAxisDep = 0x001, /**< Same as above */
+ dContactFDir1 = 0x002, /**< Use FDir for the first friction value */
+ dContactBounce = 0x004, /**< Restore collision energy anti-parallel to the normal */
+ dContactSoftERP = 0x008, /**< Don't use global erp for penetration reduction */
+ dContactSoftCFM = 0x010, /**< Don't use global cfm for penetration constraint */
+ dContactMotion1 = 0x020, /**< Use a non-zero target velocity for the constraint */
+ dContactMotion2 = 0x040,
+ dContactMotionN = 0x080,
+ dContactSlip1 = 0x100, /**< Force-dependent slip. */
+ dContactSlip2 = 0x200,
+ dContactRolling = 0x400, /**< Rolling/Angular friction */
+
+ dContactApprox0 = 0x0000,
+ dContactApprox1_1 = 0x1000,
+ dContactApprox1_2 = 0x2000,
+ dContactApprox1_N = 0x4000, /**< For rolling friction */
+ dContactApprox1 = 0x7000
+};
+
+
+typedef struct dSurfaceParameters {
+ /* must always be defined */
+ int mode;
+ dReal mu;
+
+ /* only defined if the corresponding flag is set in mode */
+ dReal mu2;
+ dReal rho; /**< Rolling friction */
+ dReal rho2;
+ dReal rhoN; /**< Spinning friction */
+ dReal bounce; /**< Coefficient of restitution */
+ dReal bounce_vel; /**< Bouncing threshold */
+ 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/libs/ode-0.16.1/include/ode/cooperative.h b/libs/ode-0.16.1/include/ode/cooperative.h
new file mode 100644
index 0000000..879477c
--- /dev/null
+++ b/libs/ode-0.16.1/include/ode/cooperative.h
@@ -0,0 +1,229 @@
+/*************************************************************************
+ * *
+ * 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_COOPERATIVE_H_
+#define _ODE_COOPERATIVE_H_
+
+
+#include <ode/common.h>
+#include <ode/threading.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup coop Cooperative Algorithms
+ *
+ * Algorithms implemented as multiple threads doing work cooperatively.
+ */
+
+
+struct dxCooperative;
+struct dxResourceRequirements;
+struct dxResourceContainer;
+
+/**
+ * @brief A container for cooperative algorithms shared context
+ *
+ * The Cooperative is a container for cooperative algorithms shared context.
+ * At present it contains threading object (either a real one or a defaulted
+ * self-threading).
+ *
+ * Cooperative use in functions performing computations must be serialized. That is,
+ * functions referring to a single instance of Cooperative object must not be called in
+ * parallel.
+ */
+typedef struct dxCooperative *dCooperativeID;
+
+
+/**
+ * @brief A container for resource requirements information
+ *
+ * The ResourceRequirements object is a container for descriptive information
+ * regarding what resources (memory, synchronization objects, etc.) need to be
+ * allocated for particular computations. The object can be used for accumulating
+ * resource requirement maxima over multiple functions and then allocating resources
+ * that would suffice for any of those function calls.
+ *
+ * ResourceRequirements objects maintain relations to Cooperative objects since
+ * amounts of resources that could be required can depend on characteristics of
+ * shared context, e.g. on maximal number of threads in the threading object.
+ *
+ * @ingroup coop
+ * @see dCooperativeID
+ * @see dResourceContainerID
+ */
+typedef struct dxResourceRequirements *dResourceRequirementsID;
+
+/**
+ * @brief A container for algorithm allocated resources
+ *
+ * The ResourceContainer object can contain resources allocated according to information
+ * in a ResourceRequirements. The resources inherit link to the threading object
+ * from the requirements they are allocated according to.
+ *
+ * @ingroup coop
+ * @see dResourceRequirementsID
+ * @see dCooperativeID
+ */
+typedef struct dxResourceContainer *dResourceContainerID;
+
+
+ /**
+ * @brief Creates a Cooperative object related to the specified threading.
+ *
+ * NULL's are allowed for the threading. In this case the default (global) self-threading
+ * object will be used.
+ *
+ * Use @c dCooperativeDestroy to destroy the object. The Cooperative object must exist
+ * until after all the objects referencing it are destroyed.
+ *
+ * @param functionInfo The threading functions to use
+ * @param threadingImpl The threading implementation object to use
+ * @returns The Cooperative object instance or NULL if allocation fails.
+ * @ingroup coop
+ * @see dCooperativeDestroy
+ */
+ODE_API dCooperativeID dCooperativeCreate(const dThreadingFunctionsInfo *functionInfo/*=NULL*/, dThreadingImplementationID threadingImpl/*=NULL*/);
+
+ /**
+ * @brief Destroys Cooperative object.
+ *
+ * The Cooperative object can only be destroyed after all the objects referencing it.
+ *
+ * @param cooperative A Cooperative object to be deleted (NULL is allowed)
+ * @ingroup coop
+ * @see dCooperativeCreate
+ */
+ODE_API void dCooperativeDestroy(dCooperativeID cooperative);
+
+
+ /**
+ * @brief Creates a ResourceRequirements object related to a Cooperative.
+ *
+ * The object is purely descriptive and does not contain any resources by itself.
+ * The actual resources are allocated by means of ResourceContainer object.
+ *
+ * The object is created with empty requirements. It can be then used to accumulate
+ * requirements for one or more function calls and can be cloned or merged with others.
+ * The actual requirements information is added to the object by computation related
+ * functions.
+ *
+ * Use @c dResourceRequirementsDestroy to delete the object when it is no longer needed.
+ *
+ * @param cooperative A Cooperative object to be used
+ * @returns The ResourceRequirements object instance or NULL if allocation fails
+ * @ingroup coop
+ * @see dResourceRequirementsDestroy
+ * @see dResourceRequirementsClone
+ * @see dResourceRequirementsMergeIn
+ * @see dCooperativeCreate
+ * @see dResourceContainerAcquire
+ */
+ODE_API dResourceRequirementsID dResourceRequirementsCreate(dCooperativeID cooperative);
+
+ /**
+ * @brief Destroys ResourceRequirements object.
+ *
+ * The ResourceRequirements object can be destroyed at any time with no regards
+ * to other objects' lifetime.
+ *
+ * @param requirements A ResourceRequirements object to be deleted (NULL is allowed)
+ * @ingroup coop
+ * @see dResourceRequirementsCreate
+ */
+ODE_API void dResourceRequirementsDestroy(dResourceRequirementsID requirements);
+
+ /**
+ * @brief Clones ResourceRequirements object.
+ *
+ * The function creates a copy of the ResourceRequirements object with all the
+ * contents and the relation to Cooperative matching. The object passed in
+ * the parameter is not changed.
+ *
+ * The object created with the function must later be destroyed with @c dResourceRequirementsDestroy.
+ *
+ * @param requirements A ResourceRequirements object to be cloned
+ * @returns A handle to the new object or NULL if allocation fails
+ * @ingroup coop
+ * @see dResourceRequirementsCreate
+ * @see dResourceRequirementsDestroy
+ * @see dResourceRequirementsMergeIn
+ */
+ODE_API dResourceRequirementsID dResourceRequirementsClone(/*const */dResourceRequirementsID requirements);
+
+ /**
+ * @brief Merges one ResourceRequirements object into another ResourceRequirements object.
+ *
+ * The function updates @a summaryRequirements requirements to be also sufficient
+ * for the purposes @a extraRequirements could be used for. The @a extraRequirements
+ * object is not changed. The both objects should normally have had been created
+ * with the same Cooperative object.
+ *
+ * @param summaryRequirements A ResourceRequirements object to be changed
+ * @param extraRequirements A ResourceRequirements the requirements to be taken from
+ * @ingroup coop
+ * @see dResourceRequirementsCreate
+ * @see dResourceRequirementsDestroy
+ * @see dResourceRequirementsClone
+ */
+ODE_API void dResourceRequirementsMergeIn(dResourceRequirementsID summaryRequirements, /*const */dResourceRequirementsID extraRequirements);
+
+
+ /**
+ * @brief Allocates resources as specified in ResourceRequirements object.
+ *
+ * The ResourceContainer object can be used in cooperative computation algorithms.
+ *
+ * The same @a requirements object can be passed to many resource allocations
+ * (with or without modifications) and can be deleted immediately, without waiting
+ * for the ResourceContainer object destruction.
+ *
+ * Use @c dResourceContainerDestroy to delete the object and release the resources
+ * when they are no longer needed.
+ *
+ * @param requirements The ResourceRequirements object to allocate resources according to
+ * @returns A ResourceContainer object instance with the resources allocated or NULL if allocation fails
+ * @ingroup coop
+ * @see dResourceContainerDestroy
+ * @see dResourceRequirementsCreate
+ */
+ODE_API dResourceContainerID dResourceContainerAcquire(/*const */dResourceRequirementsID requirements);
+
+ /**
+ * @brief Destroys ResourceContainer object and releases resources allocated in it.
+ *
+ * @param resources A ResourceContainer object to be deleted (NULL is allowed)
+ * @ingroup coop
+ * @see dResourceContainerAcquire
+ */
+ODE_API void dResourceContainerDestroy(dResourceContainerID resources);
+
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+
+#endif // #ifndef _ODE_COOPERATIVE_H_
diff --git a/libs/ode-0.16.1/include/ode/error.h b/libs/ode-0.16.1/include/ode/error.h
new file mode 100644
index 0000000..ae511e7
--- /dev/null
+++ b/libs/ode-0.16.1/include/ode/error.h
@@ -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 ODE_NORETURN dError (int num, const char *msg, ...);
+ODE_API void ODE_NORETURN dDebug (int num, const char *msg, ...);
+ODE_API void dMessage (int num, const char *msg, ...);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/libs/ode-0.16.1/include/ode/export-dif.h b/libs/ode-0.16.1/include/ode/export-dif.h
new file mode 100644
index 0000000..f6578ac
--- /dev/null
+++ b/libs/ode-0.16.1/include/ode/export-dif.h
@@ -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/libs/ode-0.16.1/include/ode/mass.h b/libs/ode-0.16.1/include/ode/mass.h
new file mode 100644
index 0000000..af89cb1
--- /dev/null
+++ b/libs/ode-0.16.1/include/ode/mass.h
@@ -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_DEPRECATED ODE_API void dMassSetCappedCylinder(dMass *a, dReal b, int c, dReal d, dReal e);
+ODE_API_DEPRECATED ODE_API 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/libs/ode-0.16.1/include/ode/matrix.h b/libs/ode-0.16.1/include/ode/matrix.h
new file mode 100644
index 0000000..65939b4
--- /dev/null
+++ b/libs/ode-0.16.1/include/ode/matrix.h
@@ -0,0 +1,200 @@
+/*************************************************************************
+ * *
+ * 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 dScaleVector (dReal *a, const dReal *d, int n);
+
+/* The function is an alias for @c dScaleVector.
+ * It has been deprecated because of a wrong naming schema used.
+ */
+ODE_API_DEPRECATED 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);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/libs/ode-0.16.1/include/ode/matrix_coop.h b/libs/ode-0.16.1/include/ode/matrix_coop.h
new file mode 100644
index 0000000..b38bf90
--- /dev/null
+++ b/libs/ode-0.16.1/include/ode/matrix_coop.h
@@ -0,0 +1,291 @@
+/*************************************************************************
+ * *
+ * 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_MATRIX_COOP_H_
+#define _ODE_MATRIX_COOP_H_
+
+
+#include <ode/common.h>
+#include <ode/cooperative.h>
+#include <ode/threading.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup matrix_coop Matrix Cooperative Algorithms
+ *
+ * Cooperative algorithms operating on matrices and vectors.
+ *
+ * @ingroup coop
+ */
+
+
+/**
+ * @brief Estimates resource requirements for a @c dCooperativelyFactorLDLT call
+ *
+ * The function updates the contents of @a requirements to also suffice for calling
+ * @c dCooperativelyFactorLDLT with the given parameters.
+ *
+ * Note: The requirements that could have already been in the @a requirements parameter
+ * are never decreased.
+ *
+ * @param requirements The ResourceRequirements object to update
+ * @param maximalAllowedThreadCount Maximal value of allowedThreadCount parameter that is going to be used
+ * @param maximalRowCount Maximal value of rowCount parameter that is going to be used
+ * @ingroup matrix_coop
+ * @see dCooperativelyFactorLDLT
+ * @see dResourceRequirementsCreate
+ */
+ODE_API void dEstimateCooperativelyFactorLDLTResourceRequirements(dResourceRequirementsID requirements,
+ unsigned maximalAllowedThreadCount, unsigned maximalRowCount);
+
+/**
+ * @brief Cooperatively factorizes a matrix `A' into L*D*L'
+ *
+ * The function factorizes a matrix `A' into L*D*L', where `L' is lower triangular with ones on
+ * the diagonal, and `D' is diagonal.
+ * @a A is a rowCount*rowCount matrix stored by rows, with a leading dimension of @a rowCount rounded
+ * up at least to 4 elements. `L; is written into the strict lower triangle of @a A
+ * (the ones are not written) and the reciprocal of the diagonal elements of `D' are written into @a d.
+ *
+ * The @a resources must have had been allocated from a ResourceRequirements object
+ * estimated in @c dEstimateCooperativelyFactorLDLTResourceRequirements.
+ *
+ * The operation is performed cooperatively by up to @a allowedThreadCount threads
+ * from thread pool available in @a resources. The threading must must not be simultaneously
+ * used (via other @c dResourceContainerID instances) in other calls that employ its features.
+ *
+ * @param resources The resources allocated for the function
+ * @param allowedThreadCount Maximum thread count to use (the actual thread count could be less, depending on other parameters)
+ * @param A The `A' matrix
+ * @param d The `d' vector
+ * @param rowCount The row count in @a A and @a d
+ * @param rowskip The actual number of elements to be added to skip to next row in @a A
+ * @ingroup matrix_coop
+ * @see dEstimateCooperativelyFactorLDLTResourceRequirements
+ * @see dResourceContainerAcquire
+ * @see dCooperativelySolveLDLT
+ */
+ODE_API void dCooperativelyFactorLDLT(dResourceContainerID resources, unsigned allowedThreadCount,
+ dReal *A, dReal *d, unsigned rowCount, unsigned rowSkip);
+
+
+/**
+ * @brief Estimates resource requirements for a @c dCooperativelySolveLDLT call
+ *
+ * The function updates the contents of @a requirements to also suffice for calling
+ * @c dCooperativelySolveLDLT with the given parameters.
+ *
+ * Note: The requirements that could have already been in the @a requirements parameter
+ * are never decreased.
+ *
+ * @param requirements The ResourceRequirements object to update
+ * @param maximalAllowedThreadCount Maximal value of allowedThreadCount parameter that is going to be used
+ * @param maximalRowCount Maximal value of rowCount parameter that is going to be used
+ * @ingroup matrix_coop
+ * @see dCooperativelySolveLDLT
+ * @see dResourceRequirementsCreate
+ */
+ODE_API void dEstimateCooperativelySolveLDLTResourceRequirements(dResourceRequirementsID requirements,
+ unsigned maximalAllowedThreadCount, unsigned maximalRowCount);
+
+/**
+ * @brief Cooperatively solves L*D*L'*x=b
+ *
+ * Given `L', a rowCount*rowCount lower triangular matrix with ones on the diagonal,
+ * and `d', a rowCount*1 vector of the reciprocal diagonal elements of a rowCount*rowCount matrix
+ * D, the function solves L*D*L'*x=b where `x' and `b' are rowCount*1.
+ * The leading dimension of @a L is @a rowSkip. The resulting vector `x' overwrites @a b.
+ *
+ * The @a resources must have had been allocated from a ResourceRequirements object
+ * estimated in @c dEstimateCooperativelySolveLDLTResourceRequirements.
+ *
+ * The operation is performed cooperatively by up to @a allowedThreadCount threads
+ * from thread pool available in @a resources. The threading must must not be simultaneously
+ * used (via other @c dResourceContainerID instances) in other calls that employ its features.
+ *
+ * @param resources The resources allocated for the function
+ * @param allowedThreadCount Maximum thread count to use (the actual thread count could be less, depending on other parameters)
+ * @param L The `L' matrix
+ * @param d The `d' vector
+ * @param b The `b' vector; also the result is stored here
+ * @param rowCount The row count in @a L, @a d and @a b
+ * @param rowskip The actual number of elements to be added to skip to next row in @a L
+ * @ingroup matrix_coop
+ * @see dEstimateCooperativelySolveLDLTResourceRequirements
+ * @see dResourceContainerAcquire
+ * @see dCooperativelyFactorLDLT
+ */
+ODE_API void dCooperativelySolveLDLT(dResourceContainerID resources, unsigned allowedThreadCount,
+ const dReal *L, const dReal *d, dReal *b, unsigned rowCount, unsigned rowSkip);
+
+
+/**
+ * @brief Estimates resource requirements for a @c dCooperativelySolveL1Straight call
+ *
+ * The function updates the contents of @a requirements to also suffice for calling
+ * @c dCooperativelySolveL1Straight with the given parameters.
+ *
+ * Note: The requirements that could have already been in the @a requirements parameter
+ * are never decreased.
+ *
+ * @param requirements The ResourceRequirements object to update
+ * @param maximalAllowedThreadCount Maximal value of allowedThreadCount parameter that is going to be used
+ * @param maximalRowCount Maximal value of rowCount parameter that is going to be used
+ * @ingroup matrix_coop
+ * @see dCooperativelySolveL1Straight
+ * @see dResourceRequirementsCreate
+ */
+ODE_API void dEstimateCooperativelySolveL1StraightResourceRequirements(dResourceRequirementsID requirements,
+ unsigned maximalAllowedThreadCount, unsigned maximalRowCount);
+
+/**
+ * @brief Cooperatively solves L*x=b
+ *
+ * The function solves L*x=b, where `L' is rowCount*rowCount lower triangular with ones on the diagonal,
+ * and `x', `b' are rowCount*1. The leading dimension of @a L is @a rowSkip.
+ * @a b is overwritten with `x'.
+ *
+ * The @a resources must have had been allocated from a ResourceRequirements object
+ * estimated in @c dEstimateCooperativelySolveL1StraightResourceRequirements.
+ *
+ * The operation is performed cooperatively by up to @a allowedThreadCount threads
+ * from thread pool available in @a resources. The threading must must not be simultaneously
+ * used (via other @c dResourceContainerID instances) in other calls that employ its features.
+ *
+ * @param resources The resources allocated for the function
+ * @param allowedThreadCount Maximum thread count to use (the actual thread count could be less, depending on other parameters)
+ * @param L The `L' matrix
+ * @param b The `b' vector; also the result is stored here
+ * @param rowCount The row count in @a L and @a b
+ * @param rowskip The actual number of elements to be added to skip to next row in @a L
+ * @ingroup matrix_coop
+ * @see dEstimateCooperativelySolveL1StraightResourceRequirements
+ * @see dResourceContainerAcquire
+ * @see dCooperativelyFactorLDLT
+ */
+ODE_API void dCooperativelySolveL1Straight(dResourceContainerID resources, unsigned allowedThreadCount,
+ const dReal *L, dReal *b, unsigned rowCount, unsigned rowSkip);
+
+
+/**
+ * @brief Estimates resource requirements for a @c dCooperativelySolveL1Transposed call
+ *
+ * The function updates the contents of @a requirements to also suffice for calling
+ * @c dCooperativelySolveL1Transposed with the given parameters.
+ *
+ * Note: The requirements that could have already been in the @a requirements parameter
+ * are never decreased.
+ *
+ * @param requirements The ResourceRequirements object to update
+ * @param maximalAllowedThreadCount Maximal value of allowedThreadCount parameter that is going to be used
+ * @param maximalRowCount Maximal value of rowCount parameter that is going to be used
+ * @ingroup matrix_coop
+ * @see dCooperativelySolveL1Transposed
+ * @see dResourceRequirementsCreate
+ */
+ODE_API void dEstimateCooperativelySolveL1TransposedResourceRequirements(dResourceRequirementsID requirements,
+ unsigned maximalAllowedThreadCount, unsigned maximalRowCount);
+
+/**
+ * @brief Cooperatively solves L'*x=b
+ *
+ * The function solves L'*x=b, where `L' is rowCount*rowCount lower triangular with ones on the diagonal,
+ * and `x', b are rowCount*1. The leading dimension of @a L is @a rowSkip.
+ * @a b is overwritten with `x'.
+ *
+ * The @a resources must have had been allocated from a ResourceRequirements object
+ * estimated in @c dEstimateCooperativelySolveL1TransposedResourceRequirements.
+ *
+ * The operation is performed cooperatively by up to @a allowedThreadCount threads
+ * from thread pool available in @a resources. The threading must must not be simultaneously
+ * used (via other @c dResourceContainerID instances) in other calls that employ its features.
+ *
+ * @param resources The resources allocated for the function
+ * @param allowedThreadCount Maximum thread count to use (the actual thread count could be less, depending on other parameters)
+ * @param L The `L' matrix
+ * @param b The `b' vector; also the result is stored here
+ * @param rowCount The row count in @a L and @a b
+ * @param rowskip The actual number of elements to be added to skip to next row in @a L
+ * @ingroup matrix_coop
+ * @see dEstimateCooperativelySolveL1TransposedResourceRequirements
+ * @see dResourceContainerAcquire
+ * @see dCooperativelyFactorLDLT
+ */
+ODE_API void dCooperativelySolveL1Transposed(dResourceContainerID resources, unsigned allowedThreadCount,
+ const dReal *L, dReal *b, unsigned rowCount, unsigned rowSkip);
+
+
+/**
+ * @brief Estimates resource requirements for a @c dCooperativelyScaleVector call
+ *
+ * The function updates the contents of @a requirements to also suffice for calling
+ * @c dCooperativelyScaleVector with the given parameters.
+ *
+ * Note: The requirements that could have already been in the @a requirements parameter
+ * are never decreased.
+ *
+ * @param requirements The ResourceRequirements object to update
+ * @param maximalAllowedThreadCount Maximal value of allowedThreadCount parameter that is going to be used
+ * @param maximalElementCount Maximal value of elementCount parameter that is going to be used
+ * @ingroup matrix_coop
+ * @see dCooperativelyScaleVector
+ * @see dResourceRequirementsCreate
+ */
+ODE_API void dEstimateCooperativelyScaleVectorResourceRequirements(dResourceRequirementsID requirements,
+ unsigned maximalAllowedThreadCount, unsigned maximalElementCount);
+
+/**
+ * @brief Multiplies elements of one vector by corresponding element of another one
+ *
+ * In matlab syntax, the operation performed is: dataVector(1:elementCount) = dataVector(1:elementCount) .* scaleVector(1:elementCount)
+ *
+ * The @a resources must have had been allocated from a ResourceRequirements object
+ * estimated in @c dEstimateCooperativelyScaleVectorResourceRequirements.
+ *
+ * The operation is performed cooperatively by up to @a allowedThreadCount threads
+ * from thread pool available in @a resources. The threading must must not be simultaneously
+ * used (via other @c dResourceContainerID instances) in other calls that employ its features.
+ *
+ * @param resources The resources allocated for the function
+ * @param allowedThreadCount Maximum thread count to use (the actual thread count could be less, depending on other parameters)
+ * @param dataVector The vector to be scaled in place
+ * @param scaleVector The scale vector
+ * @param elementCount The number of elements in @a dataVector and @a scaleVector
+ * @ingroup matrix_coop
+ * @see dEstimateCooperativelyScaleVectorResourceRequirements
+ * @see dResourceContainerAcquire
+ * @see dCooperativelyFactorLDLT
+ */
+ODE_API void dCooperativelyScaleVector(dResourceContainerID resources, unsigned allowedThreadCount,
+ dReal *dataVector, const dReal *scaleVector, unsigned elementCount);
+
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+
+#endif // #ifndef _ODE_MATRIX_COOP_H_
diff --git a/libs/ode-0.16.1/include/ode/memory.h b/libs/ode-0.16.1/include/ode/memory.h
new file mode 100644
index 0000000..8e49202
--- /dev/null
+++ b/libs/ode-0.16.1/include/ode/memory.h
@@ -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 (dsizeint size);
+typedef void * dReallocFunction (void *ptr, dsizeint oldsize, dsizeint newsize);
+typedef void dFreeFunction (void *ptr, dsizeint 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 (dsizeint size);
+ODE_API void * dRealloc (void *ptr, dsizeint oldsize, dsizeint newsize);
+ODE_API void dFree (void *ptr, dsizeint size);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/libs/ode-0.16.1/include/ode/misc.h b/libs/ode-0.16.1/include/ode/misc.h
new file mode 100644
index 0000000..01655ea
--- /dev/null
+++ b/libs/ode-0.16.1/include/ode/misc.h
@@ -0,0 +1,86 @@
+/*************************************************************************
+ * *
+ * 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 */
+ODE_API void dPrintMatrix (const dReal *A, int n, int m, const char *fmt, FILE *f);
+
+/* 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
+
+
+#ifdef __cplusplus
+static inline void dPrintMatrix (const dReal *A, int n, int m, const char *fmt="%10.4f ") { dPrintMatrix(A, n, m, fmt, stdout); }
+#endif
+
+
+#endif
diff --git a/libs/ode-0.16.1/include/ode/objects.h b/libs/ode-0.16.1/include/ode/objects.h
new file mode 100644
index 0000000..4796d56
--- /dev/null
+++ b/libs/ode-0.16.1/include/ode/objects.h
@@ -0,0 +1,3396 @@
+/*************************************************************************
+ * *
+ * 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>
+#include <ode/threading.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 user-data pointer
+ * @param world the world to set the data on
+ * @param data
+ * @ingroup world
+ */
+ODE_API void dWorldSetData (dWorldID world, void* data);
+
+
+/**
+ * @brief Get the user-data pointer
+ * @param world the world to set the data on
+ * @param data
+ * @ingroup world
+ */
+ODE_API void* dWorldGetData (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);
+
+
+#define dWORLDSTEP_THREADCOUNT_UNLIMITED dTHREADING_THREAD_COUNT_UNLIMITED
+
+/**
+ * @brief Set maximum threads to be used for island stepping
+ *
+ * The actual number of threads that is going to be used will be the minimum
+ * of this limit and number of threads in the threading pool. By default
+ * there is no limit (@c dWORLDSTEP_THREADCOUNT_UNLIMITED).
+ *
+ * @warning
+ * WARNING! Running island stepping in multiple threads requires allocating
+ * individual stepping memory buffer for each of those threads. The size of buffers
+ * allocated is the size needed to handle the largest island in the world.
+ *
+ * Note: Setting a limit for island stepping does not affect threading at lower
+ * levels in stepper functions. The sub-calls scheduled from them can be executed
+ * in as many threads as there are available in the pool.
+ *
+ * @param w The world affected
+ * @param count Thread count limit value for island stepping
+ * @ingroup world
+ * @see dWorldGetStepIslandsProcessingMaxThreadCount
+ */
+ODE_API void dWorldSetStepIslandsProcessingMaxThreadCount(dWorldID w, unsigned count);
+/**
+ * @brief Get maximum threads that are allowed to be used for island stepping.
+ *
+ * Please read commentaries to @c dWorldSetStepIslandsProcessingMaxThreadCount for
+ * important information regarding the value returned.
+ *
+ * @param w The world queried
+ * @returns Current thread count limit value for island stepping
+ * @ingroup world
+ * @see dWorldSetStepIslandsProcessingMaxThreadCount
+ */
+ODE_API unsigned dWorldGetStepIslandsProcessingMaxThreadCount(dWorldID w);
+
+/**
+ * @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.
+ *
+ * If worlds share working memory they must also use compatible threading implementations
+ * (i.e. it is illegal for one world to perform stepping with self-threaded implementation
+ * when the other world is assigned a multi-threaded implementation).
+ * For more information read section about threading approaches in ODE.
+ *
+ * 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)(dsizeint block_size);
+ void *(*shrink_block)(void *block_pointer, dsizeint block_current_size, dsizeint block_smaller_size);
+ void (*free_block)(void *block_pointer, dsizeint 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 Assign threading implementation to be used for [quick]stepping the world.
+ *
+ * @warning It is not recommended to assign the same threading implementation to
+ * different worlds if they are going to be called in parallel. In particular this
+ * makes resources preallocation for threaded calls to lose its sense.
+ * Built-in threading implementation is likely to crash if misused this way.
+ *
+ * @param w The world to change threading implementation for.
+ * @param functions_info Pointer to threading functions structure
+ * @param threading_impl ID of threading implementation object
+ *
+ * @ingroup world
+ */
+ODE_API void dWorldSetStepThreadingImplementation(dWorldID w, const dThreadingFunctionsInfo *functions_info, dThreadingImplementationID threading_impl);
+
+/**
+ * @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 average threshold for newly created bodies.
+ * @ingroup disable
+ * @return the threshold
+ */
+ODE_API dReal dWorldGetAutoDisableLinearThreshold (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 dWorldSetAutoDisableLinearThreshold (dWorldID, dReal linear_average_threshold);
+
+/**
+ * @brief Get auto disable angular average threshold for newly created bodies.
+ * @ingroup disable
+ * @return the threshold
+ */
+ODE_API dReal dWorldGetAutoDisableAngularThreshold (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 dWorldSetAutoDisableAngularThreshold (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 Create a new joint of the double ball 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 dJointCreateDBall (dWorldID, dJointGroupID);
+
+/**
+ * @brief Create a new joint of the double 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 dJointCreateDHinge (dWorldID, dJointGroupID);
+
+/**
+ * @brief Create a new joint of the Transmission 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 dJointCreateTransmission (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 both axes (optionally)
+ *
+ * This can change both axes at once avoiding transitions via invalid states
+ * while changing axes one by one and having the first changed axis coincide
+ * with the other axis existing direction.
+ *
+ * At least one of the axes must be not NULL. If NULL is passed, the corresponding
+ * axis retains its existing value.
+ *
+ * @ingroup joints
+ */
+ODE_API void dJointSetHinge2Axes (dJointID j, const dReal *axis1/*=[dSA__MAX],=NULL*/, const dReal *axis2/*=[dSA__MAX],=NULL*/);
+
+/**
+ * @brief set axis
+ *
+ * Deprecated. Use @fn dJointSetHinge2Axes instead.
+ *
+ * @ingroup joints
+ * @see dJointSetHinge2Axes
+ */
+ODE_API_DEPRECATED ODE_API void dJointSetHinge2Axis1 (dJointID j, dReal x, dReal y, dReal z);
+
+/**
+ * @brief set axis
+ *
+ * Deprecated. Use @fn dJointSetHinge2Axes instead.
+ *
+ * @ingroup joints
+ * @see dJointSetHinge2Axes
+ */
+ODE_API_DEPRECATED ODE_API void dJointSetHinge2Axis2 (dJointID j, 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 angle
+ * @ingroup joints
+ */
+ODE_API dReal dJointGetHinge2Angle2 (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);
+
+
+/**
+ * @brief get the contact point of the first wheel of the Transmission joint.
+ * @ingroup joints
+ */
+ODE_API void dJointGetTransmissionContactPoint1(dJointID, dVector3 result);
+
+/**
+ * @brief get contact point of the second wheel of the Transmission joint.
+ * @ingroup joints
+ */
+ODE_API void dJointGetTransmissionContactPoint2(dJointID, dVector3 result);
+
+/**
+ * @brief set the first axis for the Transmission joint
+ * @remarks This is the axis around which the first body is allowed to
+ * revolve and is attached to it. It is given in global coordinates
+ * and can only be set explicitly in intersecting-axes mode. For the
+ * parallel-axes and chain modes which share one common axis of
+ * revolution for both gears dJointSetTransmissionAxis should be used.
+ * @ingroup joints
+ */
+ODE_API void dJointSetTransmissionAxis1(dJointID, dReal x, dReal y, dReal z);
+
+/**
+ * @brief get first axis for the Transmission joint
+ * @remarks In parallel-axes and chain mode the common axis with
+ * respect to the first body is returned. If the joint constraint is
+ * satisfied it should be the same as the axis return with
+ * dJointGetTransmissionAxis2 or dJointGetTransmissionAxis.
+ * @ingroup joints
+ */
+ODE_API void dJointGetTransmissionAxis1(dJointID, dVector3 result);
+
+/**
+ * @brief set second axis for the Transmission joint
+ * @remarks This is the axis around which the second body is allowed
+ * to revolve and is attached to it. It is given in global
+ * coordinates and can only be set explicitly in intersecting-axes
+ * mode. For the parallel-axes and chain modes which share one common
+ * axis of revolution for both gears dJointSetTransmissionAxis should
+ * be used.
+ * @ingroup joints
+ */
+ODE_API void dJointSetTransmissionAxis2(dJointID, dReal x, dReal y, dReal z);
+
+/**
+ * @brief get second axis for the Transmission joint
+ * @remarks In parallel-axes and chain mode the common axis with
+ * respect to the second body is returned. If the joint constraint is
+ * satisfied it should be the same as the axis return with
+ * dJointGetTransmissionAxis1 or dJointGetTransmissionAxis.
+ * @ingroup joints
+ */
+ODE_API void dJointGetTransmissionAxis2(dJointID, dVector3 result);
+
+/**
+ * @brief set the first anchor for the Transmission joint
+ * @remarks This is the point of attachment of the wheel on the
+ * first body. It is given in global coordinates.
+ * @ingroup joints
+ */
+ODE_API void dJointSetTransmissionAnchor1(dJointID, dReal x, dReal y, dReal z);
+
+/**
+ * @brief get the first anchor of the Transmission joint
+ * @ingroup joints
+ */
+ODE_API void dJointGetTransmissionAnchor1(dJointID, dVector3 result);
+
+/**
+ * @brief set the second anchor for the Transmission joint
+ * @remarks This is the point of attachment of the wheel on the
+ * second body. It is given in global coordinates.
+ * @ingroup joints
+ */
+ODE_API void dJointSetTransmissionAnchor2(dJointID, dReal x, dReal y, dReal z);
+
+/**
+ * @brief get the second anchor for the Transmission joint
+ * @ingroup joints
+ */
+ODE_API void dJointGetTransmissionAnchor2(dJointID, dVector3 result);
+
+/**
+ * @brief set a Transmission joint parameter
+ * @ingroup joints
+ */
+ODE_API void dJointSetTransmissionParam(dJointID, int parameter, dReal value);
+
+/**
+ * @brief get a Transmission joint parameter
+ * @ingroup joints
+ */
+ODE_API dReal dJointGetTransmissionParam(dJointID, int parameter);
+
+/**
+ * @brief set the Transmission joint mode
+ * @remarks The mode can be one of dTransmissionParallelAxes,
+ * dTransmissionIntersectingAxes and dTransmissionChainDrive simulating a
+ * set of parallel-axes gears, intersecting-axes beveled gears or
+ * chain and sprockets respectively.
+ * @ingroup joints
+ */
+ODE_API void dJointSetTransmissionMode( dJointID j, int mode );
+
+/**
+ * @brief get the Transmission joint mode
+ * @ingroup joints
+ */
+ODE_API int dJointGetTransmissionMode( dJointID j );
+
+/**
+ * @brief set the Transmission ratio
+ * @remarks This is the ratio of the angular speed of the first gear
+ * to that of the second gear. It can only be set explicitly in
+ * parallel-axes mode. In intersecting-axes mode the ratio is defined
+ * implicitly by the initial configuration of the wheels and in chain
+ * mode it is defined implicitly be the wheel radii.
+ * @ingroup joints
+ */
+ODE_API void dJointSetTransmissionRatio( dJointID j, dReal ratio );
+
+/**
+ * @brief get the Transmission joint ratio
+ * @ingroup joints
+ */
+ODE_API dReal dJointGetTransmissionRatio( dJointID j );
+
+/**
+ * @brief set the common axis for both wheels of the Transmission joint
+ * @remarks This sets the common axis of revolution for both wheels
+ * and should only be used in parallel-axes or chain mode. For
+ * intersecting-axes mode where each wheel axis needs to be specified
+ * individually dJointSetTransmissionAxis1 and
+ * dJointSetTransmissionAxis2 should be used. The axis is given in
+ * global coordinates
+ * @ingroup joints
+ */
+ODE_API void dJointSetTransmissionAxis( dJointID j, dReal x, dReal y, dReal z );
+
+/**
+ * @brief get the common axis for both wheels of the Transmission joint
+ * @ingroup joints
+ */
+ODE_API void dJointGetTransmissionAxis( dJointID j, dVector3 result );
+
+/**
+ * @brief get the phase, that is the traversed angle for the first
+ * wheel of the Transmission joint
+ * @ingroup joints
+ */
+ODE_API dReal dJointGetTransmissionAngle1( dJointID j );
+
+/**
+ * @brief get the phase, that is the traversed angle for the second
+ * wheel of the Transmission joint
+ * @ingroup joints
+ */
+ODE_API dReal dJointGetTransmissionAngle2( dJointID j );
+
+/**
+ * @brief get the radius of the first wheel of the Transmission joint
+ * @ingroup joints
+ */
+ODE_API dReal dJointGetTransmissionRadius1( dJointID j );
+
+/**
+ * @brief get the radius of the second wheel of the Transmission joint
+ * @ingroup joints
+ */
+ODE_API dReal dJointGetTransmissionRadius2( dJointID j );
+
+/**
+ * @brief set the radius of the first wheel of the Transmission joint
+ * @remarks The wheel radii can only be set explicitly in chain mode.
+ * In the other modes they're defined implicitly by the initial
+ * configuration and ratio of the wheels.
+ * @ingroup joints
+ */
+ODE_API void dJointSetTransmissionRadius1( dJointID j, dReal radius );
+
+/**
+ * @brief set the radius of the second wheel of the Transmission joint
+ * @remarks The wheel radii can only be set explicitly in chain mode.
+ * In the other modes they're defined implicitly by the initial
+ * configuration and ratio of the wheels.
+ * @ingroup joints
+ */
+ODE_API void dJointSetTransmissionRadius2( dJointID j, dReal radius );
+
+/**
+ * @brief get the backlash of the Transmission joint
+ * @ingroup joints
+ */
+ODE_API dReal dJointGetTransmissionBacklash( dJointID j );
+
+/**
+ * @brief set the backlash of the Transmission joint
+ * @remarks Backlash is the clearance in the mesh of the wheels of the
+ * transmission and is defined as the maximum distance that the
+ * geometric contact point can travel without any actual contact or
+ * transfer of power between the wheels. This can be converted in
+ * degrees of revolution for each wheel by dividing by the wheel's
+ * radius. To further illustrate this consider the situation where a
+ * wheel of radius r_1 is driving another wheel of radius r_2 and
+ * there is an amount of backlash equal to b in their mesh. If the
+ * driving wheel were to instantaneously stop there would be no
+ * contact and hence the driven wheel would continue to turn for
+ * another b / r_2 radians until all the backlash in the mesh was take
+ * up and contact restored with the relationship of driving and driven
+ * wheel reversed. The backlash is therefore given in untis of
+ * length.
+ * @ingroup joints
+ */
+ODE_API void dJointSetTransmissionBacklash( dJointID j, dReal backlash );
+
+/**
+ * @brief set anchor1 for double ball joint
+ * @ingroup joints
+ */
+ODE_API void dJointSetDBallAnchor1(dJointID, dReal x, dReal y, dReal z);
+
+/**
+ * @brief set anchor2 for double ball joint
+ * @ingroup joints
+ */
+ODE_API void dJointSetDBallAnchor2(dJointID, dReal x, dReal y, dReal z);
+
+/**
+ * @brief get anchor1 from double ball joint
+ * @ingroup joints
+ */
+ODE_API void dJointGetDBallAnchor1(dJointID, dVector3 result);
+
+/**
+ * @brief get anchor2 from double ball joint
+ * @ingroup joints
+ */
+ODE_API void dJointGetDBallAnchor2(dJointID, dVector3 result);
+
+/**
+ * @brief get the target distance from double ball joint
+ * @ingroup joints
+ */
+ODE_API dReal dJointGetDBallDistance(dJointID);
+
+/**
+ * @brief set the target distance for the double ball joint
+ * @ingroup joints
+ */
+ODE_API void dJointSetDBallDistance(dJointID, dReal dist);
+
+/**
+ * @brief set double ball joint parameter
+ * @ingroup joints
+ */
+ODE_API void dJointSetDBallParam(dJointID, int parameter, dReal value);
+
+/**
+ * @brief get double ball joint parameter
+ * @ingroup joints
+ */
+ODE_API dReal dJointGetDBallParam(dJointID, int parameter);
+
+/**
+ * @brief set axis for double hinge joint
+ * @ingroup joints
+ */
+ODE_API void dJointSetDHingeAxis(dJointID, dReal x, dReal y, dReal z);
+
+/**
+ * @brief get axis for double hinge joint
+ * @ingroup joints
+ */
+ODE_API void dJointGetDHingeAxis(dJointID, dVector3 result);
+
+/**
+ * @brief set anchor1 for double hinge joint
+ * @ingroup joints
+ */
+ODE_API void dJointSetDHingeAnchor1(dJointID, dReal x, dReal y, dReal z);
+
+/**
+ * @brief set anchor2 for double hinge joint
+ * @ingroup joints
+ */
+ODE_API void dJointSetDHingeAnchor2(dJointID, dReal x, dReal y, dReal z);
+
+/**
+ * @brief get anchor1 from double hinge joint
+ * @ingroup joints
+ */
+ODE_API void dJointGetDHingeAnchor1(dJointID, dVector3 result);
+
+/**
+ * @brief get anchor2 from double hinge joint
+ * @ingroup joints
+ */
+ODE_API void dJointGetDHingeAnchor2(dJointID, dVector3 result);
+
+/**
+ * @brief get the set distance from double hinge joint
+ * @ingroup joints
+ */
+ODE_API dReal dJointGetDHingeDistance(dJointID);
+
+/**
+ * @brief set double hinge joint parameter
+ * @ingroup joints
+ */
+ODE_API void dJointSetDHingeParam(dJointID, int parameter, dReal value);
+
+/**
+ * @brief get double hinge joint parameter
+ * @ingroup joints
+ */
+ODE_API dReal dJointGetDHingeParam(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/libs/ode-0.16.1/include/ode/ode.h b/libs/ode-0.16.1/include/ode/ode.h
new file mode 100644
index 0000000..a69f46a
--- /dev/null
+++ b/libs/ode-0.16.1/include/ode/ode.h
@@ -0,0 +1,56 @@
+/*************************************************************************
+ * *
+ * 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/matrix_coop.h>
+#include <ode/timer.h>
+#include <ode/rotation.h>
+#include <ode/mass.h>
+#include <ode/misc.h>
+#include <ode/objects.h>
+#include <ode/collision_space.h>
+#include <ode/collision.h>
+#include <ode/threading.h>
+#include <ode/threading_impl.h>
+#include <ode/cooperative.h>
+#include <ode/export-dif.h>
+#include <ode/version.h>
+
+#ifdef __cplusplus
+# include <ode/odecpp.h>
+# include <ode/odecpp_collision.h>
+#endif
+
+#endif
diff --git a/libs/ode-0.16.1/include/ode/odeconfig.h b/libs/ode-0.16.1/include/ode/odeconfig.h
new file mode 100644
index 0000000..1a0c747
--- /dev/null
+++ b/libs/ode-0.16.1/include/ode/odeconfig.h
@@ -0,0 +1,218 @@
+/*************************************************************************
+ * *
+ * 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_ODECONFIG_H_
+#define _ODE_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>
+
+
+#include <ode/precision.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) || (defined(__GNUC__) && defined(_WIN32))
+ #if defined(ODE_DLL)
+ #define ODE_API __declspec(dllexport)
+ #else
+ #define ODE_API
+ #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
+
+#define ODE_PURE_INLINE static __inline
+#define ODE_INLINE __inline
+
+#if defined(__cplusplus)
+ #define ODE_EXTERN_C extern "C"
+#else
+ #define ODE_EXTERN_C
+#endif
+
+#if defined(__GNUC__)
+#define ODE_NORETURN __attribute__((noreturn))
+#elif defined(_MSC_VER)
+#define ODE_NORETURN __declspec(noreturn)
+#else // #if !defined(_MSC_VER)
+#define ODE_NORETURN
+#endif // #if !defined(__GNUC__)
+
+
+/* Well-defined common data types...need to be defined for 64 bit systems */
+#if defined(__aarch64__) || defined(__alpha__) || defined(__ppc64__) \
+ || defined(__s390__) || defined(__s390x__) || defined(__zarch__) \
+ || defined(__mips__) || defined(__powerpc64__) || defined(__riscv) \
+ || (defined(__sparc__) && defined(__arch64__))
+ #include <stdint.h>
+ typedef int64_t dint64;
+ typedef uint64_t duint64;
+ typedef int32_t dint32;
+ typedef uint32_t duint32;
+ typedef int16_t dint16;
+ typedef uint16_t duint16;
+ typedef int8_t dint8;
+ typedef uint8_t duint8;
+
+ typedef intptr_t dintptr;
+ typedef uintptr_t duintptr;
+ typedef ptrdiff_t ddiffint;
+ typedef size_t dsizeint;
+
+#elif (defined(_M_IA64) || defined(__ia64__) || defined(_M_AMD64) || defined(__x86_64__)) && !defined(__ILP32__) && !defined(_ILP32)
+ #define X86_64_SYSTEM 1
+#if defined(_MSC_VER)
+ typedef __int64 dint64;
+ typedef unsigned __int64 duint64;
+#else
+#if defined(_LP64) || defined(__LP64__)
+typedef long dint64;
+typedef unsigned long duint64;
+#else
+ typedef long long dint64;
+ typedef unsigned long long duint64;
+#endif
+#endif
+ typedef int dint32;
+ typedef unsigned int duint32;
+ typedef short dint16;
+ typedef unsigned short duint16;
+ typedef signed char dint8;
+ typedef unsigned char duint8;
+
+ typedef dint64 dintptr;
+ typedef duint64 duintptr;
+ typedef dint64 ddiffint;
+ typedef duint64 dsizeint;
+
+#else
+#if defined(_MSC_VER)
+ typedef __int64 dint64;
+ typedef unsigned __int64 duint64;
+#else
+ typedef long long dint64;
+ typedef unsigned long long duint64;
+#endif
+ typedef int dint32;
+ typedef unsigned int duint32;
+ typedef short dint16;
+ typedef unsigned short duint16;
+ typedef signed char dint8;
+ typedef unsigned char duint8;
+
+ typedef dint32 dintptr;
+ typedef duint32 duintptr;
+ typedef dint32 ddiffint;
+ typedef duint32 dsizeint;
+
+#endif
+
+
+/* Define the dInfinity macro */
+#ifdef INFINITY
+ #ifdef dSINGLE
+ #define dInfinity ((float)INFINITY)
+ #else
+ #define dInfinity ((double)INFINITY)
+ #endif
+#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
+
+
+/* Define the dNaN macro */
+#if defined(NAN)
+ #define dNaN NAN
+#elif defined(__GNUC__)
+ #define dNaN ({ union { duint32 m_ui; float m_f; } un; un.m_ui = 0x7FC00000; un.m_f; })
+#elif defined(__cplusplus)
+ union _dNaNUnion
+ {
+ _dNaNUnion(): m_ui(0x7FC00000) {}
+ duint32 m_ui;
+ float m_f;
+ };
+ #define dNaN (_dNaNUnion().m_f)
+#else
+ #ifdef dSINGLE
+ #define dNaN ((float)(dInfinity - dInfinity))
+ #else
+ #define dNaN (dInfinity - dInfinity)
+ #endif
+#endif
+
+
+ /* Visual C does not define these functions */
+#if defined(_MSC_VER)
+ #define _ode_copysignf(x, y) ((float)_copysign(x, y))
+ #define _ode_copysign(x, y) _copysign(x, y)
+ #define _ode_nextafterf(x, y) _nextafterf(x, y)
+ #define _ode_nextafter(x, y) _nextafter(x, y)
+ #if !defined(_WIN64) && defined(dSINGLE)
+ #define _ODE__NEXTAFTERF_REQUIRED
+ ODE_EXTERN_C float _nextafterf(float x, float y);
+ #endif
+#else
+ #define _ode_copysignf(x, y) copysignf(x, y)
+ #define _ode_copysign(x, y) copysign(x, y)
+ #define _ode_nextafterf(x, y) nextafterf(x, y)
+ #define _ode_nextafter(x, y) nextafter(x, y)
+#endif
+
+
+#endif
diff --git a/libs/ode-0.16.1/include/ode/odecpp.h b/libs/ode-0.16.1/include/ode/odecpp.h
new file mode 100644
index 0000000..f604d0d
--- /dev/null
+++ b/libs/ode-0.16.1/include/ode/odecpp.h
@@ -0,0 +1,1355 @@
+/*************************************************************************
+ * *
+ * 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 setAxes (const dReal *axis1/*=NULL*/, const dReal *axis2/*=NULL*/)
+ { dJointSetHinge2Axes (get_id(), axis1, axis2); }
+ ODE_API_DEPRECATED void setAxis1 (dReal x, dReal y, dReal z)
+ { dVector3 a = { x, y, z }; dJointSetHinge2Axes (get_id(), a, NULL); }
+ ODE_API_DEPRECATED void setAxis1 (const dVector3 a)
+ { dJointSetHinge2Axes (get_id(), a, NULL); }
+ ODE_API_DEPRECATED void setAxis2 (dReal x, dReal y, dReal z)
+ { dVector3 a = { x, y, z }; dJointSetHinge2Axes (get_id(), NULL, a); }
+ ODE_API_DEPRECATED void setAxis2 (const dVector3 a)
+ { dJointSetHinge2Axes (get_id(), NULL, a); }
+
+ 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/libs/ode-0.16.1/include/ode/odecpp_collision.h b/libs/ode-0.16.1/include/ode/odecpp_collision.h
new file mode 100644
index 0000000..f2c7725
--- /dev/null
+++ b/libs/ode-0.16.1/include/ode/odecpp_collision.h
@@ -0,0 +1,467 @@
+/*************************************************************************
+ * *
+ * 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); }
+
+#ifdef WIN32
+#pragma warning( push )
+#pragma warning( disable : 4996 )
+#else
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+#endif
+ ODE_API_DEPRECATED
+ void setParams (int firstContact, int backfaceCull)
+ { dGeomRaySetParams (_id, firstContact, backfaceCull); }
+
+ ODE_API_DEPRECATED
+ void getParams (int *firstContact, int *backfaceCull)
+ { dGeomRayGetParams (_id, firstContact, backfaceCull); }
+#ifdef WIN32
+#pragma warning( pop )
+#else
+#pragma GCC diagnostic pop
+#endif
+ void setBackfaceCull (int backfaceCull)
+ { dGeomRaySetBackfaceCull (_id, backfaceCull); }
+ int getBackfaceCull()
+ { return dGeomRayGetBackfaceCull (_id); }
+
+ void setFirstContact (int firstContact)
+ { dGeomRaySetFirstContact (_id, firstContact); }
+ int getFirstContact()
+ { return dGeomRayGetFirstContact (_id); }
+
+ void setClosestHit (int closestHit)
+ { dGeomRaySetClosestHit (_id, closestHit); }
+ int getClosestHit()
+ { return dGeomRayGetClosestHit (_id); }
+};
+
+#ifdef WIN32
+#pragma warning( push )
+#pragma warning( disable : 4996 )
+#else
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+#endif
+
+class ODE_API_DEPRECATED 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); }
+};
+
+#ifdef WIN32
+#pragma warning( pop )
+#else
+#pragma GCC diagnostic pop
+#endif
+
+//}
+
+#endif
+#endif
diff --git a/libs/ode-0.16.1/include/ode/odeinit.h b/libs/ode-0.16.1/include/ode/odeinit.h
new file mode 100644
index 0000000..645ca42
--- /dev/null
+++ b/libs/ode-0.16.1/include/ode/odeinit.h
@@ -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 = ~0 /*@< 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/libs/ode-0.16.1/include/ode/odemath.h b/libs/ode-0.16.1/include/ode/odemath.h
new file mode 100644
index 0000000..d4461b3
--- /dev/null
+++ b/libs/ode-0.16.1/include/ode/odemath.h
@@ -0,0 +1,545 @@
+/*************************************************************************
+ * *
+ * 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]) ))
+
+
+ODE_PURE_INLINE void dZeroVector3(dVector3 res)
+{
+ res[dV3E_X] = REAL(0.0);
+ res[dV3E_Y] = REAL(0.0);
+ res[dV3E_Z] = REAL(0.0);
+}
+
+ODE_PURE_INLINE void dAssignVector3(dVector3 res, dReal x, dReal y, dReal z)
+{
+ res[dV3E_X] = x;
+ res[dV3E_Y] = y;
+ res[dV3E_Z] = z;
+}
+
+ODE_PURE_INLINE void dZeroMatrix3(dMatrix3 res)
+{
+ res[dM3E_XX] = REAL(0.0); res[dM3E_XY] = REAL(0.0); res[dM3E_XZ] = REAL(0.0);
+ res[dM3E_YX] = REAL(0.0); res[dM3E_YY] = REAL(0.0); res[dM3E_YZ] = REAL(0.0);
+ res[dM3E_ZX] = REAL(0.0); res[dM3E_ZY] = REAL(0.0); res[dM3E_ZZ] = REAL(0.0);
+}
+
+ODE_PURE_INLINE void dZeroMatrix4(dMatrix4 res)
+{
+ res[dM4E_XX] = REAL(0.0); res[dM4E_XY] = REAL(0.0); res[dM4E_XZ] = REAL(0.0); res[dM4E_XO] = REAL(0.0);
+ res[dM4E_YX] = REAL(0.0); res[dM4E_YY] = REAL(0.0); res[dM4E_YZ] = REAL(0.0); res[dM4E_YO] = REAL(0.0);
+ res[dM4E_ZX] = REAL(0.0); res[dM4E_ZY] = REAL(0.0); res[dM4E_ZZ] = REAL(0.0); res[dM4E_ZO] = REAL(0.0);
+ res[dM4E_OX] = REAL(0.0); res[dM4E_OY] = REAL(0.0); res[dM4E_OZ] = REAL(0.0); res[dM4E_OO] = REAL(0.0);
+}
+
+/* Some vector math */
+ODE_PURE_INLINE void dAddVectors3(dReal *res, const dReal *a, const dReal *b)
+{
+ const dReal res_0 = a[0] + b[0];
+ const dReal res_1 = a[1] + b[1];
+ const dReal 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;
+}
+
+ODE_PURE_INLINE void dSubtractVectors3(dReal *res, const dReal *a, const dReal *b)
+{
+ const dReal res_0 = a[0] - b[0];
+ const dReal res_1 = a[1] - b[1];
+ const dReal 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;
+}
+
+ODE_PURE_INLINE void dAddVectorScaledVector3(dReal *res, const dReal *a, const dReal *b, dReal b_scale)
+{
+ const dReal res_0 = a[0] + b_scale * b[0];
+ const dReal res_1 = a[1] + b_scale * b[1];
+ const dReal res_2 = 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;
+}
+
+ODE_PURE_INLINE void dAddScaledVectors3(dReal *res, const dReal *a, const dReal *b, dReal a_scale, dReal b_scale)
+{
+ const dReal res_0 = a_scale * a[0] + b_scale * b[0];
+ const dReal res_1 = a_scale * a[1] + b_scale * b[1];
+ const dReal 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;
+}
+
+ODE_PURE_INLINE void dAddThreeScaledVectors3(dReal *res, const dReal *a, const dReal *b, const dReal *c, dReal a_scale, dReal b_scale, dReal c_scale)
+{
+ const dReal res_0 = a_scale * a[0] + b_scale * b[0] + c_scale * c[0];
+ const dReal res_1 = a_scale * a[1] + b_scale * b[1] + c_scale * c[1];
+ const dReal res_2 = a_scale * a[2] + b_scale * b[2] + c_scale * c[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;
+}
+
+ODE_PURE_INLINE void dScaleVector3(dReal *res, dReal nScale)
+{
+ res[0] *= nScale ;
+ res[1] *= nScale ;
+ res[2] *= nScale ;
+}
+
+ODE_PURE_INLINE void dNegateVector3(dReal *res)
+{
+ res[0] = -res[0];
+ res[1] = -res[1];
+ res[2] = -res[2];
+}
+
+ODE_PURE_INLINE void dCopyVector3(dReal *res, const dReal *a)
+{
+ const dReal res_0 = a[0];
+ const dReal res_1 = a[1];
+ const dReal 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;
+}
+
+ODE_PURE_INLINE void dCopyScaledVector3(dReal *res, const dReal *a, dReal nScale)
+{
+ const dReal res_0 = a[0] * nScale;
+ const dReal res_1 = a[1] * nScale;
+ const dReal 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;
+}
+
+ODE_PURE_INLINE void dCopyNegatedVector3(dReal *res, const dReal *a)
+{
+ const dReal res_0 = -a[0];
+ const dReal res_1 = -a[1];
+ const dReal 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;
+}
+
+ODE_PURE_INLINE void dCopyVector4(dReal *res, const dReal *a)
+{
+ const dReal res_0 = a[0];
+ const dReal res_1 = a[1];
+ const dReal res_2 = a[2];
+ const dReal 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;
+}
+
+ODE_PURE_INLINE void dCopyMatrix4x4(dReal *res, const dReal *a)
+{
+ dCopyVector4(res + 0, a + 0);
+ dCopyVector4(res + 4, a + 4);
+ dCopyVector4(res + 8, a + 8);
+}
+
+ODE_PURE_INLINE void dCopyMatrix4x3(dReal *res, const dReal *a)
+{
+ dCopyVector3(res + 0, a + 0);
+ dCopyVector3(res + 4, a + 4);
+ dCopyVector3(res + 8, a + 8);
+}
+
+ODE_PURE_INLINE void dGetMatrixColumn3(dReal *res, const dReal *a, unsigned n)
+{
+ const dReal res_0 = a[n + 0];
+ const dReal res_1 = a[n + 4];
+ const dReal 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;
+}
+
+ODE_PURE_INLINE dReal dCalcVectorLength3(const dReal *a)
+{
+ return dSqrt(a[0] * a[0] + a[1] * a[1] + a[2] * a[2]);
+}
+
+ODE_PURE_INLINE dReal dCalcVectorLengthSquare3(const dReal *a)
+{
+ return (a[0] * a[0] + a[1] * a[1] + a[2] * a[2]);
+}
+
+ODE_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.
+*/
+
+ODE_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];
+}
+
+
+ODE_PURE_INLINE dReal dCalcVectorDot3 (const dReal *a, const dReal *b) { return _dCalcVectorDot3(a,b,1,1); }
+ODE_PURE_INLINE dReal dCalcVectorDot3_13 (const dReal *a, const dReal *b) { return _dCalcVectorDot3(a,b,1,3); }
+ODE_PURE_INLINE dReal dCalcVectorDot3_31 (const dReal *a, const dReal *b) { return _dCalcVectorDot3(a,b,3,1); }
+ODE_PURE_INLINE dReal dCalcVectorDot3_33 (const dReal *a, const dReal *b) { return _dCalcVectorDot3(a,b,3,3); }
+ODE_PURE_INLINE dReal dCalcVectorDot3_14 (const dReal *a, const dReal *b) { return _dCalcVectorDot3(a,b,1,4); }
+ODE_PURE_INLINE dReal dCalcVectorDot3_41 (const dReal *a, const dReal *b) { return _dCalcVectorDot3(a,b,4,1); }
+ODE_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.
+ */
+
+ODE_PURE_INLINE void _dCalcVectorCross3(dReal *res, const dReal *a, const dReal *b, unsigned step_res, unsigned step_a, unsigned step_b)
+{
+ const dReal res_0 = a[ step_a]*b[2*step_b] - a[2*step_a]*b[ step_b];
+ const dReal res_1 = a[2*step_a]*b[ 0] - a[ 0]*b[2*step_b];
+ const dReal 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;
+}
+
+ODE_PURE_INLINE void dCalcVectorCross3 (dReal *res, const dReal *a, const dReal *b) { _dCalcVectorCross3(res, a, b, 1, 1, 1); }
+ODE_PURE_INLINE void dCalcVectorCross3_114(dReal *res, const dReal *a, const dReal *b) { _dCalcVectorCross3(res, a, b, 1, 1, 4); }
+ODE_PURE_INLINE void dCalcVectorCross3_141(dReal *res, const dReal *a, const dReal *b) { _dCalcVectorCross3(res, a, b, 1, 4, 1); }
+ODE_PURE_INLINE void dCalcVectorCross3_144(dReal *res, const dReal *a, const dReal *b) { _dCalcVectorCross3(res, a, b, 1, 4, 4); }
+ODE_PURE_INLINE void dCalcVectorCross3_411(dReal *res, const dReal *a, const dReal *b) { _dCalcVectorCross3(res, a, b, 4, 1, 1); }
+ODE_PURE_INLINE void dCalcVectorCross3_414(dReal *res, const dReal *a, const dReal *b) { _dCalcVectorCross3(res, a, b, 4, 1, 4); }
+ODE_PURE_INLINE void dCalcVectorCross3_441(dReal *res, const dReal *a, const dReal *b) { _dCalcVectorCross3(res, a, b, 4, 4, 1); }
+ODE_PURE_INLINE void dCalcVectorCross3_444(dReal *res, const dReal *a, const dReal *b) { _dCalcVectorCross3(res, a, b, 4, 4, 4); }
+
+ODE_PURE_INLINE void dAddVectorCross3(dReal *res, const dReal *a, const dReal *b)
+{
+ dReal tmp[3];
+ dCalcVectorCross3(tmp, a, b);
+ dAddVectors3(res, res, tmp);
+}
+
+ODE_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.
+ */
+
+ODE_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;
+}
+
+ODE_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
+ */
+
+ODE_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
+ */
+
+ODE_PURE_INLINE void dMultiplyHelper0_331(dReal *res, const dReal *a, const dReal *b)
+{
+ const dReal res_0 = dCalcVectorDot3(a, b);
+ const dReal res_1 = dCalcVectorDot3(a + 4, b);
+ const dReal 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;
+}
+
+ODE_PURE_INLINE void dMultiplyHelper1_331(dReal *res, const dReal *a, const dReal *b)
+{
+ const dReal res_0 = dCalcVectorDot3_41(a, b);
+ const dReal res_1 = dCalcVectorDot3_41(a + 1, b);
+ const dReal 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;
+}
+
+ODE_PURE_INLINE void dMultiplyHelper0_133(dReal *res, const dReal *a, const dReal *b)
+{
+ dMultiplyHelper1_331(res, b, a);
+}
+
+ODE_PURE_INLINE void dMultiplyHelper1_133(dReal *res, const dReal *a, const dReal *b)
+{
+ const dReal res_0 = dCalcVectorDot3_44(a, b);
+ const dReal res_1 = dCalcVectorDot3_44(a + 1, b);
+ const dReal 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.
+*/
+
+ODE_PURE_INLINE void dMultiply0_331(dReal *res, const dReal *a, const dReal *b)
+{
+ dMultiplyHelper0_331(res, a, b);
+}
+
+ODE_PURE_INLINE void dMultiply1_331(dReal *res, const dReal *a, const dReal *b)
+{
+ dMultiplyHelper1_331(res, a, b);
+}
+
+ODE_PURE_INLINE void dMultiply0_133(dReal *res, const dReal *a, const dReal *b)
+{
+ dMultiplyHelper0_133(res, a, b);
+}
+
+ODE_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);
+}
+
+ODE_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);
+}
+
+ODE_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);
+}
+
+ODE_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);
+}
+
+ODE_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);
+}
+
+ODE_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);
+}
+
+ODE_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);
+}
+
+ODE_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);
+}
+
+ODE_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);
+}
+
+ODE_PURE_INLINE dReal dCalcMatrix3Det( const dReal* mat )
+{
+ dReal det;
+
+ det = mat[0] * ( mat[5]*mat[10] - mat[9]*mat[6] )
+ - mat[1] * ( mat[4]*mat[10] - mat[8]*mat[6] )
+ + mat[2] * ( mat[4]*mat[9] - mat[8]*mat[5] );
+
+ return( det );
+}
+
+/**
+ Closed form matrix inversion, copied from
+ collision_util.h for use in the stepper.
+
+ Returns the determinant.
+ returns 0 and does nothing
+ if the matrix is singular.
+*/
+ODE_PURE_INLINE dReal dInvertMatrix3(dReal *dst, const dReal *ma)
+{
+ dReal det;
+ dReal detRecip;
+
+ det = dCalcMatrix3Det( ma );
+
+
+ /* Setting an arbitrary non-zero threshold
+ for the determinant doesn't do anyone
+ any favors. The condition number is the
+ important thing. If all the eigen-values
+ of the matrix are small, so is the
+ determinant, but it can still be well
+ conditioned.
+ A single extremely large eigen-value could
+ push the determinant over threshold, but
+ produce a very unstable result if the other
+ eigen-values are small. So we just say that
+ the determinant must be non-zero and trust the
+ caller to provide well-conditioned matrices.
+ */
+ if ( det == 0 )
+ {
+ return 0;
+ }
+
+ detRecip = dRecip(det);
+
+ dst[0] = ( ma[5]*ma[10] - ma[6]*ma[9] ) * detRecip;
+ dst[1] = ( ma[9]*ma[2] - ma[1]*ma[10] ) * detRecip;
+ dst[2] = ( ma[1]*ma[6] - ma[5]*ma[2] ) * detRecip;
+
+ dst[4] = ( ma[6]*ma[8] - ma[4]*ma[10] ) * detRecip;
+ dst[5] = ( ma[0]*ma[10] - ma[8]*ma[2] ) * detRecip;
+ dst[6] = ( ma[4]*ma[2] - ma[0]*ma[6] ) * detRecip;
+
+ dst[8] = ( ma[4]*ma[9] - ma[8]*ma[5] ) * detRecip;
+ dst[9] = ( ma[8]*ma[1] - ma[0]*ma[9] ) * detRecip;
+ dst[10] = ( ma[0]*ma[5] - ma[1]*ma[4] ) * detRecip;
+
+ return det;
+}
+
+
+/* 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*/
+
+/*
+ * 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, returns a boolean status */
+ODE_API int dOrthogonalizeR(dMatrix3 m);
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/libs/ode-0.16.1/include/ode/odemath_legacy.h b/libs/ode-0.16.1/include/ode/odemath_legacy.h
new file mode 100644
index 0000000..a389588
--- /dev/null
+++ b/libs/ode-0.16.1/include/ode/odemath_legacy.h
@@ -0,0 +1,162 @@
+/*************************************************************************
+ * *
+ * 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/libs/ode-0.16.1/include/ode/precision.h b/libs/ode-0.16.1/include/ode/precision.h
new file mode 100644
index 0000000..456fc36
--- /dev/null
+++ b/libs/ode-0.16.1/include/ode/precision.h
@@ -0,0 +1,16 @@
+#ifndef _ODE_PRECISION_H_
+#define _ODE_PRECISION_H_
+
+/* Define dSINGLE for single precision, dDOUBLE for double precision,
+ * but never both!
+ */
+
+#if defined(dIDESINGLE)
+#define dSINGLE
+#elif defined(dIDEDOUBLE)
+#define dDOUBLE
+#else
+#define dSINGLE
+#endif
+
+#endif
diff --git a/libs/ode-0.16.1/include/ode/precision.h.in b/libs/ode-0.16.1/include/ode/precision.h.in
new file mode 100644
index 0000000..47f3c95
--- /dev/null
+++ b/libs/ode-0.16.1/include/ode/precision.h.in
@@ -0,0 +1,16 @@
+#ifndef _ODE_PRECISION_H_
+#define _ODE_PRECISION_H_
+
+/* Define dSINGLE for single precision, dDOUBLE for double precision,
+ * but never both!
+ */
+
+#if defined(dIDESINGLE)
+#define dSINGLE
+#elif defined(dIDEDOUBLE)
+#define dDOUBLE
+#else
+#define @ODE_PRECISION@
+#endif
+
+#endif
diff --git a/libs/ode-0.16.1/include/ode/rotation.h b/libs/ode-0.16.1/include/ode/rotation.h
new file mode 100644
index 0000000..a72be27
--- /dev/null
+++ b/libs/ode-0.16.1/include/ode/rotation.h
@@ -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/libs/ode-0.16.1/include/ode/threading.h b/libs/ode-0.16.1/include/ode/threading.h
new file mode 100644
index 0000000..9602b8f
--- /dev/null
+++ b/libs/ode-0.16.1/include/ode/threading.h
@@ -0,0 +1,412 @@
+/*************************************************************************
+ * *
+ * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. *
+ * All rights reserved. Email: russ@q12.org Web: www.q12.org *
+ * *
+ * Threading support header file. *
+ * Copyright (C) 2011-2019 Oleh Derevenko. All rights reserved. *
+ * e-mail: odar@eleks.com (change all "a" to "e") *
+ * *
+ * 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. *
+ * *
+ *************************************************************************/
+
+/*
+ * ODE threading support interfaces
+ */
+
+
+#ifndef _ODE_THREADING_H_
+#define _ODE_THREADING_H_
+
+#include <ode/odeconfig.h>
+// Include <time.h> since time_t is used and it is not available by default in some OSes
+#include <time.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+struct dxThreadingImplementation;
+typedef struct dxThreadingImplementation *dThreadingImplementationID;
+
+typedef unsigned dmutexindex_t;
+struct dxMutexGroup;
+typedef struct dxMutexGroup *dMutexGroupID;
+
+
+#define dTHREADING_THREAD_COUNT_UNLIMITED 0U
+
+
+
+/**
+ * @brief Allocates a group of muteces.
+ *
+ * The Mutex allocated do not need to support recursive locking.
+ *
+ * The Mutex names are provided to aid in debugging and thread state tracking.
+ *
+ * @param impl Threading implementation ID
+ * @param Mutex_count Number of Mutex to create
+ * @Mutex_names_ptr Pointer to optional Mutex names array to be associated with individual Mutex
+ * @returns MutexGroup ID or NULL if error occurred.
+ *
+ * @ingroup threading
+ * @see dMutexGroupFreeFunction
+ * @see dMutexGroupMutexLockFunction
+ * @see dMutexGroupMutexUnlockFunction
+ */
+typedef dMutexGroupID dMutexGroupAllocFunction (dThreadingImplementationID impl, dmutexindex_t Mutex_count, const char *const *Mutex_names_ptr/*=NULL*/);
+
+/**
+ * @brief Deletes a group of muteces.
+ *
+ * @param impl Threading implementation ID
+ * @param mutex_group Mutex group to deallocate
+ *
+ * @ingroup threading
+ * @see dMutexGroupAllocFunction
+ * @see dMutexGroupMutexLockFunction
+ * @see dMutexGroupMutexUnlockFunction
+ */
+typedef void dMutexGroupFreeFunction (dThreadingImplementationID impl, dMutexGroupID mutex_group);
+
+/**
+ * @brief Locks a mutex in a group of muteces.
+ *
+ * The function is to block execution until requested mutex can be locked.
+ *
+ * Note: Mutex provided may not support recursive locking. Calling this function
+ * while mutex is already locked by current thread will result in unpredictable behavior.
+ *
+ * @param impl Threading implementation ID
+ * @param mutex_group Mutex group to use for locking
+ * @param mutex_index The index of mutex to be locked (0..Mutex_count - 1)
+ *
+ * @ingroup threading
+ * @see dMutexGroupAllocFunction
+ * @see dMutexGroupFreeFunction
+ * @see dMutexGroupMutexUnlockFunction
+ */
+typedef void dMutexGroupMutexLockFunction (dThreadingImplementationID impl, dMutexGroupID mutex_group, dmutexindex_t mutex_index);
+
+/**
+ * @brief Attempts to lock a mutex in a group of muteces.
+ *
+ * The function is to lock the requested mutex if it is unoccupied or
+ * immediately return failure if mutex is already locked by other thread.
+ *
+ * Note: Mutex provided may not support recursive locking. Calling this function
+ * while mutex is already locked by current thread will result in unpredictable behavior.
+ *
+ * @param impl Threading implementation ID
+ * @param mutex_group Mutex group to use for locking
+ * @param mutex_index The index of mutex to be locked (0..Mutex_count - 1)
+ * @returns 1 for success (mutex is locked) and 0 for failure (mutex is not locked)
+ *
+ * @ingroup threading
+ * @see dMutexGroupAllocFunction
+ * @see dMutexGroupFreeFunction
+ * @see dMutexGroupMutexLockFunction
+ * @see dMutexGroupMutexUnlockFunction
+ */
+/* typedef int dMutexGroupMutexTryLockFunction (dThreadingImplementationID impl, dMutexGroupID mutex_group, dmutexindex_t mutex_index);*/
+
+/**
+ * @brief Unlocks a mutex in a group of muteces.
+ *
+ * The function is to unlock the given mutex provided it had been locked before.
+ *
+ * @param impl Threading implementation ID
+ * @param mutex_group Mutex group to use for unlocking
+ * @param mutex_index The index of mutex to be unlocked (0..Mutex_count - 1)
+ *
+ * @ingroup threading
+ * @see dMutexGroupAllocFunction
+ * @see dMutexGroupFreeFunction
+ * @see dMutexGroupMutexLockFunction
+ */
+typedef void dMutexGroupMutexUnlockFunction (dThreadingImplementationID impl, dMutexGroupID mutex_group, dmutexindex_t mutex_index);
+
+
+struct dxCallReleasee;
+typedef struct dxCallReleasee *dCallReleaseeID;
+
+struct dxCallWait;
+typedef struct dxCallWait *dCallWaitID;
+
+typedef dsizeint ddependencycount_t;
+typedef ddiffint ddependencychange_t;
+typedef dsizeint dcallindex_t;
+typedef int dThreadedCallFunction(void *call_context, dcallindex_t instance_index,
+ dCallReleaseeID this_releasee);
+
+typedef struct dxThreadedWaitTime
+{
+ time_t wait_sec;
+ unsigned long wait_nsec;
+
+} dThreadedWaitTime;
+
+
+/**
+ * @brief Allocates a Wait ID that can be used to wait for a call.
+ *
+ * @param impl Threading implementation ID
+ * @returns Wait ID or NULL if error occurred
+ *
+ * @ingroup threading
+ * @see dThreadedCallWaitResetFunction
+ * @see dThreadedCallWaitFreeFunction
+ * @see dThreadedCallPostFunction
+ * @see dThreadedCallWaitFunction
+ */
+typedef dCallWaitID dThreadedCallWaitAllocFunction(dThreadingImplementationID impl);
+
+/**
+ * @brief Resets a Wait ID so that it could be used to wait for another call.
+ *
+ * @param impl Threading implementation ID
+ * @param call_wait Wait ID to reset
+ *
+ * @ingroup threading
+ * @see dThreadedCallWaitAllocFunction
+ * @see dThreadedCallWaitFreeFunction
+ * @see dThreadedCallPostFunction
+ * @see dThreadedCallWaitFunction
+ */
+typedef void dThreadedCallWaitResetFunction(dThreadingImplementationID impl, dCallWaitID call_wait);
+
+/**
+ * @brief Frees a Wait ID.
+ *
+ * @param impl Threading implementation ID
+ * @param call_wait Wait ID to delete
+ *
+ * @ingroup threading
+ * @see dThreadedCallWaitAllocFunction
+ * @see dThreadedCallPostFunction
+ * @see dThreadedCallWaitFunction
+ */
+typedef void dThreadedCallWaitFreeFunction(dThreadingImplementationID impl, dCallWaitID call_wait);
+
+
+/**
+ * @brief Post a function to be called in another thread.
+ *
+ * A call is scheduled to be executed asynchronously.
+ *
+ * A @a out_summary_fault variable can be provided for call to accumulate any
+ * possible faults from its execution and execution of any possible sub-calls.
+ * This variable gets result that @a call_func returns. Also, if dependent calls
+ * are executed after the call already exits, the variable is also going to be
+ * updated with results of all those calls before control is released to master.
+ *
+ * @a out_post_releasee parameter receives a value of @c dCallReleaseeID that can
+ * later be used for @a dependent_releasee while scheduling sub-calls to make
+ * current call depend on them. The value is only returned if @a dependencies_count
+ * is not zero (i.e. if any dependencies are expected at all). The call is not going
+ * to start until all its dependencies complete.
+ *
+ * In case if number of dependencies is unknown in advance 1 can be passed on call
+ * scheduling. Then @c dThreadedCallDependenciesCountAlterFunction can be used to
+ * add one more extra dependencies before scheduling each subcall. And then, after
+ * all sub-calls had been scheduled, @c dThreadedCallDependenciesCountAlterFunction
+ * can be used again to subtract initial extra dependency from total number.
+ * Adding one dependency in advance is necessary to obtain releasee ID and to make
+ * sure the call will not start and will not terminate before all sub-calls are scheduled.
+ *
+ * Extra dependencies can also be added from the call itself after it has already
+ * been started (with parameter received in @c dThreadedCallFunction).
+ * In that case those dependencies will start immediately or after call returns
+ * but the call's master will not be released/notified until all additional
+ * dependencies complete. This can be used to schedule sub-calls from a call and
+ * then pass own job to another sub-call dependent on those initial sub-calls.
+ *
+ * By using @ call_wait it is possible to assign a Wait ID that can later
+ * be passed into @c dThreadedCallWaitFunction to wait for call completion.
+ *
+ * If @a call_name is available (and it should!) the string must remain valid until
+ * after call completion. In most cases this should be a static string literal.
+ *
+ * Since the function is an analogue of normal method call it is not supposed to fail.
+ * Any complications with resource allocation on call scheduling should be
+ * anticipated, avoided and worked around by implementation.
+ *
+ * @param impl Threading implementation ID
+ * @param out_summary_fault Optional pointer to variable to be set to 1 if function
+ * call (or any sub-call) fails internally, or 0 if all calls return success
+ * @param out_post_releasee Optional pointer to variable to receive releasee ID
+ * associated with the call
+ * @param dependencies_count Number of dependencies that are going to reference
+ * this call as dependent releasee
+ * @param dependent_releasee Optional releasee ID to reference with this call
+ * @param call_wait Optional Wait ID that can later be used to wait for the call
+ * @param call_func Pointer to function to be called
+ * @param call_context Context parameter to be passed into the call
+ * @param instance_index Index parameter to be passed into the call
+ * @param call_name Optional name to be associated with the call (for debugging and state tracking)
+ *
+ * @ingroup threading
+ * @see dThreadedCallWaitFunction
+ * @see dThreadedCallDependenciesCountAlterFunction
+ * @see dThreadingImplResourcesForCallsPreallocateFunction
+ */
+typedef void dThreadedCallPostFunction(dThreadingImplementationID impl, int *out_summary_fault/*=NULL*/,
+ dCallReleaseeID *out_post_releasee/*=NULL*/, ddependencycount_t dependencies_count, dCallReleaseeID dependent_releasee/*=NULL*/,
+ dCallWaitID call_wait/*=NULL*/,
+ dThreadedCallFunction *call_func, void *call_context, dcallindex_t instance_index,
+ const char *call_name/*=NULL*/);
+
+/**
+ * @brief Add or remove extra dependencies from call that has been scheduled
+ * or is in process of execution.
+ *
+ * Extra dependencies can be added to a call if exact number of sub-calls is
+ * not known in advance at the moment the call is scheduled. Also, some dependencies
+ * can be removed if sub-calls were planned but then dropped.
+ *
+ * In case if total dependency count of a call reaches zero by result of invoking
+ * this function, the call is free to start executing immediately.
+ *
+ * After the call execution had been started, any additional dependencies can only
+ * be added from the call function itself!
+ *
+ * @param impl Threading implementation ID
+ * @param target_releasee ID of releasee to apply dependencies count change to
+ * @param dependencies_count_change Number of dependencies to add or remove
+ *
+ * @ingroup threading
+ * @see dThreadedCallPostFunction
+ */
+typedef void dThreadedCallDependenciesCountAlterFunction(dThreadingImplementationID impl, dCallReleaseeID target_releasee,
+ ddependencychange_t dependencies_count_change);
+
+/**
+ * @brief Wait for a posted call to complete.
+ *
+ * Function blocks until a call identified by @a call_wait completes or
+ * timeout elapses.
+ *
+ * IT IS ILLEGAL TO INVOKE THIS FUNCTION FROM WITHIN A THREADED CALL!
+ * This is because doing so will block a physical thread and will require
+ * increasing worker thread count to avoid starvation. Use call dependencies
+ * if it is necessary make sure sub-calls have been completed instead!
+ *
+ * If @a timeout_time_ptr is NULL, the function waits without time limit. If @a timeout_time_ptr
+ * points to zero value, the function only checks status and does not block.
+ *
+ * If @a wait_name is available (and it should!) the string must remain valid for
+ * the duration of wait. In most cases this should be a static string literal.
+ *
+ * Function is not expected to return failures caused by system call faults as
+ * those are hardly ever possible to be handled in this case anyway. In event of
+ * system call fault the function is supposed to terminate application.
+ *
+ * @param impl Threading implementation ID
+ * @param out_wait_status Optional pointer to variable to receive 1 if waiting succeeded
+ * or 0 in case of timeout
+ * @param call_wait Wait ID that had been passed to scheduling a call that needs to be waited for
+ * @param timeout_time_ptr Optional pointer to time specification the wait must not
+ * last longer than (pass NULL for infinite timeout)
+ * @param wait_name Optional name to be associated with the wait (for debugging and state tracking)
+ *
+ * @ingroup threading
+ * @see dThreadedCallPostFunction
+ */
+typedef void dThreadedCallWaitFunction(dThreadingImplementationID impl, int *out_wait_status/*=NULL*/,
+ dCallWaitID call_wait, const dThreadedWaitTime *timeout_time_ptr/*=NULL*/,
+ const char *wait_name/*=NULL*/);
+
+/**
+ * @brief Retrieve number of active threads that serve the implementation.
+ *
+ * @param impl Threading implementation ID
+ * @returns Number of active threads
+ *
+ * @ingroup threading
+ */
+typedef unsigned dThreadingImplThreadCountRetrieveFunction(dThreadingImplementationID impl);
+
+/**
+ * @brief Preallocate resources to handle posted calls.
+ *
+ * The function is intended to make sure enough resources is preallocated for the
+ * implementation to be able to handle posted calls. Then @c max_simultaneous_calls_estimate
+ * is an estimate of how many posted calls can potentially be active or scheduled
+ * at the same time. The value is usually derived from the way the calls are posted
+ * in library code and dependencies between them.
+ *
+ * @warning While working on an implementation be prepared that the estimate provided
+ * yet rarely but theoretically can be exceeded due to unpredictability of thread execution.
+ *
+ * This function is normally going to be invoked by library each time it is entered
+ * from outside to do the job but before any threaded calls are going to be posted.
+ *
+ * @param impl Threading implementation ID
+ * @param max_simultaneous_calls_estimate An estimated number of calls that can be posted simultaneously
+ * @returns 1 or 0 to indicate success or failure
+ *
+ * @ingroup threading
+ * @see dThreadedCallPostFunction
+ */
+typedef int dThreadingImplResourcesForCallsPreallocateFunction(dThreadingImplementationID impl,
+ ddependencycount_t max_simultaneous_calls_estimate);
+
+
+/**
+ * @brief An interface structure with function pointers to be provided by threading implementation.
+ */
+typedef struct dxThreadingFunctionsInfo
+{
+ unsigned struct_size;
+
+ dMutexGroupAllocFunction *alloc_mutex_group;
+ dMutexGroupFreeFunction *free_mutex_group;
+ dMutexGroupMutexLockFunction *lock_group_mutex;
+ dMutexGroupMutexUnlockFunction *unlock_group_mutex;
+
+ dThreadedCallWaitAllocFunction *alloc_call_wait;
+ dThreadedCallWaitResetFunction *reset_call_wait;
+ dThreadedCallWaitFreeFunction *free_call_wait;
+
+ dThreadedCallPostFunction *post_call;
+ dThreadedCallDependenciesCountAlterFunction *alter_call_dependencies_count;
+ dThreadedCallWaitFunction *wait_call;
+
+ dThreadingImplThreadCountRetrieveFunction *retrieve_thread_count;
+ dThreadingImplResourcesForCallsPreallocateFunction *preallocate_resources_for_calls;
+
+ /*
+ * Beware of Jon Watte's anger if you dare to uncomment this!
+ * May cryptic text below be you a warning!
+ * Стародавні легенди розказують, що кожного сміливця, хто наважиться порушити табу
+ * і відкрити заборонений код, спіткає страшне прокляття і він відразу почне робити
+ * одні лиш помилки.
+ *
+ * dMutexGroupMutexTryLockFunction *trylock_group_mutex;
+ */
+
+} dThreadingFunctionsInfo;
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* #ifndef _ODE_THREADING_H_ */
diff --git a/libs/ode-0.16.1/include/ode/threading_impl.h b/libs/ode-0.16.1/include/ode/threading_impl.h
new file mode 100644
index 0000000..0781d6a
--- /dev/null
+++ b/libs/ode-0.16.1/include/ode/threading_impl.h
@@ -0,0 +1,292 @@
+/*************************************************************************
+ * *
+ * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. *
+ * All rights reserved. Email: russ@q12.org Web: www.q12.org *
+ * *
+ * Builtin ODE threading implementation header. *
+ * Copyright (C) 2011-2019 Oleh Derevenko. All rights reserved. *
+ * e-mail: odar@eleks.com (change all "a" to "e") *
+ * *
+ * 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. *
+ * *
+ *************************************************************************/
+
+/*
+ * A threading implementation built into ODE for those who does not care to
+ * or can't implement an own one.
+ */
+
+#ifndef _ODE_THREADING_IMPL_H_
+#define _ODE_THREADING_IMPL_H_
+
+
+#include <ode/odeconfig.h>
+#include <ode/threading.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+struct dxThreadingThreadPool;
+typedef struct dxThreadingThreadPool *dThreadingThreadPoolID;
+
+
+/**
+ * @brief Allocates built-in self-threaded threading implementation object.
+ *
+ * A self-threaded implementation is a type of implementation that performs
+ * processing of posted calls by means of caller thread itself. This type of
+ * implementation does not need thread pool to serve it.
+ *
+ * Note that since May 9th, 2017 (rev. #2066) the Self-Threaded implementation
+ * returns 0 rather than 1 as available thread count to distinguish from
+ * thread pools with just one thread in them.
+ *
+ * The processing is arranged in a way to prevent call stack depth growth
+ * as more and more nested calls are posted.
+ *
+ * Note that it is not necessary to create and assign a self-threaded
+ * implementation to a world, as there is a global one used by default
+ * if no implementation is explicitly assigned. You should only assign
+ * each world an individual threading implementation instance if simulations
+ * need to be run in parallel in multiple threads for the worlds.
+ *
+ * @returns ID of object allocated or NULL on failure
+ *
+ * @ingroup threading
+ * @see dThreadingAllocateMultiThreadedImplementation
+ * @see dThreadingFreeImplementation
+ */
+ODE_API dThreadingImplementationID dThreadingAllocateSelfThreadedImplementation();
+
+/**
+ * @brief Allocates built-in multi-threaded threading implementation object.
+ *
+ * A multi-threaded implementation is a type of implementation that has to be
+ * served with a thread pool. The thread pool can be either the built-in ODE object
+ * or set of external threads that dedicate themselves to this purpose and stay
+ * in ODE until implementation releases them.
+ *
+ * @returns ID of object allocated or NULL on failure
+ *
+ * @ingroup threading
+ * @see dThreadingThreadPoolServeMultiThreadedImplementation
+ * @see dExternalThreadingServeMultiThreadedImplementation
+ * @see dThreadingFreeImplementation
+ */
+ODE_API dThreadingImplementationID dThreadingAllocateMultiThreadedImplementation();
+
+/**
+ * @brief Retrieves the functions record of a built-in threading implementation.
+ *
+ * The implementation can be the one allocated by ODE (from @c dThreadingAllocateMultiThreadedImplementation).
+ * Do not use this function with self-made custom implementations -
+ * they should be bundled with their own set of functions.
+ *
+ * @param impl Threading implementation ID
+ * @returns Pointer to associated functions structure
+ *
+ * @ingroup threading
+ * @see dThreadingAllocateMultiThreadedImplementation
+ */
+ODE_API const dThreadingFunctionsInfo *dThreadingImplementationGetFunctions(dThreadingImplementationID impl);
+
+/**
+ * @brief Requests a built-in implementation to release threads serving it.
+ *
+ * The function unblocks threads employed in implementation serving and lets them
+ * return to from where they originate. It's the responsibility of external code
+ * to make sure all the calls to ODE that might be dependent on given threading
+ * implementation object had already returned before this call is made. If threading
+ * implementation is still processing some posted calls while this function is
+ * invoked the behavior is implementation dependent.
+ *
+ * This call is to be used to request the threads to be released before waiting
+ * for them in host pool or before waiting for them to exit. Implementation object
+ * must not be destroyed before it is known that all the serving threads have already
+ * returned from it. If implementation needs to be reused after this function is called
+ * and all the threads have exited from it a call to @c dThreadingImplementationCleanupForRestart
+ * must be made to restore internal state of the object.
+ *
+ * If this function is called for self-threaded built-in threading implementation
+ * the call has no effect.
+ *
+ * @param impl Threading implementation ID
+ *
+ * @ingroup threading
+ * @see dThreadingAllocateMultiThreadedImplementation
+ * @see dThreadingImplementationCleanupForRestart
+ */
+ODE_API void dThreadingImplementationShutdownProcessing(dThreadingImplementationID impl);
+
+/**
+ * @brief Restores built-in implementation's state to let it be reused after shutdown.
+ *
+ * If a multi-threaded built-in implementation needs to be reused after a call
+ * to @c dThreadingImplementationShutdownProcessing this call is to be made to
+ * restore object's internal state. After that the implementation can be served again.
+ *
+ * If this function is called for self-threaded built-in threading implementation
+ * the call has no effect.
+ *
+ * @param impl Threading implementation ID
+ *
+ * @ingroup threading
+ * @see dThreadingAllocateMultiThreadedImplementation
+ * @see dThreadingImplementationShutdownProcessing
+ */
+ODE_API void dThreadingImplementationCleanupForRestart(dThreadingImplementationID impl);
+
+/**
+ * @brief Deletes an instance of built-in threading implementation.
+ *
+ * @warning A care must be taken to make sure the implementation is unassigned
+ * from all the objects it was assigned to and that there are no more threads
+ * serving it before attempting to call this function.
+ *
+ * @param impl Threading implementation ID
+ *
+ * @ingroup threading
+ * @see dThreadingAllocateMultiThreadedImplementation
+ */
+ODE_API void dThreadingFreeImplementation(dThreadingImplementationID impl);
+
+
+typedef void (dThreadReadyToServeCallback)(void *callback_context);
+
+/**
+ * @brief An entry point for external threads that would like to serve a built-in
+ * threading implementation object.
+ *
+ * A thread that calls this function remains blocked in ODE and serves implementation
+ * object @p impl until being released with @c dThreadingImplementationShutdownProcessing call.
+ * This function can be used to provide external threads instead of ODE's built-in
+ * thread pools.
+ *
+ * The optional callback @readiness_callback is called after the thread has reached
+ * and has registered within the implementation. The implementation should not
+ * be used until all dedicated threads register within it as otherwise it will not
+ * have accurate view of the execution resources available.
+ *
+ * @param impl Threading implementation ID
+ * @param readiness_callback Optional readiness callback to be called after thread enters the implementation
+ * @param callback_context A value to be passed as parameter to readiness callback
+ *
+ * @ingroup threading
+ * @see dThreadingAllocateMultiThreadedImplementation
+ * @see dThreadingImplementationShutdownProcessing
+ */
+ODE_API void dExternalThreadingServeMultiThreadedImplementation(dThreadingImplementationID impl,
+ dThreadReadyToServeCallback *readiness_callback/*=NULL*/, void *callback_context/*=NULL*/);
+
+
+/**
+ * @brief Creates an instance of built-in thread pool object that can be used to serve
+ * multi-threaded threading implementations.
+ *
+ * The threads allocated inherit priority of caller thread. Their affinity is not
+ * explicitly adjusted and gets the value the system assigns by default. Threads
+ * have their stack memory fully committed immediately on start. On POSIX platforms
+ * threads are started with all the possible signals blocked. Threads execute
+ * calls to @c dAllocateODEDataForThread with @p ode_data_allocate_flags
+ * on initialization.
+ *
+ * On POSIX platforms this function must be called with signals masked
+ * or other measures must be taken to prevent reception of signals by calling thread
+ * for the duration of the call.
+ *
+ * @param thread_count Number of threads to start in pool
+ * @param stack_size Size of stack to be used for every thread or 0 for system default value
+ * @param ode_data_allocate_flags Flags to be passed to @c dAllocateODEDataForThread on behalf of each thread
+ * @returns ID of object allocated or NULL on failure
+ *
+ * @ingroup threading
+ * @see dThreadingAllocateMultiThreadedImplementation
+ * @see dThreadingImplementationShutdownProcessing
+ * @see dThreadingFreeThreadPool
+ */
+ODE_API dThreadingThreadPoolID dThreadingAllocateThreadPool(unsigned thread_count,
+ dsizeint stack_size, unsigned int ode_data_allocate_flags, void *reserved/*=NULL*/);
+
+/**
+ * @brief Commands an instance of built-in thread pool to serve a built-in multi-threaded
+ * threading implementation.
+ *
+ * A pool can only serve one threading implementation at a time.
+ * Call @c dThreadingImplementationShutdownProcessing to release pool threads
+ * from implementation serving and make them idle. Pool threads must be released
+ * from any implementations before pool is attempted to be deleted.
+ *
+ * This function waits for threads to register within implementation before returning.
+ * So, after the function call exits the implementation can be used immediately.
+ *
+ * @param pool Thread pool ID to serve the implementation
+ * @param impl Implementation ID of implementation to be served
+ *
+ * @ingroup threading
+ * @see dThreadingAllocateThreadPool
+ * @see dThreadingAllocateMultiThreadedImplementation
+ * @see dThreadingImplementationShutdownProcessing
+ */
+ODE_API void dThreadingThreadPoolServeMultiThreadedImplementation(dThreadingThreadPoolID pool, dThreadingImplementationID impl);
+
+/**
+ * @brief Waits until all pool threads are released from threading implementation
+ * they might be serving.
+ *
+ * The function can be used after a call to @c dThreadingImplementationShutdownProcessing
+ * to make sure all the threads have already been released by threading implementation
+ * and it can be deleted or it can be cleaned up for restart and served by another pool
+ * or this pool's threads can be used to serve another threading implementation.
+ *
+ * Note that is it not necessary to call this function before pool destruction
+ * since @c dThreadingFreeThreadPool performs similar wait operation implicitly on its own.
+ *
+ * It is OK to call this function even if pool was not serving any threading implementation
+ * in which case the call exits immediately with minimal delay.
+ *
+ * @param pool Thread pool ID to wait for
+ *
+ * @ingroup threading
+ * @see dThreadingAllocateThreadPool
+ * @see dThreadingImplementationShutdownProcessing
+ * @see dThreadingFreeThreadPool
+ */
+ODE_API void dThreadingThreadPoolWaitIdleState(dThreadingThreadPoolID pool);
+
+/**
+ * @brief Deletes a built-in thread pool instance.
+ *
+ * The pool threads must be released from any implementations they might be serving
+ * before this function is called. Otherwise the call is going to block
+ * and wait until pool's threads return.
+ *
+ * @param pool Thread pool ID to delete
+ *
+ * @ingroup threading
+ * @see dThreadingAllocateThreadPool
+ * @see dThreadingImplementationShutdownProcessing
+ */
+ODE_API void dThreadingFreeThreadPool(dThreadingThreadPoolID pool);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* #ifndef _ODE_THREADING_IMPL_H_ */
diff --git a/libs/ode-0.16.1/include/ode/timer.h b/libs/ode-0.16.1/include/ode/timer.h
new file mode 100644
index 0000000..fe1483f
--- /dev/null
+++ b/libs/ode-0.16.1/include/ode/timer.h
@@ -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
diff --git a/libs/ode-0.16.1/include/ode/version.h b/libs/ode-0.16.1/include/ode/version.h
new file mode 100644
index 0000000..980217e
--- /dev/null
+++ b/libs/ode-0.16.1/include/ode/version.h
@@ -0,0 +1,6 @@
+#ifndef _ODE_VERSION_H_
+#define _ODE_VERSION_H_
+
+#define dODE_VERSION "0.16.1"
+
+#endif
diff --git a/libs/ode-0.16.1/include/ode/version.h.in b/libs/ode-0.16.1/include/ode/version.h.in
new file mode 100644
index 0000000..b5d3c81
--- /dev/null
+++ b/libs/ode-0.16.1/include/ode/version.h.in
@@ -0,0 +1,6 @@
+#ifndef _ODE_VERSION_H_
+#define _ODE_VERSION_H_
+
+#define dODE_VERSION "@ODE_VERSION@"
+
+#endif