summaryrefslogtreecommitdiff
path: root/libs/ode-0.16.1/tests
diff options
context:
space:
mode:
Diffstat (limited to 'libs/ode-0.16.1/tests')
-rw-r--r--libs/ode-0.16.1/tests/Makefile.am30
-rw-r--r--libs/ode-0.16.1/tests/Makefile.in1116
-rw-r--r--libs/ode-0.16.1/tests/UnitTest++/COPYING20
-rw-r--r--libs/ode-0.16.1/tests/UnitTest++/Makefile.am6
-rw-r--r--libs/ode-0.16.1/tests/UnitTest++/Makefile.in643
-rw-r--r--libs/ode-0.16.1/tests/UnitTest++/README62
-rw-r--r--libs/ode-0.16.1/tests/UnitTest++/docs/UnitTest++.html260
-rw-r--r--libs/ode-0.16.1/tests/UnitTest++/src/AssertException.cpp32
-rw-r--r--libs/ode-0.16.1/tests/UnitTest++/src/AssertException.h28
-rw-r--r--libs/ode-0.16.1/tests/UnitTest++/src/CheckMacros.h102
-rw-r--r--libs/ode-0.16.1/tests/UnitTest++/src/Checks.cpp48
-rw-r--r--libs/ode-0.16.1/tests/UnitTest++/src/Checks.h146
-rw-r--r--libs/ode-0.16.1/tests/UnitTest++/src/Config.h25
-rw-r--r--libs/ode-0.16.1/tests/UnitTest++/src/DeferredTestReporter.cpp28
-rw-r--r--libs/ode-0.16.1/tests/UnitTest++/src/DeferredTestReporter.h28
-rw-r--r--libs/ode-0.16.1/tests/UnitTest++/src/DeferredTestResult.cpp26
-rw-r--r--libs/ode-0.16.1/tests/UnitTest++/src/DeferredTestResult.h29
-rw-r--r--libs/ode-0.16.1/tests/UnitTest++/src/Makefile.am33
-rw-r--r--libs/ode-0.16.1/tests/UnitTest++/src/Makefile.in784
-rw-r--r--libs/ode-0.16.1/tests/UnitTest++/src/MemoryOutStream.cpp143
-rw-r--r--libs/ode-0.16.1/tests/UnitTest++/src/MemoryOutStream.h67
-rw-r--r--libs/ode-0.16.1/tests/UnitTest++/src/Posix/Makefile.am5
-rw-r--r--libs/ode-0.16.1/tests/UnitTest++/src/Posix/Makefile.in627
-rw-r--r--libs/ode-0.16.1/tests/UnitTest++/src/Posix/SignalTranslator.cpp46
-rw-r--r--libs/ode-0.16.1/tests/UnitTest++/src/Posix/SignalTranslator.h42
-rw-r--r--libs/ode-0.16.1/tests/UnitTest++/src/Posix/TimeHelpers.cpp33
-rw-r--r--libs/ode-0.16.1/tests/UnitTest++/src/Posix/TimeHelpers.h28
-rw-r--r--libs/ode-0.16.1/tests/UnitTest++/src/ReportAssert.cpp10
-rw-r--r--libs/ode-0.16.1/tests/UnitTest++/src/ReportAssert.h10
-rw-r--r--libs/ode-0.16.1/tests/UnitTest++/src/Test.cpp62
-rw-r--r--libs/ode-0.16.1/tests/UnitTest++/src/Test.h34
-rw-r--r--libs/ode-0.16.1/tests/UnitTest++/src/TestDetails.cpp22
-rw-r--r--libs/ode-0.16.1/tests/UnitTest++/src/TestDetails.h24
-rw-r--r--libs/ode-0.16.1/tests/UnitTest++/src/TestList.cpp39
-rw-r--r--libs/ode-0.16.1/tests/UnitTest++/src/TestList.h32
-rw-r--r--libs/ode-0.16.1/tests/UnitTest++/src/TestMacros.h99
-rw-r--r--libs/ode-0.16.1/tests/UnitTest++/src/TestReporter.cpp10
-rw-r--r--libs/ode-0.16.1/tests/UnitTest++/src/TestReporter.h20
-rw-r--r--libs/ode-0.16.1/tests/UnitTest++/src/TestReporterStdout.cpp36
-rw-r--r--libs/ode-0.16.1/tests/UnitTest++/src/TestReporterStdout.h19
-rw-r--r--libs/ode-0.16.1/tests/UnitTest++/src/TestResults.cpp60
-rw-r--r--libs/ode-0.16.1/tests/UnitTest++/src/TestResults.h36
-rw-r--r--libs/ode-0.16.1/tests/UnitTest++/src/TestRunner.cpp60
-rw-r--r--libs/ode-0.16.1/tests/UnitTest++/src/TestRunner.h17
-rw-r--r--libs/ode-0.16.1/tests/UnitTest++/src/TestSuite.h14
-rw-r--r--libs/ode-0.16.1/tests/UnitTest++/src/TimeConstraint.cpp28
-rw-r--r--libs/ode-0.16.1/tests/UnitTest++/src/TimeConstraint.h34
-rw-r--r--libs/ode-0.16.1/tests/UnitTest++/src/TimeHelpers.h7
-rw-r--r--libs/ode-0.16.1/tests/UnitTest++/src/UnitTest++.h17
-rw-r--r--libs/ode-0.16.1/tests/UnitTest++/src/Win32/Makefile.am4
-rw-r--r--libs/ode-0.16.1/tests/UnitTest++/src/Win32/Makefile.in624
-rw-r--r--libs/ode-0.16.1/tests/UnitTest++/src/Win32/TimeHelpers.cpp46
-rw-r--r--libs/ode-0.16.1/tests/UnitTest++/src/Win32/TimeHelpers.h48
-rw-r--r--libs/ode-0.16.1/tests/UnitTest++/src/XmlTestReporter.cpp126
-rw-r--r--libs/ode-0.16.1/tests/UnitTest++/src/XmlTestReporter.h34
-rw-r--r--libs/ode-0.16.1/tests/collision.cpp224
-rw-r--r--libs/ode-0.16.1/tests/friction.cpp176
-rw-r--r--libs/ode-0.16.1/tests/joint.cpp3054
-rw-r--r--libs/ode-0.16.1/tests/joints/Makefile.am21
-rw-r--r--libs/ode-0.16.1/tests/joints/Makefile.in638
-rw-r--r--libs/ode-0.16.1/tests/joints/amotor.cpp324
-rw-r--r--libs/ode-0.16.1/tests/joints/ball.cpp160
-rw-r--r--libs/ode-0.16.1/tests/joints/dball.cpp81
-rw-r--r--libs/ode-0.16.1/tests/joints/fixed.cpp149
-rw-r--r--libs/ode-0.16.1/tests/joints/hinge.cpp928
-rw-r--r--libs/ode-0.16.1/tests/joints/hinge2.cpp167
-rw-r--r--libs/ode-0.16.1/tests/joints/piston.cpp1456
-rw-r--r--libs/ode-0.16.1/tests/joints/pr.cpp1160
-rw-r--r--libs/ode-0.16.1/tests/joints/pu.cpp920
-rw-r--r--libs/ode-0.16.1/tests/joints/slider.cpp1332
-rw-r--r--libs/ode-0.16.1/tests/joints/universal.cpp2119
-rw-r--r--libs/ode-0.16.1/tests/main.cpp13
-rw-r--r--libs/ode-0.16.1/tests/odemath.cpp247
73 files changed, 19178 insertions, 0 deletions
diff --git a/libs/ode-0.16.1/tests/Makefile.am b/libs/ode-0.16.1/tests/Makefile.am
new file mode 100644
index 0000000..7ed8620
--- /dev/null
+++ b/libs/ode-0.16.1/tests/Makefile.am
@@ -0,0 +1,30 @@
+SUBDIRS = joints UnitTest++
+
+AM_CPPFLAGS = -I$(srcdir)/UnitTest++/src \
+ -I$(top_srcdir)/include \
+ -I$(top_builddir)/include \
+ -I$(top_srcdir)/ode/src
+
+if GIMPACT
+ AM_CPPFLAGS += -DdTRIMESH_ENABLED -DdTRIMESH_GIMPACT
+endif
+if OPCODE
+ AM_CPPFLAGS += -DdTRIMESH_ENABLED -DdTRIMESH_OPCODE
+endif
+
+
+check_PROGRAMS = tests
+
+TESTS = tests
+
+tests_SOURCES = \
+ collision.cpp \
+ friction.cpp \
+ joint.cpp \
+ main.cpp \
+ odemath.cpp
+
+tests_LDADD = \
+ $(top_builddir)/ode/src/libode.la \
+ joints/*.o \
+ UnitTest++/src/libunittestpp.la
diff --git a/libs/ode-0.16.1/tests/Makefile.in b/libs/ode-0.16.1/tests/Makefile.in
new file mode 100644
index 0000000..a5fb17b
--- /dev/null
+++ b/libs/ode-0.16.1/tests/Makefile.in
@@ -0,0 +1,1116 @@
+# 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@
+@GIMPACT_TRUE@am__append_1 = -DdTRIMESH_ENABLED -DdTRIMESH_GIMPACT
+@OPCODE_TRUE@am__append_2 = -DdTRIMESH_ENABLED -DdTRIMESH_OPCODE
+check_PROGRAMS = tests$(EXEEXT)
+TESTS = tests$(EXEEXT)
+subdir = tests
+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_tests_OBJECTS = collision.$(OBJEXT) friction.$(OBJEXT) \
+ joint.$(OBJEXT) main.$(OBJEXT) odemath.$(OBJEXT)
+tests_OBJECTS = $(am_tests_OBJECTS)
+tests_DEPENDENCIES = $(top_builddir)/ode/src/libode.la joints/*.o \
+ UnitTest++/src/libunittestpp.la
+AM_V_lt = $(am__v_lt_@AM_V@)
+am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+am__v_lt_1 =
+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 =
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/ode/src
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CXXFLAGS) $(CXXFLAGS)
+AM_V_CXX = $(am__v_CXX_@AM_V@)
+am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@)
+am__v_CXX_0 = @echo " CXX " $@;
+am__v_CXX_1 =
+CXXLD = $(CXX)
+CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
+ $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CXXLD = $(am__v_CXXLD_@AM_V@)
+am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@)
+am__v_CXXLD_0 = @echo " CXXLD " $@;
+am__v_CXXLD_1 =
+SOURCES = $(tests_SOURCES)
+DIST_SOURCES = $(tests_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 \
+ check recheck 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
+am__tty_colors_dummy = \
+ mgn= red= grn= lgn= blu= brg= std=; \
+ am__color_tests=no
+am__tty_colors = { \
+ $(am__tty_colors_dummy); \
+ if test "X$(AM_COLOR_TESTS)" = Xno; then \
+ am__color_tests=no; \
+ elif test "X$(AM_COLOR_TESTS)" = Xalways; then \
+ am__color_tests=yes; \
+ elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \
+ am__color_tests=yes; \
+ fi; \
+ if test $$am__color_tests = yes; then \
+ red=''; \
+ grn=''; \
+ lgn=''; \
+ blu=''; \
+ mgn=''; \
+ brg=''; \
+ std=''; \
+ fi; \
+}
+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__recheck_rx = ^[ ]*:recheck:[ ]*
+am__global_test_result_rx = ^[ ]*:global-test-result:[ ]*
+am__copy_in_global_log_rx = ^[ ]*:copy-in-global-log:[ ]*
+# A command that, given a newline-separated list of test names on the
+# standard input, print the name of the tests that are to be re-run
+# upon "make recheck".
+am__list_recheck_tests = $(AWK) '{ \
+ recheck = 1; \
+ while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+ { \
+ if (rc < 0) \
+ { \
+ if ((getline line2 < ($$0 ".log")) < 0) \
+ recheck = 0; \
+ break; \
+ } \
+ else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \
+ { \
+ recheck = 0; \
+ break; \
+ } \
+ else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \
+ { \
+ break; \
+ } \
+ }; \
+ if (recheck) \
+ print $$0; \
+ close ($$0 ".trs"); \
+ close ($$0 ".log"); \
+}'
+# A command that, given a newline-separated list of test names on the
+# standard input, create the global log from their .trs and .log files.
+am__create_global_log = $(AWK) ' \
+function fatal(msg) \
+{ \
+ print "fatal: making $@: " msg | "cat >&2"; \
+ exit 1; \
+} \
+function rst_section(header) \
+{ \
+ print header; \
+ len = length(header); \
+ for (i = 1; i <= len; i = i + 1) \
+ printf "="; \
+ printf "\n\n"; \
+} \
+{ \
+ copy_in_global_log = 1; \
+ global_test_result = "RUN"; \
+ while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+ { \
+ if (rc < 0) \
+ fatal("failed to read from " $$0 ".trs"); \
+ if (line ~ /$(am__global_test_result_rx)/) \
+ { \
+ sub("$(am__global_test_result_rx)", "", line); \
+ sub("[ ]*$$", "", line); \
+ global_test_result = line; \
+ } \
+ else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \
+ copy_in_global_log = 0; \
+ }; \
+ if (copy_in_global_log) \
+ { \
+ rst_section(global_test_result ": " $$0); \
+ while ((rc = (getline line < ($$0 ".log"))) != 0) \
+ { \
+ if (rc < 0) \
+ fatal("failed to read from " $$0 ".log"); \
+ print line; \
+ }; \
+ printf "\n"; \
+ }; \
+ close ($$0 ".trs"); \
+ close ($$0 ".log"); \
+}'
+# Restructured Text title.
+am__rst_title = { sed 's/.*/ & /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; }
+# Solaris 10 'make', and several other traditional 'make' implementations,
+# pass "-e" to $(SHELL), and POSIX 2008 even requires this. Work around it
+# by disabling -e (using the XSI extension "set +e") if it's set.
+am__sh_e_setup = case $$- in *e*) set +e;; esac
+# Default flags passed to test drivers.
+am__common_driver_flags = \
+ --color-tests "$$am__color_tests" \
+ --enable-hard-errors "$$am__enable_hard_errors" \
+ --expect-failure "$$am__expect_failure"
+# To be inserted before the command running the test. Creates the
+# directory for the log if needed. Stores in $dir the directory
+# containing $f, in $tst the test, in $log the log. Executes the
+# developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and
+# passes TESTS_ENVIRONMENT. Set up options for the wrapper that
+# will run the test scripts (or their associated LOG_COMPILER, if
+# thy have one).
+am__check_pre = \
+$(am__sh_e_setup); \
+$(am__vpath_adj_setup) $(am__vpath_adj) \
+$(am__tty_colors); \
+srcdir=$(srcdir); export srcdir; \
+case "$@" in \
+ */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;; \
+ *) am__odir=.;; \
+esac; \
+test "x$$am__odir" = x"." || test -d "$$am__odir" \
+ || $(MKDIR_P) "$$am__odir" || exit $$?; \
+if test -f "./$$f"; then dir=./; \
+elif test -f "$$f"; then dir=; \
+else dir="$(srcdir)/"; fi; \
+tst=$$dir$$f; log='$@'; \
+if test -n '$(DISABLE_HARD_ERRORS)'; then \
+ am__enable_hard_errors=no; \
+else \
+ am__enable_hard_errors=yes; \
+fi; \
+case " $(XFAIL_TESTS) " in \
+ *[\ \ ]$$f[\ \ ]* | *[\ \ ]$$dir$$f[\ \ ]*) \
+ am__expect_failure=yes;; \
+ *) \
+ am__expect_failure=no;; \
+esac; \
+$(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT)
+# A shell command to get the names of the tests scripts with any registered
+# extension removed (i.e., equivalently, the names of the test logs, with
+# the '.log' extension removed). The result is saved in the shell variable
+# '$bases'. This honors runtime overriding of TESTS and TEST_LOGS. Sadly,
+# we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)",
+# since that might cause problem with VPATH rewrites for suffix-less tests.
+# See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'.
+am__set_TESTS_bases = \
+ bases='$(TEST_LOGS)'; \
+ bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \
+ bases=`echo $$bases`
+RECHECK_LOGS = $(TEST_LOGS)
+TEST_SUITE_LOG = test-suite.log
+TEST_EXTENSIONS = @EXEEXT@ .test
+LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver
+LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS)
+am__set_b = \
+ case '$@' in \
+ */*) \
+ case '$*' in \
+ */*) b='$*';; \
+ *) b=`echo '$@' | sed 's/\.log$$//'`; \
+ esac;; \
+ *) \
+ b='$*';; \
+ esac
+am__test_logs1 = $(TESTS:=.log)
+am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log)
+TEST_LOGS = $(am__test_logs2:.test.log=.log)
+TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver
+TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \
+ $(TEST_LOG_FLAGS)
+DIST_SUBDIRS = $(SUBDIRS)
+am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp \
+ $(top_srcdir)/test-driver
+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 = joints UnitTest++
+AM_CPPFLAGS = -I$(srcdir)/UnitTest++/src -I$(top_srcdir)/include \
+ -I$(top_builddir)/include -I$(top_srcdir)/ode/src \
+ $(am__append_1) $(am__append_2)
+tests_SOURCES = \
+ collision.cpp \
+ friction.cpp \
+ joint.cpp \
+ main.cpp \
+ odemath.cpp
+
+tests_LDADD = \
+ $(top_builddir)/ode/src/libode.la \
+ joints/*.o \
+ UnitTest++/src/libunittestpp.la
+
+all: all-recursive
+
+.SUFFIXES:
+.SUFFIXES: .cpp .lo .log .o .obj .test .test$(EXEEXT) .trs
+$(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 tests/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --foreign tests/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):
+
+clean-checkPROGRAMS:
+ @list='$(check_PROGRAMS)'; test -n "$$list" || exit 0; \
+ echo " rm -f" $$list; \
+ rm -f $$list || exit $$?; \
+ test -n "$(EXEEXT)" || exit 0; \
+ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
+ echo " rm -f" $$list; \
+ rm -f $$list
+
+tests$(EXEEXT): $(tests_OBJECTS) $(tests_DEPENDENCIES) $(EXTRA_tests_DEPENDENCIES)
+ @rm -f tests$(EXEEXT)
+ $(AM_V_CXXLD)$(CXXLINK) $(tests_OBJECTS) $(tests_LDADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/collision.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/friction.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/joint.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/main.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/odemath.Po@am__quote@
+
+.cpp.o:
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $<
+
+.cpp.obj:
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.cpp.lo:
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LTCXXCOMPILE) -c -o $@ $<
+
+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
+
+# Recover from deleted '.trs' file; this should ensure that
+# "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create
+# both 'foo.log' and 'foo.trs'. Break the recipe in two subshells
+# to avoid problems with "make -n".
+.log.trs:
+ rm -f $< $@
+ $(MAKE) $(AM_MAKEFLAGS) $<
+
+# Leading 'am--fnord' is there to ensure the list of targets does not
+# expand to empty, as could happen e.g. with make check TESTS=''.
+am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck)
+am--force-recheck:
+ @:
+
+$(TEST_SUITE_LOG): $(TEST_LOGS)
+ @$(am__set_TESTS_bases); \
+ am__f_ok () { test -f "$$1" && test -r "$$1"; }; \
+ redo_bases=`for i in $$bases; do \
+ am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \
+ done`; \
+ if test -n "$$redo_bases"; then \
+ redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \
+ redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \
+ if $(am__make_dryrun); then :; else \
+ rm -f $$redo_logs && rm -f $$redo_results || exit 1; \
+ fi; \
+ fi; \
+ if test -n "$$am__remaking_logs"; then \
+ echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \
+ "recursion detected" >&2; \
+ elif test -n "$$redo_logs"; then \
+ am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \
+ fi; \
+ if $(am__make_dryrun); then :; else \
+ st=0; \
+ errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \
+ for i in $$redo_bases; do \
+ test -f $$i.trs && test -r $$i.trs \
+ || { echo "$$errmsg $$i.trs" >&2; st=1; }; \
+ test -f $$i.log && test -r $$i.log \
+ || { echo "$$errmsg $$i.log" >&2; st=1; }; \
+ done; \
+ test $$st -eq 0 || exit 1; \
+ fi
+ @$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \
+ ws='[ ]'; \
+ results=`for b in $$bases; do echo $$b.trs; done`; \
+ test -n "$$results" || results=/dev/null; \
+ all=` grep "^$$ws*:test-result:" $$results | wc -l`; \
+ pass=` grep "^$$ws*:test-result:$$ws*PASS" $$results | wc -l`; \
+ fail=` grep "^$$ws*:test-result:$$ws*FAIL" $$results | wc -l`; \
+ skip=` grep "^$$ws*:test-result:$$ws*SKIP" $$results | wc -l`; \
+ xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \
+ xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \
+ error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \
+ if test `expr $$fail + $$xpass + $$error` -eq 0; then \
+ success=true; \
+ else \
+ success=false; \
+ fi; \
+ br='==================='; br=$$br$$br$$br$$br; \
+ result_count () \
+ { \
+ if test x"$$1" = x"--maybe-color"; then \
+ maybe_colorize=yes; \
+ elif test x"$$1" = x"--no-color"; then \
+ maybe_colorize=no; \
+ else \
+ echo "$@: invalid 'result_count' usage" >&2; exit 4; \
+ fi; \
+ shift; \
+ desc=$$1 count=$$2; \
+ if test $$maybe_colorize = yes && test $$count -gt 0; then \
+ color_start=$$3 color_end=$$std; \
+ else \
+ color_start= color_end=; \
+ fi; \
+ echo "$${color_start}# $$desc $$count$${color_end}"; \
+ }; \
+ create_testsuite_report () \
+ { \
+ result_count $$1 "TOTAL:" $$all "$$brg"; \
+ result_count $$1 "PASS: " $$pass "$$grn"; \
+ result_count $$1 "SKIP: " $$skip "$$blu"; \
+ result_count $$1 "XFAIL:" $$xfail "$$lgn"; \
+ result_count $$1 "FAIL: " $$fail "$$red"; \
+ result_count $$1 "XPASS:" $$xpass "$$red"; \
+ result_count $$1 "ERROR:" $$error "$$mgn"; \
+ }; \
+ { \
+ echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \
+ $(am__rst_title); \
+ create_testsuite_report --no-color; \
+ echo; \
+ echo ".. contents:: :depth: 2"; \
+ echo; \
+ for b in $$bases; do echo $$b; done \
+ | $(am__create_global_log); \
+ } >$(TEST_SUITE_LOG).tmp || exit 1; \
+ mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG); \
+ if $$success; then \
+ col="$$grn"; \
+ else \
+ col="$$red"; \
+ test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG); \
+ fi; \
+ echo "$${col}$$br$${std}"; \
+ echo "$${col}Testsuite summary for $(PACKAGE_STRING)$${std}"; \
+ echo "$${col}$$br$${std}"; \
+ create_testsuite_report --maybe-color; \
+ echo "$$col$$br$$std"; \
+ if $$success; then :; else \
+ echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}"; \
+ if test -n "$(PACKAGE_BUGREPORT)"; then \
+ echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}"; \
+ fi; \
+ echo "$$col$$br$$std"; \
+ fi; \
+ $$success || exit 1
+
+check-TESTS:
+ @list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list
+ @list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list
+ @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+ @set +e; $(am__set_TESTS_bases); \
+ log_list=`for i in $$bases; do echo $$i.log; done`; \
+ trs_list=`for i in $$bases; do echo $$i.trs; done`; \
+ log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \
+ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \
+ exit $$?;
+recheck: all $(check_PROGRAMS)
+ @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+ @set +e; $(am__set_TESTS_bases); \
+ bases=`for i in $$bases; do echo $$i; done \
+ | $(am__list_recheck_tests)` || exit 1; \
+ log_list=`for i in $$bases; do echo $$i.log; done`; \
+ log_list=`echo $$log_list`; \
+ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \
+ am__force_recheck=am--force-recheck \
+ TEST_LOGS="$$log_list"; \
+ exit $$?
+tests.log: tests$(EXEEXT)
+ @p='tests$(EXEEXT)'; \
+ b='tests'; \
+ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+.test.log:
+ @p='$<'; \
+ $(am__set_b); \
+ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+@am__EXEEXT_TRUE@.test$(EXEEXT).log:
+@am__EXEEXT_TRUE@ @p='$<'; \
+@am__EXEEXT_TRUE@ $(am__set_b); \
+@am__EXEEXT_TRUE@ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+@am__EXEEXT_TRUE@ --log-file $$b.log --trs-file $$b.trs \
+@am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+@am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT)
+
+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
+ $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS)
+ $(MAKE) $(AM_MAKEFLAGS) check-TESTS
+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:
+ -test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS)
+ -test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs)
+ -test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+
+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-checkPROGRAMS clean-generic clean-libtool \
+ mostlyclean-am
+
+distclean: distclean-recursive
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile 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 -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-recursive
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-recursive
+
+pdf-am:
+
+ps: ps-recursive
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: $(am__recursive_targets) check-am install-am install-strip
+
+.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \
+ check-TESTS check-am clean clean-checkPROGRAMS clean-generic \
+ clean-libtool cscopelist-am ctags ctags-am distclean \
+ distclean-compile 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-compile mostlyclean-generic \
+ mostlyclean-libtool pdf pdf-am ps ps-am recheck 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/tests/UnitTest++/COPYING b/libs/ode-0.16.1/tests/UnitTest++/COPYING
new file mode 100644
index 0000000..9f96308
--- /dev/null
+++ b/libs/ode-0.16.1/tests/UnitTest++/COPYING
@@ -0,0 +1,20 @@
+Copyright (c) 2006 Noel Llopis and Charles Nicholson
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/libs/ode-0.16.1/tests/UnitTest++/Makefile.am b/libs/ode-0.16.1/tests/UnitTest++/Makefile.am
new file mode 100644
index 0000000..000d8e4
--- /dev/null
+++ b/libs/ode-0.16.1/tests/UnitTest++/Makefile.am
@@ -0,0 +1,6 @@
+# Makefile.am for UnitTest++
+
+SUBDIRS = src
+
+EXTRA_DIST = docs
+
diff --git a/libs/ode-0.16.1/tests/UnitTest++/Makefile.in b/libs/ode-0.16.1/tests/UnitTest++/Makefile.in
new file mode 100644
index 0000000..0bc32c9
--- /dev/null
+++ b/libs/ode-0.16.1/tests/UnitTest++/Makefile.in
@@ -0,0 +1,643 @@
+# 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@
+
+# Makefile.am for UnitTest++
+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 = tests/UnitTest++
+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 COPYING README
+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 = src
+EXTRA_DIST = docs
+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 tests/UnitTest++/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --foreign tests/UnitTest++/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/tests/UnitTest++/README b/libs/ode-0.16.1/tests/UnitTest++/README
new file mode 100644
index 0000000..b32ff5f
--- /dev/null
+++ b/libs/ode-0.16.1/tests/UnitTest++/README
@@ -0,0 +1,62 @@
+UnitTest++ README
+Version: v1.3
+Last update: 2007-4-22
+
+
+UnitTest++ is free software. You may copy, distribute, and modify it under
+the terms of the License contained in the file COPYING distributed
+with this package. This license is the same as the MIT/X Consortium
+license.
+
+See src/tests/TestUnitTest++.cpp for usage.
+
+Authors:
+Noel Llopis (llopis@convexhull.com)
+Charles Nicholson (cn@cnicholson.net)
+
+Contributors:
+Jim Tilander (jim.tilander@gmail.com)
+Kim Grasman (kim@mvps.org)
+Jonathan Jansson (lilliemarck@users.sourceforge.net)
+Dirck Blaskey (listtarget2@danbala.com)
+Rory Driscoll (rorydriscoll@gmail.com)
+Dan Lind (podcat@gmail.com)
+Matt Kimmel (mattkimmel@gmail.com) -- Submitted with permission from Blue Fang Games
+Anthony Moralez (anthony.moralez@gmail.com)
+Jeff Dixon <bodisafa@helixe.com>
+
+
+Release notes
+--------------
+Version 1.3 (2007-4-22)
+- Removed dynamic memory allocations (other than streams)
+- MinGW support
+- Consistent (native) line endings
+- Minor bug fixing
+
+Version 1.2 (2006-10-29)
+- First pass at documentation.
+- More detailed error crash catching in fixtures.
+- Standard streams used for printing objects under check. This should allow the
+ use of standard class types such as std::string or other custom classes with
+ stream operators to ostream.
+- Standard streams can be optionally compiled off by defining UNITTEST_USE_CUSTOM_STREAMS
+ in Config.h
+- Added named test suites
+- Added CHECK_ARRAY2D_CLOSE
+- Posix library name is libUnitTest++.a now
+- Floating point numbers are postfixed with f in the failure reports
+
+Version 1.1 (2006-04-18)
+- CHECK macros do not have side effects even if one of the parameters changes state
+- Removed CHECK_ARRAY_EQUAL (too similar to CHECK_ARRAY_CLOSE)
+- Added local and global time constraints
+- Removed dependencies on strstream
+- Improved Posix signal to exception translator
+- Failing tests are added to Visual Studio's error list
+- Fixed Visual Studio projects to work with spaces in directories
+
+
+Version 1.0 (2006-03-15)
+- Initial release
+
diff --git a/libs/ode-0.16.1/tests/UnitTest++/docs/UnitTest++.html b/libs/ode-0.16.1/tests/UnitTest++/docs/UnitTest++.html
new file mode 100644
index 0000000..cd40400
--- /dev/null
+++ b/libs/ode-0.16.1/tests/UnitTest++/docs/UnitTest++.html
@@ -0,0 +1,260 @@
+<html>
+<head>
+ <title>UnitTest++ in brief</title>
+</head>
+<body>
+<h1>UnitTest++ in brief</h1>
+<h2>Introduction</h2>
+<p>This little document serves as bare-bones documentation for UnitTest++.</p>
+
+<p>For background, goals and license details, see:</p>
+
+<ul>
+ <li><a href="http://unittest-cpp.sourceforge.net/">The UnitTest++ home page</a></li>
+ <li><a href="http://www.gamesfromwithin.com/articles/0603/000108.html">Noel Llopis' announcement</a></li>
+</ul>
+
+<p>The documentation, while sparse, aims to be practical, so it should give you enough info to get started using UnitTest++ as fast as possible.</p>
+
+<h2>Building UnitTest++</h2>
+<p>Building UnitTest++ will be specific to each platform and build environment, but it should be straightforward.</p>
+
+<h3>Building with Visual Studio</h3>
+<p>If you are using Visual Studio, go for either of the provided .sln files, depending on version. There are no prefabricated solutions for versions earlier than VS.NET 2003, but we have had reports of people building UnitTest++ with at least VS.NET 2002.</p>
+
+<h3>Building with Make</h3>
+<p>The bundled makefile is written to build with g++. It also needs <code>sed</code> installed in the path, and to be able to use the <code>mv</code> and <code>rm</code> shell commands. The makefile should be usable on most Posix-like platforms.</p>
+
+<p>Do "make all" to generate a library and test executable. A final build step runs all unit tests to make sure that the result works as expected.</p>
+
+<h3>Packaging</h3>
+<p>You'll probably want to keep the generated library in a shared space in source control, so you can reuse it for multiple test projects. A redistributable package of UnitTest++ would consist of the generated library file, and all of the header files in <code>UnitTest++/src/</code> and its per-platform subfolders. The <code>tests</code> directory only contains the unit tests for the library, and need not be included.</p>
+
+<h2>Using UnitTest++</h2>
+<p>The source code for UnitTest++ comes with a full test suite written <em>using</em> UnitTest++. This is a great place to learn techniques for testing. There is one sample .cpp file: <code>UnitTest++/src/tests/TestUnitTest++.cpp</code>. It covers most of UnitTest++'s features in an easy-to-grasp context, so start there if you want a quick overview of typical usage.</p>
+
+<h3>Getting started</h3>
+<p>Listed below is a minimal C++ program to run a failing test through UnitTest++.</p>
+
+<pre>
+ // test.cpp
+ #include &lt;UnitTest++.h&gt;
+
+ TEST(FailSpectacularly)
+ {
+ CHECK(false);
+ }
+
+ int main()
+ {
+ return UnitTest::RunAllTests();
+ }
+</pre>
+
+<p><code>UnitTest++.h</code> is a facade header for UnitTest++, so including that should get you all features of the library. All classes and free functions are placed in namespace <code>UnitTest</code>, so you need to either qualify their full names (as with <code>RunAllTests()</code> in the example) or add a <code>using namespace UnitTest;</code> statement in your .cpp files. Note that any mention of UnitTest++ functions and classes in this document assume that the <code>UnitTest</code> namespace has been opened.</p>
+
+<p>Compiling and linking this program with UnitTest++'s static library into an executable, and running it, will produce the following output (details may vary):</p>
+
+<pre>
+ .\test.cpp(5): error: Failure in FailSpectacularly: false
+ FAILED: 1 out of 1 tests failed (1 failures).
+ Test time: 0.00 seconds.
+</pre>
+
+<p>UnitTest++ attempts to report every failure in an IDE-friendly format, depending on platform (e.g. you can double-click it in Visual Studio's error list.) The exit code will be the number of failed tests, so that a failed test run always returns a non-zero exit code.</p>
+
+<h3>Test macros</h3>
+<p>To add a test, simply put the following code in a .cpp file of your choice:</p>
+
+<pre>
+ TEST(YourTestName)
+ {
+ }
+</pre>
+
+<p>The <code>TEST</code> macro contains enough machinery to turn this slightly odd-looking syntax into legal C++, and automatically register the test in a global list. This test list forms the basis of what is executed by <code>RunAllTests()</code>.</p>
+
+<p>If you want to re-use a set of test data for more than one test, or provide setup/teardown for tests, you can use the <code>TEST_FIXTURE</code> macro instead. The macro requires that you pass it a class name that it will instantiate, so any setup and teardown code should be in its constructor and destructor.</p>
+
+<pre>
+ struct SomeFixture
+ {
+ SomeFixture() { /* some setup */ }
+ ~SomeFixture() { /* some teardown */ }
+
+ int testData;
+ };
+
+ TEST_FIXTURE(SomeFixture, YourTestName)
+ {
+ int temp = testData;
+ }
+</pre>
+
+<p>Note how members of the fixture are used as if they are a part of the test, since the macro-generated test class derives from the provided fixture class.</p>
+
+<h3>Suite macros</h3>
+<p>Tests can be grouped into suites, using the <code>SUITE</code> macro. A suite serves as a namespace for test names, so that the same test name can be used in two difference contexts.</p>
+
+<pre>
+ SUITE(YourSuiteName)
+ {
+ TEST(YourTestName)
+ {
+ }
+
+ TEST(YourOtherTestName)
+ {
+ }
+ }
+</pre>
+
+<p>This will place the tests into a C++ namespace called <code>YourSuiteName</code>, and make the suite name available to UnitTest++. <code>RunAllTests()</code> can be called for a specific suite name, so you can use this to build named groups of tests to be run together.</p>
+
+<h3>Simple check macros</h3>
+<p>In test cases, we want to check the results of our system under test. UnitTest++ provides a number of check macros that handle comparison and proper failure reporting.</p>
+
+<p>The most basic variety is the boolean <code>CHECK</code> macro:</p>
+
+<pre>
+ CHECK(false); // fails
+</pre>
+
+<p>It will fail if the boolean expression evaluates to false.</p>
+
+<p>For equality checks, it's generally better to use <code>CHECK_EQUAL</code>:</p>
+
+<pre>
+ CHECK_EQUAL(10, 20); // fails
+ CHECK_EQUAL("foo", "bar"); // fails
+</pre>
+
+<p>Note how <code>CHECK_EQUAL</code> is overloaded for C strings, so you don't have to resort to <code>strcmp</code> or similar. There is no facility for case-insensitive comparison or string searches, so you may have to drop down to a plain boolean <code>CHECK</code> with help from the CRT:</p>
+
+<pre>
+ CHECK(std::strstr("zaza", "az") != 0); // succeeds
+</pre>
+
+<p>For floating-point comparison, equality <a href="http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm">isn't necessarily well-defined</a>, so you should prefer the <code>CHECK_CLOSE</code> macro:</p>
+
+<pre>
+ CHECK_CLOSE(3.14, 3.1415, 0.01); // succeeds
+</pre>
+
+<p>All of the macros are tailored to avoid unintended side-effects, for example:</p>
+
+<pre>
+ TEST(CheckMacrosHaveNoSideEffects)
+ {
+ int i = 4;
+ CHECK_EQUAL(5, ++i); // succeeds
+ CHECK_EQUAL(5, i); // succeeds
+ }
+</pre>
+
+<p>The check macros guarantee that the <code>++i</code> expression isn't repeated internally, as demonstrated above.</p>
+
+<h3>Array check macros</h3>
+<p>There is a set of check macros for array comparison as well:</p>
+
+<pre>
+ const float oned[2] = { 10, 20 };
+ CHECK_ARRAY_EQUAL(oned, oned, 2); // succeeds
+ CHECK_ARRAY_CLOSE(oned, oned, 2, 0.00); // succeeds
+
+ const float twod[2][3] = { {0, 1, 2}, {2, 3, 4} };
+ CHECK_ARRAY2D_CLOSE(twod, twod, 2, 3, 0.00); // succeeds
+</pre>
+
+<p>The array equal macro compares elements using <code>operator==</code>, so <code>CHECK_ARRAY_EQUAL</code> won't work for an array of C strings, for example.</p>
+
+<p>The array close macros are similar to the regular CHECK_CLOSE macro, and are really only useful for scalar types, that can be compared in terms of a difference between two array elements.</p>
+
+<p>Note that the one-dimensional array macros work for <code>std::vector</code> as well, as it can be indexed just as a C array.</p>
+
+<h3>Exception check macros</h3>
+<p>Finally, there's a <code>CHECK_THROW</code> macro, which asserts that its enclosed expression throws the specified type:</p>
+
+<pre>
+ struct TestException {};
+ CHECK_THROW(throw TestException(), TestException); // succeeds
+</pre>
+
+<p>UnitTest++ natively catches exceptions if your test code doesn't. So if your code under test throws any exception UnitTest++ will fail the test and report either using the <code>what()</code> method for <code>std::exception</code> derivatives or just a plain message for unknown exception types.</p>
+
+<p>Should your test or code raise an irrecoverable error (an Access Violation on Win32, for example, or a signal on Linux), UnitTest++ will attempt to map them to an exception and fail the test, just as for other unhandled exceptions.</p>
+
+<h3>Time constraints</h3>
+<p>UnitTest++ can fail a test if it takes too long to complete, using so-called time constraints.</p>
+
+<p>They come in two flavors; <em>local</em> and <em>global</em> time constraints.</p>
+
+<p>Local time constraints are limited to the current scope, like so:</p>
+
+<pre>
+ TEST(YourTimedTest)
+ {
+ // Lengthy setup...
+
+ {
+ UNITTEST_TIME_CONSTRAINT(50);
+
+ // Do time-critical stuff
+ }
+
+ // Lengthy teardown...
+ }
+</pre>
+
+<p>The test will fail if the "Do time-critical stuff" block takes longer than 50 ms to complete. The time-consuming setup and teardown are not measured, since the time constraint is scope-bound. It's perfectly valid to have multiple local time constraints in the same test, as long as there is only one per block.</p>
+
+<p>A global time constraint, on the other hand, requires that all of the tests in a test run are faster than a specified amount of time. This allows you, when you run a suite of tests, to ask UnitTest++ to fail it entirely if any test exceeds the global constraint. The max time is passed as a parameter to an overload of <code>RunAllTests()</code>.</p>
+
+<p>If you want to use a global time constraint, but have one test that is notoriously slow, you can exempt it from inspection by using the <code>UNITTEST_TIME_CONSTRAINT_EXEMPT</code> macro anywhere inside the test body.</p>
+
+<pre>
+ TEST(NotoriouslySlowTest)
+ {
+ UNITTEST_TIME_CONSTRAINT_EXEMPT();
+
+ // Oh boy, this is going to take a while
+ ...
+ }
+</pre>
+
+<h3>Test runners</h3>
+<p>The <code>RunAllTests()</code> function has an overload that lets you customize the behavior of the runner, such as global time constraints, custom reporters, which suite to run, etc.</p>
+
+<pre>
+ int RunAllTests(TestReporter& reporter, TestList const& list, char const* suiteName, int const maxTestTimeInMs);
+</pre>
+
+<p>If you attempt to pass custom parameters to <code>RunAllTests()</code>, note that the <code>list</code> parameter should have the value <code>Test::GetTestList()</code>.</p>
+
+<p>The parameterless <code>RunAllTests()</code> is a simple wrapper for this one, with sensible defaults.</p>
+
+<h3>Example setup</h3>
+<p>How to create a new test project varies depending on your environment, but here are some directions on common file structure and usage.</p>
+
+<p>The general idea is that you keep one <code>Main.cpp</code> file with the entry-point which calls <code>RunAllTests()</code>.</p>
+
+<p>Then you can simply compile and link new .cpp files at will, typically one per test suite.</p>
+
+<pre>
+ + ShaverTests/
+ |
+ +- Main.cpp
+ |
+ +- TestBrush.cpp
+ +- TestEngine.cpp
+ +- TestRazor.cpp
+</pre>
+
+<p>Each of the <code>Test*.cpp</code> files will contain one or more <code>TEST</code> macro incantations with the associated test code. There are no source-level dependencies between <code>Main.cpp</code> and <code>Test*.cpp</code>, as the <code>TEST</code> macro handles the registration and setup necessary for <code>RunAllTests()</code> to find all tests compiled into the same final executable.</p>
+
+<p>UnitTest++ does not require this structure, even if this is how the library itself does it. As long as your test project contains one or more <code>TESTs</code> and calls <code>RunAllTests()</code> at one point or another, it will be handled by UnitTest++.</p>
+
+<p>It's common to make the generated executable start as a post-build step, so that merely building your test project will run the tests as well. Since the exit code is the count of failures, a failed test will generally break the build, as most build engines will fail a build if any step returns a non-zero exit code.</p>
+
+</body>
+</html> \ No newline at end of file
diff --git a/libs/ode-0.16.1/tests/UnitTest++/src/AssertException.cpp b/libs/ode-0.16.1/tests/UnitTest++/src/AssertException.cpp
new file mode 100644
index 0000000..49f7ba7
--- /dev/null
+++ b/libs/ode-0.16.1/tests/UnitTest++/src/AssertException.cpp
@@ -0,0 +1,32 @@
+#include "AssertException.h"
+#include <cstring>
+
+namespace UnitTest {
+
+AssertException::AssertException(char const* description, char const* filename, int const lineNumber)
+ : m_lineNumber(lineNumber)
+{
+ std::strcpy(m_description, description);
+ std::strcpy(m_filename, filename);
+}
+
+AssertException::~AssertException() throw()
+{
+}
+
+char const* AssertException::what() const throw()
+{
+ return m_description;
+}
+
+char const* AssertException::Filename() const
+{
+ return m_filename;
+}
+
+int AssertException::LineNumber() const
+{
+ return m_lineNumber;
+}
+
+}
diff --git a/libs/ode-0.16.1/tests/UnitTest++/src/AssertException.h b/libs/ode-0.16.1/tests/UnitTest++/src/AssertException.h
new file mode 100644
index 0000000..e04d450
--- /dev/null
+++ b/libs/ode-0.16.1/tests/UnitTest++/src/AssertException.h
@@ -0,0 +1,28 @@
+#ifndef UNITTEST_ASSERTEXCEPTION_H
+#define UNITTEST_ASSERTEXCEPTION_H
+
+#include <exception>
+
+
+namespace UnitTest {
+
+class AssertException : public std::exception
+{
+public:
+ AssertException(char const* description, char const* filename, int lineNumber);
+ virtual ~AssertException() throw();
+
+ virtual char const* what() const throw();
+
+ char const* Filename() const;
+ int LineNumber() const;
+
+private:
+ char m_description[512];
+ char m_filename[256];
+ int m_lineNumber;
+};
+
+}
+
+#endif
diff --git a/libs/ode-0.16.1/tests/UnitTest++/src/CheckMacros.h b/libs/ode-0.16.1/tests/UnitTest++/src/CheckMacros.h
new file mode 100644
index 0000000..2d499cc
--- /dev/null
+++ b/libs/ode-0.16.1/tests/UnitTest++/src/CheckMacros.h
@@ -0,0 +1,102 @@
+#ifndef UNITTEST_CHECKMACROS_H
+#define UNITTEST_CHECKMACROS_H
+
+#include "Checks.h"
+#include "AssertException.h"
+#include "MemoryOutStream.h"
+#include "TestDetails.h"
+
+#ifdef CHECK
+ #error UnitTest++ redefines CHECK
+#endif
+
+
+#define CHECK(value) \
+ do \
+ { \
+ try { \
+ if (!UnitTest::Check(value)) \
+ testResults_.OnTestFailure( UnitTest::TestDetails(m_details, __LINE__), #value); \
+ } \
+ catch (...) { \
+ testResults_.OnTestFailure(UnitTest::TestDetails(m_details, __LINE__), \
+ "Unhandled exception in CHECK(" #value ")"); \
+ } \
+ } while (0)
+
+#define CHECK_EQUAL(expected, actual) \
+ do \
+ { \
+ try { \
+ UnitTest::CheckEqual(testResults_, expected, actual, UnitTest::TestDetails(m_details, __LINE__)); \
+ } \
+ catch (...) { \
+ testResults_.OnTestFailure(UnitTest::TestDetails(m_details, __LINE__), \
+ "Unhandled exception in CHECK_EQUAL(" #expected ", " #actual ")"); \
+ } \
+ } while (0)
+
+#define CHECK_CLOSE(expected, actual, tolerance) \
+ do \
+ { \
+ try { \
+ UnitTest::CheckClose(testResults_, expected, actual, tolerance, UnitTest::TestDetails(m_details, __LINE__)); \
+ } \
+ catch (...) { \
+ testResults_.OnTestFailure(UnitTest::TestDetails(m_details, __LINE__), \
+ "Unhandled exception in CHECK_CLOSE(" #expected ", " #actual ")"); \
+ } \
+ } while (0)
+
+#define CHECK_ARRAY_EQUAL(expected, actual, count) \
+ do \
+ { \
+ try { \
+ UnitTest::CheckArrayEqual(testResults_, expected, actual, count, UnitTest::TestDetails(m_details, __LINE__)); \
+ } \
+ catch (...) { \
+ testResults_.OnTestFailure(UnitTest::TestDetails(m_details, __LINE__), \
+ "Unhandled exception in CHECK_ARRAY_EQUAL(" #expected ", " #actual ")"); \
+ } \
+ } while (0)
+
+#define CHECK_ARRAY_CLOSE(expected, actual, count, tolerance) \
+ do \
+ { \
+ try { \
+ UnitTest::CheckArrayClose(testResults_, expected, actual, count, tolerance, UnitTest::TestDetails(m_details, __LINE__)); \
+ } \
+ catch (...) { \
+ testResults_.OnTestFailure(UnitTest::TestDetails(m_details, __LINE__), \
+ "Unhandled exception in CHECK_ARRAY_CLOSE(" #expected ", " #actual ")"); \
+ } \
+ } while (0)
+
+#define CHECK_ARRAY2D_CLOSE(expected, actual, rows, columns, tolerance) \
+ do \
+ { \
+ try { \
+ UnitTest::CheckArray2DClose(testResults_, expected, actual, rows, columns, tolerance, UnitTest::TestDetails(m_details, __LINE__)); \
+ } \
+ catch (...) { \
+ testResults_.OnTestFailure(UnitTest::TestDetails(m_details, __LINE__), \
+ "Unhandled exception in CHECK_ARRAY_CLOSE(" #expected ", " #actual ")"); \
+ } \
+ } while (0)
+
+
+#define CHECK_THROW(expression, ExpectedExceptionType) \
+ do \
+ { \
+ bool caught_ = false; \
+ try { expression; } \
+ catch (ExpectedExceptionType const&) { caught_ = true; } \
+ catch (...) {} \
+ if (!caught_) \
+ testResults_.OnTestFailure(UnitTest::TestDetails(m_details, __LINE__), "Expected exception: \"" #ExpectedExceptionType "\" not thrown"); \
+ } while(0)
+
+#define CHECK_ASSERT(expression) \
+ CHECK_THROW(expression, UnitTest::AssertException);
+
+#endif
diff --git a/libs/ode-0.16.1/tests/UnitTest++/src/Checks.cpp b/libs/ode-0.16.1/tests/UnitTest++/src/Checks.cpp
new file mode 100644
index 0000000..36db997
--- /dev/null
+++ b/libs/ode-0.16.1/tests/UnitTest++/src/Checks.cpp
@@ -0,0 +1,48 @@
+#include "Checks.h"
+#include <cstring>
+
+namespace UnitTest {
+
+namespace {
+
+void CheckStringsEqual(TestResults& results, char const* expected, char const* actual,
+ TestDetails const& details)
+{
+ if (std::strcmp(expected, actual))
+ {
+ UnitTest::MemoryOutStream stream;
+ stream << "Expected " << expected << " but was " << actual;
+
+ results.OnTestFailure(details, stream.GetText());
+ }
+}
+
+}
+
+
+void CheckEqual(TestResults& results, char const* expected, char const* actual,
+ TestDetails const& details)
+{
+ CheckStringsEqual(results, expected, actual, details);
+}
+
+void CheckEqual(TestResults& results, char* expected, char* actual,
+ TestDetails const& details)
+{
+ CheckStringsEqual(results, expected, actual, details);
+}
+
+void CheckEqual(TestResults& results, char* expected, char const* actual,
+ TestDetails const& details)
+{
+ CheckStringsEqual(results, expected, actual, details);
+}
+
+void CheckEqual(TestResults& results, char const* expected, char* actual,
+ TestDetails const& details)
+{
+ CheckStringsEqual(results, expected, actual, details);
+}
+
+
+}
diff --git a/libs/ode-0.16.1/tests/UnitTest++/src/Checks.h b/libs/ode-0.16.1/tests/UnitTest++/src/Checks.h
new file mode 100644
index 0000000..b470b62
--- /dev/null
+++ b/libs/ode-0.16.1/tests/UnitTest++/src/Checks.h
@@ -0,0 +1,146 @@
+#ifndef UNITTEST_CHECKS_H
+#define UNITTEST_CHECKS_H
+
+#include "Config.h"
+#include "TestResults.h"
+#include "MemoryOutStream.h"
+
+namespace UnitTest {
+
+
+template< typename Value >
+bool Check(Value const value)
+{
+ return !!value; // doing double negative to avoid silly VS warnings
+}
+
+
+template< typename Expected, typename Actual >
+void CheckEqual(TestResults& results, Expected const expected, Actual const actual, TestDetails const& details)
+{
+ if (!(expected == actual))
+ {
+ UnitTest::MemoryOutStream stream;
+ stream << "Expected " << expected << " but was " << actual;
+
+ results.OnTestFailure(details, stream.GetText());
+ }
+}
+
+void CheckEqual(TestResults& results, char const* expected, char const* actual, TestDetails const& details);
+
+void CheckEqual(TestResults& results, char* expected, char* actual, TestDetails const& details);
+
+void CheckEqual(TestResults& results, char* expected, char const* actual, TestDetails const& details);
+
+void CheckEqual(TestResults& results, char const* expected, char* actual, TestDetails const& details);
+
+template< typename Expected, typename Actual, typename Tolerance >
+bool AreClose(Expected const expected, Actual const actual, Tolerance const tolerance)
+{
+ return (actual >= (expected - tolerance)) && (actual <= (expected + tolerance));
+}
+
+template< typename Expected, typename Actual, typename Tolerance >
+void CheckClose(TestResults& results, Expected const expected, Actual const actual, Tolerance const tolerance,
+ TestDetails const& details)
+{
+ if (!AreClose(expected, actual, tolerance))
+ {
+ UnitTest::MemoryOutStream stream;
+ stream << "Expected " << expected << " +/- " << tolerance << " but was " << actual;
+
+ results.OnTestFailure(details, stream.GetText());
+ }
+}
+
+
+template< typename Expected, typename Actual >
+void CheckArrayEqual(TestResults& results, Expected const expected, Actual const actual,
+ int const count, TestDetails const& details)
+{
+ bool equal = true;
+ for (int i = 0; i < count; ++i)
+ equal &= (expected[i] == actual[i]);
+
+ if (!equal)
+ {
+ UnitTest::MemoryOutStream stream;
+ stream << "Expected [ ";
+ for (int i = 0; i < count; ++i)
+ stream << expected[i] << " ";
+ stream << "] but was [ ";
+ for (int i = 0; i < count; ++i)
+ stream << actual[i] << " ";
+ stream << "]";
+
+ results.OnTestFailure(details, stream.GetText());
+ }
+}
+
+template< typename Expected, typename Actual, typename Tolerance >
+bool ArrayAreClose(Expected const expected, Actual const actual, int const count, Tolerance const tolerance)
+{
+ bool equal = true;
+ for (int i = 0; i < count; ++i)
+ equal &= AreClose(expected[i], actual[i], tolerance);
+ return equal;
+}
+
+template< typename Expected, typename Actual, typename Tolerance >
+void CheckArrayClose(TestResults& results, Expected const expected, Actual const actual,
+ int const count, Tolerance const tolerance, TestDetails const& details)
+{
+ bool equal = ArrayAreClose(expected, actual, count, tolerance);
+
+ if (!equal)
+ {
+ UnitTest::MemoryOutStream stream;
+ stream << "Expected [ ";
+ for (int i = 0; i < count; ++i)
+ stream << expected[i] << " ";
+ stream << "] +/- " << tolerance << " but was [ ";
+ for (int i = 0; i < count; ++i)
+ stream << actual[i] << " ";
+ stream << "]";
+
+ results.OnTestFailure(details, stream.GetText());
+ }
+}
+
+template< typename Expected, typename Actual, typename Tolerance >
+void CheckArray2DClose(TestResults& results, Expected const expected, Actual const actual,
+ int const rows, int const columns, Tolerance const tolerance, TestDetails const& details)
+{
+ bool equal = true;
+ for (int i = 0; i < rows; ++i)
+ equal &= ArrayAreClose(expected[i], actual[i], columns, tolerance);
+
+ if (!equal)
+ {
+ UnitTest::MemoryOutStream stream;
+ stream << "Expected [ ";
+ for (int i = 0; i < rows; ++i)
+ {
+ stream << "[ ";
+ for (int j = 0; j < columns; ++j)
+ stream << expected[i][j] << " ";
+ stream << "] ";
+ }
+ stream << "] +/- " << tolerance << " but was [ ";
+ for (int i = 0; i < rows; ++i)
+ {
+ stream << "[ ";
+ for (int j = 0; j < columns; ++j)
+ stream << actual[i][j] << " ";
+ stream << "] ";
+ }
+ stream << "]";
+
+ results.OnTestFailure(details, stream.GetText());
+ }
+}
+
+}
+
+#endif
diff --git a/libs/ode-0.16.1/tests/UnitTest++/src/Config.h b/libs/ode-0.16.1/tests/UnitTest++/src/Config.h
new file mode 100644
index 0000000..db423d4
--- /dev/null
+++ b/libs/ode-0.16.1/tests/UnitTest++/src/Config.h
@@ -0,0 +1,25 @@
+#ifndef UNITTEST_CONFIG_H
+#define UNITTEST_CONFIG_H
+
+// Standard defines documented here: http://predef.sourceforge.net
+
+#if defined _MSC_VER
+ #pragma warning(disable:4127) // conditional expression is constant
+ #pragma warning(disable:4702) // unreachable code
+ #pragma warning(disable:4722) // destructor never returns, potential memory leak
+#endif
+
+#if defined(unix) || defined(__unix__) || defined(__unix) || defined(linux) || \
+ defined(__APPLE__) || defined (__NetBSD__) || defined (__OpenBSD__) || defined (__FreeBSD__)
+ #define UNITTEST_POSIX
+#endif
+
+#if defined (__MINGW32__)
+ #define UNITTEST_MINGW
+#endif
+
+// by default, MemoryOutStream is implemented in terms of std::ostringstream.
+// uncomment this line to use the custom MemoryOutStream (no deps on std::ostringstream).
+//#define UNITTEST_USE_CUSTOM_STREAMS
+
+#endif
diff --git a/libs/ode-0.16.1/tests/UnitTest++/src/DeferredTestReporter.cpp b/libs/ode-0.16.1/tests/UnitTest++/src/DeferredTestReporter.cpp
new file mode 100644
index 0000000..05e8055
--- /dev/null
+++ b/libs/ode-0.16.1/tests/UnitTest++/src/DeferredTestReporter.cpp
@@ -0,0 +1,28 @@
+#include "DeferredTestReporter.h"
+#include "TestDetails.h"
+
+using namespace UnitTest;
+
+void DeferredTestReporter::ReportTestStart(TestDetails const& details)
+{
+ m_results.push_back(DeferredTestResult(details.suiteName, details.testName));
+}
+
+void DeferredTestReporter::ReportFailure(TestDetails const& details, char const* failure)
+{
+ DeferredTestResult& r = m_results.back();
+ r.failed = true;
+ r.failures.push_back(DeferredTestResult::Failure(details.lineNumber, failure));
+ r.failureFile = details.filename;
+}
+
+void DeferredTestReporter::ReportTestFinish(TestDetails const&, float const secondsElapsed)
+{
+ DeferredTestResult& r = m_results.back();
+ r.timeElapsed = secondsElapsed;
+}
+
+DeferredTestReporter::DeferredTestResultList& DeferredTestReporter::GetResults()
+{
+ return m_results;
+}
diff --git a/libs/ode-0.16.1/tests/UnitTest++/src/DeferredTestReporter.h b/libs/ode-0.16.1/tests/UnitTest++/src/DeferredTestReporter.h
new file mode 100644
index 0000000..026ed05
--- /dev/null
+++ b/libs/ode-0.16.1/tests/UnitTest++/src/DeferredTestReporter.h
@@ -0,0 +1,28 @@
+#ifndef UNITTEST_DEFERREDTESTREPORTER_H
+#define UNITTEST_DEFERREDTESTREPORTER_H
+
+#include "TestReporter.h"
+#include "DeferredTestResult.h"
+
+#include <vector>
+
+namespace UnitTest
+{
+
+class DeferredTestReporter : public TestReporter
+{
+public:
+ virtual void ReportTestStart(TestDetails const& details);
+ virtual void ReportFailure(TestDetails const& details, char const* failure);
+ virtual void ReportTestFinish(TestDetails const& details, float secondsElapsed);
+
+ typedef std::vector< DeferredTestResult > DeferredTestResultList;
+ DeferredTestResultList& GetResults();
+
+private:
+ DeferredTestResultList m_results;
+};
+
+}
+
+#endif
diff --git a/libs/ode-0.16.1/tests/UnitTest++/src/DeferredTestResult.cpp b/libs/ode-0.16.1/tests/UnitTest++/src/DeferredTestResult.cpp
new file mode 100644
index 0000000..6e35f86
--- /dev/null
+++ b/libs/ode-0.16.1/tests/UnitTest++/src/DeferredTestResult.cpp
@@ -0,0 +1,26 @@
+#include "DeferredTestResult.h"
+
+#include <cstdlib>
+
+namespace UnitTest
+{
+
+DeferredTestResult::DeferredTestResult()
+ : suiteName("")
+ , testName("")
+ , failureFile("")
+ , timeElapsed(0.0f)
+ , failed(false)
+{
+}
+
+DeferredTestResult::DeferredTestResult(char const* suite, char const* test)
+ : suiteName(suite)
+ , testName(test)
+ , failureFile("")
+ , timeElapsed(0.0f)
+ , failed(false)
+{
+}
+
+}
diff --git a/libs/ode-0.16.1/tests/UnitTest++/src/DeferredTestResult.h b/libs/ode-0.16.1/tests/UnitTest++/src/DeferredTestResult.h
new file mode 100644
index 0000000..6cca77c
--- /dev/null
+++ b/libs/ode-0.16.1/tests/UnitTest++/src/DeferredTestResult.h
@@ -0,0 +1,29 @@
+#ifndef UNITTEST_DEFERREDTESTRESULT_H
+#define UNITTEST_DEFERREDTESTRESULT_H
+
+#include <string>
+#include <vector>
+
+namespace UnitTest
+{
+
+struct DeferredTestResult
+{
+ DeferredTestResult();
+ DeferredTestResult(char const* suite, char const* test);
+
+ std::string suiteName;
+ std::string testName;
+ std::string failureFile;
+
+ typedef std::pair< int, std::string > Failure;
+ typedef std::vector< Failure > FailureVec;
+ FailureVec failures;
+
+ float timeElapsed;
+ bool failed;
+};
+
+}
+
+#endif //UNITTEST_DEFERREDTESTRESULT_H
diff --git a/libs/ode-0.16.1/tests/UnitTest++/src/Makefile.am b/libs/ode-0.16.1/tests/UnitTest++/src/Makefile.am
new file mode 100644
index 0000000..c17c4b1
--- /dev/null
+++ b/libs/ode-0.16.1/tests/UnitTest++/src/Makefile.am
@@ -0,0 +1,33 @@
+if WIN32
+SUBDIRS = Win32
+else
+SUBDIRS = Posix
+endif
+
+
+check_LTLIBRARIES = libunittestpp.la
+
+libunittestpp_la_SOURCES = AssertException.cpp AssertException.h \
+ CheckMacros.h Checks.cpp \
+ Checks.h Config.h \
+ DeferredTestReporter.cpp DeferredTestReporter.h \
+ DeferredTestResult.cpp DeferredTestResult.h \
+ MemoryOutStream.cpp MemoryOutStream.h \
+ ReportAssert.cpp ReportAssert.h \
+ Test.cpp TestDetails.cpp \
+ TestDetails.h Test.h \
+ TestList.cpp TestList.h \
+ TestMacros.h TestReporter.cpp \
+ TestReporter.h TestReporterStdout.cpp \
+ TestReporterStdout.h TestResults.cpp \
+ TestResults.h TestRunner.cpp \
+ TestRunner.h TestSuite.h \
+ TimeConstraint.cpp TimeConstraint.h \
+ TimeHelpers.h UnitTest++.h \
+ XmlTestReporter.cpp XmlTestReporter.h
+if WIN32
+libunittestpp_la_LIBADD = $(builddir)/Win32/libhelper.la
+else
+libunittestpp_la_LIBADD = $(builddir)/Posix/libhelper.la
+endif
+
diff --git a/libs/ode-0.16.1/tests/UnitTest++/src/Makefile.in b/libs/ode-0.16.1/tests/UnitTest++/src/Makefile.in
new file mode 100644
index 0000000..a0707bd
--- /dev/null
+++ b/libs/ode-0.16.1/tests/UnitTest++/src/Makefile.in
@@ -0,0 +1,784 @@
+# 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 = tests/UnitTest++/src
+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 =
+@WIN32_FALSE@libunittestpp_la_DEPENDENCIES = \
+@WIN32_FALSE@ $(builddir)/Posix/libhelper.la
+@WIN32_TRUE@libunittestpp_la_DEPENDENCIES = \
+@WIN32_TRUE@ $(builddir)/Win32/libhelper.la
+am_libunittestpp_la_OBJECTS = AssertException.lo Checks.lo \
+ DeferredTestReporter.lo DeferredTestResult.lo \
+ MemoryOutStream.lo ReportAssert.lo Test.lo TestDetails.lo \
+ TestList.lo TestReporter.lo TestReporterStdout.lo \
+ TestResults.lo TestRunner.lo TimeConstraint.lo \
+ XmlTestReporter.lo
+libunittestpp_la_OBJECTS = $(am_libunittestpp_la_OBJECTS)
+AM_V_lt = $(am__v_lt_@AM_V@)
+am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+am__v_lt_1 =
+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 =
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/ode/src
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CXXFLAGS) $(CXXFLAGS)
+AM_V_CXX = $(am__v_CXX_@AM_V@)
+am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@)
+am__v_CXX_0 = @echo " CXX " $@;
+am__v_CXX_1 =
+CXXLD = $(CXX)
+CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
+ $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CXXLD = $(am__v_CXXLD_@AM_V@)
+am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@)
+am__v_CXXLD_0 = @echo " CXXLD " $@;
+am__v_CXXLD_1 =
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_@AM_V@)
+am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
+am__v_CC_0 = @echo " CC " $@;
+am__v_CC_1 =
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_@AM_V@)
+am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
+am__v_CCLD_0 = @echo " CCLD " $@;
+am__v_CCLD_1 =
+SOURCES = $(libunittestpp_la_SOURCES)
+DIST_SOURCES = $(libunittestpp_la_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 = Posix Win32
+am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp
+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@
+@WIN32_FALSE@SUBDIRS = Posix
+@WIN32_TRUE@SUBDIRS = Win32
+check_LTLIBRARIES = libunittestpp.la
+libunittestpp_la_SOURCES = AssertException.cpp AssertException.h \
+ CheckMacros.h Checks.cpp \
+ Checks.h Config.h \
+ DeferredTestReporter.cpp DeferredTestReporter.h \
+ DeferredTestResult.cpp DeferredTestResult.h \
+ MemoryOutStream.cpp MemoryOutStream.h \
+ ReportAssert.cpp ReportAssert.h \
+ Test.cpp TestDetails.cpp \
+ TestDetails.h Test.h \
+ TestList.cpp TestList.h \
+ TestMacros.h TestReporter.cpp \
+ TestReporter.h TestReporterStdout.cpp \
+ TestReporterStdout.h TestResults.cpp \
+ TestResults.h TestRunner.cpp \
+ TestRunner.h TestSuite.h \
+ TimeConstraint.cpp TimeConstraint.h \
+ TimeHelpers.h UnitTest++.h \
+ XmlTestReporter.cpp XmlTestReporter.h
+
+@WIN32_FALSE@libunittestpp_la_LIBADD = $(builddir)/Posix/libhelper.la
+@WIN32_TRUE@libunittestpp_la_LIBADD = $(builddir)/Win32/libhelper.la
+all: all-recursive
+
+.SUFFIXES:
+.SUFFIXES: .cpp .lo .o .obj
+$(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 tests/UnitTest++/src/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --foreign tests/UnitTest++/src/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):
+
+clean-checkLTLIBRARIES:
+ -test -z "$(check_LTLIBRARIES)" || rm -f $(check_LTLIBRARIES)
+ @list='$(check_LTLIBRARIES)'; \
+ locs=`for p in $$list; do echo $$p; done | \
+ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+ sort -u`; \
+ test -z "$$locs" || { \
+ echo rm -f $${locs}; \
+ rm -f $${locs}; \
+ }
+
+libunittestpp.la: $(libunittestpp_la_OBJECTS) $(libunittestpp_la_DEPENDENCIES) $(EXTRA_libunittestpp_la_DEPENDENCIES)
+ $(AM_V_CXXLD)$(CXXLINK) $(libunittestpp_la_OBJECTS) $(libunittestpp_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/AssertException.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Checks.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DeferredTestReporter.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DeferredTestResult.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/MemoryOutStream.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ReportAssert.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Test.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TestDetails.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TestList.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TestReporter.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TestReporterStdout.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TestResults.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TestRunner.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TimeConstraint.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/XmlTestReporter.Plo@am__quote@
+
+.cpp.o:
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $<
+
+.cpp.obj:
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.cpp.lo:
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LTCXXCOMPILE) -c -o $@ $<
+
+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
+ $(MAKE) $(AM_MAKEFLAGS) $(check_LTLIBRARIES)
+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-checkLTLIBRARIES clean-generic clean-libtool \
+ mostlyclean-am
+
+distclean: distclean-recursive
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile 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 -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-recursive
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-recursive
+
+pdf-am:
+
+ps: ps-recursive
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: $(am__recursive_targets) check-am install-am install-strip
+
+.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \
+ check-am clean clean-checkLTLIBRARIES clean-generic \
+ clean-libtool cscopelist-am ctags ctags-am distclean \
+ distclean-compile 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-compile 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/tests/UnitTest++/src/MemoryOutStream.cpp b/libs/ode-0.16.1/tests/UnitTest++/src/MemoryOutStream.cpp
new file mode 100644
index 0000000..04d4082
--- /dev/null
+++ b/libs/ode-0.16.1/tests/UnitTest++/src/MemoryOutStream.cpp
@@ -0,0 +1,143 @@
+#include "MemoryOutStream.h"
+
+#ifndef UNITTEST_USE_CUSTOM_STREAMS
+
+
+namespace UnitTest {
+
+char const* MemoryOutStream::GetText() const
+{
+ m_text = this->str();
+ return m_text.c_str();
+}
+
+
+}
+
+
+#else
+
+
+#include <cstring>
+#include <cstdio>
+
+namespace UnitTest {
+
+namespace {
+
+template<typename ValueType>
+void FormatToStream(MemoryOutStream& stream, char const* format, ValueType const& value)
+{
+ char txt[32];
+ std::sprintf(txt, format, value);
+ stream << txt;
+}
+
+int RoundUpToMultipleOfPow2Number (int n, int pow2Number)
+{
+ return (n + (pow2Number - 1)) & ~(pow2Number - 1);
+}
+
+}
+
+
+MemoryOutStream::MemoryOutStream(int const size)
+ : m_capacity (0)
+ , m_buffer (0)
+
+{
+ GrowBuffer(size);
+}
+
+MemoryOutStream::~MemoryOutStream()
+{
+ delete [] m_buffer;
+}
+
+char const* MemoryOutStream::GetText() const
+{
+ return m_buffer;
+}
+
+MemoryOutStream& MemoryOutStream::operator << (char const* txt)
+{
+ int const bytesLeft = m_capacity - (int)std::strlen(m_buffer);
+ int const bytesRequired = (int)std::strlen(txt) + 1;
+
+ if (bytesRequired > bytesLeft)
+ {
+ int const requiredCapacity = bytesRequired + m_capacity - bytesLeft;
+ GrowBuffer(requiredCapacity);
+ }
+
+ std::strcat(m_buffer, txt);
+ return *this;
+}
+
+MemoryOutStream& MemoryOutStream::operator << (int const n)
+{
+ FormatToStream(*this, "%i", n);
+ return *this;
+}
+
+MemoryOutStream& MemoryOutStream::operator << (long const n)
+{
+ FormatToStream(*this, "%li", n);
+ return *this;
+}
+
+MemoryOutStream& MemoryOutStream::operator << (unsigned long const n)
+{
+ FormatToStream(*this, "%lu", n);
+ return *this;
+}
+
+MemoryOutStream& MemoryOutStream::operator << (float const f)
+{
+ FormatToStream(*this, "%ff", f);
+ return *this;
+}
+
+MemoryOutStream& MemoryOutStream::operator << (void const* p)
+{
+ FormatToStream(*this, "%p", p);
+ return *this;
+}
+
+MemoryOutStream& MemoryOutStream::operator << (unsigned int const s)
+{
+ FormatToStream(*this, "%u", s);
+ return *this;
+}
+
+MemoryOutStream& MemoryOutStream::operator <<(double const d)
+{
+ FormatToStream(*this, "%f", d);
+ return *this;
+}
+
+int MemoryOutStream::GetCapacity() const
+{
+ return m_capacity;
+}
+
+
+void MemoryOutStream::GrowBuffer(int const desiredCapacity)
+{
+ int const newCapacity = RoundUpToMultipleOfPow2Number(desiredCapacity, GROW_CHUNK_SIZE);
+
+ char* buffer = new char[newCapacity];
+ if (m_buffer)
+ std::strcpy(buffer, m_buffer);
+ else
+ std::strcpy(buffer, "");
+
+ delete [] m_buffer;
+ m_buffer = buffer;
+ m_capacity = newCapacity;
+}
+
+}
+
+
+#endif
diff --git a/libs/ode-0.16.1/tests/UnitTest++/src/MemoryOutStream.h b/libs/ode-0.16.1/tests/UnitTest++/src/MemoryOutStream.h
new file mode 100644
index 0000000..e03227e
--- /dev/null
+++ b/libs/ode-0.16.1/tests/UnitTest++/src/MemoryOutStream.h
@@ -0,0 +1,67 @@
+#ifndef UNITTEST_MEMORYOUTSTREAM_H
+#define UNITTEST_MEMORYOUTSTREAM_H
+
+#include "Config.h"
+
+#ifndef UNITTEST_USE_CUSTOM_STREAMS
+
+#include <sstream>
+
+namespace UnitTest
+{
+
+class MemoryOutStream : public std::ostringstream
+{
+public:
+ MemoryOutStream() {}
+ char const* GetText() const;
+
+private:
+ MemoryOutStream(MemoryOutStream const&);
+ void operator =(MemoryOutStream const&);
+
+ mutable std::string m_text;
+};
+
+}
+
+#else
+
+#include <cstddef>
+
+namespace UnitTest
+{
+
+class MemoryOutStream
+{
+public:
+ explicit MemoryOutStream(int const size = 256);
+ ~MemoryOutStream();
+
+ char const* GetText() const;
+
+ MemoryOutStream& operator << (char const* txt);
+ MemoryOutStream& operator << (int n);
+ MemoryOutStream& operator << (long n);
+ MemoryOutStream& operator << (unsigned long n);
+ MemoryOutStream& operator << (float f);
+ MemoryOutStream& operator << (double d);
+ MemoryOutStream& operator << (void const* p);
+ MemoryOutStream& operator << (unsigned int s);
+
+ enum { GROW_CHUNK_SIZE = 32 };
+ int GetCapacity() const;
+
+private:
+ void operator= (MemoryOutStream const&);
+ void GrowBuffer(int capacity);
+
+ int m_capacity;
+ char* m_buffer;
+};
+
+}
+
+#endif
+
+#endif
diff --git a/libs/ode-0.16.1/tests/UnitTest++/src/Posix/Makefile.am b/libs/ode-0.16.1/tests/UnitTest++/src/Posix/Makefile.am
new file mode 100644
index 0000000..349b3c0
--- /dev/null
+++ b/libs/ode-0.16.1/tests/UnitTest++/src/Posix/Makefile.am
@@ -0,0 +1,5 @@
+check_LTLIBRARIES = libhelper.la
+
+libhelper_la_SOURCES = SignalTranslator.cpp SignalTranslator.h \
+ TimeHelpers.cpp TimeHelpers.h
+
diff --git a/libs/ode-0.16.1/tests/UnitTest++/src/Posix/Makefile.in b/libs/ode-0.16.1/tests/UnitTest++/src/Posix/Makefile.in
new file mode 100644
index 0000000..8f69c7f
--- /dev/null
+++ b/libs/ode-0.16.1/tests/UnitTest++/src/Posix/Makefile.in
@@ -0,0 +1,627 @@
+# 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 = tests/UnitTest++/src/Posix
+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 =
+libhelper_la_LIBADD =
+am_libhelper_la_OBJECTS = SignalTranslator.lo TimeHelpers.lo
+libhelper_la_OBJECTS = $(am_libhelper_la_OBJECTS)
+AM_V_lt = $(am__v_lt_@AM_V@)
+am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+am__v_lt_1 =
+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 =
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/ode/src
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CXXFLAGS) $(CXXFLAGS)
+AM_V_CXX = $(am__v_CXX_@AM_V@)
+am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@)
+am__v_CXX_0 = @echo " CXX " $@;
+am__v_CXX_1 =
+CXXLD = $(CXX)
+CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
+ $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CXXLD = $(am__v_CXXLD_@AM_V@)
+am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@)
+am__v_CXXLD_0 = @echo " CXXLD " $@;
+am__v_CXXLD_1 =
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_@AM_V@)
+am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
+am__v_CC_0 = @echo " CC " $@;
+am__v_CC_1 =
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_@AM_V@)
+am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
+am__v_CCLD_0 = @echo " CCLD " $@;
+am__v_CCLD_1 =
+SOURCES = $(libhelper_la_SOURCES)
+DIST_SOURCES = $(libhelper_la_SOURCES)
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+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 $(top_srcdir)/depcomp
+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@
+check_LTLIBRARIES = libhelper.la
+libhelper_la_SOURCES = SignalTranslator.cpp SignalTranslator.h \
+ TimeHelpers.cpp TimeHelpers.h
+
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .cpp .lo .o .obj
+$(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 tests/UnitTest++/src/Posix/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --foreign tests/UnitTest++/src/Posix/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):
+
+clean-checkLTLIBRARIES:
+ -test -z "$(check_LTLIBRARIES)" || rm -f $(check_LTLIBRARIES)
+ @list='$(check_LTLIBRARIES)'; \
+ locs=`for p in $$list; do echo $$p; done | \
+ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+ sort -u`; \
+ test -z "$$locs" || { \
+ echo rm -f $${locs}; \
+ rm -f $${locs}; \
+ }
+
+libhelper.la: $(libhelper_la_OBJECTS) $(libhelper_la_DEPENDENCIES) $(EXTRA_libhelper_la_DEPENDENCIES)
+ $(AM_V_CXXLD)$(CXXLINK) $(libhelper_la_OBJECTS) $(libhelper_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SignalTranslator.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TimeHelpers.Plo@am__quote@
+
+.cpp.o:
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $<
+
+.cpp.obj:
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.cpp.lo:
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LTCXXCOMPILE) -c -o $@ $<
+
+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
+ $(MAKE) $(AM_MAKEFLAGS) $(check_LTLIBRARIES)
+check: check-am
+all-am: Makefile
+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-checkLTLIBRARIES clean-generic clean-libtool \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile 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 -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: check-am install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean \
+ clean-checkLTLIBRARIES clean-generic clean-libtool \
+ cscopelist-am ctags ctags-am distclean distclean-compile \
+ 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-compile \
+ 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/tests/UnitTest++/src/Posix/SignalTranslator.cpp b/libs/ode-0.16.1/tests/UnitTest++/src/Posix/SignalTranslator.cpp
new file mode 100644
index 0000000..a31cb25
--- /dev/null
+++ b/libs/ode-0.16.1/tests/UnitTest++/src/Posix/SignalTranslator.cpp
@@ -0,0 +1,46 @@
+#include "SignalTranslator.h"
+
+namespace UnitTest {
+
+sigjmp_buf* SignalTranslator::s_jumpTarget = 0;
+
+namespace {
+
+void SignalHandler (int sig)
+{
+ siglongjmp(*SignalTranslator::s_jumpTarget, sig );
+}
+
+}
+
+
+SignalTranslator::SignalTranslator ()
+{
+ m_oldJumpTarget = s_jumpTarget;
+ s_jumpTarget = &m_currentJumpTarget;
+
+ struct sigaction action;
+ action.sa_flags = 0;
+ action.sa_handler = SignalHandler;
+ sigemptyset( &action.sa_mask );
+
+ sigaction( SIGSEGV, &action, &m_old_SIGSEGV_action );
+ sigaction( SIGFPE , &action, &m_old_SIGFPE_action );
+ sigaction( SIGTRAP, &action, &m_old_SIGTRAP_action );
+ sigaction( SIGBUS , &action, &m_old_SIGBUS_action );
+ sigaction( SIGILL , &action, &m_old_SIGBUS_action );
+}
+
+SignalTranslator::~SignalTranslator()
+{
+ sigaction( SIGILL , &m_old_SIGBUS_action , 0 );
+ sigaction( SIGBUS , &m_old_SIGBUS_action , 0 );
+ sigaction( SIGTRAP, &m_old_SIGTRAP_action, 0 );
+ sigaction( SIGFPE , &m_old_SIGFPE_action , 0 );
+ sigaction( SIGSEGV, &m_old_SIGSEGV_action, 0 );
+
+ s_jumpTarget = m_oldJumpTarget;
+}
+
+
+}
diff --git a/libs/ode-0.16.1/tests/UnitTest++/src/Posix/SignalTranslator.h b/libs/ode-0.16.1/tests/UnitTest++/src/Posix/SignalTranslator.h
new file mode 100644
index 0000000..dfa0d11
--- /dev/null
+++ b/libs/ode-0.16.1/tests/UnitTest++/src/Posix/SignalTranslator.h
@@ -0,0 +1,42 @@
+#ifndef UNITTEST_SIGNALTRANSLATOR_H
+#define UNITTEST_SIGNALTRANSLATOR_H
+
+#include <setjmp.h>
+#include <signal.h>
+
+namespace UnitTest {
+
+class SignalTranslator
+{
+public:
+ SignalTranslator();
+ ~SignalTranslator();
+
+ static sigjmp_buf* s_jumpTarget;
+
+private:
+ sigjmp_buf m_currentJumpTarget;
+ sigjmp_buf* m_oldJumpTarget;
+
+ struct sigaction m_old_SIGFPE_action;
+ struct sigaction m_old_SIGTRAP_action;
+ struct sigaction m_old_SIGSEGV_action;
+ struct sigaction m_old_SIGBUS_action;
+ struct sigaction m_old_SIGABRT_action;
+ struct sigaction m_old_SIGALRM_action;
+};
+
+#ifdef SOLARIS
+ #define UNITTEST_EXTENSION
+#else
+ #define UNITTEST_EXTENSION __extension__
+#endif
+
+#define UNITTEST_THROW_SIGNALS \
+ UnitTest::SignalTranslator sig; \
+ if (UNITTEST_EXTENSION sigsetjmp(*UnitTest::SignalTranslator::s_jumpTarget, 1) != 0) \
+ throw ("Unhandled system exception");
+
+}
+
+#endif
diff --git a/libs/ode-0.16.1/tests/UnitTest++/src/Posix/TimeHelpers.cpp b/libs/ode-0.16.1/tests/UnitTest++/src/Posix/TimeHelpers.cpp
new file mode 100644
index 0000000..bfd23c0
--- /dev/null
+++ b/libs/ode-0.16.1/tests/UnitTest++/src/Posix/TimeHelpers.cpp
@@ -0,0 +1,33 @@
+#include "TimeHelpers.h"
+#include <unistd.h>
+
+namespace UnitTest {
+
+Timer::Timer()
+{
+ m_startTime.tv_sec = 0;
+ m_startTime.tv_usec = 0;
+}
+
+void Timer::Start()
+{
+ gettimeofday(&m_startTime, 0);
+}
+
+
+int Timer::GetTimeInMs() const
+{
+ struct timeval currentTime;
+ gettimeofday(&currentTime, 0);
+ int const dsecs = currentTime.tv_sec - m_startTime.tv_sec;
+ int const dus = currentTime.tv_usec - m_startTime.tv_usec;
+ return dsecs*1000 + dus/1000;
+}
+
+
+void TimeHelpers::SleepMs (int ms)
+{
+ usleep(ms * 1000);
+}
+
+}
diff --git a/libs/ode-0.16.1/tests/UnitTest++/src/Posix/TimeHelpers.h b/libs/ode-0.16.1/tests/UnitTest++/src/Posix/TimeHelpers.h
new file mode 100644
index 0000000..fdc8428
--- /dev/null
+++ b/libs/ode-0.16.1/tests/UnitTest++/src/Posix/TimeHelpers.h
@@ -0,0 +1,28 @@
+#ifndef UNITTEST_TIMEHELPERS_H
+#define UNITTEST_TIMEHELPERS_H
+
+#include <sys/time.h>
+
+namespace UnitTest {
+
+class Timer
+{
+public:
+ Timer();
+ void Start();
+ int GetTimeInMs() const;
+
+private:
+ struct timeval m_startTime;
+};
+
+
+namespace TimeHelpers
+{
+void SleepMs (int ms);
+}
+
+
+}
+
+#endif
diff --git a/libs/ode-0.16.1/tests/UnitTest++/src/ReportAssert.cpp b/libs/ode-0.16.1/tests/UnitTest++/src/ReportAssert.cpp
new file mode 100644
index 0000000..6c7db58
--- /dev/null
+++ b/libs/ode-0.16.1/tests/UnitTest++/src/ReportAssert.cpp
@@ -0,0 +1,10 @@
+#include "AssertException.h"
+
+namespace UnitTest {
+
+void ReportAssert(char const* description, char const* filename, int const lineNumber)
+{
+ throw AssertException(description, filename, lineNumber);
+}
+
+}
diff --git a/libs/ode-0.16.1/tests/UnitTest++/src/ReportAssert.h b/libs/ode-0.16.1/tests/UnitTest++/src/ReportAssert.h
new file mode 100644
index 0000000..d4dd864
--- /dev/null
+++ b/libs/ode-0.16.1/tests/UnitTest++/src/ReportAssert.h
@@ -0,0 +1,10 @@
+#ifndef UNITTEST_ASSERT_H
+#define UNITTEST_ASSERT_H
+
+namespace UnitTest {
+
+void ReportAssert(char const* description, char const* filename, int lineNumber);
+
+}
+
+#endif
diff --git a/libs/ode-0.16.1/tests/UnitTest++/src/Test.cpp b/libs/ode-0.16.1/tests/UnitTest++/src/Test.cpp
new file mode 100644
index 0000000..943fced
--- /dev/null
+++ b/libs/ode-0.16.1/tests/UnitTest++/src/Test.cpp
@@ -0,0 +1,62 @@
+#include "Config.h"
+#include "Test.h"
+#include "TestList.h"
+#include "TestResults.h"
+#include "AssertException.h"
+#include "MemoryOutStream.h"
+
+#ifdef UNITTEST_POSIX
+ #include "Posix/SignalTranslator.h"
+#endif
+
+namespace UnitTest {
+
+TestList& Test::GetTestList()
+{
+ static TestList s_list;
+ return s_list;
+}
+
+Test::Test(char const* testName, char const* suiteName, char const* filename, int const lineNumber)
+ : m_details(testName, suiteName, filename, lineNumber)
+ , next(0)
+ , m_timeConstraintExempt(false)
+{
+}
+
+Test::~Test()
+{
+}
+
+void Test::Run(TestResults& testResults) const
+{
+ try
+ {
+#ifdef UNITTEST_POSIX
+ UNITTEST_THROW_SIGNALS
+#endif
+ RunImpl(testResults);
+ }
+ catch (AssertException const& e)
+ {
+ testResults.OnTestFailure( TestDetails(m_details.testName, m_details.suiteName, e.Filename(), e.LineNumber()), e.what());
+ }
+ catch (std::exception const& e)
+ {
+ MemoryOutStream stream;
+ stream << "Unhandled exception: " << e.what();
+ testResults.OnTestFailure(m_details, stream.GetText());
+ }
+ catch (...)
+ {
+ testResults.OnTestFailure(m_details, "Unhandled exception: Crash!");
+ }
+}
+
+
+void Test::RunImpl(TestResults&) const
+{
+}
+
+
+}
diff --git a/libs/ode-0.16.1/tests/UnitTest++/src/Test.h b/libs/ode-0.16.1/tests/UnitTest++/src/Test.h
new file mode 100644
index 0000000..458c75c
--- /dev/null
+++ b/libs/ode-0.16.1/tests/UnitTest++/src/Test.h
@@ -0,0 +1,34 @@
+#ifndef UNITTEST_TEST_H
+#define UNITTEST_TEST_H
+
+#include "TestDetails.h"
+
+namespace UnitTest {
+
+class TestResults;
+class TestList;
+
+class Test
+{
+public:
+ Test(char const* testName, char const* suiteName = "DefaultSuite", char const* filename = "", int lineNumber = 0);
+ virtual ~Test();
+ void Run(TestResults& testResults) const;
+
+ TestDetails const m_details;
+ Test* next;
+ mutable bool m_timeConstraintExempt;
+
+ static TestList& GetTestList();
+
+private:
+ virtual void RunImpl(TestResults& testResults_) const;
+
+ Test(Test const&);
+ Test& operator =(Test const&);
+};
+
+
+}
+
+#endif
diff --git a/libs/ode-0.16.1/tests/UnitTest++/src/TestDetails.cpp b/libs/ode-0.16.1/tests/UnitTest++/src/TestDetails.cpp
new file mode 100644
index 0000000..a13a168
--- /dev/null
+++ b/libs/ode-0.16.1/tests/UnitTest++/src/TestDetails.cpp
@@ -0,0 +1,22 @@
+#include "TestDetails.h"
+
+namespace UnitTest {
+
+TestDetails::TestDetails(char const* testName_, char const* suiteName_, char const* filename_, int lineNumber_)
+ : suiteName(suiteName_)
+ , testName(testName_)
+ , filename(filename_)
+ , lineNumber(lineNumber_)
+{
+}
+
+TestDetails::TestDetails(const TestDetails& details, int lineNumber_)
+ : suiteName(details.suiteName)
+ , testName(details.testName)
+ , filename(details.filename)
+ , lineNumber(lineNumber_)
+{
+}
+
+
+}
diff --git a/libs/ode-0.16.1/tests/UnitTest++/src/TestDetails.h b/libs/ode-0.16.1/tests/UnitTest++/src/TestDetails.h
new file mode 100644
index 0000000..eae0e71
--- /dev/null
+++ b/libs/ode-0.16.1/tests/UnitTest++/src/TestDetails.h
@@ -0,0 +1,24 @@
+#ifndef UNITTEST_TESTDETAILS_H
+#define UNITTEST_TESTDETAILS_H
+
+namespace UnitTest {
+
+class TestDetails
+{
+public:
+ TestDetails(char const* testName, char const* suiteName, char const* filename, int lineNumber);
+ TestDetails(const TestDetails& details, int lineNumber);
+
+ char const* const suiteName;
+ char const* const testName;
+ char const* const filename;
+ int const lineNumber;
+
+ TestDetails(TestDetails const&); // Why is it public? --> http://gcc.gnu.org/bugs.html#cxx_rvalbind
+private:
+ TestDetails& operator=(TestDetails const&);
+};
+
+}
+
+#endif
diff --git a/libs/ode-0.16.1/tests/UnitTest++/src/TestList.cpp b/libs/ode-0.16.1/tests/UnitTest++/src/TestList.cpp
new file mode 100644
index 0000000..d11965c
--- /dev/null
+++ b/libs/ode-0.16.1/tests/UnitTest++/src/TestList.cpp
@@ -0,0 +1,39 @@
+#include "TestList.h"
+#include "Test.h"
+
+#include <cassert>
+
+namespace UnitTest {
+
+TestList::TestList()
+ : m_head(0)
+ , m_tail(0)
+{
+}
+
+void TestList::Add(Test* test)
+{
+ if (m_tail == 0)
+ {
+ assert(m_head == 0);
+ m_head = test;
+ m_tail = test;
+ }
+ else
+ {
+ m_tail->next = test;
+ m_tail = test;
+ }
+}
+
+const Test* TestList::GetHead() const
+{
+ return m_head;
+}
+
+ListAdder::ListAdder(TestList& list, Test* test)
+{
+ list.Add(test);
+}
+
+}
diff --git a/libs/ode-0.16.1/tests/UnitTest++/src/TestList.h b/libs/ode-0.16.1/tests/UnitTest++/src/TestList.h
new file mode 100644
index 0000000..14b978a
--- /dev/null
+++ b/libs/ode-0.16.1/tests/UnitTest++/src/TestList.h
@@ -0,0 +1,32 @@
+#ifndef UNITTEST_TESTLIST_H
+#define UNITTEST_TESTLIST_H
+
+
+namespace UnitTest {
+
+class Test;
+
+class TestList
+{
+public:
+ TestList();
+ void Add (Test* test);
+
+ const Test* GetHead() const;
+
+private:
+ Test* m_head;
+ Test* m_tail;
+};
+
+
+class ListAdder
+{
+public:
+ ListAdder(TestList& list, Test* test);
+};
+
+}
+
+
+#endif
diff --git a/libs/ode-0.16.1/tests/UnitTest++/src/TestMacros.h b/libs/ode-0.16.1/tests/UnitTest++/src/TestMacros.h
new file mode 100644
index 0000000..09ecc6b
--- /dev/null
+++ b/libs/ode-0.16.1/tests/UnitTest++/src/TestMacros.h
@@ -0,0 +1,99 @@
+#ifndef UNITTEST_TESTMACROS_H
+#define UNITTEST_TESTMACROS_H
+
+#include "Config.h"
+
+#ifndef UNITTEST_POSIX
+ #define UNITTEST_THROW_SIGNALS
+#else
+ #include "Posix/SignalTranslator.h"
+#endif
+
+#ifdef TEST
+ #error UnitTest++ redefines TEST
+#endif
+
+#define SUITE(Name) \
+ namespace Name { \
+ namespace UnitTestSuite { \
+ inline char const* GetSuiteName () { \
+ return #Name ; \
+ } \
+ } \
+ } \
+ namespace Name
+
+#define TEST_EX(Name, List) \
+ class Test##Name : public UnitTest::Test \
+ { \
+ public: \
+ Test##Name() : Test(#Name, UnitTestSuite::GetSuiteName(), __FILE__, __LINE__) {} \
+ private: \
+ virtual void RunImpl(UnitTest::TestResults& testResults_) const; \
+ } test##Name##Instance; \
+ \
+ UnitTest::ListAdder adder##Name (List, &test##Name##Instance); \
+ \
+ void Test##Name::RunImpl(UnitTest::TestResults& testResults_) const
+
+
+#define TEST(Name) TEST_EX(Name, UnitTest::Test::GetTestList())
+
+
+#define TEST_FIXTURE_EX(Fixture, Name, List) \
+ class Fixture##Name##Helper : public Fixture \
+ { \
+ public: \
+ Fixture##Name##Helper(UnitTest::TestDetails const& details) : m_details(details) {} \
+ void RunTest(UnitTest::TestResults& testResults_); \
+ UnitTest::TestDetails const& m_details; \
+ private: \
+ Fixture##Name##Helper(Fixture##Name##Helper const&); \
+ Fixture##Name##Helper& operator =(Fixture##Name##Helper const&); \
+ }; \
+ \
+ class Test##Fixture##Name : public UnitTest::Test \
+ { \
+ public: \
+ Test##Fixture##Name() : Test(#Name, UnitTestSuite::GetSuiteName(), __FILE__, __LINE__) {} \
+ private: \
+ virtual void RunImpl(UnitTest::TestResults& testResults_) const; \
+ } test##Fixture##Name##Instance; \
+ \
+ UnitTest::ListAdder adder##Fixture##Name (List, &test##Fixture##Name##Instance); \
+ \
+ void Test##Fixture##Name::RunImpl(UnitTest::TestResults& testResults_) const \
+ { \
+ bool ctorOk = false; \
+ try { \
+ Fixture##Name##Helper fixtureHelper(m_details); \
+ ctorOk = true; \
+ try { \
+ UNITTEST_THROW_SIGNALS; \
+ fixtureHelper.RunTest(testResults_); \
+ } catch (UnitTest::AssertException const& e) { \
+ testResults_.OnTestFailure(UnitTest::TestDetails(m_details.testName, m_details.suiteName, e.Filename(), e.LineNumber()), e.what()); \
+ } catch (std::exception const& e) { \
+ UnitTest::MemoryOutStream stream; \
+ stream << "Unhandled exception: " << e.what(); \
+ testResults_.OnTestFailure(m_details, stream.GetText()); \
+ } catch (...) { testResults_.OnTestFailure(m_details, "Unhandled exception: Crash!"); } \
+ } \
+ catch (...) { \
+ if (ctorOk) \
+ { \
+ testResults_.OnTestFailure(UnitTest::TestDetails(m_details, __LINE__), \
+ "Unhandled exception while destroying fixture " #Fixture); \
+ } \
+ else \
+ { \
+ testResults_.OnTestFailure(UnitTest::TestDetails(m_details, __LINE__), \
+ "Unhandled exception while constructing fixture " #Fixture); \
+ } \
+ } \
+ } \
+ void Fixture##Name##Helper::RunTest(UnitTest::TestResults& testResults_)
+
+#define TEST_FIXTURE(Fixture,Name) TEST_FIXTURE_EX(Fixture, Name, UnitTest::Test::GetTestList())
+
+#endif
diff --git a/libs/ode-0.16.1/tests/UnitTest++/src/TestReporter.cpp b/libs/ode-0.16.1/tests/UnitTest++/src/TestReporter.cpp
new file mode 100644
index 0000000..608d3c6
--- /dev/null
+++ b/libs/ode-0.16.1/tests/UnitTest++/src/TestReporter.cpp
@@ -0,0 +1,10 @@
+#include "TestReporter.h"
+
+namespace UnitTest {
+
+
+TestReporter::~TestReporter()
+{
+}
+
+}
diff --git a/libs/ode-0.16.1/tests/UnitTest++/src/TestReporter.h b/libs/ode-0.16.1/tests/UnitTest++/src/TestReporter.h
new file mode 100644
index 0000000..5a2f404
--- /dev/null
+++ b/libs/ode-0.16.1/tests/UnitTest++/src/TestReporter.h
@@ -0,0 +1,20 @@
+#ifndef UNITTEST_TESTREPORTER_H
+#define UNITTEST_TESTREPORTER_H
+
+namespace UnitTest {
+
+class TestDetails;
+
+class TestReporter
+{
+public:
+ virtual ~TestReporter();
+
+ virtual void ReportTestStart(TestDetails const& test) = 0;
+ virtual void ReportFailure(TestDetails const& test, char const* failure) = 0;
+ virtual void ReportTestFinish(TestDetails const& test, float secondsElapsed) = 0;
+ virtual void ReportSummary(int totalTestCount, int failedTestCount, int failureCount, float secondsElapsed) = 0;
+};
+
+}
+#endif
diff --git a/libs/ode-0.16.1/tests/UnitTest++/src/TestReporterStdout.cpp b/libs/ode-0.16.1/tests/UnitTest++/src/TestReporterStdout.cpp
new file mode 100644
index 0000000..133e6fa
--- /dev/null
+++ b/libs/ode-0.16.1/tests/UnitTest++/src/TestReporterStdout.cpp
@@ -0,0 +1,36 @@
+#include "TestReporterStdout.h"
+#include <cstdio>
+
+#include "TestDetails.h"
+
+namespace UnitTest {
+
+void TestReporterStdout::ReportFailure(TestDetails const& details, char const* failure)
+{
+#ifdef __APPLE__
+ char const* const errorFormat = "%s:%d: error: Failure in %s: %s\n";
+#else
+ char const* const errorFormat = "%s(%d): error: Failure in %s: %s\n";
+#endif
+ std::printf(errorFormat, details.filename, details.lineNumber, details.testName, failure);
+}
+
+void TestReporterStdout::ReportTestStart(TestDetails const& /*test*/)
+{
+}
+
+void TestReporterStdout::ReportTestFinish(TestDetails const& /*test*/, float)
+{
+}
+
+void TestReporterStdout::ReportSummary(int const totalTestCount, int const failedTestCount,
+ int const failureCount, float secondsElapsed)
+{
+ if (failureCount > 0)
+ std::printf("FAILURE: %d out of %d tests failed (%d failures).\n", failedTestCount, totalTestCount, failureCount);
+ else
+ std::printf("Success: %d tests passed.\n", totalTestCount);
+ std::printf("Test time: %.2f seconds.\n", secondsElapsed);
+}
+
+}
diff --git a/libs/ode-0.16.1/tests/UnitTest++/src/TestReporterStdout.h b/libs/ode-0.16.1/tests/UnitTest++/src/TestReporterStdout.h
new file mode 100644
index 0000000..eacbba3
--- /dev/null
+++ b/libs/ode-0.16.1/tests/UnitTest++/src/TestReporterStdout.h
@@ -0,0 +1,19 @@
+#ifndef UNITTEST_TESTREPORTERSTDOUT_H
+#define UNITTEST_TESTREPORTERSTDOUT_H
+
+#include "TestReporter.h"
+
+namespace UnitTest {
+
+class TestReporterStdout : public TestReporter
+{
+private:
+ virtual void ReportTestStart(TestDetails const& test);
+ virtual void ReportFailure(TestDetails const& test, char const* failure);
+ virtual void ReportTestFinish(TestDetails const& test, float secondsElapsed);
+ virtual void ReportSummary(int totalTestCount, int failedTestCount, int failureCount, float secondsElapsed);
+};
+
+}
+
+#endif
diff --git a/libs/ode-0.16.1/tests/UnitTest++/src/TestResults.cpp b/libs/ode-0.16.1/tests/UnitTest++/src/TestResults.cpp
new file mode 100644
index 0000000..b3b67c0
--- /dev/null
+++ b/libs/ode-0.16.1/tests/UnitTest++/src/TestResults.cpp
@@ -0,0 +1,60 @@
+#include "TestResults.h"
+#include "TestReporter.h"
+
+#include "TestDetails.h"
+
+namespace UnitTest {
+
+TestResults::TestResults(TestReporter* testReporter)
+ : m_testReporter(testReporter)
+ , m_totalTestCount(0)
+ , m_failedTestCount(0)
+ , m_failureCount(0)
+ , m_currentTestFailed(false)
+{
+}
+
+void TestResults::OnTestStart(TestDetails const& test)
+{
+ ++m_totalTestCount;
+ m_currentTestFailed = false;
+ if (m_testReporter)
+ m_testReporter->ReportTestStart(test);
+}
+
+void TestResults::OnTestFailure(TestDetails const& test, char const* failure)
+{
+ ++m_failureCount;
+ if (!m_currentTestFailed)
+ {
+ ++m_failedTestCount;
+ m_currentTestFailed = true;
+ }
+
+ if (m_testReporter)
+ m_testReporter->ReportFailure(test, failure);
+}
+
+void TestResults::OnTestFinish(TestDetails const& test, float secondsElapsed)
+{
+ if (m_testReporter)
+ m_testReporter->ReportTestFinish(test, secondsElapsed);
+}
+
+int TestResults::GetTotalTestCount() const
+{
+ return m_totalTestCount;
+}
+
+int TestResults::GetFailedTestCount() const
+{
+ return m_failedTestCount;
+}
+
+int TestResults::GetFailureCount() const
+{
+ return m_failureCount;
+}
+
+
+}
diff --git a/libs/ode-0.16.1/tests/UnitTest++/src/TestResults.h b/libs/ode-0.16.1/tests/UnitTest++/src/TestResults.h
new file mode 100644
index 0000000..8ef7fda
--- /dev/null
+++ b/libs/ode-0.16.1/tests/UnitTest++/src/TestResults.h
@@ -0,0 +1,36 @@
+#ifndef UNITTEST_TESTRESULTS_H
+#define UNITTEST_TESTRESULTS_H
+
+namespace UnitTest {
+
+class TestReporter;
+class TestDetails;
+
+class TestResults
+{
+public:
+ explicit TestResults(TestReporter* reporter = 0);
+
+ void OnTestStart(TestDetails const& test);
+ void OnTestFailure(TestDetails const& test, char const* failure);
+ void OnTestFinish(TestDetails const& test, float secondsElapsed);
+
+ int GetTotalTestCount() const;
+ int GetFailedTestCount() const;
+ int GetFailureCount() const;
+
+private:
+ TestReporter* m_testReporter;
+ int m_totalTestCount;
+ int m_failedTestCount;
+ int m_failureCount;
+
+ bool m_currentTestFailed;
+
+ TestResults(TestResults const&);
+ TestResults& operator =(TestResults const&);
+};
+
+}
+
+#endif
diff --git a/libs/ode-0.16.1/tests/UnitTest++/src/TestRunner.cpp b/libs/ode-0.16.1/tests/UnitTest++/src/TestRunner.cpp
new file mode 100644
index 0000000..5780d91
--- /dev/null
+++ b/libs/ode-0.16.1/tests/UnitTest++/src/TestRunner.cpp
@@ -0,0 +1,60 @@
+#include "TestRunner.h"
+#include "TestResults.h"
+#include "Test.h"
+#include "TestList.h"
+#include "TestReporter.h"
+#include "TestReporterStdout.h"
+#include "TimeHelpers.h"
+#include "MemoryOutStream.h"
+#include <cstring>
+
+
+namespace UnitTest {
+
+
+int RunAllTests(TestReporter& reporter, TestList const& list, char const* suiteName, int const maxTestTimeInMs )
+{
+ TestResults result(&reporter);
+
+ Timer overallTimer;
+ overallTimer.Start();
+
+ Test const* curTest = list.GetHead();
+ while (curTest != 0)
+ {
+ if (suiteName == 0 || !std::strcmp(curTest->m_details.suiteName, suiteName))
+ {
+ Timer testTimer;
+ testTimer.Start();
+ result.OnTestStart(curTest->m_details);
+
+ curTest->Run(result);
+
+ int const testTimeInMs = testTimer.GetTimeInMs();
+ if (maxTestTimeInMs > 0 && testTimeInMs > maxTestTimeInMs && !curTest->m_timeConstraintExempt)
+ {
+ MemoryOutStream stream;
+ stream << "Global time constraint failed. Expected under " << maxTestTimeInMs <<
+ "ms but took " << testTimeInMs << "ms.";
+ result.OnTestFailure(curTest->m_details, stream.GetText());
+ }
+ result.OnTestFinish(curTest->m_details, testTimeInMs/1000.0f);
+ }
+
+ curTest = curTest->next;
+ }
+
+ float const secondsElapsed = overallTimer.GetTimeInMs() / 1000.0f;
+ reporter.ReportSummary(result.GetTotalTestCount(), result.GetFailedTestCount(), result.GetFailureCount(), secondsElapsed);
+
+ return result.GetFailureCount();
+}
+
+
+int RunAllTests()
+{
+ TestReporterStdout reporter;
+ return RunAllTests(reporter, Test::GetTestList(), 0);
+}
+
+}
diff --git a/libs/ode-0.16.1/tests/UnitTest++/src/TestRunner.h b/libs/ode-0.16.1/tests/UnitTest++/src/TestRunner.h
new file mode 100644
index 0000000..8b9934a
--- /dev/null
+++ b/libs/ode-0.16.1/tests/UnitTest++/src/TestRunner.h
@@ -0,0 +1,17 @@
+#ifndef UNITTEST_TESTRUNNER_H
+#define UNITTEST_TESTRUNNER_H
+
+
+namespace UnitTest {
+
+class TestReporter;
+class TestList;
+
+
+int RunAllTests();
+int RunAllTests(TestReporter& reporter, TestList const& list, char const* suiteName, int maxTestTimeInMs = 0);
+
+}
+
+
+#endif
diff --git a/libs/ode-0.16.1/tests/UnitTest++/src/TestSuite.h b/libs/ode-0.16.1/tests/UnitTest++/src/TestSuite.h
new file mode 100644
index 0000000..dd3717e
--- /dev/null
+++ b/libs/ode-0.16.1/tests/UnitTest++/src/TestSuite.h
@@ -0,0 +1,14 @@
+#ifndef UNITTEST_TESTSUITE_H
+#define UNITTEST_TESTSUITE_H
+
+namespace UnitTestSuite {
+
+ inline char const* GetSuiteName ()
+ {
+ return "DefaultSuite";
+ }
+
+}
+
+#endif
+
diff --git a/libs/ode-0.16.1/tests/UnitTest++/src/TimeConstraint.cpp b/libs/ode-0.16.1/tests/UnitTest++/src/TimeConstraint.cpp
new file mode 100644
index 0000000..451c2b3
--- /dev/null
+++ b/libs/ode-0.16.1/tests/UnitTest++/src/TimeConstraint.cpp
@@ -0,0 +1,28 @@
+#include "TimeConstraint.h"
+#include "TestResults.h"
+#include "MemoryOutStream.h"
+
+namespace UnitTest {
+
+
+TimeConstraint::TimeConstraint(int ms, TestResults& result, TestDetails const& details)
+ : m_result(result)
+ , m_details(details)
+ , m_maxMs(ms)
+{
+ m_timer.Start();
+}
+
+TimeConstraint::~TimeConstraint()
+{
+ int const totalTimeInMs = m_timer.GetTimeInMs();
+ if (totalTimeInMs > m_maxMs)
+ {
+ MemoryOutStream stream;
+ stream << "Time constraint failed. Expected to run test under " << m_maxMs <<
+ "ms but took " << totalTimeInMs << "ms.";
+ m_result.OnTestFailure(m_details, stream.GetText());
+ }
+}
+
+}
diff --git a/libs/ode-0.16.1/tests/UnitTest++/src/TimeConstraint.h b/libs/ode-0.16.1/tests/UnitTest++/src/TimeConstraint.h
new file mode 100644
index 0000000..8451c66
--- /dev/null
+++ b/libs/ode-0.16.1/tests/UnitTest++/src/TimeConstraint.h
@@ -0,0 +1,34 @@
+#ifndef UNITTEST_TIMECONSTRAINT_H
+#define UNITTEST_TIMECONSTRAINT_H
+
+#include "TimeHelpers.h"
+
+namespace UnitTest {
+
+class TestResults;
+class TestDetails;
+
+class TimeConstraint
+{
+public:
+ TimeConstraint(int ms, TestResults& result, TestDetails const& details);
+ ~TimeConstraint();
+
+private:
+ void operator=(TimeConstraint const&);
+ TimeConstraint(TimeConstraint const&);
+
+ Timer m_timer;
+ TestResults& m_result;
+ TestDetails const& m_details;
+ int const m_maxMs;
+};
+
+#define UNITTEST_TIME_CONSTRAINT(ms) \
+ UnitTest::TimeConstraint unitTest__timeConstraint__(ms, testResults_, UnitTest::TestDetails(m_details, __LINE__))
+
+#define UNITTEST_TIME_CONSTRAINT_EXEMPT() do { m_timeConstraintExempt = true; } while (0)
+
+}
+
+#endif
diff --git a/libs/ode-0.16.1/tests/UnitTest++/src/TimeHelpers.h b/libs/ode-0.16.1/tests/UnitTest++/src/TimeHelpers.h
new file mode 100644
index 0000000..f34ed00
--- /dev/null
+++ b/libs/ode-0.16.1/tests/UnitTest++/src/TimeHelpers.h
@@ -0,0 +1,7 @@
+#include "Config.h"
+
+#if defined UNITTEST_POSIX
+ #include "Posix/TimeHelpers.h"
+#else
+ #include "Win32/TimeHelpers.h"
+#endif
diff --git a/libs/ode-0.16.1/tests/UnitTest++/src/UnitTest++.h b/libs/ode-0.16.1/tests/UnitTest++/src/UnitTest++.h
new file mode 100644
index 0000000..019f80a
--- /dev/null
+++ b/libs/ode-0.16.1/tests/UnitTest++/src/UnitTest++.h
@@ -0,0 +1,17 @@
+#ifndef UNITTESTCPP_H
+#define UNITTESTCPP_H
+
+#include "Config.h"
+#include "Test.h"
+#include "TestList.h"
+#include "TestSuite.h"
+#include "TestResults.h"
+
+#include <new>
+#include "TestMacros.h"
+
+#include "CheckMacros.h"
+#include "TestRunner.h"
+#include "TimeConstraint.h"
+
+#endif
diff --git a/libs/ode-0.16.1/tests/UnitTest++/src/Win32/Makefile.am b/libs/ode-0.16.1/tests/UnitTest++/src/Win32/Makefile.am
new file mode 100644
index 0000000..faa35b8
--- /dev/null
+++ b/libs/ode-0.16.1/tests/UnitTest++/src/Win32/Makefile.am
@@ -0,0 +1,4 @@
+check_LTLIBRARIES = libhelper.la
+
+libhelper_la_SOURCES = TimeHelpers.cpp TimeHelpers.h
+
diff --git a/libs/ode-0.16.1/tests/UnitTest++/src/Win32/Makefile.in b/libs/ode-0.16.1/tests/UnitTest++/src/Win32/Makefile.in
new file mode 100644
index 0000000..0595763
--- /dev/null
+++ b/libs/ode-0.16.1/tests/UnitTest++/src/Win32/Makefile.in
@@ -0,0 +1,624 @@
+# 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 = tests/UnitTest++/src/Win32
+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 =
+libhelper_la_LIBADD =
+am_libhelper_la_OBJECTS = TimeHelpers.lo
+libhelper_la_OBJECTS = $(am_libhelper_la_OBJECTS)
+AM_V_lt = $(am__v_lt_@AM_V@)
+am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+am__v_lt_1 =
+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 =
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/ode/src
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CXXFLAGS) $(CXXFLAGS)
+AM_V_CXX = $(am__v_CXX_@AM_V@)
+am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@)
+am__v_CXX_0 = @echo " CXX " $@;
+am__v_CXX_1 =
+CXXLD = $(CXX)
+CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
+ $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CXXLD = $(am__v_CXXLD_@AM_V@)
+am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@)
+am__v_CXXLD_0 = @echo " CXXLD " $@;
+am__v_CXXLD_1 =
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_@AM_V@)
+am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
+am__v_CC_0 = @echo " CC " $@;
+am__v_CC_1 =
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_@AM_V@)
+am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
+am__v_CCLD_0 = @echo " CCLD " $@;
+am__v_CCLD_1 =
+SOURCES = $(libhelper_la_SOURCES)
+DIST_SOURCES = $(libhelper_la_SOURCES)
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+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 $(top_srcdir)/depcomp
+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@
+check_LTLIBRARIES = libhelper.la
+libhelper_la_SOURCES = TimeHelpers.cpp TimeHelpers.h
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .cpp .lo .o .obj
+$(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 tests/UnitTest++/src/Win32/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --foreign tests/UnitTest++/src/Win32/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):
+
+clean-checkLTLIBRARIES:
+ -test -z "$(check_LTLIBRARIES)" || rm -f $(check_LTLIBRARIES)
+ @list='$(check_LTLIBRARIES)'; \
+ locs=`for p in $$list; do echo $$p; done | \
+ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+ sort -u`; \
+ test -z "$$locs" || { \
+ echo rm -f $${locs}; \
+ rm -f $${locs}; \
+ }
+
+libhelper.la: $(libhelper_la_OBJECTS) $(libhelper_la_DEPENDENCIES) $(EXTRA_libhelper_la_DEPENDENCIES)
+ $(AM_V_CXXLD)$(CXXLINK) $(libhelper_la_OBJECTS) $(libhelper_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TimeHelpers.Plo@am__quote@
+
+.cpp.o:
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $<
+
+.cpp.obj:
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.cpp.lo:
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LTCXXCOMPILE) -c -o $@ $<
+
+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
+ $(MAKE) $(AM_MAKEFLAGS) $(check_LTLIBRARIES)
+check: check-am
+all-am: Makefile
+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-checkLTLIBRARIES clean-generic clean-libtool \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile 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 -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: check-am install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean \
+ clean-checkLTLIBRARIES clean-generic clean-libtool \
+ cscopelist-am ctags ctags-am distclean distclean-compile \
+ 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-compile \
+ 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/tests/UnitTest++/src/Win32/TimeHelpers.cpp b/libs/ode-0.16.1/tests/UnitTest++/src/Win32/TimeHelpers.cpp
new file mode 100644
index 0000000..7c3dae8
--- /dev/null
+++ b/libs/ode-0.16.1/tests/UnitTest++/src/Win32/TimeHelpers.cpp
@@ -0,0 +1,46 @@
+#include "TimeHelpers.h"
+#include <windows.h>
+
+namespace UnitTest {
+
+Timer::Timer()
+ : m_startTime(0)
+{
+ m_threadId = ::GetCurrentThread();
+ DWORD_PTR systemMask;
+ ::GetProcessAffinityMask(GetCurrentProcess(), &m_processAffinityMask, &systemMask);
+
+ ::SetThreadAffinityMask(m_threadId, 1);
+ ::QueryPerformanceFrequency(reinterpret_cast< LARGE_INTEGER* >(&m_frequency));
+ ::SetThreadAffinityMask(m_threadId, m_processAffinityMask);
+}
+
+void Timer::Start()
+{
+ m_startTime = GetTime();
+}
+
+int Timer::GetTimeInMs() const
+{
+ __int64 const elapsedTime = GetTime() - m_startTime;
+ double const seconds = double(elapsedTime) / double(m_frequency);
+ return int(seconds * 1000.0f);
+}
+
+__int64 Timer::GetTime() const
+{
+ LARGE_INTEGER curTime;
+ ::SetThreadAffinityMask(m_threadId, 1);
+ ::QueryPerformanceCounter(&curTime);
+ ::SetThreadAffinityMask(m_threadId, m_processAffinityMask);
+ return curTime.QuadPart;
+}
+
+
+
+void TimeHelpers::SleepMs(int const ms)
+{
+ ::Sleep(ms);
+}
+
+}
diff --git a/libs/ode-0.16.1/tests/UnitTest++/src/Win32/TimeHelpers.h b/libs/ode-0.16.1/tests/UnitTest++/src/Win32/TimeHelpers.h
new file mode 100644
index 0000000..56e30d5
--- /dev/null
+++ b/libs/ode-0.16.1/tests/UnitTest++/src/Win32/TimeHelpers.h
@@ -0,0 +1,48 @@
+#ifndef UNITTEST_TIMEHELPERS_H
+#define UNITTEST_TIMEHELPERS_H
+
+#include "../Config.h"
+
+
+#ifdef UNITTEST_MINGW
+ #ifndef __int64
+ #define __int64 long long
+ #endif
+#endif
+
+namespace UnitTest {
+
+class Timer
+{
+public:
+ Timer();
+ void Start();
+ int GetTimeInMs() const;
+
+private:
+ __int64 GetTime() const;
+
+ void* m_threadId;
+
+#if defined(_WIN64)
+ unsigned __int64 m_processAffinityMask;
+#else
+ unsigned long m_processAffinityMask;
+#endif
+
+ __int64 m_startTime;
+ __int64 m_frequency;
+};
+
+
+namespace TimeHelpers
+{
+void SleepMs (int ms);
+}
+
+
+}
+
+
+
+#endif
diff --git a/libs/ode-0.16.1/tests/UnitTest++/src/XmlTestReporter.cpp b/libs/ode-0.16.1/tests/UnitTest++/src/XmlTestReporter.cpp
new file mode 100644
index 0000000..0895e37
--- /dev/null
+++ b/libs/ode-0.16.1/tests/UnitTest++/src/XmlTestReporter.cpp
@@ -0,0 +1,126 @@
+#include "XmlTestReporter.h"
+
+#include <iostream>
+#include <sstream>
+#include <string>
+
+using std::string;
+using std::ostringstream;
+using std::ostream;
+
+namespace {
+
+void ReplaceChar(string& str, char const c, string const& replacement)
+{
+ for (size_t pos = str.find(c); pos != string::npos; pos = str.find(c, pos + 1))
+ str.replace(pos, 1, replacement);
+}
+
+string XmlEscape(string const& value)
+{
+ string escaped = value;
+
+ ReplaceChar(escaped, '&', "&amp;");
+ ReplaceChar(escaped, '<', "&lt;");
+ ReplaceChar(escaped, '>', "&gt;");
+ ReplaceChar(escaped, '\'', "&apos;");
+ ReplaceChar(escaped, '\"', "&quot;");
+
+ return escaped;
+}
+
+string BuildFailureMessage(string const& file, int const line, string const& message)
+{
+ ostringstream failureMessage;
+ failureMessage << file << "(" << line << ") : " << message;
+ return failureMessage.str();
+}
+
+}
+
+namespace UnitTest {
+
+XmlTestReporter::XmlTestReporter(ostream& ostream)
+ : m_ostream(ostream)
+{
+}
+
+void XmlTestReporter::ReportSummary(int const totalTestCount, int const failedTestCount,
+ int const failureCount, float const secondsElapsed)
+{
+ AddXmlElement(m_ostream, NULL);
+
+ BeginResults(m_ostream, totalTestCount, failedTestCount, failureCount, secondsElapsed);
+
+ DeferredTestResultList const& results = GetResults();
+ for (DeferredTestResultList::const_iterator i = results.begin(); i != results.end(); ++i)
+ {
+ BeginTest(m_ostream, *i);
+
+ if (i->failed)
+ AddFailure(m_ostream, *i);
+
+ EndTest(m_ostream, *i);
+ }
+
+ EndResults(m_ostream);
+}
+
+void XmlTestReporter::AddXmlElement(ostream& os, char const* encoding)
+{
+ os << "<?xml version=\"1.0\"";
+
+ if (encoding != NULL)
+ os << " encoding=\"" << encoding << "\"";
+
+ os << "?>";
+}
+
+void XmlTestReporter::BeginResults(std::ostream& os, int const totalTestCount, int const failedTestCount,
+ int const failureCount, float const secondsElapsed)
+{
+ os << "<unittest-results"
+ << " tests=\"" << totalTestCount << "\""
+ << " failedtests=\"" << failedTestCount << "\""
+ << " failures=\"" << failureCount << "\""
+ << " time=\"" << secondsElapsed << "\""
+ << ">";
+}
+
+void XmlTestReporter::EndResults(std::ostream& os)
+{
+ os << "</unittest-results>";
+}
+
+void XmlTestReporter::BeginTest(std::ostream& os, DeferredTestResult const& result)
+{
+ os << "<test"
+ << " suite=\"" << result.suiteName << "\""
+ << " name=\"" << result.testName << "\""
+ << " time=\"" << result.timeElapsed << "\"";
+}
+
+void XmlTestReporter::EndTest(std::ostream& os, DeferredTestResult const& result)
+{
+ if (result.failed)
+ os << "</test>";
+ else
+ os << "/>";
+}
+
+void XmlTestReporter::AddFailure(std::ostream& os, DeferredTestResult const& result)
+{
+ os << ">"; // close <test> element
+
+ for (DeferredTestResult::FailureVec::const_iterator it = result.failures.begin();
+ it != result.failures.end();
+ ++it)
+ {
+ string const escapedMessage = XmlEscape(it->second);
+ string const message = BuildFailureMessage(result.failureFile, it->first, escapedMessage);
+
+ os << "<failure" << " message=\"" << message << "\"" << "/>";
+ }
+}
+
+}
diff --git a/libs/ode-0.16.1/tests/UnitTest++/src/XmlTestReporter.h b/libs/ode-0.16.1/tests/UnitTest++/src/XmlTestReporter.h
new file mode 100644
index 0000000..884123b
--- /dev/null
+++ b/libs/ode-0.16.1/tests/UnitTest++/src/XmlTestReporter.h
@@ -0,0 +1,34 @@
+#ifndef UNITTEST_XMLTESTREPORTER_H
+#define UNITTEST_XMLTESTREPORTER_H
+
+#include "DeferredTestReporter.h"
+
+#include <iosfwd>
+
+namespace UnitTest
+{
+
+class XmlTestReporter : public DeferredTestReporter
+{
+public:
+ explicit XmlTestReporter(std::ostream& ostream);
+
+ virtual void ReportSummary(int totalTestCount, int failedTestCount, int failureCount, float secondsElapsed);
+
+private:
+ XmlTestReporter(XmlTestReporter const&);
+ XmlTestReporter& operator=(XmlTestReporter const&);
+
+ void AddXmlElement(std::ostream& os, char const* encoding);
+ void BeginResults(std::ostream& os, int totalTestCount, int failedTestCount, int failureCount, float secondsElapsed);
+ void EndResults(std::ostream& os);
+ void BeginTest(std::ostream& os, DeferredTestResult const& result);
+ void AddFailure(std::ostream& os, DeferredTestResult const& result);
+ void EndTest(std::ostream& os, DeferredTestResult const& result);
+
+ std::ostream& m_ostream;
+};
+
+}
+
+#endif
diff --git a/libs/ode-0.16.1/tests/collision.cpp b/libs/ode-0.16.1/tests/collision.cpp
new file mode 100644
index 0000000..6eef4cf
--- /dev/null
+++ b/libs/ode-0.16.1/tests/collision.cpp
@@ -0,0 +1,224 @@
+#include <UnitTest++.h>
+#include <ode/ode.h>
+#include "common.h"
+
+TEST(test_collision_trimesh_sphere_exact)
+{
+ /*
+ * This tests some extreme cases, where a sphere barely touches some triangles
+ * with zero depth.
+ */
+
+ #ifdef dTRIMESH_GIMPACT
+ /*
+ * Although GIMPACT is algorithmically able to handle this extreme case,
+ * the numerical approximation used for the square root produces inexact results.
+ */
+ return;
+ #endif
+
+ {
+ const int VertexCount = 4;
+ const int IndexCount = 2*3;
+ // this is a square on the XY plane
+ /*
+ 3 2
+ +----+
+ | /|
+ | / |
+ | / |
+ |/ |
+ +----+
+ 0 1
+ */
+ float vertices[VertexCount * 3] = {
+ -1,-1,0,
+ 1,-1,0,
+ 1,1,0,
+ -1,1,0
+ };
+ dTriIndex indices[IndexCount] = {
+ 0,1,2,
+ 0,2,3
+ };
+
+ dTriMeshDataID data = dGeomTriMeshDataCreate();
+ dGeomTriMeshDataBuildSingle(data,
+ vertices,
+ 3 * sizeof(float),
+ VertexCount,
+ indices,
+ IndexCount,
+ 3 * sizeof(dTriIndex));
+ dGeomID trimesh = dCreateTriMesh(0, data, 0, 0, 0);
+ const dReal radius = 4;
+ dGeomID sphere = dCreateSphere(0, radius);
+ dContactGeom cg[4];
+ int nc;
+ dVector3 trinormal = { 0, 0, -1 };
+
+ // Test case: sphere touches the diagonal edge
+ dGeomSetPosition(sphere, 0,0,radius);
+ nc = dCollide(trimesh, sphere, 4, &cg[0], sizeof cg[0]);
+ CHECK_EQUAL(2, nc);
+ for (int i=0; i<nc; ++i) {
+ CHECK_EQUAL(0, cg[i].depth);
+ CHECK_ARRAY_EQUAL(trinormal, cg[i].normal, 3);
+ }
+
+ // now translate both geoms
+ dGeomSetPosition(trimesh, 10,30,40);
+ dGeomSetPosition(sphere, 10,30,40+radius);
+ // check extreme case, again
+ nc = dCollide(trimesh, sphere, 4, &cg[0], sizeof cg[0]);
+ CHECK_EQUAL(2, nc);
+ for (int i=0; i<nc; ++i) {
+ CHECK_EQUAL(0, cg[i].depth);
+ CHECK_ARRAY_EQUAL(trinormal, cg[i].normal, 3);
+ }
+
+ // and now, let's rotate the trimesh, 90 degrees on X
+ dMatrix3 rot = { 1, 0, 0, 0,
+ 0, 0, -1, 0,
+ 0, 1, 0, 0 };
+ dGeomSetPosition(trimesh, 10,30,40);
+ dGeomSetRotation(trimesh, rot);
+
+ dGeomSetPosition(sphere, 10,30-radius,40);
+ // check extreme case, again
+ nc = dCollide(trimesh, sphere, 4, &cg[0], sizeof cg[0]);
+ CHECK_EQUAL(2, nc);
+ dVector3 rtrinormal = { 0, 1, 0 };
+ for (int i=0; i<nc; ++i) {
+ CHECK_EQUAL(0, cg[i].depth);
+ CHECK_ARRAY_EQUAL(rtrinormal, cg[i].normal, 3);
+ }
+ }
+}
+
+
+
+TEST(test_collision_heightfield_ray_fail)
+{
+ /*
+ * This test demonstrated a bug in the AABB handling of the
+ * heightfield.
+ */
+ {
+ // Create quick heightfield with dummy data
+ dHeightfieldDataID heightfieldData = dGeomHeightfieldDataCreate();
+ unsigned char dataBuffer[16+1] = "1234567890123456";
+ dGeomHeightfieldDataBuildByte(heightfieldData, dataBuffer, 0, 4, 4, 4, 4, 1, 0, 0, 0);
+ dGeomHeightfieldDataSetBounds(heightfieldData, '0', '9');
+ dGeomID height = dCreateHeightfield(0, heightfieldData, 1);
+
+ // Create ray outside bounds
+ dGeomID ray = dCreateRay(0, 20);
+ dGeomRaySet(ray, 5, 10, 1, 0, -1, 0);
+ dContact contactBuf[10];
+
+ // Make sure it does not crash!
+ dCollide(ray, height, 10, &(contactBuf[0].geom), sizeof(dContact));
+
+ dGeomDestroy(height);
+ dGeomDestroy(ray);
+ dGeomHeightfieldDataDestroy(heightfieldData);
+ }
+}
+
+#include "../ode/demo/convex_prism.h"
+
+TEST(test_collision_ray_convex)
+{
+ /*
+ * Issue 55: ray vs convex collider does not consider the position of the convex geometry.
+ */
+ {
+ dContact contact;
+
+ // Create convex
+ dGeomID convex = dCreateConvex(0,
+ prism_planes,
+ prism_planecount,
+ prism_points,
+ prism_pointcount,
+ prism_polygons);
+ dGeomSetPosition(convex,0,0,0);
+
+ // Create ray
+ dGeomID ray = dCreateRay(0, 20);
+
+ dGeomRaySet(ray, 0, -10, 0, 0, 1, 0);
+
+ int count = dCollide(ray, convex, 1, &contact.geom, sizeof(dContact));
+
+ CHECK_EQUAL(1,count);
+ CHECK_CLOSE(0.0,contact.geom.pos[0], dEpsilon);
+ CHECK_CLOSE(-1.0,contact.geom.pos[1], dEpsilon);
+ CHECK_CLOSE(0.0,contact.geom.pos[2], dEpsilon);
+ CHECK_CLOSE(0.0, contact.geom.normal[0], dEpsilon);
+ CHECK_CLOSE(-1.0, contact.geom.normal[1], dEpsilon);
+ CHECK_CLOSE(0.0, contact.geom.normal[2], dEpsilon);
+ CHECK_CLOSE(9.0, contact.geom.depth, dEpsilon);
+
+ // Move Ray
+ dGeomRaySet(ray, 5, -10, 0, 0, 1, 0);
+
+ count = dCollide(ray, convex, 1, &contact.geom, sizeof(dContact));
+
+ CHECK_EQUAL(1,count);
+ CHECK_CLOSE(5.0, contact.geom.pos[0], dEpsilon);
+ CHECK_CLOSE(-1.0, contact.geom.pos[1], dEpsilon);
+ CHECK_CLOSE(0.0, contact.geom.pos[2], dEpsilon);
+ CHECK_CLOSE(0.0, contact.geom.normal[0], dEpsilon);
+ CHECK_CLOSE(-1.0, contact.geom.normal[1], dEpsilon);
+ CHECK_CLOSE(0.0, contact.geom.normal[2], dEpsilon);
+ CHECK_CLOSE(9.0, contact.geom.depth, dEpsilon);
+
+ // Rotate Convex
+ dMatrix3 rotate90z =
+ {
+ 0,-1,0,0,
+ 1,0,0,0,
+ 0,0,1,0
+ };
+ dGeomSetRotation(convex, rotate90z);
+
+ count = dCollide(ray, convex, 1, &contact.geom, sizeof(dContact));
+
+ CHECK_EQUAL(0,count);
+
+ // Move Ray
+ dGeomRaySet(ray, 10, 0, 0, -1, 0, 0);
+ count = dCollide(ray, convex, 1, &contact.geom, sizeof(dContact));
+
+ CHECK_EQUAL(1,count);
+ CHECK_CLOSE(1.0, contact.geom.pos[0], dEpsilon);
+ CHECK_CLOSE(0.0, contact.geom.pos[1], dEpsilon);
+ CHECK_CLOSE(0.0, contact.geom.pos[2], dEpsilon);
+ CHECK_CLOSE(1.0, contact.geom.normal[0], dEpsilon);
+ CHECK_CLOSE(0.0, contact.geom.normal[1], dEpsilon);
+ CHECK_CLOSE(0.0, contact.geom.normal[2], dEpsilon);
+ CHECK_CLOSE(9.0,contact.geom.depth, dEpsilon);
+
+
+ // Move Ray
+ dGeomRaySet(ray, 10, 1000, 1000, -1, 0, 0);
+ // Move Geom
+ dGeomSetPosition(convex, 0, 1000, 1000);
+
+ count = dCollide(ray, convex, 1, &contact.geom, sizeof(dContact));
+
+ CHECK_EQUAL(1, count);
+ CHECK_CLOSE(1.0, contact.geom.pos[0], dEpsilon);
+ CHECK_CLOSE(1000.0, contact.geom.pos[1], dEpsilon);
+ CHECK_CLOSE(1000.0, contact.geom.pos[2], dEpsilon);
+ CHECK_CLOSE(1.0, contact.geom.normal[0], dEpsilon);
+ CHECK_CLOSE(0.0, contact.geom.normal[1], dEpsilon);
+ CHECK_CLOSE(0.0, contact.geom.normal[2], dEpsilon);
+ CHECK_CLOSE(9.0, contact.geom.depth, dEpsilon);
+
+ dGeomDestroy(convex);
+ dGeomDestroy(ray);
+ }
+}
diff --git a/libs/ode-0.16.1/tests/friction.cpp b/libs/ode-0.16.1/tests/friction.cpp
new file mode 100644
index 0000000..c082e85
--- /dev/null
+++ b/libs/ode-0.16.1/tests/friction.cpp
@@ -0,0 +1,176 @@
+/*************************************************************************
+ * *
+ * 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. *
+ * *
+ *************************************************************************/
+//234567890123456789012345678901234567890123456789012345678901234567890123456789
+// 1 2 3 4 5 6 7
+
+////////////////////////////////////////////////////////////////////////////////
+// This file create unit test for some of the functions found in:
+// ode/src/joint.cpp
+//
+//
+////////////////////////////////////////////////////////////////////////////////
+#include <algorithm>
+#include <UnitTest++.h>
+#include <ode/ode.h>
+#include "../ode/src/config.h"
+#include "../ode/src/joints/joints.h"
+
+
+/*
+ * Tests for contact friction
+ */
+
+SUITE(JointContact)
+{
+ struct ContactSetup
+ {
+ dWorldID world;
+ dBodyID body1;
+ dBodyID body2;
+ dJointID joint;
+
+ ContactSetup()
+ {
+ world = dWorldCreate();
+ body1 = dBodyCreate(world);
+ body2 = dBodyCreate(world);
+
+ dBodySetPosition(body1, -1, 0, 0);
+ dBodySetPosition(body2, 1, 0, 0);
+ }
+
+ ~ContactSetup()
+ {
+ dBodyDestroy(body1);
+ dBodyDestroy(body2);
+ dWorldDestroy(world);
+ }
+ };
+
+ TEST_FIXTURE(ContactSetup,
+ test_ZeroMu)
+ {
+ dxJoint::Info1 info1;
+ dReal dummy_J[3][16] = {{0}};
+ int dummy_findex[3];
+
+ dReal info2_fps = 100;
+ dReal info2_erp = 0;
+ dReal *J1 = dummy_J[0];
+ dReal *J2 = dummy_J[0] + 8;
+ dReal *rhscfm = dummy_J[0] + 6;
+ dReal *lohi = dummy_J[0] + 14;
+ unsigned rowskip = 16;
+ int *findex = dummy_findex;
+
+#define ZERO_ALL do { \
+ memset(dummy_J, 0, sizeof dummy_J); \
+ std::fill(dummy_findex, dummy_findex+3, -1); \
+ } \
+ while (0)
+
+ dContact contact;
+ contact.surface.mode = dContactMu2 | dContactFDir1 | dContactApprox1;
+
+ contact.geom.pos[0] = 0;
+ contact.geom.pos[1] = 0;
+ contact.geom.pos[2] = 0;
+
+ // normal points into body1
+ contact.geom.normal[0] = -1;
+ contact.geom.normal[1] = 0;
+ contact.geom.normal[2] = 0;
+
+ contact.geom.depth = 0;
+
+ contact.geom.g1 = 0;
+ contact.geom.g2 = 0;
+
+ // we ask for fdir1 = +Y, so fdir2 = normal x fdir1 = -Z
+ contact.fdir1[0] = 0;
+ contact.fdir1[1] = 1;
+ contact.fdir1[2] = 0;
+
+ /*
+ * First, test with mu = 0, mu2 = 1
+ * Because there is no friction on the first direction (+Y) the body
+ * is allowed to translate in the Y axis and rotate around the Z axis.
+ *
+ * That is, the only constraint will be for the second dir (-Z):
+ * so J[1] = [ 0 0 -1 0 1 0 0 0 1 0 1 0 ]
+ */
+ contact.surface.mu = 0;
+ contact.surface.mu2 = 1;
+ joint = dJointCreateContact(world, 0, &contact);
+ dJointAttach(joint, body1, body2);
+ joint->getInfo1(&info1);
+ CHECK_EQUAL(2, (int)info1.m);
+ ZERO_ALL;
+ joint->getInfo2(info2_fps, info2_erp, rowskip, J1, J2,
+ rowskip, rhscfm, lohi, findex);
+ CHECK_CLOSE(0, dummy_J[1][0], 1e-6);
+ CHECK_CLOSE(0, dummy_J[1][1], 1e-6);
+ CHECK_CLOSE(-1, dummy_J[1][2], 1e-6);
+ CHECK_CLOSE(0, dummy_J[1][3], 1e-6);
+ CHECK_CLOSE(1, dummy_J[1][4], 1e-6);
+ CHECK_CLOSE(0, dummy_J[1][5], 1e-6);
+ CHECK_CLOSE(0, dummy_J[1][8], 1e-6);
+ CHECK_CLOSE(0, dummy_J[1][9], 1e-6);
+ CHECK_CLOSE(1, dummy_J[1][10], 1e-6);
+ CHECK_CLOSE(0, dummy_J[1][11], 1e-6);
+ CHECK_CLOSE(1, dummy_J[1][12], 1e-6);
+ CHECK_CLOSE(0, dummy_J[1][13], 1e-6);
+ CHECK_EQUAL(0, dummy_findex[1]); // because of dContactApprox1
+ dJointDestroy(joint);
+
+
+ /*
+ * Now try with no frictino in the second direction. The Jacobian should look like:
+ * J[1] = [ 0 1 0 0 0 1 0 -1 0 0 0 1 ]
+ */
+ // try again, with zero mu2
+ contact.surface.mu = 1;
+ contact.surface.mu2 = 0;
+ joint = dJointCreateContact(world, 0, &contact);
+ dJointAttach(joint, body1, body2);
+ joint->getInfo1(&info1);
+ CHECK_EQUAL(2, (int)info1.m);
+ ZERO_ALL;
+ joint->getInfo2(info2_fps, info2_erp, rowskip, J1, J2,
+ rowskip, rhscfm, lohi, findex);
+ CHECK_CLOSE(0, dummy_J[1][0], 1e-6);
+ CHECK_CLOSE(1, dummy_J[1][1], 1e-6);
+ CHECK_CLOSE(0, dummy_J[1][2], 1e-6);
+ CHECK_CLOSE(0, dummy_J[1][3], 1e-6);
+ CHECK_CLOSE(0, dummy_J[1][4], 1e-6);
+ CHECK_CLOSE(1, dummy_J[1][5], 1e-6);
+ CHECK_CLOSE(0, dummy_J[1][8], 1e-6);
+ CHECK_CLOSE(-1, dummy_J[1][9], 1e-6);
+ CHECK_CLOSE(0, dummy_J[1][10], 1e-6);
+ CHECK_CLOSE(0, dummy_J[1][11], 1e-6);
+ CHECK_CLOSE(0, dummy_J[1][12], 1e-6);
+ CHECK_CLOSE(1, dummy_J[1][13], 1e-6);
+ CHECK_EQUAL(0, dummy_findex[1]); // because of dContactApprox1
+ dJointDestroy(joint);
+ }
+
+}
diff --git a/libs/ode-0.16.1/tests/joint.cpp b/libs/ode-0.16.1/tests/joint.cpp
new file mode 100644
index 0000000..465fb1b
--- /dev/null
+++ b/libs/ode-0.16.1/tests/joint.cpp
@@ -0,0 +1,3054 @@
+/*************************************************************************
+ * *
+ * 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. *
+ * *
+ *************************************************************************/
+//234567890123456789012345678901234567890123456789012345678901234567890123456789
+// 1 2 3 4 5 6 7
+
+////////////////////////////////////////////////////////////////////////////////
+// This file create unit test for some of the functions found in:
+// ode/src/joint.cpp
+//
+//
+////////////////////////////////////////////////////////////////////////////////
+#include <UnitTest++.h>
+#include <ode/ode.h>
+#include "../ode/src/config.h"
+#include "../ode/src/joints/joints.h"
+
+
+////////////////////////////////////////////////////////////////////////////////
+// Testing the Hinge2 Joint
+//
+SUITE(JointHinge2)
+{
+
+ struct Hinge2GetInfo1_Fixture_1
+ {
+ Hinge2GetInfo1_Fixture_1()
+ {
+ wId = dWorldCreate();
+
+ bId1 = dBodyCreate(wId);
+ dBodySetPosition(bId1, 0, -1, 0);
+
+ bId2 = dBodyCreate(wId);
+ dBodySetPosition(bId2, 0, 1, 0);
+
+
+ jId = dJointCreateHinge2(wId, 0);
+ joint = (dxJointHinge2*)jId;
+
+ dJointAttach(jId, bId1, bId2);
+
+ dJointSetHinge2Anchor (jId, REAL(0.0), REAL(0.0), REAL(0.0));
+ }
+
+ ~Hinge2GetInfo1_Fixture_1()
+ {
+ dWorldDestroy(wId);
+ }
+
+ dJointID jId;
+ dxJointHinge2* joint;
+
+ dWorldID wId;
+
+ dBodyID bId1;
+ dBodyID bId2;
+
+ dxJoint::Info1 info;
+ };
+
+ TEST_FIXTURE(Hinge2GetInfo1_Fixture_1, test_hinge2GetInfo1)
+ {
+ /*
+ // ^Y
+ // |---| HiStop
+ // | | ^Y /
+ // |B_2| | /
+ // |---| | /
+ // | ----- | /
+ // Z <-- * Z<--|B_2|--*
+ // / | \ ----- | \
+ // /|---|\ |---| \
+ // / | | \ | | \
+ // / |B_1| \ |B_1| \
+ // / |---| \ |---| \
+ //LoStop HiStop LoStop
+ //
+ //
+ //
+ //
+ */
+ dMatrix3 R;
+
+ dJointSetHinge2Param(jId, dParamLoStop, -M_PI/4.0);
+ dJointSetHinge2Param(jId, dParamHiStop, M_PI/4.0);
+
+ dxJoint::Info1 info;
+
+
+ dxJointHinge2* joint = (dxJointHinge2*)jId;
+
+ // Original position inside the limits
+ joint->getInfo1(&info);
+ CHECK_EQUAL(0, joint->limot1.limit);
+ CHECK_EQUAL(4, info.m);
+
+ // Move the body outside the Lo limits
+ dBodySetPosition (bId2, 0, 0, 1);
+ dRFromAxisAndAngle (R, 1, 0, 0, M_PI/2.0);
+ dBodySetRotation (bId2, R);
+ joint->getInfo1(&info);
+ CHECK_EQUAL(1, joint->limot1.limit);
+ CHECK_EQUAL(5, info.m);
+
+
+ // Return to original position
+ // Keep the limits
+ dBodySetPosition (bId2, 0, 1, 0);
+ dRFromAxisAndAngle (R, 1, REAL(0.0), REAL(0.0), REAL(0.0));
+ dBodySetRotation (bId2, R);
+ joint->getInfo1(&info);
+ CHECK_EQUAL(0, joint->limot1.limit);
+ CHECK_EQUAL(4, info.m);
+
+
+ // Move the body outside the Lo limits
+ dBodySetPosition (bId2, 0, 0, 1);
+ dRFromAxisAndAngle (R, 1, 0, 0, M_PI/2.0);
+ dBodySetRotation (bId2, R);
+ joint->getInfo1(&info);
+ CHECK_EQUAL(1, joint->limot1.limit);
+ CHECK_EQUAL(5, info.m);
+
+
+
+ // Return to original position
+ // and remove the limits
+ dBodySetPosition (bId2, 0, 1, 0);
+ dRFromAxisAndAngle (R, 1, REAL(0.0), REAL(0.0), REAL(0.0));
+ dBodySetRotation (bId2, R);
+ dJointSetHinge2Param(jId, dParamLoStop, -2*M_PI);
+ dJointSetHinge2Param(jId, dParamHiStop, 2*M_PI);
+ joint->getInfo1(&info);
+ CHECK_EQUAL(0, joint->limot1.limit);
+ CHECK_EQUAL(4, info.m);
+
+
+ // Set the limits
+ // Move pass the Hi limits
+ dJointSetHinge2Param(jId, dParamLoStop, -M_PI/4.0);
+ dJointSetHinge2Param(jId, dParamHiStop, M_PI/4.0);
+ dBodySetPosition (bId2, 0, 0, 1);
+ dRFromAxisAndAngle (R, 1, 0, 0, -M_PI/2.0);
+ dBodySetRotation (bId2, R);
+ joint->getInfo1(&info);
+ CHECK_EQUAL(2, joint->limot1.limit);
+ CHECK_EQUAL(5, info.m);
+
+
+ // Return to original position
+ // Keep the limits
+ dBodySetPosition (bId2, 0, 1, 0);
+ dRFromAxisAndAngle (R, 1, REAL(0.0), REAL(0.0), REAL(0.0));
+ dBodySetRotation (bId2, R);
+ joint->getInfo1(&info);
+ CHECK_EQUAL(0, joint->limot1.limit);
+ CHECK_EQUAL(4, info.m);
+
+
+ // Move the pass the Hi limit
+ dBodySetPosition (bId2, 0, 0, 1);
+ dRFromAxisAndAngle (R, 1, 0, 0, -M_PI/2.0);
+ dBodySetRotation (bId2, R);
+ joint->getInfo1(&info);
+ CHECK_EQUAL(2, joint->limot1.limit);
+ CHECK_EQUAL(5, info.m);
+
+
+ // Return to original position
+ // and remove the limits
+ dBodySetPosition (bId2, 0, 1, 0);
+ dRFromAxisAndAngle (R, 1, 0, 0, -M_PI/2.0);
+ dBodySetRotation (bId2, R);
+ dJointSetHinge2Param(jId, dParamLoStop, -2*M_PI);
+ dJointSetHinge2Param(jId, dParamHiStop, 2*M_PI);
+ joint->getInfo1(&info);
+ CHECK_EQUAL(0, joint->limot1.limit);
+ CHECK_EQUAL(4, info.m);
+
+
+ /// Motorize the first joint angle
+ dJointSetHinge2Param(jId, dParamFMax, 2);
+ joint->getInfo1(&info);
+ CHECK_EQUAL(0, joint->limot1.limit);
+ CHECK_EQUAL(5, info.m);
+
+
+ /// Motorize the second joint angle
+ dJointSetHinge2Param(jId, dParamFMax2, 2);
+ joint->getInfo1(&info);
+ CHECK_EQUAL(0, joint->limot1.limit);
+ CHECK_EQUAL(6, info.m);
+
+ /// Unmotorize the first joint angle
+ dJointSetHinge2Param(jId, dParamFMax, 0);
+ joint->getInfo1(&info);
+ CHECK_EQUAL(0, joint->limot1.limit);
+ CHECK_EQUAL(5, info.m);
+ }
+} // End of SUITE(JointHinge2)
+
+
+////////////////////////////////////////////////////////////////////////////////
+// Testing the Universal Joint
+//
+SUITE(JointUniversal)
+{
+
+ struct UniversalGetInfo1_Fixture_1
+ {
+ UniversalGetInfo1_Fixture_1()
+ {
+ wId = dWorldCreate();
+
+ bId1 = dBodyCreate(wId);
+ dBodySetPosition(bId1, 0, -1, 0);
+
+ bId2 = dBodyCreate(wId);
+ dBodySetPosition(bId2, 0, 1, 0);
+
+
+ jId = dJointCreateUniversal(wId, 0);
+ joint = (dxJointUniversal*)jId;
+
+ dJointAttach(jId, bId1, bId2);
+
+ dJointSetUniversalAnchor (jId, REAL(0.0), REAL(0.0), REAL(0.0));
+ }
+
+ ~UniversalGetInfo1_Fixture_1()
+ {
+ dWorldDestroy(wId);
+ }
+
+ dJointID jId;
+ dxJointUniversal* joint;
+
+ dWorldID wId;
+
+ dBodyID bId1;
+ dBodyID bId2;
+
+ dxJoint::Info1 info;
+ };
+
+ TEST_FIXTURE(UniversalGetInfo1_Fixture_1, test_hinge2GetInfo1_RotAroundX)
+ {
+ /*
+ // ^Y
+ // |---| HiStop
+ // | | ^Y /
+ // |B_2| | /
+ // |---| | /
+ // | ----- | /
+ // Z <-- * Z<--|B_2|--*
+ // / | \ ----- | \
+ // /|---|\ |---| \
+ // / | | \ | | \
+ // / |B_1| \ |B_1| \
+ // / |---| \ |---| \
+ //LoStop HiStop LoStop
+ //
+ //
+ //
+ //
+ */
+ dMatrix3 R;
+
+ dJointSetUniversalParam(jId, dParamLoStop, -M_PI/4.0);
+ dJointSetUniversalParam(jId, dParamHiStop, M_PI/4.0);
+ dJointSetUniversalParam(jId, dParamLoStop2, -M_PI/4.0);
+ dJointSetUniversalParam(jId, dParamHiStop2, M_PI/4.0);
+
+ dxJoint::Info1 info;
+
+
+ dxJointUniversal* joint = (dxJointUniversal*)jId;
+
+ // Original position inside the limits
+ joint->getInfo1(&info);
+ CHECK_EQUAL(0, joint->limot1.limit);
+ CHECK_EQUAL(4, info.m);
+
+ // Move the body outside the Lo limits
+ dBodySetPosition (bId2, 0, 0, 1);
+ dRFromAxisAndAngle (R, 1, 0, 0, M_PI/2.0);
+ dBodySetRotation (bId2, R);
+ joint->getInfo1(&info);
+ CHECK_EQUAL(1, joint->limot1.limit);
+ CHECK_EQUAL(5, info.m);
+
+
+ // Return to original position
+ // Keep the limits
+ dBodySetPosition (bId2, 0, 1, 0);
+ dRFromAxisAndAngle (R, 1, REAL(0.0), REAL(0.0), REAL(0.0));
+ dBodySetRotation (bId2, R);
+ joint->getInfo1(&info);
+ CHECK_EQUAL(0, joint->limot1.limit);
+ CHECK_EQUAL(4, info.m);
+
+
+ // Move the body outside the Lo limits
+ dBodySetPosition (bId2, 0, 0, 1);
+ dRFromAxisAndAngle (R, 1, 0, 0, M_PI/2.0);
+ dBodySetRotation (bId2, R);
+ joint->getInfo1(&info);
+ CHECK_EQUAL(1, joint->limot1.limit);
+ CHECK_EQUAL(5, info.m);
+
+
+
+ // Return to original position
+ // and remove the limits
+ dBodySetPosition (bId2, 0, 1, 0);
+ dRFromAxisAndAngle (R, 1, REAL(0.0), REAL(0.0), REAL(0.0));
+ dBodySetRotation (bId2, R);
+ dJointSetUniversalParam(jId, dParamLoStop, -2*M_PI);
+ dJointSetUniversalParam(jId, dParamHiStop, 2*M_PI);
+ joint->getInfo1(&info);
+ CHECK_EQUAL(0, joint->limot1.limit);
+ CHECK_EQUAL(4, info.m);
+
+
+ // Set the limits
+ // Move pass the Hi limits
+ dJointSetUniversalParam(jId, dParamLoStop, -M_PI/4.0);
+ dJointSetUniversalParam(jId, dParamHiStop, M_PI/4.0);
+ dBodySetPosition (bId2, 0, 0, 1);
+ dRFromAxisAndAngle (R, 1, 0, 0, -M_PI/2.0);
+ dBodySetRotation (bId2, R);
+ joint->getInfo1(&info);
+ CHECK_EQUAL(2, joint->limot1.limit);
+ CHECK_EQUAL(5, info.m);
+
+
+ // Return to original position
+ // Keep the limits
+ dBodySetPosition (bId2, 0, 1, 0);
+ dRFromAxisAndAngle (R, 1, REAL(0.0), REAL(0.0), REAL(0.0));
+ dBodySetRotation (bId2, R);
+ joint->getInfo1(&info);
+ CHECK_EQUAL(0, joint->limot1.limit);
+ CHECK_EQUAL(4, info.m);
+
+
+ // Move the pass the Hi limit
+ dBodySetPosition (bId2, 0, 0, 1);
+ dRFromAxisAndAngle (R, 1, 0, 0, -M_PI/2.0);
+ dBodySetRotation (bId2, R);
+ joint->getInfo1(&info);
+ CHECK_EQUAL(2, joint->limot1.limit);
+ CHECK_EQUAL(5, info.m);
+
+
+ // Return to original position
+ // and remove the limits
+ dBodySetPosition (bId2, 0, 1, 0);
+ dRFromAxisAndAngle (R, 1, 0, 0, -M_PI/2.0);
+ dBodySetRotation (bId2, R);
+ dJointSetUniversalParam(jId, dParamLoStop, -2*M_PI);
+ dJointSetUniversalParam(jId, dParamHiStop, 2*M_PI);
+ joint->getInfo1(&info);
+ CHECK_EQUAL(0, joint->limot1.limit);
+ CHECK_EQUAL(4, info.m);
+
+
+ /// Motorize the first joint angle
+ dJointSetUniversalParam(jId, dParamFMax, 2);
+ joint->getInfo1(&info);
+ CHECK_EQUAL(0, joint->limot1.limit);
+ CHECK_EQUAL(5, info.m);
+
+
+ /// Motorize the second joint angle
+ dJointSetUniversalParam(jId, dParamFMax2, 2);
+ joint->getInfo1(&info);
+ CHECK_EQUAL(0, joint->limot1.limit);
+ CHECK_EQUAL(6, info.m);
+
+ /// Unmotorize the first joint angle
+ dJointSetUniversalParam(jId, dParamFMax, 0);
+ joint->getInfo1(&info);
+ CHECK_EQUAL(0, joint->limot1.limit);
+ CHECK_EQUAL(5, info.m);
+ }
+
+ TEST_FIXTURE(UniversalGetInfo1_Fixture_1, test_hinge2GetInfo1_RotAroundY)
+ {
+ /*
+ // ^Y
+ // |---| HiStop
+ // | | ^Y /
+ // |B_2| | /
+ // |---| | /
+ // | ----- | /
+ // Z <-- * Z<--|B_2|--*
+ // / | \ ----- | \
+ // /|---|\ |---| \
+ // / | | \ | | \
+ // / |B_1| \ |B_1| \
+ // / |---| \ |---| \
+ //LoStop HiStop LoStop
+ //
+ //
+ //
+ //
+ */
+ dMatrix3 R;
+
+ dJointSetUniversalParam(jId, dParamLoStop, -M_PI/4.0);
+ dJointSetUniversalParam(jId, dParamHiStop, M_PI/4.0);
+ dJointSetUniversalParam(jId, dParamLoStop2, -M_PI/4.0);
+ dJointSetUniversalParam(jId, dParamHiStop2, M_PI/4.0);
+
+ dxJoint::Info1 info;
+
+
+ dxJointUniversal* joint = (dxJointUniversal*)jId;
+
+ // Original position inside the limits
+ joint->getInfo1(&info);
+ CHECK_EQUAL(0, joint->limot1.limit);
+ CHECK_EQUAL(4, info.m);
+
+ // Move the body outside the Lo limits
+ dBodySetPosition (bId2, 0, 0, 1);
+ dRFromAxisAndAngle (R, 0, 1, 0, M_PI/2.0);
+ dBodySetRotation (bId2, R);
+ joint->getInfo1(&info);
+ CHECK_EQUAL(1, joint->limot2.limit);
+ CHECK_EQUAL(5, info.m);
+
+
+ // Return to original position
+ // Keep the limits
+ dBodySetPosition (bId2, 0, 1, 0);
+ dRFromAxisAndAngle (R, 0, 1, 0, 0);
+ dBodySetRotation (bId2, R);
+ joint->getInfo1(&info);
+ CHECK_EQUAL(0, joint->limot2.limit);
+ CHECK_EQUAL(4, info.m);
+
+
+ // Move the body outside the Lo limits
+ dBodySetPosition (bId2, 0, 0, 1);
+ dRFromAxisAndAngle (R, 0, 1, 0, M_PI/2.0);
+ dBodySetRotation (bId2, R);
+ joint->getInfo1(&info);
+ CHECK_EQUAL(1, joint->limot2.limit);
+ CHECK_EQUAL(5, info.m);
+
+
+
+ // Return to original position
+ // and remove the limits
+ dBodySetPosition (bId2, 0, 1, 0);
+ dRFromAxisAndAngle (R, 0, 1, 0, 0);
+ dBodySetRotation (bId2, R);
+ dJointSetUniversalParam(jId, dParamLoStop2, -2*M_PI);
+ dJointSetUniversalParam(jId, dParamHiStop2, 2*M_PI);
+ joint->getInfo1(&info);
+ CHECK_EQUAL(0, joint->limot2.limit);
+ CHECK_EQUAL(4, info.m);
+
+
+ // Set the limits
+ // Move pass the Hi limits
+ dJointSetUniversalParam(jId, dParamLoStop2, -M_PI/4.0);
+ dJointSetUniversalParam(jId, dParamHiStop2, M_PI/4.0);
+ dBodySetPosition (bId2, 0, 0, 1);
+ dRFromAxisAndAngle (R, 0, 1, 0, -M_PI/2.0);
+ dBodySetRotation (bId2, R);
+ joint->getInfo1(&info);
+ CHECK_EQUAL(2, joint->limot2.limit);
+ CHECK_EQUAL(5, info.m);
+
+
+ // Return to original position
+ // Keep the limits
+ dBodySetPosition (bId2, 0, 1, 0);
+ dRFromAxisAndAngle (R, 0, 1, 0, 0);
+ dBodySetRotation (bId2, R);
+ joint->getInfo1(&info);
+ CHECK_EQUAL(0, joint->limot2.limit);
+ CHECK_EQUAL(4, info.m);
+
+
+ // Move the pass the Hi limit
+ dBodySetPosition (bId2, 0, 0, 1);
+ dRFromAxisAndAngle (R, 0, 1, 0, -M_PI/2.0);
+ dBodySetRotation (bId2, R);
+ joint->getInfo1(&info);
+ CHECK_EQUAL(2, joint->limot2.limit);
+ CHECK_EQUAL(5, info.m);
+
+
+ // Return to original position
+ // and remove the limits
+ dBodySetPosition (bId2, 0, 1, 0);
+ dRFromAxisAndAngle (R, 0, 1, 0, -M_PI/2.0);
+ dBodySetRotation (bId2, R);
+ dJointSetUniversalParam(jId, dParamLoStop2, -2*M_PI);
+ dJointSetUniversalParam(jId, dParamHiStop2, 2*M_PI);
+ joint->getInfo1(&info);
+ CHECK_EQUAL(0, joint->limot2.limit);
+ CHECK_EQUAL(4, info.m);
+
+
+ /// Motorize the first joint angle
+ dJointSetUniversalParam(jId, dParamFMax, 2);
+ joint->getInfo1(&info);
+ CHECK_EQUAL(0, joint->limot2.limit);
+ CHECK_EQUAL(5, info.m);
+
+
+ /// Motorize the second joint angle
+ dJointSetUniversalParam(jId, dParamFMax2, 2);
+ joint->getInfo1(&info);
+ CHECK_EQUAL(0, joint->limot2.limit);
+ CHECK_EQUAL(6, info.m);
+
+ /// Unmotorize the first joint angle
+ dJointSetUniversalParam(jId, dParamFMax, 0);
+ joint->getInfo1(&info);
+ CHECK_EQUAL(0, joint->limot2.limit);
+ CHECK_EQUAL(5, info.m);
+ }
+} // End of SUITE(JointUniversal)
+
+
+
+// // //
+// Testing the PR Joint
+//
+SUITE(JointPR)
+{
+ struct PRGetInfo1_Fixture_1
+ {
+ PRGetInfo1_Fixture_1()
+ {
+ wId = dWorldCreate();
+
+ bId1 = dBodyCreate(wId);
+ dBodySetPosition(bId1, 0, -1, 0);
+
+ bId2 = dBodyCreate(wId);
+ dBodySetPosition(bId2, 0, 1, 0);
+
+
+ jId = dJointCreatePR(wId, 0);
+ joint = (dxJointPR*)jId;
+
+ dJointAttach(jId, bId1, bId2);
+
+ dJointSetPRAnchor (jId, REAL(0.0), REAL(0.0), REAL(0.0));
+ }
+
+ ~PRGetInfo1_Fixture_1()
+ {
+ dWorldDestroy(wId);
+ }
+
+ dJointID jId;
+ dxJointPR* joint;
+
+ dWorldID wId;
+
+ dBodyID bId1;
+ dBodyID bId2;
+
+ dxJoint::Info1 info;
+ };
+
+
+////////////////////////////////////////////////////////////////////////////////
+// Test when there is no limits.
+// The 2 bodies stay aligned.
+//
+// Default value for axisR1 = 1,0,0
+// Default value for axisP1 = 0,1,0
+////////////////////////////////////////////////////////////////////////////////
+ TEST_FIXTURE(PRGetInfo1_Fixture_1, test1_PRGetInfo1_)
+ {
+ dJointSetPRParam(jId, dParamLoStop, -dInfinity);
+ dJointSetPRParam(jId, dParamHiStop, dInfinity);
+ dJointSetPRParam(jId, dParamLoStop2, -M_PI);
+ dJointSetPRParam(jId, dParamHiStop2, M_PI);
+
+ joint->getInfo1(&info);
+
+ CHECK_EQUAL(0, joint->limotP.limit);
+ CHECK_EQUAL(0, joint->limotR.limit);
+ CHECK_EQUAL(4, info.m);
+ }
+
+
+////////////////////////////////////////////////////////////////////////////////
+// Test when there is limits for the prismatic at -10 and 10
+// The Body 2 is moved -100 unit then at 100
+//
+// Default value for axisR1 = 1,0,0
+// Default value for axisP1 = 0,1,0
+////////////////////////////////////////////////////////////////////////////////
+ TEST_FIXTURE(PRGetInfo1_Fixture_1, test2_PRGetInfo1)
+ {
+ dJointSetPRParam(jId, dParamLoStop, -10);
+ dJointSetPRParam(jId, dParamHiStop, 10);
+ dJointSetPRParam(jId, dParamLoStop2, -M_PI);
+ dJointSetPRParam(jId, dParamHiStop2, M_PI);
+
+
+ dBodySetPosition(bId2, 0, -100, 0);
+
+ joint->getInfo1(&info);
+
+ CHECK_EQUAL(2, joint->limotP.limit);
+ CHECK_EQUAL(0, joint->limotR.limit);
+ CHECK_EQUAL(5, info.m);
+
+
+ dBodySetPosition(bId2, 0, 100, 0);
+
+ joint->getInfo1(&info);
+
+ CHECK_EQUAL(1, joint->limotP.limit);
+ CHECK_EQUAL(0, joint->limotR.limit);
+ CHECK_EQUAL(5, info.m);
+
+ // Reset Position and test
+ dBodySetPosition(bId2, 0, 1, 0);
+ dMatrix3 R_final = { 1,0,0,0,
+ 0,1,0,0,
+ 0,0,1,0
+ };
+ dBodySetRotation (bId2, R_final);
+
+ joint->getInfo1(&info);
+
+ CHECK_EQUAL(0, joint->limotP.limit);
+ CHECK_EQUAL(0, joint->limotR.limit);
+ CHECK_EQUAL(4, info.m);
+ }
+
+////////////////////////////////////////////////////////////////////////////////
+// Test when there is limits for the prismatic at -10 and 10
+// and for the rotoide at -45deg and 45deg.
+// The Body 2 is only rotated by 90deg since the rotoide limits are not
+// used this should not change the limit value.
+//
+// Default value for axisR1 = 1,0,0
+// Default value for axisP1 = 0,1,0
+//
+////////////////////////////////////////////////////////////////////////////////
+ TEST_FIXTURE(PRGetInfo1_Fixture_1, test3_PRGetInfo1)
+ {
+ dJointSetPRParam(jId, dParamLoStop, -10);
+ dJointSetPRParam(jId, dParamHiStop, 10);
+ dJointSetPRParam(jId, dParamLoStop2, -M_PI/4.0);
+ dJointSetPRParam(jId, dParamHiStop2, M_PI/4.0);
+
+
+ dMatrix3 R;
+ dBodySetPosition (bId2, 0, 0, 1);
+ dRFromAxisAndAngle (R, 1, 0, 0, M_PI/2.0);
+ dBodySetRotation (bId2, R);
+
+ joint->getInfo1(&info);
+
+ CHECK_EQUAL(0, joint->limotP.limit);
+ CHECK_EQUAL(1, joint->limotR.limit);
+ CHECK_EQUAL(5, info.m);
+
+ // Reset Position and test
+ dBodySetPosition(bId2, 0, 1, 0);
+ dMatrix3 R_final = { 1,0,0,0,
+ 0,1,0,0,
+ 0,0,1,0
+ };
+ dBodySetRotation (bId2, R_final);
+
+ joint->getInfo1(&info);
+
+ CHECK_EQUAL(0, joint->limotP.limit);
+ CHECK_EQUAL(0, joint->limotR.limit);
+ CHECK_EQUAL(4, info.m);
+ }
+
+
+// The joint is now powered. (i.e. info->fmax > 0
+ struct PRGetInfo1_Fixture_2
+ {
+ PRGetInfo1_Fixture_2()
+ {
+ wId = dWorldCreate();
+
+ bId1 = dBodyCreate(wId);
+ dBodySetPosition(bId1, 0, -1, 0);
+
+ bId2 = dBodyCreate(wId);
+ dBodySetPosition(bId2, 0, 1, 0);
+
+
+ jId = dJointCreatePR(wId, 0);
+ joint = (dxJointPR*)jId;
+
+ dJointAttach(jId, bId1, bId2);
+ dJointSetPRAnchor (jId, REAL(0.0), REAL(0.0), REAL(0.0));
+
+ joint->limotP.fmax = 1;
+ }
+
+ ~PRGetInfo1_Fixture_2()
+ {
+ dWorldDestroy(wId);
+ }
+
+ dJointID jId;
+ dxJointPR* joint;
+
+ dWorldID wId;
+
+ dBodyID bId1;
+ dBodyID bId2;
+
+ dxJoint::Info1 info;
+ };
+
+
+
+////////////////////////////////////////////////////////////////////////////////
+// Test when there is no limits.
+// The 2 bodies stay align.
+//
+// Default value for axisR1 = 1,0,0
+// Default value for axisP1 = 0,1,0
+//
+////////////////////////////////////////////////////////////////////////////////
+ TEST_FIXTURE(PRGetInfo1_Fixture_2, test1_PRGetInfo1)
+ {
+ dJointSetPRParam(jId, dParamLoStop, -dInfinity);
+ dJointSetPRParam(jId, dParamHiStop, dInfinity);
+ dJointSetPRParam(jId, dParamLoStop2, -M_PI);
+ dJointSetPRParam(jId, dParamHiStop2, M_PI);
+
+ joint->getInfo1(&info);
+
+ CHECK_EQUAL(0, joint->limotP.limit);
+ CHECK_EQUAL(0, joint->limotR.limit);
+ CHECK_EQUAL(5, info.m);
+ }
+
+
+////////////////////////////////////////////////////////////////////////////////
+// Test when there is limits for the prismatic at -10 and 10
+// The Body 2 is moved -100 unit then at 100
+//
+// Default value for axisR1 = 1,0,0
+// Default value for axisP1 = 0,1,0
+//
+////////////////////////////////////////////////////////////////////////////////
+ TEST_FIXTURE(PRGetInfo1_Fixture_2, test2_PRGetInfo1)
+ {
+
+ dJointSetPRParam(jId, dParamLoStop, -10);
+ dJointSetPRParam(jId, dParamHiStop, 10);
+ dJointSetPRParam(jId, dParamLoStop2, -M_PI);
+ dJointSetPRParam(jId, dParamHiStop2, M_PI);
+
+
+ dBodySetPosition(bId2, 0, -100, 0);
+
+ joint->getInfo1(&info);
+
+ CHECK_EQUAL(2, joint->limotP.limit);
+ CHECK_EQUAL(0, joint->limotR.limit);
+ CHECK_EQUAL(5, info.m);
+
+
+ dBodySetPosition(bId2, 0, 100, 0);
+
+ joint->getInfo1(&info);
+
+ CHECK_EQUAL(1, joint->limotP.limit);
+ CHECK_EQUAL(0, joint->limotR.limit);
+ CHECK_EQUAL(5, info.m);
+
+ // Reset Position and test
+ dBodySetPosition(bId2, 0, 1, 0);
+ dMatrix3 R_final = { 1,0,0,0,
+ 0,1,0,0,
+ 0,0,1,0
+ };
+ dBodySetRotation (bId2, R_final);
+
+ joint->getInfo1(&info);
+
+ CHECK_EQUAL(0, joint->limotP.limit);
+ CHECK_EQUAL(0, joint->limotR.limit);
+ CHECK_EQUAL(5, info.m);
+ }
+
+////////////////////////////////////////////////////////////////////////////////
+// Test when there is limits for the prismatic at -10 and 10
+// and for the rotoide at -45deg and 45deg
+// The Body 2 is only rotated by 90deg since the rotoide limits are not
+// used this should not change the limit value.
+//
+// Default value for axisR1 = 1,0,0
+// Default value for axisP1 = 0,1,0
+//
+////////////////////////////////////////////////////////////////////////////////
+ TEST_FIXTURE(PRGetInfo1_Fixture_2, test3_PRGetInfo1)
+ {
+
+ dJointSetPRParam(jId, dParamLoStop, -10);
+ dJointSetPRParam(jId, dParamHiStop, 10);
+ dJointSetPRParam(jId, dParamLoStop2, -M_PI/4.0);
+ dJointSetPRParam(jId, dParamHiStop2, M_PI/4.0);
+
+
+ dMatrix3 R;
+ dBodySetPosition (bId2, 0, 0, 100);
+ dRFromAxisAndAngle (R, 1, 0, 0, M_PI/2.0);
+ dBodySetRotation (bId2, R);
+
+ joint->getInfo1(&info);
+
+ CHECK_EQUAL(0, joint->limotP.limit);
+ CHECK_EQUAL(1, joint->limotR.limit);
+ CHECK_EQUAL(6, info.m);
+
+ // Reset Position and test
+ dBodySetPosition(bId2, 0, 1, 0);
+ dMatrix3 R_final = { 1,0,0,0,
+ 0,1,0,0,
+ 0,0,1,0
+ };
+ dBodySetRotation (bId2, R_final);
+
+ joint->getInfo1(&info);
+
+ CHECK_EQUAL(0, joint->limotP.limit);
+ CHECK_EQUAL(0, joint->limotR.limit);
+ CHECK_EQUAL(5, info.m);
+ }
+
+
+////////////////////////////////////////////////////////////////////////////////
+// Test the setting and getting of parameters
+////////////////////////////////////////////////////////////////////////////////
+ TEST_FIXTURE(PRGetInfo1_Fixture_1, test_SetPRParam)
+ {
+ dJointSetPRParam(jId, dParamHiStop, REAL(5.0) );
+ CHECK_EQUAL(REAL(5.0), joint->limotP.histop);
+
+ dJointSetPRParam(jId, dParamVel, REAL(7.0) );
+ CHECK_EQUAL(REAL(7.0), joint->limotP.vel);
+
+#ifdef dParamFudgeFactor1
+ dJointSetPRParam(jId, dParamFudgeFactor1, REAL(5.5) );
+ CHECK_EQUAL(REAL(5.5), joint->limotP.dParamFudgeFactor);
+#endif
+
+ dJointSetPRParam(jId, dParamCFM2, REAL(9.0) );
+ CHECK_EQUAL(REAL(9.0), joint->limotR.normal_cfm);
+
+ dJointSetPRParam(jId, dParamStopERP2, REAL(11.0) );
+ CHECK_EQUAL(REAL(11.0), joint->limotR.stop_erp);
+ }
+
+ TEST_FIXTURE(PRGetInfo1_Fixture_1, test_GetPRParam)
+ {
+ joint->limotP.histop = REAL(5.0);
+ CHECK_EQUAL(joint->limotP.histop,
+ dJointGetPRParam(jId, dParamHiStop) );
+
+ joint->limotP.vel = REAL(7.0);
+
+ CHECK_EQUAL(joint->limotP.vel,
+ dJointGetPRParam(jId, dParamVel) );
+
+#ifdef dParamFudgeFactor1
+ joint->limotP.dParamFudgeFactor = REAL(5.5);
+
+ CHECK_EQUAL(joint->limotP.dParamFudgeFactor,
+ dJointGetPRParam(jId, dParamFudgeFactor1) );
+#endif
+
+ joint->limotR.normal_cfm = REAL(9.0);
+ CHECK_EQUAL(joint->limotR.normal_cfm,
+ dJointGetPRParam(jId, dParamCFM2) );
+
+ joint->limotR.stop_erp = REAL(11.0);
+ CHECK_EQUAL(joint->limotR.stop_erp,
+ dJointGetPRParam(jId, dParamStopERP2) );
+ }
+
+
+
+////////////////////////////////////////////////////////////////////////////////
+// Fixture for testing the PositionRate
+//
+// Default Position
+// ^Z
+// |
+// |
+//
+// Body2 R Body1
+// +---------+ _ - +-----------+
+// | |--------(_)----|-----| | ----->Y
+// +---------+ - +-----------+
+//
+// N.B. X is comming out of the page
+////////////////////////////////////////////////////////////////////////////////
+ struct PRGetInfo1_Fixture_3
+ {
+ PRGetInfo1_Fixture_3()
+ {
+ wId = dWorldCreate();
+
+ bId1 = dBodyCreate(wId);
+ dBodySetPosition(bId1, 0, 1, 0);
+
+ bId2 = dBodyCreate(wId);
+ dBodySetPosition(bId2, 0, -1, 0);
+
+
+ jId = dJointCreatePR(wId, 0);
+ joint = (dxJointPR*)jId;
+
+ dJointAttach(jId, bId1, bId2);
+ dJointSetPRAnchor (jId, REAL(0.0), REAL(0.0), REAL(0.0));
+
+ dBodySetLinearVel (bId1, REAL(0.0), REAL(0.0), REAL(0.0));
+ dBodySetAngularVel(bId1, REAL(0.0), REAL(0.0), REAL(0.0));
+
+ dBodySetLinearVel (bId2, REAL(0.0), REAL(0.0), REAL(0.0));
+ dBodySetAngularVel(bId1, REAL(0.0), REAL(0.0), REAL(0.0));
+
+ }
+
+ ~PRGetInfo1_Fixture_3()
+ {
+ dWorldDestroy(wId);
+ }
+
+ dJointID jId;
+ dxJointPR* joint;
+
+ dWorldID wId;
+
+ dBodyID bId1;
+ dBodyID bId2;
+
+ dxJoint::Info1 info;
+ };
+
+////////////////////////////////////////////////////////////////////////////////
+// Position Body1 [0, 1, 0]
+// Position Body2 [0, -1, 0]
+// Axis of the prismatic [0, 1, 0]
+// Axis of the rotoide [1, 0, ]0
+//
+// Move at the same speed
+////////////////////////////////////////////////////////////////////////////////
+ TEST_FIXTURE(PRGetInfo1_Fixture_3, test_GetPRPositionRate_1)
+ {
+ // They move with the same linear speed
+ // Angular speed == 0
+ dBodySetLinearVel(bId1, REAL(0.0), REAL(3.33), REAL(0.0));
+ dBodySetLinearVel(bId2, REAL(0.0), REAL(3.33), REAL(0.0));
+ CHECK_EQUAL(REAL(0.0), dJointGetPRPositionRate (jId) );
+
+ dBodySetLinearVel(bId1, REAL(1.11), REAL(3.33), REAL(0.0));
+ dBodySetLinearVel(bId2, REAL(1.11), REAL(3.33), REAL(0.0));
+ CHECK_EQUAL(REAL(0.0), dJointGetPRPositionRate (jId) );
+
+ dBodySetLinearVel(bId1, REAL(1.11), REAL(3.33), REAL(2.22));
+ dBodySetLinearVel(bId2, REAL(1.11), REAL(3.33), REAL(2.22));
+ CHECK_EQUAL(REAL(0.0), dJointGetPRPositionRate (jId) );
+
+
+ // Reset for the next set of test.
+ dBodySetLinearVel(bId1, REAL(0.0), REAL(0.0), REAL(0.0));
+ dBodySetAngularVel(bId1, REAL(0.0), REAL(0.0), REAL(0.0));
+
+ dBodySetLinearVel(bId2, REAL(0.0), REAL(0.0), REAL(0.0));
+ dBodySetAngularVel(bId1, REAL(0.0), REAL(0.0), REAL(0.0));
+
+
+ // They move with the same angular speed
+ // linear speed == 0
+
+ dBodySetAngularVel(bId1, REAL(1.22), REAL(0.0), REAL(0.0));
+ dBodySetAngularVel(bId2, REAL(1.22), REAL(0.0), REAL(0.0));
+ CHECK_EQUAL(REAL(0.0), dJointGetPRPositionRate (jId) );
+
+ dBodySetAngularVel(bId1, REAL(1.22), REAL(2.33), REAL(0.0));
+ dBodySetAngularVel(bId2, REAL(1.22), REAL(2.33), REAL(0.0));
+ CHECK_EQUAL(REAL(0.0), dJointGetPRPositionRate (jId) );
+
+ dBodySetAngularVel(bId1, REAL(1.22), REAL(2.33), REAL(3.44));
+ dBodySetAngularVel(bId2, REAL(1.22), REAL(2.33), REAL(3.44));
+ CHECK_EQUAL(REAL(0.0), dJointGetPRPositionRate (jId) );
+ }
+
+
+////////////////////////////////////////////////////////////////////////////////
+// Position Body1 [0, 1, 0]
+// Position Body2 [0, -1, 0]
+// Axis of the prismatic [0, 1, 0]
+// Axis of the rotoide [1, 0, ]0
+//
+// Only the first body moves
+////////////////////////////////////////////////////////////////////////////////
+ TEST_FIXTURE(PRGetInfo1_Fixture_3, GetPRPositionRate_Bodies_in_line_B1_moves)
+ {
+ dBodySetLinearVel(bId1, REAL(3.33), REAL(0.0), REAL(0.0)); // This is impossible but ...
+ CHECK_EQUAL(REAL(0.0), dJointGetPRPositionRate (jId) );
+
+ dBodySetLinearVel(bId1, REAL(0.0), REAL(3.33), REAL(0.0));
+ CHECK_EQUAL(REAL(3.33), dJointGetPRPositionRate (jId) );
+
+ dBodySetLinearVel(bId1, REAL(0.0), REAL(0.0), REAL(3.33)); // This is impossible but ...
+ CHECK_EQUAL(REAL(0.0), dJointGetPRPositionRate (jId) );
+
+
+ // Only the first body as angular velocity
+ dBodySetAngularVel(bId1, REAL(1.22), REAL(0.0), REAL(0.0));
+ CHECK_EQUAL(REAL(0.0), dJointGetPRPositionRate (jId) );
+
+ dBodySetAngularVel(bId1, REAL(0.0), REAL(2.33), REAL(0.0));
+ CHECK_EQUAL(REAL(0.0), dJointGetPRPositionRate (jId) );
+
+ dBodySetAngularVel(bId1, REAL(0.0), REAL(0.0), REAL(5.55));
+ CHECK_EQUAL(REAL(0.0), dJointGetPRPositionRate (jId) );
+ }
+
+////////////////////////////////////////////////////////////////////////////////
+// Position Body1 [0, 1, 0]
+// Position Body2 [0, -1, 0]
+// Axis of the prismatic [0, 1, 0]
+// Axis of the rotoide [1, 0, ]0
+//
+// Only the second body moves
+////////////////////////////////////////////////////////////////////////////////
+ TEST_FIXTURE(PRGetInfo1_Fixture_3, GetPRPositionRate_Bodies_in_line_B2_moves)
+ {
+ dBodySetLinearVel(bId2, REAL(3.33), REAL(0.0), REAL(0.0)); // This is impossible but ...
+ CHECK_EQUAL(REAL(0.0), dJointGetPRPositionRate (jId) );
+
+ // The length was at zero and this will give an negative length
+ dBodySetLinearVel(bId2, REAL(0.0), REAL(3.33), REAL(0.0));
+ CHECK_EQUAL(REAL(-3.33), dJointGetPRPositionRate (jId) );
+
+ dBodySetLinearVel(bId2, REAL(0.0), REAL(0.0), REAL(3.33)); // This is impossible but ...
+ CHECK_EQUAL(REAL(0.0), dJointGetPRPositionRate (jId) );
+
+
+ // Only angular velocity
+ dBodySetAngularVel(bId2, REAL(1.22), REAL(0.0), REAL(0.0));
+ CHECK_EQUAL(REAL(0.0), dJointGetPRPositionRate (jId) );
+
+ dBodySetAngularVel(bId2, REAL(0.0), REAL(2.33), REAL(0.0));
+ CHECK_EQUAL(REAL(0.0), dJointGetPRPositionRate (jId) );
+
+ dBodySetAngularVel(bId2, REAL(0.0), REAL(0.0), REAL(5.55));
+ CHECK_EQUAL(REAL(0.0), dJointGetPRPositionRate (jId) );
+ }
+
+
+////////////////////////////////////////////////////////////////////////////////
+// Fixture for testing the PositionRate
+//
+// The second body is at 90deg w.r.t. the first body
+//
+//
+// Default Position
+// ^Z
+// |
+// |
+//
+// +---+
+// | |Body2
+// | |
+// | |
+// +---+
+// |
+// |
+// |
+// | Body1
+// R _ - +-----------+
+// (_)----|-----| | ----->Y
+// - +-----------+
+//
+// N.B. X is comming out of the page
+////////////////////////////////////////////////////////////////////////////////
+ struct PRGetInfo1_Fixture_4
+ {
+ PRGetInfo1_Fixture_4()
+ {
+ wId = dWorldCreate();
+
+ bId1 = dBodyCreate(wId);
+ dBodySetPosition(bId1, 0, 1, 0);
+
+ bId2 = dBodyCreate(wId);
+ dBodySetPosition(bId2, 0, 0, 1);
+
+ dMatrix3 R;
+ dRFromAxisAndAngle (R, 1, 0, 0, -M_PI/2.0);
+ dBodySetRotation (bId2, R);
+
+
+ jId = dJointCreatePR(wId, 0);
+ joint = (dxJointPR*)jId;
+
+ dJointAttach(jId, bId1, bId2);
+ dJointSetPRAnchor (jId, REAL(0.0), REAL(0.0), REAL(0.0));
+
+ dBodySetLinearVel(bId1, REAL(0.0), REAL(0.0), REAL(0.0));
+ dBodySetAngularVel(bId1, REAL(0.0), REAL(0.0), REAL(0.0));
+
+ dBodySetLinearVel(bId2, REAL(0.0), REAL(0.0), REAL(0.0));
+ dBodySetAngularVel(bId1, REAL(0.0), REAL(0.0), REAL(0.0));
+
+ }
+
+ ~PRGetInfo1_Fixture_4()
+ {
+ dWorldDestroy(wId);
+ }
+
+ dJointID jId;
+ dxJointPR* joint;
+
+ dWorldID wId;
+
+ dBodyID bId1;
+ dBodyID bId2;
+
+ dxJoint::Info1 info;
+ };
+
+
+////////////////////////////////////////////////////////////////////////////////
+// Position Body1 [0, 1, 0]
+// Position Body2 [0, 0, 1]
+// Axis of the prismatic [0, 1, 0]
+// Axis of the rotoide [1, 0, 0]
+//
+// Only the first body moves
+////////////////////////////////////////////////////////////////////////////////
+ TEST_FIXTURE(PRGetInfo1_Fixture_4, GetPRPositionRate_Bodies_at90deg_B1_moves)
+ {
+ dBodySetLinearVel(bId1, REAL(3.33), REAL(0.0), REAL(0.0)); // This is impossible but ...
+ CHECK_EQUAL(REAL(0.0), dJointGetPRPositionRate (jId) );
+
+ // The length was at zero and this will give an negative length
+ dBodySetLinearVel(bId1, REAL(0.0), REAL(3.33), REAL(0.0));
+ CHECK_EQUAL(REAL(3.33), dJointGetPRPositionRate (jId) );
+
+ dBodySetLinearVel(bId1, REAL(0.0), REAL(0.0), REAL(3.33)); // This is impossible but ...
+ CHECK_EQUAL(REAL(0.0), dJointGetPRPositionRate (jId) );
+
+
+ // Only angular velocity
+ dBodySetAngularVel(bId1, REAL(1.22), REAL(0.0), REAL(0.0));
+ CHECK_EQUAL(REAL(0.0), dJointGetPRPositionRate (jId) );
+
+ dBodySetAngularVel(bId1, REAL(0.0), REAL(2.33), REAL(0.0));
+ CHECK_EQUAL(REAL(0.0), dJointGetPRPositionRate (jId) );
+
+ dBodySetAngularVel(bId1, REAL(0.0), REAL(0.0), REAL(5.55));
+ CHECK_EQUAL(REAL(0.0), dJointGetPRPositionRate (jId) );
+ }
+
+////////////////////////////////////////////////////////////////////////////////
+// Position Body1 [0, 1, 0]
+// Position Body2 [0, 0, 1]
+// Axis of the prismatic [0, 1, 0]
+// Axis of the rotoide [1, 0, 0]
+//
+// Only the second body moves
+////////////////////////////////////////////////////////////////////////////////
+ TEST_FIXTURE(PRGetInfo1_Fixture_4, GetPRPositionRate_Bodies_at90deg_B2_moves)
+ {
+ dBodySetLinearVel(bId2, REAL(3.33), REAL(0.0), REAL(0.0)); // This is impossible but ...
+ CHECK_EQUAL(REAL(0.0), dJointGetPRPositionRate (jId) );
+
+ dBodySetLinearVel(bId2, REAL(0.0), REAL(3.33), REAL(0.0));
+ CHECK_EQUAL(REAL(-3.33), dJointGetPRPositionRate (jId) );
+
+ dBodySetLinearVel(bId2, REAL(0.0), REAL(0.0), REAL(3.33)); // This is impossible but ...
+ CHECK_EQUAL(REAL(0.0), dJointGetPRPositionRate (jId) );
+
+
+ // Only angular velocity
+ dBodySetAngularVel(bId2, REAL(1.22), REAL(0.0), REAL(0.0));
+ CHECK_EQUAL(REAL(-1.0*1.22), dJointGetPRPositionRate (jId) );
+
+ dBodySetAngularVel(bId2, REAL(0.0), REAL(2.33), REAL(0.0));
+ CHECK_EQUAL(REAL(0.0), dJointGetPRPositionRate (jId) );
+
+ dBodySetAngularVel(bId2, REAL(0.0), REAL(0.0), REAL(5.55));
+ CHECK_EQUAL(REAL(0.0), dJointGetPRPositionRate (jId) );
+ }
+
+} // End of SUITE(JointPR)
+
+
+
+
+
+// // //
+// Testing the PU Joint
+//
+// //
+////////////////////////////////////////////////////////////////////////////////
+// Default Position:
+// Position Body1 (3, 0, 0)
+// Position Body2 (1, 0, 0)
+// Angchor (2, 0, 0)
+// Axis1 (0, 1, 0)
+// Axis2 (0, 0, 1)
+// AxisP1 (1, 0, 0)
+//
+// Y ^ Axis2
+// ^ |
+// / | ^ Axis1
+// Z^ / | /
+// | / Body 2 | / Body 1
+// | / +---------+ | / +-----------+
+// | / / /| | / / /|
+// | / / / + _/ - / / +
+// | / / /-/--------(_)----|--- /-----------/-------> AxisP
+// | / +---------+ / - +-----------+ /
+// | / | |/ | |/
+// | / +---------+ +-----------+
+// |/
+// .-----------------------------------------> X
+// |----------------->
+// Anchor2 <--------------|
+// Anchor1
+//
+////////////////////////////////////////////////////////////////////////////////
+SUITE(JointPU)
+{
+ struct PUGetInfo1_Fixture_1
+ {
+ PUGetInfo1_Fixture_1()
+ {
+ wId = dWorldCreate();
+
+ bId1 = dBodyCreate(wId);
+ dBodySetPosition(bId1, 3, 0, 0);
+
+ bId2 = dBodyCreate(wId);
+ dBodySetPosition(bId2, 1, 0, 0);
+
+
+ jId = dJointCreatePU(wId, 0);
+ joint = (dxJointPU*)jId;
+
+ dJointAttach(jId, bId1, bId2);
+
+ dJointSetPUAnchor (jId, 2, 0, 0);
+ }
+
+ ~PUGetInfo1_Fixture_1()
+ {
+ dWorldDestroy(wId);
+ }
+
+ dJointID jId;
+ dxJointPU* joint;
+
+ dWorldID wId;
+
+ dBodyID bId1;
+ dBodyID bId2;
+
+ dxJoint::Info1 info;
+ };
+
+
+////////////////////////////////////////////////////////////////////////////////
+// Test when there is no limits.
+// The 2 bodies stay aligned.
+//
+////////////////////////////////////////////////////////////////////////////////
+ TEST_FIXTURE(PUGetInfo1_Fixture_1, test1_SetPUParam)
+ {
+ dJointSetPUParam(jId, dParamLoStop1, -M_PI);
+ dJointSetPUParam(jId, dParamHiStop1 , M_PI);
+ dJointSetPUParam(jId, dParamLoStop2, -M_PI);
+ dJointSetPUParam(jId, dParamHiStop2, M_PI);
+ dJointSetPUParam(jId, dParamLoStop3, -dInfinity);
+ dJointSetPUParam(jId, dParamHiStop3, dInfinity);
+
+ joint->getInfo1(&info);
+
+ CHECK_EQUAL(0, joint->limot1.limit);
+ CHECK_EQUAL(0, joint->limot2.limit);
+ CHECK_EQUAL(0, joint->limotP.limit);
+ CHECK_EQUAL(3, info.m);
+ }
+
+
+////////////////////////////////////////////////////////////////////////////////
+// Test when there is limits for the prismatic at -10 and 10
+// The Body 2 is moved -100 unit then at 100
+//
+// Default value for axisR1 = 1,0,0
+// Default value for axisP1 = 0,1,0
+////////////////////////////////////////////////////////////////////////////////
+ TEST_FIXTURE(PUGetInfo1_Fixture_1, test1_GetPUParam)
+ {
+ dJointSetPUParam(jId, dParamLoStop3, -10);
+ dJointSetPUParam(jId, dParamHiStop3, 10);
+
+ dBodySetPosition(bId2, REAL(-100.0), REAL(0.0), REAL(0.0));
+
+ joint->getInfo1(&info);
+
+
+ CHECK_EQUAL(0, joint->limot1.limit);
+ CHECK_EQUAL(0, joint->limot2.limit);
+ CHECK_EQUAL(2, joint->limotP.limit);
+ CHECK_EQUAL(4, info.m);
+
+
+ dBodySetPosition(bId2, REAL(100.0), REAL(0.0), REAL(0.0));
+
+ joint->getInfo1(&info);
+
+ CHECK_EQUAL(0, joint->limot1.limit);
+ CHECK_EQUAL(0, joint->limot2.limit);
+ CHECK_EQUAL(1, joint->limotP.limit);
+ CHECK_EQUAL(4, info.m);
+
+ // Reset Position and test
+ dBodySetPosition(bId2, 1, 0, 0);
+ dMatrix3 R_final = { 1,0,0,0,
+ 0,1,0,0,
+ 0,0,1,0
+ };
+ dBodySetRotation (bId2, R_final);
+
+ joint->getInfo1(&info);
+
+
+ CHECK_EQUAL(0, joint->limot1.limit);
+ CHECK_EQUAL(0, joint->limot2.limit);
+ CHECK_EQUAL(0, joint->limotP.limit);
+ CHECK_EQUAL(3, info.m);
+ }
+
+////////////////////////////////////////////////////////////////////////////////
+// Test when there is limits for the prismatic at -10 and 10
+// and for Axis1 and Axis2 at -45deg and 45deg.
+// The Body 2 is rotated by 90deg around Axis1
+//
+//
+////////////////////////////////////////////////////////////////////////////////
+ TEST_FIXTURE(PUGetInfo1_Fixture_1, test2_PUGetInfo1)
+ {
+ dJointSetPUParam(jId, dParamLoStop1, -M_PI/4.0);
+ dJointSetPUParam(jId, dParamHiStop1, M_PI/4.0);
+ dJointSetPUParam(jId, dParamLoStop2, -M_PI/4.0);
+ dJointSetPUParam(jId, dParamHiStop2, M_PI/4.0);
+ dJointSetPUParam(jId, dParamLoStop3, -10);
+ dJointSetPUParam(jId, dParamHiStop3, 10);
+
+
+ dMatrix3 R;
+ dBodySetPosition (bId2, 0, 0, 1);
+ dRFromAxisAndAngle (R, 0, 1, 0, M_PI/2.0);
+ dBodySetRotation (bId2, R);
+
+ joint->getInfo1(&info);
+
+ CHECK_EQUAL(1, joint->limot1.limit);
+ CHECK_EQUAL(0, joint->limot2.limit);
+ CHECK_EQUAL(0, joint->limotP.limit);
+ CHECK_EQUAL(4, info.m);
+
+ // Reset Position and test
+ dBodySetPosition(bId2, 1, 0, 0);
+ dMatrix3 R_final = { 1,0,0,0,
+ 0,1,0,0,
+ 0,0,1,0
+ };
+ dBodySetRotation (bId2, R_final);
+
+ joint->getInfo1(&info);
+
+ CHECK_EQUAL(0, joint->limot1.limit);
+ CHECK_EQUAL(0, joint->limot2.limit);
+ CHECK_EQUAL(0, joint->limotP.limit);
+ CHECK_EQUAL(3, info.m);
+ }
+
+////////////////////////////////////////////////////////////////////////////////
+// Test when there is limits for the prismatic at -10 and 10
+// and for Axis1 and Axis2 at -45deg and 45deg.
+// The Body 2 is rotated by 90deg around Axis1 and
+// Body1 is moved at X=100
+//
+//
+////////////////////////////////////////////////////////////////////////////////
+ TEST_FIXTURE(PUGetInfo1_Fixture_1, test3_PUGetInfo1)
+ {
+ dJointSetPUParam(jId, dParamLoStop1, -M_PI/4.0);
+ dJointSetPUParam(jId, dParamHiStop1, M_PI/4.0);
+ dJointSetPUParam(jId, dParamLoStop2, -M_PI/4.0);
+ dJointSetPUParam(jId, dParamHiStop2, M_PI/4.0);
+ dJointSetPUParam(jId, dParamLoStop3, -10);
+ dJointSetPUParam(jId, dParamHiStop3, 10);
+
+
+ dBodySetPosition (bId1, REAL(100.0), REAL(0.0), REAL(0.0));
+
+ dMatrix3 R;
+ dBodySetPosition (bId2, 0, 0, 1);
+ dRFromAxisAndAngle (R, 0, 1, 0, M_PI/2.0);
+ dBodySetRotation (bId2, R);
+
+ joint->getInfo1(&info);
+
+ CHECK_EQUAL(1, joint->limot1.limit);
+ CHECK_EQUAL(0, joint->limot2.limit);
+ CHECK_EQUAL(2, joint->limotP.limit);
+ CHECK_EQUAL(5, info.m);
+
+ // Reset Position and test
+ dBodySetPosition(bId1, 3, 0, 0);
+
+ dBodySetPosition(bId2, 1, 0, 0);
+ dMatrix3 R_final = { 1,0,0,0,
+ 0,1,0,0,
+ 0,0,1,0
+ };
+ dBodySetRotation (bId2, R_final);
+
+ joint->getInfo1(&info);
+
+ CHECK_EQUAL(0, joint->limot1.limit);
+ CHECK_EQUAL(0, joint->limot2.limit);
+ CHECK_EQUAL(0, joint->limotP.limit);
+ CHECK_EQUAL(3, info.m);
+ }
+
+
+////////////////////////////////////////////////////////////////////////////////
+// Default Position:
+// Position Body1 (3, 0, 0)
+// Position Body2 (1, 0, 0)
+// Angchor (2, 0, 0)
+// Axis1 (0, 1, 0)
+// Axis2 (0, 0, 1)
+// AxisP1 (1, 0, 0)
+//
+// The motor on axis1 is now powered. (i.e. joint->limot1->fmax > 0
+//
+// Y ^ Axis2
+// ^ |
+// / | ^ Axis1
+// Z^ / | /
+// | / Body 2 | / Body 1
+// | / +---------+ | / +-----------+
+// | / / /| | / / /|
+// | / / / + _/ - / / +
+// | / / /-/--------(_)----|--- /-----------/-------> AxisP
+// | / +---------+ / - +-----------+ /
+// | / | |/ | |/
+// | / +---------+ +-----------+
+// |/
+// .-----------------------------------------> X
+// |----------------->
+// Anchor2 <--------------|
+// Anchor1
+//
+////////////////////////////////////////////////////////////////////////////////
+ struct PUGetInfo1_Fixture_2
+ {
+ PUGetInfo1_Fixture_2()
+ {
+ wId = dWorldCreate();
+
+ bId1 = dBodyCreate(wId);
+ dBodySetPosition(bId1, 3, 0, 0);
+
+ bId2 = dBodyCreate(wId);
+ dBodySetPosition(bId2, 1, 0, 0);
+
+
+ jId = dJointCreatePU(wId, 0);
+ joint = (dxJointPU*)jId;
+
+ dJointAttach(jId, bId1, bId2);
+
+ dJointSetPUAnchor (jId, 2, 0, 0);
+
+ joint->limot1.fmax = 1;
+ }
+
+ ~PUGetInfo1_Fixture_2()
+ {
+ dWorldDestroy(wId);
+ }
+
+ dJointID jId;
+ dxJointPU* joint;
+
+ dWorldID wId;
+
+ dBodyID bId1;
+ dBodyID bId2;
+
+ dxJoint::Info1 info;
+ };
+
+
+
+////////////////////////////////////////////////////////////////////////////////
+// Test when there is no limits.
+// The 2 bodies stay aligned.
+//
+////////////////////////////////////////////////////////////////////////////////
+ TEST_FIXTURE(PUGetInfo1_Fixture_2, test0_PUGetInfo1)
+ {
+ dJointSetPUParam(jId, dParamLoStop1, -M_PI);
+ dJointSetPUParam(jId, dParamHiStop1 , M_PI);
+ dJointSetPUParam(jId, dParamLoStop2, -M_PI);
+ dJointSetPUParam(jId, dParamHiStop2, M_PI);
+ dJointSetPUParam(jId, dParamLoStop3, -dInfinity);
+ dJointSetPUParam(jId, dParamHiStop3, dInfinity);
+
+ joint->getInfo1(&info);
+
+ CHECK_EQUAL(0, joint->limot1.limit);
+ CHECK_EQUAL(0, joint->limot2.limit);
+ CHECK_EQUAL(0, joint->limotP.limit);
+ CHECK_EQUAL(4, info.m);
+ }
+
+
+////////////////////////////////////////////////////////////////////////////////
+// Test when there is limits for the prismatic at -10 and 10
+// The Body 2 is moved -100 unit then at 100
+//
+// Default value for axisR1 = 1,0,0
+// Default value for axisP1 = 0,1,0
+////////////////////////////////////////////////////////////////////////////////
+ TEST_FIXTURE(PUGetInfo1_Fixture_2, test1_PUGetInfo1)
+ {
+ dJointSetPUParam(jId, dParamLoStop3, -10);
+ dJointSetPUParam(jId, dParamHiStop3, 10);
+
+ dBodySetPosition(bId2, REAL(-100.0), REAL(0.0), REAL(0.0));
+
+ joint->getInfo1(&info);
+
+
+ CHECK_EQUAL(0, joint->limot1.limit);
+ CHECK_EQUAL(0, joint->limot2.limit);
+ CHECK_EQUAL(2, joint->limotP.limit);
+ CHECK_EQUAL(5, info.m);
+
+
+ dBodySetPosition(bId2, REAL(100.0), REAL(0.0), REAL(0.0));
+
+ joint->getInfo1(&info);
+
+ CHECK_EQUAL(0, joint->limot1.limit);
+ CHECK_EQUAL(0, joint->limot2.limit);
+ CHECK_EQUAL(1, joint->limotP.limit);
+ CHECK_EQUAL(5, info.m);
+
+ // Reset Position and test
+ dBodySetPosition(bId2, 1, 0, 0);
+ dMatrix3 R_final = { 1,0,0,0,
+ 0,1,0,0,
+ 0,0,1,0
+ };
+ dBodySetRotation (bId2, R_final);
+
+ joint->getInfo1(&info);
+
+
+ CHECK_EQUAL(0, joint->limot1.limit);
+ CHECK_EQUAL(0, joint->limot2.limit);
+ CHECK_EQUAL(0, joint->limotP.limit);
+ CHECK_EQUAL(4, info.m);
+ }
+
+////////////////////////////////////////////////////////////////////////////////
+// Test when there is limits for the prismatic at -10 and 10
+// and for Axis1 and Axis2 at -45deg and 45deg.
+// The Body 2 is rotated by 90deg around Axis1
+//
+//
+////////////////////////////////////////////////////////////////////////////////
+ TEST_FIXTURE(PUGetInfo1_Fixture_2, test2_PUGetInfo1)
+ {
+ dJointSetPUParam(jId, dParamLoStop1, -M_PI/4.0);
+ dJointSetPUParam(jId, dParamHiStop1, M_PI/4.0);
+ dJointSetPUParam(jId, dParamLoStop2, -M_PI/4.0);
+ dJointSetPUParam(jId, dParamHiStop2, M_PI/4.0);
+ dJointSetPUParam(jId, dParamLoStop3, -10);
+ dJointSetPUParam(jId, dParamHiStop3, 10);
+
+
+ dMatrix3 R;
+ dBodySetPosition (bId2, 0, 0, 1);
+ dRFromAxisAndAngle (R, 0, 1, 0, M_PI/2.0);
+ dBodySetRotation (bId2, R);
+
+ joint->getInfo1(&info);
+
+ CHECK_EQUAL(1, joint->limot1.limit);
+ CHECK_EQUAL(0, joint->limot2.limit);
+ CHECK_EQUAL(0, joint->limotP.limit);
+ CHECK_EQUAL(4, info.m);
+
+ // Reset Position and test
+ dBodySetPosition(bId2, 1, 0, 0);
+ dMatrix3 R_final = { 1,0,0,0,
+ 0,1,0,0,
+ 0,0,1,0
+ };
+ dBodySetRotation (bId2, R_final);
+
+ joint->getInfo1(&info);
+
+ CHECK_EQUAL(0, joint->limot1.limit);
+ CHECK_EQUAL(0, joint->limot2.limit);
+ CHECK_EQUAL(0, joint->limotP.limit);
+ CHECK_EQUAL(4, info.m);
+ }
+
+////////////////////////////////////////////////////////////////////////////////
+// Test when there is limits for the prismatic at -10 and 10
+// and for Axis1 and Axis2 at -45deg and 45deg.
+// The Body 2 is rotated by 90deg around Axis1 and
+// Body1 is moved at X=100
+//
+//
+////////////////////////////////////////////////////////////////////////////////
+ TEST_FIXTURE(PUGetInfo1_Fixture_2, test3_PUGetInfo1)
+ {
+ dJointSetPUParam(jId, dParamLoStop1, -M_PI/4.0);
+ dJointSetPUParam(jId, dParamHiStop1, M_PI/4.0);
+ dJointSetPUParam(jId, dParamLoStop2, -M_PI/4.0);
+ dJointSetPUParam(jId, dParamHiStop2, M_PI/4.0);
+ dJointSetPUParam(jId, dParamLoStop3, -10);
+ dJointSetPUParam(jId, dParamHiStop3, 10);
+
+
+ dBodySetPosition (bId1, REAL(100.0), REAL(0.0), REAL(0.0));
+
+ dMatrix3 R;
+ dBodySetPosition (bId2, 0, 0, 1);
+ dRFromAxisAndAngle (R, 0, 1, 0, M_PI/2.0);
+ dBodySetRotation (bId2, R);
+
+ joint->getInfo1(&info);
+
+ CHECK_EQUAL(1, joint->limot1.limit);
+ CHECK_EQUAL(0, joint->limot2.limit);
+ CHECK_EQUAL(2, joint->limotP.limit);
+ CHECK_EQUAL(5, info.m);
+
+ // Reset Position and test
+ dBodySetPosition(bId1, 3, 0, 0);
+
+ dBodySetPosition(bId2, 1, 0, 0);
+ dMatrix3 R_final = { 1,0,0,0,
+ 0,1,0,0,
+ 0,0,1,0
+ };
+ dBodySetRotation (bId2, R_final);
+
+ joint->getInfo1(&info);
+
+ CHECK_EQUAL(0, joint->limot1.limit);
+ CHECK_EQUAL(0, joint->limot2.limit);
+ CHECK_EQUAL(0, joint->limotP.limit);
+ CHECK_EQUAL(4, info.m);
+ }
+
+
+
+ TEST_FIXTURE(PUGetInfo1_Fixture_2, test_SetPUParam)
+ {
+ dJointSetPUParam(jId, dParamHiStop, REAL(5.0) );
+ CHECK_EQUAL(REAL(5.0), joint->limot1.histop);
+
+ dJointSetPUParam(jId, dParamVel, REAL(7.0) );
+ CHECK_EQUAL(REAL(7.0), joint->limot1.vel);
+
+#ifdef dParamFudgeFactor1
+ dJointSetPUParam(jId, dParamFudgeFactor1, REAL(5.5) );
+ CHECK_EQUAL(REAL(5.5), joint->limot1.dParamFudgeFactor);
+#endif
+
+ dJointSetPUParam(jId, dParamCFM2, REAL(9.0) );
+ CHECK_EQUAL(REAL(9.0), joint->limot2.normal_cfm);
+
+ dJointSetPUParam(jId, dParamStopERP2, REAL(11.0) );
+ CHECK_EQUAL(REAL(11.0), joint->limot2.stop_erp);
+
+
+ dJointSetPUParam(jId, dParamBounce3, REAL(13.0) );
+ CHECK_EQUAL(REAL(13.0), joint->limotP.bounce);
+ }
+
+
+
+ TEST_FIXTURE(PUGetInfo1_Fixture_1, test_GetPUParam)
+ {
+ joint->limotP.histop = REAL(5.0);
+ CHECK_EQUAL(joint->limot1.histop,
+ dJointGetPUParam(jId, dParamHiStop) );
+
+ joint->limotP.vel = REAL(7.0);
+
+ CHECK_EQUAL(joint->limot1.vel,
+ dJointGetPUParam(jId, dParamVel) );
+
+#ifdef dParamFudgeFactor1
+ joint->limotP.dParamFudgeFactor = REAL(5.5);
+
+ CHECK_EQUAL(joint->limot1.dParamFudgeFactor,
+ dJointGetPUParam(jId, dParamFudgeFactor1) );
+#endif
+
+ joint->limot2.normal_cfm = REAL(9.0);
+ CHECK_EQUAL(joint->limot2.normal_cfm,
+ dJointGetPUParam(jId, dParamCFM2) );
+
+ joint->limot2.stop_erp = REAL(11.0);
+ CHECK_EQUAL(joint->limot2.stop_erp,
+ dJointGetPUParam(jId, dParamStopERP2) );
+
+ joint->limotP.bounce = REAL(13.0);
+ CHECK_EQUAL(joint->limotP.bounce,
+ dJointGetPUParam(jId, dParamBounce3) );
+ }
+
+
+
+////////////////////////////////////////////////////////////////////////////////
+// Texture for testing the PositionRate
+//
+// Default Position:
+// Position Body1 (3, 0, 0)
+// Position Body2 (1, 0, 0)
+// Angchor (2, 0, 0)
+// Axis1 (0, 1, 0)
+// Axis2 (0, 0, 1)
+// AxisP1 (1, 0, 0)
+//
+// Default velocity:
+// Body 1 lvel=( 0, 0, 0) avel=( 0, 0, 0)
+// Body 2 lvel=( 0, 0, 0) avel=( 0, 0, 0)
+//
+//
+// Y ^ Axis2
+// ^ |
+// / | ^ Axis1
+// Z^ / | /
+// | / Body 2 | / Body 1
+// | / +---------+ | / +-----------+
+// | / / /| | / / /|
+// | / / / + _/ - / / +
+// | / / /-/--------(_)----|--- /-----------/-------> AxisP
+// | / +---------+ / - +-----------+ /
+// | / | |/ | |/
+// | / +---------+ +-----------+
+// |/
+// .-----------------------------------------> X
+// |----------------->
+// Anchor2 <--------------|
+// Anchor1
+//
+////////////////////////////////////////////////////////////////////////////////
+ struct PUGetInfo1_Fixture_3
+ {
+ PUGetInfo1_Fixture_3()
+ {
+ wId = dWorldCreate();
+
+ bId1 = dBodyCreate(wId);
+ dBodySetPosition(bId1, 3, 0, 0);
+
+ bId2 = dBodyCreate(wId);
+ dBodySetPosition(bId2, 1, 0, 0);
+
+
+ jId = dJointCreatePU(wId, 0);
+ joint = (dxJointPU*)jId;
+
+ dJointAttach(jId, bId1, bId2);
+ dJointSetPUAnchor (jId, 2, 0, 0);
+
+ dBodySetLinearVel (bId1, REAL(0.0), REAL(0.0), REAL(0.0));
+ dBodySetAngularVel(bId1, REAL(0.0), REAL(0.0), REAL(0.0));
+
+ dBodySetLinearVel (bId2, REAL(0.0), REAL(0.0), REAL(0.0));
+ dBodySetAngularVel(bId1, REAL(0.0), REAL(0.0), REAL(0.0));
+
+ }
+
+ ~PUGetInfo1_Fixture_3()
+ {
+ dWorldDestroy(wId);
+ }
+
+ dJointID jId;
+ dxJointPU* joint;
+
+ dWorldID wId;
+
+ dBodyID bId1;
+ dBodyID bId2;
+
+ dxJoint::Info1 info;
+ };
+
+////////////////////////////////////////////////////////////////////////////////
+// Position Body1 [3, 0, 0]
+// Position Body2 [1, 0, 0]
+// Axis of the prismatic [1, 0, 0]
+// Axis1 [0, 1, 0]
+// Axis2 [0, 0, 1]
+//
+// Move at the same speed
+////////////////////////////////////////////////////////////////////////////////
+ TEST_FIXTURE(PUGetInfo1_Fixture_3, test1_GetPUPositionRate)
+ {
+ // They move with the same linear speed
+ // Angular speed == 0
+ dBodySetLinearVel(bId1, REAL(0.0), REAL(3.33), REAL(0.0));
+ dBodySetLinearVel(bId2, REAL(0.0), REAL(3.33), REAL(0.0));
+ CHECK_EQUAL(REAL(0.0), dJointGetPUPositionRate (jId) );
+
+ dBodySetLinearVel(bId1, REAL(1.11), REAL(3.33), REAL(0.0));
+ dBodySetLinearVel(bId2, REAL(1.11), REAL(3.33), REAL(0.0));
+ CHECK_EQUAL(REAL(0.0), dJointGetPUPositionRate (jId) );
+
+ dBodySetLinearVel(bId1, REAL(1.11), REAL(3.33), REAL(2.22));
+ dBodySetLinearVel(bId2, REAL(1.11), REAL(3.33), REAL(2.22));
+ CHECK_EQUAL(REAL(0.0), dJointGetPUPositionRate (jId) );
+
+
+ // Reset for the next set of test.
+ dBodySetLinearVel(bId1, REAL(0.0), REAL(0.0), REAL(0.0));
+ dBodySetAngularVel(bId1, REAL(0.0), REAL(0.0), REAL(0.0));
+
+ dBodySetLinearVel(bId2, REAL(0.0), REAL(0.0), REAL(0.0));
+ dBodySetAngularVel(bId1, REAL(0.0), REAL(0.0), REAL(0.0));
+
+
+ // They move with the same angular speed
+ // linear speed == 0
+
+ dBodySetAngularVel(bId1, REAL(1.22), REAL(0.0), REAL(0.0));
+ dBodySetAngularVel(bId2, REAL(1.22), REAL(0.0), REAL(0.0));
+ CHECK_EQUAL(REAL(0.0), dJointGetPUPositionRate (jId) );
+
+ dBodySetAngularVel(bId1, REAL(1.22), REAL(2.33), REAL(0.0));
+ dBodySetAngularVel(bId2, REAL(1.22), REAL(2.33), REAL(0.0));
+ CHECK_EQUAL(REAL(0.0), dJointGetPUPositionRate (jId) );
+
+ dBodySetAngularVel(bId1, REAL(1.22), REAL(2.33), REAL(3.44));
+ dBodySetAngularVel(bId2, REAL(1.22), REAL(2.33), REAL(3.44));
+ CHECK_EQUAL(REAL(0.0), dJointGetPUPositionRate (jId) );
+ }
+
+
+////////////////////////////////////////////////////////////////////////////////
+// Position Body1 [3, 0, 0]
+// Position Body2 [1, 0, 0]
+// Axis of the prismatic [1, 0, 0]
+// Axis1 [0, 1, 0]
+// Axis2 [0, 0, 1]
+//
+// Only the first body moves
+////////////////////////////////////////////////////////////////////////////////
+ TEST_FIXTURE(PUGetInfo1_Fixture_3, GetPUPositionRate_Bodies_in_line_B1_moves)
+ {
+ dBodySetLinearVel(bId1, REAL(3.33), REAL(0.0), REAL(0.0)); // This is impossible but ...
+ CHECK_EQUAL(REAL(3.33), dJointGetPUPositionRate (jId) );
+
+ dBodySetLinearVel(bId1, REAL(0.0), REAL(3.33), REAL(0.0));
+ CHECK_EQUAL(REAL(0.0), dJointGetPUPositionRate (jId) );
+
+ dBodySetLinearVel(bId1, REAL(0.0), REAL(0.0), REAL(3.33)); // This is impossible but ...
+ CHECK_EQUAL(REAL(0.0), dJointGetPUPositionRate (jId) );
+
+
+ // Only the first body as angular velocity
+ dBodySetAngularVel(bId1, REAL(1.22), REAL(0.0), REAL(0.0));
+ CHECK_EQUAL(REAL(0.0), dJointGetPUPositionRate (jId) );
+
+ dBodySetAngularVel(bId1, REAL(0.0), REAL(2.33), REAL(0.0));
+ CHECK_EQUAL(REAL(0.0), dJointGetPUPositionRate (jId) );
+
+ dBodySetAngularVel(bId1, REAL(0.0), REAL(0.0), REAL(5.55));
+ CHECK_EQUAL(REAL(0.0), dJointGetPUPositionRate (jId) );
+ }
+
+////////////////////////////////////////////////////////////////////////////////
+// Position Body1 [3, 0, 0]
+// Position Body2 [1, 0, 0]
+// Axis of the prismatic [1, 0, 0]
+// Axis1 [0, 1, 0]
+// Axis2 [0, 0, 1]
+//
+// Only the second body moves
+////////////////////////////////////////////////////////////////////////////////
+ TEST_FIXTURE(PUGetInfo1_Fixture_3, GetPUPositionRate_Bodies_in_line_B2_moves)
+ {
+ // The length was at zero and this will give an negative length
+ dBodySetLinearVel(bId2, REAL(3.33), REAL(0.0), REAL(0.0));
+ CHECK_EQUAL(REAL(-3.33), dJointGetPUPositionRate (jId) );
+
+ dBodySetLinearVel(bId2, REAL(0.0), REAL(3.33), REAL(0.0)); // This is impossible but ...
+ CHECK_EQUAL(REAL(0.0), dJointGetPUPositionRate (jId) );
+
+ dBodySetLinearVel(bId2, REAL(0.0), REAL(0.0), REAL(3.33)); // This is impossible but ...
+ CHECK_EQUAL(REAL(0.0), dJointGetPUPositionRate (jId) );
+
+
+ // Only angular velocity
+ dBodySetAngularVel(bId2, REAL(1.22), REAL(0.0), REAL(0.0));
+ CHECK_EQUAL(REAL(0.0), dJointGetPUPositionRate (jId) );
+
+ dBodySetAngularVel(bId2, REAL(0.0), REAL(2.33), REAL(0.0));
+ CHECK_EQUAL(REAL(0.0), dJointGetPUPositionRate (jId) );
+
+ dBodySetAngularVel(bId2, REAL(0.0), REAL(0.0), REAL(5.55));
+ CHECK_EQUAL(REAL(0.0), dJointGetPUPositionRate (jId) );
+ }
+
+
+////////////////////////////////////////////////////////////////////////////////
+// Fixture for testing the PositionRate
+//
+// Default Position:
+// Position Body1 (3, 0, 0)
+// Position Body2 (0, 0, 1)
+// Angchor (2, 0, 0)
+// Axis1 (0, 1, 0)
+// Axis2 (1, 0, 0)
+// AxisP (1, 0, 0)
+//
+// The second body is at 90deg w.r.t. the first body
+//
+//
+// Default Position
+// ^Z
+// |
+// |
+//
+// +---+
+// | |Body2
+// | |
+// | |
+// +---+
+// | ^ Axis1
+// | /
+// | /
+// | / Body1
+// R _ - +-----------+
+// (_)----|-----| | ----->X AxisP, Axis2
+// - +-----------+
+//
+// N.B. Y is going into the page
+////////////////////////////////////////////////////////////////////////////////
+ struct PUGetInfo1_Fixture_4
+ {
+ PUGetInfo1_Fixture_4()
+ {
+ wId = dWorldCreate();
+
+ bId1 = dBodyCreate(wId);
+ dBodySetPosition(bId1, 3, 0, 0);
+
+ bId2 = dBodyCreate(wId);
+ dBodySetPosition(bId2, 0, 0, 1);
+
+ dMatrix3 R;
+ dRFromAxisAndAngle (R, 1, 0, 0, -M_PI/2.0);
+ dBodySetRotation (bId2, R);
+
+
+ jId = dJointCreatePU(wId, 0);
+ joint = (dxJointPU*)jId;
+
+ dJointAttach(jId, bId1, bId2);
+ dJointSetPUAnchor (jId, 2, 0, 0);
+ dJointSetPUAxis1 (jId, 0, 1, 0);
+ dJointSetPUAxis2 (jId, 1, 0, 0);
+ dJointSetPUAxisP (jId, 1, 0, 0);
+
+
+ dBodySetLinearVel(bId1, REAL(0.0), REAL(0.0), REAL(0.0));
+ dBodySetAngularVel(bId1, REAL(0.0), REAL(0.0), REAL(0.0));
+
+ dBodySetLinearVel(bId2, REAL(0.0), REAL(0.0), REAL(0.0));
+ dBodySetAngularVel(bId1, REAL(0.0), REAL(0.0), REAL(0.0));
+
+ }
+
+ ~PUGetInfo1_Fixture_4()
+ {
+ dWorldDestroy(wId);
+ }
+
+ dJointID jId;
+ dxJointPU* joint;
+
+ dWorldID wId;
+
+ dBodyID bId1;
+ dBodyID bId2;
+
+ dxJoint::Info1 info;
+ };
+
+
+////////////////////////////////////////////////////////////////////////////////
+// Position Body1 (3, 0, 0)
+// Position Body2 (1, 0, 0)
+// Angchor (2, 0, 0)
+// Axis1 (0, 1, 0)
+// Axis2 (0, 0, 1)
+// AxisP1 (1, 0, 0)
+//
+// Only the first body moves
+////////////////////////////////////////////////////////////////////////////////
+ TEST_FIXTURE(PUGetInfo1_Fixture_4, GetPUPositionRate_Bodies_at90deg_B1_moves)
+ {
+ dBodySetLinearVel(bId1, REAL(3.33), REAL(0.0), REAL(0.0)); // This is impossible but ...
+ CHECK_EQUAL(REAL(3.33), dJointGetPUPositionRate (jId) );
+
+ dBodySetLinearVel(bId1, REAL(0.0), REAL(3.33), REAL(0.0));
+ CHECK_EQUAL(REAL(0.0), dJointGetPUPositionRate (jId) );
+
+ dBodySetLinearVel(bId1, REAL(0.0), REAL(0.0), REAL(3.33)); // This is impossible but ...
+ CHECK_EQUAL(REAL(0.0), dJointGetPUPositionRate (jId) );
+
+
+ // Only angular velocity
+ dBodySetAngularVel(bId1, REAL(1.22), REAL(0.0), REAL(0.0));
+ CHECK_EQUAL(REAL(0.0), dJointGetPUPositionRate (jId) );
+
+ dBodySetAngularVel(bId1, REAL(0.0), REAL(2.33), REAL(0.0));
+ CHECK_EQUAL(REAL(0.0), dJointGetPUPositionRate (jId) );
+
+ dBodySetAngularVel(bId1, REAL(0.0), REAL(0.0), REAL(5.55));
+ CHECK_EQUAL(REAL(0.0), dJointGetPUPositionRate (jId) );
+ }
+
+////////////////////////////////////////////////////////////////////////////////
+// Position Body1 (3, 0, 0)
+// Position Body2 (1, 0, 0)
+// Angchor (2, 0, 0)
+// Axis1 (0, 1, 0)
+// Axis2 (0, 0, 1)
+// AxisP1 (1, 0, 0)
+//
+// Only the second body moves
+////////////////////////////////////////////////////////////////////////////////
+ TEST_FIXTURE(PUGetInfo1_Fixture_4, GetPUPositionRate_Bodies_at90deg_B2_moves)
+ {
+ // The length was at zero and this will give an negative length
+ dBodySetLinearVel(bId2, REAL(3.33), REAL(0.0), REAL(0.0));
+ CHECK_EQUAL(REAL(-3.33), dJointGetPUPositionRate (jId) );
+
+ dBodySetLinearVel(bId2, REAL(0.0), REAL(3.33), REAL(0.0)); // This is impossible but ...
+ CHECK_EQUAL(REAL(0.0), dJointGetPUPositionRate (jId) );
+
+ dBodySetLinearVel(bId2, REAL(0.0), REAL(0.0), REAL(3.33)); // This is impossible but ...
+ CHECK_EQUAL(REAL(0.0), dJointGetPUPositionRate (jId) );
+
+
+ // Only angular velocity
+ dBodySetAngularVel(bId2, REAL(1.22), REAL(0.0), REAL(0.0));
+ CHECK_EQUAL(REAL(0.0), dJointGetPUPositionRate (jId) );
+
+ dBodySetAngularVel(bId2, REAL(0.0), REAL(2.33), REAL(0.0));
+ CHECK_EQUAL(REAL(-1.0*2.330), dJointGetPUPositionRate (jId) );
+
+ dBodySetAngularVel(bId2, REAL(0.0), REAL(0.0), REAL(5.55));
+ CHECK_EQUAL(REAL(0.0), dJointGetPUPositionRate (jId) );
+ }
+
+} // End of SUITE(JointPU)
+
+
+// =============================================================================
+// =============================================================================
+//
+// Testing the Piston Joint
+//
+// =============================================================================
+// =============================================================================
+
+////////////////////////////////////////////////////////////////////////////////
+// Default Position:
+// Position Body1 (1, 0, 0)
+// Position Body2 (3, 0, 0)
+// Angchor (2, 0, 0)
+// AxisR (0, 1, 0)
+// Axis2 (0, 0, 1)
+// AxisP1 (1, 0, 0)
+//
+/// <PRE>
+///^Z |- Anchor point
+/// | Body_1 | Body_2
+/// | +---------------+ V +------------------+
+/// | / /| / /|
+/// | / / + |-- ______ / / +
+/// .- / x /./........x.......(_____()..../ x /.......> axis
+/// +---------------+ / |-- +------------------+ / X
+/// | |/ | |/
+/// +---------------+ +------------------+
+/// | |
+/// | |
+/// |------------------> <----------------------------|
+/// anchor1 anchor2
+///
+///
+/// Axis Y is going into the page
+////////////////////////////////////////////////////////////////////////////////
+SUITE(JointPiston)
+{
+ struct PistonGetInfo1_Fixture_1
+ {
+ PistonGetInfo1_Fixture_1()
+ {
+ wId = dWorldCreate();
+
+ bId1 = dBodyCreate(wId);
+ dBodySetPosition(bId1, 1, 0, 0);
+
+ bId2 = dBodyCreate(wId);
+ dBodySetPosition(bId2, 3, 0, 0);
+
+
+ jId = dJointCreatePiston(wId, 0);
+ joint = (dxJointPiston*)jId;
+
+ dJointAttach(jId, bId1, bId2);
+
+ dJointSetPistonAnchor (jId, 2, 0, 0);
+ }
+
+ ~PistonGetInfo1_Fixture_1()
+ {
+ dWorldDestroy(wId);
+ }
+
+ dJointID jId;
+ dxJointPiston* joint;
+
+ dWorldID wId;
+
+ dBodyID bId1;
+ dBodyID bId2;
+
+ dxJoint::Info1 info;
+ };
+
+
+////////////////////////////////////////////////////////////////////////////////
+// Test when there is no limits.
+// The 2 bodies stay aligned.
+//
+////////////////////////////////////////////////////////////////////////////////
+ TEST_FIXTURE(PistonGetInfo1_Fixture_1, test1_SetPistonParam)
+ {
+ dJointSetPistonParam(jId, dParamLoStop1, -dInfinity);
+ dJointSetPistonParam(jId, dParamHiStop1, dInfinity);
+ dJointSetPistonParam(jId, dParamLoStop2, -M_PI);
+ dJointSetPistonParam(jId, dParamHiStop2 , M_PI);
+
+ joint->getInfo1(&info);
+
+ CHECK_EQUAL(0, joint->limotP.limit);
+ CHECK_EQUAL(0, joint->limotR.limit);
+ CHECK_EQUAL(4, info.m);
+ }
+
+
+////////////////////////////////////////////////////////////////////////////////
+// Test when there is limits for the prismatic at -10 and 10
+// The Body 2 is moved -100 unit then at 100
+//
+// Default value for axisR1 = 1,0,0
+// Default value for axisP1 = 0,1,0
+////////////////////////////////////////////////////////////////////////////////
+ TEST_FIXTURE(PistonGetInfo1_Fixture_1, test1_GetPistonParam)
+ {
+ dJointSetPistonParam(jId, dParamLoStop1, -10);
+ dJointSetPistonParam(jId, dParamHiStop1, 10);
+
+ dBodySetPosition(bId2, REAL(-100.0), REAL(0.0), REAL(0.0));
+
+ joint->getInfo1(&info);
+
+ CHECK_EQUAL(2, joint->limotP.limit);
+ CHECK_EQUAL(0, joint->limotR.limit);
+ CHECK_EQUAL(5, info.m);
+
+
+ dBodySetPosition(bId2, REAL(100.0), REAL(0.0), REAL(0.0));
+
+ joint->getInfo1(&info);
+
+ CHECK_EQUAL(0, joint->limotR.limit);
+ CHECK_EQUAL(1, joint->limotP.limit);
+ CHECK_EQUAL(5, info.m);
+
+ // Reset Position and test
+ dBodySetPosition(bId2, 1, 0, 0);
+ dMatrix3 R_final = { 1,0,0,0,
+ 0,1,0,0,
+ 0,0,1,0
+ };
+ dBodySetRotation (bId2, R_final);
+
+ joint->getInfo1(&info);
+
+
+ CHECK_EQUAL(0, joint->limotR.limit);
+ CHECK_EQUAL(0, joint->limotP.limit);
+ CHECK_EQUAL(4, info.m);
+ }
+
+////////////////////////////////////////////////////////////////////////////////
+// Test when there is limits for the prismatic at -10 and 10
+// and the rotoide at -45deg and 45deg.
+// The Body 2 is rotated by 90deg around the axis
+//
+//
+////////////////////////////////////////////////////////////////////////////////
+ TEST_FIXTURE(PistonGetInfo1_Fixture_1, test2_PistonGetInfo1)
+ {
+ dJointSetPistonParam(jId, dParamLoStop1, -10);
+ dJointSetPistonParam(jId, dParamHiStop1, 10);
+ dJointSetPistonParam(jId, dParamLoStop2, -M_PI/4.0);
+ dJointSetPistonParam(jId, dParamHiStop2, M_PI/4.0);
+
+ dMatrix3 R;
+ dRFromAxisAndAngle (R, 1, 0, 0, M_PI/2.0);
+ dBodySetRotation (bId2, R);
+
+ joint->getInfo1(&info);
+
+ CHECK_EQUAL(1, joint->limotR.limit);
+ CHECK_EQUAL(0, joint->limotP.limit);
+ CHECK_EQUAL(5, info.m);
+
+ // Reset Position and test
+ dMatrix3 R_final = { 1,0,0,0,
+ 0,1,0,0,
+ 0,0,1,0
+ };
+ dBodySetRotation (bId2, R_final);
+
+ joint->getInfo1(&info);
+
+ CHECK_EQUAL(0, joint->limotR.limit);
+ CHECK_EQUAL(0, joint->limotP.limit);
+ CHECK_EQUAL(4, info.m);
+ }
+
+////////////////////////////////////////////////////////////////////////////////
+// Test when there is limits for the prismatic at -10 and 10
+// and for rotoide at -45deg and 45deg.
+// The Body 2 is rotated by 90deg around the axis
+// Body1 is moved at X=100
+//
+//
+////////////////////////////////////////////////////////////////////////////////
+ TEST_FIXTURE(PistonGetInfo1_Fixture_1, test3_PistonGetInfo1)
+ {
+ dJointSetPistonParam(jId, dParamLoStop1, -10);
+ dJointSetPistonParam(jId, dParamHiStop1, 10);
+ dJointSetPistonParam(jId, dParamLoStop2, -M_PI/4.0);
+ dJointSetPistonParam(jId, dParamHiStop2, M_PI/4.0);
+
+
+ dBodySetPosition (bId1, REAL(100.0), REAL(0.0), REAL(0.0));
+
+ dMatrix3 R;
+ dRFromAxisAndAngle (R, 1, 0, 0, M_PI/2.0);
+ dBodySetRotation (bId2, R);
+
+ joint->getInfo1(&info);
+
+ CHECK_EQUAL(2, joint->limotP.limit);
+ CHECK_EQUAL(1, joint->limotR.limit);
+
+ CHECK_EQUAL(6, info.m);
+
+ // Reset Position and test
+ dBodySetPosition(bId1, 1, 0, 0);
+
+ dMatrix3 R_final = { 1,0,0,0,
+ 0,1,0,0,
+ 0,0,1,0
+ };
+ dBodySetRotation (bId2, R_final);
+
+ joint->getInfo1(&info);
+
+ CHECK_EQUAL(0, joint->limotP.limit);
+ CHECK_EQUAL(0, joint->limotR.limit);
+ CHECK_EQUAL(4, info.m);
+ }
+
+
+////////////////////////////////////////////////////////////////////////////////
+// Default Position:
+// Position Body1 (1, 0, 0)
+// Position Body2 (3, 0, 0)
+// Angchor (2, 0, 0)
+// AxisR (0, 1, 0)
+// Axis2 (0, 0, 1)
+// AxisP1 (1, 0, 0)
+//
+// The motor on axis1 is now powered. (i.e. joint->limot1->fmax > 0
+//
+/// <PRE>
+///^Z |- Anchor point
+/// | Body_1 | Body_2
+/// | +---------------+ V +------------------+
+/// | / /| / /|
+/// | / / + |-- ______ / / +
+/// .- / x /./........x.......(_____()..../ x /.......> axis
+/// +---------------+ / |-- +------------------+ / X
+/// | |/ | |/
+/// +---------------+ +------------------+
+/// | |
+/// | |
+/// |------------------> <----------------------------|
+/// anchor1 anchor2
+///
+///
+/// Axis Y is going into the page
+////////////////////////////////////////////////////////////////////////////////
+ struct PistonGetInfo1_Fixture_2
+ {
+ PistonGetInfo1_Fixture_2()
+ {
+ wId = dWorldCreate();
+
+ bId1 = dBodyCreate(wId);
+ dBodySetPosition(bId1, 1, 0, 0);
+
+ bId2 = dBodyCreate(wId);
+ dBodySetPosition(bId2, 3, 0, 0);
+
+
+ jId = dJointCreatePiston(wId, 0);
+ joint = (dxJointPiston*)jId;
+
+ dJointAttach(jId, bId1, bId2);
+
+ dJointSetPistonAnchor (jId, 2, 0, 0);
+
+ joint->limotP.fmax = 1;
+ }
+
+ ~PistonGetInfo1_Fixture_2()
+ {
+ dWorldDestroy(wId);
+ }
+
+ dJointID jId;
+ dxJointPiston* joint;
+
+ dWorldID wId;
+
+ dBodyID bId1;
+ dBodyID bId2;
+
+ dxJoint::Info1 info;
+ };
+
+
+
+////////////////////////////////////////////////////////////////////////////////
+// Test when there is no limits.
+// The 2 bodies stay aligned.
+//
+////////////////////////////////////////////////////////////////////////////////
+ TEST_FIXTURE(PistonGetInfo1_Fixture_2, test0_PistonGetInfo1)
+ {
+ dJointSetPistonParam(jId, dParamLoStop1, -dInfinity);
+ dJointSetPistonParam(jId, dParamHiStop1, dInfinity);
+ dJointSetPistonParam(jId, dParamLoStop2, -M_PI);
+ dJointSetPistonParam(jId, dParamHiStop2, M_PI);
+
+
+ joint->getInfo1(&info);
+
+ CHECK_EQUAL(0, joint->limotP.limit);
+ CHECK_EQUAL(0, joint->limotR.limit);
+ CHECK_EQUAL(5, info.m);
+ }
+
+
+////////////////////////////////////////////////////////////////////////////////
+// Test when there is limits for the prismatic at -10 and 10
+// The Body 2 is moved -100 unit then at 100
+//
+// Default value for axis = 1,0,0
+////////////////////////////////////////////////////////////////////////////////
+ TEST_FIXTURE(PistonGetInfo1_Fixture_2, test1_PistonGetInfo1)
+ {
+ dJointSetPistonParam(jId, dParamLoStop1, -10);
+ dJointSetPistonParam(jId, dParamHiStop1, 10);
+
+ dBodySetPosition(bId2, REAL(-100.0), REAL(0.0), REAL(0.0));
+
+ joint->getInfo1(&info);
+
+ CHECK_EQUAL(2, joint->limotP.limit);
+ CHECK_EQUAL(0, joint->limotR.limit);
+ CHECK_EQUAL(5, info.m);
+
+
+ dBodySetPosition(bId2, REAL(100.0), REAL(0.0), REAL(0.0));
+
+ joint->getInfo1(&info);
+
+ CHECK_EQUAL(1, joint->limotP.limit);
+ CHECK_EQUAL(0, joint->limotR.limit);
+ CHECK_EQUAL(5, info.m);
+
+ // Reset Position and test
+ dBodySetPosition(bId2, 3, 0, 0);
+ dMatrix3 R_final = { 1,0,0,0,
+ 0,1,0,0,
+ 0,0,1,0
+ };
+ dBodySetRotation (bId2, R_final);
+
+ joint->getInfo1(&info);
+
+ CHECK_EQUAL(0, joint->limotP.limit);
+ CHECK_EQUAL(0, joint->limotR.limit);
+ CHECK_EQUAL(5, info.m);
+ }
+
+////////////////////////////////////////////////////////////////////////////////
+// Test when there is limits for the prismatic at -10 and 10
+// and for the rotoide at -45deg and 45deg.
+// The Body 2 is rotated by 90deg around the axis
+//
+//
+////////////////////////////////////////////////////////////////////////////////
+ TEST_FIXTURE(PistonGetInfo1_Fixture_2, test2_PistonGetInfo1)
+ {
+ dJointSetPistonParam(jId, dParamLoStop1, -10);
+ dJointSetPistonParam(jId, dParamHiStop1, 10);
+ dJointSetPistonParam(jId, dParamLoStop2, -M_PI/4.0);
+ dJointSetPistonParam(jId, dParamHiStop2, M_PI/4.0);
+
+ dMatrix3 R;
+ dRFromAxisAndAngle (R, 1, 0, 0, M_PI/2.0);
+ dBodySetRotation (bId2, R);
+
+ joint->getInfo1(&info);
+
+ CHECK_EQUAL(0, joint->limotP.limit);
+ CHECK_EQUAL(1, joint->limotR.limit);
+ CHECK_EQUAL(6, info.m);
+
+ // Reset Position and test
+ dMatrix3 R_final = { 1,0,0,0,
+ 0,1,0,0,
+ 0,0,1,0
+ };
+ dBodySetRotation (bId2, R_final);
+
+ joint->getInfo1(&info);
+
+ CHECK_EQUAL(0, joint->limotP.limit);
+ CHECK_EQUAL(0, joint->limotR.limit);
+ CHECK_EQUAL(5, info.m);
+ }
+
+////////////////////////////////////////////////////////////////////////////////
+// Test when there is limits for the prismatic at -10 and 10
+// and for the rotoide axuis at -45deg and 45deg.
+// The Body 2 is rotated by 90deg around the axis and
+// Body1 is moved at X=100
+//
+//
+////////////////////////////////////////////////////////////////////////////////
+ TEST_FIXTURE(PistonGetInfo1_Fixture_2, test3_PistonGetInfo1)
+ {
+ dJointSetPistonParam(jId, dParamLoStop1, -10);
+ dJointSetPistonParam(jId, dParamHiStop1, 10);
+ dJointSetPistonParam(jId, dParamLoStop2, -M_PI/4.0);
+ dJointSetPistonParam(jId, dParamHiStop2, M_PI/4.0);
+
+
+
+ dBodySetPosition (bId1, REAL(100.0), REAL(0.0), REAL(0.0));
+
+ dMatrix3 R;
+ dRFromAxisAndAngle (R, 1, 0, 0, M_PI/2.0);
+ dBodySetRotation (bId2, R);
+
+ joint->getInfo1(&info);
+
+ CHECK_EQUAL(2, joint->limotP.limit);
+ CHECK_EQUAL(1, joint->limotR.limit);
+ CHECK_EQUAL(6, info.m);
+
+ // Reset Position and test
+ dBodySetPosition(bId1, 1, 0, 0);
+
+ dBodySetPosition(bId2, 3, 0, 0);
+ dMatrix3 R_final = { 1,0,0,0,
+ 0,1,0,0,
+ 0,0,1,0
+ };
+ dBodySetRotation (bId2, R_final);
+
+ joint->getInfo1(&info);
+
+ CHECK_EQUAL(0, joint->limotP.limit);
+ CHECK_EQUAL(0, joint->limotR.limit);
+ CHECK_EQUAL(5, info.m);
+ }
+
+
+
+ TEST_FIXTURE(PistonGetInfo1_Fixture_2, test_SetPistonParam)
+ {
+ dJointSetPistonParam(jId, dParamHiStop, REAL(5.0) );
+ CHECK_EQUAL(REAL(5.0), joint->limotP.histop);
+
+ dJointSetPistonParam(jId, dParamVel, REAL(7.0) );
+ CHECK_EQUAL(REAL(7.0), joint->limotP.vel);
+
+#ifdef dParamFudgeFactor1
+ dJointSetPistonParam(jId, dParamFudgeFactor1, REAL(5.5) );
+ CHECK_EQUAL(REAL(5.5), joint->limotP.dParamFudgeFactor);
+#endif
+
+ dJointSetPistonParam(jId, dParamCFM2, REAL(9.0) );
+ CHECK_EQUAL(REAL(9.0), joint->limotR.normal_cfm);
+
+ dJointSetPistonParam(jId, dParamStopERP2, REAL(11.0) );
+ CHECK_EQUAL(REAL(11.0), joint->limotR.stop_erp);
+ }
+
+
+
+ TEST_FIXTURE(PistonGetInfo1_Fixture_1, test_GetPistonParam)
+ {
+ joint->limotP.histop = REAL(5.0);
+ CHECK_EQUAL(joint->limotP.histop,
+ dJointGetPistonParam(jId, dParamHiStop) );
+
+ joint->limotP.vel = REAL(7.0);
+
+ CHECK_EQUAL(joint->limotP.vel,
+ dJointGetPistonParam(jId, dParamVel) );
+
+#ifdef dParamFudgeFactor1
+ joint->limotP.dParamFudgeFactor = REAL(5.5);
+
+ CHECK_EQUAL(joint->limotP.dParamFudgeFactor,
+ dJointGetPistonParam(jId, dParamFudgeFactor1) );
+#endif
+
+ joint->limotR.normal_cfm = REAL(9.0);
+ CHECK_EQUAL(joint->limotR.normal_cfm,
+ dJointGetPistonParam(jId, dParamCFM2) );
+
+ joint->limotR.stop_erp = REAL(11.0);
+ CHECK_EQUAL(joint->limotR.stop_erp,
+ dJointGetPistonParam(jId, dParamStopERP2) );
+ }
+
+
+
+////////////////////////////////////////////////////////////////////////////////
+// Texture for testing the PositionRate
+//
+// Default Position:
+// Position Body1 (3, 0, 0)
+// Position Body2 (1, 0, 0)
+// Angchor (2, 0, 0)
+// Axis1 (0, 1, 0)
+// Axis2 (0, 0, 1)
+// AxisP1 (1, 0, 0)
+//
+// Default velocity:
+// Body 1 lvel=( 0, 0, 0) avel=( 0, 0, 0)
+// Body 2 lvel=( 0, 0, 0) avel=( 0, 0, 0)
+//
+//
+// Y ^ Axis2
+// ^ |
+// / | ^ Axis1
+// Z^ / | /
+// | / Body 2 | / Body 1
+// | / +---------+ | / +-----------+
+// | / / /| | / / /|
+// | / / / + _/ - / / +
+// | / / /-/--------(_)----|--- /-----------/-------> AxisP
+// | / +---------+ / - +-----------+ /
+// | / | |/ | |/
+// | / +---------+ +-----------+
+// |/
+// .-----------------------------------------> X
+// |----------------->
+// Anchor2 <--------------|
+// Anchor1
+//
+////////////////////////////////////////////////////////////////////////////////
+ struct PistonGetInfo1_Fixture_3
+ {
+ PistonGetInfo1_Fixture_3()
+ {
+ wId = dWorldCreate();
+
+ bId1 = dBodyCreate(wId);
+ dBodySetPosition(bId1, 3, 0, 0);
+
+ bId2 = dBodyCreate(wId);
+ dBodySetPosition(bId2, 1, 0, 0);
+
+
+ jId = dJointCreatePiston(wId, 0);
+ joint = (dxJointPiston*)jId;
+
+ dJointAttach(jId, bId1, bId2);
+ dJointSetPistonAnchor (jId, 2, 0, 0);
+
+ dBodySetLinearVel (bId1, REAL(0.0), REAL(0.0), REAL(0.0));
+ dBodySetAngularVel(bId1, REAL(0.0), REAL(0.0), REAL(0.0));
+
+ dBodySetLinearVel (bId2, REAL(0.0), REAL(0.0), REAL(0.0));
+ dBodySetAngularVel(bId1, REAL(0.0), REAL(0.0), REAL(0.0));
+
+ }
+
+ ~PistonGetInfo1_Fixture_3()
+ {
+ dWorldDestroy(wId);
+ }
+
+ dJointID jId;
+ dxJointPiston* joint;
+
+ dWorldID wId;
+
+ dBodyID bId1;
+ dBodyID bId2;
+
+ dxJoint::Info1 info;
+ };
+
+////////////////////////////////////////////////////////////////////////////////
+// Position Body1 [3, 0, 0]
+// Position Body2 [1, 0, 0]
+// Axis of the prismatic [1, 0, 0]
+// Axis1 [0, 1, 0]
+// Axis2 [0, 0, 1]
+//
+// Move at the same speed
+////////////////////////////////////////////////////////////////////////////////
+ TEST_FIXTURE(PistonGetInfo1_Fixture_3, test1_GetPistonPositionRate)
+ {
+ // They move with the same linear speed
+ // Angular speed == 0
+ dBodySetLinearVel(bId1, 0, REAL(3.33), 0);
+ dBodySetLinearVel(bId2, 0, REAL(3.33), 0);
+ CHECK_EQUAL(REAL(0.0), dJointGetPistonPositionRate (jId) );
+
+ dBodySetLinearVel(bId1, REAL(1.11), REAL(3.33), 0);
+ dBodySetLinearVel(bId2, REAL(1.11), REAL(3.33), 0);
+ CHECK_EQUAL(REAL(0.0), dJointGetPistonPositionRate (jId) );
+
+ dBodySetLinearVel(bId1, REAL(1.11), REAL(3.33), REAL(2.22));
+ dBodySetLinearVel(bId2, REAL(1.11), REAL(3.33), REAL(2.22));
+ CHECK_EQUAL(REAL(0.0), dJointGetPistonPositionRate (jId) );
+
+
+ // Reset for the next set of test.
+ dBodySetLinearVel(bId1, REAL(0.0), REAL(0.0), REAL(0.0));
+ dBodySetAngularVel(bId1, REAL(0.0), REAL(0.0), REAL(0.0));
+
+ dBodySetLinearVel(bId2, REAL(0.0), REAL(0.0), REAL(0.0));
+ dBodySetAngularVel(bId1, REAL(0.0), REAL(0.0), REAL(0.0));
+
+
+ // They move with the same angular speed
+ // linear speed == 0
+
+ dBodySetAngularVel(bId1, REAL(1.22), 0.0, 0.0);
+ dBodySetAngularVel(bId2, REAL(1.22), 0.0, 0.0);
+ CHECK_EQUAL(REAL(0.0), dJointGetPistonPositionRate (jId) );
+
+ dBodySetAngularVel(bId1, REAL(1.22), REAL(2.33), 0.0);
+ dBodySetAngularVel(bId2, REAL(1.22), REAL(2.33), 0.0);
+ CHECK_EQUAL(REAL(0.0), dJointGetPistonPositionRate (jId) );
+
+ dBodySetAngularVel(bId1, REAL(1.22), REAL(2.33), REAL(3.44));
+ dBodySetAngularVel(bId2, REAL(1.22), REAL(2.33), REAL(3.44));
+ CHECK_EQUAL(REAL(0.0), dJointGetPistonPositionRate (jId) );
+ }
+
+
+////////////////////////////////////////////////////////////////////////////////
+// Position Body1 [3, 0, 0]
+// Position Body2 [1, 0, 0]
+// Axis of the prismatic [1, 0, 0]
+// Axis1 [0, 1, 0]
+// Axis2 [0, 0, 1]
+//
+// Only the first body moves
+////////////////////////////////////////////////////////////////////////////////
+ TEST_FIXTURE(PistonGetInfo1_Fixture_3, GetPistonPositionRate_Bodies_in_line_B1_moves)
+ {
+ dBodySetLinearVel(bId1, REAL(3.33), 0.0, 0.0); // This is impossible but ...
+ CHECK_EQUAL(REAL(3.33), dJointGetPistonPositionRate (jId) );
+
+ dBodySetLinearVel(bId1, 0, REAL(3.33), 0);
+ CHECK_EQUAL(REAL(0.0), dJointGetPistonPositionRate (jId) );
+
+ dBodySetLinearVel(bId1, 0, 0, REAL(3.33)); // This is impossible but ...
+ CHECK_EQUAL(REAL(0.0), dJointGetPistonPositionRate (jId) );
+
+
+ // Only the first body as angular velocity
+ dBodySetAngularVel(bId1, REAL(1.22), 0.0, 0.0);
+ CHECK_EQUAL(REAL(0.0), dJointGetPistonPositionRate (jId) );
+
+ dBodySetAngularVel(bId1, 0.0, REAL(2.33), 0.0);
+ CHECK_EQUAL(REAL(0.0), dJointGetPistonPositionRate (jId) );
+
+ dBodySetAngularVel(bId1, 0.0, 0.0, REAL(5.55));
+ CHECK_EQUAL(REAL(0.0), dJointGetPistonPositionRate (jId) );
+ }
+
+////////////////////////////////////////////////////////////////////////////////
+// Position Body1 [3, 0, 0]
+// Position Body2 [1, 0, 0]
+// Axis of the prismatic [1, 0, 0]
+// Axis1 [0, 1, 0]
+// Axis2 [0, 0, 1]
+//
+// Only the second body moves
+////////////////////////////////////////////////////////////////////////////////
+ TEST_FIXTURE(PistonGetInfo1_Fixture_3, GetPistonPositionRate_Bodies_in_line_B2_moves)
+ {
+ // The length was at zero and this will give an negative length
+ dBodySetLinearVel(bId2, REAL(3.33), 0.0, 0.0);
+ CHECK_EQUAL(REAL(-3.33), dJointGetPistonPositionRate (jId) );
+
+ dBodySetLinearVel(bId2, 0, REAL(3.33), 0); // This is impossible but ...
+ CHECK_EQUAL(REAL(0.0), dJointGetPistonPositionRate (jId) );
+
+ dBodySetLinearVel(bId2, 0, 0, REAL(3.33)); // This is impossible but ...
+ CHECK_EQUAL(REAL(0.0), dJointGetPistonPositionRate (jId) );
+
+
+ // Only angular velocity
+ dBodySetAngularVel(bId2, REAL(1.22), 0.0, 0.0);
+ CHECK_EQUAL(REAL(0.0), dJointGetPistonPositionRate (jId) );
+
+ dBodySetAngularVel(bId2, 0.0, REAL(2.33), 0.0);
+ CHECK_EQUAL(REAL(0.0), dJointGetPistonPositionRate (jId) );
+
+ dBodySetAngularVel(bId2, 0.0, 0.0, REAL(5.55));
+ CHECK_EQUAL(REAL(0.0), dJointGetPistonPositionRate (jId) );
+ }
+
+
+////////////////////////////////////////////////////////////////////////////////
+// Fixture for testing the PositionRate
+//
+// Default Position:
+// Position Body1 (3, 0, 0)
+// Position Body2 (0, 0, 1)
+// Angchor (2, 0, 0)
+// Axis1 (0, 1, 0)
+// Axis2 (1, 0, 0)
+// AxisP (1, 0, 0)
+//
+// The second body is at 90deg w.r.t. the first body
+// From
+//
+// Y ^ Axis2
+// ^ |
+// / | ^ Axis1
+// Z^ / | /
+// | / Body 2 | / Body 1
+// | / +---------+ | / +-----------+
+// | / / /| | / / /|
+// | / / / + _/ - / / +
+// | / / /-/--------(_)----|--- /-----------/-------> AxisP
+// | / +---------+ / - +-----------+ /
+// | / | |/ | |/
+// | / +---------+ +-----------+
+// |/
+// .-----------------------------------------> X
+// |----------------->
+// Anchor2 <--------------|
+// Anchor1
+// To
+//
+// Y ^ Axis2
+// ^ |
+// / Body 2 | ^ Axis1
+// Z^ +----------+ | /
+// | // /| | / Body 1
+// | /+----------+ | | / +-----------+
+// | / | | | | / / /|
+// | / | | | _/ - / / +
+// | / | |-|------(_)----|--- /-----------/-------> AxisP
+// | / | | | - +-----------+ /
+// | / | | | | |/
+// | / | | + +-----------+
+// |/ | |/
+// .--------+----------+--------------------> X
+// |---------------->
+// Anchor2 <--------------|
+// Anchor1
+// Default Position
+//
+// N.B. Y is going into the page
+////////////////////////////////////////////////////////////////////////////////
+ struct PistonGetInfo1_Fixture_4
+ {
+ PistonGetInfo1_Fixture_4()
+ {
+ wId = dWorldCreate();
+
+ bId1 = dBodyCreate(wId);
+ dBodySetPosition(bId1, 3, 0, 0);
+
+ bId2 = dBodyCreate(wId);
+ dBodySetPosition(bId2, 0, 0, 1);
+
+ dMatrix3 R;
+ dRFromAxisAndAngle (R, 1, 0, 0, -M_PI/2.0);
+ dBodySetRotation (bId2, R);
+
+
+ jId = dJointCreatePiston(wId, 0);
+ joint = (dxJointPiston*)jId;
+
+ dJointAttach(jId, bId1, bId2);
+ dJointSetPistonAnchor (jId, 2, 0, 0);
+
+
+ dBodySetLinearVel(bId1, REAL(0.0), REAL(0.0), REAL(0.0));
+ dBodySetAngularVel(bId1, REAL(0.0), REAL(0.0), REAL(0.0));
+
+ dBodySetLinearVel(bId2, REAL(0.0), REAL(0.0), REAL(0.0));
+ dBodySetAngularVel(bId1, REAL(0.0), REAL(0.0), REAL(0.0));
+
+ }
+
+ ~PistonGetInfo1_Fixture_4()
+ {
+ dWorldDestroy(wId);
+ }
+
+ dJointID jId;
+ dxJointPiston* joint;
+
+ dWorldID wId;
+
+ dBodyID bId1;
+ dBodyID bId2;
+
+ dxJoint::Info1 info;
+ };
+
+
+////////////////////////////////////////////////////////////////////////////////
+// Position Body1 (3, 0, 0)
+// Position Body2 (1, 0, 0)
+// Angchor (2, 0, 0)
+// Axis1 (0, 1, 0)
+// Axis2 (0, 0, 1)
+// AxisP1 (1, 0, 0)
+//
+// Only the first body moves
+////////////////////////////////////////////////////////////////////////////////
+ TEST_FIXTURE(PistonGetInfo1_Fixture_4, GetPistonPositionRate_Bodies_at90deg_B1_moves)
+ {
+ dBodySetLinearVel(bId1, REAL(3.33), 0.0, 0.0); // This is impossible but ...
+ CHECK_EQUAL(REAL(3.33), dJointGetPistonPositionRate (jId) );
+
+ dBodySetLinearVel(bId1, 0, REAL(3.33), 0);
+ CHECK_EQUAL(REAL(0.0), dJointGetPistonPositionRate (jId) );
+
+ dBodySetLinearVel(bId1, 0, 0, REAL(3.33)); // This is impossible but ...
+ CHECK_EQUAL(REAL(0.0), dJointGetPistonPositionRate (jId) );
+
+
+ // Only angular velocity
+ dBodySetAngularVel(bId1, REAL(1.22), 0.0, 0.0);
+ CHECK_EQUAL(REAL(0.0), dJointGetPistonPositionRate (jId) );
+
+ dBodySetAngularVel(bId1, 0.0, REAL(2.33), 0.0);
+ CHECK_EQUAL(REAL(0.0), dJointGetPistonPositionRate (jId) );
+
+ dBodySetAngularVel(bId1, 0.0, 0.0, REAL(5.55));
+ CHECK_EQUAL(REAL(0.0), dJointGetPistonPositionRate (jId) );
+ }
+
+////////////////////////////////////////////////////////////////////////////////
+// Position Body1 (3, 0, 0)
+// Position Body2 (1, 0, 0)
+// Angchor (2, 0, 0)
+// Axis1 (0, 1, 0)
+// Axis2 (0, 0, 1)
+// AxisP1 (1, 0, 0)
+//
+// Only the second body moves
+////////////////////////////////////////////////////////////////////////////////
+ TEST_FIXTURE(PistonGetInfo1_Fixture_4, GetPistonPositionRate_Bodies_at90deg_B2_moves)
+ {
+ // The length was at zero and this will give an negative length
+ dBodySetLinearVel(bId2, REAL(3.33), 0.0, 0.0);
+ CHECK_EQUAL(REAL(-3.33), dJointGetPistonPositionRate (jId) );
+
+ dBodySetLinearVel(bId2, 0, REAL(3.33), 0); // This is impossible but ...
+ CHECK_EQUAL(REAL(0.0), dJointGetPistonPositionRate (jId) );
+
+ dBodySetLinearVel(bId2, 0, 0, REAL(3.33)); // This is impossible but ...
+ CHECK_EQUAL(REAL(0.0), dJointGetPistonPositionRate (jId) );
+
+
+ // Only angular velocity
+ dBodySetAngularVel(bId2, REAL(1.22), 0.0, 0.0);
+ CHECK_EQUAL(REAL(0.0), dJointGetPistonPositionRate (jId) );
+
+ dBodySetAngularVel(bId2, 0.0, REAL(2.33), 0.0);
+ CHECK_EQUAL(REAL(0.0), dJointGetPistonPositionRate (jId) );
+
+ dBodySetAngularVel(bId2, 0.0, 0.0, REAL(5.55));
+ CHECK_EQUAL(REAL(0.0), dJointGetPistonPositionRate (jId) );
+ }
+
+
+
+ struct Fixture_Simple_Hinge
+ {
+ Fixture_Simple_Hinge ()
+ {
+ wId = dWorldCreate();
+
+ bId1 = dBodyCreate(wId);
+ dBodySetPosition(bId1, 0, -1, 0);
+
+ bId2 = dBodyCreate(wId);
+ dBodySetPosition(bId2, 0, 1, 0);
+
+
+ jId = dJointCreateHinge(wId, 0);
+
+ dJointAttach(jId, bId1, bId2);
+ }
+
+ ~Fixture_Simple_Hinge()
+ {
+ dWorldDestroy(wId);
+ }
+
+ dJointID jId;
+
+ dWorldID wId;
+
+ dBodyID bId1;
+ dBodyID bId2;
+ };
+
+ // Test that it is possible to have joint without a body
+ TEST_FIXTURE(Fixture_Simple_Hinge, test_dJointAttach)
+ {
+ bool only_body1_OK = true;
+ try {
+ dJointAttach(jId, bId1, 0);
+ dWorldStep (wId, 1);
+ }
+ catch (...) {
+ only_body1_OK = false;
+ }
+ CHECK_EQUAL(true, only_body1_OK);
+
+ bool only_body2_OK = true;
+ try {
+ dJointAttach(jId, 0, bId2);
+ dWorldStep (wId, 1);
+ }
+ catch (...) {
+ only_body2_OK = false;
+ }
+ CHECK_EQUAL(true, only_body2_OK);
+
+ bool no_body_OK = true;
+ try {
+ dJointAttach(jId, 0, 0);
+ dWorldStep (wId, 1);
+ }
+ catch (...) {
+ no_body_OK = false;
+ }
+ CHECK_EQUAL(true, no_body_OK);
+ }
+
+
+
+} // End of SUITE(JointPiston)
diff --git a/libs/ode-0.16.1/tests/joints/Makefile.am b/libs/ode-0.16.1/tests/joints/Makefile.am
new file mode 100644
index 0000000..5b8f743
--- /dev/null
+++ b/libs/ode-0.16.1/tests/joints/Makefile.am
@@ -0,0 +1,21 @@
+AM_CPPFLAGS = -I$(srcdir)/../UnitTest++/src \
+ -I$(top_srcdir)/include \
+ -I$(top_builddir)/include \
+ -I$(top_srcdir)/ode/src
+
+check_LTLIBRARIES = libjoints.la
+
+libjoints_la_LDFLAGS = -static
+
+libjoints_la_SOURCES = \
+ amotor.cpp \
+ ball.cpp \
+ dball.cpp \
+ fixed.cpp \
+ hinge.cpp \
+ hinge2.cpp \
+ piston.cpp \
+ pr.cpp \
+ pu.cpp \
+ slider.cpp \
+ universal.cpp
diff --git a/libs/ode-0.16.1/tests/joints/Makefile.in b/libs/ode-0.16.1/tests/joints/Makefile.in
new file mode 100644
index 0000000..edbb187
--- /dev/null
+++ b/libs/ode-0.16.1/tests/joints/Makefile.in
@@ -0,0 +1,638 @@
+# 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 = tests/joints
+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 =
+libjoints_la_LIBADD =
+am_libjoints_la_OBJECTS = amotor.lo ball.lo dball.lo fixed.lo hinge.lo \
+ hinge2.lo piston.lo pr.lo pu.lo slider.lo universal.lo
+libjoints_la_OBJECTS = $(am_libjoints_la_OBJECTS)
+AM_V_lt = $(am__v_lt_@AM_V@)
+am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+am__v_lt_1 =
+libjoints_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
+ $(CXXFLAGS) $(libjoints_la_LDFLAGS) $(LDFLAGS) -o $@
+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 =
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/ode/src
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CXXFLAGS) $(CXXFLAGS)
+AM_V_CXX = $(am__v_CXX_@AM_V@)
+am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@)
+am__v_CXX_0 = @echo " CXX " $@;
+am__v_CXX_1 =
+CXXLD = $(CXX)
+CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
+ $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CXXLD = $(am__v_CXXLD_@AM_V@)
+am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@)
+am__v_CXXLD_0 = @echo " CXXLD " $@;
+am__v_CXXLD_1 =
+SOURCES = $(libjoints_la_SOURCES)
+DIST_SOURCES = $(libjoints_la_SOURCES)
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+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 $(top_srcdir)/depcomp
+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@
+AM_CPPFLAGS = -I$(srcdir)/../UnitTest++/src \
+ -I$(top_srcdir)/include \
+ -I$(top_builddir)/include \
+ -I$(top_srcdir)/ode/src
+
+check_LTLIBRARIES = libjoints.la
+libjoints_la_LDFLAGS = -static
+libjoints_la_SOURCES = \
+ amotor.cpp \
+ ball.cpp \
+ dball.cpp \
+ fixed.cpp \
+ hinge.cpp \
+ hinge2.cpp \
+ piston.cpp \
+ pr.cpp \
+ pu.cpp \
+ slider.cpp \
+ universal.cpp
+
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .cpp .lo .o .obj
+$(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 tests/joints/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --foreign tests/joints/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):
+
+clean-checkLTLIBRARIES:
+ -test -z "$(check_LTLIBRARIES)" || rm -f $(check_LTLIBRARIES)
+ @list='$(check_LTLIBRARIES)'; \
+ locs=`for p in $$list; do echo $$p; done | \
+ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+ sort -u`; \
+ test -z "$$locs" || { \
+ echo rm -f $${locs}; \
+ rm -f $${locs}; \
+ }
+
+libjoints.la: $(libjoints_la_OBJECTS) $(libjoints_la_DEPENDENCIES) $(EXTRA_libjoints_la_DEPENDENCIES)
+ $(AM_V_CXXLD)$(libjoints_la_LINK) $(libjoints_la_OBJECTS) $(libjoints_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/amotor.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ball.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dball.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fixed.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hinge.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hinge2.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/piston.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pr.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pu.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/slider.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/universal.Plo@am__quote@
+
+.cpp.o:
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $<
+
+.cpp.obj:
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.cpp.lo:
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LTCXXCOMPILE) -c -o $@ $<
+
+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
+ $(MAKE) $(AM_MAKEFLAGS) $(check_LTLIBRARIES)
+check: check-am
+all-am: Makefile
+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-checkLTLIBRARIES clean-generic clean-libtool \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile 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 -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: check-am install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean \
+ clean-checkLTLIBRARIES clean-generic clean-libtool \
+ cscopelist-am ctags ctags-am distclean distclean-compile \
+ 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-compile \
+ 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/tests/joints/amotor.cpp b/libs/ode-0.16.1/tests/joints/amotor.cpp
new file mode 100644
index 0000000..0dc1c2d
--- /dev/null
+++ b/libs/ode-0.16.1/tests/joints/amotor.cpp
@@ -0,0 +1,324 @@
+/*************************************************************************
+ * *
+ * 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. *
+ * *
+ *************************************************************************/
+//234567890123456789012345678901234567890123456789012345678901234567890123456789
+// 1 2 3 4 5 6 7
+
+////////////////////////////////////////////////////////////////////////////////
+// This file create unit test for some of the functions found in:
+// ode/src/joinst/fixed.cpp
+//
+//
+////////////////////////////////////////////////////////////////////////////////
+
+#include <UnitTest++.h>
+#include <ode/ode.h>
+
+#include "config.h"
+#include "../../ode/src/joints/amotor.h"
+
+const dReal tol = 1e-5;
+
+SUITE (TestdxJointAMotor)
+{
+ struct FixtureBase {
+ dWorldID world;
+ dBodyID body;
+ dJointID joint;
+
+ FixtureBase()
+ {
+ world = dWorldCreate();
+ body = dBodyCreate(world);
+ joint = dJointCreateAMotor(world, 0);
+ }
+
+ ~FixtureBase()
+ {
+ dJointDestroy(joint);
+ dBodyDestroy(body);
+ dWorldDestroy(world);
+ }
+ };
+
+
+ struct FixtureXUser: FixtureBase {
+ FixtureXUser()
+ {
+ // body only allowed to rotate around X axis
+ dBodySetFiniteRotationMode(body, 1);
+ dBodySetFiniteRotationAxis(body, 1, 0, 0);
+ dJointAttach(joint, body, 0);
+ dJointSetAMotorNumAxes(joint, 2);
+ dJointSetAMotorAxis(joint, 0, 2, 0, 1, 0);
+ dJointSetAMotorAxis(joint, 1, 2, 0, 0, 1);
+ dJointSetAMotorParam(joint, dParamVel, 0);
+ dJointSetAMotorParam(joint, dParamFMax, dInfinity);
+ dJointSetAMotorParam(joint, dParamVel2, 0);
+ dJointSetAMotorParam(joint, dParamFMax2, dInfinity);
+ }
+ };
+
+ TEST_FIXTURE(FixtureXUser, rotate_x)
+ {
+ const dReal h = 1;
+ const dReal v = 1;
+ dMatrix3 identity = {1, 0, 0, 0,
+ 0, 1, 0, 0,
+ 0, 0, 1, 0};
+ dBodySetRotation(body, identity);
+ dBodySetAngularVel(body, v, 0, 0);
+ dWorldQuickStep(world, h);
+ const dReal* rot = dBodyGetRotation(body);
+ CHECK_CLOSE(1, rot[0], tol);
+ CHECK_CLOSE(0, rot[4], tol);
+ CHECK_CLOSE(0, rot[8], tol);
+
+ CHECK_CLOSE(0, rot[1], tol);
+ CHECK_CLOSE(dCos(v*h), rot[5], tol);
+ CHECK_CLOSE(dSin(v*h), rot[9], tol);
+
+ CHECK_CLOSE(0, rot[2], tol);
+ CHECK_CLOSE(-dSin(v*h), rot[6], tol);
+ CHECK_CLOSE( dCos(v*h), rot[10], tol);
+ }
+
+ TEST_FIXTURE(FixtureXUser, rotate_yz)
+ {
+ const dReal h = 1;
+ const dReal v = 1;
+ dMatrix3 identity = {1, 0, 0, 0,
+ 0, 1, 0, 0,
+ 0, 0, 1, 0};
+ dBodySetRotation(body, identity);
+
+ dVector3 axis_y;
+ dJointGetAMotorAxis(joint, 0, axis_y);
+ CHECK_CLOSE(0, axis_y[0], tol);
+ CHECK_CLOSE(1, axis_y[1], tol);
+ CHECK_CLOSE(0, axis_y[2], tol);
+
+ dVector3 axis_z;
+ dJointGetAMotorAxis(joint, 1, axis_z);
+ CHECK_CLOSE(0, axis_z[0], tol);
+ CHECK_CLOSE(0, axis_z[1], tol);
+ CHECK_CLOSE(1, axis_z[2], tol);
+
+ dBodySetAngularVel(body, 0, v, v);
+ dWorldStep(world, h);
+ const dReal* rot = dBodyGetRotation(body);
+ CHECK_CLOSE(1, rot[0], tol);
+ CHECK_CLOSE(0, rot[4], tol);
+ CHECK_CLOSE(0, rot[8], tol);
+
+ CHECK_CLOSE(0, rot[1], tol);
+ CHECK_CLOSE(1, rot[5], tol);
+ CHECK_CLOSE(0, rot[9], tol);
+
+ CHECK_CLOSE(0, rot[2], tol);
+ CHECK_CLOSE(0, rot[6], tol);
+ CHECK_CLOSE(1, rot[10], tol);
+ }
+
+
+ TEST_FIXTURE(FixtureBase, sanity_check)
+ {
+ dMatrix3 R;
+ dRFromAxisAndAngle(R, 1, 1, 1, 10*M_PI/180);
+ dBodySetRotation(body, R);
+
+ dVector3 res;
+
+ dJointAttach(joint, body, 0);
+ dJointSetAMotorNumAxes(joint, 3);
+ CHECK_EQUAL(3, dJointGetAMotorNumAxes(joint));
+
+ // axes relative to world
+ dJointSetAMotorAxis(joint, 0, 0, 1, 0, 0);
+ dJointGetAMotorAxis(joint, 0, res);
+ CHECK_EQUAL(0, dJointGetAMotorAxisRel(joint, 0));
+ CHECK_CLOSE(1, res[0], tol);
+ CHECK_CLOSE(0, res[1], tol);
+ CHECK_CLOSE(0, res[2], tol);
+
+ dJointSetAMotorAxis(joint, 1, 0, 0, 1, 0);
+ dJointGetAMotorAxis(joint, 1, res);
+ CHECK_EQUAL(0, dJointGetAMotorAxisRel(joint, 1));
+ CHECK_CLOSE(0, res[0], tol);
+ CHECK_CLOSE(1, res[1], tol);
+ CHECK_CLOSE(0, res[2], tol);
+
+ dJointSetAMotorAxis(joint, 2, 0, 0, 0, 1);
+ dJointGetAMotorAxis(joint, 2, res);
+ CHECK_EQUAL(0, dJointGetAMotorAxisRel(joint, 2));
+ CHECK_CLOSE(0, res[0], tol);
+ CHECK_CLOSE(0, res[1], tol);
+ CHECK_CLOSE(1, res[2], tol);
+
+ // axes relative to body1
+ dJointSetAMotorAxis(joint, 0, 1, 1, 0, 0);
+ dJointGetAMotorAxis(joint, 0, res);
+ CHECK_EQUAL(1, dJointGetAMotorAxisRel(joint, 0));
+ CHECK_CLOSE(1, res[0], tol);
+ CHECK_CLOSE(0, res[1], tol);
+ CHECK_CLOSE(0, res[2], tol);
+
+ dJointSetAMotorAxis(joint, 1, 1, 0, 1, 0);
+ dJointGetAMotorAxis(joint, 1, res);
+ CHECK_EQUAL(1, dJointGetAMotorAxisRel(joint, 1));
+ CHECK_CLOSE(0, res[0], tol);
+ CHECK_CLOSE(1, res[1], tol);
+ CHECK_CLOSE(0, res[2], tol);
+
+ dJointSetAMotorAxis(joint, 2, 1, 0, 0, 1);
+ dJointGetAMotorAxis(joint, 2, res);
+ CHECK_EQUAL(1, dJointGetAMotorAxisRel(joint, 2));
+ CHECK_CLOSE(0, res[0], tol);
+ CHECK_CLOSE(0, res[1], tol);
+ CHECK_CLOSE(1, res[2], tol);
+
+ // axes relative to body2
+ dJointSetAMotorAxis(joint, 0, 2, 1, 0, 0);
+ dJointGetAMotorAxis(joint, 0, res);
+ CHECK_EQUAL(2, dJointGetAMotorAxisRel(joint, 0));
+ CHECK_CLOSE(1, res[0], tol);
+ CHECK_CLOSE(0, res[1], tol);
+ CHECK_CLOSE(0, res[2], tol);
+
+ dJointSetAMotorAxis(joint, 1, 2, 0, 1, 0);
+ dJointGetAMotorAxis(joint, 1, res);
+ CHECK_EQUAL(2, dJointGetAMotorAxisRel(joint, 1));
+ CHECK_CLOSE(0, res[0], tol);
+ CHECK_CLOSE(1, res[1], tol);
+ CHECK_CLOSE(0, res[2], tol);
+
+ dJointSetAMotorAxis(joint, 2, 2, 0, 0, 1);
+ dJointGetAMotorAxis(joint, 2, res);
+ CHECK_EQUAL(2, dJointGetAMotorAxisRel(joint, 2));
+ CHECK_CLOSE(0, res[0], tol);
+ CHECK_CLOSE(0, res[1], tol);
+ CHECK_CLOSE(1, res[2], tol);
+
+ // reverse attachment to force internal reversal
+ dJointAttach(joint, 0, body);
+ // axes relative to world
+ dJointSetAMotorAxis(joint, 0, 0, 1, 0, 0);
+ dJointGetAMotorAxis(joint, 0, res);
+ CHECK_EQUAL(0, dJointGetAMotorAxisRel(joint, 0));
+ CHECK_CLOSE(1, res[0], tol);
+ CHECK_CLOSE(0, res[1], tol);
+ CHECK_CLOSE(0, res[2], tol);
+
+ dJointSetAMotorAxis(joint, 1, 0, 0, 1, 0);
+ dJointGetAMotorAxis(joint, 1, res);
+ CHECK_EQUAL(0, dJointGetAMotorAxisRel(joint, 1));
+ CHECK_CLOSE(0, res[0], tol);
+ CHECK_CLOSE(1, res[1], tol);
+ CHECK_CLOSE(0, res[2], tol);
+
+ dJointSetAMotorAxis(joint, 2, 0, 0, 0, 1);
+ dJointGetAMotorAxis(joint, 2, res);
+ CHECK_EQUAL(0, dJointGetAMotorAxisRel(joint, 2));
+ CHECK_CLOSE(0, res[0], tol);
+ CHECK_CLOSE(0, res[1], tol);
+ CHECK_CLOSE(1, res[2], tol);
+
+ // axes relative to body1
+ dJointSetAMotorAxis(joint, 0, 1, 1, 0, 0);
+ dJointGetAMotorAxis(joint, 0, res);
+ CHECK_EQUAL(1, dJointGetAMotorAxisRel(joint, 0));
+ CHECK_CLOSE(1, res[0], tol);
+ CHECK_CLOSE(0, res[1], tol);
+ CHECK_CLOSE(0, res[2], tol);
+
+ dJointSetAMotorAxis(joint, 1, 1, 0, 1, 0);
+ dJointGetAMotorAxis(joint, 1, res);
+ CHECK_EQUAL(1, dJointGetAMotorAxisRel(joint, 1));
+ CHECK_CLOSE(0, res[0], tol);
+ CHECK_CLOSE(1, res[1], tol);
+ CHECK_CLOSE(0, res[2], tol);
+
+ dJointSetAMotorAxis(joint, 2, 1, 0, 0, 1);
+ dJointGetAMotorAxis(joint, 2, res);
+ CHECK_EQUAL(1, dJointGetAMotorAxisRel(joint, 2));
+ CHECK_CLOSE(0, res[0], tol);
+ CHECK_CLOSE(0, res[1], tol);
+ CHECK_CLOSE(1, res[2], tol);
+
+ // axes relative to body2
+ dJointSetAMotorAxis(joint, 0, 2, 1, 0, 0);
+ dJointGetAMotorAxis(joint, 0, res);
+ CHECK_EQUAL(2, dJointGetAMotorAxisRel(joint, 0));
+ CHECK_CLOSE(1, res[0], tol);
+ CHECK_CLOSE(0, res[1], tol);
+ CHECK_CLOSE(0, res[2], tol);
+
+ dJointSetAMotorAxis(joint, 1, 2, 0, 1, 0);
+ dJointGetAMotorAxis(joint, 1, res);
+ CHECK_EQUAL(2, dJointGetAMotorAxisRel(joint, 1));
+ CHECK_CLOSE(0, res[0], tol);
+ CHECK_CLOSE(1, res[1], tol);
+ CHECK_CLOSE(0, res[2], tol);
+
+ dJointSetAMotorAxis(joint, 2, 2, 0, 0, 1);
+ dJointGetAMotorAxis(joint, 2, res);
+ CHECK_EQUAL(2, dJointGetAMotorAxisRel(joint, 2));
+ CHECK_CLOSE(0, res[0], tol);
+ CHECK_CLOSE(0, res[1], tol);
+ CHECK_CLOSE(1, res[2], tol);
+ }
+
+
+ struct FixtureXEuler : FixtureBase {
+ FixtureXEuler()
+ {
+ // body only allowed to rotate around X axis
+ dJointAttach(joint, 0, body);
+ dJointSetAMotorMode(joint, dAMotorEuler);
+ dJointSetAMotorAxis(joint, 0, 0, 1, 0, 0);
+ dJointSetAMotorAxis(joint, 2, 0, 0, 0, 1);
+ }
+ };
+
+
+ TEST_FIXTURE(FixtureXEuler, check_axes)
+ {
+ // test patch #181 bug fix
+ dVector3 axis_x;
+ dJointGetAMotorAxis(joint, 0, axis_x);
+ CHECK_CLOSE(1, axis_x[0], tol);
+ CHECK_CLOSE(0, axis_x[1], tol);
+ CHECK_CLOSE(0, axis_x[2], tol);
+
+ dVector3 axis_y;
+ dJointGetAMotorAxis(joint, 1, axis_y);
+ CHECK_CLOSE(0, axis_y[0], tol);
+ CHECK_CLOSE(1, axis_y[1], tol);
+ CHECK_CLOSE(0, axis_y[2], tol);
+
+ dVector3 axis_z;
+ dJointGetAMotorAxis(joint, 2, axis_z);
+ CHECK_CLOSE(0, axis_z[0], tol);
+ CHECK_CLOSE(0, axis_z[1], tol);
+ CHECK_CLOSE(1, axis_z[2], tol);
+ }
+
+} // End of SUITE TestdxJointAMotor
diff --git a/libs/ode-0.16.1/tests/joints/ball.cpp b/libs/ode-0.16.1/tests/joints/ball.cpp
new file mode 100644
index 0000000..edbb243
--- /dev/null
+++ b/libs/ode-0.16.1/tests/joints/ball.cpp
@@ -0,0 +1,160 @@
+/*************************************************************************
+ * *
+ * 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. *
+ * *
+ *************************************************************************/
+//234567890123456789012345678901234567890123456789012345678901234567890123456789
+// 1 2 3 4 5 6 7
+
+////////////////////////////////////////////////////////////////////////////////
+// This file create unit test for some of the functions found in:
+// ode/src/joinst/ball.cpp
+//
+//
+////////////////////////////////////////////////////////////////////////////////
+
+#include <UnitTest++.h>
+#include <ode/ode.h>
+
+#include "../../ode/src/config.h"
+#include "../../ode/src/joints/ball.h"
+
+
+using namespace std;
+
+SUITE (TestdxJointBall)
+{
+ // The 2 bodies are positionned at (-1, -2, -3), and (11, 22, 33)
+ // The bodis have rotation of 27deg around some axis.
+ // The joint is a Ball Joint
+ // Axis is along the X axis
+ // Anchor at (0, 0, 0)
+ struct dxJointBall_Fixture_B1_and_B2_At_Zero_Axis_Along_X {
+ dxJointBall_Fixture_B1_and_B2_At_Zero_Axis_Along_X()
+ {
+ wId = dWorldCreate();
+
+ for (int j=0; j<2; ++j) {
+ bId[j][0] = dBodyCreate (wId);
+ dBodySetPosition (bId[j][0], -1, -2, -3);
+
+ bId[j][1] = dBodyCreate (wId);
+ dBodySetPosition (bId[j][1], 11, 22, 33);
+
+
+ dMatrix3 R;
+ dVector3 axis; // Random axis
+
+ axis[0] = REAL(0.53);
+ axis[1] = -REAL(0.71);
+ axis[2] = REAL(0.43);
+ dNormalize3(axis);
+ dRFromAxisAndAngle (R, axis[0], axis[1], axis[2],
+ REAL(0.47123)); // 27deg
+ dBodySetRotation (bId[j][0], R);
+
+
+ axis[0] = REAL(1.2);
+ axis[1] = REAL(0.87);
+ axis[2] = -REAL(0.33);
+ dNormalize3(axis);
+ dRFromAxisAndAngle (R, axis[0], axis[1], axis[2],
+ REAL(0.47123)); // 27deg
+ dBodySetRotation (bId[j][1], R);
+
+ jId[j] = dJointCreateBall (wId, 0);
+ dJointAttach (jId[j], bId[j][0], bId[j][1]);
+ }
+ }
+
+ ~dxJointBall_Fixture_B1_and_B2_At_Zero_Axis_Along_X()
+ {
+ dWorldDestroy (wId);
+ }
+
+ dWorldID wId;
+
+ dBodyID bId[2][2];
+
+
+ dJointID jId[2];
+ };
+
+ // Rotate 2nd body 90deg around X then back to original position
+ //
+ // ^ ^ ^
+ // | | => | <---
+ // | | |
+ // B1 B2 B1 B2
+ //
+ // Start with a Delta of 90deg
+ // ^ ^ ^
+ // | <--- => | |
+ // | | |
+ // B1 B2 B1 B2
+ TEST_FIXTURE (dxJointBall_Fixture_B1_and_B2_At_Zero_Axis_Along_X,
+ test_dJointSetBallAxisOffset_B2_90deg) {
+
+ dVector3 anchor;
+ dJointGetBallAnchor(jId[1], anchor);
+ dJointSetBallAnchor(jId[1], anchor[0], anchor[1], anchor[2]);
+
+
+ for (int b=0; b<2; ++b) {
+ // Compare body b of the first joint with its equivalent on the
+ // second joint
+ const dReal *qA = dBodyGetQuaternion(bId[0][b]);
+ const dReal *qB = dBodyGetQuaternion(bId[1][b]);
+ CHECK_CLOSE (qA[0], qB[0], 1e-4);
+ CHECK_CLOSE (qA[1], qB[1], 1e-4);
+ CHECK_CLOSE (qA[2], qB[2], 1e-4);
+ CHECK_CLOSE (qA[3], qB[3], 1e-4);
+ }
+
+ dWorldStep (wId,0.5);
+ dWorldStep (wId,0.5);
+ dWorldStep (wId,0.5);
+ dWorldStep (wId,0.5);
+
+ for (int b=0; b<2; ++b) {
+ // Compare body b of the first joint with its equivalent on the
+ // second joint
+ const dReal *qA = dBodyGetQuaternion(bId[0][b]);
+ const dReal *qB = dBodyGetQuaternion(bId[1][b]);
+ CHECK_CLOSE (qA[0], qB[0], 1e-4);
+ CHECK_CLOSE (qA[1], qB[1], 1e-4);
+ CHECK_CLOSE (qA[2], qB[2], 1e-4);
+ CHECK_CLOSE (qA[3], qB[3], 1e-4);
+
+
+ const dReal *posA = dBodyGetPosition(bId[0][b]);
+ const dReal *posB = dBodyGetPosition(bId[1][b]);
+ CHECK_CLOSE (posA[0], posB[0], 1e-4);
+ CHECK_CLOSE (posA[1], posB[1], 1e-4);
+ CHECK_CLOSE (posA[2], posB[2], 1e-4);
+ CHECK_CLOSE (posA[3], posB[3], 1e-4);
+ }
+ }
+
+
+
+
+} // End of SUITE TestdxJointBall
+
+
diff --git a/libs/ode-0.16.1/tests/joints/dball.cpp b/libs/ode-0.16.1/tests/joints/dball.cpp
new file mode 100644
index 0000000..0e82c8d
--- /dev/null
+++ b/libs/ode-0.16.1/tests/joints/dball.cpp
@@ -0,0 +1,81 @@
+/*************************************************************************
+ * *
+ * 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. *
+ * *
+ *************************************************************************/
+//234567890123456789012345678901234567890123456789012345678901234567890123456789
+// 1 2 3 4 5 6 7
+
+////////////////////////////////////////////////////////////////////////////////
+// This file create unit test for some of the functions found in:
+// ode/src/joinst/dball.cpp
+//
+//
+////////////////////////////////////////////////////////////////////////////////
+
+#include <UnitTest++.h>
+#include <ode/ode.h>
+
+#include "../../ode/src/config.h"
+
+
+using namespace std;
+
+SUITE (TestdxJointDBall)
+{
+ struct SimpleFixture {
+ dWorldID w;
+ dBodyID b1, b2;
+ dJointID j;
+
+ SimpleFixture() :
+ w(dWorldCreate()),
+ b1(dBodyCreate(w)),
+ b2(dBodyCreate(w)),
+ j(dJointCreateDBall(w, 0))
+ {
+ dJointAttach(j, b1, b2);
+ }
+
+ ~SimpleFixture()
+ {
+ dJointDestroy(j);
+ dBodyDestroy(b1);
+ dBodyDestroy(b2);
+ dWorldDestroy(w);
+ }
+ };
+
+ TEST_FIXTURE(SimpleFixture, testTargetDistance)
+ {
+ dBodySetPosition(b1, -1, -2, -3);
+ dBodySetPosition(b2, 3, 5, 7);
+ dJointAttach(j, b1, b2); // this recomputes the deduced target distance
+ CHECK_CLOSE(dJointGetDBallDistance(j), dSqrt(REAL(165.0)), 1e-4);
+
+ // moving body should not change target distance
+ dBodySetPosition(b1, 2,3,4);
+ CHECK_CLOSE(dJointGetDBallDistance(j), dSqrt(REAL(165.0)), 1e-4);
+
+ // setting target distance manually should override the deduced one
+ dJointSetDBallDistance(j, REAL(6.0));
+ CHECK_EQUAL(dJointGetDBallDistance(j), REAL(6.0));
+ }
+
+}
diff --git a/libs/ode-0.16.1/tests/joints/fixed.cpp b/libs/ode-0.16.1/tests/joints/fixed.cpp
new file mode 100644
index 0000000..c069073
--- /dev/null
+++ b/libs/ode-0.16.1/tests/joints/fixed.cpp
@@ -0,0 +1,149 @@
+/*************************************************************************
+ * *
+ * 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. *
+ * *
+ *************************************************************************/
+//234567890123456789012345678901234567890123456789012345678901234567890123456789
+// 1 2 3 4 5 6 7
+
+////////////////////////////////////////////////////////////////////////////////
+// This file create unit test for some of the functions found in:
+// ode/src/joinst/fixed.cpp
+//
+//
+////////////////////////////////////////////////////////////////////////////////
+
+#include <UnitTest++.h>
+#include <ode/ode.h>
+
+#include "../../ode/src/config.h"
+#include "../../ode/src/joints/fixed.h"
+
+SUITE (TestdxJointFixed)
+{
+ struct dxJointFixed_Fixture_1
+ {
+ dxJointFixed_Fixture_1()
+ {
+ wId = dWorldCreate();
+
+ bId1 = dBodyCreate (wId);
+ dBodySetPosition (bId1, 0, -1, 0);
+
+ bId2 = dBodyCreate (wId);
+ dBodySetPosition (bId2, 0, 1, 0);
+
+ jId = dJointCreateFixed (wId, 0);
+ joint = (dxJointFixed*) jId;
+
+
+ dJointAttach (jId, bId1, bId2);
+ }
+
+ ~dxJointFixed_Fixture_1()
+ {
+ dWorldDestroy (wId);
+ }
+
+ dWorldID wId;
+
+ dBodyID bId1;
+ dBodyID bId2;
+
+
+ dJointID jId;
+ dxJointFixed* joint;
+ };
+
+ TEST_FIXTURE (dxJointFixed_Fixture_1, test_dJointSetFixed)
+ {
+ // the 2 bodies are align
+ dJointSetFixed (jId);
+ CHECK_CLOSE (joint->qrel[0], 1.0, 1e-4);
+ CHECK_CLOSE (joint->qrel[1], 0.0, 1e-4);
+ CHECK_CLOSE (joint->qrel[2], 0.0, 1e-4);
+ CHECK_CLOSE (joint->qrel[3], 0.0, 1e-4);
+
+ dMatrix3 R;
+ // Rotate 2nd body 90deg around X
+ dBodySetPosition (bId2, 0, 0, 1);
+ dRFromAxisAndAngle (R, 1, 0, 0, M_PI/2.0);
+ dBodySetRotation (bId2, R);
+
+ dJointSetFixed (jId);
+ CHECK_CLOSE (joint->qrel[0], 0.70710678118654757, 1e-4);
+ CHECK_CLOSE (joint->qrel[1], 0.70710678118654757, 1e-4);
+ CHECK_CLOSE (joint->qrel[2], 0.0, 1e-4);
+ CHECK_CLOSE (joint->qrel[3], 0.0, 1e-4);
+
+
+ // Rotate 2nd body -90deg around X
+ dBodySetPosition (bId2, 0, 0, -1);
+ dRFromAxisAndAngle (R, 1, 0, 0, -M_PI/2.0);
+ dBodySetRotation (bId2, R);
+
+ dJointSetFixed (jId);
+ CHECK_CLOSE (joint->qrel[0], 0.70710678118654757, 1e-4);
+ CHECK_CLOSE (joint->qrel[1], -0.70710678118654757, 1e-4);
+ CHECK_CLOSE (joint->qrel[2], 0.0, 1e-4);
+ CHECK_CLOSE (joint->qrel[3], 0.0, 1e-4);
+
+
+ // Rotate 2nd body 90deg around Z
+ dBodySetPosition (bId2, 0, 1, 0);
+ dRFromAxisAndAngle (R, 0, 0, 1, M_PI/2.0);
+ dBodySetRotation (bId2, R);
+
+ dJointSetFixed (jId);
+ CHECK_CLOSE (joint->qrel[0], 0.70710678118654757, 1e-4);
+ CHECK_CLOSE (joint->qrel[1], 0.0, 1e-4);
+ CHECK_CLOSE (joint->qrel[2], 0.0, 1e-4);
+ CHECK_CLOSE (joint->qrel[3], 0.70710678118654757, 1e-4);
+
+
+ // Rotate 2nd body 45deg around Y
+ dBodySetPosition (bId2, 0, 1, 0);
+ dRFromAxisAndAngle (R, 0, 1, 0, M_PI/4.0);
+ dBodySetRotation (bId2, R);
+
+ dJointSetFixed (jId);
+ CHECK_CLOSE (joint->qrel[0], 0.92387953251128674, 1e-4);
+ CHECK_CLOSE (joint->qrel[1], 0.0, 1e-4);
+ CHECK_CLOSE (joint->qrel[2], 0.38268343236508984, 1e-4);
+ CHECK_CLOSE (joint->qrel[3], 0.0, 1e-4);
+
+ // Rotate in a strange manner
+ // Both bodies at origin
+ dRFromEulerAngles (R, REAL(0.23), REAL(3.1), REAL(-0.73));
+ dBodySetPosition (bId1, 0, 0, 0);
+ dBodySetRotation (bId1, R);
+
+ dRFromEulerAngles (R, REAL(-0.57), REAL(1.49), REAL(0.81));
+ dBodySetPosition (bId2, 0, 0, 0);
+ dBodySetRotation (bId2, R);
+
+ dJointSetFixed (jId);
+ CHECK_CLOSE (joint->qrel[0], -0.25526036263124319, 1e-4);
+ CHECK_CLOSE (joint->qrel[1], 0.28434861188441968, 1e-4);
+ CHECK_CLOSE (joint->qrel[2], -0.65308047160141625, 1e-4);
+ CHECK_CLOSE (joint->qrel[3], 0.65381489108282143, 1e-4);
+ }
+
+
+} // End of SUITE TestdxJointFixed
diff --git a/libs/ode-0.16.1/tests/joints/hinge.cpp b/libs/ode-0.16.1/tests/joints/hinge.cpp
new file mode 100644
index 0000000..f715a6e
--- /dev/null
+++ b/libs/ode-0.16.1/tests/joints/hinge.cpp
@@ -0,0 +1,928 @@
+/*************************************************************************
+ * *
+ * 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. *
+ * *
+ *************************************************************************/
+//234567890123456789012345678901234567890123456789012345678901234567890123456789
+// 1 2 3 4 5 6 7
+
+////////////////////////////////////////////////////////////////////////////////
+// This file create unit test for some of the functions found in:
+// ode/src/joinst/hinge.cpp
+//
+//
+////////////////////////////////////////////////////////////////////////////////
+
+#include <UnitTest++.h>
+#include <ode/ode.h>
+
+#include "../../ode/src/config.h"
+#include "../../ode/src/joints/hinge.h"
+
+SUITE (TestdxJointHinge)
+{
+ // The 2 bodies are positionned at (0, 0, 0), with no rotation
+ // The joint is an Hinge Joint
+ // Axis is along the X axis
+ // Anchor at (0, 0, 0)
+ // ^Y
+ // |
+ // |
+ // |
+ // |
+ // |
+ // Z <---- . (X going out of the page)
+ struct dxJointHinge_Fixture_B1_and_B2_At_Zero_Axis_Along_X {
+ dxJointHinge_Fixture_B1_and_B2_At_Zero_Axis_Along_X()
+ {
+ wId = dWorldCreate();
+
+ bId1 = dBodyCreate (wId);
+ dBodySetPosition (bId1, 0, 0, 0);
+
+ bId2 = dBodyCreate (wId);
+ dBodySetPosition (bId2, 0, 0, 0);
+
+ jId = dJointCreateHinge (wId, 0);
+ joint = (dxJointHinge*) jId;
+
+
+ dJointAttach (jId, bId1, bId2);
+ dJointSetHingeAnchor (jId, 0, 0, 0);
+
+ axis[0] = 1;
+ axis[1] = 0;
+ axis[2] = 0;
+ }
+
+ ~dxJointHinge_Fixture_B1_and_B2_At_Zero_Axis_Along_X()
+ {
+ dWorldDestroy (wId);
+ }
+
+ dWorldID wId;
+
+ dBodyID bId1;
+ dBodyID bId2;
+
+
+ dJointID jId;
+ dxJointHinge* joint;
+
+ dVector3 axis;
+ };
+
+ // Rotate 2nd body 90deg around X then back to original position
+ //
+ // ^ ^ ^
+ // | | => | <---
+ // | | |
+ // B1 B2 B1 B2
+ //
+ // Start with a Delta of 90deg
+ // ^ ^ ^
+ // | <--- => | |
+ // | | |
+ // B1 B2 B1 B2
+ TEST_FIXTURE (dxJointHinge_Fixture_B1_and_B2_At_Zero_Axis_Along_X,
+ test_dJointSetHingeAxisOffset_B2_90deg) {
+ dMatrix3 R;
+
+ CHECK_CLOSE (dJointGetHingeAngle (jId), 0.0, 1e-4);
+
+ dRFromAxisAndAngle (R, 1, 0, 0, M_PI/2.0);
+ dBodySetRotation (bId2, R);
+
+ CHECK_CLOSE (-M_PI/2.0, dJointGetHingeAngle (jId), 1e-4);
+
+ dJointSetHingeAxisOffset (jId, axis[0], axis[1], axis[2], -M_PI/2.0);
+ CHECK_CLOSE (-M_PI/2.0, dJointGetHingeAngle (jId), 1e-4);
+
+ dRFromAxisAndAngle (R, 1, 0, 0, 0);
+ dBodySetRotation (bId2, R);
+
+ CHECK_CLOSE (0.0, dJointGetHingeAngle (jId), 1e-4);
+ }
+
+
+ // Rotate 2nd body -90deg around X then back to original position
+ //
+ // ^ ^ ^
+ // | | => | --->
+ // | | |
+ // B1 B2 B1 B2
+ //
+ // Start with a Delta of 90deg
+ // ^ ^ ^
+ // | ---> => | |
+ // | | |
+ // B1 B2 B1 B2
+ TEST_FIXTURE (dxJointHinge_Fixture_B1_and_B2_At_Zero_Axis_Along_X,
+ test_dJointSetHingeAxisOffset_B2_Minus90deg) {
+ dMatrix3 R;
+
+ dJointSetHingeAxis (jId, axis[0], axis[1], axis[2]);
+
+ CHECK_CLOSE (dJointGetHingeAngle (jId), 0.0, 1e-4);
+
+ dRFromAxisAndAngle (R, 1, 0, 0, -M_PI/2.0);
+ dBodySetRotation (bId2, R);
+
+ CHECK_CLOSE (M_PI/2.0, dJointGetHingeAngle (jId), 1e-4);
+
+ dJointSetHingeAxisOffset (jId, axis[0], axis[1], axis[2], M_PI/2.0);
+ CHECK_CLOSE (M_PI/2.0, dJointGetHingeAngle (jId), 1e-4);
+
+ dRFromAxisAndAngle (R, 1, 0, 0, 0);
+ dBodySetRotation (bId2, R);
+
+ CHECK_CLOSE (0.0, dJointGetHingeAngle (jId), 1e-4);
+ }
+
+
+ // Rotate 1st body 0.23rad around X then back to original position
+ //
+ // ^ ^ ^ ^
+ // | | => \ |
+ // | | \ |
+ // B1 B2 B1 B2
+ //
+ // Start with a Delta of 0.23rad
+ // ^ ^ ^ ^
+ // \ | => | |
+ // \ | | |
+ // B1 B2 B1 B2
+ TEST_FIXTURE (dxJointHinge_Fixture_B1_and_B2_At_Zero_Axis_Along_X,
+ test_dJointSetHingeAxisOffset_B1_0_23rad) {
+ dMatrix3 R;
+
+ dJointSetHingeAxis (jId, axis[0], axis[1], axis[2]);
+
+ CHECK_CLOSE (dJointGetHingeAngle (jId), 0.0, 1e-4);
+
+ dRFromAxisAndAngle (R, 1, 0, 0, REAL(0.23) );
+ dBodySetRotation (bId1, R);
+
+ CHECK_CLOSE (REAL(0.23), dJointGetHingeAngle (jId), 1e-4);
+
+ dJointSetHingeAxisOffset (jId, axis[0], axis[1], axis[2], REAL(0.23));
+ CHECK_CLOSE (REAL(0.23), dJointGetHingeAngle (jId), 1e-4);
+
+ dRFromAxisAndAngle (R, 1, 0, 0, 0);
+ dBodySetRotation (bId1, R);
+
+ CHECK_CLOSE (0.0, dJointGetHingeAngle (jId), 1e-4);
+ }
+
+
+ // Rotate 1st body -0.23rad around Z then back to original position
+ //
+ // ^ ^ ^ ^
+ // | | => / |
+ // | | / |
+ // B1 B2 B1 B2
+ //
+ // Start with a Delta of 0.23rad
+ // ^ ^ ^ ^
+ // / | => | |
+ // / | | |
+ // B1 B2 B1 B2
+ TEST_FIXTURE (dxJointHinge_Fixture_B1_and_B2_At_Zero_Axis_Along_X,
+ test_dJointSetHingeAxisOffset_B1_Minus0_23rad) {
+ dMatrix3 R;
+
+ dJointSetHingeAxis (jId, axis[0], axis[1], axis[2]);
+
+ CHECK_CLOSE (dJointGetHingeAngle (jId), 0.0, 1e-4);
+
+ dRFromAxisAndAngle (R, 1, 0, 0, -REAL(0.23));
+ dBodySetRotation (bId1, R);
+
+ CHECK_CLOSE (-REAL(0.23), dJointGetHingeAngle (jId), 1e-4);
+
+ dJointSetHingeAxisOffset (jId, axis[0], axis[1], axis[2], -REAL(0.23));
+ CHECK_CLOSE (-REAL(0.23), dJointGetHingeAngle (jId), 1e-4);
+
+ dRFromAxisAndAngle (R, 1, 0, 0, 0);
+ dBodySetRotation (bId1, R);
+
+ CHECK_CLOSE (0.0, dJointGetHingeAngle (jId), 1e-4);
+ }
+
+
+ // The 2 bodies are positionned at (0, 0, 0), with no rotation
+ // The joint is an Hinge Joint.
+ // Axis in the inverse direction of the X axis
+ // Anchor at (0, 0, 0)
+ // ^Y
+ // |
+ // |
+ // |
+ // |
+ // |
+ // Z <---- x (X going out of the page)
+ struct dxJointHinge_Fixture_B1_and_B2_At_Zero_Axis_Inverse_of_X {
+ dxJointHinge_Fixture_B1_and_B2_At_Zero_Axis_Inverse_of_X()
+ {
+ wId = dWorldCreate();
+
+ bId1 = dBodyCreate (wId);
+ dBodySetPosition (bId1, 0, -1, 0);
+
+ bId2 = dBodyCreate (wId);
+ dBodySetPosition (bId2, 0, 1, 0);
+
+ jId = dJointCreateHinge (wId, 0);
+ joint = (dxJointHinge*) jId;
+
+
+ dJointAttach (jId, bId1, bId2);
+ dJointSetHingeAnchor (jId, 0, 0, 0);
+
+ axis[0] = -1;
+ axis[1] = 0;
+ axis[2] = 0;
+ }
+
+ ~dxJointHinge_Fixture_B1_and_B2_At_Zero_Axis_Inverse_of_X()
+ {
+ dWorldDestroy (wId);
+ }
+
+ dWorldID wId;
+
+ dBodyID bId1;
+ dBodyID bId2;
+
+
+ dJointID jId;
+ dxJointHinge* joint;
+
+ dVector3 axis;
+ };
+
+ // Rotate 2nd body 90deg around X then back to original position
+ //
+ // ^ ^ ^
+ // | | => | <---
+ // | | |
+ // B1 B2 B1 B2
+ //
+ // Start with a Delta of 90deg
+ // ^ ^ ^
+ // | <--- => | |
+ // | | |
+ // B1 B2 B1 B2
+ TEST_FIXTURE (dxJointHinge_Fixture_B1_and_B2_At_Zero_Axis_Inverse_of_X,
+ test_dJointSetHingeAxisOffset_B2_90Deg) {
+ dMatrix3 R;
+
+ dJointSetHingeAxis (jId, axis[0], axis[1], axis[2]);
+
+ CHECK_CLOSE (dJointGetHingeAngle (jId), 0.0, 1e-4);
+
+ dRFromAxisAndAngle (R, 1, 0, 0, M_PI/2.0);
+ dBodySetRotation (bId2, R);
+
+ CHECK_CLOSE (M_PI/2.0, dJointGetHingeAngle (jId), 1e-4);
+
+ dJointSetHingeAxisOffset (jId, axis[0], axis[1], axis[2], M_PI/2.0);
+ CHECK_CLOSE (M_PI/2.0, dJointGetHingeAngle (jId), 1e-4);
+
+ dRFromAxisAndAngle (R, 1, 0, 0, 0);
+ dBodySetRotation (bId2, R);
+
+ CHECK_CLOSE (0.0, dJointGetHingeAngle (jId), 1e-4);
+ }
+
+
+ // Rotate 2nd body -90deg around X then back to original position
+ //
+ // ^ ^ ^
+ // | | => | --->
+ // | | |
+ // B1 B2 B1 B2
+ //
+ // Start with a Delta of 90deg
+ // ^ ^ ^
+ // | ---> => | |
+ // | | |
+ // B1 B2 B1 B2
+ TEST_FIXTURE (dxJointHinge_Fixture_B1_and_B2_At_Zero_Axis_Inverse_of_X,
+ test_dJointSetHingeAxisOffset_B2_Minus90Deg) {
+ dMatrix3 R;
+
+ dJointSetHingeAxis (jId, axis[0], axis[1], axis[2]);
+
+ CHECK_CLOSE (dJointGetHingeAngle (jId), 0.0, 1e-4);
+
+ dRFromAxisAndAngle (R, 1, 0, 0, -M_PI/2.0);
+ dBodySetRotation (bId2, R);
+
+ CHECK_CLOSE (-M_PI/2.0, dJointGetHingeAngle (jId), 1e-4);
+
+ dJointSetHingeAxisOffset (jId, axis[0], axis[1], axis[2], -M_PI/2.0);
+ CHECK_CLOSE (-M_PI/2.0, dJointGetHingeAngle (jId), 1e-4);
+
+ dRFromAxisAndAngle (R, 1, 0, 0, 0);
+ dBodySetRotation (bId2, R);
+
+ CHECK_CLOSE (0.0, dJointGetHingeAngle (jId), 1e-4);
+ }
+
+
+ // Rotate 1st body 0.23rad around X then back to original position
+ //
+ // ^ ^ ^ ^
+ // | | => \ |
+ // | | \ |
+ // B1 B2 B1 B2
+ //
+ // Start with a Delta of 0.23rad
+ // ^ ^ ^ ^
+ // \ | => | |
+ // \ | | |
+ // B1 B2 B1 B2
+ TEST_FIXTURE (dxJointHinge_Fixture_B1_and_B2_At_Zero_Axis_Inverse_of_X,
+ test_dJointSetHingeAxisOffset_B1_0_23rad) {
+ dMatrix3 R;
+
+ dJointSetHingeAxis (jId, axis[0], axis[1], axis[2]);
+
+ CHECK_CLOSE (dJointGetHingeAngle (jId), 0.0, 1e-4);
+
+ dRFromAxisAndAngle (R, 1, 0, 0, REAL(0.23));
+ dBodySetRotation (bId1, R);
+
+ CHECK_CLOSE (-REAL(0.23), dJointGetHingeAngle (jId), 1e-4);
+
+ dJointSetHingeAxisOffset (jId, axis[0], axis[1], axis[2], -REAL(0.23));
+ CHECK_CLOSE (-REAL(0.23), dJointGetHingeAngle (jId), 1e-4);
+
+ dRFromAxisAndAngle (R, 1, 0, 0, 0);
+ dBodySetRotation (bId1, R);
+
+ CHECK_CLOSE (0.0, dJointGetHingeAngle (jId), 1e-4);
+ }
+
+
+ // Rotate 2nd body -0.23rad around Z then back to original position
+ //
+ // ^ ^ ^ ^
+ // | | => / |
+ // | | / |
+ // B1 B2 B1 B2
+ //
+ // Start with a Delta of 0.23rad
+ // ^ ^ ^ ^
+ // / | => | |
+ // / | | |
+ // B1 B2 B1 B2
+ TEST_FIXTURE (dxJointHinge_Fixture_B1_and_B2_At_Zero_Axis_Inverse_of_X,
+ test_dJointSetHingeAxisOffset_B1_Minus0_23rad) {
+ dMatrix3 R;
+
+ dJointSetHingeAxis (jId, axis[0], axis[1], axis[2]);
+
+ CHECK_CLOSE (dJointGetHingeAngle (jId), 0.0, 1e-4);
+
+ dRFromAxisAndAngle (R, 1, 0, 0, -REAL(0.23));
+ dBodySetRotation (bId1, R);
+
+ CHECK_CLOSE (REAL(0.23), dJointGetHingeAngle (jId), 1e-4);
+
+ dJointSetHingeAxisOffset (jId, axis[0], axis[1], axis[2], REAL(0.23));
+ CHECK_CLOSE (REAL(0.23), dJointGetHingeAngle (jId), 1e-4);
+
+ dRFromAxisAndAngle (R, 1, 0, 0, 0);
+ dBodySetRotation (bId1, R);
+
+ CHECK_CLOSE (0.0, dJointGetHingeAngle (jId), 1e-4);
+ }
+
+
+ // Only one body body1 at (0,0,0)
+ // The joint is an Hinge Joint.
+ // Axis is along the X axis
+ // Anchor at (0, 0, 0)
+ //
+ // ^Y
+ // |
+ // |
+ // |
+ // |
+ // |
+ // Z <-- X
+ struct dxJointHinge_Fixture_B1_At_Zero_Axis_Along_X {
+ dxJointHinge_Fixture_B1_At_Zero_Axis_Along_X()
+ {
+ wId = dWorldCreate();
+
+ bId1 = dBodyCreate (wId);
+ dBodySetPosition (bId1, 0, 0, 0);
+
+ jId = dJointCreateHinge (wId, 0);
+ joint = (dxJointHinge*) jId;
+
+
+ dJointAttach (jId, bId1, NULL);
+ dJointSetHingeAnchor (jId, 0, 0, 0);
+
+ axis[0] = 1;
+ axis[1] = 0;
+ axis[2] = 0;
+ }
+
+ ~dxJointHinge_Fixture_B1_At_Zero_Axis_Along_X()
+ {
+ dWorldDestroy (wId);
+ }
+
+ dWorldID wId;
+
+ dBodyID bId1;
+
+
+ dJointID jId;
+ dxJointHinge* joint;
+
+ dVector3 axis;
+ };
+
+ // Rotate B1 by 90deg around X then back to original position
+ //
+ // ^
+ // | => <---
+ // |
+ // B1 B1
+ //
+ // Start with a Delta of 90deg
+ // ^
+ // <--- => |
+ // |
+ // B1 B1
+ TEST_FIXTURE (dxJointHinge_Fixture_B1_At_Zero_Axis_Along_X,
+ test_dJointSetHingeAxisOffset_1Body_B1_90Deg) {
+ dMatrix3 R;
+
+ dJointSetHingeAxis (jId, axis[0], axis[1], axis[2]);
+
+ CHECK_CLOSE (dJointGetHingeAngle (jId), 0.0, 1e-4);
+
+ dRFromAxisAndAngle (R, 1, 0, 0, M_PI/2.0);
+ dBodySetRotation (bId1, R);
+
+ CHECK_CLOSE (M_PI/2.0, dJointGetHingeAngle (jId), 1e-4);
+
+ dJointSetHingeAxisOffset (jId, axis[0], axis[1], axis[2], M_PI/2.0);
+ CHECK_CLOSE (M_PI/2.0, dJointGetHingeAngle (jId), 1e-4);
+
+ dRFromAxisAndAngle (R, 1, 0, 0, 0);
+ dBodySetRotation (bId1, R);
+
+ CHECK_CLOSE (0, dJointGetHingeAngle (jId), 1e-4);
+ }
+
+ // Rotate B1 by -0.23rad around X then back to original position
+ //
+ // ^ ^
+ // | => /
+ // | /
+ // B1 B1
+ //
+ // Start with a Delta of -0.23rad
+ // ^ ^
+ // / => |
+ // / |
+ // B1 B1
+ TEST_FIXTURE (dxJointHinge_Fixture_B1_At_Zero_Axis_Along_X,
+ test_dJointSetHingeAxisOffset_1Body_B1_Minus0_23rad) {
+ dMatrix3 R;
+
+ dJointSetHingeAxis (jId, axis[0], axis[1], axis[2]);
+
+ CHECK_CLOSE (dJointGetHingeAngle (jId), 0.0, 1e-4);
+
+ dRFromAxisAndAngle (R, 1, 0, 0, -REAL(0.23));
+ dBodySetRotation (bId1, R);
+
+ CHECK_CLOSE (-REAL(0.23), dJointGetHingeAngle (jId), 1e-4);
+
+ dJointSetHingeAxisOffset (jId, axis[0], axis[1], axis[2], -REAL(0.23));
+ CHECK_CLOSE (-REAL(0.23), dJointGetHingeAngle (jId), 1e-4);
+
+ dRFromAxisAndAngle (R, 1, 0, 0, 0);
+ dBodySetRotation (bId1, R);
+
+ CHECK_CLOSE (0, dJointGetHingeAngle (jId), 1e-4);
+ }
+
+
+
+ // Only one body body1 at (0,0,0)
+ // The joint is an Hinge Joint.
+ // Axis the inverse of the X axis
+ // Anchor at (0, 0, 0)
+ //
+ // ^Y
+ // |
+ // |
+ // |
+ // |
+ // |
+ // Z <-- X
+ struct dxJointHinge_Fixture_B1_At_Zero_Axis_Inverse_of_X {
+ dxJointHinge_Fixture_B1_At_Zero_Axis_Inverse_of_X()
+ {
+ wId = dWorldCreate();
+
+ bId1 = dBodyCreate (wId);
+ dBodySetPosition (bId1, 0, 0, 0);
+
+ jId = dJointCreateHinge (wId, 0);
+ joint = (dxJointHinge*) jId;
+
+
+ dJointAttach (jId, bId1, NULL);
+ dJointSetHingeAnchor (jId, 0, 0, 0);
+
+ axis[0] = -1;
+ axis[1] = 0;
+ axis[2] = 0;
+ }
+
+ ~dxJointHinge_Fixture_B1_At_Zero_Axis_Inverse_of_X()
+ {
+ dWorldDestroy (wId);
+ }
+
+ dWorldID wId;
+
+ dBodyID bId1;
+
+
+ dJointID jId;
+ dxJointHinge* joint;
+
+ dVector3 axis;
+ };
+
+ // Rotate B1 by 90deg around X then back to original position
+ //
+ // ^
+ // | => <---
+ // |
+ // B1 B1
+ //
+ // Start with a Delta of 90deg
+ // ^
+ // <--- => |
+ // |
+ // B1 B1
+ TEST_FIXTURE (dxJointHinge_Fixture_B1_At_Zero_Axis_Inverse_of_X,
+ test_dJointSetHingeAxisOffset_1Body_B1_90Deg) {
+ dMatrix3 R;
+
+ dJointSetHingeAxis (jId, axis[0], axis[1], axis[2]);
+
+ CHECK_CLOSE (dJointGetHingeAngle (jId), 0.0, 1e-4);
+
+ dRFromAxisAndAngle (R, 1, 0, 0, M_PI/2.0);
+ dBodySetRotation (bId1, R);
+
+ CHECK_CLOSE (-M_PI/2.0, dJointGetHingeAngle (jId), 1e-4);
+
+ dJointSetHingeAxisOffset (jId, axis[0], axis[1], axis[2], -M_PI/2.0);
+ CHECK_CLOSE (-M_PI/2.0, dJointGetHingeAngle (jId), 1e-4);
+
+ dRFromAxisAndAngle (R, 1, 0, 0, 0);
+ dBodySetRotation (bId1, R);
+
+ CHECK_CLOSE (0, dJointGetHingeAngle (jId), 1e-4);
+ }
+
+ // Rotate B1 by -0.23rad around X then back to original position
+ //
+ // ^ ^
+ // | => /
+ // | /
+ // B1 B1
+ //
+ // Start with a Delta of -0.23rad
+ // ^ ^
+ // / => |
+ // / |
+ // B1 B1
+ TEST_FIXTURE (dxJointHinge_Fixture_B1_At_Zero_Axis_Inverse_of_X,
+ test_dJointSetHingeAxisOffset_1Body_B1_Minus0_23rad) {
+ dMatrix3 R;
+
+ dJointSetHingeAxis (jId, axis[0], axis[1], axis[2]);
+
+ CHECK_CLOSE (dJointGetHingeAngle (jId), 0.0, 1e-4);
+
+ dRFromAxisAndAngle (R, 1, 0, 0, -REAL(0.23));
+ dBodySetRotation (bId1, R);
+
+ CHECK_CLOSE (REAL(0.23), dJointGetHingeAngle (jId), 1e-4);
+
+ dJointSetHingeAxisOffset (jId, axis[0], axis[1], axis[2], REAL(0.23));
+ CHECK_CLOSE (REAL(0.23), dJointGetHingeAngle (jId), 1e-4);
+
+ dRFromAxisAndAngle (R, 1, 0, 0, 0);
+ dBodySetRotation (bId1, R);
+
+ CHECK_CLOSE (0, dJointGetHingeAngle (jId), 1e-4);
+ }
+
+
+
+
+
+ // Only one body body2 at (0,0,0)
+ // The joint is an Hinge Joint.
+ // Axis is along the X axis
+ // Anchor at (0, 0, 0)
+ //
+ // ^Y
+ // |
+ // |
+ // |
+ // |
+ // |
+ // Z <-- X
+ struct dxJointHinge_Fixture_B2_At_Zero_Axis_Along_X {
+ dxJointHinge_Fixture_B2_At_Zero_Axis_Along_X()
+ {
+ wId = dWorldCreate();
+
+ bId2 = dBodyCreate (wId);
+ dBodySetPosition (bId2, 0, 0, 0);
+
+ jId = dJointCreateHinge (wId, 0);
+ joint = (dxJointHinge*) jId;
+
+
+ dJointAttach (jId, NULL, bId2);
+ dJointSetHingeAnchor (jId, 0, 0, 0);
+
+ axis[0] = 1;
+ axis[1] = 0;
+ axis[2] = 0;
+ }
+
+ ~dxJointHinge_Fixture_B2_At_Zero_Axis_Along_X()
+ {
+ dWorldDestroy (wId);
+ }
+
+ dWorldID wId;
+
+ dBodyID bId2;
+
+
+ dJointID jId;
+ dxJointHinge* joint;
+
+ dVector3 axis;
+ };
+
+ // Rotate B2 by 90deg around X then back to original position
+ //
+ // ^
+ // | => <---
+ // |
+ // B2 B2
+ //
+ // Start with a Delta of 90deg
+ // ^
+ // <--- => |
+ // |
+ // B2 B2
+ TEST_FIXTURE (dxJointHinge_Fixture_B2_At_Zero_Axis_Along_X,
+ test_dJointSetHingeAxisOffset_1Body_B2_90Deg) {
+ dMatrix3 R;
+
+ dJointSetHingeAxis (jId, axis[0], axis[1], axis[2]);
+
+ CHECK_CLOSE (dJointGetHingeAngle (jId), 0.0, 1e-4);
+
+ dRFromAxisAndAngle (R, 1, 0, 0, M_PI/2.0);
+ dBodySetRotation (bId2, R);
+
+ CHECK_CLOSE (-M_PI/2.0, dJointGetHingeAngle (jId), 1e-4);
+
+ dJointSetHingeAxisOffset (jId, axis[0], axis[1], axis[2], -M_PI/2.0);
+ CHECK_CLOSE (-M_PI/2.0, dJointGetHingeAngle (jId), 1e-4);
+
+ dRFromAxisAndAngle (R, 1, 0, 0, 0);
+ dBodySetRotation (bId2, R);
+
+ CHECK_CLOSE (0, dJointGetHingeAngle (jId), 1e-4);
+ }
+
+ // Rotate B2 by -0.23rad around X then back to original position
+ //
+ // ^ ^
+ // | => /
+ // | /
+ // B2 B2
+ //
+ // Start with a Delta of -0.23rad
+ // ^ ^
+ // / => |
+ // / |
+ // B2 B2
+ TEST_FIXTURE (dxJointHinge_Fixture_B2_At_Zero_Axis_Along_X,
+ test_dJointSetHingeAxisOffset_1Body_B2_Minus0_23rad) {
+ dMatrix3 R;
+
+ dJointSetHingeAxis (jId, axis[0], axis[1], axis[2]);
+
+ CHECK_CLOSE (dJointGetHingeAngle (jId), 0.0, 1e-4);
+
+ dRFromAxisAndAngle (R, 1, 0, 0, -REAL(0.23));
+ dBodySetRotation (bId2, R);
+
+ CHECK_CLOSE (REAL(0.23), dJointGetHingeAngle (jId), 1e-4);
+
+ dJointSetHingeAxisOffset (jId, axis[0], axis[1], axis[2], REAL(0.23));
+ CHECK_CLOSE (REAL(0.23), dJointGetHingeAngle (jId), 1e-4);
+
+ dRFromAxisAndAngle (R, 1, 0, 0, 0);
+ dBodySetRotation (bId2, R);
+
+ CHECK_CLOSE (0, dJointGetHingeAngle (jId), 1e-4);
+ }
+
+
+
+ // Create 2 bodies attached by a Hinge joint
+ // Axis is along the X axis (Default value
+ // Anchor at (0, 0, 0) (Default value)
+ //
+ // ^Y
+ // |
+ // * Body2
+ // |
+ // |
+ // Body1 |
+ // * Z-------->
+ struct dxJointHinge_Test_Initialization {
+ dxJointHinge_Test_Initialization()
+ {
+ wId = dWorldCreate();
+
+ // Remove gravity to have the only force be the force of the joint
+ dWorldSetGravity(wId, 0,0,0);
+
+ for (int j=0; j<2; ++j) {
+ bId[j][0] = dBodyCreate (wId);
+ dBodySetPosition (bId[j][0], -1, -2, -3);
+
+ bId[j][1] = dBodyCreate (wId);
+ dBodySetPosition (bId[j][1], 11, 22, 33);
+
+
+ dMatrix3 R;
+ dVector3 axis; // Random axis
+
+ axis[0] = REAL(0.53);
+ axis[1] = -REAL(0.71);
+ axis[2] = REAL(0.43);
+ dNormalize3(axis);
+ dRFromAxisAndAngle (R, axis[0], axis[1], axis[2],
+ REAL(0.47123)); // 27deg
+ dBodySetRotation (bId[j][0], R);
+
+
+ axis[0] = REAL(1.2);
+ axis[1] = REAL(0.87);
+ axis[2] = -REAL(0.33);
+ dNormalize3(axis);
+ dRFromAxisAndAngle (R, axis[0], axis[1], axis[2],
+ REAL(0.47123)); // 27deg
+ dBodySetRotation (bId[j][1], R);
+
+ jId[j] = dJointCreateHinge (wId, 0);
+ dJointAttach (jId[j], bId[j][0], bId[j][1]);
+ // dJointSetHingeParam(jId[j], dParamLoStop, 1);
+ // dJointSetHingeParam(jId[j], dParamHiStop, 2);
+ // dJointSetHingeParam(jId[j], dParamFMax, 200);
+ }
+ }
+
+ ~dxJointHinge_Test_Initialization()
+ {
+ dWorldDestroy (wId);
+ }
+
+ dWorldID wId;
+
+ dBodyID bId[2][2];
+
+
+ dJointID jId[2];
+
+ };
+
+
+ // Test if setting a Hinge with its default values
+ // will behave the same as a default Hinge joint
+ TEST_FIXTURE (dxJointHinge_Test_Initialization,
+ test_Hinge_Initialization) {
+ using namespace std;
+
+ dVector3 axis;
+ dJointGetHingeAxis(jId[1], axis);
+ dJointSetHingeAxis(jId[1], axis[0], axis[1], axis[2]);
+
+
+ dVector3 anchor;
+ dJointGetHingeAnchor(jId[1], anchor);
+ dJointSetHingeAnchor(jId[1], anchor[0], anchor[1], anchor[2]);
+
+
+ for (int b=0; b<2; ++b) {
+ // Compare body b of the first joint with its equivalent on the
+ // second joint
+ const dReal *qA = dBodyGetQuaternion(bId[0][b]);
+ const dReal *qB = dBodyGetQuaternion(bId[1][b]);
+ CHECK_CLOSE (qA[0], qB[0], 1e-6);
+ CHECK_CLOSE (qA[1], qB[1], 1e-6);
+ CHECK_CLOSE (qA[2], qB[2], 1e-6);
+ CHECK_CLOSE (qA[3], qB[3], 1e-6);
+ }
+
+ dWorldStep (wId,0.5);
+ dWorldStep (wId,0.5);
+ dWorldStep (wId,0.5);
+ dWorldStep (wId,0.5);
+
+ for (int b=0; b<2; ++b) {
+ // Compare body b of the first joint with its equivalent on the
+ // second joint
+ const dReal *qA = dBodyGetQuaternion(bId[0][b]);
+ const dReal *qB = dBodyGetQuaternion(bId[1][b]);
+ CHECK_CLOSE (qA[0], qB[0], 1e-6);
+ CHECK_CLOSE (qA[1], qB[1], 1e-6);
+ CHECK_CLOSE (qA[2], qB[2], 1e-6);
+ CHECK_CLOSE (qA[3], qB[3], 1e-6);
+
+
+ const dReal *posA = dBodyGetPosition(bId[0][b]);
+ const dReal *posB = dBodyGetPosition(bId[1][b]);
+ CHECK_CLOSE (posA[0], posB[0], 1e-6);
+ CHECK_CLOSE (posA[1], posB[1], 1e-6);
+ CHECK_CLOSE (posA[2], posB[2], 1e-6);
+ CHECK_CLOSE (posA[3], posB[3], 1e-6);
+ }
+ }
+
+
+ TEST_FIXTURE(dxJointHinge_Fixture_B1_and_B2_At_Zero_Axis_Along_X,
+ test_Hinge_dParamVel)
+ {
+ const dReal targetvel = 100;
+ const dReal tolerance = targetvel *
+#ifdef dSINGLE
+ 1e-2
+#else
+ 1e-6
+#endif
+ ;
+
+ dJointSetHingeParam(jId, dParamFMax, dInfinity);
+ dJointSetHingeParam(jId, dParamVel, targetvel);
+
+ dWorldStep(wId, 0.001);
+
+ const dReal *v1 = dBodyGetAngularVel(bId1);
+ const dReal *v2 = dBodyGetAngularVel(bId2);
+ dVector3 rvel = { v1[0]-v2[0], v1[1]-v2[1], v1[2]-v2[2] };
+ CHECK_CLOSE(rvel[0], targetvel, tolerance);
+ CHECK_CLOSE(rvel[1], 0, tolerance);
+ CHECK_CLOSE(rvel[2], 0, tolerance);
+ }
+
+
+
+} // End of SUITE TestdxJointHinge
+
+
diff --git a/libs/ode-0.16.1/tests/joints/hinge2.cpp b/libs/ode-0.16.1/tests/joints/hinge2.cpp
new file mode 100644
index 0000000..3f9007c
--- /dev/null
+++ b/libs/ode-0.16.1/tests/joints/hinge2.cpp
@@ -0,0 +1,167 @@
+/*************************************************************************
+ * *
+ * 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. *
+ * *
+ *************************************************************************/
+//234567890123456789012345678901234567890123456789012345678901234567890123456789
+// 1 2 3 4 5 6 7
+
+////////////////////////////////////////////////////////////////////////////////
+// This file create unit test for some of the functions found in:
+// ode/src/joinst/hinge2.cpp
+//
+//
+////////////////////////////////////////////////////////////////////////////////
+
+#include <UnitTest++.h>
+#include <ode/ode.h>
+
+#include "../../ode/src/config.h"
+#include "../../ode/src/joints/hinge2.h"
+
+
+using namespace std;
+
+SUITE (TestdxJointHinge2)
+{
+ // The 2 bodies are positionned at (-1, -2, -3), and (11, 22, 33)
+ // The bodis have rotation of 27deg around some axis.
+ // The joint is a Hinge2 Joint
+ // Axis is along the X axis
+ // Anchor at (0, 0, 0)
+ struct dxJointHinge2_Fixture_B1_and_B2_At_Zero_Axis_Along_X {
+ dxJointHinge2_Fixture_B1_and_B2_At_Zero_Axis_Along_X()
+ {
+ wId = dWorldCreate();
+
+ for (int j=0; j<2; ++j) {
+ bId[j][0] = dBodyCreate (wId);
+ dBodySetPosition (bId[j][0], -1, -2, -3);
+
+ bId[j][1] = dBodyCreate (wId);
+ dBodySetPosition (bId[j][1], 11, 22, 33);
+
+
+ dMatrix3 R;
+ dVector3 axis; // Random axis
+
+ axis[0] = REAL(0.53);
+ axis[1] = -REAL(0.71);
+ axis[2] = REAL(0.43);
+ dNormalize3(axis);
+ dRFromAxisAndAngle (R, axis[0], axis[1], axis[2],
+ REAL(0.47123)); // 27deg
+ dBodySetRotation (bId[j][0], R);
+
+
+ axis[0] = REAL(1.2);
+ axis[1] = REAL(0.87);
+ axis[2] = -REAL(0.33);
+ dNormalize3(axis);
+ dRFromAxisAndAngle (R, axis[0], axis[1], axis[2],
+ REAL(0.47123)); // 27deg
+ dBodySetRotation (bId[j][1], R);
+
+ jId[j] = dJointCreateHinge2 (wId, 0);
+ dJointAttach (jId[j], bId[j][0], bId[j][1]);
+ }
+ }
+
+ ~dxJointHinge2_Fixture_B1_and_B2_At_Zero_Axis_Along_X()
+ {
+ dWorldDestroy (wId);
+ }
+
+ dWorldID wId;
+
+ dBodyID bId[2][2];
+
+
+ dJointID jId[2];
+ };
+
+ // Rotate 2nd body 90deg around X then back to original position
+ //
+ // ^ ^ ^
+ // | | => | <---
+ // | | |
+ // B1 B2 B1 B2
+ //
+ // Start with a Delta of 90deg
+ // ^ ^ ^
+ // | <--- => | |
+ // | | |
+ // B1 B2 B1 B2
+ TEST_FIXTURE (dxJointHinge2_Fixture_B1_and_B2_At_Zero_Axis_Along_X,
+ test_dJointSetHinge2AxisOffset_B2_90deg) {
+
+ dVector3 anchor;
+ dJointGetHinge2Anchor(jId[1], anchor);
+ dJointSetHinge2Anchor(jId[1], anchor[0], anchor[1], anchor[2]);
+
+ dVector3 axis1, axis2;
+ dJointGetHinge2Axis1(jId[1], axis1);
+ dJointGetHinge2Axis2(jId[1], axis2);
+ dJointSetHinge2Axes(jId[1], axis1, axis2);
+ dJointSetHinge2Axes(jId[1], axis1, NULL);
+ dJointSetHinge2Axes(jId[1], NULL, axis2);
+
+
+ for (int b=0; b<2; ++b) {
+ // Compare body b of the first joint with its equivalent on the
+ // second joint
+ const dReal *qA = dBodyGetQuaternion(bId[0][b]);
+ const dReal *qB = dBodyGetQuaternion(bId[1][b]);
+ CHECK_CLOSE (qA[0], qB[0], 1e-4);
+ CHECK_CLOSE (qA[1], qB[1], 1e-4);
+ CHECK_CLOSE (qA[2], qB[2], 1e-4);
+ CHECK_CLOSE (qA[3], qB[3], 1e-4);
+ }
+
+ dWorldStep (wId,0.5);
+ dWorldStep (wId,0.5);
+ dWorldStep (wId,0.5);
+ dWorldStep (wId,0.5);
+
+ for (int b=0; b<2; ++b) {
+ // Compare body b of the first joint with its equivalent on the
+ // second joint
+ const dReal *qA = dBodyGetQuaternion(bId[0][b]);
+ const dReal *qB = dBodyGetQuaternion(bId[1][b]);
+ CHECK_CLOSE (qA[0], qB[0], 1e-4);
+ CHECK_CLOSE (qA[1], qB[1], 1e-4);
+ CHECK_CLOSE (qA[2], qB[2], 1e-4);
+ CHECK_CLOSE (qA[3], qB[3], 1e-4);
+
+
+ const dReal *posA = dBodyGetPosition(bId[0][b]);
+ const dReal *posB = dBodyGetPosition(bId[1][b]);
+ CHECK_CLOSE (posA[0], posB[0], 1e-4);
+ CHECK_CLOSE (posA[1], posB[1], 1e-4);
+ CHECK_CLOSE (posA[2], posB[2], 1e-4);
+ CHECK_CLOSE (posA[3], posB[3], 1e-4);
+ }
+ }
+
+
+
+
+} // End of SUITE TestdxJointHinge2
+
+
diff --git a/libs/ode-0.16.1/tests/joints/piston.cpp b/libs/ode-0.16.1/tests/joints/piston.cpp
new file mode 100644
index 0000000..9422180
--- /dev/null
+++ b/libs/ode-0.16.1/tests/joints/piston.cpp
@@ -0,0 +1,1456 @@
+/*************************************************************************
+ * *
+ * 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. *
+ * *
+ *************************************************************************/
+//234567890123456789012345678901234567890123456789012345678901234567890123456789
+// 1 2 3 4 5 6 7
+
+////////////////////////////////////////////////////////////////////////////////
+// This file create unit test for some of the functions found in:
+// ode/src/joinst/piston.cpp
+//
+//
+////////////////////////////////////////////////////////////////////////////////
+
+#include <UnitTest++.h>
+#include <ode/ode.h>
+
+#include "../../ode/src/config.h"
+#include "../../ode/src/joints/piston.h"
+
+SUITE (TestdxJointPiston)
+{
+ // The 2 bodies are positionned at (0, 0, 0), with no rotation
+ // The joint is a Piston Joint
+ // Axis is along the X axis
+ // Anchor at (0, 0, 0)
+ struct Fixture_dxJointPiston_B1_and_B2_At_Zero_Axis_Along_X
+ {
+ Fixture_dxJointPiston_B1_and_B2_At_Zero_Axis_Along_X()
+ {
+ wId = dWorldCreate();
+
+ bId1 = dBodyCreate (wId);
+ dBodySetPosition (bId1, 0, 0, 0);
+
+ bId2 = dBodyCreate (wId);
+ dBodySetPosition (bId2, 0, 0, 0);
+
+ jId = dJointCreatePiston (wId, 0);
+ joint = (dxJointPiston*) jId;
+
+
+ dJointAttach (jId, bId1, bId2);
+
+ dJointSetPistonAxis (jId, axis[0], axis[1], axis[2]);
+ }
+
+ ~Fixture_dxJointPiston_B1_and_B2_At_Zero_Axis_Along_X()
+ {
+ dWorldDestroy (wId);
+ }
+
+ dWorldID wId;
+
+ dBodyID bId1;
+ dBodyID bId2;
+
+
+ dJointID jId;
+ dxJointPiston* joint;
+
+ static const dVector3 axis;
+
+ static const dReal offset;
+ };
+ const dVector3 Fixture_dxJointPiston_B1_and_B2_At_Zero_Axis_Along_X::axis =
+ {
+ 1, 0, 0
+ };
+ const dReal Fixture_dxJointPiston_B1_and_B2_At_Zero_Axis_Along_X::offset = REAL (3.1);
+
+ // Move 1st body offset unit in the X direction
+ //
+ // X-------> X---------> Axis -->
+ // B1 => B1
+ // B2 B2
+ //
+ // Start with a Offset of offset unit
+ //
+ // X-------> X---------> Axis -->
+ // B1 => B1
+ // B2 B2
+ TEST_FIXTURE (Fixture_dxJointPiston_B1_and_B2_At_Zero_Axis_Along_X,
+ test_dJointSetPistonAxisOffset_B1_3Unit)
+ {
+ dJointSetPistonAnchor (jId, 0, 0, 0);
+
+ CHECK_CLOSE (0.0, dJointGetPistonPosition (jId), 1e-4);
+
+ dBodySetPosition (bId1, offset, 0, 0);
+
+ CHECK_CLOSE (offset, dJointGetPistonPosition (jId), 1e-4);
+
+ dJointSetPistonAnchorOffset (jId, 0, 0, 0,
+ offset*axis[0],offset*axis[1],offset*axis[2]);
+ CHECK_CLOSE (offset, dJointGetPistonPosition (jId), 1e-4);
+
+ dBodySetPosition (bId1, 0, 0, 0);
+ CHECK_CLOSE (0.0, dJointGetPistonPosition (jId), 1e-4);
+
+ // Only here to test a deprecated warning
+ #if 0 // the deprecated warning is not a functional part of the API, no need to test it.
+ dJointSetPistonAxisDelta (jId, 1, 0, 0, 0, 0, 0);
+ #endif
+ }
+
+ // Move 1st body offset unit in the opposite X direction
+ //
+ // X-------> X---------> Axis -->
+ // B1 => B1
+ // B2 B2
+ //
+ // Start with a Offset of -offset unit
+ //
+ // X-------> X---------> Axis -->
+ // B1 => B1
+ // B2 B2
+ TEST_FIXTURE (Fixture_dxJointPiston_B1_and_B2_At_Zero_Axis_Along_X,
+ test_dJointSetPistonAxisOffset_B1_Minus_3Unit)
+ {
+ dJointSetPistonAnchor (jId, 0, 0, 0);
+
+ CHECK_CLOSE (0.0, dJointGetPistonPosition (jId), 1e-4);
+
+ dBodySetPosition (bId1, -offset, 0, 0);
+
+ CHECK_CLOSE (-offset, dJointGetPistonPosition (jId), 1e-4);
+
+ dJointSetPistonAnchorOffset (jId, 0, 0, 0,
+ -offset*axis[0],-offset*axis[1],-offset*axis[2]);
+ CHECK_CLOSE (-offset, dJointGetPistonPosition (jId), 1e-4);
+
+ dBodySetPosition (bId1, 0, 0, 0);
+ CHECK_CLOSE (0.0, dJointGetPistonPosition (jId), 1e-4);
+ }
+
+ // Move 2nd body offset unit in the X direction
+ //
+ // X-------> X---------> Axis -->
+ // B1 => B1
+ // B2 B2
+ //
+ // Start with a Offset of offset unit
+ //
+ // X-------> X---------> Axis -->
+ // B1 => B1
+ // B2 B2
+ TEST_FIXTURE (Fixture_dxJointPiston_B1_and_B2_At_Zero_Axis_Along_X,
+ test_dJointSetPistonAxisOffset_B2_3Unit)
+ {
+ dJointSetPistonAnchor (jId, 0, 0, 0);
+
+ CHECK_CLOSE (0.0, dJointGetPistonPosition (jId), 1e-4);
+
+ dBodySetPosition (bId2, offset, 0, 0);
+
+ CHECK_CLOSE (-offset, dJointGetPistonPosition (jId), 1e-4);
+
+ dJointSetPistonAnchorOffset (jId, 0, 0, 0,
+ -offset*axis[0],-offset*axis[1],-offset*axis[2]);
+ CHECK_CLOSE (-offset, dJointGetPistonPosition (jId), 1e-4);
+
+ dBodySetPosition (bId2, 0, 0, 0);
+ CHECK_CLOSE (0.0, dJointGetPistonPosition (jId), 1e-4);
+ }
+
+ // Move 2nd body offset unit in the opposite X direction
+ //
+ // X-------> X---------> Axis -->
+ // B1 => B1
+ // B2 B2
+ //
+ // Start with a Offset of -offset unit
+ //
+ // X-------> X---------> Axis -->
+ // B1 => B1
+ // B2 B2
+ TEST_FIXTURE (Fixture_dxJointPiston_B1_and_B2_At_Zero_Axis_Along_X,
+ test_dJointSetPistonAxisOffset_B2_Minus_3Unit)
+ {
+ dJointSetPistonAnchor (jId, 0, 0, 0);
+
+ CHECK_CLOSE (0.0, dJointGetPistonPosition (jId), 1e-4);
+
+ dBodySetPosition (bId2, -offset, 0, 0);
+
+ CHECK_CLOSE (offset, dJointGetPistonPosition (jId), 1e-4);
+
+ dJointSetPistonAnchorOffset (jId, 0, 0, 0,
+ offset*axis[0],offset*axis[1],offset*axis[2]);
+ CHECK_CLOSE (offset, dJointGetPistonPosition (jId), 1e-4);
+
+ dBodySetPosition (bId2, 0, 0, 0);
+ CHECK_CLOSE (0.0, dJointGetPistonPosition (jId), 1e-4);
+ }
+
+
+
+ // The 2 bodies are positionned at (0, 0, 0), with no rotation
+ // The joint is a Piston Joint
+ // Axis is the opposite of the X axis
+ // Anchor at (0, 0, 0)
+ struct Fixture_dxJointPiston_B1_and_B2_At_Zero_Axis_Inverse_of_X
+ {
+ Fixture_dxJointPiston_B1_and_B2_At_Zero_Axis_Inverse_of_X()
+ {
+ wId = dWorldCreate();
+
+ bId1 = dBodyCreate (wId);
+ dBodySetPosition (bId1, 0, 0, 0);
+
+ bId2 = dBodyCreate (wId);
+ dBodySetPosition (bId2, 0, 0, 0);
+
+ jId = dJointCreatePiston (wId, 0);
+ joint = (dxJointPiston*) jId;
+
+
+ dJointAttach (jId, bId1, bId2);
+
+
+ dJointSetPistonAxis (jId, axis[0], axis[1], axis[2]);
+ }
+
+ ~Fixture_dxJointPiston_B1_and_B2_At_Zero_Axis_Inverse_of_X()
+ {
+ dWorldDestroy (wId);
+ }
+
+ dWorldID wId;
+
+ dBodyID bId1;
+ dBodyID bId2;
+
+
+ dJointID jId;
+ dxJointPiston* joint;
+
+ static const dVector3 axis;
+ static const dReal offset;
+ };
+ const dVector3 Fixture_dxJointPiston_B1_and_B2_At_Zero_Axis_Inverse_of_X::axis =
+ {
+ -1, 0, 0
+ };
+ const dReal Fixture_dxJointPiston_B1_and_B2_At_Zero_Axis_Inverse_of_X::offset = REAL (3.1);
+
+ // Move 1st body offset unit in the X direction
+ //
+ // X-------> X---------> <-- Axis
+ // B1 => B1
+ // B2 B2
+ //
+ // Start with a Offset of offset unit
+ //
+ // X-------> X---------> <-- Axis
+ // B1 => B1
+ // B2 B2
+ TEST_FIXTURE (Fixture_dxJointPiston_B1_and_B2_At_Zero_Axis_Inverse_of_X,
+ test_dJointSetPistonAxisOffset_B1_3Unit)
+ {
+ dJointSetPistonAnchor (jId, 0, 0, 0);
+
+ CHECK_CLOSE (0.0, dJointGetPistonPosition (jId), 1e-4);
+
+ dBodySetPosition (bId1, offset, 0, 0);
+
+ CHECK_CLOSE (-offset, dJointGetPistonPosition (jId), 1e-4);
+
+ dJointSetPistonAnchorOffset (jId, 0, 0, 0,
+ -offset*axis[0],-offset*axis[1],-offset*axis[2]);
+ CHECK_CLOSE (-offset, dJointGetPistonPosition (jId), 1e-4);
+
+ dBodySetPosition (bId1, 0, 0, 0);
+ CHECK_CLOSE (0.0, dJointGetPistonPosition (jId), 1e-4);
+ }
+
+ // Move 1st body offset unit in the opposite X direction
+ //
+ // X-------> X---------> <-- Axis
+ // B1 => B1
+ // B2 B2
+ //
+ // Start with a Offset of offset unit
+ //
+ // X-------> X---------> <-- Axis
+ // B1 => B1
+ // B2 B2
+ TEST_FIXTURE (Fixture_dxJointPiston_B1_and_B2_At_Zero_Axis_Inverse_of_X,
+ test_dJointSetPistonAxisOffset_B1_Minus_3Unit)
+ {
+ dJointSetPistonAnchor (jId, 0, 0, 0);
+
+ CHECK_CLOSE (0.0, dJointGetPistonPosition (jId), 1e-4);
+
+ dBodySetPosition (bId1, -offset, 0, 0);
+
+ CHECK_CLOSE (offset, dJointGetPistonPosition (jId), 1e-4);
+
+ dJointSetPistonAnchorOffset (jId, 0, 0, 0,
+ offset*axis[0],offset*axis[1],offset*axis[2]);
+ CHECK_CLOSE (offset, dJointGetPistonPosition (jId), 1e-4);
+
+ dBodySetPosition (bId1, 0, 0, 0);
+ CHECK_CLOSE (0.0, dJointGetPistonPosition (jId), 1e-4);
+ }
+
+ // Move 2nd body offset unit in the X direction
+ //
+ // X-------> X---------> <-- Axis
+ // B1 => B1
+ // B2 B2
+ //
+ // Start with a Offset of offset unit
+ //
+ // X-------> X---------> <-- Axis
+ // B1 => B1
+ // B2 B2
+ TEST_FIXTURE (Fixture_dxJointPiston_B1_and_B2_At_Zero_Axis_Inverse_of_X,
+ test_dJointSetPistonAxisOffset_B2_3Unit)
+ {
+ dJointSetPistonAnchor (jId, 0, 0, 0);
+
+ CHECK_CLOSE (0.0, dJointGetPistonPosition (jId), 1e-4);
+
+ dBodySetPosition (bId2, offset, 0, 0);
+
+ CHECK_CLOSE (offset, dJointGetPistonPosition (jId), 1e-4);
+
+ dJointSetPistonAnchorOffset (jId, 0, 0, 0,
+ offset*axis[0],offset*axis[1],offset*axis[2]);
+ CHECK_CLOSE (offset, dJointGetPistonPosition (jId), 1e-4);
+
+ dBodySetPosition (bId2, 0, 0, 0);
+ CHECK_CLOSE (0.0, dJointGetPistonPosition (jId), 1e-4);
+ }
+
+ // Move 2nd body offset unit in the opposite X direction
+ //
+ // X-------> X---------> <-- Axis
+ // B1 => B1
+ // B2 B2
+ //
+ // Start with a Offset of -offset unit
+ //
+ // X-------> X---------> <-- Axis
+ // B1 => B1
+ // B2 B2
+ TEST_FIXTURE (Fixture_dxJointPiston_B1_and_B2_At_Zero_Axis_Inverse_of_X,
+ test_dJointSetPistonAxisOffset_B2_Minus_3Unit)
+ {
+ dJointSetPistonAnchor (jId, 0, 0, 0);
+
+ CHECK_CLOSE (0.0, dJointGetPistonPosition (jId), 1e-4);
+
+ dBodySetPosition (bId2, -offset, 0, 0);
+
+ CHECK_CLOSE (-offset, dJointGetPistonPosition (jId), 1e-4);
+
+ dJointSetPistonAnchorOffset (jId, 0, 0, 0,
+ -offset*axis[0],-offset*axis[1],-offset*axis[2]);
+ CHECK_CLOSE (-offset, dJointGetPistonPosition (jId), 1e-4);
+
+ dBodySetPosition (bId2, 0, 0, 0);
+ CHECK_CLOSE (0.0, dJointGetPistonPosition (jId), 1e-4);
+ }
+
+
+ // Only body 1
+ // The body are positionned at (0, 0, 0), with no rotation
+ // The joint is a Piston Joint
+ // Axis is along the X axis
+ // Anchor at (0, 0, 0)
+ struct Fixture_dxJointPiston_B1_At_Zero_Axis_Along_X
+ {
+ Fixture_dxJointPiston_B1_At_Zero_Axis_Along_X()
+ {
+ wId = dWorldCreate();
+
+ bId1 = dBodyCreate (wId);
+ dBodySetPosition (bId1, 0, 0, 0);
+
+ jId = dJointCreatePiston (wId, 0);
+ joint = (dxJointPiston*) jId;
+
+
+ dJointAttach (jId, bId1, NULL);
+
+ dJointSetPistonAxis (jId, axis[0], axis[1], axis[2]);
+ }
+
+ ~Fixture_dxJointPiston_B1_At_Zero_Axis_Along_X()
+ {
+ dWorldDestroy (wId);
+ }
+
+ dWorldID wId;
+
+ dBodyID bId1;
+
+ dJointID jId;
+ dxJointPiston* joint;
+
+ static const dVector3 axis;
+
+ static const dReal offset;
+ };
+ const dVector3 Fixture_dxJointPiston_B1_At_Zero_Axis_Along_X::axis =
+ {
+ 1, 0, 0
+ };
+ const dReal Fixture_dxJointPiston_B1_At_Zero_Axis_Along_X::offset = REAL (3.1);
+
+ // Move 1st body offset unit in the X direction
+ //
+ // X-------> X---------> Axis -->
+ // B1 => B1
+ //
+ // Start with a Offset of offset unit
+ //
+ // X-------> X---------> Axis -->
+ // B1 => B1
+ TEST_FIXTURE (Fixture_dxJointPiston_B1_At_Zero_Axis_Along_X,
+ test_dJointSetPistonAxisOffset_B1_OffsetUnit)
+ {
+ dJointSetPistonAnchor (jId, 0, 0, 0);
+
+ CHECK_CLOSE (0.0, dJointGetPistonPosition (jId), 1e-4);
+
+ dBodySetPosition (bId1, offset, 0, 0);
+
+ CHECK_CLOSE (offset, dJointGetPistonPosition (jId), 1e-4);
+
+ dJointSetPistonAnchorOffset (jId, 0, 0, 0,
+ offset*axis[0],offset*axis[1],offset*axis[2]);
+ CHECK_CLOSE (offset, dJointGetPistonPosition (jId), 1e-4);
+
+ dBodySetPosition (bId1, 0, 0, 0);
+ CHECK_CLOSE (0.0, dJointGetPistonPosition (jId), 1e-4);
+ }
+
+ // Move 1st body offset unit in the opposite X direction
+ //
+ // X-------> X---------> Axis -->
+ // B1 => B1
+ //
+ // Start with a Offset of -offset unit
+ //
+ // X-------> X---------> Axis -->
+ // B1 => B1
+ TEST_FIXTURE (Fixture_dxJointPiston_B1_At_Zero_Axis_Along_X,
+ test_dJointSetPistonAxisOffset_B1_Minus_OffsetUnit)
+ {
+ dJointSetPistonAnchor (jId, 0, 0, 0);
+
+ CHECK_CLOSE (0.0, dJointGetPistonPosition (jId), 1e-4);
+
+ dBodySetPosition (bId1, -offset, 0, 0);
+
+ CHECK_CLOSE (-offset, dJointGetPistonPosition (jId), 1e-4);
+
+ dJointSetPistonAnchorOffset (jId, 0, 0, 0,
+ -offset*axis[0],-offset*axis[1],-offset*axis[2]);
+ CHECK_CLOSE (-offset, dJointGetPistonPosition (jId), 1e-4);
+
+ dBodySetPosition (bId1, 0, 0, 0);
+ CHECK_CLOSE (0.0, dJointGetPistonPosition (jId), 1e-4);
+ }
+
+ // Only body 1
+ // The body are positionned at (0, 0, 0), with no rotation
+ // The joint is a Piston Joint
+ // Axis is in the oppsite X axis
+ // Anchor at (0, 0, 0)
+ struct Fixture_dxJointPiston_B1_At_Zero_Axis_Inverse_of_X
+ {
+ Fixture_dxJointPiston_B1_At_Zero_Axis_Inverse_of_X()
+ {
+ wId = dWorldCreate();
+
+ bId1 = dBodyCreate (wId);
+ dBodySetPosition (bId1, 0, 0, 0);
+
+ jId = dJointCreatePiston (wId, 0);
+ joint = (dxJointPiston*) jId;
+
+
+ dJointAttach (jId, bId1, NULL);
+
+ dJointSetPistonAxis (jId, axis[0], axis[1], axis[2]);
+ }
+
+ ~Fixture_dxJointPiston_B1_At_Zero_Axis_Inverse_of_X()
+ {
+ dWorldDestroy (wId);
+ }
+
+ dWorldID wId;
+
+ dBodyID bId1;
+
+ dJointID jId;
+ dxJointPiston* joint;
+
+ static const dVector3 axis;
+
+ static const dReal offset;
+ };
+ const dVector3 Fixture_dxJointPiston_B1_At_Zero_Axis_Inverse_of_X::axis =
+ {
+ -1, 0, 0
+ };
+ const dReal Fixture_dxJointPiston_B1_At_Zero_Axis_Inverse_of_X::offset = REAL (3.1);
+
+ // Move 1st body offset unit in the X direction
+ //
+ // X-------> X---------> <--- Axis
+ // B1 => B1
+ //
+ // Start with a Offset of offset unit
+ //
+ // X-------> X---------> <--- Axis
+ // B1 => B1
+ TEST_FIXTURE (Fixture_dxJointPiston_B1_At_Zero_Axis_Inverse_of_X,
+ test_dJointSetPistonAxisOffset_B1_OffsetUnit)
+ {
+ dJointSetPistonAnchor (jId, 0, 0, 0);
+
+ CHECK_CLOSE (0.0, dJointGetPistonPosition (jId), 1e-4);
+
+ dBodySetPosition (bId1, offset, 0, 0);
+
+ CHECK_CLOSE (-offset, dJointGetPistonPosition (jId), 1e-4);
+
+ dJointSetPistonAnchorOffset (jId, 0, 0, 0,
+ -offset*axis[0],-offset*axis[1],-offset*axis[2]);
+ CHECK_CLOSE (-offset, dJointGetPistonPosition (jId), 1e-4);
+
+ dBodySetPosition (bId1, 0, 0, 0);
+ CHECK_CLOSE (0.0, dJointGetPistonPosition (jId), 1e-4);
+ }
+
+ // Move 1st body offset unit in the opposite X direction
+ //
+ // X-------> X---------> <--- Axis
+ // B1 => B1
+ //
+ // Start with a Offset of -offset unit
+ //
+ // X-------> X---------> <--- Axis
+ // B1 => B1
+ TEST_FIXTURE (Fixture_dxJointPiston_B1_At_Zero_Axis_Inverse_of_X,
+ test_dJointSetPistonAxisOffset_B1_Minus_OffsetUnit)
+ {
+ dJointSetPistonAnchor (jId, 0, 0, 0);
+
+ CHECK_CLOSE (0.0, dJointGetPistonPosition (jId), 1e-4);
+
+ dBodySetPosition (bId1, -offset, 0, 0);
+
+ CHECK_CLOSE (offset, dJointGetPistonPosition (jId), 1e-4);
+
+ dJointSetPistonAnchorOffset (jId, 0, 0, 0,
+ offset*axis[0],offset*axis[1],offset*axis[2]);
+ CHECK_CLOSE (offset, dJointGetPistonPosition (jId), 1e-4);
+
+ dBodySetPosition (bId1, 0, 0, 0);
+ CHECK_CLOSE (0.0, dJointGetPistonPosition (jId), 1e-4);
+ }
+
+
+
+
+
+
+
+
+
+ // Only body 2
+ // The body are positionned at (0, 0, 0), with no rotation
+ // The joint is a Piston Joint
+ // Axis is along the X axis
+ // Anchor at (0, 0, 0)
+ struct Fixture_dxJointPiston_B2_At_Zero_Axis_Along_X
+ {
+ Fixture_dxJointPiston_B2_At_Zero_Axis_Along_X()
+ {
+ wId = dWorldCreate();
+
+ bId2 = dBodyCreate (wId);
+ dBodySetPosition (bId2, 0, 0, 0);
+
+ jId = dJointCreatePiston (wId, 0);
+ joint = (dxJointPiston*) jId;
+
+
+ dJointAttach (jId, NULL, bId2);
+
+ dJointSetPistonAxis (jId, axis[0], axis[1], axis[2]);
+ }
+
+ ~Fixture_dxJointPiston_B2_At_Zero_Axis_Along_X()
+ {
+ dWorldDestroy (wId);
+ }
+
+ dWorldID wId;
+
+ dBodyID bId2;
+
+ dJointID jId;
+ dxJointPiston* joint;
+
+ static const dVector3 axis;
+
+ static const dReal offset;
+ };
+ const dVector3 Fixture_dxJointPiston_B2_At_Zero_Axis_Along_X::axis =
+ {
+ 1, 0, 0
+ };
+ const dReal Fixture_dxJointPiston_B2_At_Zero_Axis_Along_X::offset = REAL (3.1);
+
+ // Move 2nd body offset unit in the X direction
+ //
+ // X-------> X---------> Axis -->
+ // B2 => B2
+ //
+ // Start with a Offset of offset unit
+ //
+ // X-------> X---------> Axis -->
+ // B2 => B2
+ TEST_FIXTURE (Fixture_dxJointPiston_B2_At_Zero_Axis_Along_X,
+ test_dJointSetPistonAxisOffset_B2_OffsetUnit)
+ {
+ dJointSetPistonAnchor (jId, 0, 0, 0);
+
+ CHECK_CLOSE (0.0, dJointGetPistonPosition (jId), 1e-4);
+
+ dBodySetPosition (bId2, offset, 0, 0);
+
+ CHECK_CLOSE (-offset, dJointGetPistonPosition (jId), 1e-4);
+
+ dJointSetPistonAnchorOffset (jId, 0, 0, 0,
+ -offset*axis[0],-offset*axis[1],-offset*axis[2]);
+ CHECK_CLOSE (-offset, dJointGetPistonPosition (jId), 1e-4);
+
+ dBodySetPosition (bId2, 0, 0, 0);
+ CHECK_CLOSE (0.0, dJointGetPistonPosition (jId), 1e-4);
+ }
+
+ // Move 2nd body offset unit in the opposite X direction
+ //
+ // X-------> X---------> Axis -->
+ // B2 => B2
+ //
+ // Start with a Offset of -offset unit
+ //
+ // X-------> X---------> Axis -->
+ // B2 => B2
+ TEST_FIXTURE (Fixture_dxJointPiston_B2_At_Zero_Axis_Along_X,
+ test_dJointSetPistonAxisOffset_B2_Minus_OffsetUnit)
+ {
+ dJointSetPistonAnchor (jId, 0, 0, 0);
+
+ CHECK_CLOSE (0.0, dJointGetPistonPosition (jId), 1e-4);
+
+ dBodySetPosition (bId2, -offset, 0, 0);
+
+ CHECK_CLOSE (offset, dJointGetPistonPosition (jId), 1e-4);
+
+ dJointSetPistonAnchorOffset (jId, 0, 0, 0,
+ offset*axis[0],offset*axis[1],offset*axis[2]);
+ CHECK_CLOSE (offset, dJointGetPistonPosition (jId), 1e-4);
+
+ dBodySetPosition (bId2, 0, 0, 0);
+ CHECK_CLOSE (0.0, dJointGetPistonPosition (jId), 1e-4);
+ }
+
+ // Only body 2
+ // The body are positionned at (0, 0, 0), with no rotation
+ // The joint is a Piston Joint
+ // Axis is in the opposite X axis
+ // Anchor at (0, 0, 0)
+ struct Fixture_dxJointPiston_B2_At_Zero_Axis_Inverse_of_X
+ {
+ Fixture_dxJointPiston_B2_At_Zero_Axis_Inverse_of_X()
+ {
+ wId = dWorldCreate();
+
+ bId2 = dBodyCreate (wId);
+ dBodySetPosition (bId2, 0, 0, 0);
+
+ jId = dJointCreatePiston (wId, 0);
+ joint = (dxJointPiston*) jId;
+
+
+ dJointAttach (jId, NULL, bId2);
+
+ dJointSetPistonAxis (jId, axis[0], axis[1], axis[2]);
+ }
+
+ ~Fixture_dxJointPiston_B2_At_Zero_Axis_Inverse_of_X()
+ {
+ dWorldDestroy (wId);
+ }
+
+ dWorldID wId;
+
+ dBodyID bId2;
+
+ dJointID jId;
+ dxJointPiston* joint;
+
+ static const dVector3 axis;
+
+ static const dReal offset;
+ };
+ const dVector3 Fixture_dxJointPiston_B2_At_Zero_Axis_Inverse_of_X::axis =
+ {
+ -1, 0, 0
+ };
+ const dReal Fixture_dxJointPiston_B2_At_Zero_Axis_Inverse_of_X::offset = REAL (3.1);
+
+ // Move 2nd body offset unit in the X direction
+ //
+ // X-------> X---------> <--- Axis
+ // B2 => B2
+ //
+ // Start with a Offset of offset unit
+ //
+ // X-------> X---------> <--- Axis
+ // B2 => B2
+ TEST_FIXTURE (Fixture_dxJointPiston_B2_At_Zero_Axis_Inverse_of_X,
+ test_dJointSetPistonAxisOffset_B2_OffsetUnit)
+ {
+ dJointSetPistonAnchor (jId, 0, 0, 0);
+
+ CHECK_CLOSE (0.0, dJointGetPistonPosition (jId), 1e-4);
+
+ dBodySetPosition (bId2, offset, 0, 0);
+
+ CHECK_CLOSE (offset, dJointGetPistonPosition (jId), 1e-4);
+
+ dJointSetPistonAnchorOffset (jId, 0, 0, 0,
+ offset*axis[0],offset*axis[1],offset*axis[2]);
+ CHECK_CLOSE (offset, dJointGetPistonPosition (jId), 1e-4);
+
+ dBodySetPosition (bId2, 0, 0, 0);
+ CHECK_CLOSE (0.0, dJointGetPistonPosition (jId), 1e-4);
+ #if 0 // another deprecated warning test?
+ dJointSetPistonAxisDelta (jId, 1, 0, 0, 0, 0, 0);
+ #endif
+ }
+
+ // Move 1st body offset unit in the opposite X direction
+ //
+ // X-------> X---------> <--- Axis
+ // B2 => B2
+ //
+ // Start with a Offset of -offset unit
+ //
+ // X-------> X---------> <--- Axis
+ // B2 => B2
+ TEST_FIXTURE (Fixture_dxJointPiston_B2_At_Zero_Axis_Inverse_of_X,
+ test_dJointSetPistonAxisOffset_B2_Minus_OffsetUnit)
+ {
+ dJointSetPistonAnchor (jId, 0, 0, 0);
+
+ CHECK_CLOSE (0.0, dJointGetPistonPosition (jId), 1e-4);
+
+ dBodySetPosition (bId2, -offset, 0, 0);
+
+ CHECK_CLOSE (-offset, dJointGetPistonPosition (jId), 1e-4);
+
+ dJointSetPistonAnchorOffset (jId, 0, 0, 0,
+ -offset*axis[0],-offset*axis[1],-offset*axis[2]);
+ CHECK_CLOSE (-offset, dJointGetPistonPosition (jId), 1e-4);
+
+ dBodySetPosition (bId2, 0, 0, 0);
+ CHECK_CLOSE (0.0, dJointGetPistonPosition (jId), 1e-4);
+ }
+
+ // ==========================================================================
+ // Test Position Rate
+ // ==========================================================================
+
+ // Apply force on 1st body in the X direction also the Axis direction
+ //
+ // X-------> X---------> Axis -->
+ // B1 F-> => B1
+ // B2 B2
+ TEST_FIXTURE (Fixture_dxJointPiston_B1_and_B2_At_Zero_Axis_Along_X,
+ test_dJointSetPistonPositionRate_Force_Along_Axis_on_B1)
+ {
+ CHECK_CLOSE (0.0, dJointGetPistonPosition (jId), 1e-4);
+ CHECK_CLOSE (0.0, dJointGetPistonPositionRate (jId), 1e-4);
+
+ dBodyAddForce (bId1, 1.0, 0, 0);
+ dWorldQuickStep (wId, 1.0);
+
+ CHECK_CLOSE (1, dJointGetPistonPositionRate (jId), 1e-4);
+ }
+
+ // Apply force on 1st body in the inverse X direction
+ //
+ // X-------> X---------> Axis -->
+ // B1 <-F => B1
+ // B2 B2
+ TEST_FIXTURE (Fixture_dxJointPiston_B1_and_B2_At_Zero_Axis_Along_X,
+ test_dJointSetPistonPositionRate_Force_Inverse_of_Axis_on_B1)
+ {
+ CHECK_CLOSE (0.0, dJointGetPistonPosition (jId), 1e-4);
+ CHECK_CLOSE (0.0, dJointGetPistonPositionRate (jId), 1e-4);
+
+ dBodyAddForce (bId1, -1.0, 0, 0);
+ dWorldQuickStep (wId, 1.0);
+
+ CHECK_CLOSE (-1, dJointGetPistonPositionRate (jId), 1e-4);
+ }
+
+
+ // Apply force on 1st body in the X direction also the Axis direction
+ //
+ // X-------> X---------> <-- Axis
+ // B1 F-> => B1
+ // B2 B2
+ TEST_FIXTURE (Fixture_dxJointPiston_B1_and_B2_At_Zero_Axis_Inverse_of_X,
+ test_dJointSetPistonPositionRate_Force_Inverse_Axis_on_B1)
+ {
+ CHECK_CLOSE (0.0, dJointGetPistonPosition (jId), 1e-4);
+ CHECK_CLOSE (0.0, dJointGetPistonPositionRate (jId), 1e-4);
+
+ dBodyAddForce (bId1, 1.0, 0, 0);
+ dWorldQuickStep (wId, 1.0);
+
+ CHECK_CLOSE (-1, dJointGetPistonPositionRate (jId), 1e-4);
+ }
+
+ // Apply force on 1st body in the inverse X direction
+ //
+ // X-------> X---------> <-- Axis
+ // B1 <-F => B1
+ // B2 B2
+ TEST_FIXTURE (Fixture_dxJointPiston_B1_and_B2_At_Zero_Axis_Inverse_of_X,
+ test_dJointSetPistonPositionRate_Force_Along_of_Axis_on_B1)
+ {
+ CHECK_CLOSE (0.0, dJointGetPistonPosition (jId), 1e-4);
+ CHECK_CLOSE (0.0, dJointGetPistonPositionRate (jId), 1e-4);
+
+ dBodyAddForce (bId1, -1.0, 0, 0);
+ dWorldQuickStep (wId, 1.0);
+
+ CHECK_CLOSE (1, dJointGetPistonPositionRate (jId), 1e-4);
+ }
+
+ // Apply force on 1st body in the X direction also the Axis direction
+ //
+ // X-------> X---------> Axis -->
+ // B1 => B1
+ // B2 F-> B2
+ TEST_FIXTURE (Fixture_dxJointPiston_B1_and_B2_At_Zero_Axis_Along_X,
+ test_dJointSetPistonPositionRate_Force_Along_Axis_on_B2)
+ {
+ CHECK_CLOSE (0.0, dJointGetPistonPosition (jId), 1e-4);
+ CHECK_CLOSE (0.0, dJointGetPistonPositionRate (jId), 1e-4);
+
+ dBodyAddForce (bId2, 1.0, 0, 0);
+ dWorldQuickStep (wId, 1.0);
+
+ CHECK_CLOSE (-1, dJointGetPistonPositionRate (jId), 1e-4);
+ }
+
+ // Apply force on 1st body in the inverse X direction
+ //
+ // X-------> X---------> Axis -->
+ // B1 => B1
+ // B2 <-F B2
+ TEST_FIXTURE (Fixture_dxJointPiston_B1_and_B2_At_Zero_Axis_Along_X,
+ test_dJointSetPistonPositionRate_Force_Inverse_of_Axis_on_B2)
+ {
+ CHECK_CLOSE (0.0, dJointGetPistonPosition (jId), 1e-4);
+ CHECK_CLOSE (0.0, dJointGetPistonPositionRate (jId), 1e-4);
+
+ dBodyAddForce (bId2, -1.0, 0, 0);
+ dWorldQuickStep (wId, 1.0);
+
+ CHECK_CLOSE (1, dJointGetPistonPositionRate (jId), 1e-4);
+ }
+
+
+ // Apply force on 1st body in the X direction also the Axis direction
+ //
+ // X-------> X---------> <-- Axis
+ // B1 => B1
+ // B2 F-> B2
+ TEST_FIXTURE (Fixture_dxJointPiston_B1_and_B2_At_Zero_Axis_Inverse_of_X,
+ test_dJointSetPistonPositionRate_Force_Inverse_Axis_on_B2)
+ {
+ CHECK_CLOSE (0.0, dJointGetPistonPosition (jId), 1e-4);
+ CHECK_CLOSE (0.0, dJointGetPistonPositionRate (jId), 1e-4);
+
+ dBodyAddForce (bId2, 1.0, 0, 0);
+ dWorldQuickStep (wId, 1.0);
+
+ CHECK_CLOSE (1, dJointGetPistonPositionRate (jId), 1e-4);
+ }
+
+ // Apply force on 1st body in the inverse X direction
+ //
+ // X-------> X---------> <-- Axis
+ // B1 => B1
+ // B2 <-F B2
+ TEST_FIXTURE (Fixture_dxJointPiston_B1_and_B2_At_Zero_Axis_Inverse_of_X,
+ test_dJointSetPistonPositionRate_Force_Along_of_Axis_on_B2)
+ {
+ CHECK_CLOSE (0.0, dJointGetPistonPosition (jId), 1e-4);
+ CHECK_CLOSE (0.0, dJointGetPistonPositionRate (jId), 1e-4);
+
+ dBodyAddForce (bId2, -1.0, 0, 0);
+ dWorldQuickStep (wId, 1.0);
+
+ CHECK_CLOSE (-1, dJointGetPistonPositionRate (jId), 1e-4);
+ }
+
+
+
+ // Apply force on 1st body in the X direction also the Axis direction
+ //
+ // X-------> X---------> Axis -->
+ // B1 F-> => B1
+ TEST_FIXTURE (Fixture_dxJointPiston_B1_At_Zero_Axis_Along_X,
+ test_dJointSetPistonPositionRate_Force_Along_Axis_on_B1)
+ {
+ CHECK_CLOSE (0.0, dJointGetPistonPosition (jId), 1e-4);
+ CHECK_CLOSE (0.0, dJointGetPistonPositionRate (jId), 1e-4);
+
+ dBodyAddForce (bId1, 1.0, 0, 0);
+ dWorldQuickStep (wId, 1.0);
+
+ CHECK_CLOSE (1, dJointGetPistonPositionRate (jId), 1e-4);
+ }
+
+ // Apply force on 1st body in the inverse X direction
+ //
+ // X-------> X---------> Axis -->
+ // B1 <-F => B1
+ TEST_FIXTURE (Fixture_dxJointPiston_B1_At_Zero_Axis_Along_X,
+ test_dJointSetPistonPositionRate_Force_Inverse_of_Axis_on_B1)
+ {
+ CHECK_CLOSE (0.0, dJointGetPistonPosition (jId), 1e-4);
+ CHECK_CLOSE (0.0, dJointGetPistonPositionRate (jId), 1e-4);
+
+ dBodyAddForce (bId1, -1.0, 0, 0);
+ dWorldQuickStep (wId, 1.0);
+
+ CHECK_CLOSE (-1, dJointGetPistonPositionRate (jId), 1e-4);
+ }
+
+
+ // Apply force on 1st body in the X direction also the Axis direction
+ //
+ // X-------> X---------> <-- Axis
+ // B1 F-> => B1
+ TEST_FIXTURE (Fixture_dxJointPiston_B1_At_Zero_Axis_Inverse_of_X,
+ test_dJointSetPistonPositionRate_Force_Inverse_Axis_on_B1)
+ {
+ CHECK_CLOSE (0.0, dJointGetPistonPosition (jId), 1e-4);
+ CHECK_CLOSE (0.0, dJointGetPistonPositionRate (jId), 1e-4);
+
+ dBodyAddForce (bId1, 1.0, 0, 0);
+ dWorldQuickStep (wId, 1.0);
+
+ CHECK_CLOSE (-1, dJointGetPistonPositionRate (jId), 1e-4);
+ }
+
+ // Apply force on 1st body in the inverse X direction
+ //
+ // X-------> X---------> <-- Axis
+ // B1 <-F => B1
+ TEST_FIXTURE (Fixture_dxJointPiston_B1_At_Zero_Axis_Inverse_of_X,
+ test_dJointSetPistonPositionRate_Force_Along_of_Axis_on_B1)
+ {
+ CHECK_CLOSE (0.0, dJointGetPistonPosition (jId), 1e-4);
+ CHECK_CLOSE (0.0, dJointGetPistonPositionRate (jId), 1e-4);
+
+ dBodyAddForce (bId1, -1.0, 0, 0);
+ dWorldQuickStep (wId, 1.0);
+
+ CHECK_CLOSE (1, dJointGetPistonPositionRate (jId), 1e-4);
+ }
+
+
+ // Apply force on body 2 in the X direction also the Axis direction
+ //
+ // X-------> X---------> Axis -->
+ // B2 F-> B2
+ TEST_FIXTURE (Fixture_dxJointPiston_B2_At_Zero_Axis_Along_X,
+ test_dJointSetPistonPositionRate_Force_Along_Axis_on_B2)
+ {
+ CHECK_CLOSE (0.0, dJointGetPistonPosition (jId), 1e-4);
+ CHECK_CLOSE (0.0, dJointGetPistonPositionRate (jId), 1e-4);
+
+ dBodyAddForce (bId2, 1.0, 0, 0);
+ dWorldQuickStep (wId, 1.0);
+
+ CHECK_CLOSE (-1, dJointGetPistonPositionRate (jId), 1e-4);
+ }
+
+ // Apply force on body 2 in the inverse X direction
+ //
+ // X-------> X---------> Axis -->
+ // B2 <-F B2
+ TEST_FIXTURE (Fixture_dxJointPiston_B2_At_Zero_Axis_Along_X,
+ test_dJointSetPistonPositionRate_Force_Inverse_of_Axis_on_B2)
+ {
+ CHECK_CLOSE (0.0, dJointGetPistonPosition (jId), 1e-4);
+ CHECK_CLOSE (0.0, dJointGetPistonPositionRate (jId), 1e-4);
+
+ dBodyAddForce (bId2, -1.0, 0, 0);
+ dWorldQuickStep (wId, 1.0);
+
+ CHECK_CLOSE (1, dJointGetPistonPositionRate (jId), 1e-4);
+ }
+
+
+ // Apply force on body 2 in the X direction also the Axis direction
+ //
+ // X-------> X---------> <-- Axis
+ // B2 F-> B2
+ TEST_FIXTURE (Fixture_dxJointPiston_B2_At_Zero_Axis_Inverse_of_X,
+ test_dJointSetPistonPositionRate_Force_Inverse_Axis_on_B2)
+ {
+ CHECK_CLOSE (0.0, dJointGetPistonPosition (jId), 1e-4);
+ CHECK_CLOSE (0.0, dJointGetPistonPositionRate (jId), 1e-4);
+
+ dBodyAddForce (bId2, 1.0, 0, 0);
+ dWorldQuickStep (wId, 1.0);
+
+ CHECK_CLOSE (1, dJointGetPistonPositionRate (jId), 1e-4);
+ }
+
+ // Apply force on body 2 in the inverse X direction
+ //
+ // X-------> X---------> <-- Axis
+ // B2 <-F B2
+ TEST_FIXTURE (Fixture_dxJointPiston_B2_At_Zero_Axis_Inverse_of_X,
+ test_dJointSetPistonPositionRate_Force_Along_of_Axis_on_B2)
+ {
+ CHECK_CLOSE (0.0, dJointGetPistonPosition (jId), 1e-4);
+ CHECK_CLOSE (0.0, dJointGetPistonPositionRate (jId), 1e-4);
+
+ dBodyAddForce (bId2, -1.0, 0, 0);
+ dWorldQuickStep (wId, 1.0);
+
+ CHECK_CLOSE (-1, dJointGetPistonPositionRate (jId), 1e-4);
+ }
+
+
+
+
+// Create 2 bodies attached by a Piston joint
+ // Axis is along the X axis (Default value
+ // Anchor at (0, 0, 0) (Default value)
+ //
+ // ^Y
+ // |
+ // * Body2
+ // |
+ // |
+ // Body1 |
+ // * Z-------->
+ struct dxJointPiston_Test_Initialization
+ {
+ dxJointPiston_Test_Initialization()
+ {
+ wId = dWorldCreate();
+
+ // Remove gravity to have the only force be the force of the joint
+ dWorldSetGravity(wId, 0,0,0);
+
+ for (int j=0; j<2; ++j)
+ {
+ bId[j][0] = dBodyCreate (wId);
+ dBodySetPosition (bId[j][0], -1, -2, -3);
+
+ bId[j][1] = dBodyCreate (wId);
+ dBodySetPosition (bId[j][1], 11, 22, 33);
+
+
+ dMatrix3 R;
+ dVector3 axis; // Random axis
+
+ axis[0] = REAL(0.53);
+ axis[1] = -REAL(0.71);
+ axis[2] = REAL(0.43);
+ dNormalize3(axis);
+ dRFromAxisAndAngle (R, axis[0], axis[1], axis[2],
+ REAL(0.47123)); // 27deg
+ dBodySetRotation (bId[j][0], R);
+
+
+ axis[0] = REAL(1.2);
+ axis[1] = REAL(0.87);
+ axis[2] = -REAL(0.33);
+ dNormalize3(axis);
+ dRFromAxisAndAngle (R, axis[0], axis[1], axis[2],
+ REAL(0.47123)); // 27deg
+ dBodySetRotation (bId[j][1], R);
+
+ jId[j] = dJointCreatePiston (wId, 0);
+ dJointAttach (jId[j], bId[j][0], bId[j][1]);
+ }
+ }
+
+ ~dxJointPiston_Test_Initialization()
+ {
+ dWorldDestroy (wId);
+ }
+
+ dWorldID wId;
+
+ dBodyID bId[2][2];
+
+
+ dJointID jId[2];
+
+ };
+
+
+ // Test if setting a Piston with its default values
+ // will behave the same as a default Piston joint
+ TEST_FIXTURE (dxJointPiston_Test_Initialization,
+ test_Piston_Initialization)
+ {
+ using namespace std;
+
+ dVector3 axis;
+ dJointGetPistonAxis(jId[1], axis);
+ dJointSetPistonAxis(jId[1], axis[0], axis[1], axis[2]);
+
+
+ dVector3 anchor;
+ dJointGetPistonAnchor(jId[1], anchor);
+ dJointSetPistonAnchor(jId[1], anchor[0], anchor[1], anchor[2]);
+
+
+ for (int b=0; b<2; ++b)
+ {
+ // Compare body b of the first joint with its equivalent on the
+ // second joint
+ const dReal *qA = dBodyGetQuaternion(bId[0][b]);
+ const dReal *qB = dBodyGetQuaternion(bId[1][b]);
+ CHECK_CLOSE (qA[0], qB[0], 1e-6);
+ CHECK_CLOSE (qA[1], qB[1], 1e-6);
+ CHECK_CLOSE (qA[2], qB[2], 1e-6);
+ CHECK_CLOSE (qA[3], qB[3], 1e-6);
+ }
+
+ dWorldStep (wId,0.5);
+ dWorldStep (wId,0.5);
+ dWorldStep (wId,0.5);
+ dWorldStep (wId,0.5);
+
+ for (int b=0; b<2; ++b)
+ {
+ // Compare body b of the first joint with its equivalent on the
+ // second joint
+ const dReal *qA = dBodyGetQuaternion(bId[0][b]);
+ const dReal *qB = dBodyGetQuaternion(bId[1][b]);
+ CHECK_CLOSE (qA[0], qB[0], 1e-6);
+ CHECK_CLOSE (qA[1], qB[1], 1e-6);
+ CHECK_CLOSE (qA[2], qB[2], 1e-6);
+ CHECK_CLOSE (qA[3], qB[3], 1e-6);
+
+
+ const dReal *posA = dBodyGetPosition(bId[0][b]);
+ const dReal *posB = dBodyGetPosition(bId[1][b]);
+ CHECK_CLOSE (posA[0], posB[0], 1e-6);
+ CHECK_CLOSE (posA[1], posB[1], 1e-6);
+ CHECK_CLOSE (posA[2], posB[2], 1e-6);
+ CHECK_CLOSE (posA[3], posB[3], 1e-6);
+ }
+
+
+ }
+
+
+
+
+
+ // Compare only one body to 2 bodies with one fixed.
+ //
+ // The body are positionned at (0, 0, 0), with no rotation
+ // The joint is a Piston Joint
+ // Axis is along the X axis
+ // Anchor at (0, 0, 0)
+ struct Fixture_dxJointPiston_Compare_Body_At_Zero_Axis_Along_X
+ {
+ Fixture_dxJointPiston_Compare_Body_At_Zero_Axis_Along_X()
+ {
+ wId = dWorldCreate();
+
+ bId1_12 = dBodyCreate (wId);
+ dBodySetPosition (bId1_12, 0, 0, 0);
+
+ bId2_12 = dBodyCreate (wId);
+ dBodySetPosition (bId2_12, 0, 0, 0);
+ // The force will be added in the function since it is not
+ // always on the same body
+
+ jId_12 = dJointCreatePiston (wId, 0);
+ dJointAttach(jId_12, bId1_12, bId2_12);
+
+ fixed = dJointCreateFixed (wId, 0);
+
+
+
+ bId = dBodyCreate (wId);
+ dBodySetPosition (bId, 0, 0, 0);
+
+ dBodyAddForce (bId, 4, 0, 0);
+
+ jId = dJointCreatePiston (wId, 0);
+ }
+
+ ~Fixture_dxJointPiston_Compare_Body_At_Zero_Axis_Along_X()
+ {
+ dWorldDestroy (wId);
+ }
+
+ dWorldID wId;
+
+ dBodyID bId1_12;
+ dBodyID bId2_12;
+
+ dJointID jId_12; // Joint with 2 bodies
+
+ dJointID fixed;
+
+
+
+ dBodyID bId;
+ dJointID jId; // Joint with one body
+ };
+
+ // This test compare the result of a slider with 2 bodies where body body 2 is
+ // fixed to the world to a slider with only one body at position 1.
+ //
+ // Test the limits [-1, 0.25] when only one body at is attached to the joint
+ // using dJointAttache(jId, bId, 0);
+ //
+ TEST_FIXTURE(Fixture_dxJointPiston_Compare_Body_At_Zero_Axis_Along_X,
+ test_Limit_minus1_025_One_Body_on_left)
+ {
+ dBodyAddForce (bId1_12, 4, 0, 0);
+
+ dJointAttach(jId_12, bId1_12, bId2_12);
+ dJointSetPistonParam(jId_12, dParamLoStop, -1);
+ dJointSetPistonParam(jId_12, dParamHiStop, 0.25);
+
+ dJointAttach(fixed, 0, bId2_12);
+ dJointSetFixed(fixed);
+
+ dJointAttach(jId, bId, 0);
+ dJointSetPistonParam(jId, dParamLoStop, -1);
+ dJointSetPistonParam(jId, dParamHiStop, 0.25);
+
+
+ for (int i=0; i<50; ++i)
+ dWorldStep(wId, 1.0);
+
+
+ const dReal *pos1_12 = dBodyGetPosition(bId1_12);
+ const dReal *pos = dBodyGetPosition(bId);
+
+ CHECK_CLOSE (pos1_12[0], pos[0], 1e-2);
+ CHECK_CLOSE (pos1_12[1], pos[1], 1e-2);
+ CHECK_CLOSE (pos1_12[2], pos[2], 1e-2);
+
+ const dReal *q1_12 = dBodyGetQuaternion(bId1_12);
+ const dReal *q = dBodyGetQuaternion(bId);
+
+ CHECK_CLOSE (q1_12[0], q[0], 1e-4);
+ CHECK_CLOSE (q1_12[1], q[1], 1e-4);
+ CHECK_CLOSE (q1_12[2], q[2], 1e-4);
+ CHECK_CLOSE (q1_12[3], q[3], 1e-4);
+ }
+
+
+
+ // This test compare the result of a slider with 2 bodies where body body 1 is
+ // fixed to the world to a slider with only one body at position 2.
+ //
+ // Test the limits [-1, 0.25] when only one body at is attached to the joint
+ // using dJointAttache(jId, 0, bId);
+ //
+ TEST_FIXTURE(Fixture_dxJointPiston_Compare_Body_At_Zero_Axis_Along_X,
+ test_Limit_minus1_025_One_Body_on_right)
+ {
+ dBodyAddForce (bId2_12, 4, 0, 0);
+
+ dJointAttach(jId_12, bId1_12, bId2_12);
+ dJointSetPistonParam(jId_12, dParamLoStop, -1);
+ dJointSetPistonParam(jId_12, dParamHiStop, 0.25);
+
+ dJointAttach(fixed, bId1_12, 0);
+ dJointSetFixed(fixed);
+
+
+ dJointAttach(jId, 0, bId);
+ dJointSetPistonParam(jId, dParamLoStop, -1);
+ dJointSetPistonParam(jId, dParamHiStop, 0.25);
+
+ for (int i=0; i<50; ++i)
+ dWorldStep(wId, 1.0);
+
+
+ const dReal *pos2_12 = dBodyGetPosition(bId2_12);
+ const dReal *pos = dBodyGetPosition(bId);
+
+ CHECK_CLOSE (pos2_12[0], pos[0], 1e-2);
+ CHECK_CLOSE (pos2_12[1], pos[1], 1e-2);
+ CHECK_CLOSE (pos2_12[2], pos[2], 1e-2);
+
+
+ const dReal *q2_12 = dBodyGetQuaternion(bId2_12);
+ const dReal *q = dBodyGetQuaternion(bId);
+
+ CHECK_CLOSE (q2_12[0], q[0], 1e-4);
+ CHECK_CLOSE (q2_12[1], q[1], 1e-4);
+ CHECK_CLOSE (q2_12[2], q[2], 1e-4);
+ CHECK_CLOSE (q2_12[3], q[3], 1e-4);
+ }
+
+
+
+ // This test compare the result of a slider with 2 bodies where body body 2 is
+ // fixed to the world to a slider with only one body at position 1.
+ //
+ // Test the limits [0, 0] when only one body at is attached to the joint
+ // using dJointAttache(jId, bId, 0);
+ //
+ // The body should not move since their is no room between the two limits
+ //
+ TEST_FIXTURE(Fixture_dxJointPiston_Compare_Body_At_Zero_Axis_Along_X,
+ test_Limit_0_0_One_Body_on_left)
+ {
+ dBodyAddForce (bId1_12, 4, 0, 0);
+
+ dJointAttach(jId_12, bId1_12, bId2_12);
+ dJointSetPistonParam(jId_12, dParamLoStop, 0);
+ dJointSetPistonParam(jId_12, dParamHiStop, 0);
+
+ dJointAttach(fixed, 0, bId2_12);
+ dJointSetFixed(fixed);
+
+
+ dJointAttach(jId, bId, 0);
+ dJointSetPistonParam(jId, dParamLoStop, 0);
+ dJointSetPistonParam(jId, dParamHiStop, 0);
+
+ for (int i=0; i<500; ++i)
+ dWorldStep(wId, 1.0);
+
+
+ const dReal *pos1_12 = dBodyGetPosition(bId1_12);
+ const dReal *pos = dBodyGetPosition(bId);
+
+ CHECK_CLOSE (pos1_12[0], pos[0], 1e-4);
+ CHECK_CLOSE (pos1_12[1], pos[1], 1e-4);
+ CHECK_CLOSE (pos1_12[2], pos[2], 1e-4);
+
+ CHECK_CLOSE (0, pos[0], 1e-4);
+ CHECK_CLOSE (0, pos[1], 1e-4);
+ CHECK_CLOSE (0, pos[2], 1e-4);
+
+
+ const dReal *q1_12 = dBodyGetQuaternion(bId1_12);
+ const dReal *q = dBodyGetQuaternion(bId);
+
+ CHECK_CLOSE (q1_12[0], q[0], 1e-4);
+ CHECK_CLOSE (q1_12[1], q[1], 1e-4);
+ CHECK_CLOSE (q1_12[2], q[2], 1e-4);
+ CHECK_CLOSE (q1_12[3], q[3], 1e-4);
+ }
+
+
+ // This test compare the result of a slider with 2 bodies where body body 1 is
+ // fixed to the world to a slider with only one body at position 2.
+ //
+ // Test the limits [0, 0] when only one body at is attached to the joint
+ // using dJointAttache(jId, 0, bId);
+ //
+ // The body should not move since their is no room between the two limits
+ //
+ TEST_FIXTURE(Fixture_dxJointPiston_Compare_Body_At_Zero_Axis_Along_X,
+ test_Limit_0_0_One_Body_on_right)
+ {
+ dBodyAddForce (bId2_12, 4, 0, 0);
+
+ dJointAttach(jId_12, bId1_12, bId2_12);
+ dJointSetPistonParam(jId_12, dParamLoStop, 0);
+ dJointSetPistonParam(jId_12, dParamHiStop, 0);
+
+ dJointAttach(fixed, bId1_12, 0);
+ dJointSetFixed(fixed);
+
+
+ dJointAttach(jId, 0, bId);
+ dJointSetPistonParam(jId, dParamLoStop, 0);
+ dJointSetPistonParam(jId, dParamHiStop, 0);
+
+ for (int i=0; i<500; ++i)
+ dWorldStep(wId, 1.0);
+
+ const dReal *pos2_12 = dBodyGetPosition(bId2_12);
+ const dReal *pos = dBodyGetPosition(bId);
+
+ CHECK_CLOSE (pos2_12[0], pos[0], 1e-4);
+ CHECK_CLOSE (pos2_12[1], pos[1], 1e-4);
+ CHECK_CLOSE (pos2_12[2], pos[2], 1e-4);
+
+ CHECK_CLOSE (0, pos[0], 1e-4);
+ CHECK_CLOSE (0, pos[1], 1e-4);
+ CHECK_CLOSE (0, pos[2], 1e-4);
+
+
+ const dReal *q2_12 = dBodyGetQuaternion(bId2_12);
+ const dReal *q = dBodyGetQuaternion(bId);
+
+ CHECK_CLOSE (q2_12[0], q[0], 1e-4);
+ CHECK_CLOSE (q2_12[1], q[1], 1e-4);
+ CHECK_CLOSE (q2_12[2], q[2], 1e-4);
+ CHECK_CLOSE (q2_12[3], q[3], 1e-4);
+ }
+
+
+} // End of SUITE TestdxJointPiston
diff --git a/libs/ode-0.16.1/tests/joints/pr.cpp b/libs/ode-0.16.1/tests/joints/pr.cpp
new file mode 100644
index 0000000..30995c7
--- /dev/null
+++ b/libs/ode-0.16.1/tests/joints/pr.cpp
@@ -0,0 +1,1160 @@
+/*************************************************************************
+ * *
+ * 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. *
+ * *
+ *************************************************************************/
+//234567890123456789012345678901234567890123456789012345678901234567890123456789
+// 1 2 3 4 5 6 7
+
+////////////////////////////////////////////////////////////////////////////////
+// This file create unit test for some of the functions found in:
+// ode/src/joinst/pr.cpp
+//
+//
+////////////////////////////////////////////////////////////////////////////////
+
+#include <UnitTest++.h>
+#include <ode/ode.h>
+
+#include "../../ode/src/config.h"
+#include "../../ode/src/joints/pr.h"
+
+SUITE (TestdxJointPR)
+{
+ // The 2 bodies are positionned at (0, 0, 0), with no rotation
+ // The joint is a PR Joint
+ // Axis is along the X axis
+ // Anchor at (0, 0, 0)
+ struct Fixture_dxJointPR_B1_and_B2_At_Zero_Axis_Along_X
+ {
+ Fixture_dxJointPR_B1_and_B2_At_Zero_Axis_Along_X()
+ {
+ wId = dWorldCreate();
+
+ bId1 = dBodyCreate (wId);
+ dBodySetPosition (bId1, 0, 0, 0);
+
+ bId2 = dBodyCreate (wId);
+ dBodySetPosition (bId2, 0, 0, 0);
+
+ jId = dJointCreatePR (wId, 0);
+ joint = (dxJointPR*) jId;
+
+
+ dJointAttach (jId, bId1, bId2);
+
+ dJointSetPRAxis1 (jId, axis[0], axis[1], axis[2]);
+ }
+
+ ~Fixture_dxJointPR_B1_and_B2_At_Zero_Axis_Along_X()
+ {
+ dWorldDestroy (wId);
+ }
+
+ dWorldID wId;
+
+ dBodyID bId1;
+ dBodyID bId2;
+
+
+ dJointID jId;
+ dxJointPR* joint;
+
+ static const dVector3 axis;
+
+ static const dReal offset;
+ };
+ const dVector3 Fixture_dxJointPR_B1_and_B2_At_Zero_Axis_Along_X::axis =
+ {
+ 1, 0, 0
+ };
+ const dReal Fixture_dxJointPR_B1_and_B2_At_Zero_Axis_Along_X::offset = REAL (3.1);
+
+
+
+
+
+ // Move 1st body offset unit in the X direction
+ //
+ // X-------> X---------> Axis -->
+ // B1 => B1
+ // B2 B2
+ //
+ // Start with a Offset of offset unit
+ //
+ // X-------> X---------> Axis -->
+ // B1 => B1
+ // B2 B2
+ TEST_FIXTURE (Fixture_dxJointPR_B1_and_B2_At_Zero_Axis_Along_X,
+ test_dJointSetPRAxisOffset_B1_3Unit)
+ {
+ dJointSetPRAnchor (jId, 0, 0, 0);
+
+ CHECK_CLOSE (0.0, dJointGetPRPosition (jId), 1e-4);
+
+ dBodySetPosition (bId1, offset, 0, 0);
+
+ CHECK_CLOSE (offset, dJointGetPRPosition (jId), 1e-4);
+
+// dJointSetPRAnchorOffset (jId, 0, 0, 0,
+// offset*axis[0],offset*axis[1],offset*axis[2]);
+// CHECK_CLOSE (offset, dJointGetPRPosition (jId), 1e-4);
+
+// dBodySetPosition (bId1, 0, 0, 0);
+// CHECK_CLOSE (0.0, dJointGetPRPosition (jId), 1e-4);
+
+// // Only here to test a deprecated warning
+// dJointSetPRAxisDelta (jId, 1, 0, 0, 0, 0, 0);
+ }
+
+ // Move 1st body offset unit in the opposite X direction
+ //
+ // X-------> X---------> Axis -->
+ // B1 => B1
+ // B2 B2
+ //
+ // Start with a Offset of -offset unit
+ //
+ // X-------> X---------> Axis -->
+ // B1 => B1
+ // B2 B2
+ TEST_FIXTURE (Fixture_dxJointPR_B1_and_B2_At_Zero_Axis_Along_X,
+ test_dJointSetPRAxisOffset_B1_Minus_3Unit)
+ {
+ dJointSetPRAnchor (jId, 0, 0, 0);
+
+ CHECK_CLOSE (0.0, dJointGetPRPosition (jId), 1e-4);
+
+ dBodySetPosition (bId1, -offset, 0, 0);
+
+ CHECK_CLOSE (-offset, dJointGetPRPosition (jId), 1e-4);
+
+// dJointSetPRAnchorOffset (jId, 0, 0, 0,
+// -offset*axis[0],-offset*axis[1],-offset*axis[2]);
+// CHECK_CLOSE (-offset, dJointGetPRPosition (jId), 1e-4);
+
+// dBodySetPosition (bId1, 0, 0, 0);
+// CHECK_CLOSE (0.0, dJointGetPRPosition (jId), 1e-4);
+ }
+
+ // Move 2nd body offset unit in the X direction
+ //
+ // X-------> X---------> Axis -->
+ // B1 => B1
+ // B2 B2
+ //
+ // Start with a Offset of offset unit
+ //
+ // X-------> X---------> Axis -->
+ // B1 => B1
+ // B2 B2
+ TEST_FIXTURE (Fixture_dxJointPR_B1_and_B2_At_Zero_Axis_Along_X,
+ test_dJointSetPRAxisOffset_B2_3Unit)
+ {
+ dJointSetPRAnchor (jId, 0, 0, 0);
+
+ CHECK_CLOSE (0.0, dJointGetPRPosition (jId), 1e-4);
+
+ dBodySetPosition (bId2, offset, 0, 0);
+
+ CHECK_CLOSE (-offset, dJointGetPRPosition (jId), 1e-4);
+
+// dJointSetPRAnchorOffset (jId, 0, 0, 0,
+// -offset*axis[0],-offset*axis[1],-offset*axis[2]);
+// CHECK_CLOSE (-offset, dJointGetPRPosition (jId), 1e-4);
+
+// dBodySetPosition (bId2, 0, 0, 0);
+// CHECK_CLOSE (0.0, dJointGetPRPosition (jId), 1e-4);
+ }
+
+ // Move 2nd body offset unit in the opposite X direction
+ //
+ // X-------> X---------> Axis -->
+ // B1 => B1
+ // B2 B2
+ //
+ // Start with a Offset of -offset unit
+ //
+ // X-------> X---------> Axis -->
+ // B1 => B1
+ // B2 B2
+ TEST_FIXTURE (Fixture_dxJointPR_B1_and_B2_At_Zero_Axis_Along_X,
+ test_dJointSetPRAxisOffset_B2_Minus_3Unit)
+ {
+ dJointSetPRAnchor (jId, 0, 0, 0);
+
+ CHECK_CLOSE (0.0, dJointGetPRPosition (jId), 1e-4);
+
+ dBodySetPosition (bId2, -offset, 0, 0);
+
+ CHECK_CLOSE (offset, dJointGetPRPosition (jId), 1e-4);
+
+// dJointSetPRAnchorOffset (jId, 0, 0, 0,
+// offset*axis[0],offset*axis[1],offset*axis[2]);
+// CHECK_CLOSE (offset, dJointGetPRPosition (jId), 1e-4);
+
+// dBodySetPosition (bId2, 0, 0, 0);
+// CHECK_CLOSE (0.0, dJointGetPRPosition (jId), 1e-4);
+ }
+
+
+
+
+
+
+ // Only body 1
+ // The body are positionned at (0, 0, 0), with no rotation
+ // The joint is a PR Joint
+ // Axis is along the X axis
+ // Anchor at (0, 0, 0)
+ struct Fixture_dxJointPR_B1_At_Zero_Axis_Along_X
+ {
+ Fixture_dxJointPR_B1_At_Zero_Axis_Along_X()
+ {
+ wId = dWorldCreate();
+
+ bId1 = dBodyCreate (wId);
+ dBodySetPosition (bId1, 0, 0, 0);
+
+ jId = dJointCreatePR (wId, 0);
+ joint = (dxJointPR*) jId;
+
+
+ dJointAttach (jId, bId1, NULL);
+
+ dJointSetPRAxis1 (jId, axis[0], axis[1], axis[2]);
+ }
+
+ ~Fixture_dxJointPR_B1_At_Zero_Axis_Along_X()
+ {
+ dWorldDestroy (wId);
+ }
+
+ dWorldID wId;
+
+ dBodyID bId1;
+
+ dJointID jId;
+ dxJointPR* joint;
+
+ static const dVector3 axis;
+
+ static const dReal offset;
+ };
+ const dVector3 Fixture_dxJointPR_B1_At_Zero_Axis_Along_X::axis =
+ {
+ 1, 0, 0
+ };
+ const dReal Fixture_dxJointPR_B1_At_Zero_Axis_Along_X::offset = REAL (3.1);
+
+ // Move 1st body offset unit in the X direction
+ //
+ // X-------> X---------> Axis -->
+ // B1 => B1
+ //
+ // Start with a Offset of offset unit
+ //
+ // X-------> X---------> Axis -->
+ // B1 => B1
+ TEST_FIXTURE (Fixture_dxJointPR_B1_At_Zero_Axis_Along_X,
+ test_dJointSetPRAxisOffset_B1_OffsetUnit)
+ {
+ dJointSetPRAnchor (jId, 0, 0, 0);
+
+ CHECK_CLOSE (0.0, dJointGetPRPosition (jId), 1e-4);
+
+ dBodySetPosition (bId1, offset, 0, 0);
+
+ CHECK_CLOSE (offset, dJointGetPRPosition (jId), 1e-4);
+
+// dJointSetPRAnchorOffset (jId, 0, 0, 0,
+// offset*axis[0],offset*axis[1],offset*axis[2]);
+// CHECK_CLOSE (offset, dJointGetPRPosition (jId), 1e-4);
+
+// dBodySetPosition (bId1, 0, 0, 0);
+// CHECK_CLOSE (0.0, dJointGetPRPosition (jId), 1e-4);
+ }
+
+ // Move 1st body offset unit in the opposite X direction
+ //
+ // X-------> X---------> Axis -->
+ // B1 => B1
+ //
+ // Start with a Offset of -offset unit
+ //
+ // X-------> X---------> Axis -->
+ // B1 => B1
+ TEST_FIXTURE (Fixture_dxJointPR_B1_At_Zero_Axis_Along_X,
+ test_dJointSetPRAxisOffset_B1_Minus_OffsetUnit)
+ {
+ dJointSetPRAnchor (jId, 0, 0, 0);
+
+ CHECK_CLOSE (0.0, dJointGetPRPosition (jId), 1e-4);
+
+ dBodySetPosition (bId1, -offset, 0, 0);
+
+ CHECK_CLOSE (-offset, dJointGetPRPosition (jId), 1e-4);
+
+// dJointSetPRAnchorOffset (jId, 0, 0, 0,
+// -offset*axis[0],-offset*axis[1],-offset*axis[2]);
+// CHECK_CLOSE (-offset, dJointGetPRPosition (jId), 1e-4);
+
+// dBodySetPosition (bId1, 0, 0, 0);
+// CHECK_CLOSE (0.0, dJointGetPRPosition (jId), 1e-4);
+ }
+
+ // Only body 1
+ // The body are positionned at (0, 0, 0), with no rotation
+ // The joint is a PR Joint
+ // Axis is in the oppsite X axis
+ // Anchor at (0, 0, 0)
+ struct Fixture_dxJointPR_B1_At_Zero_Axis_Inverse_of_X
+ {
+ Fixture_dxJointPR_B1_At_Zero_Axis_Inverse_of_X()
+ {
+ wId = dWorldCreate();
+
+ bId1 = dBodyCreate (wId);
+ dBodySetPosition (bId1, 0, 0, 0);
+
+ jId = dJointCreatePR (wId, 0);
+ joint = (dxJointPR*) jId;
+
+
+ dJointAttach (jId, bId1, NULL);
+
+ dJointSetPRAxis1 (jId, axis[0], axis[1], axis[2]);
+ }
+
+ ~Fixture_dxJointPR_B1_At_Zero_Axis_Inverse_of_X()
+ {
+ dWorldDestroy (wId);
+ }
+
+ dWorldID wId;
+
+ dBodyID bId1;
+
+ dJointID jId;
+ dxJointPR* joint;
+
+ static const dVector3 axis;
+
+ static const dReal offset;
+ };
+ const dVector3 Fixture_dxJointPR_B1_At_Zero_Axis_Inverse_of_X::axis =
+ {
+ -1, 0, 0
+ };
+ const dReal Fixture_dxJointPR_B1_At_Zero_Axis_Inverse_of_X::offset = REAL (3.1);
+
+ // Move 1st body offset unit in the X direction
+ //
+ // X-------> X---------> <--- Axis
+ // B1 => B1
+ //
+ // Start with a Offset of offset unit
+ //
+ // X-------> X---------> <--- Axis
+ // B1 => B1
+ TEST_FIXTURE (Fixture_dxJointPR_B1_At_Zero_Axis_Inverse_of_X,
+ test_dJointSetPRAxisOffset_B1_OffsetUnit)
+ {
+ dJointSetPRAnchor (jId, 0, 0, 0);
+
+ CHECK_CLOSE (0.0, dJointGetPRPosition (jId), 1e-4);
+
+ dBodySetPosition (bId1, offset, 0, 0);
+
+ CHECK_CLOSE (-offset, dJointGetPRPosition (jId), 1e-4);
+
+// dJointSetPRAnchorOffset (jId, 0, 0, 0,
+// -offset*axis[0],-offset*axis[1],-offset*axis[2]);
+// CHECK_CLOSE (-offset, dJointGetPRPosition (jId), 1e-4);
+
+// dBodySetPosition (bId1, 0, 0, 0);
+// CHECK_CLOSE (0.0, dJointGetPRPosition (jId), 1e-4);
+ }
+
+ // Move 1st body offset unit in the opposite X direction
+ //
+ // X-------> X---------> <--- Axis
+ // B1 => B1
+ //
+ // Start with a Offset of -offset unit
+ //
+ // X-------> X---------> <--- Axis
+ // B1 => B1
+ TEST_FIXTURE (Fixture_dxJointPR_B1_At_Zero_Axis_Inverse_of_X,
+ test_dJointSetPRAxisOffset_B1_Minus_OffsetUnit)
+ {
+ dJointSetPRAnchor (jId, 0, 0, 0);
+
+ CHECK_CLOSE (0.0, dJointGetPRPosition (jId), 1e-4);
+
+ dBodySetPosition (bId1, -offset, 0, 0);
+
+ CHECK_CLOSE (offset, dJointGetPRPosition (jId), 1e-4);
+
+// dJointSetPRAnchorOffset (jId, 0, 0, 0,
+// offset*axis[0],offset*axis[1],offset*axis[2]);
+// CHECK_CLOSE (offset, dJointGetPRPosition (jId), 1e-4);
+
+// dBodySetPosition (bId1, 0, 0, 0);
+// CHECK_CLOSE (0.0, dJointGetPRPosition (jId), 1e-4);
+ }
+
+
+
+
+ // Compare only one body to 2 bodies with one fixed.
+ //
+ // The body are positionned at (0, 0, 0), with no rotation
+ // The joint is a PR Joint
+ // Axis is along the X axis
+ // Anchor at (0, 0, 0)
+ struct Fixture_dxJointPR_Compare_Body_At_Zero_AxisP_Along_Y
+ {
+ Fixture_dxJointPR_Compare_Body_At_Zero_AxisP_Along_Y()
+ {
+ wId = dWorldCreate();
+
+ bId1_12 = dBodyCreate (wId);
+ dBodySetPosition (bId1_12, 0, 0, 0);
+
+ bId2_12 = dBodyCreate (wId);
+ dBodySetPosition (bId2_12, 0, 0, 0);
+ // The force will be added in the function since it is not
+ // always on the same body
+
+ jId_12 = dJointCreatePR (wId, 0);
+ dJointAttach(jId_12, bId1_12, bId2_12);
+
+ fixed = dJointCreateFixed (wId, 0);
+
+
+
+ jId = dJointCreatePR (wId, 0);
+
+ bId = dBodyCreate (wId);
+ dBodySetPosition (bId, 0, 0, 0);
+
+ // Linear velocity along the prismatic axis;
+ dVector3 axis;
+ dJointGetPRAxis1(jId_12, axis);
+ dJointSetPRAxis1(jId, axis[0], axis[1], axis[2]);
+ dBodySetLinearVel (bId, 4*axis[0], 4*axis[1], 4*axis[2]);
+ }
+
+ ~Fixture_dxJointPR_Compare_Body_At_Zero_AxisP_Along_Y()
+ {
+ dWorldDestroy (wId);
+ }
+
+ dWorldID wId;
+
+ dBodyID bId1_12;
+ dBodyID bId2_12;
+
+ dJointID jId_12; // Joint with 2 bodies
+
+ dJointID fixed;
+
+
+
+ dBodyID bId;
+ dJointID jId; // Joint with one body
+ };
+
+
+ TEST_FIXTURE (Fixture_dxJointPR_Compare_Body_At_Zero_AxisP_Along_Y,
+ test_dJointSetPRPositionRate_Only_B1)
+ {
+ // Linear velocity along the prismatic axis;
+ dVector3 axis;
+ dJointGetPRAxis1(jId_12, axis);
+ dBodySetLinearVel (bId1_12, 4*axis[0], 4*axis[1], 4*axis[2]);
+
+ dJointAttach(jId_12, bId1_12, bId2_12);
+
+ dJointAttach(fixed, 0, bId2_12);
+ dJointSetFixed(fixed);
+
+ dJointAttach(jId, bId, 0);
+
+ CHECK_CLOSE(dJointGetPRPositionRate(jId_12), dJointGetPRPositionRate(jId), 1e-2);
+
+ CHECK_CLOSE(dJointGetPRAngleRate(jId_12), dJointGetPRAngleRate(jId), 1e-2);
+ }
+
+
+ TEST_FIXTURE (Fixture_dxJointPR_Compare_Body_At_Zero_AxisP_Along_Y,
+ test_dJointSetPRPositionRate_Only_B2)
+ {
+ // Linear velocity along the prismatic axis;
+ dVector3 axis;
+ dJointGetPRAxis1(jId_12, axis);
+ dBodySetLinearVel (bId2_12, 4*axis[0], 4*axis[1], 4*axis[2]);
+
+ dJointAttach(jId_12, bId1_12, bId2_12);
+
+ dJointAttach(fixed, bId1_12, 0);
+ dJointSetFixed(fixed);
+
+ dJointAttach(jId, 0, bId);
+
+ CHECK_CLOSE(dJointGetPRPositionRate(jId_12), dJointGetPRPositionRate(jId), 1e-2);
+ CHECK_CLOSE(dJointGetPRAngleRate(jId_12), dJointGetPRAngleRate(jId), 1e-2);
+ }
+
+
+
+
+
+ // Only body 2
+ // The body are positionned at (0, 0, 0), with no rotation
+ // The joint is a PR Joint
+ // Axis is along the X axis
+ // Anchor at (0, 0, 0)
+ struct Fixture_dxJointPR_B2_At_Zero_Axis_Along_X
+ {
+ Fixture_dxJointPR_B2_At_Zero_Axis_Along_X()
+ {
+ wId = dWorldCreate();
+
+ bId2 = dBodyCreate (wId);
+ dBodySetPosition (bId2, 0, 0, 0);
+
+ jId = dJointCreatePR (wId, 0);
+ joint = (dxJointPR*) jId;
+
+
+ dJointAttach (jId, NULL, bId2);
+
+ dJointSetPRAxis1 (jId, axis[0], axis[1], axis[2]);
+ }
+
+ ~Fixture_dxJointPR_B2_At_Zero_Axis_Along_X()
+ {
+ dWorldDestroy (wId);
+ }
+
+ dWorldID wId;
+
+ dBodyID bId2;
+
+ dJointID jId;
+ dxJointPR* joint;
+
+ static const dVector3 axis;
+
+ static const dReal offset;
+ };
+ const dVector3 Fixture_dxJointPR_B2_At_Zero_Axis_Along_X::axis =
+ {
+ 1, 0, 0
+ };
+ const dReal Fixture_dxJointPR_B2_At_Zero_Axis_Along_X::offset = REAL (3.1);
+
+ // Move 2nd body offset unit in the X direction
+ //
+ // X-------> X---------> Axis -->
+ // B2 => B2
+ //
+ // Start with a Offset of offset unit
+ //
+ // X-------> X---------> Axis -->
+ // B2 => B2
+ TEST_FIXTURE (Fixture_dxJointPR_B2_At_Zero_Axis_Along_X,
+ test_dJointSetPRAxisOffset_B2_OffsetUnit)
+ {
+ dJointSetPRAnchor (jId, 0, 0, 0);
+
+ CHECK_CLOSE (0.0, dJointGetPRPosition (jId), 1e-4);
+
+ dBodySetPosition (bId2, offset, 0, 0);
+
+ CHECK_CLOSE (-offset, dJointGetPRPosition (jId), 1e-4);
+
+// dJointSetPRAnchorOffset (jId, 0, 0, 0,
+// -offset*axis[0],-offset*axis[1],-offset*axis[2]);
+// CHECK_CLOSE (-offset, dJointGetPRPosition (jId), 1e-4);
+
+// dBodySetPosition (bId2, 0, 0, 0);
+// CHECK_CLOSE (0.0, dJointGetPRPosition (jId), 1e-4);
+ }
+
+ // Move 2nd body offset unit in the opposite X direction
+ //
+ // X-------> X---------> Axis -->
+ // B2 => B2
+ //
+ // Start with a Offset of -offset unit
+ //
+ // X-------> X---------> Axis -->
+ // B2 => B2
+ TEST_FIXTURE (Fixture_dxJointPR_B2_At_Zero_Axis_Along_X,
+ test_dJointSetPRAxisOffset_B2_Minus_OffsetUnit)
+ {
+ dJointSetPRAnchor (jId, 0, 0, 0);
+
+ CHECK_CLOSE (0.0, dJointGetPRPosition (jId), 1e-4);
+
+ dBodySetPosition (bId2, -offset, 0, 0);
+
+ CHECK_CLOSE (offset, dJointGetPRPosition (jId), 1e-4);
+
+// dJointSetPRAnchorOffset (jId, 0, 0, 0,
+// offset*axis[0],offset*axis[1],offset*axis[2]);
+// CHECK_CLOSE (offset, dJointGetPRPosition (jId), 1e-4);
+
+// dBodySetPosition (bId2, 0, 0, 0);
+// CHECK_CLOSE (0.0, dJointGetPRPosition (jId), 1e-4);
+ }
+
+ // Only body 2
+ // The body are positionned at (0, 0, 0), with no rotation
+ // The joint is a PR Joint
+ // Axis is in the opposite X axis
+ // Anchor at (0, 0, 0)
+ struct Fixture_dxJointPR_B2_At_Zero_Axis_Inverse_of_X
+ {
+ Fixture_dxJointPR_B2_At_Zero_Axis_Inverse_of_X()
+ {
+ wId = dWorldCreate();
+
+ bId2 = dBodyCreate (wId);
+ dBodySetPosition (bId2, 0, 0, 0);
+
+ jId = dJointCreatePR (wId, 0);
+ joint = (dxJointPR*) jId;
+
+
+ dJointAttach (jId, NULL, bId2);
+
+ dJointSetPRAxis1 (jId, axis[0], axis[1], axis[2]);
+ }
+
+ ~Fixture_dxJointPR_B2_At_Zero_Axis_Inverse_of_X()
+ {
+ dWorldDestroy (wId);
+ }
+
+ dWorldID wId;
+
+ dBodyID bId2;
+
+ dJointID jId;
+ dxJointPR* joint;
+
+ static const dVector3 axis;
+
+ static const dReal offset;
+ };
+ const dVector3 Fixture_dxJointPR_B2_At_Zero_Axis_Inverse_of_X::axis =
+ {
+ -1, 0, 0
+ };
+ const dReal Fixture_dxJointPR_B2_At_Zero_Axis_Inverse_of_X::offset = REAL (3.1);
+
+ // Move 2nd body offset unit in the X direction
+ //
+ // X-------> X---------> <--- Axis
+ // B2 => B2
+ //
+ // Start with a Offset of offset unit
+ //
+ // X-------> X---------> <--- Axis
+ // B2 => B2
+ TEST_FIXTURE (Fixture_dxJointPR_B2_At_Zero_Axis_Inverse_of_X,
+ test_dJointSetPRAxisOffset_B2_OffsetUnit)
+ {
+ dJointSetPRAnchor (jId, 0, 0, 0);
+
+ CHECK_CLOSE (0.0, dJointGetPRPosition (jId), 1e-4);
+
+ dBodySetPosition (bId2, offset, 0, 0);
+
+ CHECK_CLOSE (offset, dJointGetPRPosition (jId), 1e-4);
+
+// dJointSetPRAnchorOffset (jId, 0, 0, 0,
+// offset*axis[0],offset*axis[1],offset*axis[2]);
+// CHECK_CLOSE (offset, dJointGetPRPosition (jId), 1e-4);
+
+// dBodySetPosition (bId2, 0, 0, 0);
+// CHECK_CLOSE (0.0, dJointGetPRPosition (jId), 1e-4);
+// dJointSetPRAxisDelta (jId, 1, 0, 0, 0, 0, 0);
+ }
+
+ // Move 1st body offset unit in the opposite X direction
+ //
+ // X-------> X---------> <--- Axis
+ // B2 => B2
+ //
+ // Start with a Offset of -offset unit
+ //
+ // X-------> X---------> <--- Axis
+ // B2 => B2
+ TEST_FIXTURE (Fixture_dxJointPR_B2_At_Zero_Axis_Inverse_of_X,
+ test_dJointSetPRAxisOffset_B2_Minus_OffsetUnit)
+ {
+ dJointSetPRAnchor (jId, 0, 0, 0);
+
+ CHECK_CLOSE (0.0, dJointGetPRPosition (jId), 1e-4);
+
+ dBodySetPosition (bId2, -offset, 0, 0);
+
+ CHECK_CLOSE (-offset, dJointGetPRPosition (jId), 1e-4);
+
+// dJointSetPRAnchorOffset (jId, 0, 0, 0,
+// -offset*axis[0],-offset*axis[1],-offset*axis[2]);
+// CHECK_CLOSE (-offset, dJointGetPRPosition (jId), 1e-4);
+
+// dBodySetPosition (bId2, 0, 0, 0);
+// CHECK_CLOSE (0.0, dJointGetPRPosition (jId), 1e-4);
+ }
+
+
+ // The 2 bodies are positionned at (0, 0, 0), and (0, 0, 0)
+ // The bodis have rotation of 27deg around some axis.
+ // The joint is a PR Joint
+ // Axis is along the X axis
+ // Anchor at (0, 0, 0)
+ struct Fixture_dxJointPR_B1_and_B2_Random_Orientation_At_Zero_Axis_Along_X
+ {
+ Fixture_dxJointPR_B1_and_B2_Random_Orientation_At_Zero_Axis_Along_X()
+ {
+ wId = dWorldCreate();
+
+ bId1 = dBodyCreate (wId);
+ dBodySetPosition (bId1, 0, 0, 0);
+
+ bId2 = dBodyCreate (wId);
+ dBodySetPosition (bId2, 0, 0, 0);
+
+ dMatrix3 R;
+
+ dVector3 axis; // Random axis
+
+ axis[0] = REAL(0.53);
+ axis[1] = -REAL(0.71);
+ axis[2] = REAL(0.43);
+ dNormalize3(axis);
+ dRFromAxisAndAngle (R, axis[0], axis[1], axis[2],
+ REAL(0.47123)); // 27deg
+ dBodySetRotation (bId1, R);
+
+
+ axis[0] = REAL(1.2);
+ axis[1] = REAL(0.87);
+ axis[2] = -REAL(0.33);
+ dNormalize3(axis);
+ dRFromAxisAndAngle (R, axis[0], axis[1], axis[2],
+ REAL(0.47123)); // 27deg
+ dBodySetRotation (bId2, R);
+
+ jId = dJointCreatePR (wId, 0);
+ joint = (dxJointPR*) jId;
+
+
+ dJointAttach (jId, bId1, bId2);
+ }
+
+ ~Fixture_dxJointPR_B1_and_B2_Random_Orientation_At_Zero_Axis_Along_X()
+ {
+ dWorldDestroy (wId);
+ }
+
+ dWorldID wId;
+
+ dBodyID bId1;
+ dBodyID bId2;
+
+
+ dJointID jId;
+ dxJointPR* joint;
+ };
+
+ // Test is dJointSetPRAxis and dJointGetPRAxis return same value
+ TEST_FIXTURE (Fixture_dxJointPR_B1_and_B2_Random_Orientation_At_Zero_Axis_Along_X,
+ test_dJointSetGetPRAxis)
+ {
+ dVector3 axisOrig, axis;
+
+
+ dJointGetPRAxis1 (jId, axisOrig);
+ dJointGetPRAxis1 (jId, axis);
+ dJointSetPRAxis1 (jId, axis[0], axis[1], axis[2]);
+ dJointGetPRAxis1 (jId, axis);
+ CHECK_CLOSE (axis[0], axisOrig[0] , 1e-4);
+ CHECK_CLOSE (axis[1], axisOrig[1] , 1e-4);
+ CHECK_CLOSE (axis[2], axisOrig[2] , 1e-4);
+
+
+ dJointGetPRAxis2 (jId, axisOrig);
+ dJointGetPRAxis2(jId, axis);
+ dJointSetPRAxis2 (jId, axis[0], axis[1], axis[2]);
+ dJointGetPRAxis2 (jId, axis);
+ CHECK_CLOSE (axis[0], axisOrig[0] , 1e-4);
+ CHECK_CLOSE (axis[1], axisOrig[1] , 1e-4);
+ CHECK_CLOSE (axis[2], axisOrig[2] , 1e-4);
+ }
+
+
+
+ // Create 2 bodies attached by a PR joint
+ // Axis is along the X axis (Default value
+ // Anchor at (0, 0, 0) (Default value)
+ //
+ // ^Y
+ // |
+ // * Body2
+ // |
+ // |
+ // Body1 |
+ // * Z-------->
+ struct dxJointPR_Test_Initialization
+ {
+ dxJointPR_Test_Initialization()
+ {
+ wId = dWorldCreate();
+
+ // Remove gravity to have the only force be the force of the joint
+ dWorldSetGravity(wId, 0,0,0);
+
+ for (int j=0; j<2; ++j)
+ {
+ bId[j][0] = dBodyCreate (wId);
+ dBodySetPosition (bId[j][0], -1, -2, -3);
+
+ bId[j][1] = dBodyCreate (wId);
+ dBodySetPosition (bId[j][1], 11, 22, 33);
+
+
+ dMatrix3 R;
+ dVector3 axis; // Random axis
+
+ axis[0] = REAL(0.53);
+ axis[1] = -REAL(0.71);
+ axis[2] = REAL(0.43);
+ dNormalize3(axis);
+ dRFromAxisAndAngle (R, axis[0], axis[1], axis[2],
+ REAL(0.47123)); // 27deg
+ dBodySetRotation (bId[j][0], R);
+
+
+ axis[0] = REAL(1.2);
+ axis[1] = REAL(0.87);
+ axis[2] = -REAL(0.33);
+ dNormalize3(axis);
+ dRFromAxisAndAngle (R, axis[0], axis[1], axis[2],
+ REAL(0.47123)); // 27deg
+ dBodySetRotation (bId[j][1], R);
+
+
+ jId[j] = dJointCreatePR (wId, 0);
+ dJointAttach (jId[j], bId[j][0], bId[j][1]);
+ }
+ }
+
+ ~dxJointPR_Test_Initialization()
+ {
+ dWorldDestroy (wId);
+ }
+
+ dWorldID wId;
+
+ dBodyID bId[2][2];
+
+
+ dJointID jId[2];
+
+ };
+
+
+ // Test if setting a PR with its default values
+ // will behave the same as a default PR joint
+ TEST_FIXTURE (dxJointPR_Test_Initialization,
+ test_PR_Initialization)
+ {
+ using namespace std;
+
+ dVector3 axis;
+ dJointGetPRAxis1(jId[1], axis);
+ dJointSetPRAxis1(jId[1], axis[0], axis[1], axis[2]);
+
+ dJointGetPRAxis2(jId[1], axis);
+ dJointSetPRAxis2(jId[1], axis[0], axis[1], axis[2]);
+
+ dVector3 anchor;
+ dJointGetPRAnchor(jId[1], anchor);
+ dJointSetPRAnchor(jId[1], anchor[0], anchor[1], anchor[2]);
+
+ for (int b=0; b<2; ++b)
+ {
+ // Compare body b of the first joint with its equivalent on the
+ // second joint
+ const dReal *qA = dBodyGetQuaternion(bId[0][b]);
+ const dReal *qB = dBodyGetQuaternion(bId[1][b]);
+ CHECK_CLOSE (qA[0], qB[0], 1e-4);
+ CHECK_CLOSE (qA[1], qB[1], 1e-4);
+ CHECK_CLOSE (qA[2], qB[2], 1e-4);
+ CHECK_CLOSE (qA[3], qB[3], 1e-4);
+ }
+
+ dWorldStep (wId,0.5);
+ dWorldStep (wId,0.5);
+ dWorldStep (wId,0.5);
+ dWorldStep (wId,0.5);
+
+ for (int b=0; b<2; ++b)
+ {
+ // Compare body b of the first joint with its equivalent on the
+ // second joint
+ const dReal *qA = dBodyGetQuaternion(bId[0][b]);
+ const dReal *qB = dBodyGetQuaternion(bId[1][b]);
+ CHECK_CLOSE (qA[0], qB[0], 1e-4);
+ CHECK_CLOSE (qA[1], qB[1], 1e-4);
+ CHECK_CLOSE (qA[2], qB[2], 1e-4);
+ CHECK_CLOSE (qA[3], qB[3], 1e-4);
+
+
+ const dReal *posA = dBodyGetPosition(bId[0][b]);
+ const dReal *posB = dBodyGetPosition(bId[1][b]);
+ CHECK_CLOSE (posA[0], posB[0], 1e-4);
+ CHECK_CLOSE (posA[1], posB[1], 1e-4);
+ CHECK_CLOSE (posA[2], posB[2], 1e-4);
+ CHECK_CLOSE (posA[3], posB[3], 1e-4);
+ }
+ }
+
+
+
+
+
+
+ // This test compare the result of a slider with 2 bodies where body body 2 is
+ // fixed to the world to a slider with only one body at position 1.
+ //
+ // Test the limits [-1, 0.25] when only one body at is attached to the joint
+ // using dJointAttache(jId, bId, 0);
+ //
+ TEST_FIXTURE(Fixture_dxJointPR_Compare_Body_At_Zero_AxisP_Along_Y,
+ test_Limit_minus1_025_One_Body_on_left)
+ {
+ // Linear velocity along the prismatic axis;
+ dVector3 axis;
+ dJointGetPRAxis1(jId_12, axis);
+ dBodySetLinearVel (bId1_12, 4*axis[0], 4*axis[1], 4*axis[2]);
+
+ dJointAttach(jId_12, bId1_12, bId2_12);
+ dJointSetPRParam(jId_12, dParamLoStop, -1);
+ dJointSetPRParam(jId_12, dParamHiStop, 0.25);
+
+ dJointAttach(fixed, 0, bId2_12);
+ dJointSetFixed(fixed);
+
+ dJointAttach(jId, bId, 0);
+ dJointSetPRParam(jId, dParamLoStop, -1);
+ dJointSetPRParam(jId, dParamHiStop, 0.25);
+
+
+ for (int i=0; i<50; ++i)
+ dWorldStep(wId, 1.0);
+
+
+ const dReal *pos1_12 = dBodyGetPosition(bId1_12);
+ const dReal *pos = dBodyGetPosition(bId);
+
+ CHECK_CLOSE (pos1_12[0], pos[0], 1e-2);
+ CHECK_CLOSE (pos1_12[1], pos[1], 1e-2);
+ CHECK_CLOSE (pos1_12[2], pos[2], 1e-2);
+
+ const dReal *q1_12 = dBodyGetQuaternion(bId1_12);
+ const dReal *q = dBodyGetQuaternion(bId);
+
+ CHECK_CLOSE (q1_12[0], q[0], 1e-4);
+ CHECK_CLOSE (q1_12[1], q[1], 1e-4);
+ CHECK_CLOSE (q1_12[2], q[2], 1e-4);
+ CHECK_CLOSE (q1_12[3], q[3], 1e-4);
+ }
+
+
+
+ // This test compare the result of a slider with 2 bodies where body body 1 is
+ // fixed to the world to a slider with only one body at position 2.
+ //
+ // Test the limits [-1, 0.25] when only one body at is attached to the joint
+ // using dJointAttache(jId, 0, bId);
+ //
+ TEST_FIXTURE(Fixture_dxJointPR_Compare_Body_At_Zero_AxisP_Along_Y,
+ test_Limit_minus1_025_One_Body_on_right)
+ {
+ // Linear velocity along the prismatic axis;
+ dVector3 axis;
+ dJointGetPRAxis1(jId_12, axis);
+ dBodySetLinearVel (bId2_12, 4*axis[0], 4*axis[1], 4*axis[2]);
+
+ dJointAttach(jId_12, bId1_12, bId2_12);
+ dJointSetPRParam(jId_12, dParamLoStop, -1);
+ dJointSetPRParam(jId_12, dParamHiStop, 0.25);
+
+ dJointAttach(fixed, bId1_12, 0);
+ dJointSetFixed(fixed);
+
+
+ dJointAttach(jId, 0, bId);
+ dJointSetPRParam(jId, dParamLoStop, -1);
+ dJointSetPRParam(jId, dParamHiStop, 0.25);
+
+ for (int i=0; i<50; ++i)
+ dWorldStep(wId, 1.0);
+
+
+ const dReal *pos2_12 = dBodyGetPosition(bId2_12);
+ const dReal *pos = dBodyGetPosition(bId);
+
+ CHECK_CLOSE (pos2_12[0], pos[0], 1e-2);
+ CHECK_CLOSE (pos2_12[1], pos[1], 1e-2);
+ CHECK_CLOSE (pos2_12[2], pos[2], 1e-2);
+
+
+ const dReal *q2_12 = dBodyGetQuaternion(bId2_12);
+ const dReal *q = dBodyGetQuaternion(bId);
+
+ CHECK_CLOSE (q2_12[0], q[0], 1e-4);
+ CHECK_CLOSE (q2_12[1], q[1], 1e-4);
+ CHECK_CLOSE (q2_12[2], q[2], 1e-4);
+ CHECK_CLOSE (q2_12[3], q[3], 1e-4);
+ }
+
+
+
+ // This test compare the result of a slider with 2 bodies where body body 2 is
+ // fixed to the world to a slider with only one body at position 1.
+ //
+ // Test the limits [0, 0] when only one body at is attached to the joint
+ // using dJointAttache(jId, bId, 0);
+ //
+ // The body should not move since their is no room between the two limits
+ //
+ TEST_FIXTURE(Fixture_dxJointPR_Compare_Body_At_Zero_AxisP_Along_Y,
+ test_Limit_0_0_One_Body_on_left)
+ {
+ // Linear velocity along the prismatic axis;
+ dVector3 axis;
+ dJointGetPRAxis1(jId_12, axis);
+ dBodySetLinearVel (bId1_12, 4*axis[0], 4*axis[1], 4*axis[2]);
+
+ dJointAttach(jId_12, bId1_12, bId2_12);
+ dJointSetPRParam(jId_12, dParamLoStop, 0);
+ dJointSetPRParam(jId_12, dParamHiStop, 0);
+
+ dJointAttach(fixed, 0, bId2_12);
+ dJointSetFixed(fixed);
+
+
+ dJointAttach(jId, bId, 0);
+ dJointSetPRParam(jId, dParamLoStop, 0);
+ dJointSetPRParam(jId, dParamHiStop, 0);
+
+ for (int i=0; i<50; ++i)
+ dWorldStep(wId, 1.0);
+
+
+
+ const dReal *pos1_12 = dBodyGetPosition(bId1_12);
+ const dReal *pos = dBodyGetPosition(bId);
+
+ CHECK_CLOSE (pos1_12[0], pos[0], 1e-4);
+ CHECK_CLOSE (pos1_12[1], pos[1], 1e-4);
+ CHECK_CLOSE (pos1_12[2], pos[2], 1e-4);
+
+ CHECK_CLOSE (0, pos[0], 1e-4);
+ CHECK_CLOSE (0, pos[1], 1e-4);
+ CHECK_CLOSE (0, pos[2], 1e-4);
+
+
+ const dReal *q1_12 = dBodyGetQuaternion(bId1_12);
+ const dReal *q = dBodyGetQuaternion(bId);
+
+ CHECK_CLOSE (q1_12[0], q[0], 1e-4);
+ CHECK_CLOSE (q1_12[1], q[1], 1e-4);
+ CHECK_CLOSE (q1_12[2], q[2], 1e-4);
+ CHECK_CLOSE (q1_12[3], q[3], 1e-4);
+ }
+
+
+ // This test compare the result of a slider with 2 bodies where body body 1 is
+ // fixed to the world to a slider with only one body at position 2.
+ //
+ // Test the limits [0, 0] when only one body at is attached to the joint
+ // using dJointAttache(jId, 0, bId);
+ //
+ // The body should not move since their is no room between the two limits
+ //
+ TEST_FIXTURE(Fixture_dxJointPR_Compare_Body_At_Zero_AxisP_Along_Y,
+ test_Limit_0_0_One_Body_on_right)
+ {
+ // Linear velocity along the prismatic axis;
+ dVector3 axis;
+ dJointGetPRAxis1(jId_12, axis);
+ dBodySetLinearVel (bId2_12, 4*axis[0], 4*axis[1], 4*axis[2]);
+
+ dJointAttach(jId_12, bId1_12, bId2_12);
+ dJointSetPRParam(jId_12, dParamLoStop, 0);
+ dJointSetPRParam(jId_12, dParamHiStop, 0);
+
+ dJointAttach(fixed, bId1_12, 0);
+ dJointSetFixed(fixed);
+
+
+ dJointAttach(jId, 0, bId);
+ dJointSetPRParam(jId, dParamLoStop, 0);
+ dJointSetPRParam(jId, dParamHiStop, 0);
+
+ for (int i=0; i<50; ++i)
+ {
+ dWorldStep(wId, 1.0);
+ }
+
+
+ const dReal *pos2_12 = dBodyGetPosition(bId2_12);
+ const dReal *pos = dBodyGetPosition(bId);
+
+ CHECK_CLOSE (pos2_12[0], pos[0], 1e-4);
+ CHECK_CLOSE (pos2_12[1], pos[1], 1e-4);
+ CHECK_CLOSE (pos2_12[2], pos[2], 1e-4);
+
+ CHECK_CLOSE (0, pos[0], 1e-4);
+ CHECK_CLOSE (0, pos[1], 1e-4);
+ CHECK_CLOSE (0, pos[2], 1e-4);
+
+
+ const dReal *q2_12 = dBodyGetQuaternion(bId2_12);
+ const dReal *q = dBodyGetQuaternion(bId);
+
+ CHECK_CLOSE (q2_12[0], q[0], 1e-4);
+ CHECK_CLOSE (q2_12[1], q[1], 1e-4);
+ CHECK_CLOSE (q2_12[2], q[2], 1e-4);
+ CHECK_CLOSE (q2_12[3], q[3], 1e-4);
+ }
+
+} // End of SUITE TestdxJointPR
+
diff --git a/libs/ode-0.16.1/tests/joints/pu.cpp b/libs/ode-0.16.1/tests/joints/pu.cpp
new file mode 100644
index 0000000..6d97a07
--- /dev/null
+++ b/libs/ode-0.16.1/tests/joints/pu.cpp
@@ -0,0 +1,920 @@
+/*************************************************************************
+ * *
+ * 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. *
+ * *
+ *************************************************************************/
+//234567890123456789012345678901234567890123456789012345678901234567890123456789
+// 1 2 3 4 5 6 7
+
+////////////////////////////////////////////////////////////////////////////////
+// This file create unit test for some of the functions found in:
+// ode/src/joinst/pu.cpp
+//
+//
+////////////////////////////////////////////////////////////////////////////////
+
+#include <UnitTest++.h>
+#include <ode/ode.h>
+
+#include "../../ode/src/config.h"
+#include "../../ode/src/joints/pu.h"
+
+SUITE (TestdxJointPU)
+{
+ // The 2 bodies are positionned at (0, 0, 0), and (0, 0, 0)
+ // The second body has a rotation of 27deg around X axis.
+ // The joint is a PU Joint
+ // Axis is along the X axis
+ // Anchor at (0, 0, 0)
+ struct Fixture_dxJointPU_B1_and_B2_At_Zero_Axis_Along_X
+ {
+ Fixture_dxJointPU_B1_and_B2_At_Zero_Axis_Along_X()
+ {
+ wId = dWorldCreate();
+
+ bId1 = dBodyCreate (wId);
+ dBodySetPosition (bId1, 0, 0, 0);
+
+ bId2 = dBodyCreate (wId);
+ dBodySetPosition (bId2, 0, 0, 0);
+
+ dMatrix3 R;
+
+ dRFromAxisAndAngle (R, 1, 0, 0, REAL(0.47123)); // 27deg
+ dBodySetRotation (bId2, R);
+
+ jId = dJointCreatePU (wId, 0);
+ joint = (dxJointPU*) jId;
+
+
+ dJointAttach (jId, bId1, bId2);
+ }
+
+ ~Fixture_dxJointPU_B1_and_B2_At_Zero_Axis_Along_X()
+ {
+ dWorldDestroy (wId);
+ }
+
+ dWorldID wId;
+
+ dBodyID bId1;
+ dBodyID bId2;
+
+
+ dJointID jId;
+ dxJointPU* joint;
+ };
+
+ // Test is dJointSetPUAxis and dJointGetPUAxis return same value
+ TEST_FIXTURE (Fixture_dxJointPU_B1_and_B2_At_Zero_Axis_Along_X,
+ test_dJointSetGetPUAxis)
+ {
+ dVector3 axisOrig, axis;
+
+
+ dJointGetPUAxis1 (jId, axisOrig);
+ dJointGetPUAxis1 (jId, axis);
+ dJointSetPUAxis1 (jId, axis[0], axis[1], axis[2]);
+ dJointGetPUAxis1 (jId, axis);
+ CHECK_CLOSE (axis[0], axisOrig[0] , 1e-4);
+ CHECK_CLOSE (axis[1], axisOrig[1] , 1e-4);
+ CHECK_CLOSE (axis[2], axisOrig[2] , 1e-4);
+
+
+ dJointGetPUAxis2 (jId, axisOrig);
+ dJointGetPUAxis2(jId, axis);
+ dJointSetPUAxis2 (jId, axis[0], axis[1], axis[2]);
+ dJointGetPUAxis2 (jId, axis);
+ CHECK_CLOSE (axis[0], axisOrig[0] , 1e-4);
+ CHECK_CLOSE (axis[1], axisOrig[1] , 1e-4);
+ CHECK_CLOSE (axis[2], axisOrig[2] , 1e-4);
+
+
+ dJointGetPUAxis3 (jId, axisOrig);
+ dJointGetPUAxis3(jId, axis);
+ dJointSetPUAxis3 (jId, axis[0], axis[1], axis[2]);
+ dJointGetPUAxis3 (jId, axis);
+ CHECK_CLOSE (axis[0], axisOrig[0] , 1e-4);
+ CHECK_CLOSE (axis[1], axisOrig[1] , 1e-4);
+ CHECK_CLOSE (axis[2], axisOrig[2] , 1e-4);
+ }
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ // The joint is a PU Joint
+ // Default joint value
+ // The two bodies at at (0, 0, 0)
+ struct Fixture_dxJointPU_B1_and_B2_At_Zero
+ {
+ Fixture_dxJointPU_B1_and_B2_At_Zero()
+ {
+ wId = dWorldCreate();
+
+ bId1 = dBodyCreate (wId);
+ dBodySetPosition (bId1, 0, 0, 0);
+
+ bId2 = dBodyCreate (wId);
+ dBodySetPosition (bId2, 0, 0, 0);
+
+ jId = dJointCreatePU (wId, 0);
+ joint = (dxJointPU*) jId;
+
+
+ dJointAttach (jId, bId1, bId2);
+ }
+
+ ~Fixture_dxJointPU_B1_and_B2_At_Zero()
+ {
+ dWorldDestroy (wId);
+ }
+
+ dWorldID wId;
+
+ dBodyID bId1;
+ dBodyID bId2;
+
+
+ dJointID jId;
+ dxJointPU* joint;
+
+ static const dReal offset;
+ };
+ const dReal Fixture_dxJointPU_B1_and_B2_At_Zero::offset = REAL (3.1);
+
+
+
+
+
+ // Move 1st body offset unit in the X direction
+ //
+ // X-------> X---------> Axis -->
+ // B1 => B1
+ // B2 B2
+ //
+ // Start with a Offset of offset unit
+ //
+ // X-------> X---------> Axis -->
+ // B1 => B1
+ // B2 B2
+ TEST_FIXTURE (Fixture_dxJointPU_B1_and_B2_At_Zero,
+ test_dJointSetPUAxisOffset_B1_3Unit)
+ {
+ CHECK_CLOSE (0.0, dJointGetPUPosition (jId), 1e-4);
+
+ dBodySetPosition (bId1, offset, 0, 0);
+
+ CHECK_CLOSE (offset, dJointGetPUPosition (jId), 1e-4);
+
+ dVector3 axis;
+ dJointGetPUAxisP (jId, axis);
+
+ dJointSetPUAnchorOffset (jId, 0, 0, 0,
+ offset*axis[0],offset*axis[1],offset*axis[2]);
+ CHECK_CLOSE (offset, dJointGetPUPosition (jId), 1e-4);
+
+ dBodySetPosition (bId1, 0, 0, 0);
+ CHECK_CLOSE (0.0, dJointGetPUPosition (jId), 1e-4);
+ }
+
+ // Move 1st body offset unit in the opposite X direction
+ //
+ // X-------> X---------> Axis -->
+ // B1 => B1
+ // B2 B2
+ //
+ // Start with a Offset of -offset unit
+ //
+ // X-------> X---------> Axis -->
+ // B1 => B1
+ // B2 B2
+ TEST_FIXTURE (Fixture_dxJointPU_B1_and_B2_At_Zero,
+ test_dJointSetPUAxisOffset_B1_Minus_3Unit)
+ {
+ CHECK_CLOSE (0.0, dJointGetPUPosition (jId), 1e-4);
+
+ dBodySetPosition (bId1, -offset, 0, 0);
+
+ CHECK_CLOSE (-offset, dJointGetPUPosition (jId), 1e-4);
+
+ dVector3 axis;
+ dJointGetPUAxisP (jId, axis);
+ dJointSetPUAnchorOffset (jId, 0, 0, 0,
+ -offset*axis[0],-offset*axis[1],-offset*axis[2]);
+ CHECK_CLOSE (-offset, dJointGetPUPosition (jId), 1e-4);
+
+ dBodySetPosition (bId1, 0, 0, 0);
+ CHECK_CLOSE (0.0, dJointGetPUPosition (jId), 1e-4);
+ }
+
+ // Move 2nd body offset unit in the X direction
+ //
+ // X-------> X---------> Axis -->
+ // B1 => B1
+ // B2 B2
+ //
+ // Start with a Offset of offset unit
+ //
+ // X-------> X---------> Axis -->
+ // B1 => B1
+ // B2 B2
+ TEST_FIXTURE (Fixture_dxJointPU_B1_and_B2_At_Zero,
+ test_dJointSetPUAxisOffset_B2_3Unit)
+ {
+ CHECK_CLOSE (0.0, dJointGetPUPosition (jId), 1e-4);
+
+ dBodySetPosition (bId2, offset, 0, 0);
+
+ CHECK_CLOSE (-offset, dJointGetPUPosition (jId), 1e-4);
+
+ dVector3 axis;
+ dJointGetPUAxisP (jId, axis);
+ dJointSetPUAnchorOffset (jId, 0, 0, 0,
+ -offset*axis[0],-offset*axis[1],-offset*axis[2]);
+ CHECK_CLOSE (-offset, dJointGetPUPosition (jId), 1e-4);
+
+ dBodySetPosition (bId2, 0, 0, 0);
+ CHECK_CLOSE (0.0, dJointGetPUPosition (jId), 1e-4);
+ }
+
+ // Move 2nd body offset unit in the opposite X direction
+ //
+ // X-------> X---------> Axis -->
+ // B1 => B1
+ // B2 B2
+ //
+ // Start with a Offset of -offset unit
+ //
+ // X-------> X---------> Axis -->
+ // B1 => B1
+ // B2 B2
+ TEST_FIXTURE (Fixture_dxJointPU_B1_and_B2_At_Zero,
+ test_dJointSetPUAxisOffset_B2_Minus_3Unit)
+ {
+ CHECK_CLOSE (0.0, dJointGetPUPosition (jId), 1e-4);
+
+ dBodySetPosition (bId2, -offset, 0, 0);
+
+ CHECK_CLOSE (offset, dJointGetPUPosition (jId), 1e-4);
+
+ dVector3 axis;
+ dJointGetPUAxisP (jId, axis);
+ dJointSetPUAnchorOffset (jId, 0, 0, 0,
+ offset*axis[0],offset*axis[1],offset*axis[2]);
+ CHECK_CLOSE (offset, dJointGetPUPosition (jId), 1e-4);
+
+ dBodySetPosition (bId2, 0, 0, 0);
+ CHECK_CLOSE (0.0, dJointGetPUPosition (jId), 1e-4);
+ }
+
+
+
+ // Attach only one body at position 1 to the joint dJointAttach (jId, bId, 0)
+ // Move 1st body offset unit in the X direction
+ //
+ // X-------> X---------> Axis -->
+ // B1 => B1
+ //
+ // Start with a Offset of offset unit
+ //
+ // X-------> X---------> Axis -->
+ // B1 => B1
+ TEST_FIXTURE (Fixture_dxJointPU_B1_and_B2_At_Zero,
+ test_dJointSetPUAxisOffset_B1_OffsetUnit)
+ {
+ dJointAttach (jId, bId1, 0);
+
+ CHECK_CLOSE (0.0, dJointGetPUPosition (jId), 1e-4);
+
+ dBodySetPosition (bId1, offset, 0, 0);
+
+ CHECK_CLOSE (offset, dJointGetPUPosition (jId), 1e-4);
+
+ dVector3 axis;
+ dJointGetPUAxisP (jId, axis);
+ dJointSetPUAnchorOffset (jId, 0, 0, 0,
+ offset*axis[0],offset*axis[1],offset*axis[2]);
+ CHECK_CLOSE (offset, dJointGetPUPosition (jId), 1e-4);
+
+ dBodySetPosition (bId1, 0, 0, 0);
+ CHECK_CLOSE (0.0, dJointGetPUPosition (jId), 1e-4);
+ }
+
+ // Attache only one body at position 1 to the joint dJointAttach (jId, bId, 0)
+ // Move 1st body offset unit in the opposite X direction
+ //
+ // X-------> X---------> Axis -->
+ // B1 => B1
+ //
+ // Start with a Offset of -offset unit
+ //
+ // X-------> X---------> Axis -->
+ // B1 => B1
+ TEST_FIXTURE (Fixture_dxJointPU_B1_and_B2_At_Zero,
+ test_dJointSetPUAxisOffset_B1_Minus_OffsetUnit)
+ {
+ dJointAttach (jId, bId1, 0);
+
+ CHECK_CLOSE (0.0, dJointGetPUPosition (jId), 1e-4);
+
+ dBodySetPosition (bId1, -offset, 0, 0);
+
+ CHECK_CLOSE (-offset, dJointGetPUPosition (jId), 1e-4);
+
+ dVector3 axis;
+ dJointGetPUAxisP (jId, axis);
+ dJointSetPUAnchorOffset (jId, 0, 0, 0,
+ -offset*axis[0],-offset*axis[1],-offset*axis[2]);
+ CHECK_CLOSE (-offset, dJointGetPUPosition (jId), 1e-4);
+
+ dBodySetPosition (bId1, 0, 0, 0);
+ CHECK_CLOSE (0.0, dJointGetPUPosition (jId), 1e-4);
+ }
+
+
+
+ // Attache only one body at position 2 to the joint dJointAttach (jId, 0, bId)
+ // Move 1st body offset unit in the X direction
+ //
+ // X-------> X---------> Axis -->
+ // B2 => B2
+ //
+ // Start with a Offset of offset unit
+ //
+ // X-------> X---------> Axis -->
+ // B2 => B2
+ TEST_FIXTURE (Fixture_dxJointPU_B1_and_B2_At_Zero,
+ test_dJointSetPUAxisOffset_B2_OffsetUnit)
+ {
+ dJointAttach (jId, 0, bId2);
+
+ CHECK_CLOSE (0.0, dJointGetPUPosition (jId), 1e-4);
+
+ dBodySetPosition (bId2, offset, 0, 0);
+
+ CHECK_CLOSE (-offset, dJointGetPUPosition (jId), 1e-4);
+
+ dVector3 axis;
+ dJointGetPUAxisP (jId, axis);
+ dJointSetPUAnchorOffset (jId, 0, 0, 0,
+ -offset*axis[0], -offset*axis[1], -offset*axis[2]);
+ CHECK_CLOSE (-offset, dJointGetPUPosition (jId), 1e-4);
+
+ dBodySetPosition (bId2, 0, 0, 0);
+ CHECK_CLOSE (0.0, dJointGetPUPosition (jId), 1e-4);
+ }
+
+ // Attache only one body at position 2 to the joint dJointAttach (jId, 0, bId)
+ // Move 1st body offset unit in the opposite X direction
+ //
+ // X-------> X---------> Axis -->
+ // B2 => B2
+ //
+ // Start with a Offset of -offset unit
+ //
+ // X-------> X---------> Axis -->
+ // B2 => B2
+ TEST_FIXTURE (Fixture_dxJointPU_B1_and_B2_At_Zero,
+ test_dJointSetPUAxisOffset_B2_Minus_OffsetUnit)
+ {
+ dJointAttach (jId, 0, bId2);
+
+ CHECK_CLOSE (0.0, dJointGetPUPosition (jId), 1e-4);
+
+ dBodySetPosition (bId2, -offset, 0, 0);
+
+ CHECK_CLOSE (offset, dJointGetPUPosition (jId), 1e-4);
+
+ dVector3 axis;
+ dJointGetPUAxisP (jId, axis);
+ dJointSetPUAnchorOffset (jId, 0, 0, 0,
+ offset*axis[0], offset*axis[1], offset*axis[2]);
+ CHECK_CLOSE (offset, dJointGetPUPosition (jId), 1e-4);
+
+ dBodySetPosition (bId2, 0, 0, 0);
+ CHECK_CLOSE (0.0, dJointGetPUPosition (jId), 1e-4);
+ }
+
+
+
+
+ // Only one body
+ // The body are positionned at (0, 0, 0), with no rotation
+ // The joint is a PU Joint
+ // Axis is in the oppsite X axis
+ // Anchor at (0, 0, 0)
+ // N.B. By default the body is attached at position 1 on the joint
+ // dJointAttach (jId, bId, 0);
+ struct Fixture_dxJointPU_One_Body_At_Zero_Axis_Inverse_of_X
+ {
+ Fixture_dxJointPU_One_Body_At_Zero_Axis_Inverse_of_X()
+ {
+ wId = dWorldCreate();
+
+ bId = dBodyCreate (wId);
+ dBodySetPosition (bId, 0, 0, 0);
+
+ jId = dJointCreatePU (wId, 0);
+ joint = (dxJointPU*) jId;
+
+
+ dJointAttach (jId, bId, NULL);
+
+ dJointSetPUAxisP (jId, axis[0], axis[1], axis[2]);
+ }
+
+ ~Fixture_dxJointPU_One_Body_At_Zero_Axis_Inverse_of_X()
+ {
+ dWorldDestroy (wId);
+ }
+
+ dWorldID wId;
+
+ dBodyID bId;
+
+ dJointID jId;
+ dxJointPU* joint;
+
+ static const dVector3 axis;
+
+ static const dReal offset;
+ };
+ const dVector3 Fixture_dxJointPU_One_Body_At_Zero_Axis_Inverse_of_X::axis =
+ {
+ -1, 0, 0
+ };
+ const dReal Fixture_dxJointPU_One_Body_At_Zero_Axis_Inverse_of_X::offset = REAL (3.1);
+
+
+ // Move 1st body offset unit in the X direction
+ //
+ // X-------> X---------> <--- Axis
+ // B1 => B1
+ //
+ // Start with a Offset of offset unit
+ //
+ // X-------> X---------> <--- Axis
+ // B1 => B1
+ TEST_FIXTURE (Fixture_dxJointPU_One_Body_At_Zero_Axis_Inverse_of_X,
+ test_dJointSetPUAxisOffset_B1_At_Position_1_OffsetUnit)
+ {
+ CHECK_CLOSE (0.0, dJointGetPUPosition (jId), 1e-4);
+
+ dBodySetPosition (bId, offset, 0, 0);
+
+ CHECK_CLOSE (-offset, dJointGetPUPosition (jId), 1e-4);
+
+ dJointSetPUAnchorOffset (jId, 0, 0, 0,
+ -offset*axis[0],-offset*axis[1],-offset*axis[2]);
+ CHECK_CLOSE (-offset, dJointGetPUPosition (jId), 1e-4);
+
+ dBodySetPosition (bId, 0, 0, 0);
+ CHECK_CLOSE (0.0, dJointGetPUPosition (jId), 1e-4);
+ }
+
+ // Move 1st body offset unit in the opposite X direction
+ //
+ // X-------> X---------> <--- Axis
+ // B1 => B1
+ //
+ // Start with a Offset of -offset unit
+ //
+ // X-------> X---------> <--- Axis
+ // B1 => B1
+ TEST_FIXTURE (Fixture_dxJointPU_One_Body_At_Zero_Axis_Inverse_of_X,
+ test_dJointSetPUAxisOffset_B1_Minus_OffsetUnit)
+ {
+ CHECK_CLOSE (0.0, dJointGetPUPosition (jId), 1e-4);
+
+ dBodySetPosition (bId, -offset, 0, 0);
+
+ CHECK_CLOSE (offset, dJointGetPUPosition (jId), 1e-4);
+
+ dJointSetPUAnchorOffset (jId, 0, 0, 0,
+ offset*axis[0],offset*axis[1],offset*axis[2]);
+ CHECK_CLOSE (offset, dJointGetPUPosition (jId), 1e-4);
+
+ dBodySetPosition (bId, 0, 0, 0);
+ CHECK_CLOSE (0.0, dJointGetPUPosition (jId), 1e-4);
+ }
+
+
+ // Move 1st body offset unit in the X direction
+ //
+ // X-------> X---------> <--- Axis
+ // B2 => B2
+ //
+ // Start with a Offset of offset unit
+ //
+ // X-------> X---------> <--- Axis
+ // B2 => B2
+ TEST_FIXTURE (Fixture_dxJointPU_One_Body_At_Zero_Axis_Inverse_of_X,
+ test_dJointSetPUAxisOffset_B2_OffsetUnit)
+ {
+ // By default it is attached to position 1
+ // Now attach the body at positiojn 2
+ dJointAttach(jId, 0, bId);
+
+ CHECK_CLOSE (0.0, dJointGetPUPosition (jId), 1e-4);
+
+ dBodySetPosition (bId, offset, 0, 0);
+
+ CHECK_CLOSE (offset, dJointGetPUPosition (jId), 1e-4);
+
+ dJointSetPUAnchorOffset (jId, 0, 0, 0,
+ offset*axis[0], offset*axis[1], offset*axis[2]);
+ CHECK_CLOSE (offset, dJointGetPUPosition (jId), 1e-4);
+
+ dBodySetPosition (bId, 0, 0, 0);
+ CHECK_CLOSE (0.0, dJointGetPUPosition (jId), 1e-4);
+ }
+
+ // Move 1st body offset unit in the opposite X direction
+ //
+ // X-------> X---------> <--- Axis
+ // B2 => B2
+ //
+ // Start with a Offset of -offset unit
+ //
+ // X-------> X---------> <--- Axis
+ // B2 => B2
+ TEST_FIXTURE (Fixture_dxJointPU_One_Body_At_Zero_Axis_Inverse_of_X,
+ test_dJointSetPUAxisOffset_B2_Minus_OffsetUnit)
+ {
+ // By default it is attached to position 1
+ // Now attach the body at positiojn 2
+ dJointAttach(jId, 0, bId);
+
+ CHECK_CLOSE (0.0, dJointGetPUPosition (jId), 1e-4);
+
+ dBodySetPosition (bId, -offset, 0, 0);
+
+ CHECK_CLOSE (-offset, dJointGetPUPosition (jId), 1e-4);
+
+ dJointSetPUAnchorOffset (jId, 0, 0, 0,
+ -offset*axis[0], -offset*axis[1], -offset*axis[2]);
+ CHECK_CLOSE (-offset, dJointGetPUPosition (jId), 1e-4);
+
+ dBodySetPosition (bId, 0, 0, 0);
+ CHECK_CLOSE (0.0, dJointGetPUPosition (jId), 1e-4);
+ }
+
+
+
+
+
+
+
+
+
+ // Compare only one body to 2 bodies with one fixed.
+ //
+ // The body are positionned at (0, 0, 0), with no rotation
+ // The joint is a PU Joint with default values
+ struct Fixture_dxJointPU_Compare_One_Body_To_Two_Bodies_At_Zero
+ {
+ Fixture_dxJointPU_Compare_One_Body_To_Two_Bodies_At_Zero()
+ {
+ wId = dWorldCreate();
+
+ bId1_12 = dBodyCreate (wId);
+ dBodySetPosition (bId1_12, 0, 0, 0);
+
+ bId2_12 = dBodyCreate (wId);
+ dBodySetPosition (bId2_12, 0, 0, 0);
+ // The force will be added in the function since it is not
+ // always on the same body
+
+ jId_12 = dJointCreatePU (wId, 0);
+ dJointAttach(jId_12, bId1_12, bId2_12);
+
+ fixed = dJointCreateFixed (wId, 0);
+
+
+
+ jId = dJointCreatePU (wId, 0);
+
+ bId = dBodyCreate (wId);
+ dBodySetPosition (bId, 0, 0, 0);
+
+ // Linear velocity along the prismatic axis;
+ dVector3 axis;
+ dJointGetPUAxisP(jId_12, axis);
+ dJointSetPUAxisP(jId, axis[0], axis[1], axis[2]);
+ dBodySetLinearVel (bId, magnitude*axis[0], magnitude*axis[1], magnitude*axis[2]);
+ }
+
+ ~Fixture_dxJointPU_Compare_One_Body_To_Two_Bodies_At_Zero()
+ {
+ dWorldDestroy (wId);
+ }
+
+ dWorldID wId;
+
+ dBodyID bId1_12;
+ dBodyID bId2_12;
+
+ dJointID jId_12; // Joint with 2 bodies
+
+ dJointID fixed;
+
+
+
+ dBodyID bId;
+ dJointID jId; // Joint with one body
+
+ static const dReal magnitude;
+ };
+ const dReal Fixture_dxJointPU_Compare_One_Body_To_Two_Bodies_At_Zero::magnitude = REAL (4.27);
+
+
+ TEST_FIXTURE (Fixture_dxJointPU_Compare_One_Body_To_Two_Bodies_At_Zero,
+ test_dJointSetPUPositionRate_Only_B1)
+ {
+ // Linear velocity along the prismatic axis;
+ dVector3 axis;
+ dJointGetPUAxisP(jId_12, axis);
+ dBodySetLinearVel (bId1_12, magnitude*axis[0], magnitude*axis[1], magnitude*axis[2]);
+
+ dJointAttach(jId_12, bId1_12, bId2_12);
+
+ dJointAttach(fixed, 0, bId2_12);
+ dJointSetFixed(fixed);
+
+ dJointAttach(jId, bId, 0);
+
+ CHECK_CLOSE(dJointGetPUPositionRate(jId_12), dJointGetPUPositionRate(jId), 1e-2);
+ }
+
+
+ TEST_FIXTURE (Fixture_dxJointPU_Compare_One_Body_To_Two_Bodies_At_Zero,
+ test_dJointSetPUPositionRate_Only_B2)
+ {
+ // Linear velocity along the prismatic axis;
+ dVector3 axis;
+ dJointGetPUAxisP(jId_12, axis);
+ dBodySetLinearVel (bId2_12, magnitude*axis[0], magnitude*axis[1], magnitude*axis[2]);
+
+ dJointAttach(jId_12, bId1_12, bId2_12);
+
+ dJointAttach(fixed, bId1_12, 0);
+ dJointSetFixed(fixed);
+
+ dJointAttach(jId, 0, bId);
+
+ CHECK_CLOSE(dJointGetPUPositionRate(jId_12), dJointGetPUPositionRate(jId), 1e-2);
+ }
+
+
+
+
+
+
+
+
+ // This test compare the result of a pu joint with 2 bodies where body body 2 is
+ // fixed to the world to a pu joint with only one body at position 1.
+ //
+ // Test the limits [-1, 0.25] when only one body at is attached to the joint
+ // using dJointAttache(jId, bId, 0);
+ //
+ TEST_FIXTURE(Fixture_dxJointPU_Compare_One_Body_To_Two_Bodies_At_Zero,
+ test_Limit_minus1_025_One_Body_on_left)
+ {
+ dVector3 axis;
+ dJointGetPUAxisP(jId_12, axis);
+ dJointSetPUAxisP(jId, axis[0], axis[1], axis[2]);
+ dBodySetLinearVel (bId1_12, magnitude*axis[0], magnitude*axis[1], magnitude*axis[2]);
+
+ dJointAttach(jId_12, bId1_12, bId2_12);
+ dJointSetPUParam(jId_12, dParamLoStop3, -1);
+ dJointSetPUParam(jId_12, dParamHiStop3, 0.25);
+
+ dJointAttach(fixed, 0, bId2_12);
+ dJointSetFixed(fixed);
+
+ dJointAttach(jId, bId, 0);
+ dJointSetPUParam(jId, dParamLoStop3, -1);
+ dJointSetPUParam(jId, dParamHiStop3, 0.25);
+
+
+ for (int i=0; i<50; ++i)
+ dWorldStep(wId, 1.0);
+
+
+ const dReal *pos1_12 = dBodyGetPosition(bId1_12);
+ const dReal *pos = dBodyGetPosition(bId);
+
+ CHECK_CLOSE (pos1_12[0], pos[0], 1e-2);
+ CHECK_CLOSE (pos1_12[1], pos[1], 1e-2);
+ CHECK_CLOSE (pos1_12[2], pos[2], 1e-2);
+
+ const dReal *q1_12 = dBodyGetQuaternion(bId1_12);
+ const dReal *q = dBodyGetQuaternion(bId);
+
+ CHECK_CLOSE (q1_12[0], q[0], 1e-4);
+ CHECK_CLOSE (q1_12[1], q[1], 1e-4);
+ CHECK_CLOSE (q1_12[2], q[2], 1e-4);
+ CHECK_CLOSE (q1_12[3], q[3], 1e-4);
+
+ // Should be different than zero
+ CHECK( dJointGetPUPosition(jId_12) );
+ CHECK( dJointGetPUPosition(jId) );
+
+ CHECK( dJointGetPUPositionRate(jId_12) );
+ CHECK( dJointGetPUPositionRate(jId) );
+ }
+
+
+
+ // This test compare the result of a pu joint with 2 bodies where body body 1 is
+ // fixed to the world to a pu joint with only one body at position 2.
+ //
+ // Test the limits [-1, 0.25] when only one body at is attached to the joint
+ // using dJointAttache(jId, 0, bId);
+ //
+ TEST_FIXTURE(Fixture_dxJointPU_Compare_One_Body_To_Two_Bodies_At_Zero,
+ test_Limit_minus1_025_One_Body_on_right)
+ {
+ dVector3 axis;
+ dJointGetPUAxisP(jId_12, axis);
+ dJointSetPUAxisP(jId, axis[0], axis[1], axis[2]);
+ dBodySetLinearVel (bId2_12, magnitude*axis[0], magnitude*axis[1], magnitude*axis[2]);
+
+ dJointAttach(jId_12, bId1_12, bId2_12);
+ dJointSetPUParam(jId_12, dParamLoStop3, -1);
+ dJointSetPUParam(jId_12, dParamHiStop3, 0.25);
+
+ dJointAttach(fixed, bId1_12, 0);
+ dJointSetFixed(fixed);
+
+
+ dJointAttach(jId, 0, bId);
+ dJointSetPUParam(jId, dParamLoStop3, -1);
+ dJointSetPUParam(jId, dParamHiStop3, 0.25);
+
+ for (int i=0; i<50; ++i)
+ dWorldStep(wId, 1.0);
+
+
+ const dReal *pos2_12 = dBodyGetPosition(bId2_12);
+ const dReal *pos = dBodyGetPosition(bId);
+
+ CHECK_CLOSE (pos2_12[0], pos[0], 1e-2);
+ CHECK_CLOSE (pos2_12[1], pos[1], 1e-2);
+ CHECK_CLOSE (pos2_12[2], pos[2], 1e-2);
+
+
+ const dReal *q2_12 = dBodyGetQuaternion(bId2_12);
+ const dReal *q = dBodyGetQuaternion(bId);
+
+ CHECK_CLOSE (q2_12[0], q[0], 1e-4);
+ CHECK_CLOSE (q2_12[1], q[1], 1e-4);
+ CHECK_CLOSE (q2_12[2], q[2], 1e-4);
+ CHECK_CLOSE (q2_12[3], q[3], 1e-4);
+
+ // Should be different than zero
+ CHECK( dJointGetPUPosition(jId_12) );
+ CHECK( dJointGetPUPosition(jId) );
+
+ CHECK( dJointGetPUPositionRate(jId_12) );
+ CHECK( dJointGetPUPositionRate(jId) );
+ }
+
+
+
+ // This test compare the result of a pu joint with 2 bodies where body 2 is
+ // fixed to the world to a pu joint with only one body at position 1.
+ //
+ // Test the limits [0, 0] when only one body at is attached to the joint
+ // using dJointAttache(jId, bId, 0);
+ //
+ // The body should not move since their is no room between the two limits
+ //
+ TEST_FIXTURE(Fixture_dxJointPU_Compare_One_Body_To_Two_Bodies_At_Zero,
+ test_Limit_0_0_One_Body_on_left)
+ {
+ dVector3 axis;
+ dJointGetPUAxisP(jId_12, axis);
+ dJointSetPUAxisP(jId, axis[0], axis[1], axis[2]);
+ dBodySetLinearVel (bId1_12, magnitude*axis[0], magnitude*axis[1], magnitude*axis[2]);
+
+ dJointAttach(jId_12, bId1_12, bId2_12);
+ dJointSetPUParam(jId_12, dParamLoStop3, 0);
+ dJointSetPUParam(jId_12, dParamHiStop3, 0);
+
+ dJointAttach(fixed, 0, bId2_12);
+ dJointSetFixed(fixed);
+
+
+ dJointAttach(jId, bId, 0);
+ dJointSetPUParam(jId, dParamLoStop3, 0);
+ dJointSetPUParam(jId, dParamHiStop3, 0);
+
+ for (int i=0; i<500; ++i)
+ dWorldStep(wId, 1.0);
+
+
+ const dReal *pos1_12 = dBodyGetPosition(bId1_12);
+ const dReal *pos = dBodyGetPosition(bId);
+
+ CHECK_CLOSE (pos1_12[0], pos[0], 1e-4);
+ CHECK_CLOSE (pos1_12[1], pos[1], 1e-4);
+ CHECK_CLOSE (pos1_12[2], pos[2], 1e-4);
+
+ CHECK_CLOSE (0, pos[0], 1e-4);
+ CHECK_CLOSE (0, pos[1], 1e-4);
+ CHECK_CLOSE (0, pos[2], 1e-4);
+
+
+ const dReal *q1_12 = dBodyGetQuaternion(bId1_12);
+ const dReal *q = dBodyGetQuaternion(bId);
+
+ CHECK_CLOSE (q1_12[0], q[0], 1e-4);
+ CHECK_CLOSE (q1_12[1], q[1], 1e-4);
+ CHECK_CLOSE (q1_12[2], q[2], 1e-4);
+ CHECK_CLOSE (q1_12[3], q[3], 1e-4);
+ }
+
+
+ // This test compare the result of a pu joint with 2 bodies where body body 1 is
+ // fixed to the world to a pu joint with only one body at position 2.
+ //
+ // Test the limits [0, 0] when only one body at is attached to the joint
+ // using dJointAttache(jId, 0, bId);
+ //
+ // The body should not move since their is no room between the two limits
+ //
+ TEST_FIXTURE(Fixture_dxJointPU_Compare_One_Body_To_Two_Bodies_At_Zero,
+ test_Limit_0_0_One_Body_on_right)
+ {
+ dVector3 axis;
+ dJointGetPUAxisP(jId_12, axis);
+ dJointSetPUAxisP(jId, axis[0], axis[1], axis[2]);
+ dBodySetLinearVel (bId2_12, magnitude*axis[0], magnitude*axis[1], magnitude*axis[2]);
+
+ dJointAttach(jId_12, bId1_12, bId2_12);
+ dJointSetPUParam(jId_12, dParamLoStop3, 0);
+ dJointSetPUParam(jId_12, dParamHiStop3, 0);
+
+ dJointAttach(fixed, bId1_12, 0);
+ dJointSetFixed(fixed);
+
+
+ dJointAttach(jId, 0, bId);
+ dJointSetPUParam(jId, dParamLoStop3, 0);
+ dJointSetPUParam(jId, dParamHiStop3, 0);
+
+ for (int i=0; i<500; ++i)
+ dWorldStep(wId, 1.0);
+
+ const dReal *pos2_12 = dBodyGetPosition(bId2_12);
+ const dReal *pos = dBodyGetPosition(bId);
+
+ CHECK_CLOSE (pos2_12[0], pos[0], 1e-4);
+ CHECK_CLOSE (pos2_12[1], pos[1], 1e-4);
+ CHECK_CLOSE (pos2_12[2], pos[2], 1e-4);
+
+ CHECK_CLOSE (0, pos[0], 1e-4);
+ CHECK_CLOSE (0, pos[1], 1e-4);
+ CHECK_CLOSE (0, pos[2], 1e-4);
+
+
+ const dReal *q2_12 = dBodyGetQuaternion(bId2_12);
+ const dReal *q = dBodyGetQuaternion(bId);
+
+ CHECK_CLOSE (q2_12[0], q[0], 1e-4);
+ CHECK_CLOSE (q2_12[1], q[1], 1e-4);
+ CHECK_CLOSE (q2_12[2], q[2], 1e-4);
+ CHECK_CLOSE (q2_12[3], q[3], 1e-4);
+ }
+
+
+} // End of SUITE TestdxJointPU
+
diff --git a/libs/ode-0.16.1/tests/joints/slider.cpp b/libs/ode-0.16.1/tests/joints/slider.cpp
new file mode 100644
index 0000000..fe57a55
--- /dev/null
+++ b/libs/ode-0.16.1/tests/joints/slider.cpp
@@ -0,0 +1,1332 @@
+
+/*************************************************************************
+ * *
+ * 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. *
+ * *
+ *************************************************************************/
+//234567890123456789012345678901234567890123456789012345678901234567890123456789
+// 1 2 3 4 5 6 7
+
+////////////////////////////////////////////////////////////////////////////////
+// This file create unit test for some of the functions found in:
+// ode/src/joinst/slider.cpp
+//
+//
+////////////////////////////////////////////////////////////////////////////////
+
+#include <UnitTest++.h>
+#include <ode/ode.h>
+
+#include "../../ode/src/config.h"
+#include "../../ode/src/joints/slider.h"
+
+SUITE (TestdxJointSlider)
+{
+ struct dxJointSlider_Fixture_1
+ {
+ dxJointSlider_Fixture_1()
+ {
+ wId = dWorldCreate();
+
+ bId1 = dBodyCreate (wId);
+ dBodySetPosition (bId1, 0, -1, 0);
+
+ bId2 = dBodyCreate (wId);
+ dBodySetPosition (bId2, 0, 1, 0);
+
+ jId = dJointCreateSlider (wId, 0);
+ joint = (dxJointSlider*) jId;
+
+
+ dJointAttach (jId, bId1, bId2);
+ }
+
+ ~dxJointSlider_Fixture_1()
+ {
+ dWorldDestroy (wId);
+ }
+
+ dWorldID wId;
+
+ dBodyID bId1;
+ dBodyID bId2;
+
+
+ dJointID jId;
+ dxJointSlider* joint;
+ };
+
+ TEST_FIXTURE (dxJointSlider_Fixture_1, test_dJointSetSlider)
+ {
+ // the 2 bodies are align
+ dJointSetSliderAxis (jId, 1, 0, 0);
+ CHECK_CLOSE (joint->qrel[0], 1.0, 1e-4);
+ CHECK_CLOSE (joint->qrel[1], 0.0, 1e-4);
+ CHECK_CLOSE (joint->qrel[2], 0.0, 1e-4);
+ CHECK_CLOSE (joint->qrel[3], 0.0, 1e-4);
+
+ dMatrix3 R;
+ // Rotate 2nd body 90deg around X
+ dBodySetPosition (bId2, 0, 0, 1);
+ dRFromAxisAndAngle (R, 1, 0, 0, M_PI/2.0);
+ dBodySetRotation (bId2, R);
+
+ dJointSetSliderAxis (jId, 1, 0 ,0);
+ CHECK_CLOSE (joint->qrel[0], 0.70710678118654757, 1e-4);
+ CHECK_CLOSE (joint->qrel[1], 0.70710678118654757, 1e-4);
+ CHECK_CLOSE (joint->qrel[2], 0.0, 1e-4);
+ CHECK_CLOSE (joint->qrel[3], 0.0, 1e-4);
+
+
+ // Rotate 2nd body -90deg around X
+ dBodySetPosition (bId2, 0, 0, -1);
+ dRFromAxisAndAngle (R, 1, 0, 0, -M_PI/2.0);
+ dBodySetRotation (bId2, R);
+
+ dJointSetSliderAxis (jId, 1, 0 ,0);
+ CHECK_CLOSE (joint->qrel[0], 0.70710678118654757, 1e-4);
+ CHECK_CLOSE (joint->qrel[1], -0.70710678118654757, 1e-4);
+ CHECK_CLOSE (joint->qrel[2], 0.0, 1e-4);
+ CHECK_CLOSE (joint->qrel[3], 0.0, 1e-4);
+
+
+ // Rotate 2nd body 90deg around Z
+ dBodySetPosition (bId2, 0, 1, 0);
+ dRFromAxisAndAngle (R, 0, 0, 1, M_PI/2.0);
+ dBodySetRotation (bId2, R);
+
+ dJointSetSliderAxis (jId, 1, 0 ,0);
+ CHECK_CLOSE (joint->qrel[0], 0.70710678118654757, 1e-4);
+ CHECK_CLOSE (joint->qrel[1], 0.0, 1e-4);
+ CHECK_CLOSE (joint->qrel[2], 0.0, 1e-4);
+ CHECK_CLOSE (joint->qrel[3], 0.70710678118654757, 1e-4);
+
+
+ // Rotate 2nd body 45deg around Y
+ dBodySetPosition (bId2, 0, 1, 0);
+ dRFromAxisAndAngle (R, 0, 1, 0, M_PI/4.0);
+ dBodySetRotation (bId2, R);
+
+ dJointSetSliderAxis (jId, 1, 0 ,0);
+ CHECK_CLOSE (joint->qrel[0], 0.92387953251128674, 1e-4);
+ CHECK_CLOSE (joint->qrel[1], 0.0, 1e-4);
+ CHECK_CLOSE (joint->qrel[2], 0.38268343236508984, 1e-4);
+ CHECK_CLOSE (joint->qrel[3], 0.0, 1e-4);
+
+ // Rotate in a strange manner
+ // Both bodies at origin
+ dRFromEulerAngles (R, REAL(0.23), REAL(3.1), REAL(-0.73));
+ dBodySetPosition (bId1, 0, 0, 0);
+ dBodySetRotation (bId1, R);
+
+ dRFromEulerAngles (R, REAL(-0.57), REAL(1.49), REAL(0.81));
+ dBodySetPosition (bId2, 0, 0, 0);
+ dBodySetRotation (bId2, R);
+
+ dJointSetSliderAxis (jId, 1, 0 ,0);
+ CHECK_CLOSE (joint->qrel[0], -0.25526036263124319, 1e-4);
+ CHECK_CLOSE (joint->qrel[1], 0.28434861188441968, 1e-4);
+ CHECK_CLOSE (joint->qrel[2], -0.65308047160141625, 1e-4);
+ CHECK_CLOSE (joint->qrel[3], 0.65381489108282143, 1e-4);
+ }
+
+
+
+ // The 2 bodies are positionned at (0, 0, 0), with no rotation
+ // The joint is a Slider Joint
+ // Axis is along the X axis
+ // Anchor at (0, 0, 0)
+ struct Fixture_dxJointSlider_B1_and_B2_At_Zero_Axis_Along_X
+ {
+ Fixture_dxJointSlider_B1_and_B2_At_Zero_Axis_Along_X()
+ {
+ wId = dWorldCreate();
+
+ bId1 = dBodyCreate (wId);
+ dBodySetPosition (bId1, 0, 0, 0);
+
+ bId2 = dBodyCreate (wId);
+ dBodySetPosition (bId2, 0, 0, 0);
+
+ jId = dJointCreateSlider (wId, 0);
+ joint = (dxJointSlider*) jId;
+
+
+ dJointAttach (jId, bId1, bId2);
+
+ dJointSetSliderAxis(jId, axis[0], axis[1], axis[2]);
+ }
+
+ ~Fixture_dxJointSlider_B1_and_B2_At_Zero_Axis_Along_X()
+ {
+ dWorldDestroy (wId);
+ }
+
+ dWorldID wId;
+
+ dBodyID bId1;
+ dBodyID bId2;
+
+
+ dJointID jId;
+ dxJointSlider* joint;
+
+ static const dVector3 axis;
+
+ static const dReal offset;
+ };
+ const dVector3 Fixture_dxJointSlider_B1_and_B2_At_Zero_Axis_Along_X::axis = {1, 0, 0};
+ const dReal Fixture_dxJointSlider_B1_and_B2_At_Zero_Axis_Along_X::offset = REAL(3.1);
+
+ // Move 1st body offset unit in the X direction
+ //
+ // X-------> X---------> Axis -->
+ // B1 => B1
+ // B2 B2
+ //
+ // Start with a Offset of offset unit
+ //
+ // X-------> X---------> Axis -->
+ // B1 => B1
+ // B2 B2
+ TEST_FIXTURE (Fixture_dxJointSlider_B1_and_B2_At_Zero_Axis_Along_X,
+ test_dJointSetSliderAxisOffset_B1_3Unit)
+ {
+ CHECK_CLOSE (0.0, dJointGetSliderPosition(jId), 1e-4);
+
+ dBodySetPosition(bId1, offset, 0, 0);
+
+ CHECK_CLOSE (offset, dJointGetSliderPosition(jId), 1e-4);
+ }
+
+ // Move 1st body offset unit in the opposite X direction
+ //
+ // X-------> X---------> Axis -->
+ // B1 => B1
+ // B2 B2
+ //
+ // Start with a Offset of -offset unit
+ //
+ // X-------> X---------> Axis -->
+ // B1 => B1
+ // B2 B2
+ TEST_FIXTURE (Fixture_dxJointSlider_B1_and_B2_At_Zero_Axis_Along_X,
+ test_dJointSetSliderAxisOffset_B1_Minus_3Unit)
+ {
+ CHECK_CLOSE (0.0, dJointGetSliderPosition(jId), 1e-4);
+
+ dBodySetPosition(bId1, -offset, 0, 0);
+
+ CHECK_CLOSE (-offset, dJointGetSliderPosition(jId), 1e-4);
+ }
+
+ // Move 2nd body offset unit in the X direction
+ //
+ // X-------> X---------> Axis -->
+ // B1 => B1
+ // B2 B2
+ //
+ // Start with a Offset of offset unit
+ //
+ // X-------> X---------> Axis -->
+ // B1 => B1
+ // B2 B2
+ TEST_FIXTURE (Fixture_dxJointSlider_B1_and_B2_At_Zero_Axis_Along_X,
+ test_dJointSetSliderAxisOffset_B2_3Unit)
+ {
+ CHECK_CLOSE (0.0, dJointGetSliderPosition(jId), 1e-4);
+
+ dBodySetPosition(bId2, offset, 0, 0);
+
+ CHECK_CLOSE (-offset, dJointGetSliderPosition(jId), 1e-4);
+ }
+
+ // Move 2nd body offset unit in the opposite X direction
+ //
+ // X-------> X---------> Axis -->
+ // B1 => B1
+ // B2 B2
+ //
+ // Start with a Offset of -offset unit
+ //
+ // X-------> X---------> Axis -->
+ // B1 => B1
+ // B2 B2
+ TEST_FIXTURE (Fixture_dxJointSlider_B1_and_B2_At_Zero_Axis_Along_X,
+ test_dJointSetSliderAxisOffset_B2_Minus_3Unit)
+ {
+ CHECK_CLOSE (0.0, dJointGetSliderPosition(jId), 1e-4);
+
+ dBodySetPosition(bId2, -offset, 0, 0);
+
+ CHECK_CLOSE (offset, dJointGetSliderPosition(jId), 1e-4);
+ }
+
+
+
+ // The 2 bodies are positionned at (0, 0, 0), with no rotation
+ // The joint is a Slider Joint
+ // Axis is the opposite of the X axis
+ // Anchor at (0, 0, 0)
+ struct Fixture_dxJointSlider_B1_and_B2_At_Zero_Axis_Inverse_of_X
+ {
+ Fixture_dxJointSlider_B1_and_B2_At_Zero_Axis_Inverse_of_X()
+ {
+ wId = dWorldCreate();
+
+ bId1 = dBodyCreate (wId);
+ dBodySetPosition (bId1, 0, 0, 0);
+
+ bId2 = dBodyCreate (wId);
+ dBodySetPosition (bId2, 0, 0, 0);
+
+ jId = dJointCreateSlider (wId, 0);
+ joint = (dxJointSlider*) jId;
+
+
+ dJointAttach (jId, bId1, bId2);
+
+
+ dJointSetSliderAxis(jId, axis[0], axis[1], axis[2]);
+ }
+
+ ~Fixture_dxJointSlider_B1_and_B2_At_Zero_Axis_Inverse_of_X()
+ {
+ dWorldDestroy (wId);
+ }
+
+ dWorldID wId;
+
+ dBodyID bId1;
+ dBodyID bId2;
+
+
+ dJointID jId;
+ dxJointSlider* joint;
+
+ static const dVector3 axis;
+ static const dReal offset;
+ };
+ const dVector3 Fixture_dxJointSlider_B1_and_B2_At_Zero_Axis_Inverse_of_X::axis = {-1, 0, 0};
+ const dReal Fixture_dxJointSlider_B1_and_B2_At_Zero_Axis_Inverse_of_X::offset = REAL(3.1);
+
+ // Move 1st body offset unit in the X direction
+ //
+ // X-------> X---------> <-- Axis
+ // B1 => B1
+ // B2 B2
+ //
+ // Start with a Offset of offset unit
+ //
+ // X-------> X---------> <-- Axis
+ // B1 => B1
+ // B2 B2
+ TEST_FIXTURE (Fixture_dxJointSlider_B1_and_B2_At_Zero_Axis_Inverse_of_X,
+ test_dJointSetSliderAxisOffset_B1_3Unit)
+ {
+ CHECK_CLOSE (0.0, dJointGetSliderPosition(jId), 1e-4);
+
+ dBodySetPosition(bId1, offset, 0, 0);
+
+ CHECK_CLOSE (-offset, dJointGetSliderPosition(jId), 1e-4);
+ }
+
+ // Move 1st body offset unit in the opposite X direction
+ //
+ // X-------> X---------> <-- Axis
+ // B1 => B1
+ // B2 B2
+ //
+ // Start with a Offset of offset unit
+ //
+ // X-------> X---------> <-- Axis
+ // B1 => B1
+ // B2 B2
+ TEST_FIXTURE (Fixture_dxJointSlider_B1_and_B2_At_Zero_Axis_Inverse_of_X,
+ test_dJointSetSliderAxisOffset_B1_Minus_3Unit)
+ {
+ CHECK_CLOSE (0.0, dJointGetSliderPosition(jId), 1e-4);
+
+ dBodySetPosition(bId1, -offset, 0, 0);
+
+ CHECK_CLOSE (offset, dJointGetSliderPosition(jId), 1e-4);
+ }
+
+ // Move 2nd body offset unit in the X direction
+ //
+ // X-------> X---------> <-- Axis
+ // B1 => B1
+ // B2 B2
+ //
+ // Start with a Offset of offset unit
+ //
+ // X-------> X---------> <-- Axis
+ // B1 => B1
+ // B2 B2
+ TEST_FIXTURE (Fixture_dxJointSlider_B1_and_B2_At_Zero_Axis_Inverse_of_X,
+ test_dJointSetSliderAxisOffset_B2_3Unit)
+ {
+ CHECK_CLOSE (0.0, dJointGetSliderPosition(jId), 1e-4);
+
+ dBodySetPosition(bId2, offset, 0, 0);
+
+ CHECK_CLOSE (offset, dJointGetSliderPosition(jId), 1e-4);
+ }
+
+ // Move 2nd body offset unit in the opposite X direction
+ //
+ // X-------> X---------> <-- Axis
+ // B1 => B1
+ // B2 B2
+ //
+ // Start with a Offset of -offset unit
+ //
+ // X-------> X---------> <-- Axis
+ // B1 => B1
+ // B2 B2
+ TEST_FIXTURE (Fixture_dxJointSlider_B1_and_B2_At_Zero_Axis_Inverse_of_X,
+ test_dJointSetSliderAxisOffset_B2_Minus_3Unit)
+ {
+ CHECK_CLOSE (0.0, dJointGetSliderPosition(jId), 1e-4);
+
+ dBodySetPosition(bId2, -offset, 0, 0);
+
+ CHECK_CLOSE (-offset, dJointGetSliderPosition(jId), 1e-4);
+ }
+
+
+ // Only body 1
+ // The body are positionned at (0, 0, 0), with no rotation
+ // The joint is a Slider Joint
+ // Axis is along the X axis
+ // Anchor at (0, 0, 0)
+ struct Fixture_dxJointSlider_B1_At_Zero_Axis_Along_X
+ {
+ Fixture_dxJointSlider_B1_At_Zero_Axis_Along_X()
+ {
+ wId = dWorldCreate();
+
+ bId1 = dBodyCreate (wId);
+ dBodySetPosition (bId1, 0, 0, 0);
+
+ jId = dJointCreateSlider (wId, 0);
+ joint = (dxJointSlider*) jId;
+
+
+ dJointAttach (jId, bId1, NULL);
+
+ dJointSetSliderAxis(jId, axis[0], axis[1], axis[2]);
+ }
+
+ ~Fixture_dxJointSlider_B1_At_Zero_Axis_Along_X()
+ {
+ dWorldDestroy (wId);
+ }
+
+ dWorldID wId;
+
+ dBodyID bId1;
+
+ dJointID jId;
+ dxJointSlider* joint;
+
+ static const dVector3 axis;
+
+ static const dReal offset;
+ };
+ const dVector3 Fixture_dxJointSlider_B1_At_Zero_Axis_Along_X::axis = {1, 0, 0};
+ const dReal Fixture_dxJointSlider_B1_At_Zero_Axis_Along_X::offset = REAL(3.1);
+
+ // Move 1st body offset unit in the X direction
+ //
+ // X-------> X---------> Axis -->
+ // B1 => B1
+ //
+ TEST_FIXTURE (Fixture_dxJointSlider_B1_At_Zero_Axis_Along_X,
+ test_dJointSetSliderAxisOffset_B1_OffsetUnit)
+ {
+ CHECK_CLOSE (0.0, dJointGetSliderPosition(jId), 1e-4);
+
+ dBodySetPosition(bId1, offset, 0, 0);
+
+ CHECK_CLOSE (offset, dJointGetSliderPosition(jId), 1e-4);
+ }
+
+ // Move 1st body offset unit in the opposite X direction
+ //
+ // X-------> X---------> Axis -->
+ // B1 => B1
+ //
+ TEST_FIXTURE (Fixture_dxJointSlider_B1_At_Zero_Axis_Along_X,
+ test_dJointSetSliderAxisOffset_B1_Minus_OffsetUnit)
+ {
+ CHECK_CLOSE (0.0, dJointGetSliderPosition(jId), 1e-4);
+
+ dBodySetPosition(bId1, -offset, 0, 0);
+
+ CHECK_CLOSE (-offset, dJointGetSliderPosition(jId), 1e-4);
+ }
+
+
+ // Only body 1
+ // The body are positionned at (0, 0, 0), with no rotation
+ // The joint is a Slider Joint
+ // Axis is in the oppsite X axis
+ // Anchor at (0, 0, 0)
+ struct Fixture_dxJointSlider_B1_At_Zero_Axis_Inverse_of_X
+ {
+ Fixture_dxJointSlider_B1_At_Zero_Axis_Inverse_of_X()
+ {
+ wId = dWorldCreate();
+
+ bId1 = dBodyCreate (wId);
+ dBodySetPosition (bId1, 0, 0, 0);
+
+ jId = dJointCreateSlider (wId, 0);
+ joint = (dxJointSlider*) jId;
+
+
+ dJointAttach (jId, bId1, NULL);
+
+ dJointSetSliderAxis(jId, axis[0], axis[1], axis[2]);
+ }
+
+ ~Fixture_dxJointSlider_B1_At_Zero_Axis_Inverse_of_X()
+ {
+ dWorldDestroy (wId);
+ }
+
+ dWorldID wId;
+
+ dBodyID bId1;
+
+ dJointID jId;
+ dxJointSlider* joint;
+
+ static const dVector3 axis;
+
+ static const dReal offset;
+ };
+ const dVector3 Fixture_dxJointSlider_B1_At_Zero_Axis_Inverse_of_X::axis = {-1, 0, 0};
+ const dReal Fixture_dxJointSlider_B1_At_Zero_Axis_Inverse_of_X::offset = REAL(3.1);
+
+ // Move 1st body offset unit in the X direction
+ //
+ // X-------> X---------> <--- Axis
+ // B1 => B1
+ //
+ TEST_FIXTURE (Fixture_dxJointSlider_B1_At_Zero_Axis_Inverse_of_X,
+ test_dJointSetSliderAxisOffset_B1_OffsetUnit)
+ {
+ CHECK_CLOSE (0.0, dJointGetSliderPosition(jId), 1e-4);
+
+ dBodySetPosition(bId1, offset, 0, 0);
+
+ CHECK_CLOSE (-offset, dJointGetSliderPosition(jId), 1e-4);
+ }
+
+ // Move 1st body offset unit in the opposite X direction
+ //
+ // X-------> X---------> <--- Axis
+ // B1 => B1
+ //
+ TEST_FIXTURE (Fixture_dxJointSlider_B1_At_Zero_Axis_Inverse_of_X,
+ test_dJointSetSliderAxisOffset_B1_Minus_OffsetUnit)
+ {
+ CHECK_CLOSE (0.0, dJointGetSliderPosition(jId), 1e-4);
+
+ dBodySetPosition(bId1, -offset, 0, 0);
+
+ CHECK_CLOSE (offset, dJointGetSliderPosition(jId), 1e-4);
+ }
+
+
+ // Only body 2
+ // The body are positionned at (0, 0, 0), with no rotation
+ // The joint is a Slider Joint
+ // Axis is along the X axis
+ // Anchor at (0, 0, 0)
+ struct Fixture_dxJointSlider_B2_At_Zero_Axis_Along_X
+ {
+ Fixture_dxJointSlider_B2_At_Zero_Axis_Along_X()
+ {
+ wId = dWorldCreate();
+
+ bId2 = dBodyCreate (wId);
+ dBodySetPosition (bId2, 0, 0, 0);
+
+ jId = dJointCreateSlider (wId, 0);
+ joint = (dxJointSlider*) jId;
+
+
+ dJointAttach (jId, NULL, bId2);
+
+ dJointSetSliderAxis(jId, axis[0], axis[1], axis[2]);
+ }
+
+ ~Fixture_dxJointSlider_B2_At_Zero_Axis_Along_X()
+ {
+ dWorldDestroy (wId);
+ }
+
+ dWorldID wId;
+
+ dBodyID bId2;
+
+ dJointID jId;
+ dxJointSlider* joint;
+
+ static const dVector3 axis;
+
+ static const dReal offset;
+ };
+ const dVector3 Fixture_dxJointSlider_B2_At_Zero_Axis_Along_X::axis = {1, 0, 0};
+ const dReal Fixture_dxJointSlider_B2_At_Zero_Axis_Along_X::offset = REAL(3.1);
+
+ // Move 2nd body offset unit in the X direction
+ //
+ // X-------> X---------> Axis -->
+ // B2 => B2
+ //
+ TEST_FIXTURE (Fixture_dxJointSlider_B2_At_Zero_Axis_Along_X,
+ test_dJointSetSliderAxisOffset_B2_OffsetUnit)
+ {
+ CHECK_CLOSE (0.0, dJointGetSliderPosition(jId), 1e-4);
+
+ dBodySetPosition(bId2, offset, 0, 0);
+
+ CHECK_CLOSE (-offset, dJointGetSliderPosition(jId), 1e-4);
+ }
+
+ // Move 2nd body offset unit in the opposite X direction
+ //
+ // X-------> X---------> Axis -->
+ // B2 => B2
+ //
+ TEST_FIXTURE (Fixture_dxJointSlider_B2_At_Zero_Axis_Along_X,
+ test_dJointSetSliderAxisOffset_B2_Minus_OffsetUnit)
+ {
+ CHECK_CLOSE (0.0, dJointGetSliderPosition(jId), 1e-4);
+
+ dBodySetPosition(bId2, -offset, 0, 0);
+
+ CHECK_CLOSE (offset, dJointGetSliderPosition(jId), 1e-4);
+ }
+
+ // Only body 2
+ // The body are positionned at (0, 0, 0), with no rotation
+ // The joint is a Slider Joint
+ // Axis is in the oppsite X axis
+ // Anchor at (0, 0, 0)
+ struct Fixture_dxJointSlider_B2_At_Zero_Axis_Inverse_of_X
+ {
+ Fixture_dxJointSlider_B2_At_Zero_Axis_Inverse_of_X()
+ {
+ wId = dWorldCreate();
+
+ bId2 = dBodyCreate (wId);
+ dBodySetPosition (bId2, 0, 0, 0);
+
+ jId = dJointCreateSlider (wId, 0);
+ joint = (dxJointSlider*) jId;
+
+
+ dJointAttach (jId, NULL, bId2);
+
+ dJointSetSliderAxis(jId, axis[0], axis[1], axis[2]);
+ }
+
+ ~Fixture_dxJointSlider_B2_At_Zero_Axis_Inverse_of_X()
+ {
+ dWorldDestroy (wId);
+ }
+
+ dWorldID wId;
+
+ dBodyID bId2;
+
+ dJointID jId;
+ dxJointSlider* joint;
+
+ static const dVector3 axis;
+
+ static const dReal offset;
+ };
+ const dVector3 Fixture_dxJointSlider_B2_At_Zero_Axis_Inverse_of_X::axis = {-1, 0, 0};
+ const dReal Fixture_dxJointSlider_B2_At_Zero_Axis_Inverse_of_X::offset = REAL(3.1);
+
+ // Move 2nd body offset unit in the X direction
+ //
+ // X-------> X---------> <--- Axis
+ // B2 => B2
+ //
+ TEST_FIXTURE (Fixture_dxJointSlider_B2_At_Zero_Axis_Inverse_of_X,
+ test_dJointSetSliderAxisOffset_B2_OffsetUnit)
+ {
+ CHECK_CLOSE (0.0, dJointGetSliderPosition(jId), 1e-4);
+
+ dBodySetPosition(bId2, offset, 0, 0);
+
+ CHECK_CLOSE (offset, dJointGetSliderPosition(jId), 1e-4);
+ }
+
+ // Move 2nd body offset unit in the opposite X direction
+ //
+ // X-------> X---------> <--- Axis
+ // B2 => B2
+ //
+ TEST_FIXTURE (Fixture_dxJointSlider_B2_At_Zero_Axis_Inverse_of_X,
+ test_dJointSetSliderAxisOffset_B2_Minus_OffsetUnit)
+ {
+ CHECK_CLOSE (0.0, dJointGetSliderPosition(jId), 1e-4);
+
+ dBodySetPosition(bId2, -offset, 0, 0);
+
+ CHECK_CLOSE (-offset, dJointGetSliderPosition(jId), 1e-4);
+ }
+
+ // ==========================================================================
+ // Test Position Rate
+ // ==========================================================================
+
+
+ // Apply force on 1st body in the X direction also the Axis direction
+ //
+ // X-------> X---------> Axis -->
+ // B1 F-> => B1
+ // B2 B2
+ TEST_FIXTURE (Fixture_dxJointSlider_B1_and_B2_At_Zero_Axis_Along_X,
+ test_dJointSetSliderPositionRate_Force_Along_Axis_on_B1)
+ {
+ CHECK_CLOSE (0.0, dJointGetSliderPosition(jId), 1e-4);
+ CHECK_CLOSE (0.0, dJointGetSliderPositionRate(jId), 1e-4);
+
+ dBodyAddForce(bId1, 1.0, 0, 0);
+ dWorldQuickStep (wId, 1.0);
+
+ CHECK_CLOSE (1, dJointGetSliderPositionRate(jId), 1e-4);
+ }
+
+ // Apply force on 1st body in the inverse X direction
+ //
+ // X-------> X---------> Axis -->
+ // B1 <-F => B1
+ // B2 B2
+ TEST_FIXTURE (Fixture_dxJointSlider_B1_and_B2_At_Zero_Axis_Along_X,
+ test_dJointSetSliderPositionRate_Force_Inverse_of_Axis_on_B1)
+ {
+ CHECK_CLOSE (0.0, dJointGetSliderPosition(jId), 1e-4);
+ CHECK_CLOSE (0.0, dJointGetSliderPositionRate(jId), 1e-4);
+
+ dBodyAddForce(bId1, -1.0, 0, 0);
+ dWorldQuickStep (wId, 1.0);
+
+ CHECK_CLOSE (-1, dJointGetSliderPositionRate(jId), 1e-4);
+ }
+
+
+ // Apply force on 1st body in the X direction also the Axis direction
+ //
+ // X-------> X---------> <-- Axis
+ // B1 F-> => B1
+ // B2 B2
+ TEST_FIXTURE (Fixture_dxJointSlider_B1_and_B2_At_Zero_Axis_Inverse_of_X,
+ test_dJointSetSliderPositionRate_Force_Inverse_Axis_on_B1)
+ {
+ CHECK_CLOSE (0.0, dJointGetSliderPosition(jId), 1e-4);
+ CHECK_CLOSE (0.0, dJointGetSliderPositionRate(jId), 1e-4);
+
+ dBodyAddForce(bId1, 1.0, 0, 0);
+ dWorldQuickStep (wId, 1.0);
+
+ CHECK_CLOSE (-1, dJointGetSliderPositionRate(jId), 1e-4);
+ }
+
+ // Apply force on 1st body in the inverse X direction
+ //
+ // X-------> X---------> <-- Axis
+ // B1 <-F => B1
+ // B2 B2
+ TEST_FIXTURE (Fixture_dxJointSlider_B1_and_B2_At_Zero_Axis_Inverse_of_X,
+ test_dJointSetSliderPositionRate_Force_Along_of_Axis_on_B1)
+ {
+ CHECK_CLOSE (0.0, dJointGetSliderPosition(jId), 1e-4);
+ CHECK_CLOSE (0.0, dJointGetSliderPositionRate(jId), 1e-4);
+
+ dBodyAddForce(bId1, -1.0, 0, 0);
+ dWorldQuickStep (wId, 1.0);
+
+ CHECK_CLOSE (1, dJointGetSliderPositionRate(jId), 1e-4);
+ }
+
+ // Apply force on 1st body in the X direction also the Axis direction
+ //
+ // X-------> X---------> Axis -->
+ // B1 => B1
+ // B2 F-> B2
+ TEST_FIXTURE (Fixture_dxJointSlider_B1_and_B2_At_Zero_Axis_Along_X,
+ test_dJointSetSliderPositionRate_Force_Along_Axis_on_B2)
+ {
+ CHECK_CLOSE (0.0, dJointGetSliderPosition(jId), 1e-4);
+ CHECK_CLOSE (0.0, dJointGetSliderPositionRate(jId), 1e-4);
+
+ dBodyAddForce(bId2, 1.0, 0, 0);
+ dWorldQuickStep (wId, 1.0);
+
+ CHECK_CLOSE (-1, dJointGetSliderPositionRate(jId), 1e-4);
+ }
+
+ // Apply force on 1st body in the inverse X direction
+ //
+ // X-------> X---------> Axis -->
+ // B1 => B1
+ // B2 <-F B2
+ TEST_FIXTURE (Fixture_dxJointSlider_B1_and_B2_At_Zero_Axis_Along_X,
+ test_dJointSetSliderPositionRate_Force_Inverse_of_Axis_on_B2)
+ {
+ CHECK_CLOSE (0.0, dJointGetSliderPosition(jId), 1e-4);
+ CHECK_CLOSE (0.0, dJointGetSliderPositionRate(jId), 1e-4);
+
+ dBodyAddForce(bId2, -1.0, 0, 0);
+ dWorldQuickStep (wId, 1.0);
+
+ CHECK_CLOSE (1, dJointGetSliderPositionRate(jId), 1e-4);
+ }
+
+
+ // Apply force on 1st body in the X direction also the Axis direction
+ //
+ // X-------> X---------> <-- Axis
+ // B1 => B1
+ // B2 F-> B2
+ TEST_FIXTURE (Fixture_dxJointSlider_B1_and_B2_At_Zero_Axis_Inverse_of_X,
+ test_dJointSetSliderPositionRate_Force_Inverse_Axis_on_B2)
+ {
+ CHECK_CLOSE (0.0, dJointGetSliderPosition(jId), 1e-4);
+ CHECK_CLOSE (0.0, dJointGetSliderPositionRate(jId), 1e-4);
+
+ dBodyAddForce(bId2, 1.0, 0, 0);
+ dWorldQuickStep (wId, 1.0);
+
+ CHECK_CLOSE (1, dJointGetSliderPositionRate(jId), 1e-4);
+ }
+
+ // Apply force on 1st body in the inverse X direction
+ //
+ // X-------> X---------> <-- Axis
+ // B1 => B1
+ // B2 <-F B2
+ TEST_FIXTURE (Fixture_dxJointSlider_B1_and_B2_At_Zero_Axis_Inverse_of_X,
+ test_dJointSetSliderPositionRate_Force_Along_of_Axis_on_B2)
+ {
+ CHECK_CLOSE (0.0, dJointGetSliderPosition(jId), 1e-4);
+ CHECK_CLOSE (0.0, dJointGetSliderPositionRate(jId), 1e-4);
+
+ dBodyAddForce(bId2, -1.0, 0, 0);
+ dWorldQuickStep (wId, 1.0);
+
+ CHECK_CLOSE (-1, dJointGetSliderPositionRate(jId), 1e-4);
+ }
+
+
+
+ // Apply force on 1st body in the X direction also the Axis direction
+ //
+ // X-------> X---------> Axis -->
+ // B1 F-> => B1
+ TEST_FIXTURE (Fixture_dxJointSlider_B1_At_Zero_Axis_Along_X,
+ test_dJointSetSliderPositionRate_Force_Along_Axis_on_B1)
+ {
+ CHECK_CLOSE (0.0, dJointGetSliderPosition(jId), 1e-4);
+ CHECK_CLOSE (0.0, dJointGetSliderPositionRate(jId), 1e-4);
+
+ dBodyAddForce(bId1, 1.0, 0, 0);
+ dWorldQuickStep (wId, 1.0);
+
+ CHECK_CLOSE (1, dJointGetSliderPositionRate(jId), 1e-4);
+ }
+
+ // Apply force on 1st body in the inverse X direction
+ //
+ // X-------> X---------> Axis -->
+ // B1 <-F => B1
+ TEST_FIXTURE (Fixture_dxJointSlider_B1_At_Zero_Axis_Along_X,
+ test_dJointSetSliderPositionRate_Force_Inverse_of_Axis_on_B1)
+ {
+ CHECK_CLOSE (0.0, dJointGetSliderPosition(jId), 1e-4);
+ CHECK_CLOSE (0.0, dJointGetSliderPositionRate(jId), 1e-4);
+
+ dBodyAddForce(bId1, -1.0, 0, 0);
+ dWorldQuickStep (wId, 1.0);
+
+ CHECK_CLOSE (-1, dJointGetSliderPositionRate(jId), 1e-4);
+ }
+
+
+ // Apply force on 1st body in the X direction also the Axis direction
+ //
+ // X-------> X---------> <-- Axis
+ // B1 F-> => B1
+ TEST_FIXTURE (Fixture_dxJointSlider_B1_At_Zero_Axis_Inverse_of_X,
+ test_dJointSetSliderPositionRate_Force_Inverse_Axis_on_B1)
+ {
+ CHECK_CLOSE (0.0, dJointGetSliderPosition(jId), 1e-4);
+ CHECK_CLOSE (0.0, dJointGetSliderPositionRate(jId), 1e-4);
+
+ dBodyAddForce(bId1, 1.0, 0, 0);
+ dWorldQuickStep (wId, 1.0);
+
+ CHECK_CLOSE (-1, dJointGetSliderPositionRate(jId), 1e-4);
+ }
+
+ // Apply force on 1st body in the inverse X direction
+ //
+ // X-------> X---------> <-- Axis
+ // B1 <-F => B1
+ TEST_FIXTURE (Fixture_dxJointSlider_B1_At_Zero_Axis_Inverse_of_X,
+ test_dJointSetSliderPositionRate_Force_Along_of_Axis_on_B1)
+ {
+ CHECK_CLOSE (0.0, dJointGetSliderPosition(jId), 1e-4);
+ CHECK_CLOSE (0.0, dJointGetSliderPositionRate(jId), 1e-4);
+
+ dBodyAddForce(bId1, -1.0, 0, 0);
+ dWorldQuickStep (wId, 1.0);
+
+ CHECK_CLOSE (1, dJointGetSliderPositionRate(jId), 1e-4);
+ }
+
+
+ // Apply force on body 2 in the X direction also the Axis direction
+ //
+ // X-------> X---------> Axis -->
+ // B2 F-> B2
+ TEST_FIXTURE (Fixture_dxJointSlider_B2_At_Zero_Axis_Along_X,
+ test_dJointSetSliderPositionRate_Force_Along_Axis_on_B2)
+ {
+ CHECK_CLOSE (0.0, dJointGetSliderPosition(jId), 1e-4);
+ CHECK_CLOSE (0.0, dJointGetSliderPositionRate(jId), 1e-4);
+
+ dBodyAddForce(bId2, 1.0, 0, 0);
+ dWorldQuickStep (wId, 1.0);
+
+ CHECK_CLOSE (-1, dJointGetSliderPositionRate(jId), 1e-4);
+ }
+
+ // Apply force on body 2 in the inverse X direction
+ //
+ // X-------> X---------> Axis -->
+ // B2 <-F B2
+ TEST_FIXTURE (Fixture_dxJointSlider_B2_At_Zero_Axis_Along_X,
+ test_dJointSetSliderPositionRate_Force_Inverse_of_Axis_on_B2)
+ {
+ CHECK_CLOSE (0.0, dJointGetSliderPosition(jId), 1e-4);
+ CHECK_CLOSE (0.0, dJointGetSliderPositionRate(jId), 1e-4);
+
+ dBodyAddForce(bId2, -1.0, 0, 0);
+ dWorldQuickStep (wId, 1.0);
+
+ CHECK_CLOSE (1, dJointGetSliderPositionRate(jId), 1e-4);
+ }
+
+
+ // Apply force on body 2 in the X direction also the Axis direction
+ //
+ // X-------> X---------> <-- Axis
+ // B2 F-> B2
+ TEST_FIXTURE (Fixture_dxJointSlider_B2_At_Zero_Axis_Inverse_of_X,
+ test_dJointSetSliderPositionRate_Force_Inverse_Axis_on_B2)
+ {
+ CHECK_CLOSE (0.0, dJointGetSliderPosition(jId), 1e-4);
+ CHECK_CLOSE (0.0, dJointGetSliderPositionRate(jId), 1e-4);
+
+ dBodyAddForce(bId2, 1.0, 0, 0);
+ dWorldQuickStep (wId, 1.0);
+
+ CHECK_CLOSE (1, dJointGetSliderPositionRate(jId), 1e-4);
+ }
+
+ // Apply force on body 2 in the inverse X direction
+ //
+ // X-------> X---------> <-- Axis
+ // B2 <-F B2
+ TEST_FIXTURE (Fixture_dxJointSlider_B2_At_Zero_Axis_Inverse_of_X,
+ test_dJointSetSliderPositionRate_Force_Along_of_Axis_on_B2)
+ {
+ CHECK_CLOSE (0.0, dJointGetSliderPosition(jId), 1e-4);
+ CHECK_CLOSE (0.0, dJointGetSliderPositionRate(jId), 1e-4);
+
+ dBodyAddForce(bId2, -1.0, 0, 0);
+ dWorldQuickStep (wId, 1.0);
+
+ CHECK_CLOSE (-1, dJointGetSliderPositionRate(jId), 1e-4);
+ }
+
+
+
+
+
+
+ // Create 2 bodies attached by a Slider joint
+ // Axis is along the X axis (Default value
+ // Anchor at (0, 0, 0) (Default value)
+ //
+ // ^Y
+ // |
+ // |
+ // |
+ // |
+ // Body1 | Body2
+ // * Z-----*->x
+ struct dxJointSlider_Test_Initialization
+ {
+ dxJointSlider_Test_Initialization()
+ {
+ wId = dWorldCreate();
+
+ // Remove gravity to have the only force be the force of the joint
+ dWorldSetGravity(wId, 0,0,0);
+
+ for (int j=0; j<2; ++j)
+ {
+ bId[j][0] = dBodyCreate (wId);
+ dBodySetPosition (bId[j][0], -1, -2, -3);
+
+ bId[j][1] = dBodyCreate (wId);
+ dBodySetPosition (bId[j][1], 11, 22, 33);
+
+
+ dMatrix3 R;
+ dVector3 axis; // Random axis
+
+ axis[0] = REAL(0.53);
+ axis[1] = -REAL(0.71);
+ axis[2] = REAL(0.43);
+ dNormalize3(axis);
+ dRFromAxisAndAngle (R, axis[0], axis[1], axis[2],
+ REAL(0.47123)); // 27deg
+ dBodySetRotation (bId[j][0], R);
+
+
+ axis[0] = REAL(1.2);
+ axis[1] = REAL(0.87);
+ axis[2] = -REAL(0.33);
+ dNormalize3(axis);
+ dRFromAxisAndAngle (R, axis[0], axis[1], axis[2],
+ REAL(0.47123)); // 27deg
+ dBodySetRotation (bId[j][1], R);
+
+
+ jId[j] = dJointCreateSlider (wId, 0);
+ dJointAttach (jId[j], bId[j][0], bId[j][1]);
+ }
+ }
+
+ ~dxJointSlider_Test_Initialization()
+ {
+ dWorldDestroy (wId);
+ }
+
+ dWorldID wId;
+
+ dBodyID bId[2][2];
+
+
+ dJointID jId[2];
+
+ };
+
+
+ // Test if setting a Slider joint with its default values
+ // will behave the same as a default Slider joint
+ TEST_FIXTURE (dxJointSlider_Test_Initialization,
+ test_Slider_Initialization)
+ {
+ using namespace std;
+
+ dVector3 axis;
+ dJointGetSliderAxis(jId[1], axis);
+ dJointSetSliderAxis(jId[1], axis[0], axis[1], axis[2]);
+
+
+ CHECK_CLOSE (dJointGetSliderPosition(jId[0]),
+ dJointGetSliderPosition(jId[1]), 1e-6);
+
+
+ for (int b=0; b<2; ++b)
+ {
+ // Compare body b of the first joint with its equivalent on the
+ // second joint
+ const dReal *qA = dBodyGetQuaternion(bId[0][b]);
+ const dReal *qB = dBodyGetQuaternion(bId[1][b]);
+ CHECK_CLOSE (qA[0], qB[0], 1e-6);
+ CHECK_CLOSE (qA[1], qB[1], 1e-6);
+ CHECK_CLOSE (qA[2], qB[2], 1e-6);
+ CHECK_CLOSE (qA[3], qB[3], 1e-6);
+ }
+
+ dWorldStep (wId,0.5);
+ dWorldStep (wId,0.5);
+ dWorldStep (wId,0.5);
+ dWorldStep (wId,0.5);
+
+ for (int b=0; b<2; ++b)
+ {
+ // Compare body b of the first joint with its equivalent on the
+ // second joint
+ const dReal *qA = dBodyGetQuaternion(bId[0][b]);
+ const dReal *qB = dBodyGetQuaternion(bId[1][b]);
+ CHECK_CLOSE (qA[0], qB[0], 1e-6);
+ CHECK_CLOSE (qA[1], qB[1], 1e-6);
+ CHECK_CLOSE (qA[2], qB[2], 1e-6);
+ CHECK_CLOSE (qA[3], qB[3], 1e-6);
+
+
+ const dReal *posA = dBodyGetPosition(bId[0][b]);
+ const dReal *posB = dBodyGetPosition(bId[1][b]);
+ CHECK_CLOSE (posA[0], posB[0], 1e-6);
+ CHECK_CLOSE (posA[1], posB[1], 1e-6);
+ CHECK_CLOSE (posA[2], posB[2], 1e-6);
+ CHECK_CLOSE (posA[3], posB[3], 1e-6);
+ }
+ }
+
+
+
+ // Compare Only body 1 to 2 bodies with one fixed.
+ //
+ // The body are positionned at (0, 0, 0), with no rotation
+ // The joint is a Slider Joint
+ // Axis is along the X axis
+ // Anchor at (0, 0, 0)
+ struct Fixture_dxJointSlider_Compare_Body_At_Zero_Axis_Along_X
+ {
+ Fixture_dxJointSlider_Compare_Body_At_Zero_Axis_Along_X()
+ {
+ wId = dWorldCreate();
+
+ bId1_12 = dBodyCreate (wId);
+ dBodySetPosition (bId1_12, 0, 0, 0);
+
+ bId2_12 = dBodyCreate (wId);
+ dBodySetPosition (bId2_12, 0, 0, 0);
+ // The force will be added in the function since it is not
+ // always on the same body
+
+ jId_12 = dJointCreateSlider (wId, 0);
+ dJointAttach(jId_12, bId1_12, bId2_12);
+
+ fixed = dJointCreateFixed (wId, 0);
+
+
+
+ bId = dBodyCreate (wId);
+ dBodySetPosition (bId, 0, 0, 0);
+
+ dBodyAddForce (bId, 4, 0, 0);
+
+ jId = dJointCreateSlider (wId, 0);
+ }
+
+ ~Fixture_dxJointSlider_Compare_Body_At_Zero_Axis_Along_X()
+ {
+ dWorldDestroy (wId);
+ }
+
+ dWorldID wId;
+
+ dBodyID bId1_12;
+ dBodyID bId2_12;
+
+ dJointID jId_12; // Joint with 2 bodies
+
+ dJointID fixed;
+
+
+
+ dBodyID bId;
+ dJointID jId; // Joint with one body
+ };
+
+ // This test compare the result of a slider with 2 bodies where body body 2 is
+ // fixed to the world to a slider with only one body at position 1.
+ //
+ // Test the limits [-1, 0.25] when only one body at is attached to the joint
+ // using dJointAttache(jId, bId, 0);
+ //
+ TEST_FIXTURE(Fixture_dxJointSlider_Compare_Body_At_Zero_Axis_Along_X,
+ test_Limit_minus1_025_One_Body_on_left)
+ {
+ dBodyAddForce (bId1_12, 4, 0, 0);
+
+ dJointAttach(jId_12, bId1_12, bId2_12);
+ dJointSetSliderParam(jId_12, dParamLoStop, -1);
+ dJointSetSliderParam(jId_12, dParamHiStop, 0.25);
+
+ dJointAttach(fixed, 0, bId2_12);
+ dJointSetFixed(fixed);
+
+ dJointAttach(jId, bId, 0);
+ dJointSetSliderParam(jId, dParamLoStop, -1);
+ dJointSetSliderParam(jId, dParamHiStop, 0.25);
+
+
+ for (int i=0; i<50; ++i)
+ dWorldStep(wId, 1.0);
+
+ const dReal *pos1_12 = dBodyGetPosition(bId1_12);
+
+ const dReal *pos = dBodyGetPosition(bId);
+
+
+ CHECK_CLOSE (pos[0], pos1_12[0], 1e-2);
+ CHECK_CLOSE (pos[1], pos1_12[1], 1e-2);
+ CHECK_CLOSE (pos[2], pos1_12[2], 1e-2);
+ }
+
+
+
+ // This test compare the result of a slider with 2 bodies where body body 1 is
+ // fixed to the world to a slider with only one body at position 2.
+ //
+ // Test the limits [-1, 0.25] when only one body at is attached to the joint
+ // using dJointAttache(jId, 0, bId);
+ //
+ TEST_FIXTURE(Fixture_dxJointSlider_Compare_Body_At_Zero_Axis_Along_X,
+ test_Limit_minus1_025_One_Body_on_right)
+ {
+ dBodyAddForce (bId2_12, 4, 0, 0);
+
+ dJointAttach(jId_12, bId1_12, bId2_12);
+ dJointSetSliderParam(jId_12, dParamLoStop, -1);
+ dJointSetSliderParam(jId_12, dParamHiStop, 0.25);
+
+ dJointAttach(fixed, bId1_12, 0);
+ dJointSetFixed(fixed);
+
+
+ dJointAttach(jId, 0, bId);
+ dJointSetSliderParam(jId, dParamLoStop, -1);
+ dJointSetSliderParam(jId, dParamHiStop, 0.25);
+
+ for (int i=0; i<50; ++i)
+ {
+ dWorldStep(wId, 1.0);
+ }
+
+ const dReal *pos2_12 = dBodyGetPosition(bId2_12);
+
+ const dReal *pos = dBodyGetPosition(bId);
+
+
+ CHECK_CLOSE (pos[0], pos2_12[0], 1e-2);
+ CHECK_CLOSE (pos[1], pos2_12[1], 1e-2);
+ CHECK_CLOSE (pos[2], pos2_12[2], 1e-2);
+ }
+
+
+
+ // This test compare the result of a slider with 2 bodies where body body 2 is
+ // fixed to the world to a slider with only one body at position 1.
+ //
+ // Test the limits [0, 0] when only one body at is attached to the joint
+ // using dJointAttache(jId, bId, 0);
+ //
+ // The body should not move since their is no room between the two limits
+ //
+ TEST_FIXTURE(Fixture_dxJointSlider_Compare_Body_At_Zero_Axis_Along_X,
+ test_Limit_0_0_One_Body_on_left)
+ {
+ dBodyAddForce (bId1_12, 4, 0, 0);
+
+ dJointAttach(jId_12, bId1_12, bId2_12);
+ dJointSetSliderParam(jId_12, dParamLoStop, 0);
+ dJointSetSliderParam(jId_12, dParamHiStop, 0);
+
+ dJointAttach(fixed, 0, bId2_12);
+ dJointSetFixed(fixed);
+
+
+ dJointAttach(jId, bId, 0);
+ dJointSetSliderParam(jId, dParamLoStop, 0);
+ dJointSetSliderParam(jId, dParamHiStop, 0);
+
+ for (int i=0; i<500; ++i)
+ dWorldStep(wId, 1.0);
+
+ const dReal *pos1_12 = dBodyGetPosition(bId1_12);
+
+ const dReal *pos = dBodyGetPosition(bId);
+
+
+ CHECK_CLOSE (pos[0], pos1_12[0], 1e-4);
+ CHECK_CLOSE (pos[1], pos1_12[1], 1e-4);
+ CHECK_CLOSE (pos[2], pos1_12[2], 1e-4);
+
+ CHECK_CLOSE (pos[0], 0, 1e-4);
+ CHECK_CLOSE (pos[1], 0, 1e-4);
+ CHECK_CLOSE (pos[2], 0, 1e-4);
+ }
+
+
+ // This test compare the result of a slider with 2 bodies where body body 1 is
+ // fixed to the world to a slider with only one body at position 2.
+ //
+ // Test the limits [0, 0] when only one body at is attached to the joint
+ // using dJointAttache(jId, 0, bId);
+ //
+ // The body should not move since their is no room between the two limits
+ //
+ TEST_FIXTURE(Fixture_dxJointSlider_Compare_Body_At_Zero_Axis_Along_X,
+ test_Limit_0_0_One_Body_on_right)
+ {
+ dBodyAddForce (bId2_12, 4, 0, 0);
+
+ dJointAttach(jId_12, bId1_12, bId2_12);
+ dJointSetSliderParam(jId_12, dParamLoStop, 0);
+ dJointSetSliderParam(jId_12, dParamHiStop, 0);
+
+ dJointAttach(fixed, bId1_12, 0);
+ dJointSetFixed(fixed);
+
+
+ dJointAttach(jId, 0, bId);
+ dJointSetSliderParam(jId, dParamLoStop, 0);
+ dJointSetSliderParam(jId, dParamHiStop, 0);
+
+ for (int i=0; i<500; ++i)
+ dWorldStep(wId, 1.0);
+
+ const dReal *pos2_12 = dBodyGetPosition(bId2_12);
+
+ const dReal *pos = dBodyGetPosition(bId);
+
+
+ CHECK_CLOSE (pos[0], pos2_12[0], 1e-4);
+ CHECK_CLOSE (pos[1], pos2_12[1], 1e-4);
+ CHECK_CLOSE (pos[2], pos2_12[2], 1e-4);
+
+ CHECK_CLOSE (pos[0], 0, 1e-4);
+ CHECK_CLOSE (pos[1], 0, 1e-4);
+ CHECK_CLOSE (pos[2], 0, 1e-4);
+ }
+
+
+
+
+} // End of SUITE TestdxJointSlider
diff --git a/libs/ode-0.16.1/tests/joints/universal.cpp b/libs/ode-0.16.1/tests/joints/universal.cpp
new file mode 100644
index 0000000..5a4c17b
--- /dev/null
+++ b/libs/ode-0.16.1/tests/joints/universal.cpp
@@ -0,0 +1,2119 @@
+/*************************************************************************
+ * *
+ * 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 file create unit test for some of the functions found in:
+// ode/src/joinst/universal.cpp
+//
+//
+////////////////////////////////////////////////////////////////////////////////
+
+#include <iostream>
+
+#include <UnitTest++.h>
+#include <ode/ode.h>
+
+#include "../../ode/src/config.h"
+#include "../../ode/src/joints/universal.h"
+
+dReal d2r(dReal degree)
+{
+ return degree * (dReal)(M_PI / 180.0);
+}
+dReal r2d(dReal degree)
+{
+ return degree * (dReal)(180.0/M_PI);
+}
+
+SUITE (TestdxJointUniversal)
+{
+ // The 2 bodies are positionned at (0, 0, 0)
+ // The bodis have no rotation.
+ // The joint is a Universal Joint
+ // Axis1 is along the X axis
+ // Axis2 is along the Y axis
+ // Anchor at (0, 0, 0)
+ struct Fixture_dxJointUniversal_B1_and_B2_At_Zero_Axis1_Along_X_Axis2_Along_Y
+ {
+ Fixture_dxJointUniversal_B1_and_B2_At_Zero_Axis1_Along_X_Axis2_Along_Y()
+ {
+
+ wId = dWorldCreate();
+
+ bId1 = dBodyCreate (wId);
+ dBodySetPosition (bId1, 0, 0, 0);
+
+ bId2 = dBodyCreate (wId);
+ dBodySetPosition (bId2, 0, 0, 0);
+
+
+ jId = dJointCreateUniversal (wId, 0);
+ joint = (dxJointUniversal*) jId;
+
+
+ dJointAttach (jId, bId1, bId2);
+ }
+
+ ~Fixture_dxJointUniversal_B1_and_B2_At_Zero_Axis1_Along_X_Axis2_Along_Y()
+ {
+ dWorldDestroy (wId);
+ }
+
+ dWorldID wId;
+
+ dBodyID bId1;
+ dBodyID bId2;
+
+
+ dJointID jId;
+ dxJointUniversal* joint;
+ };
+
+
+ // The 2 bodies are positionned at (-1, -2, -3), and (11, 22, 33)
+ // The bodis have rotation of 27deg around some axis.
+ // The joint is a Universal Joint
+ // Axis is along the X axis
+ // Anchor at (0, 0, 0)
+ struct Fixture_dxJointUniversal_B1_and_B2_At_Random_Axis_Along_X
+ {
+ Fixture_dxJointUniversal_B1_and_B2_At_Random_Axis_Along_X()
+ {
+ wId = dWorldCreate();
+
+ bId1 = dBodyCreate (wId);
+ dBodySetPosition (bId1, -1, -2, -3);
+
+ bId2 = dBodyCreate (wId);
+ dBodySetPosition (bId2, 11, 22, 33);
+
+ dMatrix3 R;
+
+ dVector3 axis;
+
+ axis[0] = REAL(0.53);
+ axis[1] = -REAL(0.71);
+ axis[2] = REAL(0.43);
+ dNormalize3(axis);
+ dRFromAxisAndAngle (R, axis[0], axis[1], axis[2],
+ REAL(0.47123)); // 27deg
+ dBodySetRotation (bId1, R);
+
+
+ axis[0] = REAL(1.2);
+ axis[1] = REAL(0.87);
+ axis[2] = -REAL(0.33);
+ dNormalize3(axis);
+ dRFromAxisAndAngle (R, axis[0], axis[1], axis[2],
+ REAL(0.47123)); // 27deg
+ dBodySetRotation (bId2, R);
+
+ jId = dJointCreateUniversal (wId, 0);
+ joint = (dxJointUniversal*) jId;
+
+
+ dJointAttach (jId, bId1, bId2);
+ }
+
+ ~Fixture_dxJointUniversal_B1_and_B2_At_Random_Axis_Along_X()
+ {
+ dWorldDestroy (wId);
+ }
+
+ dWorldID wId;
+
+ dBodyID bId1;
+ dBodyID bId2;
+
+
+ dJointID jId;
+ dxJointUniversal* joint;
+ };
+
+
+ // Only one body body1 at (0,0,0)
+ // The joint is an Universal Joint.
+ // Axis1 is along the X axis
+ // Axis2 is along the Y axis
+ // Anchor at (0, 0, 0)
+ //
+ // ^Y
+ // |
+ // |
+ // |
+ // |
+ // |
+ // Z <-- X
+ struct Fixture_dxJointUniversal_B1_At_Zero_Default_Axes
+ {
+ Fixture_dxJointUniversal_B1_At_Zero_Default_Axes()
+ {
+ wId = dWorldCreate();
+
+ bId1 = dBodyCreate (wId);
+ dBodySetPosition (bId1, 0, 0, 0);
+
+ jId = dJointCreateUniversal (wId, 0);
+
+
+ dJointAttach (jId, bId1, NULL);
+ dJointSetUniversalAnchor (jId, 0, 0, 0);
+ }
+
+ ~Fixture_dxJointUniversal_B1_At_Zero_Default_Axes()
+ {
+ dWorldDestroy (wId);
+ }
+
+ dWorldID wId;
+
+ dBodyID bId1;
+
+
+ dJointID jId;
+ };
+
+
+
+ // Only one body body2 at (0,0,0)
+ // The joint is an Universal Joint.
+ // Axis1 is along the X axis.
+ // Axis2 is along the Y axis.
+ // Anchor at (0, 0, 0)
+ //
+ // ^Y
+ // |
+ // |
+ // |
+ // |
+ // |
+ // Z <-- X
+ struct Fixture_dxJointUniversal_B2_At_Zero_Default_Axes
+ {
+ Fixture_dxJointUniversal_B2_At_Zero_Default_Axes()
+ {
+ wId = dWorldCreate();
+
+ bId2 = dBodyCreate (wId);
+ dBodySetPosition (bId2, 0, 0, 0);
+
+ jId = dJointCreateUniversal (wId, 0);
+
+
+ dJointAttach (jId, NULL, bId2);
+ dJointSetUniversalAnchor (jId, 0, 0, 0);
+ }
+
+ ~Fixture_dxJointUniversal_B2_At_Zero_Default_Axes()
+ {
+ dWorldDestroy (wId);
+ }
+
+ dWorldID wId;
+
+ dBodyID bId2;
+
+ dJointID jId;
+ };
+
+
+ // Test is dJointGetUniversalAngles versus
+ // dJointGetUniversalAngle1 and dJointGetUniversalAngle2 dJointGetUniversalAxis
+ TEST_FIXTURE (Fixture_dxJointUniversal_B1_and_B2_At_Zero_Axis1_Along_X_Axis2_Along_Y,
+ test_dJointSetGetUniversalAngles_Versus_Angle1_and_Angle2)
+ {
+ CHECK_CLOSE (0, dJointGetUniversalAngle1 (jId), 1e-4);
+ CHECK_CLOSE (0, dJointGetUniversalAngle2 (jId), 1e-4);
+
+ dReal angle1, angle2;
+ dJointGetUniversalAngles(jId, &angle1, &angle2);
+ CHECK_CLOSE (0, angle1, 1e-4);
+ CHECK_CLOSE (0, angle2, 1e-4);
+
+ dMatrix3 R;
+ dReal ang1, ang2;
+
+
+ dVector3 axis1;
+ dJointGetUniversalAxis1 (jId, axis1);
+
+ dVector3 axis2;
+ dJointGetUniversalAxis2 (jId, axis2);
+
+ ang1 = d2r(REAL(23.0));
+ dRFromAxisAndAngle (R, axis1[0], axis1[1], axis1[2], ang1);
+ dBodySetRotation (bId1, R);
+
+ ang2 = d2r(REAL(17.0));
+ dRFromAxisAndAngle (R, axis2[0], axis2[1], axis2[2], ang2);
+ dBodySetRotation (bId2, R);
+
+ CHECK_CLOSE (ang1, dJointGetUniversalAngle1 (jId), 1e-4);
+ CHECK_CLOSE (-ang2, dJointGetUniversalAngle2 (jId), 1e-4);
+
+ dJointGetUniversalAngles(jId, &angle1, &angle2);
+ CHECK_CLOSE (ang1, angle1, 1e-4);
+ CHECK_CLOSE (-ang2, angle2, 1e-4);
+
+
+
+
+
+
+ // ax1 and ax2 are pseudo-random axis. N.B. They are NOT the axis of the joints.
+ dVector3 ax1;
+ ax1[0] = REAL(0.2);
+ ax1[1] = -REAL(0.67);
+ ax1[2] = -REAL(0.81);
+ dNormalize3(ax1);
+
+ dVector3 ax2;
+ ax2[0] = REAL(0.62);
+ ax2[1] = REAL(0.31);
+ ax2[2] = REAL(0.43);
+ dNormalize3(ax2);
+
+
+ ang1 = d2r(REAL(23.0));
+ dRFromAxisAndAngle (R, ax1[0], ax1[1], ax1[2], ang1);
+ dBodySetRotation (bId1, R);
+
+ ang2 = d2r(REAL(0.0));
+
+ dJointGetUniversalAngles(jId, &angle1, &angle2);
+ CHECK_CLOSE (angle1, dJointGetUniversalAngle1 (jId), 1e-4);
+ CHECK_CLOSE (angle2, dJointGetUniversalAngle2 (jId), 1e-4);
+
+
+
+ ang1 = d2r(REAL(0.0));
+
+ ang2 = d2r(REAL(23.0));
+ dRFromAxisAndAngle (R, ax2[0], ax2[1], ax2[2], ang2);
+ dBodySetRotation (bId1, R);
+
+ dJointGetUniversalAngles(jId, &angle1, &angle2);
+ CHECK_CLOSE (angle1, dJointGetUniversalAngle1 (jId), 1e-4);
+ CHECK_CLOSE (angle2, dJointGetUniversalAngle2 (jId), 1e-4);
+
+
+ ang1 = d2r(REAL(38.0));
+ dRFromAxisAndAngle (R, ax1[0], ax1[1], ax1[2], ang2);
+ dBodySetRotation (bId1, R);
+
+ ang2 = d2r(REAL(-43.0));
+ dRFromAxisAndAngle (R, ax2[0], ax2[1], ax2[2], ang2);
+ dBodySetRotation (bId1, R);
+
+ dJointGetUniversalAngles(jId, &angle1, &angle2);
+ CHECK_CLOSE (angle1, dJointGetUniversalAngle1 (jId), 1e-4);
+ CHECK_CLOSE (angle2, dJointGetUniversalAngle2 (jId), 1e-4);
+
+
+ // Try with random axis for the axis of the joints
+ dRSetIdentity(R);
+ dBodySetRotation (bId1, R);
+ dBodySetRotation (bId1, R);
+
+ axis1[0] = REAL(0.32);
+ axis1[1] = -REAL(0.57);
+ axis1[2] = REAL(0.71);
+ dNormalize3(axis1);
+
+ axis2[0] = -REAL(0.26);
+ axis2[1] = -REAL(0.31);
+ axis2[2] = REAL(0.69);
+ dNormalize3(axis2);
+
+ dVector3 cross;
+ dCalcVectorCross3(cross, axis1, axis2);
+ dJointSetUniversalAxis1(jId, axis1[0], axis1[1], axis1[2]);
+ dJointSetUniversalAxis2(jId, cross[0], cross[1], cross[2]);
+
+
+ ang1 = d2r(REAL(23.0));
+ dRFromAxisAndAngle (R, ax1[0], ax1[1], ax1[2], ang1);
+ dBodySetRotation (bId1, R);
+
+ ang2 = d2r(REAL(0.0));
+
+ dJointGetUniversalAngles(jId, &angle1, &angle2);
+ CHECK_CLOSE (angle1, dJointGetUniversalAngle1 (jId), 1e-4);
+ CHECK_CLOSE (angle2, dJointGetUniversalAngle2 (jId), 1e-4);
+
+
+
+ ang1 = d2r(REAL(0.0));
+
+ ang2 = d2r(REAL(23.0));
+ dRFromAxisAndAngle (R, ax2[0], ax2[1], ax2[2], ang2);
+ dBodySetRotation (bId1, R);
+
+ dJointGetUniversalAngles(jId, &angle1, &angle2);
+ CHECK_CLOSE (angle1, dJointGetUniversalAngle1 (jId), 1e-4);
+ CHECK_CLOSE (angle2, dJointGetUniversalAngle2 (jId), 1e-4);
+
+
+ ang1 = d2r(REAL(38.0));
+ dRFromAxisAndAngle (R, ax1[0], ax1[1], ax1[2], ang2);
+ dBodySetRotation (bId1, R);
+
+ ang2 = d2r(REAL(-43.0));
+ dRFromAxisAndAngle (R, ax2[0], ax2[1], ax2[2], ang2);
+ dBodySetRotation (bId1, R);
+
+ dJointGetUniversalAngles(jId, &angle1, &angle2);
+ CHECK_CLOSE (angle1, dJointGetUniversalAngle1 (jId), 1e-4);
+ CHECK_CLOSE (angle2, dJointGetUniversalAngle2 (jId), 1e-4);
+ }
+
+
+ // =========================================================================
+ // Test ONE BODY behavior
+ // =========================================================================
+
+
+ // Test when there is only one body at position one on the joint
+ TEST_FIXTURE (Fixture_dxJointUniversal_B1_At_Zero_Default_Axes,
+ test_dJointGetUniversalAngle1_1Body_B1)
+ {
+ CHECK_CLOSE (0, dJointGetUniversalAngle1 (jId), 1e-4);
+ CHECK_CLOSE (0, dJointGetUniversalAngle2 (jId), 1e-4);
+
+ dReal angle1, angle2;
+ dJointGetUniversalAngles(jId, &angle1, &angle2);
+ CHECK_CLOSE (0, angle1, 1e-4);
+ CHECK_CLOSE (0, angle2, 1e-4);
+
+ dVector3 axis1;
+ dJointGetUniversalAxis1 (jId, axis1);
+ dVector3 axis2;
+ dJointGetUniversalAxis2 (jId, axis2);
+
+ dMatrix3 R;
+
+ dReal ang1 = REAL(0.23);
+ dRFromAxisAndAngle (R, axis1[0], axis1[1], axis1[2], ang1);
+ dBodySetRotation (bId1, R);
+
+ dReal ang2 = REAL(0.0);
+
+
+ CHECK_CLOSE (ang1, dJointGetUniversalAngle1 (jId), 1e-4);
+ CHECK_CLOSE (-ang2, dJointGetUniversalAngle2 (jId), 1e-4);
+
+ dJointGetUniversalAngles(jId, &angle1, &angle2);
+ CHECK_CLOSE (ang1, angle1, 1e-4);
+ CHECK_CLOSE (-ang2, angle2, 1e-4);
+
+
+
+ dMatrix3 I;
+ dRSetIdentity(I); // Set the rotation of the body to be the Identity (i.e. zero)
+ dBodySetRotation (bId1, I);
+
+ CHECK_CLOSE (0, dJointGetUniversalAngle1 (jId), 1e-4);
+ CHECK_CLOSE (0, dJointGetUniversalAngle2 (jId), 1e-4);
+
+
+ // Test the same rotation, when axis1 is inverted
+ dJointSetUniversalAxis1 (jId, -axis1[0], -axis1[1], -axis1[2]);
+
+ dBodySetRotation (bId1, R);
+
+ CHECK_CLOSE (-ang1, dJointGetUniversalAngle1 (jId), 1e-4);
+ CHECK_CLOSE (-ang2, dJointGetUniversalAngle2 (jId), 1e-4);
+
+ dJointGetUniversalAngles(jId, &angle1, &angle2);
+ CHECK_CLOSE (-ang1, angle1, 1e-4);
+ CHECK_CLOSE (-ang2, angle2, 1e-4);
+
+
+ // Test the same rotation, when axis1 is default and axis2 is inverted
+ dBodySetRotation (bId1, I);
+
+ dJointSetUniversalAxis1 (jId, axis1[0], axis1[1], axis1[2]);
+ dJointSetUniversalAxis2 (jId, -axis2[0], -axis2[1], -axis2[2]);
+
+
+ dBodySetRotation (bId1, R);
+
+ CHECK_CLOSE (ang1, dJointGetUniversalAngle1 (jId), 1e-4);
+ CHECK_CLOSE (ang2, dJointGetUniversalAngle2 (jId), 1e-4);
+
+ dJointGetUniversalAngles(jId, &angle1, &angle2);
+ CHECK_CLOSE (ang1, angle1, 1e-4);
+ CHECK_CLOSE (ang2, angle2, 1e-4);
+ }
+
+
+
+
+ // Test when there is only one body at position two on the joint
+ TEST_FIXTURE (Fixture_dxJointUniversal_B2_At_Zero_Default_Axes,
+ test_dJointGetUniversalAngle1_1Body_B2)
+ {
+ CHECK_CLOSE (0, dJointGetUniversalAngle1 (jId), 1e-4);
+ CHECK_CLOSE (0, dJointGetUniversalAngle2 (jId), 1e-4);
+
+ dReal angle1, angle2;
+ dJointGetUniversalAngles(jId, &angle1, &angle2);
+ CHECK_CLOSE (0, angle1, 1e-4);
+ CHECK_CLOSE (0, angle2, 1e-4);
+
+ dVector3 axis1;
+ dJointGetUniversalAxis1 (jId, axis1);
+
+ dVector3 axis2;
+ dJointGetUniversalAxis2 (jId, axis2);
+
+ dMatrix3 R;
+
+ dReal ang1 = REAL(0.0);
+
+ dReal ang2 = REAL(0.23);
+ dRFromAxisAndAngle (R, axis2[0], axis2[1], axis2[2], ang2);
+ dBodySetRotation (bId2, R);
+
+
+
+ CHECK_CLOSE (ang1, dJointGetUniversalAngle1 (jId), 1e-4);
+ CHECK_CLOSE (-ang2, dJointGetUniversalAngle2 (jId), 1e-4);
+
+ dJointGetUniversalAngles(jId, &angle1, &angle2);
+ CHECK_CLOSE (ang1, angle1, 1e-4);
+ CHECK_CLOSE (-ang2, angle2, 1e-4);
+
+
+
+ dMatrix3 I;
+ dRSetIdentity(I); // Set the rotation of the body to be the Identity (i.e. zero)
+ dBodySetRotation (bId2, I);
+
+ CHECK_CLOSE (0, dJointGetUniversalAngle1 (jId), 1e-4);
+ CHECK_CLOSE (0, dJointGetUniversalAngle2 (jId), 1e-4);
+
+
+ dJointSetUniversalAxis2 (jId, -axis2[0], -axis2[1], -axis2[2]);
+
+ dBodySetRotation (bId2, R);
+
+ CHECK_CLOSE (-ang1, dJointGetUniversalAngle1 (jId), 1e-4);
+ CHECK_CLOSE (ang2, dJointGetUniversalAngle2 (jId), 1e-4);
+
+ dJointGetUniversalAngles(jId, &angle1, &angle2);
+ CHECK_CLOSE (-ang1, angle1, 1e-4);
+ CHECK_CLOSE (ang2, angle2, 1e-4);
+
+ // Test the same rotation, when axis1 is inverted and axis2 is default
+ dBodySetRotation (bId2, I);
+
+ dJointSetUniversalAxis1 (jId, -axis1[0], -axis1[1], -axis1[2]);
+ dJointSetUniversalAxis2 (jId, axis2[0], axis2[1], axis2[2]);
+
+
+ dBodySetRotation (bId2, R);
+
+ CHECK_CLOSE (ang1, dJointGetUniversalAngle1 (jId), 1e-4);
+ CHECK_CLOSE (-ang2, dJointGetUniversalAngle2 (jId), 1e-4);
+
+ dJointGetUniversalAngles(jId, &angle1, &angle2);
+ CHECK_CLOSE (ang1, angle1, 1e-4);
+ CHECK_CLOSE (-ang2, angle2, 1e-4);
+ }
+
+
+
+
+
+
+ // =========================================================================
+ //
+ // =========================================================================
+
+
+ // Test is dJointSetUniversalAxis and dJointGetUniversalAxis return same value
+ TEST_FIXTURE (Fixture_dxJointUniversal_B1_and_B2_At_Random_Axis_Along_X,
+ test_dJointSetGetUniversalAxis)
+ {
+ dVector3 axisOrig, axis;
+
+
+ dJointGetUniversalAxis1 (jId, axisOrig);
+ dJointGetUniversalAxis1 (jId, axis);
+ dJointSetUniversalAxis1 (jId, axis[0], axis[1], axis[2]);
+ dJointGetUniversalAxis1 (jId, axis);
+ CHECK_CLOSE (axis[0], axisOrig[0] , 1e-4);
+ CHECK_CLOSE (axis[1], axisOrig[1] , 1e-4);
+ CHECK_CLOSE (axis[2], axisOrig[2] , 1e-4);
+
+
+ dJointGetUniversalAxis2 (jId, axisOrig);
+ dJointGetUniversalAxis2(jId, axis);
+ dJointSetUniversalAxis2 (jId, axis[0], axis[1], axis[2]);
+ dJointGetUniversalAxis2 (jId, axis);
+ CHECK_CLOSE (axis[0], axisOrig[0] , 1e-4);
+ CHECK_CLOSE (axis[1], axisOrig[1] , 1e-4);
+ CHECK_CLOSE (axis[2], axisOrig[2] , 1e-4);
+
+
+ dVector3 anchor1, anchor2, anchorOrig1, anchorOrig2;
+ dJointGetUniversalAnchor (jId, anchorOrig1);
+ dJointGetUniversalAnchor (jId, anchor1);
+ dJointGetUniversalAnchor2 (jId, anchorOrig2);
+ dJointGetUniversalAnchor2 (jId, anchor2);
+
+ dJointSetUniversalAnchor (jId, anchor1[0], anchor1[1], anchor1[2]);
+ dJointGetUniversalAnchor (jId, anchor1);
+ dJointGetUniversalAnchor2 (jId, anchor2);
+ CHECK_CLOSE (anchor1[0], anchorOrig1[0] , 1e-4);
+ CHECK_CLOSE (anchor1[1], anchorOrig1[1] , 1e-4);
+ CHECK_CLOSE (anchor1[2], anchorOrig1[2] , 1e-4);
+
+ CHECK_CLOSE (anchor2[0], anchorOrig2[0] , 1e-4);
+ CHECK_CLOSE (anchor2[1], anchorOrig2[1] , 1e-4);
+ CHECK_CLOSE (anchor2[2], anchorOrig2[2] , 1e-4);
+ }
+
+
+
+ // Create 2 bodies attached by a Universal joint
+ // Axis is along the X axis (Default value
+ // Anchor at (0, 0, 0) (Default value)
+ //
+ // ^Y
+ // |
+ // * Body2
+ // |
+ // |
+ // Body1 |
+ // * Z-------->
+ struct dxJointUniversal_Test_Initialization
+ {
+ dxJointUniversal_Test_Initialization()
+ {
+ wId = dWorldCreate();
+
+ // Remove gravity to have the only force be the force of the joint
+ dWorldSetGravity(wId, 0,0,0);
+
+ for (int j=0; j<2; ++j)
+ {
+ bId[j][0] = dBodyCreate (wId);
+ dBodySetPosition (bId[j][0], -1, -2, -3);
+
+ bId[j][1] = dBodyCreate (wId);
+ dBodySetPosition (bId[j][1], 11, 22, 33);
+
+
+ dMatrix3 R;
+ dVector3 axis; // Random axis
+
+ axis[0] = REAL(0.53);
+ axis[1] = -REAL(0.71);
+ axis[2] = REAL(0.43);
+ dNormalize3(axis);
+ dRFromAxisAndAngle (R, axis[0], axis[1], axis[2],
+ REAL(0.47123)); // 27deg
+ dBodySetRotation (bId[j][0], R);
+
+
+ axis[0] = REAL(1.2);
+ axis[1] = REAL(0.87);
+ axis[2] = -REAL(0.33);
+ dNormalize3(axis);
+ dRFromAxisAndAngle (R, axis[0], axis[1], axis[2],
+ REAL(0.47123)); // 27deg
+ dBodySetRotation (bId[j][1], R);
+
+ jId[j] = dJointCreateUniversal (wId, 0);
+ dJointAttach (jId[j], bId[j][0], bId[j][1]);
+ dJointSetUniversalParam(jId[j], dParamLoStop, 1);
+ dJointSetUniversalParam(jId[j], dParamHiStop, 2);
+ dJointSetUniversalParam(jId[j], dParamFMax, 200);
+ }
+ }
+
+ ~dxJointUniversal_Test_Initialization()
+ {
+ dWorldDestroy (wId);
+ }
+
+ dWorldID wId;
+
+ dBodyID bId[2][2];
+
+
+ dJointID jId[2];
+
+ };
+
+
+ // Test if setting a Universal with its default values
+ // will behave the same as a default Universal joint
+ TEST_FIXTURE (dxJointUniversal_Test_Initialization,
+ test_Universal_Initialization)
+ {
+ using namespace std;
+
+ dVector3 axis;
+ dJointGetUniversalAxis1(jId[1], axis);
+ dJointSetUniversalAxis1(jId[1], axis[0], axis[1], axis[2]);
+
+ dJointGetUniversalAxis2(jId[1], axis);
+ dJointSetUniversalAxis2(jId[1], axis[0], axis[1], axis[2]);
+
+ dVector3 anchor;
+ dJointGetUniversalAnchor(jId[1], anchor);
+ dJointSetUniversalAnchor(jId[1], anchor[0], anchor[1], anchor[2]);
+
+
+ for (int b=0; b<2; ++b)
+ {
+ // Compare body b of the first joint with its equivalent on the
+ // second joint
+ const dReal *qA = dBodyGetQuaternion(bId[0][b]);
+ const dReal *qB = dBodyGetQuaternion(bId[1][b]);
+ CHECK_CLOSE (qA[0], qB[0], 1e-4);
+ CHECK_CLOSE (qA[1], qB[1], 1e-4);
+ CHECK_CLOSE (qA[2], qB[2], 1e-4);
+ CHECK_CLOSE (qA[3], qB[3], 1e-4);
+ }
+
+ dWorldStep (wId,0.5);
+ dWorldStep (wId,0.5);
+ dWorldStep (wId,0.5);
+ dWorldStep (wId,0.5);
+
+ for (int b=0; b<2; ++b)
+ {
+ // Compare body b of the first joint with its equivalent on the
+ // second joint
+ const dReal *qA = dBodyGetQuaternion(bId[0][b]);
+ const dReal *qB = dBodyGetQuaternion(bId[1][b]);
+ CHECK_CLOSE (qA[0], qB[0], 1e-4);
+ CHECK_CLOSE (qA[1], qB[1], 1e-4);
+ CHECK_CLOSE (qA[2], qB[2], 1e-4);
+ CHECK_CLOSE (qA[3], qB[3], 1e-4);
+
+
+ const dReal *posA = dBodyGetPosition(bId[0][b]);
+ const dReal *posB = dBodyGetPosition(bId[1][b]);
+ CHECK_CLOSE (posA[0], posB[0], 1e-4);
+ CHECK_CLOSE (posA[1], posB[1], 1e-4);
+ CHECK_CLOSE (posA[2], posB[2], 1e-4);
+ CHECK_CLOSE (posA[3], posB[3], 1e-4);
+ }
+ }
+
+
+
+
+
+
+
+
+
+
+
+
+
+ // ==========================================================================
+ // Testing the offset
+ // TODO:
+ // - Test Axis1Offset(...., 0, ang2);
+ // ==========================================================================
+
+
+ // Rotate first body 90deg around X (Axis1) then back to original position
+ //
+ // ^ ^ ^ Z ^
+ // | | => <--- | |
+ // | | | |
+ // B1 B2 B1 B2 .----->Y
+ // /
+ // /
+ // v X (N.B. X is going out of the screen)
+ //
+ // Set Axis1 with an Offset of 90deg
+ // ^ ^ ^
+ // <--- | => | |
+ // | | |
+ // B1 B2 B1 B2
+ TEST_FIXTURE (Fixture_dxJointUniversal_B1_and_B2_At_Zero_Axis1_Along_X_Axis2_Along_Y,
+ test_dJointSetUniversalAxis1Offset_B1_90deg)
+ {
+ dMatrix3 R;
+
+ CHECK_CLOSE (0, dJointGetUniversalAngle1 (jId), 1e-4);
+ CHECK_CLOSE (0, dJointGetUniversalAngle2 (jId), 1e-4);
+
+ dReal angle1, angle2;
+ dJointGetUniversalAngles(jId, &angle1, &angle2);
+ CHECK_CLOSE (0, angle1, 1e-4);
+ CHECK_CLOSE (0, angle2, 1e-4);
+
+
+ dVector3 axis;
+ dJointGetUniversalAxis1 (jId, axis);
+
+ dReal ang1 = d2r(REAL(90.0));
+ dReal ang2 = d2r(REAL(0.0));
+ dRFromAxisAndAngle (R, axis[0], axis[1], axis[2], ang1);
+ dBodySetRotation (bId1, R);
+
+ CHECK_CLOSE (ang1, dJointGetUniversalAngle1 (jId), 1e-4);
+ CHECK_CLOSE (ang2, dJointGetUniversalAngle2 (jId), 1e-4);
+
+ dJointGetUniversalAngles(jId, &angle1, &angle2);
+ CHECK_CLOSE (ang1, angle1, 1e-4);
+ CHECK_CLOSE (ang2, angle2, 1e-4);
+
+
+
+ dJointSetUniversalAxis1Offset (jId, axis[0], axis[1], axis[2],
+ ang1, ang2);
+ CHECK_CLOSE (ang1, dJointGetUniversalAngle1 (jId), 1e-4);
+ CHECK_CLOSE (ang2, dJointGetUniversalAngle2 (jId), 1e-4);
+
+ dJointGetUniversalAngles(jId, &angle1, &angle2);
+ CHECK_CLOSE (ang1, angle1, 1e-4);
+ CHECK_CLOSE (ang2, angle2, 1e-4);
+
+
+ dRSetIdentity(R); // Set the rotation of the body to be zero
+ dBodySetRotation (bId1, R);
+
+ CHECK_CLOSE (0, dJointGetUniversalAngle1 (jId), 1e-4);
+ CHECK_CLOSE (0, dJointGetUniversalAngle2 (jId), 1e-4);
+
+ dJointGetUniversalAngles(jId, &angle1, &angle2);
+ CHECK_CLOSE (0, angle1, 1e-4);
+ CHECK_CLOSE (0, angle2, 1e-4);
+ }
+
+ // Rotate 2nd body 90deg around (Axis2) then back to original position
+ // Offset when setting axis1
+ //
+ // ^ ^ ^ Z ^
+ // | | => <--- | |
+ // | | | |
+ // B1 B2 B1 B2 .----->Y
+ // /
+ // /
+ // v X (N.B. X is going out of the screen)
+ //
+ // Set Axis1 with an Offset of 90deg
+ // ^ ^ ^
+ // <--- | => | |
+ // | | |
+ // B1 B2 B1 B2
+ TEST_FIXTURE (Fixture_dxJointUniversal_B1_and_B2_At_Zero_Axis1_Along_X_Axis2_Along_Y,
+ test_dJointSetUniversalAxis1Offset_B2_90deg)
+ {
+ dMatrix3 R;
+
+ CHECK_CLOSE (0, dJointGetUniversalAngle1 (jId), 1e-4);
+ CHECK_CLOSE (0, dJointGetUniversalAngle2 (jId), 1e-4);
+
+ dReal angle1, angle2;
+ dJointGetUniversalAngles(jId, &angle1, &angle2);
+ CHECK_CLOSE (0, angle1, 1e-4);
+ CHECK_CLOSE (0, angle2, 1e-4);
+
+
+ dVector3 ax1, ax2;
+ dJointGetUniversalAxis1 (jId, ax1);
+ dJointGetUniversalAxis2 (jId, ax2);
+
+ dReal ang1 = d2r(REAL(0.0));
+ dReal ang2 = d2r(REAL(90.0));
+ dRFromAxisAndAngle (R, ax2[0], ax2[1], ax2[2], ang2);
+ dBodySetRotation (bId2, R);
+
+ CHECK_CLOSE (ang1, dJointGetUniversalAngle1 (jId), 1e-4);
+ CHECK_CLOSE (-ang2, dJointGetUniversalAngle2 (jId), 1e-4);
+
+ dJointGetUniversalAngles(jId, &angle1, &angle2);
+ CHECK_CLOSE (ang1, angle1, 1e-4);
+ CHECK_CLOSE (-ang2, angle2, 1e-4);
+
+
+
+ dJointSetUniversalAxis1Offset (jId, ax1[0], ax1[1], ax1[2],
+ ang1, -ang2);
+ CHECK_CLOSE (ang1, dJointGetUniversalAngle1 (jId), 1e-4);
+ CHECK_CLOSE (-ang2, dJointGetUniversalAngle2 (jId), 1e-4);
+
+ dJointGetUniversalAngles(jId, &angle1, &angle2);
+ CHECK_CLOSE (ang1, angle1, 1e-4);
+ CHECK_CLOSE (-ang2, angle2, 1e-4);
+
+
+ dRSetIdentity(R); // Set the rotation of the body to be zero
+ dBodySetRotation (bId1, R);
+ dBodySetRotation (bId2, R);
+
+ CHECK_CLOSE (0, dJointGetUniversalAngle1 (jId), 1e-4);
+ CHECK_CLOSE (0, dJointGetUniversalAngle2 (jId), 1e-4);
+
+ dJointGetUniversalAngles(jId, &angle1, &angle2);
+ CHECK_CLOSE (0, angle1, 1e-4);
+ CHECK_CLOSE (0, angle2, 1e-4);
+ }
+
+
+
+
+
+
+
+
+ // Rotate second body 90deg around Y (Axis2) then back to original position
+ //
+ // ^ ^ ^ Z ^
+ // | | => | . |
+ // | | | |
+ // B1 B2 B1 B2 .----->Y
+ // /
+ // /
+ // v X (N.B. X is going out of the screen)
+ //
+ // Set Axis2 with an Offset of 90deg
+ // ^ ^ ^
+ // | . => | |
+ // | | |
+ // B1 B2 B1 B2
+ TEST_FIXTURE (Fixture_dxJointUniversal_B1_and_B2_At_Zero_Axis1_Along_X_Axis2_Along_Y,
+ test_dJointSetUniversalAxisOffset_B2_90deg)
+ {
+ CHECK_CLOSE (0, dJointGetUniversalAngle1 (jId), 1e-4);
+ CHECK_CLOSE (0, dJointGetUniversalAngle2 (jId), 1e-4);
+
+ dReal angle1, angle2;
+ dJointGetUniversalAngles(jId, &angle1, &angle2);
+ CHECK_CLOSE (0, angle1, 1e-4);
+ CHECK_CLOSE (0, angle2, 1e-4);
+
+ dVector3 axis;
+ dJointGetUniversalAxis2 (jId, axis);
+
+ dReal ang1 = d2r(REAL(0.0));
+ dReal ang2 = d2r(REAL(90.0));
+
+ dMatrix3 R;
+ dRFromAxisAndAngle (R, axis[0], axis[1], axis[2], ang2);
+ dBodySetRotation (bId2, R);
+
+ CHECK_CLOSE (ang1, dJointGetUniversalAngle1 (jId), 1e-4);
+ CHECK_CLOSE (-ang2, dJointGetUniversalAngle2 (jId), 1e-4);
+
+ dJointGetUniversalAngles(jId, &angle1, &angle2);
+ CHECK_CLOSE (ang1, angle1, 1e-4);
+ CHECK_CLOSE (-ang2, angle2, 1e-4);
+
+
+ dJointSetUniversalAxis2Offset (jId, axis[0], axis[1], axis[2],
+ ang1, -ang2);
+ CHECK_CLOSE (ang1, dJointGetUniversalAngle1 (jId), 1e-4);
+ CHECK_CLOSE (-ang2, dJointGetUniversalAngle2 (jId), 1e-4);
+
+ dJointGetUniversalAngles(jId, &angle1, &angle2);
+ CHECK_CLOSE (ang1, angle1, 1e-4);
+ CHECK_CLOSE (-ang2, angle2, 1e-4);
+
+
+ dRSetIdentity(R); // Set the rotation of the body to be zero
+ dBodySetRotation (bId2, R);
+
+ CHECK_CLOSE (0, dJointGetUniversalAngle1 (jId), 1e-4);
+ CHECK_CLOSE (0, dJointGetUniversalAngle2 (jId), 1e-4);
+
+ dJointGetUniversalAngles(jId, &angle1, &angle2);
+ CHECK_CLOSE (0, angle1, 1e-4);
+ CHECK_CLOSE (0, angle2, 1e-4);
+ }
+
+
+
+ // Rotate 2nd body -90deg around Y (Axis2) then back to original position
+ //
+ // ^ ^ ^ Z ^
+ // | | => | x |
+ // | | | |
+ // B1 B2 B1 B2 X .----> Y
+ // N.B. X is going out of the screen
+ // Start with a Delta of 90deg
+ // ^ ^ ^
+ // | x => | |
+ // | | |
+ // B1 B2 B1 B2
+ TEST_FIXTURE (Fixture_dxJointUniversal_B1_and_B2_At_Zero_Axis1_Along_X_Axis2_Along_Y,
+ test_dJointSetUniversalAxisOffset_B2_Minus90deg)
+ {
+ CHECK_CLOSE (dJointGetUniversalAngle1 (jId), 0, 1e-4);
+ CHECK_CLOSE (dJointGetUniversalAngle2 (jId), 0, 1e-4);
+
+ dReal angle1, angle2;
+ dJointGetUniversalAngles(jId, &angle1, &angle2);
+ CHECK_CLOSE (0, angle1, 1e-4);
+ CHECK_CLOSE (0, angle2, 1e-4);
+
+ dVector3 axis;
+ dJointGetUniversalAxis2 (jId, axis);
+
+ dReal ang1 = d2r(REAL(0.0));
+ dReal ang2 = d2r(REAL(90.0));
+
+ dMatrix3 R;
+ dRFromAxisAndAngle (R, axis[0], axis[1], axis[2], -ang2);
+ dBodySetRotation (bId2, R);
+
+ CHECK_CLOSE (ang1, dJointGetUniversalAngle1 (jId), 1e-4);
+ CHECK_CLOSE (ang2, dJointGetUniversalAngle2 (jId), 1e-4);
+
+ dJointGetUniversalAngles(jId, &angle1, &angle2);
+ CHECK_CLOSE (ang1, angle1, 1e-4);
+ CHECK_CLOSE (ang2, angle2, 1e-4);
+
+
+
+ dJointSetUniversalAxis2Offset (jId, axis[0], axis[1], axis[2],
+ ang1, ang2);
+ CHECK_CLOSE (ang1, dJointGetUniversalAngle1 (jId), 1e-4);
+ CHECK_CLOSE (ang2, dJointGetUniversalAngle2 (jId), 1e-4);
+
+ dJointGetUniversalAngles(jId, &angle1, &angle2);
+ CHECK_CLOSE (ang1, angle1, 1e-4);
+ CHECK_CLOSE (ang2, angle2, 1e-4);
+
+
+ dRFromAxisAndAngle (R, axis[0], axis[1], axis[2], 0);
+ dBodySetRotation (bId2, R);
+
+ CHECK_CLOSE (0, dJointGetUniversalAngle1 (jId), 1e-4);
+ CHECK_CLOSE (0, dJointGetUniversalAngle2 (jId), 1e-4);
+
+ dJointGetUniversalAngles(jId, &angle1, &angle2);
+ CHECK_CLOSE (0, angle1, 1e-4);
+ CHECK_CLOSE (0, angle2, 1e-4);
+ }
+
+
+ // Rotate 1st body 0.23rad around X (Axis1) then back to original position
+ //
+ // ^ ^ ^ ^ Z ^
+ // | | => \ | |
+ // | | \ | |
+ // B1 B2 B1 B2 .-------> Y
+ // /
+ // /
+ // v X (N.B. X is going out of the screen)
+ //
+ // Start with a Delta of 0.23rad
+ // ^ ^ ^ ^
+ // \ | => | |
+ // \ | | |
+ // B1 B2 B1 B2
+ TEST_FIXTURE (Fixture_dxJointUniversal_B1_and_B2_At_Zero_Axis1_Along_X_Axis2_Along_Y,
+ test_dJointSetUniversalAxis1Offset_B1_0_23rad)
+ {
+ CHECK_CLOSE (0, dJointGetUniversalAngle1 (jId), 1e-4);
+ CHECK_CLOSE (0, dJointGetUniversalAngle2 (jId), 1e-4);
+
+ dReal angle1, angle2;
+ dJointGetUniversalAngles(jId, &angle1, &angle2);
+ CHECK_CLOSE (0, angle1, 1e-4);
+ CHECK_CLOSE (0, angle2, 1e-4);
+
+ dVector3 axis;
+ dJointGetUniversalAxis1 (jId, axis);
+
+ dReal ang1 = REAL(0.23);
+ dReal ang2 = REAL(0.0);
+
+ dMatrix3 R;
+ dRFromAxisAndAngle (R, axis[0], axis[1], axis[2], ang1);
+ dBodySetRotation (bId1, R);
+
+ CHECK_CLOSE (ang1, dJointGetUniversalAngle1 (jId), 1e-4);
+ CHECK_CLOSE (ang2, dJointGetUniversalAngle2 (jId), 1e-4);
+
+
+ dJointSetUniversalAxis1Offset (jId, axis[0], axis[1], axis[2],
+ ang1, ang2);
+ CHECK_CLOSE (ang1, dJointGetUniversalAngle1 (jId), 1e-4);
+ CHECK_CLOSE (ang2, dJointGetUniversalAngle2 (jId), 1e-4);
+
+ dJointGetUniversalAngles(jId, &angle1, &angle2);
+ CHECK_CLOSE (ang1, angle1, 1e-4);
+ CHECK_CLOSE (ang2, angle2, 1e-4);
+
+
+ dRSetIdentity(R); // Set the rotation of the body to be zero
+ dBodySetRotation (bId1, R);
+
+ CHECK_CLOSE (0, dJointGetUniversalAngle1 (jId), 1e-4);
+ CHECK_CLOSE (0, dJointGetUniversalAngle2 (jId), 1e-4);
+
+ dJointGetUniversalAngles(jId, &angle1, &angle2);
+ CHECK_CLOSE (0, angle1, 1e-4);
+ CHECK_CLOSE (0, angle2, 1e-4);
+ }
+
+ // Rotate 2nd body 0.23rad around Y (Axis2) then back to original position
+ //
+ // ^ ^ ^ ^ Z ^ ^ Y (N.B. Y is going in the screen)
+ // | | => | / | /
+ // | | | / | /
+ // B1 B2 B1 B2 .-------> X
+ //
+ // Start with a Delta of 0.23rad
+ // ^ ^ ^ ^
+ // | / => | |
+ // | / | |
+ // B1 B2 B1 B2
+ TEST_FIXTURE (Fixture_dxJointUniversal_B1_and_B2_At_Zero_Axis1_Along_X_Axis2_Along_Y,
+ test_dJointSetUniversalAxisOffset_B2_0_23rad)
+ {
+ CHECK_CLOSE (0, dJointGetUniversalAngle1 (jId), 1e-4);
+ CHECK_CLOSE (0, dJointGetUniversalAngle2 (jId), 1e-4);
+
+ dReal angle1, angle2;
+ dJointGetUniversalAngles(jId, &angle1, &angle2);
+ CHECK_CLOSE (0, angle1, 1e-4);
+ CHECK_CLOSE (0, angle2, 1e-4);
+
+ dVector3 axis;
+ dJointGetUniversalAxis2 (jId, axis);
+
+ dReal ang1 = REAL(0.0);
+ dReal ang2 = REAL(0.23);
+
+ dMatrix3 R;
+ dRFromAxisAndAngle (R, axis[0], axis[1], axis[2], ang2);
+ dBodySetRotation (bId2, R);
+
+ CHECK_CLOSE (ang1, dJointGetUniversalAngle1 (jId), 1e-4);
+ CHECK_CLOSE (-ang2, dJointGetUniversalAngle2 (jId), 1e-4);
+
+
+ dJointSetUniversalAxis2Offset (jId, axis[0], axis[1], axis[2],
+ ang1, -ang2);
+ CHECK_CLOSE (ang1, dJointGetUniversalAngle1 (jId), 1e-4);
+ CHECK_CLOSE (-ang2, dJointGetUniversalAngle2 (jId), 1e-4);
+
+ dJointGetUniversalAngles(jId, &angle1, &angle2);
+ CHECK_CLOSE (ang1, angle1, 1e-4);
+ CHECK_CLOSE (-ang2, angle2, 1e-4);
+
+
+ dRSetIdentity(R); // Set the rotation of the body to be zero
+ dBodySetRotation (bId2, R);
+
+ CHECK_CLOSE (0, dJointGetUniversalAngle1 (jId), 1e-4);
+ CHECK_CLOSE (0, dJointGetUniversalAngle2 (jId), 1e-4);
+
+ dJointGetUniversalAngles(jId, &angle1, &angle2);
+ CHECK_CLOSE (0, angle1, 1e-4);
+ CHECK_CLOSE (0, angle2, 1e-4);
+ }
+
+
+ // Rotate 1st body 0.23rad around X axis and 2nd body 0.37rad around Y (Axis2)
+ // then back to their original position.
+ // The Axis offset are set one at a time
+ //
+ // ^ ^ ^ ^ Z ^ ^ Y (N.B. Y is going in the screen)
+ // | | => \ / | /
+ // | | \ / | /
+ // B1 B2 B1 B2 .-------> X
+ //
+ // Start with a Delta of 0.23rad
+ // ^ ^ ^ ^
+ // \ / => | |
+ // \ / | |
+ // B1 B2 B1 B2
+ TEST_FIXTURE (Fixture_dxJointUniversal_B1_and_B2_At_Zero_Axis1_Along_X_Axis2_Along_Y,
+ test_dJointSetUniversalAxisOffset_B1_0_23rad_B2_0_37rad_One_by_One)
+ {
+ CHECK_CLOSE (0, dJointGetUniversalAngle1 (jId), 1e-4);
+ CHECK_CLOSE (0, dJointGetUniversalAngle2 (jId), 1e-4);
+
+ dReal angle1, angle2;
+ dJointGetUniversalAngles(jId, &angle1, &angle2);
+ CHECK_CLOSE (0, angle1, 1e-4);
+ CHECK_CLOSE (0, angle2, 1e-4);
+
+ dVector3 axis1;
+ dJointGetUniversalAxis1 (jId, axis1);
+ dVector3 axis2;
+ dJointGetUniversalAxis2 (jId, axis2);
+
+ dMatrix3 R;
+
+ dReal ang1 = REAL(0.23);
+ dRFromAxisAndAngle (R, axis1[0], axis1[1], axis1[2], ang1);
+ dBodySetRotation (bId1, R);
+
+ dReal ang2 = REAL(0.37);
+ dRFromAxisAndAngle (R, axis2[0], axis2[1], axis2[2], ang2);
+ dBodySetRotation (bId2, R);
+
+
+ CHECK_CLOSE (ang1, dJointGetUniversalAngle1 (jId), 1e-4);
+ CHECK_CLOSE (-ang2, dJointGetUniversalAngle2 (jId), 1e-4);
+
+ dJointGetUniversalAngles(jId, &angle1, &angle2);
+ CHECK_CLOSE (ang1, angle1, 1e-4);
+ CHECK_CLOSE (-ang2, angle2, 1e-4);
+
+
+ dJointSetUniversalAxis1Offset (jId, axis1[0], axis1[1], axis1[2],
+ ang1, -ang2 );
+ CHECK_CLOSE (ang1, dJointGetUniversalAngle1 (jId), 1e-4);
+ CHECK_CLOSE (-ang2, dJointGetUniversalAngle2 (jId), 1e-4);
+
+ dJointGetUniversalAngles(jId, &angle1, &angle2);
+ CHECK_CLOSE (ang1, angle1, 1e-4);
+ CHECK_CLOSE (-ang2, angle2, 1e-4);
+
+ dJointGetUniversalAxis1 (jId, axis1);
+ dJointGetUniversalAxis2 (jId, axis2);
+
+ dRFromAxisAndAngle (R, axis2[0], axis2[1], axis2[2], ang2);
+ dBodySetRotation (bId2, R);
+
+ dJointSetUniversalAxis2Offset (jId, axis2[0], axis2[1], axis2[2],
+ ang1, -ang2);
+ CHECK_CLOSE (ang1, dJointGetUniversalAngle1 (jId), 1e-4);
+ CHECK_CLOSE (-ang2, dJointGetUniversalAngle2 (jId), 1e-4);
+
+ dJointGetUniversalAngles(jId, &angle1, &angle2);
+ CHECK_CLOSE (ang1, angle1, 1e-4);
+ CHECK_CLOSE (-ang2, angle2, 1e-4);
+
+
+ dRSetIdentity(R); // Set the rotation of the body to be zero
+ dBodySetRotation (bId1, R);
+ dBodySetRotation (bId2, R);
+
+ CHECK_CLOSE (0, dJointGetUniversalAngle1 (jId), 1e-4);
+ CHECK_CLOSE (0, dJointGetUniversalAngle2 (jId), 1e-4);
+
+ dJointGetUniversalAngles(jId, &angle1, &angle2);
+ CHECK_CLOSE (0, angle1, 1e-4);
+ CHECK_CLOSE (0, angle2, 1e-4);
+ }
+
+
+
+// The 2 bodies are positionned at (0, 0, 0), with no rotation
+// The joint is an Universal Joint.
+// Axis in the inverse direction of the X axis
+// Anchor at (0, 0, 0)
+// ^Y
+// |
+// |
+// |
+// |
+// |
+// Z <---- x (X going out of the page)
+ struct Fixture_dxJointUniversal_B1_and_B2_At_Zero_Axis1_Inverse_of_X
+ {
+ Fixture_dxJointUniversal_B1_and_B2_At_Zero_Axis1_Inverse_of_X()
+ {
+ wId = dWorldCreate();
+
+ bId1 = dBodyCreate (wId);
+ dBodySetPosition (bId1, 0, 0, 0);
+
+ bId2 = dBodyCreate (wId);
+ dBodySetPosition (bId2, 0, 0, 0);
+
+ jId = dJointCreateUniversal (wId, 0);
+ joint = (dxJointUniversal*) jId;
+
+
+ dJointAttach (jId, bId1, bId2);
+ dJointSetUniversalAnchor (jId, 0, 0, 0);
+
+ axis[0] = -1;
+ axis[1] = 0;
+ axis[2] = 0;
+ dJointSetUniversalAxis1(jId, axis[0], axis[1], axis[2]);
+ }
+
+ ~Fixture_dxJointUniversal_B1_and_B2_At_Zero_Axis1_Inverse_of_X()
+ {
+ dWorldDestroy (wId);
+ }
+
+ dWorldID wId;
+
+ dBodyID bId1;
+ dBodyID bId2;
+
+
+ dJointID jId;
+ dxJointUniversal* joint;
+
+ dVector3 axis;
+ };
+
+
+ // No offset when setting the Axis1 offset
+ // x is a Symbol for lines pointing into the screen
+ // . is a Symbol for lines pointing out of the screen
+ //
+ // In 2D In 3D
+ // ^ ^ ^ ^ Z ^ ^ Y
+ // | | => | | | /
+ // | | | | | /
+ // B1 B2 B1 B2 .-------> X <-- Axis1
+ //
+ // Start with a Delta of 90deg
+ // ^ ^ ^ ^
+ // | | => | |
+ // | | | |
+ // B1 B2 B1 B2
+ TEST_FIXTURE (Fixture_dxJointUniversal_B1_and_B2_At_Zero_Axis1_Inverse_of_X,
+ test_dJointSetUniversalAxis1Offset_No_Offset_Axis1_Inverse_of_X)
+ {
+ CHECK_CLOSE (dJointGetUniversalAngle1 (jId), 0, 1e-4);
+ CHECK_CLOSE (dJointGetUniversalAngle2 (jId), 0, 1e-4);
+
+ dReal angle1, angle2;
+ dJointGetUniversalAngles(jId, &angle1, &angle2);
+ CHECK_CLOSE (0, angle1, 1e-4);
+ CHECK_CLOSE (0, angle2, 1e-4);
+
+ dVector3 axis;
+ dJointGetUniversalAxis1 (jId, axis);
+
+ dReal ang1 = REAL(0.0);
+ dReal ang2 = REAL(0.0);
+
+ dMatrix3 R;
+ dRFromAxisAndAngle (R, axis[0], axis[1], axis[2], ang1);
+ dBodySetRotation (bId1, R);
+
+ CHECK_CLOSE (ang1, dJointGetUniversalAngle1 (jId), 1e-4);
+ CHECK_CLOSE (ang2, dJointGetUniversalAngle2 (jId), 1e-4);
+
+
+ dJointSetUniversalAxis1Offset (jId, axis[0], axis[1], axis[2],
+ ang1, ang2);
+ CHECK_CLOSE (ang1, dJointGetUniversalAngle1 (jId), 1e-4);
+ CHECK_CLOSE (ang2, dJointGetUniversalAngle2 (jId), 1e-4);
+
+ dJointGetUniversalAngles(jId, &angle1, &angle2);
+ CHECK_CLOSE (ang1, angle1, 1e-4);
+ CHECK_CLOSE (ang2, angle2, 1e-4);
+
+ dRSetIdentity(R); // Set the rotation of the body to be zero
+ dBodySetRotation (bId1, R);
+
+ CHECK_CLOSE (0, dJointGetUniversalAngle1 (jId), 1e-4);
+ CHECK_CLOSE (0, dJointGetUniversalAngle2 (jId), 1e-4);
+
+ dJointGetUniversalAngles(jId, &angle1, &angle2);
+ CHECK_CLOSE (0, angle1, 1e-4);
+ CHECK_CLOSE (0, angle2, 1e-4);
+ }
+
+
+
+ // Rotate 1st body 90deg around axis1 then back to original position
+ // x is a Symbol for lines pointing into the screen
+ // . is a Symbol for lines pointing out of the screen
+ //
+ // In 2D In 3D
+ // ^ ^ ^ Z ^ ^ Y
+ // | | => x | | /
+ // | | | | /
+ // B1 B2 B1 B2 .-------> X <-- Axis1
+ //
+ // Start with a Delta of 90deg
+ // ^ ^ ^
+ // x | => | |
+ // | | |
+ // B1 B2 B1 B2
+ TEST_FIXTURE (Fixture_dxJointUniversal_B1_and_B2_At_Zero_Axis1_Inverse_of_X,
+ test_dJointSetUniversalAxis1Offset_B1_90Deg_Axis1_Inverse_of_X)
+ {
+ CHECK_CLOSE (dJointGetUniversalAngle1 (jId), 0, 1e-4);
+ CHECK_CLOSE (dJointGetUniversalAngle2 (jId), 0, 1e-4);
+
+ dReal angle1, angle2;
+ dJointGetUniversalAngles(jId, &angle1, &angle2);
+ CHECK_CLOSE (0, angle1, 1e-4);
+ CHECK_CLOSE (0, angle2, 1e-4);
+
+ dVector3 axis;
+ dJointGetUniversalAxis1 (jId, axis);
+
+ dReal ang1 = d2r(90);
+ dReal ang2 = REAL(0.0);
+
+ dMatrix3 R;
+ dRFromAxisAndAngle (R, axis[0], axis[1], axis[2], ang1);
+ dBodySetRotation (bId1, R);
+
+ CHECK_CLOSE (ang1, dJointGetUniversalAngle1 (jId), 1e-4);
+ CHECK_CLOSE (ang2, dJointGetUniversalAngle2 (jId), 1e-4);
+
+
+ dJointSetUniversalAxis1Offset (jId, axis[0], axis[1], axis[2],
+ ang1, ang2);
+ CHECK_CLOSE (ang1, dJointGetUniversalAngle1 (jId), 1e-4);
+ CHECK_CLOSE (ang2, dJointGetUniversalAngle2 (jId), 1e-4);
+
+ dJointGetUniversalAngles(jId, &angle1, &angle2);
+ CHECK_CLOSE (ang1, angle1, 1e-4);
+ CHECK_CLOSE (ang2, angle2, 1e-4);
+
+ dRSetIdentity(R); // Set the rotation of the body to be zero
+ dBodySetRotation (bId1, R);
+
+ CHECK_CLOSE (0, dJointGetUniversalAngle1 (jId), 1e-4);
+ CHECK_CLOSE (0, dJointGetUniversalAngle2 (jId), 1e-4);
+
+ dJointGetUniversalAngles(jId, &angle1, &angle2);
+ CHECK_CLOSE (0, angle1, 1e-4);
+ CHECK_CLOSE (0, angle2, 1e-4);
+ }
+
+
+
+ // No offset when setting the Axis 2 offset
+ // x is a Symbol for lines pointing into the screen
+ // . is a Symbol for lines pointing out of the screen
+ //
+ // In 2D In 3D
+ // ^ ^ ^ ^ Z ^ ^ Y ^ Axis2
+ // | | => | | | / /
+ // | | | | | / /
+ // B1 B2 B1 B2 . -------> <-- Axis1
+ //
+ // Start with a Delta of 90deg
+ // ^ ^ ^ ^
+ // | | => | |
+ // | | | |
+ // B1 B2 B1 B2
+ TEST_FIXTURE (Fixture_dxJointUniversal_B1_and_B2_At_Zero_Axis1_Inverse_of_X,
+ test_dJointSetUniversalAxis2Offset_No_Offset_Axis2_Inverse_of_X)
+ {
+ CHECK_CLOSE (dJointGetUniversalAngle1 (jId), 0, 1e-4);
+ CHECK_CLOSE (dJointGetUniversalAngle2 (jId), 0, 1e-4);
+
+ dReal angle1, angle2;
+ dJointGetUniversalAngles(jId, &angle1, &angle2);
+ CHECK_CLOSE (0, angle1, 1e-4);
+ CHECK_CLOSE (0, angle2, 1e-4);
+
+ dVector3 axis;
+ dJointGetUniversalAxis2 (jId, axis);
+
+ dReal ang1 = d2r(REAL(0.0));
+ dReal ang2 = d2r(REAL(0.0));
+
+ dMatrix3 R;
+ dRFromAxisAndAngle (R, axis[0], axis[1], axis[2], ang2);
+ dBodySetRotation (bId2, R);
+
+ CHECK_CLOSE (ang1, dJointGetUniversalAngle1 (jId), 1e-4);
+ CHECK_CLOSE (-ang2, dJointGetUniversalAngle2 (jId), 1e-4);
+
+
+ dJointSetUniversalAxis2Offset (jId, axis[0], axis[1], axis[2],
+ ang1, -ang2);
+ CHECK_CLOSE (ang1, dJointGetUniversalAngle1 (jId), 1e-4);
+ CHECK_CLOSE (-ang2, dJointGetUniversalAngle2 (jId), 1e-4);
+
+ dJointGetUniversalAngles(jId, &angle1, &angle2);
+ CHECK_CLOSE (ang1, angle1, 1e-4);
+ CHECK_CLOSE (-ang2, angle2, 1e-4);
+
+ dRSetIdentity(R); // Set the rotation of the body to be zero
+ dBodySetRotation (bId2, R);
+
+ CHECK_CLOSE (0, dJointGetUniversalAngle1 (jId), 1e-4);
+ CHECK_CLOSE (0, dJointGetUniversalAngle2 (jId), 1e-4);
+
+ dJointGetUniversalAngles(jId, &angle1, &angle2);
+ CHECK_CLOSE (0, angle1, 1e-4);
+ CHECK_CLOSE (0, angle2, 1e-4);
+ }
+
+ // Rotate 2nd body 90deg around axis2 then back to original position
+ //
+ // In 2D In 3D
+ // ^ ^ ^ Z ^ ^ Y ^ Axis2
+ // | | => | --> | / /
+ // | | | | / /
+ // B1 B2 B1 B2 . -------> <-- Axis1
+ //
+ // Start with a Delta of 90deg
+ // ^ ^ ^
+ // | <--- => | |
+ // | | |
+ // B1 B2 B1 B2
+ TEST_FIXTURE (Fixture_dxJointUniversal_B1_and_B2_At_Zero_Axis1_Inverse_of_X,
+ test_dJointSetUniversalAxisOffset_B2_90Deg)
+ {
+ CHECK_CLOSE (dJointGetUniversalAngle1 (jId), 0, 1e-4);
+ CHECK_CLOSE (dJointGetUniversalAngle2 (jId), 0, 1e-4);
+
+ dReal angle1, angle2;
+ dJointGetUniversalAngles(jId, &angle1, &angle2);
+ CHECK_CLOSE (0, angle1, 1e-4);
+ CHECK_CLOSE (0, angle2, 1e-4);
+
+ dVector3 axis;
+ dJointGetUniversalAxis2 (jId, axis);
+
+ dReal ang1 = d2r(REAL(0.0));
+ dReal ang2 = d2r(REAL(90.0));
+
+ dMatrix3 R;
+ dRFromAxisAndAngle (R, axis[0], axis[1], axis[2], ang2);
+ dBodySetRotation (bId2, R);
+
+ CHECK_CLOSE (0, dJointGetUniversalAngle1 (jId), 1e-4);
+ CHECK_CLOSE (-ang2, dJointGetUniversalAngle2 (jId), 1e-4);
+
+
+ dJointSetUniversalAxis2Offset (jId, axis[0], axis[1], axis[2],
+ ang1, -ang2);
+ CHECK_CLOSE (ang1, dJointGetUniversalAngle1 (jId), 1e-4);
+ CHECK_CLOSE (-ang2, dJointGetUniversalAngle2 (jId), 1e-4);
+
+ dJointGetUniversalAngles(jId, &angle1, &angle2);
+ CHECK_CLOSE (ang1, angle1, 1e-4);
+ CHECK_CLOSE (-ang2, angle2, 1e-4);
+
+ dRSetIdentity(R); // Set the rotation of the body to be zero
+ dBodySetRotation (bId2, R);
+
+ CHECK_CLOSE (0, dJointGetUniversalAngle1 (jId), 1e-4);
+ CHECK_CLOSE (0, dJointGetUniversalAngle2 (jId), 1e-4);
+
+ dJointGetUniversalAngles(jId, &angle1, &angle2);
+ CHECK_CLOSE (0, angle1, 1e-4);
+ CHECK_CLOSE (0, angle2, 1e-4);
+ }
+
+
+ // Rotate 2nd body -90deg around axis2 then back to original position
+ //
+ // ^ ^ ^
+ // | | => | --->
+ // | | |
+ // B1 B2 B1 B2
+ //
+ // Start with a Delta of 90deg
+ // ^ ^ ^
+ // | ---> => | |
+ // | | |
+ // B1 B2 B1 B2
+ TEST_FIXTURE (Fixture_dxJointUniversal_B1_and_B2_At_Zero_Axis1_Inverse_of_X,
+ test_dJointSetUniversalAxis1Offset_B2_Minus90Deg)
+ {
+ CHECK_CLOSE (dJointGetUniversalAngle1 (jId), 0, 1e-4);
+ CHECK_CLOSE (dJointGetUniversalAngle2 (jId), 0, 1e-4);
+
+ dReal angle1, angle2;
+ dJointGetUniversalAngles(jId, &angle1, &angle2);
+ CHECK_CLOSE (0, angle1, 1e-4);
+ CHECK_CLOSE (0, angle2, 1e-4);
+
+ dVector3 axis;
+ dJointGetUniversalAxis2 (jId, axis);
+
+ dReal ang1 = d2r(0.0);
+ dReal ang2 = d2r(REAL(-90.0));
+
+
+ dMatrix3 R;
+ dRFromAxisAndAngle (R, axis[0], axis[1], axis[2], ang2);
+ dBodySetRotation (bId2, R);
+
+ CHECK_CLOSE (ang1, dJointGetUniversalAngle1 (jId), 1e-4);
+ CHECK_CLOSE (-ang2, dJointGetUniversalAngle2 (jId), 1e-4);
+
+ dJointGetUniversalAngles(jId, &angle1, &angle2);
+ CHECK_CLOSE (ang1, angle1, 1e-4);
+ CHECK_CLOSE (-ang2, angle2, 1e-4);
+
+
+ dJointGetUniversalAxis1 (jId, axis);
+ dJointSetUniversalAxis1Offset (jId, axis[0], axis[1], axis[2],
+ ang1, -ang2);
+ CHECK_CLOSE (ang1, dJointGetUniversalAngle1 (jId), 1e-4);
+ CHECK_CLOSE (-ang2, dJointGetUniversalAngle2 (jId), 1e-4);
+
+ dJointGetUniversalAngles(jId, &angle1, &angle2);
+ CHECK_CLOSE (ang1, angle1, 1e-4);
+ CHECK_CLOSE (-ang2, angle2, 1e-4);
+
+
+ dRSetIdentity(R); // Set the rotation of the body to be zero
+ dBodySetRotation (bId2, R);
+
+
+ CHECK_CLOSE (0, dJointGetUniversalAngle1 (jId), 1e-4);
+ CHECK_CLOSE (0, dJointGetUniversalAngle2 (jId), 1e-4);
+
+ dJointGetUniversalAngles(jId, &angle1, &angle2);
+ CHECK_CLOSE (0, angle1, 1e-4);
+ CHECK_CLOSE (0, angle2, 1e-4);
+ }
+
+
+ // Rotate 1st body 0.23rad around X then back to original position
+ //
+ // ^ ^ ^ ^
+ // | | => \ |
+ // | | \ |
+ // B1 B2 B1 B2
+ //
+ // Start with a Delta of 0.23rad
+ // ^ ^ ^ ^
+ // \ | => | |
+ // \ | | |
+ // B1 B2 B1 B2
+ TEST_FIXTURE (Fixture_dxJointUniversal_B1_and_B2_At_Zero_Axis1_Inverse_of_X,
+ test_dJointSetUniversalAxis1Offset_B1_0_23rad)
+ {
+ CHECK_CLOSE (0, dJointGetUniversalAngle1 (jId), 1e-4);
+ CHECK_CLOSE (0, dJointGetUniversalAngle2 (jId), 1e-4);
+
+ dReal angle1, angle2;
+ dJointGetUniversalAngles(jId, &angle1, &angle2);
+ CHECK_CLOSE (0, angle1, 1e-4);
+ CHECK_CLOSE (0, angle2, 1e-4);
+
+ dVector3 axis;
+ dJointGetUniversalAxis1 (jId, axis);
+
+ dReal ang1 = REAL(0.23);
+ dReal ang2 = REAL(0.0);
+
+ dMatrix3 R;
+ dRFromAxisAndAngle (R, axis[0], axis[1], axis[2], ang1);
+ dBodySetRotation (bId1, R);
+
+ CHECK_CLOSE (ang1, dJointGetUniversalAngle1 (jId), 1e-4);
+ CHECK_CLOSE (-ang2, dJointGetUniversalAngle2 (jId), 1e-4);
+
+
+ dJointSetUniversalAxis1Offset (jId, axis[0], axis[1], axis[2], ang1, ang2);
+ CHECK_CLOSE (ang1, dJointGetUniversalAngle1 (jId), 1e-4);
+ CHECK_CLOSE (-ang2, dJointGetUniversalAngle2 (jId), 1e-4);
+
+ dJointGetUniversalAngles(jId, &angle1, &angle2);
+ CHECK_CLOSE (ang1, angle1, 1e-4);
+ CHECK_CLOSE (-ang2, angle2, 1e-4);
+
+
+ dRSetIdentity(R); // Set the rotation of the body to be zero
+ dBodySetRotation (bId1, R);
+
+ CHECK_CLOSE (0, dJointGetUniversalAngle1 (jId), 1e-4);
+ CHECK_CLOSE (0, dJointGetUniversalAngle2 (jId), 1e-4);
+
+ dJointGetUniversalAngles(jId, &angle1, &angle2);
+ CHECK_CLOSE (0, angle1, 1e-4);
+ CHECK_CLOSE (0, angle2, 1e-4);
+ }
+
+
+ // Rotate 2nd body -0.23rad around Z then back to original position
+ //
+ // ^ ^ ^ ^
+ // | | => / |
+ // | | / |
+ // B1 B2 B1 B2
+ //
+ // Start with a Delta of 0.23rad
+ // ^ ^ ^ ^
+ // / | => | |
+ // / | | |
+ // B1 B2 B1 B2
+ TEST_FIXTURE (Fixture_dxJointUniversal_B1_and_B2_At_Zero_Axis1_Inverse_of_X,
+ test_dJointSetUniversalAxisOffset_B1_Minus0_23rad)
+ {
+ CHECK_CLOSE (dJointGetUniversalAngle1 (jId), 0, 1e-4);
+
+ dMatrix3 R;
+ dRFromAxisAndAngle (R, 1, 0, 0, -REAL(0.23));
+ dBodySetRotation (bId1, R);
+
+ CHECK_CLOSE (REAL(0.23), dJointGetUniversalAngle1 (jId), 1e-4);
+
+ dVector3 axis;
+ dJointGetUniversalAxis1 (jId, axis);
+ dJointSetUniversalAxis1Offset (jId, axis[0], axis[1], axis[2], REAL(0.23), 0);
+ CHECK_CLOSE (REAL(0.23), dJointGetUniversalAngle1 (jId), 1e-4);
+
+ dRFromAxisAndAngle (R, 1, 0, 0, 0);
+ dBodySetRotation (bId1, R);
+
+ CHECK_CLOSE (0, dJointGetUniversalAngle1 (jId), 1e-4);
+ }
+
+
+
+
+ // Rotate the body by 90deg around X then back to original position.
+ // The body is attached at the second position of the joint:
+ // dJointAttache(jId, 0, bId);
+ //
+ // ^
+ // | => <---
+ // |
+ // B1 B1
+ //
+ // Start with a Delta of 90deg
+ // ^
+ // <--- => |
+ // |
+ // B1 B1
+ TEST_FIXTURE (Fixture_dxJointUniversal_B1_At_Zero_Default_Axes,
+ test_dJointSetUniversalAxisOffset_1Body_B1_90Deg)
+ {
+ CHECK_CLOSE (dJointGetUniversalAngle1 (jId), 0, 1e-4);
+
+ dMatrix3 R;
+ dRFromAxisAndAngle (R, 1, 0, 0, M_PI/2.0);
+ dBodySetRotation (bId1, R);
+
+ CHECK_CLOSE (M_PI/2.0, dJointGetUniversalAngle1 (jId), 1e-4);
+
+ dVector3 axis;
+ dJointGetUniversalAxis1 (jId, axis);
+ dJointSetUniversalAxis1Offset (jId, axis[0], axis[1], axis[2], M_PI/2.0, 0);
+ CHECK_CLOSE (M_PI/2.0, dJointGetUniversalAngle1 (jId), 1e-4);
+
+ dRFromAxisAndAngle (R, 1, 0, 0, 0);
+ dBodySetRotation (bId1, R);
+
+ CHECK_CLOSE (0, dJointGetUniversalAngle1 (jId), 1e-4);
+ }
+
+ // Rotate the body by -0.23rad around X then back to original position.
+ // The body is attached at the second position of the joint:
+ // dJointAttache(jId, 0, bId);
+ //
+ // ^ ^
+ // | => /
+ // | /
+ // B1 B1
+ //
+ // Start with a Delta of -0.23rad
+ // ^ ^
+ // / => |
+ // / |
+ // B1 B1
+ TEST_FIXTURE (Fixture_dxJointUniversal_B1_At_Zero_Default_Axes,
+ test_dJointSetUniversalAxisOffset_1Body_B1_Minus0_23rad)
+ {
+ CHECK_CLOSE (dJointGetUniversalAngle1 (jId), 0, 1e-4);
+
+ dMatrix3 R;
+ dRFromAxisAndAngle (R, 1, 0, 0, -REAL(0.23));
+ dBodySetRotation (bId1, R);
+
+ CHECK_CLOSE (-REAL(0.23), dJointGetUniversalAngle1 (jId), 1e-4);
+
+ dVector3 axis;
+ dJointGetUniversalAxis1 (jId, axis);
+ dJointSetUniversalAxis1Offset (jId, axis[0], axis[1], axis[2], -REAL(0.23), 0);
+ CHECK_CLOSE (-REAL(0.23), dJointGetUniversalAngle1 (jId), 1e-4);
+
+ dRFromAxisAndAngle (R, 1, 0, 0, 0);
+ dBodySetRotation (bId1, R);
+
+ CHECK_CLOSE (0, dJointGetUniversalAngle1 (jId), 1e-4);
+ }
+
+
+
+ // Only one body body1 at (0,0,0)
+ // The joint is an Universal Joint.
+ // Axis the inverse of the X axis
+ // Anchor at (0, 0, 0)
+ //
+ // ^Y
+ // |
+ // |
+ // |
+ // |
+ // |
+ // Z <-- X
+ struct Fixture_dxJointUniversal_B1_At_Zero_Axis_Inverse_of_X
+ {
+ Fixture_dxJointUniversal_B1_At_Zero_Axis_Inverse_of_X()
+ {
+ wId = dWorldCreate();
+
+ bId1 = dBodyCreate (wId);
+ dBodySetPosition (bId1, 0, 0, 0);
+
+ jId = dJointCreateUniversal (wId, 0);
+ joint = (dxJointUniversal*) jId;
+
+
+ dJointAttach (jId, bId1, NULL);
+ dJointSetUniversalAnchor (jId, 0, 0, 0);
+
+ axis[0] = -1;
+ axis[1] = 0;
+ axis[2] = 0;
+ dJointSetUniversalAxis1(jId, axis[0], axis[1], axis[2]);
+ }
+
+ ~Fixture_dxJointUniversal_B1_At_Zero_Axis_Inverse_of_X()
+ {
+ dWorldDestroy (wId);
+ }
+
+ dWorldID wId;
+
+ dBodyID bId1;
+
+
+ dJointID jId;
+ dxJointUniversal* joint;
+
+ dVector3 axis;
+ };
+
+ // Rotate B1 by 90deg around X then back to original position
+ //
+ // ^
+ // | => <---
+ // |
+ // B1 B1
+ //
+ // Start with a Delta of 90deg
+ // ^
+ // <--- => |
+ // |
+ // B1 B1
+ TEST_FIXTURE (Fixture_dxJointUniversal_B1_At_Zero_Axis_Inverse_of_X,
+ test_dJointSetUniversalAxisOffset_1Body_B1_90Deg)
+ {
+ CHECK_CLOSE (0, dJointGetUniversalAngle1 (jId), 1e-4);
+
+ dVector3 axis;
+ dJointGetUniversalAxis1(jId, axis);
+
+ dReal ang1 = d2r(REAL(90.0));
+
+ dMatrix3 R;
+ dRFromAxisAndAngle (R, axis[0], axis[1], axis[2], ang1);
+ dBodySetRotation (bId1, R);
+
+ CHECK_CLOSE (ang1, dJointGetUniversalAngle1 (jId), 1e-4);
+
+ dJointSetUniversalAxis1Offset (jId, axis[0], axis[1], axis[2], ang1, 0);
+ CHECK_CLOSE (ang1, dJointGetUniversalAngle1 (jId), 1e-4);
+
+ dRSetIdentity(R); // Set the rotation of the body to be zero
+ dBodySetRotation (bId1, R);
+
+ CHECK_CLOSE (0, dJointGetUniversalAngle1 (jId), 1e-4);
+ }
+
+ // Rotate B1 by -0.23rad around X then back to original position
+ //
+ // ^ ^
+ // | => /
+ // | /
+ // B1 B1
+ //
+ // Start with a Delta of -0.23rad
+ // ^ ^
+ // / => |
+ // / |
+ // B1 B1
+ TEST_FIXTURE (Fixture_dxJointUniversal_B1_At_Zero_Axis_Inverse_of_X,
+ test_dJointSetUniversalAxisOffset_1Body_B1_Minus0_23rad)
+ {
+ CHECK_CLOSE (dJointGetUniversalAngle1 (jId), 0, 1e-4);
+
+ dMatrix3 R;
+ dRFromAxisAndAngle (R, 1, 0, 0, -REAL(0.23));
+ dBodySetRotation (bId1, R);
+
+ CHECK_CLOSE (REAL(0.23), dJointGetUniversalAngle1 (jId), 1e-4);
+
+ dVector3 axis;
+ dJointGetUniversalAxis1 (jId, axis);
+ dJointSetUniversalAxis1Offset (jId, axis[0], axis[1], axis[2], REAL(0.23), 0);
+ CHECK_CLOSE (REAL(0.23), dJointGetUniversalAngle1 (jId), 1e-4);
+
+ dRFromAxisAndAngle (R, 1, 0, 0, 0);
+ dBodySetRotation (bId1, R);
+
+ CHECK_CLOSE (0, dJointGetUniversalAngle1 (jId), 1e-4);
+ }
+
+
+
+
+
+
+
+ // Rotate B2 by 90deg around X then back to original position
+ //
+ // ^
+ // | => <---
+ // |
+ // B2 B2
+ //
+ // Start with a Delta of 90deg
+ // ^
+ // <--- => |
+ // |
+ // B2 B2
+ TEST_FIXTURE (Fixture_dxJointUniversal_B2_At_Zero_Default_Axes,
+ test_dJointSetUniversalAxisOffset_1Body_B2_90Deg)
+ {
+ CHECK_CLOSE (0, dJointGetUniversalAngle1 (jId), 1e-4);
+ CHECK_CLOSE (0, dJointGetUniversalAngle2 (jId), 1e-4);
+
+
+ dVector3 axis;
+ dJointGetUniversalAxis2 (jId, axis);
+
+ dReal ang2 = d2r(REAL(90.0));
+
+ dMatrix3 R;
+ dRFromAxisAndAngle (R, axis[0], axis[1], axis[2], ang2);
+ dBodySetRotation (bId2, R);
+
+ CHECK_CLOSE (-ang2, dJointGetUniversalAngle2 (jId), 1e-4);
+
+ dJointSetUniversalAxis2Offset (jId, axis[0], axis[1], axis[2], 0, -ang2);
+ CHECK_CLOSE (0, dJointGetUniversalAngle1 (jId), 1e-4);
+ CHECK_CLOSE (-ang2, dJointGetUniversalAngle2 (jId), 1e-4);
+
+
+ dRSetIdentity(R); // Set the rotation of the body to be zero
+ dBodySetRotation (bId2, R);
+
+ CHECK_CLOSE (0, dJointGetUniversalAngle2 (jId), 1e-4);
+ }
+
+ // Rotate B2 by -0.23rad around Y then back to original position
+ //
+ // ^ ^
+ // | => /
+ // | /
+ // B2 B2
+ //
+ // Start with an offset of -0.23rad
+ // ^ ^
+ // / => |
+ // / |
+ // B2 B2
+ TEST_FIXTURE (Fixture_dxJointUniversal_B2_At_Zero_Default_Axes,
+ test_dJointSetUniversalAxis2Offset_1Body_B2_Minus0_23rad)
+ {
+ CHECK_CLOSE (0, dJointGetUniversalAngle1 (jId), 1e-4);
+ CHECK_CLOSE (0, dJointGetUniversalAngle2 (jId), 1e-4);
+
+ dReal angle1, angle2;
+ dJointGetUniversalAngles(jId, &angle1, &angle2);
+ CHECK_CLOSE (0, angle1, 1e-4);
+ CHECK_CLOSE (0, angle2, 1e-4);
+
+ dVector3 axis;
+ dJointGetUniversalAxis2 (jId, axis);
+
+ dReal ang1 = 0;
+ dReal ang2 = REAL(-0.23);
+
+
+ dMatrix3 R;
+ dRFromAxisAndAngle (R, axis[0], axis[1], axis[2], ang2);
+ dBodySetRotation (bId2, R);
+
+
+ CHECK_CLOSE (ang1, dJointGetUniversalAngle1 (jId), 1e-4);
+ CHECK_CLOSE (-ang2, dJointGetUniversalAngle2 (jId), 1e-4);
+
+ dJointGetUniversalAngles(jId, &angle1, &angle2);
+ CHECK_CLOSE (ang1, angle1, 1e-4);
+ CHECK_CLOSE (-ang2, angle2, 1e-4);
+
+
+ dJointSetUniversalAxis2Offset (jId, axis[0], axis[1], axis[2],
+ ang1, -ang2);
+ CHECK_CLOSE (ang1, dJointGetUniversalAngle1 (jId), 1e-4);
+ CHECK_CLOSE (-ang2, dJointGetUniversalAngle2 (jId), 1e-4);
+
+ dRSetIdentity(R); // Set the rotation of the body to be zero
+ dBodySetRotation (bId2, R);
+
+ CHECK_CLOSE (0, dJointGetUniversalAngle1 (jId), 1e-4);
+ CHECK_CLOSE (0, dJointGetUniversalAngle2 (jId), 1e-4);
+
+ dJointGetUniversalAngles(jId, &angle1, &angle2);
+ CHECK_CLOSE (0, angle1, 1e-4);
+ CHECK_CLOSE (0, angle2, 1e-4);
+ }
+
+
+
+
+
+
+
+
+
+
+
+
+ // The 2 bodies are positionned at (0,0,0), and (0,0,0)
+ // The bodis have no rotation.
+ // The joint is a Universal Joint
+ // The axis of the joint are at random (Still at 90deg w.r.t each other)
+ // Anchor at (0, 0, 0)
+ struct Fixture_dxJointUniversal_B1_and_B2_Axis_Random
+ {
+ Fixture_dxJointUniversal_B1_and_B2_Axis_Random()
+ {
+ wId = dWorldCreate();
+
+ bId1 = dBodyCreate (wId);
+ dBodySetPosition (bId1, -1, -2, -3);
+
+ bId2 = dBodyCreate (wId);
+ dBodySetPosition (bId2, 11, 22, 33);
+
+
+ jId = dJointCreateUniversal (wId, 0);
+
+
+ dJointAttach (jId, bId1, bId2);
+
+ dVector3 axis1;
+ axis1[0] = REAL(0.53);
+ axis1[1] = -REAL(0.71);
+ axis1[2] = REAL(0.43);
+ dNormalize3(axis1);
+
+ dVector3 axis;
+ axis[0] = REAL(1.2);
+ axis[1] = REAL(0.87);
+ axis[2] = -REAL(0.33);
+
+ dVector3 axis2;
+ dCalcVectorCross3(axis2, axis1, axis);
+
+ dJointSetUniversalAxis1(jId, axis1[0], axis1[1], axis1[2]);
+ dJointSetUniversalAxis2(jId, axis2[0], axis2[1], axis2[2]);
+ }
+
+ ~Fixture_dxJointUniversal_B1_and_B2_Axis_Random()
+ {
+ dWorldDestroy (wId);
+ }
+
+
+ dWorldID wId;
+
+ dBodyID bId1;
+ dBodyID bId2;
+
+
+ dJointID jId;
+ };
+
+
+ // Rotate first body 90deg around Axis1 then back to original position
+ //
+ // ^ ^ ^ Z ^
+ // | | => <--- | |
+ // | | | |
+ // B1 B2 B1 B2 X .----->Y
+ // N.B. X is going out of the screen
+ // Set Axis1 with an Offset of 90deg
+ // ^ ^ ^
+ // <--- | => | |
+ // | | |
+ // B1 B2 B1 B2
+ TEST_FIXTURE (Fixture_dxJointUniversal_B1_and_B2_Axis_Random,
+ test_dJointSetUniversalAxisOffset_B1_90deg_Axis_Random)
+ {
+ CHECK_CLOSE (0, dJointGetUniversalAngle1 (jId), 1e-4);
+ CHECK_CLOSE (0, dJointGetUniversalAngle2 (jId), 1e-4);
+ dReal angle1, angle2;
+ dJointGetUniversalAngles(jId, &angle1, &angle2);
+ CHECK_CLOSE (0, angle1, 1e-4);
+ CHECK_CLOSE (0, angle2, 1e-4);
+
+
+ dVector3 axis;
+ dJointGetUniversalAxis1 (jId, axis);
+
+ dReal angle = d2r(90);
+ dMatrix3 R;
+ dRFromAxisAndAngle (R, axis[0], axis[1], axis[2], angle);
+ dBodySetRotation (bId1, R);
+
+
+ CHECK_CLOSE (angle, dJointGetUniversalAngle1 (jId), 1e-4);
+ CHECK_CLOSE (0, dJointGetUniversalAngle2 (jId), 1e-4);
+
+ dJointGetUniversalAngles(jId, &angle1, &angle2);
+ CHECK_CLOSE (angle, angle1, 1e-4);
+ CHECK_CLOSE (0, angle2, 1e-4);
+
+
+
+ dJointSetUniversalAxis1Offset (jId, axis[0], axis[1], axis[2], angle, 0);
+ CHECK_CLOSE (angle, dJointGetUniversalAngle1 (jId), 1e-4);
+ CHECK_CLOSE (0, dJointGetUniversalAngle2 (jId), 1e-4);
+
+ dJointGetUniversalAngles(jId, &angle1, &angle2);
+ CHECK_CLOSE (angle, angle1, 1e-4);
+ CHECK_CLOSE (0, angle2, 1e-4);
+
+
+ dRFromAxisAndAngle (R, axis[0], axis[1], axis[2], 0);
+ dBodySetRotation (bId1, R);
+
+ CHECK_CLOSE (0, dJointGetUniversalAngle1 (jId), 1e-4);
+ CHECK_CLOSE (0, dJointGetUniversalAngle2 (jId), 1e-4);
+
+ dJointGetUniversalAngles(jId, &angle1, &angle2);
+ CHECK_CLOSE (0, angle1, 1e-4);
+ CHECK_CLOSE (0, angle2, 1e-4);
+ }
+
+} // End of SUITE TestdxJointUniversal
+
diff --git a/libs/ode-0.16.1/tests/main.cpp b/libs/ode-0.16.1/tests/main.cpp
new file mode 100644
index 0000000..d427825
--- /dev/null
+++ b/libs/ode-0.16.1/tests/main.cpp
@@ -0,0 +1,13 @@
+// openode_UnitTest++.cpp : Defines the entry point for the console application.
+//
+
+#include <UnitTest++.h>
+#include <ode/ode.h>
+
+int main()
+{
+ dInitODE();
+ int res = UnitTest::RunAllTests();
+ dCloseODE();
+ return res;
+}
diff --git a/libs/ode-0.16.1/tests/odemath.cpp b/libs/ode-0.16.1/tests/odemath.cpp
new file mode 100644
index 0000000..4ddd818
--- /dev/null
+++ b/libs/ode-0.16.1/tests/odemath.cpp
@@ -0,0 +1,247 @@
+/*************************************************************************
+ * *
+ * 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. *
+ * *
+ *************************************************************************/
+//234567890123456789012345678901234567890123456789012345678901234567890123456789
+// 1 2 3 4 5 6 7
+
+#include <UnitTest++.h>
+#include <ode/ode.h>
+#include <ode/odemath.h>
+
+
+
+TEST(test_dNormalization3)
+{
+ const dVector3 x = {1,0,0,0};
+ const dVector3 y = {0,1,0,0};
+ const dVector3 z = {0,0,1,0};
+ dVector3 v;
+
+ // Check when value in first component (i.e. [0])
+ v[0] = REAL(1.0);
+ v[1] = REAL(0.0);
+ v[2] = REAL(0.0);
+ dSafeNormalize3(v);
+ CHECK_ARRAY_CLOSE(x, v, 3, 1e-6);
+ CHECK_EQUAL(dCalcVectorLength3(v), REAL(1.0));
+
+ v[0] = REAL(0.1);
+ v[1] = REAL(0.0);
+ v[2] = REAL(0.0);
+ dSafeNormalize3(v);
+ CHECK_ARRAY_CLOSE(x, v, 3, 1e-6);
+ CHECK_EQUAL(dCalcVectorLength3(v), REAL(1.0));
+
+ v[0] = REAL(1e-20);
+ v[1] = REAL(0.0);
+ v[2] = REAL(0.0);
+ dSafeNormalize3(v);
+ CHECK_ARRAY_CLOSE(x, v, 3, 1e-6);
+ CHECK_EQUAL(dCalcVectorLength3(v), REAL(1.0));
+
+
+ // Check when value in first component (i.e. [0])
+ v[0] = REAL(0.0);
+ v[1] = REAL(1.0);
+ v[2] = REAL(0.0);
+ dSafeNormalize3(v);
+ CHECK_ARRAY_CLOSE(y, v, 3, 1e-6);
+ CHECK_EQUAL(dCalcVectorLength3(v), REAL(1.0));
+
+ v[0] = REAL(0.0);
+ v[1] = REAL(0.1);
+ v[2] = REAL(0.0);
+ dSafeNormalize3(v);
+ CHECK_ARRAY_CLOSE(y, v, 3, 1e-6);
+ CHECK_EQUAL(dCalcVectorLength3(v), REAL(1.0));
+
+ v[0] = REAL(0.0);
+ v[1] = REAL(1e-20);
+ v[2] = REAL(0.0);
+ dSafeNormalize3(v);
+ CHECK_ARRAY_CLOSE(y, v, 3, 1e-6);
+ CHECK_EQUAL(dCalcVectorLength3(v), REAL(1.0));
+
+
+ // Check when value in first component (i.e. [0])
+ v[0] = REAL(0.0);
+ v[1] = REAL(0.0);
+ v[2] = REAL(1.0);
+ dSafeNormalize3(v);
+ CHECK_ARRAY_CLOSE(z, v, 3, 1e-6);
+ CHECK_EQUAL(dCalcVectorLength3(v), REAL(1.0));
+
+ v[0] = REAL(0.0);
+ v[1] = REAL(0.0);
+ v[2] = REAL(0.1);
+ dSafeNormalize3(v);
+ CHECK_ARRAY_CLOSE(z, v, 3, 1e-6);
+ CHECK_EQUAL(dCalcVectorLength3(v), REAL(1.0));
+
+ v[0] = REAL(0.0);
+ v[1] = REAL(0.0);
+ v[2] = REAL(1e-20);
+ dSafeNormalize3(v);
+ CHECK_ARRAY_CLOSE(z, v, 3, 1e-6);
+ CHECK_EQUAL(dCalcVectorLength3(v), REAL(1.0));
+
+
+ // Check negative
+ // Check when value in first component (i.e. [0])
+ v[0] = REAL(-1.0);
+ v[1] = REAL(0.0);
+ v[2] = REAL(0.0);
+ dSafeNormalize3(v);
+ CHECK_EQUAL(dCalcVectorLength3(v), REAL(1.0));
+
+ v[0] = REAL(-0.1);
+ v[1] = REAL(0.0);
+ v[2] = REAL(0.0);
+ dSafeNormalize3(v);
+ CHECK_EQUAL(dCalcVectorLength3(v), REAL(1.0));
+
+ v[0] = REAL(-1e-20);
+ v[1] = REAL(0.0);
+ v[2] = REAL(0.0);
+ dSafeNormalize3(v);
+ CHECK_EQUAL(dCalcVectorLength3(v), REAL(1.0));
+
+
+ // Check when value in first component (i.e. [0])
+ v[0] = REAL(0.0);
+ v[1] = REAL(-1.0);
+ v[2] = REAL(0.0);
+ dSafeNormalize3(v);
+ CHECK_EQUAL(dCalcVectorLength3(v), REAL(1.0));
+
+ v[0] = REAL(0.0);
+ v[1] = REAL(-0.1);
+ v[2] = REAL(0.0);
+ dSafeNormalize3(v);
+ CHECK_EQUAL(dCalcVectorLength3(v), REAL(1.0));
+
+ v[0] = REAL(0.0);
+ v[1] = REAL(-1e-20);
+ v[2] = REAL(0.0);
+ dSafeNormalize3(v);
+ CHECK_EQUAL(dCalcVectorLength3(v), REAL(1.0));
+
+
+ // Check when value in first component (i.e. [0])
+ v[0] = REAL(0.0);
+ v[1] = REAL(0.0);
+ v[2] = REAL(-1.0);
+ dSafeNormalize3(v);
+ CHECK_EQUAL(dCalcVectorLength3(v), REAL(1.0));
+
+ v[0] = REAL(0.0);
+ v[1] = REAL(0.0);
+ v[2] = REAL(-0.1);
+ dSafeNormalize3(v);
+ CHECK_EQUAL(dCalcVectorLength3(v), REAL(1.0));
+
+ v[0] = REAL(0.0);
+ v[1] = REAL(0.0);
+ v[2] = REAL(-1e-20);
+ dSafeNormalize3(v);
+ CHECK_EQUAL(dCalcVectorLength3(v), REAL(1.0));
+
+
+ v[0] = REAL(9999999999.0);
+ v[1] = REAL(0.0);
+ v[2] = REAL(1e-20);
+ dSafeNormalize3(v);
+ CHECK_EQUAL(dCalcVectorLength3(v), REAL(1.0));
+
+
+ v[0] = REAL(9999999999.0);
+ v[1] = REAL(9999.0);
+ v[2] = REAL(9.0);
+ dSafeNormalize3(v);
+ CHECK_CLOSE(dCalcVectorLength3(v), REAL(1.0),REAL(0.001));
+
+}
+
+
+TEST(test_dOrthogonalizeR)
+{
+ {
+ dMatrix3 r1 = { 1, 0, 0, 0,
+ 0, 1, 0, 0,
+ 0, 0, 1, 0
+ };
+ dMatrix3 r2;
+ memcpy(r2, r1, sizeof(dMatrix3));
+ dOrthogonalizeR(r2);
+ CHECK_ARRAY_EQUAL(r1, r2, 12);
+ }
+ {
+ dMatrix3 r1 = { 0, 1, 0, 0,
+ 0, 0, 1, 0,
+ 1, 0, 0, 0
+ };
+ dMatrix3 r2;
+ memcpy(r2, r1, sizeof(dMatrix3));
+ dOrthogonalizeR(r2);
+ CHECK_ARRAY_EQUAL(r1, r2, 12);
+ }
+ {
+ dMatrix3 r1 = { 0, 0, 1, 0,
+ 1, 0, 0, 0,
+ 0, 1, 0, 0
+ };
+ dMatrix3 r2;
+ memcpy(r2, r1, sizeof(dMatrix3));
+ dOrthogonalizeR(r2);
+ CHECK_ARRAY_EQUAL(r1, r2, 12);
+ }
+ {
+ dMatrix3 r1 = { -1, 0, 0, 0,
+ 0, 1, 0, 0,
+ 0, 0, -1, 0
+ };
+ dMatrix3 r2;
+ memcpy(r2, r1, sizeof(dMatrix3));
+ dOrthogonalizeR(r2);
+ CHECK_ARRAY_EQUAL(r1, r2, 12);
+ }
+ {
+ dMatrix3 r1 = { 0, -1, 0, 0,
+ 0, 0, 1, 0,
+ -1, 0, 0, 0
+ };
+ dMatrix3 r2;
+ memcpy(r2, r1, sizeof(dMatrix3));
+ dOrthogonalizeR(r2);
+ CHECK_ARRAY_EQUAL(r1, r2, 12);
+ }
+ {
+ dMatrix3 r1 = { 0, 0, -1, 0,
+ 0, -1, 0, 0,
+ -1, 0, 0, 0
+ };
+ dMatrix3 r2;
+ memcpy(r2, r1, sizeof(dMatrix3));
+ dOrthogonalizeR(r2);
+ CHECK_ARRAY_EQUAL(r1, r2, 12);
+ }
+
+}