checkin of ODE library. Do not modify the ODE source code; instead, follow the
authorNorman Lin <nlin@nlin.net>
Fri, 18 Oct 2002 15:02:02 +0000 (15:02 +0000)
committerNorman Lin <nlin@nlin.net>
Fri, 18 Oct 2002 15:02:02 +0000 (15:02 +0000)
development of ode at http://q12.org and periodically copy the q12.org ODE
sourcecode into this tree to update the Blender ODE.

This ODE has not been changed from q12.org and is provided here merely as a
convenience to Blender developers.

97 files changed:
extern/ode/dist/INSTALL [new file with mode: 0644]
extern/ode/dist/LICENSE-BSD.TXT [new file with mode: 0644]
extern/ode/dist/LICENSE.TXT [new file with mode: 0644]
extern/ode/dist/Makefile [new file with mode: 0644]
extern/ode/dist/Makefile.deps [new file with mode: 0644]
extern/ode/dist/README [new file with mode: 0644]
extern/ode/dist/README_BLENDER [new file with mode: 0644]
extern/ode/dist/config/README [new file with mode: 0644]
extern/ode/dist/config/makefile.cygwin [new file with mode: 0644]
extern/ode/dist/config/makefile.mingw [new file with mode: 0644]
extern/ode/dist/config/makefile.msvc [new file with mode: 0644]
extern/ode/dist/config/makefile.msvc-dll [new file with mode: 0644]
extern/ode/dist/config/makefile.osx [new file with mode: 0644]
extern/ode/dist/config/makefile.unix-gcc [new file with mode: 0644]
extern/ode/dist/config/makefile.unix-generic [new file with mode: 0644]
extern/ode/dist/config/msvcdefs.def [new file with mode: 0644]
extern/ode/dist/config/user-settings [new file with mode: 0644]
extern/ode/dist/config/user-settings.example [new file with mode: 0644]
extern/ode/dist/configurator.c [new file with mode: 0644]
extern/ode/dist/include/ode/README [new file with mode: 0644]
extern/ode/dist/include/ode/common.h [new file with mode: 0644]
extern/ode/dist/include/ode/contact.h [new file with mode: 0644]
extern/ode/dist/include/ode/error.h [new file with mode: 0644]
extern/ode/dist/include/ode/geom.h [new file with mode: 0644]
extern/ode/dist/include/ode/mass.h [new file with mode: 0644]
extern/ode/dist/include/ode/matrix.h [new file with mode: 0644]
extern/ode/dist/include/ode/memory.h [new file with mode: 0644]
extern/ode/dist/include/ode/misc.h [new file with mode: 0644]
extern/ode/dist/include/ode/objects.h [new file with mode: 0644]
extern/ode/dist/include/ode/ode.h [new file with mode: 0644]
extern/ode/dist/include/ode/odecpp.h [new file with mode: 0644]
extern/ode/dist/include/ode/odecpp_old.h [new file with mode: 0644]
extern/ode/dist/include/ode/odemath.h [new file with mode: 0644]
extern/ode/dist/include/ode/rotation.h [new file with mode: 0644]
extern/ode/dist/include/ode/space.h [new file with mode: 0644]
extern/ode/dist/include/ode/timer.h [new file with mode: 0644]
extern/ode/dist/ode/README [new file with mode: 0644]
extern/ode/dist/ode/fbuild/BuildDot [new file with mode: 0644]
extern/ode/dist/ode/fbuild/BuildLDLT [new file with mode: 0644]
extern/ode/dist/ode/fbuild/BuildMultidot [new file with mode: 0644]
extern/ode/dist/ode/fbuild/BuildUtil [new file with mode: 0644]
extern/ode/dist/ode/fbuild/Dependencies [new file with mode: 0644]
extern/ode/dist/ode/fbuild/Makefile [new file with mode: 0644]
extern/ode/dist/ode/fbuild/OptimizeDot [new file with mode: 0644]
extern/ode/dist/ode/fbuild/OptimizeLDLT [new file with mode: 0644]
extern/ode/dist/ode/fbuild/OptimizeLSolve [new file with mode: 0644]
extern/ode/dist/ode/fbuild/OptimizeLTSolve [new file with mode: 0644]
extern/ode/dist/ode/fbuild/OptimizeMultidot [new file with mode: 0644]
extern/ode/dist/ode/fbuild/OptimizeUtil [new file with mode: 0644]
extern/ode/dist/ode/fbuild/ParametersD.example [new file with mode: 0644]
extern/ode/dist/ode/fbuild/ParametersF.example [new file with mode: 0644]
extern/ode/dist/ode/fbuild/ParametersM.example [new file with mode: 0644]
extern/ode/dist/ode/fbuild/ParametersS.example [new file with mode: 0644]
extern/ode/dist/ode/fbuild/ParametersT.example [new file with mode: 0644]
extern/ode/dist/ode/fbuild/README [new file with mode: 0644]
extern/ode/dist/ode/fbuild/ldlt.m [new file with mode: 0644]
extern/ode/dist/ode/fbuild/test_dot.cpp [new file with mode: 0644]
extern/ode/dist/ode/fbuild/test_ldlt.cpp [new file with mode: 0644]
extern/ode/dist/ode/fbuild/test_multidot.cpp [new file with mode: 0644]
extern/ode/dist/ode/src/array.cpp [new file with mode: 0644]
extern/ode/dist/ode/src/array.h [new file with mode: 0644]
extern/ode/dist/ode/src/error.cpp [new file with mode: 0644]
extern/ode/dist/ode/src/fastdot.c [new file with mode: 0644]
extern/ode/dist/ode/src/fastldlt.c [new file with mode: 0644]
extern/ode/dist/ode/src/fastlsolve.c [new file with mode: 0644]
extern/ode/dist/ode/src/fastltsolve.c [new file with mode: 0644]
extern/ode/dist/ode/src/geom.cpp [new file with mode: 0644]
extern/ode/dist/ode/src/geom_internal.h [new file with mode: 0644]
extern/ode/dist/ode/src/joint.cpp [new file with mode: 0644]
extern/ode/dist/ode/src/joint.h [new file with mode: 0644]
extern/ode/dist/ode/src/lcp.cpp [new file with mode: 0644]
extern/ode/dist/ode/src/lcp.h [new file with mode: 0644]
extern/ode/dist/ode/src/mass.cpp [new file with mode: 0644]
extern/ode/dist/ode/src/mat.cpp [new file with mode: 0644]
extern/ode/dist/ode/src/mat.h [new file with mode: 0644]
extern/ode/dist/ode/src/matrix.cpp [new file with mode: 0644]
extern/ode/dist/ode/src/memory.cpp [new file with mode: 0644]
extern/ode/dist/ode/src/misc.cpp [new file with mode: 0644]
extern/ode/dist/ode/src/objects.h [new file with mode: 0644]
extern/ode/dist/ode/src/obstack.cpp [new file with mode: 0644]
extern/ode/dist/ode/src/obstack.h [new file with mode: 0644]
extern/ode/dist/ode/src/ode.cpp [new file with mode: 0644]
extern/ode/dist/ode/src/odemath.cpp [new file with mode: 0644]
extern/ode/dist/ode/src/rotation.cpp [new file with mode: 0644]
extern/ode/dist/ode/src/scrapbook.cpp [new file with mode: 0644]
extern/ode/dist/ode/src/space.cpp [new file with mode: 0644]
extern/ode/dist/ode/src/stack.cpp [new file with mode: 0644]
extern/ode/dist/ode/src/stack.h [new file with mode: 0644]
extern/ode/dist/ode/src/step.cpp [new file with mode: 0644]
extern/ode/dist/ode/src/step.h [new file with mode: 0644]
extern/ode/dist/ode/src/testing.cpp [new file with mode: 0644]
extern/ode/dist/ode/src/testing.h [new file with mode: 0644]
extern/ode/dist/ode/src/timer.cpp [new file with mode: 0644]
extern/ode/dist/tools/build4 [new file with mode: 0755]
extern/ode/dist/tools/build4.bat [new file with mode: 0755]
extern/ode/dist/tools/make_distribution [new file with mode: 0755]
extern/ode/dist/tools/process_deps [new file with mode: 0755]

diff --git a/extern/ode/dist/INSTALL b/extern/ode/dist/INSTALL
new file mode 100644 (file)
index 0000000..f82285d
--- /dev/null
@@ -0,0 +1,44 @@
+
+here are the steps to buid ODE:
+
+(1) get the GNU 'make' tool. many unix platforms come with this, although
+    sometimes it is called 'gmake'. i have provided a version of GNU make
+    for windows at: http://q12.org/ode/bin/make.exe
+
+(2) edit the settings in the file config/user-settings. the list of supported
+    platforms is given in that file.
+
+(3) run 'make' to configure and build ODE and the graphical test programs.
+    to build parts of ODE the make targets are:
+
+       make configure          create configuration file include/ode/config.h
+       make ode-lib            build the core ODE library
+       make drawstuff-lib      build the OpenGL-based graphics library
+       make ode-test           build some ODE tests (they need drawstuff)
+       make drawstuff-test     build a test app for the drawstuff library
+
+    all of these targets will do an implicit 'make configure'. if the
+    configurator screws up then you can edit the settings directly in
+    include/ode/config.h.
+
+(4) to install the ODE library onto your system you should copy the 'lib' and
+    'include' directories to a suitable place, e.g. on unix:
+
+       include/ode  --> /usr/local/include/ode
+       lib/libode.a --> /usr/local/lib/libode.a
+
+ODE has been verified to build on the following platforms:
+
+                               config          ode-lib         ode-test
+                               ------          -------         --------
+  windows
+    MSVC                       msvc            *               *
+    MinGW                      mingw           *               *
+    CygWin                     cygwin          *               *
+  linux (x86, mandrake 8.1)    unix-gcc        *               *
+  linux (alpha, debian 2.2)    unix-gcc        *               ?
+  linux (RS/6000, debian 2.2)  unix-gcc        *               ?
+  linux (Sparc U60, debian 2.2) unix-gcc       *               ?
+  freebsd 4.3                  unix-gcc        *               ?
+  Mac OS-X                     osx             *               ?
+  Solaris 8 (Sparc R220)       unix-gcc        *               ?
diff --git a/extern/ode/dist/LICENSE-BSD.TXT b/extern/ode/dist/LICENSE-BSD.TXT
new file mode 100644 (file)
index 0000000..0592923
--- /dev/null
@@ -0,0 +1,34 @@
+
+This is the BSD-style license for the Open Dynamics Engine
+----------------------------------------------------------
+
+Open Dynamics Engine
+Copyright (c) 2001,2002, Russell L. Smith.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+Redistributions of source code must retain the above copyright notice,
+this list of conditions and the following disclaimer.
+
+Redistributions in binary form must reproduce the above copyright notice,
+this list of conditions and the following disclaimer in the documentation
+and/or other materials provided with the distribution.
+
+Neither the names of ODE's copyright owner nor the names of its
+contributors may be used to endorse or promote products derived from
+this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/extern/ode/dist/LICENSE.TXT b/extern/ode/dist/LICENSE.TXT
new file mode 100644 (file)
index 0000000..cfe59bc
--- /dev/null
@@ -0,0 +1,502 @@
+                 GNU LESSER GENERAL PUBLIC LICENSE
+                      Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+     59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL.  It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+                           Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+  This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it.  You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+  When we speak of free software, we are referring to freedom of use,
+not price.  Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+  To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights.  These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+  For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you.  You must make sure that they, too, receive or can get the source
+code.  If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it.  And you must show them these terms so they know their rights.
+
+  We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+  To protect each distributor, we want to make it very clear that
+there is no warranty for the free library.  Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+\f
+  Finally, software patents pose a constant threat to the existence of
+any free program.  We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder.  Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+  Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License.  This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License.  We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+  When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library.  The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom.  The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+  We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License.  It also provides other free software developers Less
+of an advantage over competing non-free programs.  These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries.  However, the Lesser license provides advantages in certain
+special circumstances.
+
+  For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard.  To achieve this, non-free programs must be
+allowed to use the library.  A more frequent case is that a free
+library does the same job as widely used non-free libraries.  In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+  In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software.  For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+  Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.  Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library".  The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+\f
+                 GNU LESSER GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+  A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+  The "Library", below, refers to any such software library or work
+which has been distributed under these terms.  A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language.  (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+  "Source code" for a work means the preferred form of the work for
+making modifications to it.  For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+  Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it).  Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+  
+  1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+  You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+\f
+  2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) The modified work must itself be a software library.
+
+    b) You must cause the files modified to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    c) You must cause the whole of the work to be licensed at no
+    charge to all third parties under the terms of this License.
+
+    d) If a facility in the modified Library refers to a function or a
+    table of data to be supplied by an application program that uses
+    the facility, other than as an argument passed when the facility
+    is invoked, then you must make a good faith effort to ensure that,
+    in the event an application does not supply such function or
+    table, the facility still operates, and performs whatever part of
+    its purpose remains meaningful.
+
+    (For example, a function in a library to compute square roots has
+    a purpose that is entirely well-defined independent of the
+    application.  Therefore, Subsection 2d requires that any
+    application-supplied function or table used by this function must
+    be optional: if the application does not supply it, the square
+    root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library.  To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License.  (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.)  Do not make any other change in
+these notices.
+\f
+  Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+  This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+  4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+  If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library".  Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+  However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library".  The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+  When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library.  The
+threshold for this to be true is not precisely defined by law.
+
+  If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work.  (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+  Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+\f
+  6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+  You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License.  You must supply a copy of this License.  If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License.  Also, you must do one
+of these things:
+
+    a) Accompany the work with the complete corresponding
+    machine-readable source code for the Library including whatever
+    changes were used in the work (which must be distributed under
+    Sections 1 and 2 above); and, if the work is an executable linked
+    with the Library, with the complete machine-readable "work that
+    uses the Library", as object code and/or source code, so that the
+    user can modify the Library and then relink to produce a modified
+    executable containing the modified Library.  (It is understood
+    that the user who changes the contents of definitions files in the
+    Library will not necessarily be able to recompile the application
+    to use the modified definitions.)
+
+    b) Use a suitable shared library mechanism for linking with the
+    Library.  A suitable mechanism is one that (1) uses at run time a
+    copy of the library already present on the user's computer system,
+    rather than copying library functions into the executable, and (2)
+    will operate properly with a modified version of the library, if
+    the user installs one, as long as the modified version is
+    interface-compatible with the version that the work was made with.
+
+    c) Accompany the work with a written offer, valid for at
+    least three years, to give the same user the materials
+    specified in Subsection 6a, above, for a charge no more
+    than the cost of performing this distribution.
+
+    d) If distribution of the work is made by offering access to copy
+    from a designated place, offer equivalent access to copy the above
+    specified materials from the same place.
+
+    e) Verify that the user has already received a copy of these
+    materials or that you have already sent this user a copy.
+
+  For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it.  However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+  It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system.  Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+\f
+  7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+    a) Accompany the combined library with a copy of the same work
+    based on the Library, uncombined with any other library
+    facilities.  This must be distributed under the terms of the
+    Sections above.
+
+    b) Give prominent notice with the combined library of the fact
+    that part of it is a work based on the Library, and explaining
+    where to find the accompanying uncombined form of the same work.
+
+  8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License.  Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License.  However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+  9. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Library or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+  10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+\f
+  11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded.  In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+  13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation.  If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+\f
+  14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission.  For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this.  Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+                           NO WARRANTY
+
+  15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+                    END OF TERMS AND CONDITIONS
+\f
+           How to Apply These Terms to Your New Libraries
+
+  If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change.  You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+  To apply these terms, attach the following notices to the library.  It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the library's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of 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.
+
+    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 GNU
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the
+  library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+  <signature of Ty Coon>, 1 April 1990
+  Ty Coon, President of Vice
+
+That's all there is to it!
diff --git a/extern/ode/dist/Makefile b/extern/ode/dist/Makefile
new file mode 100644 (file)
index 0000000..54ae683
--- /dev/null
@@ -0,0 +1,280 @@
+#########################################################################
+#                                                                       #
+# Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith.       #
+# All rights reserved.  Email: russ@q12.org   Web: www.q12.org          #
+#                                                                       #
+# This library is free software; you can redistribute it and/or         #
+# modify it under the terms of EITHER:                                  #
+#   (1) The GNU Lesser General Public License as published by the Free  #
+#       Software Foundation; either version 2.1 of the License, or (at  #
+#       your option) any later version. The text of the GNU Lesser      #
+#       General Public License is included with this library in the     #
+#       file LICENSE.TXT.                                               #
+#   (2) The BSD-style license that is included with this library in     #
+#       the file LICENSE-BSD.TXT.                                       #
+#                                                                       #
+# This library is distributed in the hope that it will be useful,       #
+# but WITHOUT ANY WARRANTY; without even the implied warranty of        #
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files    #
+# LICENSE.TXT and LICENSE-BSD.TXT for more details.                     #
+#                                                                       #
+#########################################################################
+
+USER_SETTINGS=config/user-settings
+include $(USER_SETTINGS)
+PLATFORM_MAKEFILE=config/makefile.$(PLATFORM)
+include $(PLATFORM_MAKEFILE)
+
+##############################################################################
+# check some variables that were supposed to be defined
+
+ifneq ($(BUILD),debug)
+ifneq ($(BUILD),release)
+$(error the BUILD variable is not set properly)
+endif
+endif
+
+ifneq ($(PRECISION),SINGLE)
+ifneq ($(PRECISION),DOUBLE)
+$(error the PRECISION variable is not set properly)
+endif
+endif
+
+##############################################################################
+# package settings
+
+ODE_SRC = \
+       ode/src/array.cpp \
+       ode/src/error.cpp \
+       ode/src/memory.cpp \
+       ode/src/obstack.cpp \
+       ode/src/odemath.cpp \
+       ode/src/matrix.cpp \
+       ode/src/misc.cpp \
+       ode/src/rotation.cpp \
+       ode/src/mass.cpp \
+       ode/src/ode.cpp \
+       ode/src/step.cpp \
+       ode/src/lcp.cpp \
+       ode/src/joint.cpp \
+       ode/src/space.cpp \
+       ode/src/geom.cpp \
+       ode/src/timer.cpp \
+       ode/src/mat.cpp \
+       ode/src/testing.cpp
+ODE_PREGEN_SRC = \
+       ode/src/fastldlt.c \
+       ode/src/fastlsolve.c \
+       ode/src/fastltsolve.c \
+       ode/src/fastdot.c
+
+ifeq ($(WINDOWS),1)
+DRAWSTUFF_SRC = drawstuff/src/drawstuff.cpp drawstuff/src/windows.cpp
+RESOURCE_FILE=lib/resources.RES
+else
+DRAWSTUFF_SRC = drawstuff/src/drawstuff.cpp drawstuff/src/x11.cpp
+endif
+
+ODE_LIB_NAME=ode
+DRAWSTUFF_LIB_NAME=drawstuff
+
+INCPATH=include
+LIBPATH=lib
+
+ODE_TEST_SRC_CPP = \
+       ode/test/test_ode.cpp \
+       ode/test/test_chain2.cpp \
+       ode/test/test_hinge.cpp \
+       ode/test/test_slider.cpp \
+       ode/test/test_collision.cpp \
+       ode/test/test_boxstack.cpp \
+       ode/test/test_buggy.cpp \
+       ode/test/test_joints.cpp \
+       ode/test/test_space.cpp \
+       ode/test/test_I.cpp \
+       ode/test/test_step.cpp \
+       ode/test/test_friction.cpp
+ODE_TEST_SRC_C = \
+       ode/test/test_chain1.c
+DRAWSTUFF_TEST_SRC_CPP = \
+       drawstuff/dstest/dstest.cpp
+
+CONFIGURATOR_SRC=configurator.c
+CONFIG_H=include/ode/config.h
+
+##############################################################################
+# derived things
+
+DEFINES=
+
+# add some defines depending on the build mode
+ifeq ($(BUILD),release)
+DEFINES+=$(C_DEF)dNODEBUG
+endif
+ifeq ($(BUILD),debug)
+DEFINES+=$(C_DEF)dDEBUG_ALLOC
+endif
+
+# object file names
+ODE_PREGEN_OBJECTS=$(ODE_PREGEN_SRC:%.c=%$(OBJ))
+ODE_OBJECTS=$(ODE_SRC:%.cpp=%$(OBJ)) $(ODE_PREGEN_OBJECTS)
+DRAWSTUFF_OBJECTS=$(DRAWSTUFF_SRC:%.cpp=%$(OBJ)) $(RESOURCE_FILE)
+
+# side-effect variables causing creation of files containing lists of
+# filenames to be linked, to work around command-line-length limitations
+# on outdated 16-bit operating systems. because of command-line length
+# limitations we cannot issue a link command with all object filenames
+# specified (because this command is too long and overflows the command
+# buffer), but instead must create a file containing all object filenames
+# to be linked, and specify this list-file with @listfile on the command-line.
+#
+# the difficult part is doing this in a flexible way; we don't want to
+# hard-code the to-be-linked object filenames in a file, but instead
+# want to dynamically create a file containing a list of all object filenames
+# within the $XXX_OBJECTS makefile variables. to do this, we use side-effect
+# variables.
+#
+# idea: when these variables are EVALUATED (i.e. later during rule execution,
+# not now during variable definition), they cause a SIDE EFFECT which creates
+# a file with the list of all ODE object files. why the chicanery??? because
+# if we have a command-line length limitation, no SINGLE command we issue will 
+# be able to create a file containing all object files to be linked
+# (because that command itself would need to include all filenames, making
+# it too long to be executed). instead, we must use the gnu-make "foreach"
+# function, combined - probably in an unintended way - with the "shell" 
+# function. this is probably unintended because we are not using the "shell"
+# function to return a string value for variable evaluation, but are instead 
+# using the "shell" function to cause a side effect (appending of each filename
+# to the filename-list-file).
+#
+# one possible snag is that, forbidding use of any external EXE utilities and
+# relying only on the facilities provided by the outdated 16-bit operating
+# system, there is no way to issue a SERIES of commands which append text to
+# the end of a file WITHOUT adding newlines. therefore, the list of to-be-
+# linked object files is separated by newlines in the list file. fortunately,
+# the linker utility for this outdated 16-bit operating system accepts
+# filenames on separate lines in the list file.
+
+# remember: when we evaluate these variables later, this causes the creation
+# of the appropriate list file.
+ifeq ($(WINDOWS16),1)
+SIDE_EFFECT_ODE_OBJLIST = $(foreach o,$(ODE_OBJECTS),$(shell echo $(o) >> odeobj.txt ))
+SIDE_EFFECT_DRAWSTUFF_OBJLIST = $(foreach o,$(DRAWSTUFF_OBJECTS),$(shell echo $(o) >> dsobj.txt ))
+endif
+
+# library file names
+ODE_LIB=$(LIBPATH)/$(LIB_PREFIX)$(ODE_LIB_NAME)$(LIB_SUFFIX)
+DRAWSTUFF_LIB=$(LIBPATH)/$(LIB_PREFIX)$(DRAWSTUFF_LIB_NAME)$(LIB_SUFFIX)
+
+# executable file names
+ODE_TEST_EXE=$(ODE_TEST_SRC_CPP:%.cpp=%.exe) $(ODE_TEST_SRC_C:%.c=%.exe)
+DRAWSTUFF_TEST_EXE=$(DRAWSTUFF_TEST_SRC_CPP:%.cpp=%.exe)
+CONFIGURATOR_EXE=$(CONFIGURATOR_SRC:%.c=%.exe)
+
+##############################################################################
+# rules
+#
+# NOTE: the '.c' files are pregenerated sources, and must be compiled with
+# -O1 optimization. that is why the rule for .c files is a bit different.
+# why should it be compiled with O1? it is numerical code that is generated
+# by fbuild. O1 optimization is used to preserve the operation orders that
+# were discovered by fbuild to be the fastest on that platform. believe it or
+# not, O2 makes this code run much slower for most compilers.
+
+all: ode-lib drawstuff-lib ode-test drawstuff-test
+       @echo SUCCESS
+
+ode-lib: configure $(ODE_LIB)
+drawstuff-lib: configure $(DRAWSTUFF_LIB)
+ode-test: ode-lib drawstuff-lib $(ODE_TEST_EXE)
+drawstuff-test: drawstuff-lib $(DRAWSTUFF_TEST_EXE)
+
+ifndef ODE_LIB_AR_RULE
+ODE_LIB_AR_RULE=$(AR)$@
+endif
+
+$(ODE_LIB): pre_ode_lib $(ODE_OBJECTS)
+ifeq ($(WINDOWS16),1)
+#   if we have a command-line-length limitation, then dynamically create
+#   a file containing all object filenames, and pass this file to the linker
+#   instead of directly specifying the object filenames on the command line.
+#   the very evaluation of the following variable causes creation of file
+#   odeobj.txt
+       $(SIDE_EFFECT_ODE_OBJLIST)
+       $(ODE_LIB_AR_RULE) @odeobj.txt
+else
+#   if we have no command-line-length limitation, directly specify all
+#   object files to be linked.
+       $(ODE_LIB_AR_RULE) $(ODE_OBJECTS)
+endif
+
+ifdef RANLIB
+       $(RANLIB) $@
+endif
+
+$(DRAWSTUFF_LIB): pre_drawstuff_lib $(DRAWSTUFF_OBJECTS)
+ifeq ($WINDOWS16),1)
+#   if we have a command-line-length limitation, then do the same as above.
+       $(SIDE_EFFECT_DRAWSTUFF_OBJLIST)
+       $(AR)$@ @dsobj.txt
+else
+#   if we have no command-line-length limitation, directly specify all object
+#   files to be linked.
+       $(AR)$@ $(DRAWSTUFF_OBJECTS)
+endif
+ifdef RANLIB
+       $(RANLIB) $@
+endif
+
+# rules to be executed before library linking starts: delete list file (if one is used)
+
+pre_ode_lib:
+ifeq ($WINDOWS16),1)
+       $(DEL_CMD) odeobj.txt
+endif
+
+pre_drawstuff_lib:
+ifeq ($WINDOWS16),1)
+       $(DEL_CMD) dsobj.txt
+endif
+
+clean:
+       -$(DEL_CMD) $(ODE_OBJECTS) $(ODE_TEST_EXE) $(ODE_LIB) $(DRAWSTUFF_OBJECTS) $(DRAWSTUFF_TEST_EXE) $(DRAWSTUFF_LIB) ode/test/*$(OBJ) drawstuff/dstest/*$(OBJ) $(CONFIGURATOR_EXE) $(CONFIG_H)
+
+%$(OBJ): %.c
+       $(CC) $(C_FLAGS) $(C_INC)$(INCPATH) $(DEFINES) $(C_OPT)1 $(C_OUT)$@ $<
+
+%$(OBJ): %.cpp
+       $(CC) $(C_FLAGS) $(C_INC)$(INCPATH) $(DEFINES) $(C_OPT)$(OPT) $(C_OUT)$@ $<
+
+%.exe: %$(OBJ)
+       $(CC) $(C_EXEOUT)$@ $< $(ODE_LIB) $(DRAWSTUFF_LIB) $(RESOURCE_FILE) $(LINK_OPENGL) $(LINK_MATH)
+
+
+# windows specific rules
+
+lib/resources.RES: drawstuff/src/resources.rc
+       $(RC_RULE)
+
+
+# configurator rules
+
+configure: $(CONFIG_H)
+
+$(CONFIG_H): $(CONFIGURATOR_EXE) $(USER_SETTINGS) $(PLATFORM_MAKEFILE)
+       $(THIS_DIR)$(CONFIGURATOR_EXE) $(CONFIG_H) "$(CC) $(DEFINES) $(C_EXEOUT)" "$(DEL_CMD)" $(THIS_DIR)
+
+$(CONFIGURATOR_EXE): $(CONFIGURATOR_SRC) $(USER_SETTINGS) $(PLATFORM_MAKEFILE)
+       $(CC) $(C_DEF)d$(PRECISION) $(DEFINES) $(C_EXEOUT)$@ $<
+
+
+# unix-gcc specific dependency making
+
+DEP_RULE=gcc -M $(C_INC)$(INCPATH) $(DEFINES)
+depend: $(ODE_SRC) $(ODE_PREGEN_SRC) $(DRAWSTUFF_SRC) $(ODE_TEST_SRC_CPP) $(ODE_TEST_SRC_C) $(DRAWSTUFF_TEST_SRC_CPP)
+       $(DEP_RULE) $(ODE_SRC) $(ODE_PREGEN_SRC) | tools/process_deps ode/src/ > Makefile.deps
+       $(DEP_RULE) $(DRAWSTUFF_SRC) | tools/process_deps drawstuff/src/ >> Makefile.deps
+       $(DEP_RULE) $(ODE_TEST_SRC_CPP) | tools/process_deps ode/test/ >> Makefile.deps
+       $(DEP_RULE) $(DRAWSTUFF_TEST_SRC_CPP) | tools/process_deps drawstuff/dstest/ >> Makefile.deps
+
+include Makefile.deps
diff --git a/extern/ode/dist/Makefile.deps b/extern/ode/dist/Makefile.deps
new file mode 100644 (file)
index 0000000..ad11f01
--- /dev/null
@@ -0,0 +1,456 @@
+ode/src/array.o: \
+  ode/src/array.cpp \
+  include/ode/config.h \
+  include/ode/memory.h \
+  include/ode/error.h \
+  ode/src/array.h
+ode/src/error.o: \
+  ode/src/error.cpp \
+  include/ode/config.h \
+  include/ode/error.h
+ode/src/memory.o: \
+  ode/src/memory.cpp \
+  include/ode/config.h \
+  include/ode/memory.h \
+  include/ode/error.h
+ode/src/obstack.o: \
+  ode/src/obstack.cpp \
+  include/ode/common.h \
+  include/ode/config.h \
+  include/ode/error.h \
+  include/ode/memory.h \
+  ode/src/obstack.h \
+  ode/src/objects.h \
+  include/ode/mass.h \
+  ode/src/array.h
+ode/src/odemath.o: \
+  ode/src/odemath.cpp \
+  include/ode/common.h \
+  include/ode/config.h \
+  include/ode/error.h \
+  include/ode/odemath.h
+ode/src/matrix.o: \
+  ode/src/matrix.cpp \
+  include/ode/common.h \
+  include/ode/config.h \
+  include/ode/error.h \
+  include/ode/matrix.h
+ode/src/misc.o: \
+  ode/src/misc.cpp \
+  include/ode/config.h \
+  include/ode/misc.h \
+  include/ode/common.h \
+  include/ode/error.h \
+  include/ode/matrix.h
+ode/src/rotation.o: \
+  ode/src/rotation.cpp \
+  include/ode/rotation.h \
+  include/ode/common.h \
+  include/ode/config.h \
+  include/ode/error.h
+ode/src/mass.o: \
+  ode/src/mass.cpp \
+  include/ode/config.h \
+  include/ode/mass.h \
+  include/ode/common.h \
+  include/ode/error.h \
+  include/ode/odemath.h \
+  include/ode/matrix.h
+ode/src/ode.o: \
+  ode/src/ode.cpp \
+  ode/src/objects.h \
+  include/ode/common.h \
+  include/ode/config.h \
+  include/ode/error.h \
+  include/ode/memory.h \
+  include/ode/mass.h \
+  ode/src/array.h \
+  include/ode/ode.h \
+  include/ode/contact.h \
+  include/ode/odemath.h \
+  include/ode/matrix.h \
+  include/ode/timer.h \
+  include/ode/rotation.h \
+  include/ode/space.h \
+  include/ode/geom.h \
+  include/ode/misc.h \
+  include/ode/objects.h \
+  include/ode/odecpp.h \
+  ode/src/joint.h \
+  ode/src/obstack.h \
+  ode/src/step.h
+ode/src/step.o: \
+  ode/src/step.cpp \
+  ode/src/objects.h \
+  include/ode/common.h \
+  include/ode/config.h \
+  include/ode/error.h \
+  include/ode/memory.h \
+  include/ode/mass.h \
+  ode/src/array.h \
+  ode/src/joint.h \
+  include/ode/contact.h \
+  ode/src/obstack.h \
+  include/ode/odemath.h \
+  include/ode/rotation.h \
+  include/ode/timer.h \
+  include/ode/matrix.h \
+  ode/src/lcp.h
+ode/src/lcp.o: \
+  ode/src/lcp.cpp \
+  include/ode/common.h \
+  include/ode/config.h \
+  include/ode/error.h \
+  ode/src/lcp.h \
+  include/ode/matrix.h \
+  include/ode/misc.h \
+  ode/src/mat.h \
+  include/ode/timer.h
+ode/src/joint.o: \
+  ode/src/joint.cpp \
+  include/ode/odemath.h \
+  include/ode/common.h \
+  include/ode/config.h \
+  include/ode/error.h \
+  include/ode/rotation.h \
+  include/ode/matrix.h \
+  ode/src/joint.h \
+  ode/src/objects.h \
+  include/ode/memory.h \
+  include/ode/mass.h \
+  ode/src/array.h \
+  include/ode/contact.h \
+  ode/src/obstack.h
+ode/src/space.o: \
+  ode/src/space.cpp \
+  include/ode/common.h \
+  include/ode/config.h \
+  include/ode/error.h \
+  include/ode/space.h \
+  include/ode/geom.h \
+  include/ode/contact.h \
+  include/ode/memory.h \
+  ode/src/objects.h \
+  include/ode/mass.h \
+  ode/src/array.h \
+  ode/src/geom_internal.h
+ode/src/geom.o: \
+  ode/src/geom.cpp \
+  include/ode/common.h \
+  include/ode/config.h \
+  include/ode/error.h \
+  include/ode/geom.h \
+  include/ode/space.h \
+  include/ode/contact.h \
+  include/ode/rotation.h \
+  include/ode/odemath.h \
+  include/ode/memory.h \
+  include/ode/misc.h \
+  include/ode/objects.h \
+  include/ode/mass.h \
+  include/ode/matrix.h \
+  ode/src/objects.h \
+  ode/src/array.h \
+  ode/src/geom_internal.h
+ode/src/timer.o: \
+  ode/src/timer.cpp \
+  include/ode/common.h \
+  include/ode/config.h \
+  include/ode/error.h \
+  include/ode/timer.h
+ode/src/mat.o: \
+  ode/src/mat.cpp \
+  include/ode/config.h \
+  include/ode/misc.h \
+  include/ode/common.h \
+  include/ode/error.h \
+  include/ode/matrix.h \
+  include/ode/memory.h \
+  ode/src/mat.h
+ode/src/testing.o: \
+  ode/src/testing.cpp \
+  include/ode/config.h \
+  include/ode/misc.h \
+  include/ode/common.h \
+  include/ode/error.h \
+  include/ode/memory.h \
+  ode/src/testing.h \
+  ode/src/array.h
+ode/src/fastldlt.o: \
+  ode/src/fastldlt.c \
+  include/ode/matrix.h \
+  include/ode/common.h \
+  include/ode/config.h \
+  include/ode/error.h
+ode/src/fastlsolve.o: \
+  ode/src/fastlsolve.c \
+  include/ode/matrix.h \
+  include/ode/common.h \
+  include/ode/config.h \
+  include/ode/error.h
+ode/src/fastltsolve.o: \
+  ode/src/fastltsolve.c \
+  include/ode/matrix.h \
+  include/ode/common.h \
+  include/ode/config.h \
+  include/ode/error.h
+ode/src/fastdot.o: \
+  ode/src/fastdot.c \
+  include/ode/matrix.h \
+  include/ode/common.h \
+  include/ode/config.h \
+  include/ode/error.h
+drawstuff/src/drawstuff.o: \
+  drawstuff/src/drawstuff.cpp \
+  include/ode/config.h \
+  include/drawstuff/drawstuff.h \
+  include/drawstuff/version.h \
+  drawstuff/src/internal.h
+drawstuff/src/x11.o: \
+  drawstuff/src/x11.cpp \
+  include/ode/config.h \
+  include/drawstuff/drawstuff.h \
+  include/drawstuff/version.h \
+  drawstuff/src/internal.h
+ode/test/test_ode.o: \
+  ode/test/test_ode.cpp \
+  include/ode/ode.h \
+  include/ode/config.h \
+  include/ode/contact.h \
+  include/ode/common.h \
+  include/ode/error.h \
+  include/ode/memory.h \
+  include/ode/odemath.h \
+  include/ode/matrix.h \
+  include/ode/timer.h \
+  include/ode/rotation.h \
+  include/ode/mass.h \
+  include/ode/space.h \
+  include/ode/geom.h \
+  include/ode/misc.h \
+  include/ode/objects.h \
+  include/ode/odecpp.h
+ode/test/test_chain2.o: \
+  ode/test/test_chain2.cpp \
+  include/ode/ode.h \
+  include/ode/config.h \
+  include/ode/contact.h \
+  include/ode/common.h \
+  include/ode/error.h \
+  include/ode/memory.h \
+  include/ode/odemath.h \
+  include/ode/matrix.h \
+  include/ode/timer.h \
+  include/ode/rotation.h \
+  include/ode/mass.h \
+  include/ode/space.h \
+  include/ode/geom.h \
+  include/ode/misc.h \
+  include/ode/objects.h \
+  include/ode/odecpp.h \
+  include/drawstuff/drawstuff.h \
+  include/drawstuff/version.h
+ode/test/test_hinge.o: \
+  ode/test/test_hinge.cpp \
+  include/ode/ode.h \
+  include/ode/config.h \
+  include/ode/contact.h \
+  include/ode/common.h \
+  include/ode/error.h \
+  include/ode/memory.h \
+  include/ode/odemath.h \
+  include/ode/matrix.h \
+  include/ode/timer.h \
+  include/ode/rotation.h \
+  include/ode/mass.h \
+  include/ode/space.h \
+  include/ode/geom.h \
+  include/ode/misc.h \
+  include/ode/objects.h \
+  include/ode/odecpp.h \
+  include/drawstuff/drawstuff.h \
+  include/drawstuff/version.h
+ode/test/test_slider.o: \
+  ode/test/test_slider.cpp \
+  include/ode/ode.h \
+  include/ode/config.h \
+  include/ode/contact.h \
+  include/ode/common.h \
+  include/ode/error.h \
+  include/ode/memory.h \
+  include/ode/odemath.h \
+  include/ode/matrix.h \
+  include/ode/timer.h \
+  include/ode/rotation.h \
+  include/ode/mass.h \
+  include/ode/space.h \
+  include/ode/geom.h \
+  include/ode/misc.h \
+  include/ode/objects.h \
+  include/ode/odecpp.h \
+  include/drawstuff/drawstuff.h \
+  include/drawstuff/version.h
+ode/test/test_collision.o: \
+  ode/test/test_collision.cpp \
+  include/ode/ode.h \
+  include/ode/config.h \
+  include/ode/contact.h \
+  include/ode/common.h \
+  include/ode/error.h \
+  include/ode/memory.h \
+  include/ode/odemath.h \
+  include/ode/matrix.h \
+  include/ode/timer.h \
+  include/ode/rotation.h \
+  include/ode/mass.h \
+  include/ode/space.h \
+  include/ode/geom.h \
+  include/ode/misc.h \
+  include/ode/objects.h \
+  include/ode/odecpp.h \
+  include/drawstuff/drawstuff.h \
+  include/drawstuff/version.h
+ode/test/test_boxstack.o: \
+  ode/test/test_boxstack.cpp \
+  include/ode/ode.h \
+  include/ode/config.h \
+  include/ode/contact.h \
+  include/ode/common.h \
+  include/ode/error.h \
+  include/ode/memory.h \
+  include/ode/odemath.h \
+  include/ode/matrix.h \
+  include/ode/timer.h \
+  include/ode/rotation.h \
+  include/ode/mass.h \
+  include/ode/space.h \
+  include/ode/geom.h \
+  include/ode/misc.h \
+  include/ode/objects.h \
+  include/ode/odecpp.h \
+  include/drawstuff/drawstuff.h \
+  include/drawstuff/version.h
+ode/test/test_buggy.o: \
+  ode/test/test_buggy.cpp \
+  include/ode/ode.h \
+  include/ode/config.h \
+  include/ode/contact.h \
+  include/ode/common.h \
+  include/ode/error.h \
+  include/ode/memory.h \
+  include/ode/odemath.h \
+  include/ode/matrix.h \
+  include/ode/timer.h \
+  include/ode/rotation.h \
+  include/ode/mass.h \
+  include/ode/space.h \
+  include/ode/geom.h \
+  include/ode/misc.h \
+  include/ode/objects.h \
+  include/ode/odecpp.h \
+  include/drawstuff/drawstuff.h \
+  include/drawstuff/version.h
+ode/test/test_joints.o: \
+  ode/test/test_joints.cpp \
+  include/ode/ode.h \
+  include/ode/config.h \
+  include/ode/contact.h \
+  include/ode/common.h \
+  include/ode/error.h \
+  include/ode/memory.h \
+  include/ode/odemath.h \
+  include/ode/matrix.h \
+  include/ode/timer.h \
+  include/ode/rotation.h \
+  include/ode/mass.h \
+  include/ode/space.h \
+  include/ode/geom.h \
+  include/ode/misc.h \
+  include/ode/objects.h \
+  include/ode/odecpp.h \
+  include/drawstuff/drawstuff.h \
+  include/drawstuff/version.h
+ode/test/test_space.o: \
+  ode/test/test_space.cpp \
+  include/ode/ode.h \
+  include/ode/config.h \
+  include/ode/contact.h \
+  include/ode/common.h \
+  include/ode/error.h \
+  include/ode/memory.h \
+  include/ode/odemath.h \
+  include/ode/matrix.h \
+  include/ode/timer.h \
+  include/ode/rotation.h \
+  include/ode/mass.h \
+  include/ode/space.h \
+  include/ode/geom.h \
+  include/ode/misc.h \
+  include/ode/objects.h \
+  include/ode/odecpp.h \
+  include/drawstuff/drawstuff.h \
+  include/drawstuff/version.h
+ode/test/test_I.o: \
+  ode/test/test_I.cpp \
+  include/ode/ode.h \
+  include/ode/config.h \
+  include/ode/contact.h \
+  include/ode/common.h \
+  include/ode/error.h \
+  include/ode/memory.h \
+  include/ode/odemath.h \
+  include/ode/matrix.h \
+  include/ode/timer.h \
+  include/ode/rotation.h \
+  include/ode/mass.h \
+  include/ode/space.h \
+  include/ode/geom.h \
+  include/ode/misc.h \
+  include/ode/objects.h \
+  include/ode/odecpp.h \
+  include/drawstuff/drawstuff.h \
+  include/drawstuff/version.h
+ode/test/test_step.o: \
+  ode/test/test_step.cpp \
+  include/ode/ode.h \
+  include/ode/config.h \
+  include/ode/contact.h \
+  include/ode/common.h \
+  include/ode/error.h \
+  include/ode/memory.h \
+  include/ode/odemath.h \
+  include/ode/matrix.h \
+  include/ode/timer.h \
+  include/ode/rotation.h \
+  include/ode/mass.h \
+  include/ode/space.h \
+  include/ode/geom.h \
+  include/ode/misc.h \
+  include/ode/objects.h \
+  include/ode/odecpp.h \
+  include/drawstuff/drawstuff.h \
+  include/drawstuff/version.h
+ode/test/test_friction.o: \
+  ode/test/test_friction.cpp \
+  include/ode/ode.h \
+  include/ode/config.h \
+  include/ode/contact.h \
+  include/ode/common.h \
+  include/ode/error.h \
+  include/ode/memory.h \
+  include/ode/odemath.h \
+  include/ode/matrix.h \
+  include/ode/timer.h \
+  include/ode/rotation.h \
+  include/ode/mass.h \
+  include/ode/space.h \
+  include/ode/geom.h \
+  include/ode/misc.h \
+  include/ode/objects.h \
+  include/ode/odecpp.h \
+  include/drawstuff/drawstuff.h \
+  include/drawstuff/version.h
+drawstuff/dstest/dstest.o: \
+  drawstuff/dstest/dstest.cpp \
+  include/drawstuff/drawstuff.h \
+  include/drawstuff/version.h
diff --git a/extern/ode/dist/README b/extern/ode/dist/README
new file mode 100644 (file)
index 0000000..6b151d1
--- /dev/null
@@ -0,0 +1,30 @@
+The Open Dynamics Engine (ODE), Copyright (C) 2001,2002 Russell L. Smith.
+-------------------------------------------------------------------------
+
+ODE is a free, industrial quality library for simulating articulated
+rigid body dynamics - for example ground vehicles, legged creatures,
+and moving objects in VR environments. It is fast, flexible, robust
+and platform independent, with advanced joints, contact with friction,
+and built-in collision detection.
+
+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.
+
+  * Installation instructions are in the INSTALL file
+
+  * The ODE web pages are at http://q12.org/ode/
+
+  * The ODE documentation is in the file ode/doc/ode.html, or you
+    can view it on the web at http://q12.org/ode/ode-docs.html
diff --git a/extern/ode/dist/README_BLENDER b/extern/ode/dist/README_BLENDER
new file mode 100644 (file)
index 0000000..64d9762
--- /dev/null
@@ -0,0 +1,18 @@
+Checked out from ODE cvs (http://q12.org) on or around
+Fri Oct 18 14:24:11 GMT 2002
+
+Note that ODE has its own build system. The source/ode/
+directory is traversed by Blender's source/Makefile. However
+source/ode/config/user-settings has to be set correctly
+depending on the target platform. This needs to be done in the
+source/Makefile which determines the proper platform, then copies
+the appropriate platform-specific user-settings.platform file to
+source/ode/config/user-settings. Currently source/ode/user-settings is
+for Linux.
+
+Don't change the source in this directory. This source code is
+maintained on the CVS server at http://q12.org and is provided here
+so that Blender developers can compile ODE without having to separately
+download and install it. This source code can and should periodically
+be synchronized (manually) with the source code at http://q12.org.
+
diff --git a/extern/ode/dist/config/README b/extern/ode/dist/config/README
new file mode 100644 (file)
index 0000000..0fa1806
--- /dev/null
@@ -0,0 +1,41 @@
+
+variable names used in the per-platform makefile configuration files:
+
+platform stuff
+--------------
+
+WINDOWS                        set to 1 if this is a microsoft windows based platform
+
+filesystem stuff and commands
+-----------------------------
+
+THIS_DIR               prefix to run a command from the current directory
+DEL_CMD                        the name of the delete command
+
+compiler stuff
+--------------
+
+CC                     the C/C++ compiler to use
+OBJ                    the object file extension
+C_FLAGS                        the standard set of compiler flags
+C_INC                  flag to add an include path
+C_OUT                  flag to specify the object file output
+C_EXEOUT               flag to specify the executable file output
+C_DEF                  flag to add a define
+C_OPT                  flag to set the optimization level
+OPT                    the optimization level to use
+
+library archiver
+----------------
+
+AR                     library archiver command
+RANLIB                 ranlib command, if necessary
+LIB_PREFIX             library file prefix
+LIB_SUFFIX             library file suffix
+LINK_OPENGL            link flags to link in windowing stuff and opengl
+LINK_MATH              link flags to link in the system math library
+
+windows specific stuff
+----------------------
+
+RC_RULE                        makefile rule to use for the resource compiler
diff --git a/extern/ode/dist/config/makefile.cygwin b/extern/ode/dist/config/makefile.cygwin
new file mode 100644 (file)
index 0000000..de23b71
--- /dev/null
@@ -0,0 +1,28 @@
+WINDOWS=1
+THIS_DIR=./
+DEL_CMD=rm -f
+CC=gcc
+OBJ=.o
+C_FLAGS=-c -Wall -fno-exceptions -fno-rtti -DWIN32 -DCYGWIN
+C_INC=-I
+C_OUT=-o 
+C_EXEOUT=-o 
+C_DEF=-D
+C_OPT=-O
+AR=ar rc 
+RANLIB=
+LIB_PREFIX=lib
+LIB_SUFFIX=.a
+LINK_OPENGL=-lComctl32 -lkernel32 -luser32 -lgdi32 -lOpenGL32 -lGlu32
+LINK_MATH=-lm
+RC_RULE=windres -I rc -O coff $< $@
+
+ifeq ($(BUILD),release)
+OPT=2
+C_FLAGS+=-fomit-frame-pointer -ffast-math
+endif
+
+ifeq ($(BUILD),debug)
+OPT=0
+C_FLAGS+=-g
+endif
diff --git a/extern/ode/dist/config/makefile.mingw b/extern/ode/dist/config/makefile.mingw
new file mode 100644 (file)
index 0000000..4b18fb6
--- /dev/null
@@ -0,0 +1,28 @@
+WINDOWS=1
+THIS_DIR=
+DEL_CMD=tools\rm
+CC=gcc
+OBJ=.o
+C_FLAGS=-c -Wall -fno-exceptions -fno-rtti -DWIN32
+C_INC=-I
+C_OUT=-o 
+C_EXEOUT=-o 
+C_DEF=-D
+C_OPT=-O
+AR=ar rc 
+RANLIB=
+LIB_PREFIX=lib
+LIB_SUFFIX=.a
+LINK_OPENGL=-lComctl32 -lkernel32 -luser32 -lgdi32 -lOpenGL32 -lGlu32
+LINK_MATH=-lm
+RC_RULE=windres -I rc -O coff $< $@
+
+ifeq ($(BUILD),release)
+OPT=2
+C_FLAGS+=-fomit-frame-pointer -ffast-math
+endif
+
+ifeq ($(BUILD),debug)
+OPT=0
+C_FLAGS+=-g
+endif
diff --git a/extern/ode/dist/config/makefile.msvc b/extern/ode/dist/config/makefile.msvc
new file mode 100644 (file)
index 0000000..9d4da0b
--- /dev/null
@@ -0,0 +1,27 @@
+WINDOWS=1
+THIS_DIR=
+DEL_CMD=tools\rm
+CC=cl /nologo /DWIN32 /DMSVC /DSHAREDLIBEXPORT= /DSHAREDLIBIMPORT=
+OBJ=.obj
+C_FLAGS=/c /GR- /GX- /W3 /GF
+C_INC=/I
+C_OUT=/Fo
+C_EXEOUT=/Fe
+C_DEF=/D
+C_OPT=/O
+AR=lib /nologo /OUT:
+RANLIB=
+LIB_PREFIX=
+LIB_SUFFIX=.lib
+LINK_OPENGL=Comctl32.lib kernel32.lib user32.lib gdi32.lib OpenGL32.lib Glu32.lib
+LINK_MATH=
+RC_RULE=rc /r /fo$@ $<
+
+ifeq ($(BUILD),release)
+OPT=2
+C_FLAGS+=/Oy
+endif
+
+ifeq ($(BUILD),debug)
+OPT=d
+endif
diff --git a/extern/ode/dist/config/makefile.msvc-dll b/extern/ode/dist/config/makefile.msvc-dll
new file mode 100644 (file)
index 0000000..fe49589
--- /dev/null
@@ -0,0 +1,29 @@
+WINDOWS=1
+THIS_DIR=
+DEL_CMD=tools\rm
+CC=cl /nologo /DWIN32 /DMSVC /DSHAREDLIBIMPORT=__declspec(dllimport) /DSHAREDLIBEXPORT=__declspec(dllexport)
+OBJ=.obj
+C_FLAGS=/c /GR- /GX- /W3 /GF
+C_INC=/I
+C_OUT=/Fo
+C_EXEOUT=/Fe
+C_DEF=/D
+C_OPT=/O
+AR=lib /nologo /OUT:
+RANLIB=
+LIB_PREFIX=
+LIB_SUFFIX=.lib
+LINK_OPENGL=Comctl32.lib kernel32.lib user32.lib gdi32.lib OpenGL32.lib Glu32.lib
+LINK_MATH=
+RC_RULE=rc /r /fo$@ $<
+
+ifeq ($(BUILD),release)
+OPT=2
+C_FLAGS+=/Oy
+endif
+
+ifeq ($(BUILD),debug)
+OPT=d
+endif
+
+ODE_LIB_AR_RULE=link /dll /nologo /SUBSYSTEM:WINDOWS /LIBPATH:"C:\Programme\Micros~2\VC98\Lib" /def:config/msvcdefs.def $(LINK_OPENGL) /OUT:$(patsubst %.lib,%.dll,$@)
diff --git a/extern/ode/dist/config/makefile.osx b/extern/ode/dist/config/makefile.osx
new file mode 100644 (file)
index 0000000..cb883e3
--- /dev/null
@@ -0,0 +1,26 @@
+THIS_DIR=./
+DEL_CMD=rm -f
+CC=cc
+OBJ=.o
+C_FLAGS=-c -Wall -fno-rtti -fno-exceptions -Wall
+C_INC=-I
+C_OUT=-o 
+C_EXEOUT=-o 
+C_DEF=-D
+C_OPT=-O
+AR=ar rc 
+RANLIB=
+LIB_PREFIX=lib
+LIB_SUFFIX=.a
+LINK_OPENGL=-L/usr/X11R6/lib -L/usr/X11/lib -L/usr/lib/X11R6 -L/usr/lib/X11 -lX11 -lGL -lGLU
+LINK_MATH=-lm
+
+ifeq ($(BUILD),release)
+OPT=2
+C_FLAGS+=-fomit-frame-pointer -ffast-math
+endif
+
+ifeq ($(BUILD),debug)
+OPT=0
+C_FLAGS+=-g
+endif
diff --git a/extern/ode/dist/config/makefile.unix-gcc b/extern/ode/dist/config/makefile.unix-gcc
new file mode 100644 (file)
index 0000000..b9d0763
--- /dev/null
@@ -0,0 +1,29 @@
+THIS_DIR=./
+DEL_CMD=rm -f
+CC=gcc
+OBJ=.o
+C_FLAGS=-c -Wall -fno-rtti -fno-exceptions -Wall
+C_INC=-I
+C_OUT=-o 
+C_EXEOUT=-o 
+C_DEF=-D
+C_OPT=-O
+AR=ar rc 
+RANLIB=
+LIB_PREFIX=lib
+LIB_SUFFIX=.a
+LINK_OPENGL=-L/usr/X11R6/lib -L/usr/X11/lib -L/usr/lib/X11R6 -L/usr/lib/X11 -lX11 -lGL -lGLU
+LINK_MATH=-lm
+
+ifeq ($(BUILD),release)
+OPT=2
+C_FLAGS+=-fomit-frame-pointer -ffast-math
+endif
+
+ifeq ($(BUILD),debug)
+OPT=0
+C_FLAGS+=-g
+endif
+
+# some other possible flags:
+#   -malign-double -mpentiumpro -march=pentiumpro
diff --git a/extern/ode/dist/config/makefile.unix-generic b/extern/ode/dist/config/makefile.unix-generic
new file mode 100644 (file)
index 0000000..f435e1a
--- /dev/null
@@ -0,0 +1,24 @@
+THIS_DIR=./
+DEL_CMD=rm -f
+CC=CC
+OBJ=.o
+C_FLAGS=-c
+C_INC=-I
+C_OUT=-o 
+C_EXEOUT=-o 
+C_DEF=-D
+C_OPT=-O
+AR=ar rc 
+RANLIB=
+LIB_PREFIX=lib
+LIB_SUFFIX=.a
+LINK_OPENGL=-L/usr/X11R6/lib -L/usr/X11/lib -L/usr/lib/X11R6 -L/usr/lib/X11 -lX11 -lGL -lGLU
+LINK_MATH=-lm
+
+ifeq ($(BUILD),release)
+OPT=2
+endif
+
+ifeq ($(BUILD),debug)
+OPT=0
+endif
diff --git a/extern/ode/dist/config/msvcdefs.def b/extern/ode/dist/config/msvcdefs.def
new file mode 100644 (file)
index 0000000..11258ab
--- /dev/null
@@ -0,0 +1,228 @@
+LIBRARY ODE
+EXPORTS
+dAreConnected
+dBodyAddForce
+dBodyAddForceAtPos
+dBodyAddForceAtRelPos
+dBodyAddRelForce
+dBodyAddRelForceAtPos
+dBodyAddRelForceAtRelPos
+dBodyAddRelTorque
+dBodyAddTorque
+dBodyCreate
+dBodyDestroy
+dBodyDisable
+dBodyEnable
+dBodyGetAngularVel
+dBodyGetData
+dBodyGetFiniteRotationAxis
+dBodyGetFiniteRotationMode
+dBodyGetForce
+dBodyGetGravityMode
+dBodyGetJoint
+dBodyGetLinearVel
+dBodyGetMass
+dBodyGetNumJoints
+dBodyGetPointVel
+dBodyGetPosRelPoint
+dBodyGetPosition
+dBodyGetQuaternion
+dBodyGetRelPointPos
+dBodyGetRelPointVel
+dBodyGetRotation
+dBodyGetTorque
+dBodyIsEnabled
+dBodySetAngularVel
+dBodySetData
+dBodySetFiniteRotationAxis
+dBodySetFiniteRotationMode
+dBodySetForce
+dBodySetGravityMode
+dBodySetLinearVel
+dBodySetMass
+dBodySetPosition
+dBodySetQuaternion
+dBodySetRotation
+dBodySetTorque
+dBodyVectorFromWorld
+dBodyVectorToWorld
+dBoxBox
+dBoxClass
+dBoxTouchesBox
+dCCylinderClass
+dClearUpperTriangle
+dCloseODE
+dClosestLineSegmentPoints
+dCollide
+dCreateBox
+dCreateCCylinder
+dCreateGeom
+dCreateGeomClass
+dCreateGeomGroup
+dCreateGeomTransform
+dCreatePlane
+dCreateSphere
+dError
+dFactorCholesky
+dFactorLDLT
+dGeomBoxGetLengths
+dGeomBoxSetLengths
+dGeomCCylinderGetParams
+dGeomCCylinderSetParams
+dGeomDestroy
+dGeomGetAABB
+dGeomGetBody
+dGeomGetClass
+dGeomGetClassData
+dGeomGetData
+dGeomGetPosition
+dGeomGetRotation
+dGeomGetSpaceAABB
+dGeomGroupAdd
+dGeomGroupGetGeom
+dGeomGroupGetNumGeoms
+dGeomGroupRemove
+dGeomPlaneGetParams
+dGeomPlaneSetParams
+dGeomSetBody
+dGeomSetData
+dGeomSetPosition
+dGeomSetRotation
+dGeomSphereGetRadius
+dGeomSphereSetRadius
+dGeomTransformClass
+dGeomTransformGetCleanup
+dGeomTransformGetGeom
+dGeomTransformSetCleanup
+dGeomTransformSetGeom
+dHashSpaceCreate
+dHashSpaceSetLevels
+dInfiniteAABB
+dInfinityValue
+dInvertPDMatrix
+dIsPositiveDefinite
+dJointAttach
+dJointCreateAMotor
+dJointCreateBall
+dJointCreateContact
+dJointCreateFixed
+dJointCreateHinge
+dJointCreateHinge2
+dJointCreateSlider
+dJointCreateUniversal
+dJointDestroy
+dJointGetAMotorAngle
+dJointGetAMotorAngleRate
+dJointGetAMotorAxis
+dJointGetAMotorAxisRel
+dJointGetAMotorMode
+dJointGetAMotorNumAxes
+dJointGetAMotorParam
+dJointGetBallAnchor
+dJointGetBody
+dJointGetData
+dJointGetHinge2Anchor
+dJointGetHinge2Angle1
+dJointGetHinge2Angle1Rate
+dJointGetHinge2Angle2Rate
+dJointGetHinge2Axis1
+dJointGetHinge2Axis2
+dJointGetHinge2Param
+dJointGetHingeAnchor
+dJointGetHingeAngle
+dJointGetHingeAngleRate
+dJointGetHingeAxis
+dJointGetHingeParam
+dJointGetSliderAxis
+dJointGetSliderParam
+dJointGetSliderPosition
+dJointGetSliderPositionRate
+dJointGetType
+dJointGetUniversalAnchor
+dJointGetUniversalAxis1
+dJointGetUniversalAxis2
+dJointGroupCreate
+dJointGroupDestroy
+dJointGroupEmpty
+dJointSetAMotorAngle
+dJointSetAMotorAxis
+dJointSetAMotorMode
+dJointSetAMotorNumAxes
+dJointSetAMotorParam
+dJointSetBallAnchor
+dJointSetData
+dJointSetFixed
+dJointSetHinge2Anchor
+dJointSetHinge2Axis1
+dJointSetHinge2Axis2
+dJointSetHinge2Param
+dJointSetHingeAnchor
+dJointSetHingeAxis
+dJointSetHingeParam
+dJointSetSliderAxis
+dJointSetSliderParam
+dJointSetUniversalAnchor
+dJointSetUniversalAxis1
+dJointSetUniversalAxis2
+dLDLTAddTL
+dLDLTRemove
+dMakeRandomMatrix
+dMakeRandomVector
+dMassAdd
+dMassAdjust
+dMassRotate
+dMassSetBox
+dMassSetCappedCylinder
+dMassSetParameters
+dMassSetSphere
+dMassSetZero
+dMassTranslate
+dMaxDifference
+dMultiply0
+dMultiply1
+dMultiply2
+dNormalize3
+dNormalize4
+dPlaneSpace
+dQFromAxisAndAngle
+dQMultiply0
+dQMultiply1
+dQMultiply2
+dQMultiply3
+dQSetIdentity
+dQtoR
+dRFrom2Axes
+dRFromAxisAndAngle
+dRFromEulerAngles
+dRSetIdentity
+dRandInt
+dRandReal
+dRandSetSeed
+dRemoveRowCol
+dRtoQ
+dSetMessageHandler
+dSetZero
+dSimpleSpaceCreate
+dSolveCholesky
+dSolveLDLT
+dSpaceAdd
+dSpaceCollide
+dSpaceDestroy
+dSpaceQuery
+dSpaceRemove
+dSphereClass
+dTestMatrixComparison
+dTestRand
+dTestSolveLCP
+dWorldCreate
+dWorldDestroy
+dWorldGetCFM
+dWorldGetERP
+dWorldGetGravity
+dWorldImpulseToForce
+dWorldSetCFM
+dWorldSetERP
+dWorldSetGravity
+dWorldStep
+dWorldStep 
+dWtoDQ
diff --git a/extern/ode/dist/config/user-settings b/extern/ode/dist/config/user-settings
new file mode 100644 (file)
index 0000000..d632eba
--- /dev/null
@@ -0,0 +1,31 @@
+# ODE user settings: the following variables must be set by the user
+
+# (1) the platform to use. this name should have a corresponding
+#     makefile.PLATFORM file. currently supported platforms are:
+#       msvc           microsoft visual C/C++
+#       msvc-dll       microsoft visual C/C++, create a DLL
+#       mingw          minimalist GNU for windows
+#       cygwin         cygnus GNU for windows
+#       unix-gcc       GNU gcc on unix
+#       unix-generic   generic unix compiler. you may need to edit the CC
+#                      variable in makefile.unix-generic
+#      osx             Mac OS-X, with the gnu compiler.
+
+PLATFORM=unix-gcc
+
+# (2) the floating point precision to use (either "SINGLE" or "DOUBLE")
+
+PRECISION=SINGLE
+#PRECISION=DOUBLE
+
+# (3) the library type to build (either "debug" if you are doing development,
+#     or "release" for the optimized library)
+
+#BUILD=debug
+BUILD=release
+
+# (4) if you are using an old version of MS-Windows that has command line
+#     length limitations then you will need to set this to "1". otherwise,
+#     leave it at "0".
+
+WINDOWS16=0
diff --git a/extern/ode/dist/config/user-settings.example b/extern/ode/dist/config/user-settings.example
new file mode 100644 (file)
index 0000000..0b0d480
--- /dev/null
@@ -0,0 +1,31 @@
+# ODE user settings: the following variables must be set by the user
+
+# (1) the platform to use. this name should have a corresponding
+#     makefile.PLATFORM file. currently supported platforms are:
+#       msvc           microsoft visual C/C++
+#       msvc-dll       microsoft visual C/C++, create a DLL
+#       mingw          minimalist GNU for windows
+#       cygwin         cygnus GNU for windows
+#       unix-gcc       GNU gcc on unix
+#       unix-generic   generic unix compiler. you may need to edit the CC
+#                      variable in makefile.unix-generic
+#      osx             Mac OS-X, with the gnu compiler.
+
+PLATFORM=unix-gcc
+
+# (2) the floating point precision to use (either "SINGLE" or "DOUBLE")
+
+#PRECISION=SINGLE
+PRECISION=DOUBLE
+
+# (3) the library type to build (either "debug" if you are doing development,
+#     or "release" for the optimized library)
+
+#BUILD=debug
+BUILD=release
+
+# (4) if you are using an old version of MS-Windows that has command line
+#     length limitations then you will need to set this to "1". otherwise,
+#     leave it at "0".
+
+WINDOWS16=0
diff --git a/extern/ode/dist/configurator.c b/extern/ode/dist/configurator.c
new file mode 100644 (file)
index 0000000..8129716
--- /dev/null
@@ -0,0 +1,437 @@
+/*************************************************************************
+ *                                                                       *
+ * 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 program discovers some system configuration stuff, prior to compiling
+ODE. the usage is:
+
+  configurator <config.h-file-to-generate> <compiler-command-line>
+       <delete-command-line> <THIS_DIR-variable>
+
+this program looks long, but it really has an extremely simple structure and
+should be very easy for anyone to modify. it should be very portable as it
+is written in straight ANSI C and only uses the following library functions:
+  * printf
+  * fopen (assumes 0 returned on failure)
+  * fclose
+  * fprintf
+  * system
+  * exit
+except where stated, we do not assume anything about the return codes from
+these functions.
+
+why didn't i just use GNU autoconf? :
+  * autoconf needs a bourne shell and a bunch of other tools that windows
+    users may not have.
+  * i like reinventing the wheel.
+
+*/
+
+#include <stdio.h>
+
+/****************************************************************************/
+/* project constants */
+
+#define SETUP_SHLIB_DEFS \
+  "#ifndef SHAREDLIBIMPORT\n" \
+  "#define SHAREDLIBIMPORT\n" \
+  "#endif\n" \
+  "#ifndef SHAREDLIBEXPORT\n" \
+  "#define SHAREDLIBEXPORT\n" \
+  "#endif\n"
+
+/* the config.h header */
+char *config_h_part1 =
+"/* per-machine configuration. this file is automatically generated. */\n"
+"\n"
+"#ifndef _ODE_CONFIG_H_\n"
+"#define _ODE_CONFIG_H_\n"
+"\n"
+"/* shared lib definitions */\n"
+SETUP_SHLIB_DEFS
+"\n"
+"/* standard system headers */\n";
+
+
+char *config_h_part2 =
+"\n"
+"#ifdef __cplusplus\n"
+"extern \"C\" {\n"
+"#endif\n"
+"\n";
+
+/* the config.h footer */
+char *config_h_footer =
+"#ifdef __cplusplus\n"
+"}\n"
+"#endif\n"
+"#endif\n";
+
+/****************************************************************************/
+/* implementations of some string functions. these are prefixed with 'x'
+ * to prevent any conflicts with built-in functions.
+ */
+
+#define strcpy xstrcpy
+void xstrcpy (char *dest, char *src)
+{
+  while (*src) *dest++ = *src++;
+  *dest = 0;
+}
+
+
+#define strcat xstrcat
+void xstrcat (char *dest, char *src)
+{
+  while (*dest) dest++;
+  while (*src) *dest++ = *src++;
+  *dest = 0;
+}
+
+/****************************************************************************/
+/* utility functions */
+
+/* print an error message and exit */
+
+void fatal_error (char *message)
+{
+  printf ("\n*** configurator failed: %s.\n\n"
+         "please fix your configuration and try again.\n"
+         "if you have to fix the configurator program or the makefiles, "
+         "please email\n"
+         "your changes to the ODE mailing list (ode@q12.org).\n\n", message);
+  exit (0);
+}
+
+
+/* open a file, generate an error if it can't be done */
+
+FILE * xfopen (char *filename, char *mode)
+{
+  FILE *f;
+  f = fopen (filename,mode);
+  if (!f) fatal_error ("can not open a file");
+  return f;
+}
+
+
+/* return 1 if the file exists or 0 if not */
+
+int file_exists (char *filename)
+{
+  FILE *f;
+  f = fopen (filename,"rb");
+  if (f) fclose (f);
+  return (f != 0);
+}
+
+
+/* write a string to a new file */
+
+void write_to_file (char *filename, char *s)
+{
+  FILE *f = xfopen (filename,"wt");
+  fprintf (f,"%s",s);
+  fclose (f);
+}
+
+
+/* write a comment to a header file */
+
+void write_header_comment (FILE *file, char *description)
+{
+  fprintf (file,"/* %s */\n",description);
+  printf ("%s ...\n",description);
+}
+
+
+/* delete a file */
+
+char *delete_cmd_line = 0;
+void delete_file (char *filename)
+{
+  char cmd[1000];
+  strcpy (cmd,delete_cmd_line);
+  strcat (cmd," ");
+  strcat (cmd,filename);
+  printf ("%s\n",cmd);
+  system (cmd);
+}
+
+
+/* run a compile command */
+
+char *compile_cmd_line = 0;
+void compile (char *output, char *input)
+{
+  char cmd[1000];
+  strcpy (cmd,compile_cmd_line);
+  strcat (cmd,output);
+  strcat (cmd," ");
+  strcat (cmd,input);
+  printf ("%s\n",cmd);
+  system (cmd);
+}
+
+
+/* run a program we've just compiled */
+
+char *run_prefix = "";
+void run (char *filename)
+{
+  char cmd[1000];
+  strcpy (cmd,run_prefix);
+  strcat (cmd,filename);
+  printf ("%s\n",cmd);
+  system (cmd);
+}
+
+/****************************************************************************/
+/* system tests */
+
+void check_if_this_is_a_pentium (FILE *file)
+{
+  write_header_comment (file,"is this a pentium on a gcc-based platform?");
+  write_to_file ("ctest.c",
+                "int main() {\n"
+                "  asm (\"mov $0,%%eax\\n cpuid\\n\" : : : \"%eax\");\n"
+                "  return 0;\n"
+                "}\n");
+  delete_file ("ctest.exe");
+  compile ("ctest.exe","ctest.c");
+  if (file_exists ("ctest.exe")) {
+    fprintf (file,"#define PENTIUM 1\n\n");
+  }
+  else {
+    fprintf (file,"/* #define PENTIUM 1 -- not a pentium */\n\n");
+  }
+
+  delete_file ("ctest.c");
+  delete_file ("ctest.exe");
+}
+
+/****************************************************************************/
+/* tests: standard headers */
+
+void get_all_standard_headers (FILE *file)
+{
+  int i;
+  FILE *f;
+  char *header[7] = {"stdio.h", "stdlib.h", "math.h", "string.h",
+                    "stdarg.h", "malloc.h", "alloca.h"};
+
+  for (i=0; i < sizeof(header)/sizeof(char*); i++) {
+    FILE *f = xfopen ("ctest.c","wt");
+    fprintf (f,"#include <%s>\nint main() { return 0; }\n",header[i]);
+    fclose (f);
+    delete_file ("ctest.exe");
+    compile ("ctest.exe","ctest.c");
+    if (file_exists ("ctest.exe")) {
+      fprintf (file,"#include <%s>\n",header[i]);
+    }
+  }
+
+  delete_file ("ctest.c");
+  delete_file ("ctest.exe");
+}
+
+/****************************************************************************/
+/* tests: typedefs and constants for ODE */
+
+void get_ODE_integer_typedefs (FILE *file)
+{
+  write_header_comment (file,"integer types (we assume int >= 32 bits)");
+  if (sizeof(char) != 1) fatal_error ("expecting sizeof(char) == 1");
+  if (sizeof(int) < 4) fatal_error ("expecting sizeof(int) >= 4");
+  fprintf (file,"typedef char int8;\ntypedef unsigned char uint8;\n");
+  if (sizeof(short) == 4) {
+    fprintf (file,"typedef short int32;\ntypedef unsigned short uint32;\n");
+  }
+  else if (sizeof(int) == 4) {
+    fprintf (file,"typedef int int32;\ntypedef unsigned int uint32;\n");
+  }
+  else {
+    fatal_error ("can not find 4 byte integer type");
+  }
+  fprintf (file,"\n"
+          "/* an integer type that we can safely cast a pointer to and\n"
+          " * from without loss of bits.\n"
+          " */\n");
+  if (sizeof(short) == sizeof(void*)) {
+    fprintf (file,"typedef unsigned short intP;\n");
+  }
+  else if (sizeof(int) == sizeof(void*)) {
+    fprintf (file,"typedef unsigned int intP;\n");
+  }
+  else if (sizeof(long int) == sizeof(void*)) {
+    fprintf (file,"typedef unsigned long int intP;\n");
+  }
+  fprintf (file,"\n");
+}
+
+
+void get_ODE_float_stuff (FILE *file)
+{
+  char *suffix,*type;
+  int i;
+  FILE *f;
+
+#define SHARED_LIB_SPEC_DECISION \
+    "#if defined SHARED_CONFIG_H_INCLUDED_FROM_DEFINING_FILE\n" \
+    "  #define GLOBAL_SHAREDLIB_SPEC SHAREDLIBEXPORT\n" \
+    "#else \n" \
+    "  #define GLOBAL_SHAREDLIB_SPEC SHAREDLIBIMPORT\n" \
+    "#endif\n"
+
+#define UNDEF_SHAREDLIB_SPEC "\n#undef GLOBAL_SHAREDLIB_SPEC\n"
+
+#ifdef dSINGLE
+
+#define INFBYTES SHARED_LIB_SPEC_DECISION "union dInfBytes { unsigned char c[4]; float f; };\nextern GLOBAL_SHAREDLIB_SPEC union dInfBytes dInfinityValue;\n#define dInfinity (dInfinityValue.f)"
+
+  char *inc[6] = {"#include <math.h>",
+                  "#include <math.h>",
+                  "",
+                  "",
+                  "",
+                  ""};
+  char *decl[6] = {
+    "SHAREDLIBEXPORT double dInfinityValue = HUGE_VALF;",
+    "SHAREDLIBEXPORT double dInfinityValue = HUGE_VAL;",
+    "SHAREDLIBEXPORT union dInfBytes dInfinityValue = {{0x7f,0x80,0,0}};",
+    "SHAREDLIBEXPORT union dInfBytes dInfinityValue = {{0,0,0x80,0x7f}};",
+    "SHAREDLIBEXPORT double dInfinityValue = 1.0f/0.0f;",
+    "SHAREDLIBEXPORT double dInfinityValue = 1e20f;"};
+  char *inf[6] = {
+    SHARED_LIB_SPEC_DECISION "extern GLOBAL_SHAREDLIB_SPEC double dInfinityValue;\n#define dInfinity dInfinityValue" UNDEF_SHAREDLIB_SPEC,
+    SHARED_LIB_SPEC_DECISION "extern GLOBAL_SHAREDLIB_SPEC double dInfinityValue;\n#define dInfinity dInfinityValue" UNDEF_SHAREDLIB_SPEC,
+    INFBYTES UNDEF_SHAREDLIB_SPEC,
+    INFBYTES UNDEF_SHAREDLIB_SPEC,
+    SHARED_LIB_SPEC_DECISION "extern GLOBAL_SHAREDLIB_SPEC double dInfinityValue;\n#define dInfinity dInfinityValue" UNDEF_SHAREDLIB_SPEC,
+    SHARED_LIB_SPEC_DECISION "extern GLOBAL_SHAREDLIB_SPEC double dInfinityValue;\n#define dInfinity dInfinityValue" UNDEF_SHAREDLIB_SPEC};
+
+#else /* not dSINGLE, must be dDOUBLE */
+
+#define INFBYTES SHARED_LIB_SPEC_DECISION "union dInfBytes { unsigned char c[8]; double d; };\nextern GLOBAL_SHAREDLIB_SPEC union dInfBytes dInfinityValue;\n#define dInfinity (dInfinityValue.d)"
+
+  char *inc[5] = {
+    "#include <math.h>",
+    "",
+    "",
+    "",
+    ""};
+  char *decl[5] = {
+    "SHAREDLIBEXPORT double dInfinityValue = HUGE_VAL;",
+    "SHAREDLIBEXPORT union dInfBytes dInfinityValue = {{0x7f,0xf0,0,0,0,0,0,0}};",
+    "SHAREDLIBEXPORT union dInfBytes dInfinityValue = {{0,0,0,0,0,0,0xf0,0x7f}};",
+    "SHAREDLIBEXPORT double dInfinityValue = 1.0/0.0;",
+    "SHAREDLIBEXPORT double dInfinityValue = 1e20;"};
+  char *inf[5] = {
+    SHARED_LIB_SPEC_DECISION "extern GLOBAL_SHAREDLIB_SPEC double dInfinityValue;\n#define dInfinity dInfinityValue" UNDEF_SHAREDLIB_SPEC,
+    INFBYTES UNDEF_SHAREDLIB_SPEC,
+    INFBYTES UNDEF_SHAREDLIB_SPEC,
+    SHARED_LIB_SPEC_DECISION "extern GLOBAL_SHAREDLIB_SPEC double dInfinityValue;\n#define dInfinity dInfinityValue" UNDEF_SHAREDLIB_SPEC,
+    SHARED_LIB_SPEC_DECISION "extern GLOBAL_SHAREDLIB_SPEC double dInfinityValue;\n#define dInfinity dInfinityValue" UNDEF_SHAREDLIB_SPEC};
+#endif
+
+  write_header_comment (file,"select the base floating point type");
+#ifdef dSINGLE
+  fprintf (file,"#define dSINGLE 1\n\n");
+  type = "float";
+  suffix = "f";
+#else
+  fprintf (file,"#define dDOUBLE 1\n\n");
+  type = "double";
+  suffix = "";
+#endif
+
+  /* infinity */
+  write_header_comment (file,"the floating point infinity");
+
+  /* try the different infinity constants until one works */
+  for (i=0; i < sizeof(inf)/sizeof(char*); i++) {
+    f = xfopen ("ctest.c","wt");
+    fprintf (f,
+            "#include <stdio.h>\n"
+            "#define SHARED_CONFIG_H_INCLUDED_FROM_DEFINING_FILE 1\n"
+            SETUP_SHLIB_DEFS
+            "%s\n"
+            "%s\n"
+            "%s\n"
+            "int main() {\n"
+            "  if (dInfinity > 1e10%s && -dInfinity < -1e10%s &&\n"
+            "      -dInfinity < dInfinity) {\n"
+            "    FILE *f = fopen (\"data\",\"wt\");\n"
+            "    fprintf (f,\"foo\\n\");\n"
+            "    fclose (f);\n"
+            "  }\n"
+            "  return 0;\n"
+            "}\n"
+            ,inc[i],inf[i],decl[i],suffix,suffix);
+    fclose (f);
+    delete_file ("data");
+    compile ("ctest.exe","ctest.c");
+    run ("ctest.exe");
+    if (file_exists ("data")) {
+      fprintf (file,"#define DINFINITY_DECL %s\n",decl[i]);
+      fprintf (file,"%s\n\n",inf[i]);
+      delete_file ("ctest.c");
+      delete_file ("ctest.exe");
+      delete_file ("data");
+      return;
+    }
+  }
+
+  fatal_error ("can't determine dInfinity constant");
+}
+
+/****************************************************************************/
+
+int main (int argc, char **argv)
+{
+  FILE *file;
+
+  if (argc < 4 || argc > 5)
+    fatal_error ("configurator expects 3 or 4 arguments");
+  compile_cmd_line = argv[2];
+  delete_cmd_line = argv[3];
+  if (argc >= 5) run_prefix = argv[4];
+
+  /* check some defines we should have been compiled with */
+#if !defined(dSINGLE) && !defined(dDOUBLE)
+  fatal_error ("you must set PRECISION to either SINGLE or DOUBLE");
+#endif
+
+  file = xfopen (argv[1],"wt");
+  fprintf (file,config_h_part1);
+  get_all_standard_headers (file);
+  fprintf (file,config_h_part2);
+  check_if_this_is_a_pentium (file);
+  get_ODE_integer_typedefs (file);
+  get_ODE_float_stuff (file);
+  fprintf (file,config_h_footer);
+  fclose (file);
+
+  printf ("\n*** configurator succeeded ***\n\n");
+  return 0;
+}
diff --git a/extern/ode/dist/include/ode/README b/extern/ode/dist/include/ode/README
new file mode 100644 (file)
index 0000000..aaedfcc
--- /dev/null
@@ -0,0 +1,18 @@
+
+this is the public C interface to the ODE library.
+
+all these files should be includable from C, i.e. they should not use any
+C++ features. everything should be protected with
+
+       #ifdef __cplusplus
+       extern "C" {
+       #endif
+
+       ...
+
+       #ifdef __cplusplus
+       }
+       #endif
+
+the only exception is the odecpp.h file, which defines a C++ wrapper for
+the C interface. remember to keep this in sync!
diff --git a/extern/ode/dist/include/ode/common.h b/extern/ode/dist/include/ode/common.h
new file mode 100644 (file)
index 0000000..705d222
--- /dev/null
@@ -0,0 +1,306 @@
+/*************************************************************************
+ *                                                                       *
+ * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith.       *
+ * All rights reserved.  Email: russ@q12.org   Web: www.q12.org          *
+ *                                                                       *
+ * This library is free software; you can redistribute it and/or         *
+ * modify it under the terms of EITHER:                                  *
+ *   (1) The GNU Lesser General Public License as published by the Free  *
+ *       Software Foundation; either version 2.1 of the License, or (at  *
+ *       your option) any later version. The text of the GNU Lesser      *
+ *       General Public License is included with this library in the     *
+ *       file LICENSE.TXT.                                               *
+ *   (2) The BSD-style license that is included with this library in     *
+ *       the file LICENSE-BSD.TXT.                                       *
+ *                                                                       *
+ * This library is distributed in the hope that it will be useful,       *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files    *
+ * LICENSE.TXT and LICENSE-BSD.TXT for more details.                     *
+ *                                                                       *
+ *************************************************************************/
+
+#ifndef _ODE_COMMON_H_
+#define _ODE_COMMON_H_
+
+#include <ode/config.h>
+#include <ode/error.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/* configuration stuff */
+
+/* the efficient alignment. most platforms align data structures to some
+ * number of bytes, but this is not always the most efficient alignment.
+ * for example, many x86 compilers align to 4 bytes, but on a pentium it
+ * is important to align doubles to 8 byte boundaries (for speed), and
+ * the 4 floats in a SIMD register to 16 byte boundaries. many other
+ * platforms have similar behavior. setting a larger alignment can waste
+ * a (very) small amount of memory. NOTE: this number must be a power of
+ * two. this is set to 16 by default.
+ */
+#define EFFICIENT_ALIGNMENT 16
+
+
+/* constants */
+
+/* pi and 1/sqrt(2) are defined here if necessary because they don't get
+ * defined in <math.h> on some platforms (like MS-Windows)
+ */
+
+#ifndef M_PI
+#define M_PI REAL(3.1415926535897932384626433832795029)
+#endif
+#ifndef M_SQRT1_2
+#define M_SQRT1_2 REAL(0.7071067811865475244008443621048490)
+#endif
+
+
+/* debugging:
+ *   IASSERT  is an internal assertion, i.e. a consistency check. if it fails
+ *            we want to know where.
+ *   UASSERT  is a user assertion, i.e. if it fails a nice error message
+ *            should be printed for the user.
+ *   AASSERT  is an arguments assertion, i.e. if it fails "bad argument(s)"
+ *            is printed.
+ *   DEBUGMSG just prints out a message
+ */
+
+#ifndef dNODEBUG
+#ifdef __GNUC__
+#define dIASSERT(a) if (!(a)) dDebug (d_ERR_IASSERT, \
+  "assertion \"" #a "\" failed in %s() [%s]",__FUNCTION__,__FILE__);
+#define dUASSERT(a,msg) if (!(a)) dDebug (d_ERR_UASSERT, \
+  msg " in %s()", __FUNCTION__);
+#define dDEBUGMSG(msg) dMessage (d_ERR_UASSERT, \
+  msg " in %s()", __FUNCTION__);
+#else
+#define dIASSERT(a) if (!(a)) dDebug (d_ERR_IASSERT, \
+  "assertion \"" #a "\" failed in %s:%d",__FILE__,__LINE__);
+#define dUASSERT(a,msg) if (!(a)) dDebug (d_ERR_UASSERT, \
+  msg " (%s:%d)", __FILE__,__LINE__);
+#define dDEBUGMSG(msg) dMessage (d_ERR_UASSERT, \
+  msg " (%s:%d)", __FILE__,__LINE__);
+#endif
+#else
+#define dIASSERT(a) ;
+#define dUASSERT(a,msg) ;
+#define dDEBUGMSG(msg) ;
+#endif
+#define dAASSERT(a) dUASSERT(a,"Bad argument(s)")
+
+/* floating point data type, vector, matrix and quaternion types */
+
+#if defined(dSINGLE)
+typedef float dReal;
+#elif defined(dDOUBLE)
+typedef double dReal;
+#else
+#error You must #define dSINGLE or dDOUBLE
+#endif
+
+
+/* round an integer up to a multiple of 4, except that 0 and 1 are unmodified
+ * (used to compute matrix leading dimensions)
+ */
+#define dPAD(a) (((a) > 1) ? ((((a)-1)|3)+1) : (a))
+
+/* these types are mainly just used in headers */
+typedef dReal dVector3[4];
+typedef dReal dVector4[4];
+typedef dReal dMatrix3[4*3];
+typedef dReal dMatrix4[4*4];
+typedef dReal dMatrix6[8*6];
+typedef dReal dQuaternion[4];
+
+
+/* precision dependent scalar math functions */
+
+#if defined(dSINGLE)
+
+#define REAL(x) (x ## f)                       /* form a constant */
+#define dRecip(x) ((float)(1.0f/(x)))          /* reciprocal */
+#define dSqrt(x) ((float)sqrt(x))              /* square root */
+#define dRecipSqrt(x) ((float)(1.0f/sqrt(x)))  /* reciprocal square root */
+#define dSin(x) ((float)sin(x))                        /* sine */
+#define dCos(x) ((float)cos(x))                        /* cosine */
+#define dFabs(x) ((float)fabs(x))              /* absolute value */
+#define dAtan2(y,x) ((float)atan2((y),(x)))    /* arc tangent with 2 args */
+
+#elif defined(dDOUBLE)
+
+#define REAL(x) (x)
+#define dRecip(x) (1.0/(x))
+#define dSqrt(x) sqrt(x)
+#define dRecipSqrt(x) (1.0/sqrt(x))
+#define dSin(x) sin(x)
+#define dCos(x) cos(x)
+#define dFabs(x) fabs(x)
+#define dAtan2(y,x) atan2((y),(x))
+
+#else
+#error You must #define dSINGLE or dDOUBLE
+#endif
+
+
+/* utility */
+
+
+/* round something up to be a multiple of the EFFICIENT_ALIGNMENT */
+
+#define dEFFICIENT_SIZE(x) ((((x)-1)|(EFFICIENT_ALIGNMENT-1))+1)
+
+
+/* alloca aligned to the EFFICIENT_ALIGNMENT. note that this can waste
+ * up to 15 bytes per allocation, depending on what alloca() returns.
+ */
+
+#define dALLOCA16(n) \
+  ((char*)dEFFICIENT_SIZE(((int)(alloca((n)+(EFFICIENT_ALIGNMENT-1))))))
+
+
+/* internal object types (all prefixed with `dx') */
+
+struct dxWorld;                /* dynamics world */
+struct dxSpace;                /* collision space */
+struct dxBody;         /* rigid body (dynamics object) */
+struct dxGeom;         /* geometry (collision object) */
+struct dxJoint;
+struct dxJointNode;
+struct dxJointGroup;
+
+typedef struct dxWorld *dWorldID;
+typedef struct dxSpace *dSpaceID;
+typedef struct dxBody *dBodyID;
+typedef struct dxGeom *dGeomID;
+typedef struct dxJoint *dJointID;
+typedef struct dxJointGroup *dJointGroupID;
+
+
+/* error numbers */
+
+enum {
+  d_ERR_UNKNOWN = 0,           /* unknown error */
+  d_ERR_IASSERT,               /* internal assertion failed */
+  d_ERR_UASSERT,               /* user assertion failed */
+  d_ERR_LCP                    /* user assertion failed */
+};
+
+
+/* joint type numbers */
+
+enum {
+  dJointTypeNone = 0,          /* or "unknown" */
+  dJointTypeBall,
+  dJointTypeHinge,
+  dJointTypeSlider,
+  dJointTypeContact,
+  dJointTypeUniversal,
+  dJointTypeHinge2,
+  dJointTypeFixed,
+  dJointTypeNull,
+  dJointTypeAMotor
+};
+
+
+/* an alternative way of setting joint parameters, using joint parameter
+ * structures and member constants. we don't actually do this yet.
+ */
+
+/*
+typedef struct dLimot {
+  int mode;
+  dReal lostop, histop;
+  dReal vel, fmax;
+  dReal fudge_factor;
+  dReal bounce, soft;
+  dReal suspension_erp, suspension_cfm;
+} dLimot;
+
+enum {
+  dLimotLoStop         = 0x0001,
+  dLimotHiStop         = 0x0002,
+  dLimotVel            = 0x0004,
+  dLimotFMax           = 0x0008,
+  dLimotFudgeFactor    = 0x0010,
+  dLimotBounce         = 0x0020,
+  dLimotSoft           = 0x0040
+};
+*/
+
+
+/* standard joint parameter names. why are these here? - because we don't want
+ * to include all the joint function definitions in joint.cpp. hmmmm.
+ * MSVC complains if we call D_ALL_PARAM_NAMES_X with a blank second argument,
+ * which is why we have the D_ALL_PARAM_NAMES macro as well. please copy and
+ * paste between these two.
+ */
+
+#define D_ALL_PARAM_NAMES(start) \
+  /* parameters for limits and motors */ \
+  dParamLoStop = start, \
+  dParamHiStop, \
+  dParamVel, \
+  dParamFMax, \
+  dParamFudgeFactor, \
+  dParamBounce, \
+  dParamCFM, \
+  dParamStopERP, \
+  dParamStopCFM, \
+  /* parameters for suspension */ \
+  dParamSuspensionERP, \
+  dParamSuspensionCFM,
+
+#define D_ALL_PARAM_NAMES_X(start,x) \
+  /* parameters for limits and motors */ \
+  dParamLoStop ## x = start, \
+  dParamHiStop ## x, \
+  dParamVel ## x, \
+  dParamFMax ## x, \
+  dParamFudgeFactor ## x, \
+  dParamBounce ## x, \
+  dParamCFM ## x, \
+  dParamStopERP ## x, \
+  dParamStopCFM ## x, \
+  /* parameters for suspension */ \
+  dParamSuspensionERP ## x, \
+  dParamSuspensionCFM ## x,
+
+enum {
+  D_ALL_PARAM_NAMES(0)
+  D_ALL_PARAM_NAMES_X(0x100,2)
+  D_ALL_PARAM_NAMES_X(0x200,3)
+
+  /* add a multiple of this constant to the basic parameter numbers to get
+   * the parameters for the second, third etc axes.
+   */
+  dParamGroup=0x100
+};
+
+
+/* angular motor mode numbers */
+
+enum{
+  dAMotorUser = 0,
+  dAMotorEuler = 1
+};
+
+
+/* joint force feedback information */
+
+typedef struct dJointFeedback {
+  dVector3 f1;         // force applied to body 1
+  dVector3 t1;         // torque applied to body 1
+  dVector3 f2;         // force applied to body 2
+  dVector3 t2;         // torque applied to body 2
+} dJointFeedback;
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/extern/ode/dist/include/ode/contact.h b/extern/ode/dist/include/ode/contact.h
new file mode 100644 (file)
index 0000000..926d77f
--- /dev/null
@@ -0,0 +1,90 @@
+/*************************************************************************
+ *                                                                       *
+ * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith.       *
+ * All rights reserved.  Email: russ@q12.org   Web: www.q12.org          *
+ *                                                                       *
+ * This library is free software; you can redistribute it and/or         *
+ * modify it under the terms of EITHER:                                  *
+ *   (1) The GNU Lesser General Public License as published by the Free  *
+ *       Software Foundation; either version 2.1 of the License, or (at  *
+ *       your option) any later version. The text of the GNU Lesser      *
+ *       General Public License is included with this library in the     *
+ *       file LICENSE.TXT.                                               *
+ *   (2) The BSD-style license that is included with this library in     *
+ *       the file LICENSE-BSD.TXT.                                       *
+ *                                                                       *
+ * This library is distributed in the hope that it will be useful,       *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files    *
+ * LICENSE.TXT and LICENSE-BSD.TXT for more details.                     *
+ *                                                                       *
+ *************************************************************************/
+
+#ifndef _ODE_CONTACT_H_
+#define _ODE_CONTACT_H_
+
+#include <ode/common.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+enum {
+  dContactMu2          = 0x001,
+  dContactFDir1                = 0x002,
+  dContactBounce       = 0x004,
+  dContactSoftERP      = 0x008,
+  dContactSoftCFM      = 0x010,
+  dContactMotion1      = 0x020,
+  dContactMotion2      = 0x040,
+  dContactSlip1                = 0x080,
+  dContactSlip2                = 0x100,
+
+  dContactApprox0      = 0x0000,
+  dContactApprox1_1    = 0x1000,
+  dContactApprox1_2    = 0x2000,
+  dContactApprox1      = 0x3000
+};
+
+
+typedef struct dSurfaceParameters {
+  /* must always be defined */
+  int mode;
+  dReal mu;
+
+  /* only defined if the corresponding flag is set in mode */
+  dReal mu2;
+  dReal bounce;
+  dReal bounce_vel;
+  dReal soft_erp;
+  dReal soft_cfm;
+  dReal motion1,motion2;
+  dReal slip1,slip2;
+} dSurfaceParameters;
+
+
+/* contact info set by collision functions */
+
+typedef struct dContactGeom {
+  dVector3 pos;
+  dVector3 normal;
+  dReal depth;
+  dGeomID g1,g2;
+} dContactGeom;
+
+
+/* contact info used by contact joint */
+
+typedef struct dContact {
+  dSurfaceParameters surface;
+  dContactGeom geom;
+  dVector3 fdir1;
+} dContact;
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/extern/ode/dist/include/ode/error.h b/extern/ode/dist/include/ode/error.h
new file mode 100644 (file)
index 0000000..700bf44
--- /dev/null
@@ -0,0 +1,63 @@
+/*************************************************************************
+ *                                                                       *
+ * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith.       *
+ * All rights reserved.  Email: russ@q12.org   Web: www.q12.org          *
+ *                                                                       *
+ * This library is free software; you can redistribute it and/or         *
+ * modify it under the terms of EITHER:                                  *
+ *   (1) The GNU Lesser General Public License as published by the Free  *
+ *       Software Foundation; either version 2.1 of the License, or (at  *
+ *       your option) any later version. The text of the GNU Lesser      *
+ *       General Public License is included with this library in the     *
+ *       file LICENSE.TXT.                                               *
+ *   (2) The BSD-style license that is included with this library in     *
+ *       the file LICENSE-BSD.TXT.                                       *
+ *                                                                       *
+ * This library is distributed in the hope that it will be useful,       *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files    *
+ * LICENSE.TXT and LICENSE-BSD.TXT for more details.                     *
+ *                                                                       *
+ *************************************************************************/
+
+/* this comes from the `reuse' library. copy any changes back to the source */
+
+#ifndef _ODE_ERROR_H_
+#define _ODE_ERROR_H_
+
+#include <ode/config.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* all user defined error functions have this type. error and debug functions
+ * should not return.
+ */
+typedef void dMessageFunction (int errnum, const char *msg, va_list ap);
+
+/* set a new error, debug or warning handler. if fn is 0, the default handlers
+ * are used.
+ */
+void dSetErrorHandler (dMessageFunction *fn);
+void dSetDebugHandler (dMessageFunction *fn);
+void dSetMessageHandler (dMessageFunction *fn);
+
+/* return the current error, debug or warning handler. if the return value is
+ * 0, the default handlers are in place.
+ */
+dMessageFunction *dGetErrorHandler();
+dMessageFunction *dGetDebugHandler();
+dMessageFunction *dGetMessageHandler();
+
+/* generate a fatal error, debug trap or a message. */
+void dError (int num, const char *msg, ...);
+void dDebug (int num, const char *msg, ...);
+void dMessage (int num, const char *msg, ...);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/extern/ode/dist/include/ode/geom.h b/extern/ode/dist/include/ode/geom.h
new file mode 100644 (file)
index 0000000..ec0aafe
--- /dev/null
@@ -0,0 +1,152 @@
+/*************************************************************************
+ *                                                                       *
+ * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith.       *
+ * All rights reserved.  Email: russ@q12.org   Web: www.q12.org          *
+ *                                                                       *
+ * This library is free software; you can redistribute it and/or         *
+ * modify it under the terms of EITHER:                                  *
+ *   (1) The GNU Lesser General Public License as published by the Free  *
+ *       Software Foundation; either version 2.1 of the License, or (at  *
+ *       your option) any later version. The text of the GNU Lesser      *
+ *       General Public License is included with this library in the     *
+ *       file LICENSE.TXT.                                               *
+ *   (2) The BSD-style license that is included with this library in     *
+ *       the file LICENSE-BSD.TXT.                                       *
+ *                                                                       *
+ * This library is distributed in the hope that it will be useful,       *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files    *
+ * LICENSE.TXT and LICENSE-BSD.TXT for more details.                     *
+ *                                                                       *
+ *************************************************************************/
+
+#ifndef _ODE_GEOM_H_
+#define _ODE_GEOM_H_
+
+#include <ode/common.h>
+#include <ode/space.h>
+#include <ode/contact.h>
+
+#if defined SHARED_GEOM_H_INCLUDED_FROM_DEFINING_FILE
+#define GLOBAL_SHAREDLIB_SPEC SHAREDLIBEXPORT
+#else 
+#define GLOBAL_SHAREDLIB_SPEC SHAREDLIBIMPORT
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* ************************************************************************ */
+/* utility functions */
+
+void dClosestLineSegmentPoints (const dVector3 a1, const dVector3 a2,
+                               const dVector3 b1, const dVector3 b2,
+                               dVector3 cp1, dVector3 cp2);
+
+int dBoxTouchesBox (const dVector3 _p1, const dMatrix3 R1,
+                   const dVector3 side1, const dVector3 _p2,
+                   const dMatrix3 R2, const dVector3 side2);
+
+void dInfiniteAABB (dGeomID geom, dReal aabb[6]);
+void dCloseODE();
+
+/* ************************************************************************ */
+/* standard classes */
+
+/* class numbers */
+extern GLOBAL_SHAREDLIB_SPEC int dSphereClass;
+extern GLOBAL_SHAREDLIB_SPEC int dBoxClass;
+extern GLOBAL_SHAREDLIB_SPEC int dCCylinderClass;
+extern GLOBAL_SHAREDLIB_SPEC int dPlaneClass;
+extern GLOBAL_SHAREDLIB_SPEC int dGeomGroupClass;
+extern GLOBAL_SHAREDLIB_SPEC int dGeomTransformClass;
+
+/* constructors */
+dGeomID dCreateSphere (dSpaceID space, dReal radius);
+dGeomID dCreateBox (dSpaceID space, dReal lx, dReal ly, dReal lz);
+dGeomID dCreatePlane (dSpaceID space, dReal a, dReal b, dReal c, dReal d);
+dGeomID dCreateCCylinder (dSpaceID space, dReal radius, dReal length);
+dGeomID dCreateGeomGroup (dSpaceID space);
+
+/* set geometry parameters */
+void dGeomSphereSetRadius (dGeomID sphere, dReal radius);
+void dGeomBoxSetLengths (dGeomID box, dReal lx, dReal ly, dReal lz);
+void dGeomPlaneSetParams (dGeomID plane, dReal a, dReal b, dReal c, dReal d);
+void dGeomCCylinderSetParams (dGeomID ccylinder, dReal radius, dReal length);
+
+/* get geometry parameters */
+int   dGeomGetClass (dGeomID);
+dReal dGeomSphereGetRadius (dGeomID sphere);
+void  dGeomBoxGetLengths (dGeomID box, dVector3 result);
+void  dGeomPlaneGetParams (dGeomID plane, dVector4 result);
+void  dGeomCCylinderGetParams (dGeomID ccylinder,
+                              dReal *radius, dReal *length);
+
+/* general functions */
+void dGeomSetData (dGeomID, void *);
+void *dGeomGetData (dGeomID);
+void dGeomSetBody (dGeomID, dBodyID);
+dBodyID dGeomGetBody (dGeomID);
+void dGeomSetPosition (dGeomID, dReal x, dReal y, dReal z);
+void dGeomSetRotation (dGeomID, const dMatrix3 R);
+const dReal * dGeomGetPosition (dGeomID);
+const dReal * dGeomGetRotation (dGeomID);
+void dGeomDestroy (dGeomID);
+void dGeomGetAABB (dGeomID, dReal aabb[6]);
+dReal *dGeomGetSpaceAABB (dGeomID);
+
+/* ************************************************************************ */
+/* geometry group functions */
+
+void dGeomGroupAdd (dGeomID group, dGeomID x);
+void dGeomGroupRemove (dGeomID group, dGeomID x);
+int dGeomGroupGetNumGeoms (dGeomID group);
+dGeomID dGeomGroupGetGeom (dGeomID group, int i);
+
+/* ************************************************************************ */
+/* transformed geometry functions */
+
+dGeomID dCreateGeomTransform (dSpaceID space);
+void dGeomTransformSetGeom (dGeomID g, dGeomID obj);
+dGeomID dGeomTransformGetGeom (dGeomID g);
+void dGeomTransformSetCleanup (dGeomID g, int mode);
+int dGeomTransformGetCleanup (dGeomID g);
+void dGeomTransformSetInfo (dGeomID g, int mode);
+int dGeomTransformGetInfo (dGeomID g);
+
+/* ************************************************************************ */
+/* general collision */
+
+int dCollide (dGeomID o1, dGeomID o2, int flags, dContactGeom *contact,
+             int skip);
+
+/* ************************************************************************ */
+/* custom classes */
+
+typedef void dGetAABBFn (dGeomID, dReal aabb[6]);
+typedef int dColliderFn (dGeomID o1, dGeomID o2,
+                        int flags, dContactGeom *contact, int skip);
+typedef dColliderFn * dGetColliderFnFn (int num);
+typedef void dGeomDtorFn (dGeomID o);
+typedef int dAABBTestFn (dGeomID o1, dGeomID o2, dReal aabb[6]);
+
+typedef struct dGeomClass {
+  int bytes;
+  dGetColliderFnFn *collider;
+  dGetAABBFn *aabb;
+  dAABBTestFn *aabb_test;
+  dGeomDtorFn *dtor;
+} dGeomClass;
+
+int dCreateGeomClass (const dGeomClass *classptr);
+void * dGeomGetClassData (dGeomID);
+dGeomID dCreateGeom (int classnum);
+
+/* ************************************************************************ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/extern/ode/dist/include/ode/mass.h b/extern/ode/dist/include/ode/mass.h
new file mode 100644 (file)
index 0000000..53e4374
--- /dev/null
@@ -0,0 +1,97 @@
+/*************************************************************************
+ *                                                                       *
+ * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith.       *
+ * All rights reserved.  Email: russ@q12.org   Web: www.q12.org          *
+ *                                                                       *
+ * This library is free software; you can redistribute it and/or         *
+ * modify it under the terms of EITHER:                                  *
+ *   (1) The GNU Lesser General Public License as published by the Free  *
+ *       Software Foundation; either version 2.1 of the License, or (at  *
+ *       your option) any later version. The text of the GNU Lesser      *
+ *       General Public License is included with this library in the     *
+ *       file LICENSE.TXT.                                               *
+ *   (2) The BSD-style license that is included with this library in     *
+ *       the file LICENSE-BSD.TXT.                                       *
+ *                                                                       *
+ * This library is distributed in the hope that it will be useful,       *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files    *
+ * LICENSE.TXT and LICENSE-BSD.TXT for more details.                     *
+ *                                                                       *
+ *************************************************************************/
+
+#ifndef _ODE_MASS_H_
+#define _ODE_MASS_H_
+
+#include <ode/common.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct dMass;
+typedef struct dMass dMass;
+
+
+void dMassSetZero (dMass *);
+
+void dMassSetParameters (dMass *, dReal themass,
+                        dReal cgx, dReal cgy, dReal cgz,
+                        dReal I11, dReal I22, dReal I33,
+                        dReal I12, dReal I13, dReal I23);
+
+void dMassSetSphere (dMass *, dReal density, dReal radius);
+
+void dMassSetCappedCylinder (dMass *, dReal density, int direction,
+                            dReal a, dReal b);
+
+void dMassSetBox (dMass *, dReal density,
+                 dReal lx, dReal ly, dReal lz);
+
+void dMassAdjust (dMass *, dReal newmass);
+
+void dMassTranslate (dMass *, dReal x, dReal y, dReal z);
+
+void dMassRotate (dMass *, const dMatrix3 R);
+
+void dMassAdd (dMass *a, const dMass *b);
+
+
+
+struct dMass {
+  dReal mass;
+  dVector4 c;
+  dMatrix3 I;
+
+#ifdef __cplusplus
+  dMass()
+    { dMassSetZero (this); }
+  void setZero()
+    { dMassSetZero (this); }
+  void setParameters (dReal themass, dReal cgx, dReal cgy, dReal cgz,
+                     dReal I11, dReal I22, dReal I33,
+                     dReal I12, dReal I13, dReal I23)
+    { dMassSetParameters (this,themass,cgx,cgy,cgz,I11,I22,I33,I12,I13,I23); }
+  void setSphere (dReal density, dReal radius)
+    { dMassSetSphere (this,density,radius); }
+  void setCappedCylinder (dReal density, int direction, dReal a, dReal b)
+    { dMassSetCappedCylinder (this,density,direction,a,b); }
+  void setBox (dReal density, dReal lx, dReal ly, dReal lz)
+    { dMassSetBox (this,density,lx,ly,lz); }
+  void adjust (dReal newmass)
+    { dMassAdjust (this,newmass); }
+  void translate (dReal x, dReal y, dReal z)
+    { dMassTranslate (this,x,y,z); }
+  void rotate (const dMatrix3 R)
+    { dMassRotate (this,R); }
+  void add (const dMass *b)
+    { dMassAdd (this,b); }
+#endif
+};
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/extern/ode/dist/include/ode/matrix.h b/extern/ode/dist/include/ode/matrix.h
new file mode 100644 (file)
index 0000000..75218fd
--- /dev/null
@@ -0,0 +1,194 @@
+/*************************************************************************
+ *                                                                       *
+ * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith.       *
+ * All rights reserved.  Email: russ@q12.org   Web: www.q12.org          *
+ *                                                                       *
+ * This library is free software; you can redistribute it and/or         *
+ * modify it under the terms of EITHER:                                  *
+ *   (1) The GNU Lesser General Public License as published by the Free  *
+ *       Software Foundation; either version 2.1 of the License, or (at  *
+ *       your option) any later version. The text of the GNU Lesser      *
+ *       General Public License is included with this library in the     *
+ *       file LICENSE.TXT.                                               *
+ *   (2) The BSD-style license that is included with this library in     *
+ *       the file LICENSE-BSD.TXT.                                       *
+ *                                                                       *
+ * This library is distributed in the hope that it will be useful,       *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files    *
+ * LICENSE.TXT and LICENSE-BSD.TXT for more details.                     *
+ *                                                                       *
+ *************************************************************************/
+
+/* optimized and unoptimized vector and matrix functions */
+
+#ifndef _ODE_MATRIX_H_
+#define _ODE_MATRIX_H_
+
+#include <ode/common.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/* set a vector/matrix of size n to all zeros, or to a specific value. */
+
+void dSetZero (dReal *a, int n);
+void dSetValue (dReal *a, int n, dReal value);
+
+
+/* get the dot product of two n*1 vectors. if n <= 0 then
+ * zero will be returned (in which case a and b need not be valid).
+ */
+
+dReal dDot (const dReal *a, const dReal *b, int n);
+
+
+/* get the dot products of (a0,b), (a1,b), etc and return them in outsum.
+ * all vectors are n*1. if n <= 0 then zeroes will be returned (in which case
+ * the input vectors need not be valid). this function is somewhat faster
+ * than calling dDot() for all of the combinations separately.
+ */
+
+/* NOT INCLUDED in the library for now.
+void dMultidot2 (const dReal *a0, const dReal *a1,
+                const dReal *b, dReal *outsum, int n);
+*/
+
+
+/* matrix multiplication. all matrices are stored in standard row format.
+ * the digit refers to the argument that is transposed:
+ *   0:   A = B  * C   (sizes: A:p*r B:p*q C:q*r)
+ *   1:   A = B' * C   (sizes: A:p*r B:q*p C:q*r)
+ *   2:   A = B  * C'  (sizes: A:p*r B:p*q C:r*q)
+ * case 1,2 are equivalent to saying that the operation is A=B*C but
+ * B or C are stored in standard column format.
+ */
+
+void dMultiply0 (dReal *A, const dReal *B, const dReal *C, int p,int q,int r);
+void dMultiply1 (dReal *A, const dReal *B, const dReal *C, int p,int q,int r);
+void dMultiply2 (dReal *A, const dReal *B, const dReal *C, int p,int q,int r);
+
+
+/* do an in-place cholesky decomposition on the lower triangle of the n*n
+ * symmetric matrix A (which is stored by rows). the resulting lower triangle
+ * will be such that L*L'=A. return 1 on success and 0 on failure (on failure
+ * the matrix is not positive definite).
+ */
+
+int dFactorCholesky (dReal *A, int n);
+
+
+/* solve for x: L*L'*x = b, and put the result back into x.
+ * L is size n*n, b is size n*1. only the lower triangle of L is considered.
+ */
+
+void dSolveCholesky (const dReal *L, dReal *b, int n);
+
+
+/* compute the inverse of the n*n positive definite matrix A and put it in
+ * Ainv. this is not especially fast. this returns 1 on success (A was
+ * positive definite) or 0 on failure (not PD).
+ */
+
+int dInvertPDMatrix (const dReal *A, dReal *Ainv, int n);
+
+
+/* check whether an n*n matrix A is positive definite, return 1/0 (yes/no).
+ * positive definite means that x'*A*x > 0 for any x. this performs a
+ * cholesky decomposition of A. if the decomposition fails then the matrix
+ * is not positive definite. A is stored by rows. A is not altered.
+ */
+
+int dIsPositiveDefinite (const dReal *A, int n);
+
+
+/* factorize a matrix A into L*D*L', where L is lower triangular with ones on
+ * the diagonal, and D is diagonal.
+ * A is an n*n matrix stored by rows, with a leading dimension of n rounded
+ * up to 4. L is written into the strict lower triangle of A (the ones are not
+ * written) and the reciprocal of the diagonal elements of D are written into
+ * d.
+ */
+void dFactorLDLT (dReal *A, dReal *d, int n, int nskip);
+
+
+/* solve L*x=b, where L is n*n lower triangular with ones on the diagonal,
+ * and x,b are n*1. b is overwritten with x.
+ * the leading dimension of L is `nskip'.
+ */
+void dSolveL1 (const dReal *L, dReal *b, int n, int nskip);
+
+
+/* solve L'*x=b, where L is n*n lower triangular with ones on the diagonal,
+ * and x,b are n*1. b is overwritten with x.
+ * the leading dimension of L is `nskip'.
+ */
+void dSolveL1T (const dReal *L, dReal *b, int n, int nskip);
+
+
+/* in matlab syntax: a(1:n) = a(1:n) .* d(1:n) */
+
+void dVectorScale (dReal *a, const dReal *d, int n);
+
+
+/* given `L', a n*n lower triangular matrix with ones on the diagonal,
+ * and `d', a n*1 vector of the reciprocal diagonal elements of an n*n matrix
+ * D, solve L*D*L'*x=b where x,b are n*1. x overwrites b.
+ * the leading dimension of L is `nskip'.
+ */
+
+void dSolveLDLT (const dReal *L, const dReal *d, dReal *b, int n, int nskip);
+
+
+/* given an L*D*L' factorization of an n*n matrix A, return the updated
+ * factorization L2*D2*L2' of A plus the following "top left" matrix:
+ *
+ *    [ b a' ]     <-- b is a[0]
+ *    [ a 0  ]     <-- a is a[1..n-1]
+ *
+ *   - L has size n*n, its leading dimension is nskip. L is lower triangular
+ *     with ones on the diagonal. only the lower triangle of L is referenced.
+ *   - d has size n. d contains the reciprocal diagonal elements of D.
+ *   - a has size n.
+ * the result is written into L, except that the left column of L and d[0]
+ * are not actually modified. see ldltaddTL.m for further comments. 
+ */
+void dLDLTAddTL (dReal *L, dReal *d, const dReal *a, int n, int nskip);
+
+
+/* given an L*D*L' factorization of a permuted matrix A, produce a new
+ * factorization for row and column `r' removed.
+ *   - A has size n1*n1, its leading dimension in nskip. A is symmetric and
+ *     positive definite. only the lower triangle of A is referenced.
+ *     A itself may actually be an array of row pointers.
+ *   - L has size n2*n2, its leading dimension in nskip. L is lower triangular
+ *     with ones on the diagonal. only the lower triangle of L is referenced.
+ *   - d has size n2. d contains the reciprocal diagonal elements of D.
+ *   - p is a permutation vector. it contains n2 indexes into A. each index
+ *     must be in the range 0..n1-1.
+ *   - r is the row/column of L to remove.
+ * the new L will be written within the old L, i.e. will have the same leading
+ * dimension. the last row and column of L, and the last element of d, are
+ * undefined on exit.
+ *
+ * a fast O(n^2) algorithm is used. see ldltremove.m for further comments.
+ */
+void dLDLTRemove (dReal **A, const int *p, dReal *L, dReal *d,
+                 int n1, int n2, int r, int nskip);
+
+
+/* given an n*n matrix A (with leading dimension nskip), remove the r'th row
+ * and column by moving elements. the new matrix will have the same leading
+ * dimension. the last row and column of A are untouched on exit.
+ */
+void dRemoveRowCol (dReal *A, int n, int nskip, int r);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/extern/ode/dist/include/ode/memory.h b/extern/ode/dist/include/ode/memory.h
new file mode 100644 (file)
index 0000000..476a05a
--- /dev/null
@@ -0,0 +1,63 @@
+/*************************************************************************
+ *                                                                       *
+ * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith.       *
+ * All rights reserved.  Email: russ@q12.org   Web: www.q12.org          *
+ *                                                                       *
+ * This library is free software; you can redistribute it and/or         *
+ * modify it under the terms of EITHER:                                  *
+ *   (1) The GNU Lesser General Public License as published by the Free  *
+ *       Software Foundation; either version 2.1 of the License, or (at  *
+ *       your option) any later version. The text of the GNU Lesser      *
+ *       General Public License is included with this library in the     *
+ *       file LICENSE.TXT.                                               *
+ *   (2) The BSD-style license that is included with this library in     *
+ *       the file LICENSE-BSD.TXT.                                       *
+ *                                                                       *
+ * This library is distributed in the hope that it will be useful,       *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files    *
+ * LICENSE.TXT and LICENSE-BSD.TXT for more details.                     *
+ *                                                                       *
+ *************************************************************************/
+
+/* this comes from the `reuse' library. copy any changes back to the source */
+
+#ifndef _ODE_MEMORY_H_
+#define _ODE_MEMORY_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* function types to allocate and free memory */
+typedef void * dAllocFunction (int size);
+typedef void * dReallocFunction (void *ptr, int oldsize, int newsize);
+typedef void dFreeFunction (void *ptr, int size);
+
+/* set new memory management functions. if fn is 0, the default handlers are
+ * used. */
+void dSetAllocHandler (dAllocFunction *fn);
+void dSetReallocHandler (dReallocFunction *fn);
+void dSetFreeHandler (dFreeFunction *fn);
+
+/* get current memory management functions */
+dAllocFunction *dGetAllocHandler ();
+dReallocFunction *dGetReallocHandler ();
+dFreeFunction *dGetFreeHandler ();
+
+/* allocate and free memory. */
+void * dAlloc (int size);
+void * dRealloc (void *ptr, int oldsize, int newsize);
+void dFree (void *ptr, int size);
+
+/* when alloc debugging is turned on, this indicates that the given block of
+ * alloc()ed memory should not be reported as "still in use" when the program
+ * exits.
+ */
+void dAllocDontReport (void *ptr);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/extern/ode/dist/include/ode/misc.h b/extern/ode/dist/include/ode/misc.h
new file mode 100644 (file)
index 0000000..9ceca30
--- /dev/null
@@ -0,0 +1,85 @@
+/*************************************************************************
+ *                                                                       *
+ * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith.       *
+ * All rights reserved.  Email: russ@q12.org   Web: www.q12.org          *
+ *                                                                       *
+ * This library is free software; you can redistribute it and/or         *
+ * modify it under the terms of EITHER:                                  *
+ *   (1) The GNU Lesser General Public License as published by the Free  *
+ *       Software Foundation; either version 2.1 of the License, or (at  *
+ *       your option) any later version. The text of the GNU Lesser      *
+ *       General Public License is included with this library in the     *
+ *       file LICENSE.TXT.                                               *
+ *   (2) The BSD-style license that is included with this library in     *
+ *       the file LICENSE-BSD.TXT.                                       *
+ *                                                                       *
+ * This library is distributed in the hope that it will be useful,       *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files    *
+ * LICENSE.TXT and LICENSE-BSD.TXT for more details.                     *
+ *                                                                       *
+ *************************************************************************/
+
+/* miscellaneous math functions. these are mostly useful for testing */
+
+#ifndef _ODE_MISC_H_
+#define _ODE_MISC_H_
+
+#include <ode/common.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/* return 1 if the random number generator is working. */
+int dTestRand();
+
+/* return next 32 bit random number. this uses a not-very-random linear
+ * congruential method.
+ */
+unsigned long dRand();
+
+/* get and set the current random number seed. */
+unsigned long  dRandGetSeed();
+void dRandSetSeed (unsigned long s);
+
+/* return a random integer between 0..n-1. the distribution will get worse
+ * as n approaches 2^32.
+ */
+int dRandInt (int n);
+
+/* return a random real number between 0..1 */
+dReal dRandReal();
+
+/* print out a matrix */
+#ifdef __cplusplus
+void dPrintMatrix (dReal *A, int n, int m, char *fmt = "%10.4f ",
+                  FILE *f=stdout);
+#else
+void dPrintMatrix (dReal *A, int n, int m, char *fmt, FILE *f);
+#endif
+
+/* make a random vector with entries between +/- range. A has n elements. */
+void dMakeRandomVector (dReal *A, int n, dReal range);
+
+/* make a random matrix with entries between +/- range. A has size n*m. */
+void dMakeRandomMatrix (dReal *A, int n, int m, dReal range);
+
+/* clear the upper triangle of a square matrix */
+void dClearUpperTriangle (dReal *A, int n);
+
+/* return the maximum element difference between the two n*m matrices */
+dReal dMaxDifference (const dReal *A, const dReal *B, int n, int m);
+
+/* return the maximum element difference between the lower triangle of two
+ * n*n matrices */
+dReal dMaxDifferenceLowerTriangle (const dReal *A, const dReal *B, int n);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/extern/ode/dist/include/ode/objects.h b/extern/ode/dist/include/ode/objects.h
new file mode 100644 (file)
index 0000000..9531c63
--- /dev/null
@@ -0,0 +1,201 @@
+/*************************************************************************
+ *                                                                       *
+ * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith.       *
+ * All rights reserved.  Email: russ@q12.org   Web: www.q12.org          *
+ *                                                                       *
+ * This library is free software; you can redistribute it and/or         *
+ * modify it under the terms of EITHER:                                  *
+ *   (1) The GNU Lesser General Public License as published by the Free  *
+ *       Software Foundation; either version 2.1 of the License, or (at  *
+ *       your option) any later version. The text of the GNU Lesser      *
+ *       General Public License is included with this library in the     *
+ *       file LICENSE.TXT.                                               *
+ *   (2) The BSD-style license that is included with this library in     *
+ *       the file LICENSE-BSD.TXT.                                       *
+ *                                                                       *
+ * This library is distributed in the hope that it will be useful,       *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files    *
+ * LICENSE.TXT and LICENSE-BSD.TXT for more details.                     *
+ *                                                                       *
+ *************************************************************************/
+
+#ifndef _ODE_OBJECTS_H_
+#define _ODE_OBJECTS_H_
+
+#include <ode/common.h>
+#include <ode/mass.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* world */
+
+dWorldID dWorldCreate();
+void dWorldDestroy (dWorldID);
+
+void dWorldSetGravity (dWorldID, dReal x, dReal y, dReal z);
+void dWorldGetGravity (dWorldID, dVector3 gravity);
+void dWorldSetERP (dWorldID, dReal erp);
+dReal dWorldGetERP (dWorldID);
+void dWorldSetCFM (dWorldID, dReal cfm);
+dReal dWorldGetCFM (dWorldID);
+void dWorldStep (dWorldID, dReal stepsize);
+void dWorldImpulseToForce (dWorldID, dReal stepsize,
+                          dReal ix, dReal iy, dReal iz, dVector3 force);
+
+/* bodies */
+
+dBodyID dBodyCreate (dWorldID);
+void dBodyDestroy (dBodyID);
+
+void  dBodySetData (dBodyID, void *data);
+void *dBodyGetData (dBodyID);
+
+void dBodySetPosition   (dBodyID, dReal x, dReal y, dReal z);
+void dBodySetRotation   (dBodyID, const dMatrix3 R);
+void dBodySetQuaternion (dBodyID, const dQuaternion q);
+void dBodySetLinearVel  (dBodyID, dReal x, dReal y, dReal z);
+void dBodySetAngularVel (dBodyID, dReal x, dReal y, dReal z);
+const dReal * dBodyGetPosition   (dBodyID);
+const dReal * dBodyGetRotation   (dBodyID);    /* ptr to 4x3 rot matrix */
+const dReal * dBodyGetQuaternion (dBodyID);
+const dReal * dBodyGetLinearVel  (dBodyID);
+const dReal * dBodyGetAngularVel (dBodyID);
+
+void dBodySetMass (dBodyID, const dMass *mass);
+void dBodyGetMass (dBodyID, dMass *mass);
+
+void dBodyAddForce            (dBodyID, dReal fx, dReal fy, dReal fz);
+void dBodyAddTorque           (dBodyID, dReal fx, dReal fy, dReal fz);
+void dBodyAddRelForce         (dBodyID, dReal fx, dReal fy, dReal fz);
+void dBodyAddRelTorque        (dBodyID, dReal fx, dReal fy, dReal fz);
+void dBodyAddForceAtPos       (dBodyID, dReal fx, dReal fy, dReal fz,
+                                       dReal px, dReal py, dReal pz);
+void dBodyAddForceAtRelPos    (dBodyID, dReal fx, dReal fy, dReal fz,
+                                       dReal px, dReal py, dReal pz);
+void dBodyAddRelForceAtPos    (dBodyID, dReal fx, dReal fy, dReal fz,
+                                       dReal px, dReal py, dReal pz);
+void dBodyAddRelForceAtRelPos (dBodyID, dReal fx, dReal fy, dReal fz,
+                                       dReal px, dReal py, dReal pz);
+
+const dReal * dBodyGetForce   (dBodyID);
+const dReal * dBodyGetTorque  (dBodyID);
+void dBodySetForce  (dBodyID b, dReal x, dReal y, dReal z);
+void dBodySetTorque (dBodyID b, dReal x, dReal y, dReal z);
+
+void dBodyGetRelPointPos    (dBodyID, dReal px, dReal py, dReal pz,
+                            dVector3 result);
+void dBodyGetRelPointVel    (dBodyID, dReal px, dReal py, dReal pz,
+                            dVector3 result);
+void dBodyGetPointVel       (dBodyID, dReal px, dReal py, dReal pz,
+                            dVector3 result);
+void dBodyGetPosRelPoint    (dBodyID, dReal px, dReal py, dReal pz,
+                            dVector3 result);
+void dBodyVectorToWorld     (dBodyID, dReal px, dReal py, dReal pz,
+                            dVector3 result);
+void dBodyVectorFromWorld   (dBodyID, dReal px, dReal py, dReal pz,
+                            dVector3 result);
+
+void dBodySetFiniteRotationMode (dBodyID, int mode);
+void dBodySetFiniteRotationAxis (dBodyID, dReal x, dReal y, dReal z);
+
+int dBodyGetFiniteRotationMode (dBodyID);
+void dBodyGetFiniteRotationAxis (dBodyID, dVector3 result);
+
+int dBodyGetNumJoints (dBodyID b);
+dJointID dBodyGetJoint (dBodyID, int index);
+
+void dBodyEnable (dBodyID);
+void dBodyDisable (dBodyID);
+int dBodyIsEnabled (dBodyID);
+
+void dBodySetGravityMode (dBodyID b, int mode);
+int dBodyGetGravityMode (dBodyID b);
+
+
+/* joints */
+
+dJointID dJointCreateBall (dWorldID, dJointGroupID);
+dJointID dJointCreateHinge (dWorldID, dJointGroupID);
+dJointID dJointCreateSlider (dWorldID, dJointGroupID);
+dJointID dJointCreateContact (dWorldID, dJointGroupID, const dContact *);
+dJointID dJointCreateHinge2 (dWorldID, dJointGroupID);
+dJointID dJointCreateUniversal (dWorldID, dJointGroupID);
+dJointID dJointCreateFixed (dWorldID, dJointGroupID);
+dJointID dJointCreateNull (dWorldID, dJointGroupID);
+dJointID dJointCreateAMotor (dWorldID, dJointGroupID);
+
+void dJointDestroy (dJointID);
+
+dJointGroupID dJointGroupCreate (int max_size);
+void dJointGroupDestroy (dJointGroupID);
+void dJointGroupEmpty (dJointGroupID);
+
+void dJointAttach (dJointID, dBodyID body1, dBodyID body2);
+void dJointSetData (dJointID, void *data);
+void *dJointGetData (dJointID);
+int dJointGetType (dJointID);
+dBodyID dJointGetBody (dJointID, int index);
+
+void dJointSetFeedback (dJointID, dJointFeedback *);
+dJointFeedback *dJointGetFeedback (dJointID);
+
+void dJointSetBallAnchor (dJointID, dReal x, dReal y, dReal z);
+void dJointSetHingeAnchor (dJointID, dReal x, dReal y, dReal z);
+void dJointSetHingeAxis (dJointID, dReal x, dReal y, dReal z);
+void dJointSetHingeParam (dJointID, int parameter, dReal value);
+void dJointSetSliderAxis (dJointID, dReal x, dReal y, dReal z);
+void dJointSetSliderParam (dJointID, int parameter, dReal value);
+void dJointSetHinge2Anchor (dJointID, dReal x, dReal y, dReal z);
+void dJointSetHinge2Axis1 (dJointID, dReal x, dReal y, dReal z);
+void dJointSetHinge2Axis2 (dJointID, dReal x, dReal y, dReal z);
+void dJointSetHinge2Param (dJointID, int parameter, dReal value);
+void dJointSetUniversalAnchor (dJointID, dReal x, dReal y, dReal z);
+void dJointSetUniversalAxis1 (dJointID, dReal x, dReal y, dReal z);
+void dJointSetUniversalAxis2 (dJointID, dReal x, dReal y, dReal z);
+void dJointSetFixed (dJointID);
+void dJointSetAMotorNumAxes (dJointID, int num);
+void dJointSetAMotorAxis (dJointID, int anum, int rel,
+                         dReal x, dReal y, dReal z);
+void dJointSetAMotorAngle (dJointID, int anum, dReal angle);
+void dJointSetAMotorParam (dJointID, int parameter, dReal value);
+void dJointSetAMotorMode (dJointID, int mode);
+
+void dJointGetBallAnchor (dJointID, dVector3 result);
+void dJointGetHingeAnchor (dJointID, dVector3 result);
+void dJointGetHingeAxis (dJointID, dVector3 result);
+dReal dJointGetHingeParam (dJointID, int parameter);
+dReal dJointGetHingeAngle (dJointID);
+dReal dJointGetHingeAngleRate (dJointID);
+dReal dJointGetSliderPosition (dJointID);
+dReal dJointGetSliderPositionRate (dJointID);
+void dJointGetSliderAxis (dJointID, dVector3 result);
+dReal dJointGetSliderParam (dJointID, int parameter);
+void dJointGetHinge2Anchor (dJointID, dVector3 result);
+void dJointGetHinge2Axis1 (dJointID, dVector3 result);
+void dJointGetHinge2Axis2 (dJointID, dVector3 result);
+dReal dJointGetHinge2Param (dJointID, int parameter);
+dReal dJointGetHinge2Angle1 (dJointID);
+dReal dJointGetHinge2Angle1Rate (dJointID);
+dReal dJointGetHinge2Angle2Rate (dJointID);
+void dJointGetUniversalAnchor (dJointID, dVector3 result);
+void dJointGetUniversalAxis1 (dJointID, dVector3 result);
+void dJointGetUniversalAxis2 (dJointID, dVector3 result);
+int dJointGetAMotorNumAxes (dJointID);
+void dJointGetAMotorAxis (dJointID, int anum, dVector3 result);
+int dJointGetAMotorAxisRel (dJointID, int anum);
+dReal dJointGetAMotorAngle (dJointID, int anum);
+dReal dJointGetAMotorAngleRate (dJointID, int anum);
+dReal dJointGetAMotorParam (dJointID, int parameter);
+int dJointGetAMotorMode (dJointID);
+
+int dAreConnected (dBodyID, dBodyID);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/extern/ode/dist/include/ode/ode.h b/extern/ode/dist/include/ode/ode.h
new file mode 100644 (file)
index 0000000..f0ee944
--- /dev/null
@@ -0,0 +1,44 @@
+/*************************************************************************
+ *                                                                       *
+ * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith.       *
+ * All rights reserved.  Email: russ@q12.org   Web: www.q12.org          *
+ *                                                                       *
+ * This library is free software; you can redistribute it and/or         *
+ * modify it under the terms of EITHER:                                  *
+ *   (1) The GNU Lesser General Public License as published by the Free  *
+ *       Software Foundation; either version 2.1 of the License, or (at  *
+ *       your option) any later version. The text of the GNU Lesser      *
+ *       General Public License is included with this library in the     *
+ *       file LICENSE.TXT.                                               *
+ *   (2) The BSD-style license that is included with this library in     *
+ *       the file LICENSE-BSD.TXT.                                       *
+ *                                                                       *
+ * This library is distributed in the hope that it will be useful,       *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files    *
+ * LICENSE.TXT and LICENSE-BSD.TXT for more details.                     *
+ *                                                                       *
+ *************************************************************************/
+
+#ifndef _ODE_ODE_H_
+#define _ODE_ODE_H_
+
+/* include *everything* here */
+
+#include <ode/config.h>
+#include <ode/common.h>
+#include <ode/contact.h>
+#include <ode/error.h>
+#include <ode/memory.h>
+#include <ode/odemath.h>
+#include <ode/matrix.h>
+#include <ode/timer.h>
+#include <ode/rotation.h>
+#include <ode/mass.h>
+#include <ode/space.h>
+#include <ode/geom.h>
+#include <ode/misc.h>
+#include <ode/objects.h>
+#include <ode/odecpp.h>
+
+#endif
diff --git a/extern/ode/dist/include/ode/odecpp.h b/extern/ode/dist/include/ode/odecpp.h
new file mode 100644 (file)
index 0000000..3eaa973
--- /dev/null
@@ -0,0 +1,796 @@
+/*************************************************************************
+ *                                                                      *
+ * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith.      *
+ * All rights reserved.  Email: russ@q12.org   Web: www.q12.org         *
+ *                                                                      *
+ * This library is free software; you can redistribute it and/or        *
+ * modify it under the terms of EITHER:                                 *
+ *   (1) The GNU Lesser General Public License as published by the Free  *
+ *      Software Foundation; either version 2.1 of the License, or (at  *
+ *      your option) any later version. The text of the GNU Lesser      *
+ *      General Public License is included with this library in the     *
+ *      file LICENSE.TXT.                                               *
+ *   (2) The BSD-style license that is included with this library in    *
+ *      the file LICENSE-BSD.TXT.                                       *
+ *                                                                      *
+ * This library is distributed in the hope that it will be useful,      *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of       *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files   *
+ * LICENSE.TXT and LICENSE-BSD.TXT for more details.                    *
+ *                                                                      *
+ *************************************************************************/
+
+// C++ interface for everything
+
+
+#ifndef _ODE_ODECPP_H_
+#define _ODE_ODECPP_H_
+#ifdef __cplusplus
+
+#include <ode/error.h>
+
+
+class dWorld {
+  dWorldID _id;
+
+  // intentionally undefined, don't use these
+  dWorld (const dWorld &);
+  void operator= (const dWorld &);
+
+public:
+  dWorld()
+    { _id = dWorldCreate(); }
+  ~dWorld()
+    { dWorldDestroy (_id); }
+
+  dWorldID id() const
+    { return _id; }
+  operator dWorldID() const
+    { return _id; }
+
+  void setGravity (dReal x, dReal y, dReal z)
+    { dWorldSetGravity (_id,x,y,z); }
+  void getGravity (dVector3 g) const
+    { dWorldGetGravity (_id,g); }
+
+  void setERP (dReal erp)
+    { dWorldSetERP(_id, erp); }
+  dReal getERP() const
+    { return dWorldGetERP(_id); }
+
+  void setCFM (dReal cfm)
+    { dWorldSetCFM(_id, cfm); }
+  dReal getCFM() const
+    { return dWorldGetCFM(_id); }
+
+  void step (dReal stepsize)
+    { dWorldStep (_id,stepsize); }
+
+  void impulseToForce (dReal stepsize, dReal ix, dReal iy, dReal iz,
+                      dVector3 force)
+    { dWorldImpulseToForce (_id,stepsize,ix,iy,iz,force); }
+};
+
+
+class dBody {
+  dBodyID _id;
+
+  // intentionally undefined, don't use these
+  dBody (const dBody &);
+  void operator= (const dBody &);
+
+public:
+  dBody()
+    { _id = 0; }
+  dBody (dWorldID world)
+    { _id = dBodyCreate (world); }
+  ~dBody()
+    { if (_id) dBodyDestroy (_id); }
+
+  void create (dWorldID world) {
+    if (_id) dBodyDestroy (_id);
+    _id = dBodyCreate (world);
+  }
+
+  dBodyID id() const
+    { return _id; }
+  operator dBodyID() const
+    { return _id; }
+
+  void setData (void *data)
+    { dBodySetData (_id,data); }
+  void *getData() const
+    { return dBodyGetData (_id); }
+
+  void setPosition (dReal x, dReal y, dReal z)
+    { dBodySetPosition (_id,x,y,z); }
+  void setRotation (const dMatrix3 R)
+    { dBodySetRotation (_id,R); }
+  void setQuaternion (const dQuaternion q)
+    { dBodySetQuaternion (_id,q); }
+  void setLinearVel  (dReal x, dReal y, dReal z)
+    { dBodySetLinearVel (_id,x,y,z); }
+  void setAngularVel (dReal x, dReal y, dReal z)
+    { dBodySetAngularVel (_id,x,y,z); }
+
+  const dReal * getPosition() const
+    { return dBodyGetPosition (_id); }
+  const dReal * getRotation() const
+    { return dBodyGetRotation (_id); }
+  const dReal * getQuaternion() const
+    { return dBodyGetQuaternion (_id); }
+  const dReal * getLinearVel() const
+    { return dBodyGetLinearVel (_id); }
+  const dReal * getAngularVel() const
+    { return dBodyGetAngularVel (_id); }
+
+  void setMass (const dMass *mass)
+    { dBodySetMass (_id,mass); }
+  void getMass (dMass *mass) const
+    { dBodyGetMass (_id,mass); }
+
+  void addForce (dReal fx, dReal fy, dReal fz)
+    { dBodyAddForce (_id, fx, fy, fz); }
+  void addTorque (dReal fx, dReal fy, dReal fz)
+    { dBodyAddTorque (_id, fx, fy, fz); }
+  void addRelForce (dReal fx, dReal fy, dReal fz)
+    { dBodyAddRelForce (_id, fx, fy, fz); }
+  void addRelTorque (dReal fx, dReal fy, dReal fz)
+    { dBodyAddRelTorque (_id, fx, fy, fz); }
+  void addForceAtPos (dReal fx, dReal fy, dReal fz,
+                     dReal px, dReal py, dReal pz)
+    { dBodyAddForceAtPos (_id, fx, fy, fz, px, py, pz); }
+  void addForceAtRelPos (dReal fx, dReal fy, dReal fz,
+                     dReal px, dReal py, dReal pz)
+    { dBodyAddForceAtRelPos (_id, fx, fy, fz, px, py, pz); }
+  void addRelForceAtPos (dReal fx, dReal fy, dReal fz,
+                        dReal px, dReal py, dReal pz)
+    { dBodyAddRelForceAtPos (_id, fx, fy, fz, px, py, pz); }
+  void addRelForceAtRelPos (dReal fx, dReal fy, dReal fz,
+                           dReal px, dReal py, dReal pz)
+    { dBodyAddRelForceAtRelPos (_id, fx, fy, fz, px, py, pz); }
+
+  const dReal * getForce() const
+    { return dBodyGetForce(_id); }
+  const dReal * getTorque() const
+    { return dBodyGetTorque(_id); }
+  void setForce (dReal x, dReal y, dReal z)
+    { dBodySetForce (_id,x,y,z); }
+  void setTorque (dReal x, dReal y, dReal z)
+    { dBodySetTorque (_id,x,y,z); }
+
+  void enable()
+    { dBodyEnable (_id); }
+  void disable()
+    { dBodyDisable (_id); }
+  int isEnabled() const
+    { return dBodyIsEnabled (_id); }
+
+  void getRelPointPos (dReal px, dReal py, dReal pz, dVector3 result) const
+    { dBodyGetRelPointPos (_id, px, py, pz, result); }
+  void getRelPointVel (dReal px, dReal py, dReal pz, dVector3 result) const
+    { dBodyGetRelPointVel (_id, px, py, pz, result); }
+  void getPointVel (dReal px, dReal py, dReal pz, dVector3 result) const
+    { dBodyGetPointVel (_id,px,py,pz,result); }
+  void getPosRelPoint (dReal px, dReal py, dReal pz, dVector3 result) const
+    { dBodyGetPosRelPoint (_id,px,py,pz,result); }
+  void vectorToWorld (dReal px, dReal py, dReal pz, dVector3 result) const
+    { dBodyVectorToWorld (_id,px,py,pz,result); }
+  void vectorFromWorld (dReal px, dReal py, dReal pz, dVector3 result) const
+    { dBodyVectorFromWorld (_id,px,py,pz,result); }
+
+  void setFiniteRotationMode (int mode)
+    { dBodySetFiniteRotationMode (_id, mode); }
+  void setFiniteRotationAxis (dReal x, dReal y, dReal z)
+    { dBodySetFiniteRotationAxis (_id, x, y, z); }
+
+  int getFiniteRotationMode() const
+    { return dBodyGetFiniteRotationMode (_id); }
+  void getFiniteRotationAxis (dVector3 result) const
+    { dBodyGetFiniteRotationAxis (_id, result); }
+
+  int getNumJoints() const
+    { return dBodyGetNumJoints (_id); }
+  dJointID getJoint (int index) const
+    { return dBodyGetJoint (_id, index); }
+
+  void setGravityMode (int mode)
+    { dBodySetGravityMode (_id,mode); }
+  int getGravityMode() const
+    { return dBodyGetGravityMode (_id); }
+
+  int isConnectedTo (dBodyID body) const
+    { return dAreConnected (_id, body); }
+};
+
+
+class dJointGroup {
+  dJointGroupID _id;
+
+  // intentionally undefined, don't use these
+  dJointGroup (const dJointGroup &);
+  void operator= (const dJointGroup &);
+
+public:
+  dJointGroup (int dummy_arg=0)
+    { _id = dJointGroupCreate (0); }
+  ~dJointGroup()
+    { dJointGroupDestroy (_id); }
+  void create (int dummy_arg=0) {
+    if (_id) dJointGroupDestroy (_id);
+    _id = dJointGroupCreate (0);
+  }
+
+  dJointGroupID id() const
+    { return _id; }
+  operator dJointGroupID() const
+    { return _id; }
+
+  void empty()
+    { dJointGroupEmpty (_id); }
+};
+
+
+class dJoint {
+private:
+  // intentionally undefined, don't use these
+  dJoint (const dJoint &) ;
+  void operator= (const dJoint &);
+
+protected:
+  dJointID _id;
+
+public:
+  dJoint()
+    { _id = 0; }
+  ~dJoint()
+    { if (_id) dJointDestroy (_id); }
+
+  dJointID id() const
+    { return _id; }
+  operator dJointID() const
+    { return _id; }
+
+  void attach (dBodyID body1, dBodyID body2)
+    { dJointAttach (_id, body1, body2); }
+
+  void setData (void *data)
+    { dJointSetData (_id, data); }
+  void *getData (void *data) const
+    { return dJointGetData (_id); }
+
+  int getType() const
+    { return dJointGetType (_id); }
+
+  dBodyID getBody (int index) const
+    { return dJointGetBody (_id, index); }
+};
+
+
+class dBallJoint : public dJoint {
+private:
+  // intentionally undefined, don't use these
+  dBallJoint (const dBallJoint &);
+  void operator= (const dBallJoint &);
+
+public:
+  dBallJoint() { }
+  dBallJoint (dWorldID world, dJointGroupID group=0)
+    { _id = dJointCreateBall (world, group); }
+
+  void create (dWorldID world, dJointGroupID group=0) {
+    if (_id) dJointDestroy (_id);
+    _id = dJointCreateBall (world, group);
+  }
+
+  void setAnchor (dReal x, dReal y, dReal z)
+    { dJointSetBallAnchor (_id, x, y, z); }
+  void getAnchor (dVector3 result) const
+    { dJointGetBallAnchor (_id, result); }
+} ;
+
+
+class dHingeJoint : public dJoint {
+  // intentionally undefined, don't use these
+  dHingeJoint (const dHingeJoint &);
+  void operator = (const dHingeJoint &);
+
+public:
+  dHingeJoint() { }
+  dHingeJoint (dWorldID world, dJointGroupID group=0)
+    { _id = dJointCreateHinge (world, group); }
+
+  void create (dWorldID world, dJointGroupID group=0) {
+    if (_id) dJointDestroy (_id);
+    _id = dJointCreateHinge (world, group);
+  }
+
+  void setAnchor (dReal x, dReal y, dReal z)
+    { dJointSetHingeAnchor (_id, x, y, z); }
+  void getAnchor (dVector3 result) const
+    { dJointGetHingeAnchor (_id, result); }
+
+  void setAxis (dReal x, dReal y, dReal z)
+    { dJointSetHingeAxis (_id, x, y, z); }
+  void getAxis (dVector3 result) const
+    { dJointGetHingeAxis (_id, result); }
+
+  dReal getAngle() const
+    { return dJointGetHingeAngle (_id); }
+  dReal getAngleRate() const
+    { return dJointGetHingeAngleRate (_id); }
+
+  void setParam (int parameter, dReal value)
+    { dJointSetHingeParam (_id, parameter, value); }
+  dReal getParam (int parameter) const
+    { return dJointGetHingeParam (_id, parameter); }
+};
+
+
+class dSliderJoint : public dJoint {
+  // intentionally undefined, don't use these
+  dSliderJoint (const dSliderJoint &);
+  void operator = (const dSliderJoint &);
+
+public:
+  dSliderJoint() { }
+  dSliderJoint (dWorldID world, dJointGroupID group=0)
+    { _id = dJointCreateSlider (world, group); }
+
+  void create (dWorldID world, dJointGroupID group=0) {
+    if (_id) dJointDestroy (_id);
+    _id = dJointCreateSlider (world, group);
+  }
+
+  void setAxis (dReal x, dReal y, dReal z)
+    { dJointSetSliderAxis (_id, x, y, z); }
+  void getAxis (dVector3 result) const
+    { dJointGetSliderAxis (_id, result); }
+
+  dReal getPosition() const
+    { return dJointGetSliderPosition (_id); }
+  dReal getPositionRate() const
+    { return dJointGetSliderPositionRate (_id); }
+
+  void setParam (int parameter, dReal value)
+    { dJointSetSliderParam (_id, parameter, value); }
+  dReal getParam (int parameter) const
+    { return dJointGetSliderParam (_id, parameter); }
+};
+
+
+class dUniversalJoint : public dJoint {
+  // intentionally undefined, don't use these
+  dUniversalJoint (const dUniversalJoint &);
+  void operator = (const dUniversalJoint &);
+
+public:
+  dUniversalJoint() { }
+  dUniversalJoint (dWorldID world, dJointGroupID group=0)
+    { _id = dJointCreateUniversal (world, group); }
+
+  void create (dWorldID world, dJointGroupID group=0) {
+    if (_id) dJointDestroy (_id);
+    _id = dJointCreateUniversal (world, group);
+  }
+
+  void setAnchor (dReal x, dReal y, dReal z)
+    { dJointSetUniversalAnchor (_id, x, y, z); }
+  void setAxis1 (dReal x, dReal y, dReal z)
+    { dJointSetUniversalAxis1 (_id, x, y, z); }
+  void setAxis2 (dReal x, dReal y, dReal z)
+    { dJointSetUniversalAxis2 (_id, x, y, z); }
+
+  void getAnchor (dVector3 result) const
+    { dJointGetUniversalAnchor (_id, result); }
+  void getAxis1 (dVector3 result) const
+    { dJointGetUniversalAxis1 (_id, result); }
+  void getAxis2 (dVector3 result) const
+    { dJointGetUniversalAxis2 (_id, result); }
+};
+
+
+class dHinge2Joint : public dJoint {
+  // intentionally undefined, don't use these
+  dHinge2Joint (const dHinge2Joint &);
+  void operator = (const dHinge2Joint &);
+
+public:
+  dHinge2Joint() { }
+  dHinge2Joint (dWorldID world, dJointGroupID group=0)
+    { _id = dJointCreateHinge2 (world, group); }
+
+  void create (dWorldID world, dJointGroupID group=0) {
+    if (_id) dJointDestroy (_id);
+    _id = dJointCreateHinge2 (world, group);
+  }
+
+  void setAnchor (dReal x, dReal y, dReal z)
+    { dJointSetHinge2Anchor (_id, x, y, z); }
+  void setAxis1 (dReal x, dReal y, dReal z)
+    { dJointSetHinge2Axis1 (_id, x, y, z); }
+  void setAxis2 (dReal x, dReal y, dReal z)
+    { dJointSetHinge2Axis2 (_id, x, y, z); }
+
+  void getAnchor (dVector3 result) const
+    { dJointGetHinge2Anchor (_id, result); }
+  void getAxis1 (dVector3 result) const
+    { dJointGetHinge2Axis1 (_id, result); }
+  void getAxis2 (dVector3 result) const
+    { dJointGetHinge2Axis2 (_id, result); }
+
+  dReal getAngle1() const
+    { return dJointGetHinge2Angle1 (_id); }
+  dReal getAngle1Rate() const
+    { return dJointGetHinge2Angle1Rate (_id); }
+  dReal getAngle2Rate() const
+    { return dJointGetHinge2Angle2Rate (_id); }
+
+  void setParam (int parameter, dReal value)
+    { dJointSetHinge2Param (_id, parameter, value); }
+  dReal getParam (int parameter) const
+    { return dJointGetHinge2Param (_id, parameter); }
+};
+
+
+class dFixedJoint : public dJoint {
+  // intentionally undefined, don't use these
+  dFixedJoint (const dFixedJoint &);
+  void operator = (const dFixedJoint &);
+
+public:
+  dFixedJoint() { }
+  dFixedJoint (dWorldID world, dJointGroupID group=0)
+    { _id = dJointCreateFixed (world, group); }
+
+  void create (dWorldID world, dJointGroupID group=0) {
+    if (_id) dJointDestroy (_id);
+    _id = dJointCreateFixed (world, group);
+  }
+
+  void set()
+    { dJointSetFixed (_id); }
+};
+
+
+class dContactJoint : public dJoint {
+  // intentionally undefined, don't use these
+  dContactJoint (const dContactJoint &);
+  void operator = (const dContactJoint &);
+
+public:
+  dContactJoint() { }
+  dContactJoint (dWorldID world, dJointGroupID group, dContact *contact)
+    { _id = dJointCreateContact (world, group, contact); }
+
+  void create (dWorldID world, dJointGroupID group, dContact *contact) {
+    if (_id) dJointDestroy (_id);
+    _id = dJointCreateContact (world, group, contact);
+  }
+};
+
+
+class dNullJoint : public dJoint {
+  // intentionally undefined, don't use these
+  dNullJoint (const dNullJoint &);
+  void operator = (const dNullJoint &);
+
+public:
+  dNullJoint() { }
+  dNullJoint (dWorldID world, dJointGroupID group=0)
+    { _id = dJointCreateNull (world, group); }
+
+  void create (dWorldID world, dJointGroupID group=0) {
+    if (_id) dJointDestroy (_id);
+    _id = dJointCreateNull (world, group);
+  }
+};
+
+
+class dAMotorJoint : public dJoint {
+  // intentionally undefined, don't use these
+  dAMotorJoint (const dAMotorJoint &);
+  void operator = (const dAMotorJoint &);
+
+public:
+  dAMotorJoint() { }
+  dAMotorJoint (dWorldID world, dJointGroupID group=0)
+    { _id = dJointCreateAMotor (world, group); }
+
+  void create (dWorldID world, dJointGroupID group=0) {
+    if (_id) dJointDestroy (_id);
+    _id = dJointCreateAMotor (world, group);
+  }
+
+  void setMode (int mode)
+    { dJointSetAMotorMode (_id, mode); }
+  int getMode() const
+    { return dJointGetAMotorMode (_id); }
+
+  void setNumAxes (int num)
+    { dJointSetAMotorNumAxes (_id, num); }
+  int getNumAxes() const
+    { return dJointGetAMotorNumAxes (_id); }
+
+  void setAxis (int anum, int rel, dReal x, dReal y, dReal z)
+    { dJointSetAMotorAxis (_id, anum, rel, x, y, z); }
+  void getAxis (int anum, dVector3 result) const
+    { dJointGetAMotorAxis (_id, anum, result); }
+  int getAxisRel (int anum) const
+    { return dJointGetAMotorAxisRel (_id, anum); }
+
+  void setAngle (int anum, dReal angle)
+    { dJointSetAMotorAngle (_id, anum, angle); }
+  dReal getAngle (int anum) const
+    { return dJointGetAMotorAngle (_id, anum); }
+  dReal getAngleRate (int anum)
+    { return dJointGetAMotorAngleRate (_id,anum); }
+
+  void setParam (int parameter, dReal value)
+    { dJointSetAMotorParam (_id, parameter, value); }
+  dReal getParam (int parameter) const
+    { return dJointGetAMotorParam (_id, parameter); }
+};
+
+
+class dGeom {
+  // intentionally undefined, don't use these
+  dGeom (dGeom &);
+  void operator= (dGeom &);
+
+protected:
+  dGeomID _id;
+
+public:
+  dGeom()
+    { _id = 0; }
+  ~dGeom()
+    { if (_id) dGeomDestroy (_id); }
+
+  dGeomID id() const
+    { return _id; }
+  operator dGeomID() const
+    { return _id; }
+
+  void destroy() {
+    if (_id) dGeomDestroy (_id);
+    _id = 0;
+  }
+
+  int getClass() const
+    { return dGeomGetClass (_id); }
+
+  void setData (void *data)
+    { dGeomSetData (_id,data); }
+  void *getData() const
+    { return dGeomGetData (_id); }
+
+  void setBody (dBodyID b)
+    { dGeomSetBody (_id,b); }
+  dBodyID getBody() const
+    { return dGeomGetBody (_id); }
+
+  void setPosition (dReal x, dReal y, dReal z)
+    { dGeomSetPosition (_id,x,y,z); }
+  const dReal * getPosition() const
+    { return dGeomGetPosition (_id); }
+
+  void setRotation (const dMatrix3 R)
+    { dGeomSetRotation (_id,R); }
+  const dReal * getRotation() const
+    { return dGeomGetRotation (_id); }
+
+  void getAABB (dReal aabb[6]) const
+    { dGeomGetAABB (_id, aabb); }
+  const dReal *getSpaceAABB() const
+    { return dGeomGetSpaceAABB (_id); }
+};
+
+
+class dSpace {
+  // intentionally undefined, don't use these
+  dSpace (dSpace &);
+  void operator= (dSpace &);
+
+protected:
+  dSpaceID _id;
+
+  // the default constructor is protected so that you
+  // can't instance this class. you must instance one
+  // of its subclasses instead.
+  dSpace () { _id = 0; }
+
+public:
+  ~dSpace()
+    { dSpaceDestroy (_id); }
+
+  dSpaceID id() const
+    { return _id; }
+  operator dSpaceID() const
+    { return _id; }
+
+  void add (dGeomID x)
+    { dSpaceAdd (_id, x); }
+  void remove (dGeomID x)
+    { dSpaceRemove (_id, x); }
+  int query (dGeomID x)
+    { return dSpaceQuery (_id,x); }
+
+  void collide (void *data, dNearCallback *callback)
+    { dSpaceCollide (_id,data,callback); }
+};
+
+
+class dSimpleSpace : public dSpace {
+  // intentionally undefined, don't use these
+  dSimpleSpace (dSimpleSpace &);
+  void operator= (dSimpleSpace &);
+
+public:
+  dSimpleSpace ()
+    { _id = dSimpleSpaceCreate(); }
+};
+
+
+class dHashSpace : public dSpace {
+  // intentionally undefined, don't use these
+  dHashSpace (dHashSpace &);
+  void operator= (dHashSpace &);
+
+public:
+  dHashSpace ()
+    { _id = dHashSpaceCreate(); }
+  void setLevels (int minlevel, int maxlevel)
+    { dHashSpaceSetLevels (_id,minlevel,maxlevel); }
+};
+
+
+class dSphere : public dGeom {
+  // intentionally undefined, don't use these
+  dSphere (dSphere &);
+  void operator= (dSphere &);
+
+public:
+  dSphere () { }
+  dSphere (dSpaceID space, dReal radius)
+    { _id = dCreateSphere (space, radius); }
+
+  void create (dSpaceID space, dReal radius) {
+    if (_id) dGeomDestroy (_id);
+    _id = dCreateSphere (space, radius);
+  }
+
+  void setRadius (dReal radius)
+    { dGeomSphereSetRadius (_id, radius); }
+  dReal getRadius() const
+    { return dGeomSphereGetRadius (_id); }
+};
+
+
+class dBox : public dGeom {
+  // intentionally undefined, don't use these
+  dBox (dBox &);
+  void operator= (dBox &);
+
+public:
+  dBox () { }
+  dBox (dSpaceID space, dReal lx, dReal ly, dReal lz)
+    { _id = dCreateBox (space,lx,ly,lz); }
+
+  void create (dSpaceID space, dReal lx, dReal ly, dReal lz) {
+    if (_id) dGeomDestroy (_id);
+    _id = dCreateBox (space,lx,ly,lz);
+  }
+
+  void setLengths (dReal lx, dReal ly, dReal lz)
+    { dGeomBoxSetLengths (_id, lx, ly, lz); }
+  void getLengths (dVector3 result) const
+    { dGeomBoxGetLengths (_id,result); }
+};
+
+
+class dPlane : public dGeom {
+  // intentionally undefined, don't use these
+  dPlane (dPlane &);
+  void operator= (dPlane &);
+
+public:
+  dPlane() { }
+  dPlane (dSpaceID space, dReal a, dReal b, dReal c, dReal d)
+    { _id = dCreatePlane (space,a,b,c,d); }
+
+  void create (dSpaceID space, dReal a, dReal b, dReal c, dReal d) {
+    if (_id) dGeomDestroy (_id);
+    _id = dCreatePlane (space,a,b,c,d);
+  }
+
+  void setParams (dReal a, dReal b, dReal c, dReal d)
+    { dGeomPlaneSetParams (_id, a, b, c, d); }
+  void getParams (dVector4 result) const
+    { dGeomPlaneGetParams (_id,result); }
+};
+
+
+class dCCylinder : public dGeom {
+  // intentionally undefined, don't use these
+  dCCylinder (dCCylinder &);
+  void operator= (dCCylinder &);
+
+public:
+  dCCylinder() { }
+  dCCylinder (dSpaceID space, dReal radius, dReal length)
+    { _id = dCreateCCylinder (space,radius,length); }
+
+  void create (dSpaceID space, dReal radius, dReal length) {
+    if (_id) dGeomDestroy (_id);
+    _id = dCreateCCylinder (space,radius,length);
+  }
+
+  void setParams (dReal radius, dReal length)
+    { dGeomCCylinderSetParams (_id, radius, length); }
+  void getParams (dReal *radius, dReal *length) const
+    { dGeomCCylinderGetParams (_id,radius,length); }
+};
+
+
+class dGeomGroup : public dGeom {
+  // intentionally undefined, don't use these
+  dGeomGroup (dGeomGroup &);
+  void operator= (dGeomGroup &);
+
+public:
+  dGeomGroup() { }
+  dGeomGroup (dSpaceID space)
+    { _id = dCreateGeomGroup (space); }
+
+  void create (dSpaceID space=0) {
+    if (_id) dGeomDestroy (_id);
+    _id = dCreateGeomGroup (space);
+  }
+
+  void add (dGeomID x)
+    { dGeomGroupAdd (_id, x); }
+  void remove (dGeomID x)
+    { dGeomGroupRemove (_id, x); }
+
+  int getNumGeoms() const
+    { return dGeomGroupGetNumGeoms (_id); }
+  dGeomID getGeom (int i) const
+    { return dGeomGroupGetGeom (_id, i); }
+};
+
+
+class dGeomTransform : public dGeom {
+  // intentionally undefined, don't use these
+  dGeomTransform (dGeomTransform &);
+  void operator= (dGeomTransform &);
+
+public:
+  dGeomTransform() { }
+  dGeomTransform (dSpaceID space)
+    { _id = dCreateGeomTransform (space); }
+
+  void create (dSpaceID space=0) {
+    if (_id) dGeomDestroy (_id);
+    _id = dCreateGeomTransform (space);
+  }
+
+  void setGeom (dGeomID geom)
+    { dGeomTransformSetGeom (_id, geom); }
+  dGeomID getGeom() const
+    { return dGeomTransformGetGeom (_id); }
+
+  void setCleanup (int mode)
+    { dGeomTransformSetCleanup (_id,mode); }
+  int getCleanup (dGeomID g)
+    { return dGeomTransformGetCleanup (_id); }
+
+  void setInfo (int mode)
+    { dGeomTransformSetInfo (_id,mode); }
+  int getInfo()
+    { return dGeomTransformGetInfo (_id); }
+};
+
+
+#endif
+#endif
diff --git a/extern/ode/dist/include/ode/odecpp_old.h b/extern/ode/dist/include/ode/odecpp_old.h
new file mode 100644 (file)
index 0000000..49e7d7f
--- /dev/null
@@ -0,0 +1,316 @@
+/*************************************************************************
+ *                                                                       *
+ * 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 is the old C++ interface, the new C++ interface is not quite
+ * compatible with this. but this file is kept around in case you were
+ * using the old interface.
+ */
+
+#ifndef _ODE_ODECPP_H_
+#define _ODE_ODECPP_H_
+#ifdef __cplusplus
+
+#include <ode/error.h>
+
+
+class dWorld {
+  dWorldID _id;
+
+  dWorld (dWorld &) { dDebug (0,"bad"); }
+  void operator= (dWorld &) { dDebug (0,"bad"); }
+
+public:
+  dWorld()
+    { _id = dWorldCreate(); }
+  ~dWorld()
+    { dWorldDestroy (_id); }
+  dWorldID id()
+    { return _id; }
+
+  void setGravity (dReal x, dReal y, dReal z)
+    { dWorldSetGravity (_id,x,y,z); }
+  void getGravity (dVector3 g)
+    { dWorldGetGravity (_id,g); }
+  void step (dReal stepsize)
+    { dWorldStep (_id,stepsize); }
+};
+
+
+class dBody {
+  dBodyID _id;
+
+  dBody (dBody &) { dDebug (0,"bad"); }
+  void operator= (dBody &) { dDebug (0,"bad"); }
+
+public:
+  dBody()
+    { _id = 0; }
+  dBody (dWorld &world)
+    { _id = dBodyCreate (world.id()); }
+  ~dBody()
+    { dBodyDestroy (_id); }
+  void create (dWorld &world)
+    { if (_id) dBodyDestroy (_id); _id = dBodyCreate (world.id()); }
+  dBodyID id()
+    { return _id; }
+
+  void setData (void *data)
+    { dBodySetData (_id,data); }
+  void *getData()
+    { return dBodyGetData (_id); }
+
+  void setPosition (dReal x, dReal y, dReal z)
+    { dBodySetPosition (_id,x,y,z); }
+  void setRotation (const dMatrix3 R)
+    { dBodySetRotation (_id,R); }
+  void setQuaternion (const dQuaternion q)
+    { dBodySetQuaternion (_id,q); }
+  void setLinearVel  (dReal x, dReal y, dReal z)
+    { dBodySetLinearVel (_id,x,y,z); }
+  void setAngularVel (dReal x, dReal y, dReal z)
+    { dBodySetAngularVel (_id,x,y,z); }
+
+  const dReal * getPosition()
+    { return dBodyGetPosition (_id); }
+  const dReal * getRotation()
+    { return dBodyGetRotation (_id); }
+  const dReal * getQuaternion()
+    { return dBodyGetQuaternion (_id); }
+  const dReal * getLinearVel()
+    { return dBodyGetLinearVel (_id); }
+  const dReal * getAngularVel()
+    { return dBodyGetAngularVel (_id); }
+
+  void setMass (const dMass *mass)
+    { dBodySetMass (_id,mass); }
+  void getMass (dMass *mass)
+    { dBodyGetMass (_id,mass); }
+
+  void addForce (dReal fx, dReal fy, dReal fz)
+    { dBodyAddForce (_id, fx, fy, fz); }
+  void addTorque (dReal fx, dReal fy, dReal fz)
+    { dBodyAddTorque (_id, fx, fy, fz); }
+  void addRelForce (dReal fx, dReal fy, dReal fz)
+    { dBodyAddRelForce (_id, fx, fy, fz); }
+  void addRelTorque (dReal fx, dReal fy, dReal fz)
+    { dBodyAddRelTorque (_id, fx, fy, fz); }
+  void addForceAtPos (dReal fx, dReal fy, dReal fz,
+                     dReal px, dReal py, dReal pz)
+    { dBodyAddForceAtPos (_id, fx, fy, fz, px, py, pz); }
+  void addRelForceAtPos (dReal fx, dReal fy, dReal fz,
+                        dReal px, dReal py, dReal pz)
+    { dBodyAddRelForceAtPos (_id, fx, fy, fz, px, py, pz); }
+  void addRelForceAtRelPos (dReal fx, dReal fy, dReal fz,
+                           dReal px, dReal py, dReal pz)
+    { dBodyAddRelForceAtRelPos (_id, fx, fy, fz, px, py, pz); }
+
+  void getRelPointPos (dReal px, dReal py, dReal pz, dVector3 result)
+    { dBodyGetRelPointPos (_id, px, py, pz, result); }
+  void getRelPointVel (dReal px, dReal py, dReal pz, dVector3 result)
+    { dBodyGetRelPointVel (_id, px, py, pz, result); }
+
+  int isConnectedTo (const dBody &b)
+    { return dAreConnected (_id,b._id); }
+};
+
+
+class dJointGroup {
+  dJointGroupID _id;
+
+  dJointGroup (dJointGroup &) { dDebug (0,"bad"); }
+  void operator= (dJointGroup &) { dDebug (0,"bad"); }
+
+public:
+  dJointGroup()
+    { _id = 0; }
+  dJointGroup (int max_size)
+    { _id = dJointGroupCreate (max_size); }
+  ~dJointGroup()
+    { dJointGroupDestroy (_id); }
+  void create (int max_size)
+    { if (_id) dJointGroupDestroy (_id); _id = dJointGroupCreate (max_size); }
+  dJointGroupID id()
+    { return _id; }
+
+  void empty()
+    { dJointGroupEmpty (_id); }
+};
+
+
+class dJoint {
+  dJointID _id;
+
+  dJoint (dJoint &) { dDebug (0,"bad"); }
+  void operator= (dJoint &) { dDebug (0,"bad"); }
+
+public:
+  dJoint()
+    { _id = 0; }
+  ~dJoint()
+    { dJointDestroy (_id); }
+  dJointID id()
+    { return _id; }
+
+  void createBall (dWorld &world, dJointGroup *group=0) {
+    if (_id) dJointDestroy (_id);
+    _id = dJointCreateBall (world.id(), group ? group->id() : 0);
+  }
+  void createHinge (dWorld &world, dJointGroup *group=0) {
+    if (_id) dJointDestroy (_id);
+    _id = dJointCreateHinge (world.id(), group ? group->id() : 0);
+  }
+  void createSlider (dWorld &world, dJointGroup *group=0) {
+    if (_id) dJointDestroy (_id);
+    _id = dJointCreateSlider (world.id(), group ? group->id() : 0);
+  }
+  void createContact (dWorld &world, dJointGroup *group, dContact *contact) {
+    if (_id) dJointDestroy (_id);
+    _id = dJointCreateContact (world.id(), group ? group->id() : 0, contact);
+  }
+
+  void attach (dBody &body1, dBody &body2)
+    { dJointAttach (_id, body1.id(), body2.id()); }
+
+  void setBallAnchor (dReal x, dReal y, dReal z)
+    { dJointSetBallAnchor (_id, x, y, z); }
+  void setHingeAnchor (dReal x, dReal y, dReal z)
+    { dJointSetHingeAnchor (_id, x, y, z); }
+
+  void setHingeAxis (dReal x, dReal y, dReal z)
+    { dJointSetHingeAxis (_id, x, y, z); }
+  void setSliderAxis (dReal x, dReal y, dReal z)
+    { dJointSetSliderAxis (_id, x, y, z); }
+
+  void getBallAnchor (dVector3 result)
+    { dJointGetBallAnchor (_id, result); }
+  void getHingeAnchor (dVector3 result)
+    { dJointGetHingeAnchor (_id, result); }
+
+  void getHingeAxis (dVector3 result)
+    { dJointGetHingeAxis (_id, result); }
+  void getSliderAxis (dVector3 result)
+    { dJointGetSliderAxis (_id, result); }
+};
+
+
+class dSpace {
+  dSpaceID _id;
+
+  dSpace (dSpace &) { dDebug (0,"bad"); }
+  void operator= (dSpace &) { dDebug (0,"bad"); }
+
+public:
+  dSpace ()
+    { _id = dHashSpaceCreate(); }
+  ~dSpace()
+    { dSpaceDestroy (_id); }
+  dSpaceID id()
+    { return _id; }
+  void collide (void *data, dNearCallback *callback)
+    { dSpaceCollide (_id,data,callback); }
+};
+
+
+class dGeom {
+  dGeomID _id;
+
+  dGeom (dGeom &) { dDebug (0,"bad"); }
+  void operator= (dGeom &) { dDebug (0,"bad"); }
+
+public:
+  dGeom()
+    { _id = 0; }
+  ~dGeom()
+    { dGeomDestroy (_id); }
+  dGeomID id()
+    { return _id; }
+
+  void createSphere (dSpace &space, dReal radius) {
+    if (_id) dGeomDestroy (_id);
+    _id = dCreateSphere (space.id(),radius);
+  }
+
+  void createBox (dSpace &space, dReal lx, dReal ly, dReal lz) {
+    if (_id) dGeomDestroy (_id);
+    _id = dCreateBox (space.id(),lx,ly,lz);
+  }
+
+  void createPlane (dSpace &space, dReal a, dReal b, dReal c, dReal d) {
+    if (_id) dGeomDestroy (_id);
+    _id = dCreatePlane (space.id(),a,b,c,d);
+  }
+
+  void createCCylinder (dSpace &space, dReal radius, dReal length) {
+    if (_id) dGeomDestroy (_id);
+    _id = dCreateCCylinder (space.id(),radius,length);
+  }
+
+  void destroy() {
+    if (_id) dGeomDestroy (_id);
+    _id = 0;
+  }
+
+  int getClass()
+    { return dGeomGetClass (_id); }
+
+  dReal sphereGetRadius()
+    { return dGeomSphereGetRadius (_id); }
+
+  void boxGetLengths (dVector3 result)
+    { dGeomBoxGetLengths (_id,result); }
+
+  void planeGetParams (dVector4 result)
+    { dGeomPlaneGetParams (_id,result); }
+
+  void CCylinderGetParams (dReal *radius, dReal *length)
+    { dGeomCCylinderGetParams (_id,radius,length); }
+
+  void setData (void *data)
+    { dGeomSetData (_id,data); }
+
+  void *getData()
+    { return dGeomGetData (_id); }
+
+  void setBody (dBody &b)
+    { dGeomSetBody (_id,b.id()); }
+  void setBody (dBodyID b)
+    { dGeomSetBody (_id,b); }
+
+  dBodyID getBody()
+    { return dGeomGetBody (_id); }
+
+  void setPosition (dReal x, dReal y, dReal z)
+    { dGeomSetPosition (_id,x,y,z); }
+
+  void setRotation (const dMatrix3 R)
+    { dGeomSetRotation (_id,R); }
+
+  const dReal * getPosition()
+    { return dGeomGetPosition (_id); }
+
+  const dReal * getRotation()
+    { return dGeomGetRotation (_id); }
+};
+
+
+#endif
+#endif
diff --git a/extern/ode/dist/include/ode/odemath.h b/extern/ode/dist/include/ode/odemath.h
new file mode 100644 (file)
index 0000000..070c118
--- /dev/null
@@ -0,0 +1,216 @@
+/*************************************************************************
+ *                                                                       *
+ * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith.       *
+ * All rights reserved.  Email: russ@q12.org   Web: www.q12.org          *
+ *                                                                       *
+ * This library is free software; you can redistribute it and/or         *
+ * modify it under the terms of EITHER:                                  *
+ *   (1) The GNU Lesser General Public License as published by the Free  *
+ *       Software Foundation; either version 2.1 of the License, or (at  *
+ *       your option) any later version. The text of the GNU Lesser      *
+ *       General Public License is included with this library in the     *
+ *       file LICENSE.TXT.                                               *
+ *   (2) The BSD-style license that is included with this library in     *
+ *       the file LICENSE-BSD.TXT.                                       *
+ *                                                                       *
+ * This library is distributed in the hope that it will be useful,       *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files    *
+ * LICENSE.TXT and LICENSE-BSD.TXT for more details.                     *
+ *                                                                       *
+ *************************************************************************/
+
+#ifndef _ODE_ODEMATH_H_
+#define _ODE_ODEMATH_H_
+
+#include <ode/common.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/* 3-way dot product. dDOTpq means that elements of `a' and `b' are spaced
+ * p and q indexes apart respectively. dDOT() means dDOT11.
+ */
+
+#ifdef __cplusplus
+inline dReal dDOT (const dReal *a, const dReal *b)
+  { return ((a)[0]*(b)[0] + (a)[1]*(b)[1] + (a)[2]*(b)[2]); }
+inline dReal dDOT14(const dReal *a, const dReal *b)
+  { return ((a)[0]*(b)[0] + (a)[1]*(b)[4] + (a)[2]*(b)[8]); }
+inline dReal dDOT41(const dReal *a, const dReal *b)
+  { return ((a)[0]*(b)[0] + (a)[4]*(b)[1] + (a)[8]*(b)[2]); }
+inline dReal dDOT44(const dReal *a, const dReal *b)
+  { return ((a)[0]*(b)[0] + (a)[4]*(b)[4] + (a)[8]*(b)[8]); }
+#else
+#define dDOT(a,b)   ((a)[0]*(b)[0] + (a)[1]*(b)[1] + (a)[2]*(b)[2])
+#define dDOT14(a,b) ((a)[0]*(b)[0] + (a)[1]*(b)[4] + (a)[2]*(b)[8])
+#define dDOT41(a,b) ((a)[0]*(b)[0] + (a)[4]*(b)[1] + (a)[8]*(b)[2])
+#define dDOT44(a,b) ((a)[0]*(b)[0] + (a)[4]*(b)[4] + (a)[8]*(b)[8])
+#endif
+
+
+/* cross product, set a = b x c. dCROSSpqr means that elements of `a', `b'
+ * and `c' are spaced p, q and r indexes apart respectively.
+ * dCROSS() means dCROSS111. `op' is normally `=', but you can set it to
+ * +=, -= etc to get other effects.
+ */
+
+#define dCROSS(a,op,b,c) \
+  (a)[0] op ((b)[1]*(c)[2] - (b)[2]*(c)[1]); \
+  (a)[1] op ((b)[2]*(c)[0] - (b)[0]*(c)[2]); \
+  (a)[2] op ((b)[0]*(c)[1] - (b)[1]*(c)[0]);
+#define dCROSSpqr(a,op,b,c,p,q,r) \
+  (a)[  0] op ((b)[  q]*(c)[2*r] - (b)[2*q]*(c)[  r]); \
+  (a)[  p] op ((b)[2*q]*(c)[  0] - (b)[  0]*(c)[2*r]); \
+  (a)[2*p] op ((b)[  0]*(c)[  r] - (b)[  q]*(c)[  0]);
+#define dCROSS114(a,op,b,c) dCROSSpqr(a,op,b,c,1,1,4)
+#define dCROSS141(a,op,b,c) dCROSSpqr(a,op,b,c,1,4,1)
+#define dCROSS144(a,op,b,c) dCROSSpqr(a,op,b,c,1,4,4)
+#define dCROSS411(a,op,b,c) dCROSSpqr(a,op,b,c,4,1,1)
+#define dCROSS414(a,op,b,c) dCROSSpqr(a,op,b,c,4,1,4)
+#define dCROSS441(a,op,b,c) dCROSSpqr(a,op,b,c,4,4,1)
+#define dCROSS444(a,op,b,c) dCROSSpqr(a,op,b,c,4,4,4)
+
+
+/* set a 3x3 submatrix of A to a matrix such that submatrix(A)*b = a x b.
+ * A is stored by rows, and has `skip' elements per row. the matrix is
+ * assumed to be already zero, so this does not write zero elements!
+ * if (plus,minus) is (+,-) then a positive version will be written.
+ * if (plus,minus) is (-,+) then a negative version will be written.
+ */
+
+#define dCROSSMAT(A,a,skip,plus,minus) \
+  (A)[1] = minus (a)[2]; \
+  (A)[2] = plus (a)[1]; \
+  (A)[(skip)+0] = plus (a)[2]; \
+  (A)[(skip)+2] = minus (a)[0]; \
+  (A)[2*(skip)+0] = minus (a)[1]; \
+  (A)[2*(skip)+1] = plus (a)[0];
+
+
+/* compute the distance between two 3-vectors (oops, C++!) */
+#ifdef __cplusplus
+inline dReal dDISTANCE (const dVector3 a, const dVector3 b)
+  { return dSqrt( (a[0]-b[0])*(a[0]-b[0]) + (a[1]-b[1])*(a[1]-b[1]) +
+                  (a[2]-b[2])*(a[2]-b[2]) ); }
+#else
+#define dDISTANCE(a,b) \
+ (dSqrt( ((a)[0]-(b)[0])*((a)[0]-(b)[0]) + ((a)[1]-(b)[1])*((a)[1]-(b)[1]) + \
+        ((a)[2]-(b)[2])*((a)[2]-(b)[2]) ))
+#endif
+
+
+/* normalize 3x1 and 4x1 vectors (i.e. scale them to unit length) */
+void dNormalize3 (dVector3 a);
+void dNormalize4 (dVector4 a);
+
+
+/* given a unit length "normal" vector n, generate vectors p and q vectors
+ * that are an orthonormal basis for the plane space perpendicular to n.
+ * i.e. this makes p,q such that n,p,q are all perpendicular to each other.
+ * q will equal n x p. if n is not unit length then p will be unit length but
+ * q wont be.
+ */
+
+void dPlaneSpace (const dVector3 n, dVector3 p, dVector3 q);
+
+
+/* special case matrix multipication, with operator selection */
+
+#define dMULTIPLYOP0_331(A,op,B,C) \
+  (A)[0] op dDOT((B),(C)); \
+  (A)[1] op dDOT((B+4),(C)); \
+  (A)[2] op dDOT((B+8),(C));
+#define dMULTIPLYOP1_331(A,op,B,C) \
+  (A)[0] op dDOT41((B),(C)); \
+  (A)[1] op dDOT41((B+1),(C)); \
+  (A)[2] op dDOT41((B+2),(C));
+#define dMULTIPLYOP0_133(A,op,B,C) \
+  (A)[0] op dDOT14((B),(C)); \
+  (A)[1] op dDOT14((B),(C+1)); \
+  (A)[2] op dDOT14((B),(C+2));
+#define dMULTIPLYOP0_333(A,op,B,C) \
+  (A)[0] op dDOT14((B),(C)); \
+  (A)[1] op dDOT14((B),(C+1)); \
+  (A)[2] op dDOT14((B),(C+2)); \
+  (A)[4] op dDOT14((B+4),(C)); \
+  (A)[5] op dDOT14((B+4),(C+1)); \
+  (A)[6] op dDOT14((B+4),(C+2)); \
+  (A)[8] op dDOT14((B+8),(C)); \
+  (A)[9] op dDOT14((B+8),(C+1)); \
+  (A)[10] op dDOT14((B+8),(C+2));
+#define dMULTIPLYOP1_333(A,op,B,C) \
+  (A)[0] op dDOT44((B),(C)); \
+  (A)[1] op dDOT44((B),(C+1)); \
+  (A)[2] op dDOT44((B),(C+2)); \
+  (A)[4] op dDOT44((B+1),(C)); \
+  (A)[5] op dDOT44((B+1),(C+1)); \
+  (A)[6] op dDOT44((B+1),(C+2)); \
+  (A)[8] op dDOT44((B+2),(C)); \
+  (A)[9] op dDOT44((B+2),(C+1)); \
+  (A)[10] op dDOT44((B+2),(C+2));
+#define dMULTIPLYOP2_333(A,op,B,C) \
+  (A)[0] op dDOT((B),(C)); \
+  (A)[1] op dDOT((B),(C+4)); \
+  (A)[2] op dDOT((B),(C+8)); \
+  (A)[4] op dDOT((B+4),(C)); \
+  (A)[5] op dDOT((B+4),(C+4)); \
+  (A)[6] op dDOT((B+4),(C+8)); \
+  (A)[8] op dDOT((B+8),(C)); \
+  (A)[9] op dDOT((B+8),(C+4)); \
+  (A)[10] op dDOT((B+8),(C+8));
+
+#ifdef __cplusplus
+
+inline void dMULTIPLY0_331(dReal *A, const dReal *B, const dReal *C)
+  { dMULTIPLYOP0_331(A,=,B,C) }
+inline void dMULTIPLY1_331(dReal *A, const dReal *B, const dReal *C)
+  { dMULTIPLYOP1_331(A,=,B,C) }
+inline void dMULTIPLY0_133(dReal *A, const dReal *B, const dReal *C)
+  { dMULTIPLYOP0_133(A,=,B,C) }
+inline void dMULTIPLY0_333(dReal *A, const dReal *B, const dReal *C)
+  { dMULTIPLYOP0_333(A,=,B,C) }
+inline void dMULTIPLY1_333(dReal *A, const dReal *B, const dReal *C)
+  { dMULTIPLYOP1_333(A,=,B,C) }
+inline void dMULTIPLY2_333(dReal *A, const dReal *B, const dReal *C)
+  { dMULTIPLYOP2_333(A,=,B,C) }
+
+inline void dMULTIPLYADD0_331(dReal *A, const dReal *B, const dReal *C)
+  { dMULTIPLYOP0_331(A,+=,B,C) }
+inline void dMULTIPLYADD1_331(dReal *A, const dReal *B, const dReal *C)
+  { dMULTIPLYOP1_331(A,+=,B,C) }
+inline void dMULTIPLYADD0_133(dReal *A, const dReal *B, const dReal *C)
+  { dMULTIPLYOP0_133(A,+=,B,C) }
+inline void dMULTIPLYADD0_333(dReal *A, const dReal *B, const dReal *C)
+  { dMULTIPLYOP0_333(A,+=,B,C) }
+inline void dMULTIPLYADD1_333(dReal *A, const dReal *B, const dReal *C)
+  { dMULTIPLYOP1_333(A,+=,B,C) }
+inline void dMULTIPLYADD2_333(dReal *A, const dReal *B, const dReal *C)
+  { dMULTIPLYOP2_333(A,+=,B,C) }
+
+#else
+
+#define dMULTIPLY0_331(A,B,C) dMULTIPLYOP0_331(A,=,B,C)
+#define dMULTIPLY1_331(A,B,C) dMULTIPLYOP1_331(A,=,B,C)
+#define dMULTIPLY0_133(A,B,C) dMULTIPLYOP0_133(A,=,B,C)
+#define dMULTIPLY0_333(A,B,C) dMULTIPLYOP0_333(A,=,B,C)
+#define dMULTIPLY1_333(A,B,C) dMULTIPLYOP1_333(A,=,B,C)
+#define dMULTIPLY2_333(A,B,C) dMULTIPLYOP2_333(A,=,B,C)
+
+#define dMULTIPLYADD0_331(A,B,C) dMULTIPLYOP0_331(A,+=,B,C)
+#define dMULTIPLYADD1_331(A,B,C) dMULTIPLYOP1_331(A,+=,B,C)
+#define dMULTIPLYADD0_133(A,B,C) dMULTIPLYOP0_133(A,+=,B,C)
+#define dMULTIPLYADD0_333(A,B,C) dMULTIPLYOP0_333(A,+=,B,C)
+#define dMULTIPLYADD1_333(A,B,C) dMULTIPLYOP1_333(A,+=,B,C)
+#define dMULTIPLYADD2_333(A,B,C) dMULTIPLYOP2_333(A,+=,B,C)
+
+#endif
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/extern/ode/dist/include/ode/rotation.h b/extern/ode/dist/include/ode/rotation.h
new file mode 100644 (file)
index 0000000..26df94d
--- /dev/null
@@ -0,0 +1,64 @@
+/*************************************************************************
+ *                                                                       *
+ * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith.       *
+ * All rights reserved.  Email: russ@q12.org   Web: www.q12.org          *
+ *                                                                       *
+ * This library is free software; you can redistribute it and/or         *
+ * modify it under the terms of EITHER:                                  *
+ *   (1) The GNU Lesser General Public License as published by the Free  *
+ *       Software Foundation; either version 2.1 of the License, or (at  *
+ *       your option) any later version. The text of the GNU Lesser      *
+ *       General Public License is included with this library in the     *
+ *       file LICENSE.TXT.                                               *
+ *   (2) The BSD-style license that is included with this library in     *
+ *       the file LICENSE-BSD.TXT.                                       *
+ *                                                                       *
+ * This library is distributed in the hope that it will be useful,       *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files    *
+ * LICENSE.TXT and LICENSE-BSD.TXT for more details.                     *
+ *                                                                       *
+ *************************************************************************/
+
+#ifndef _ODE_ROTATION_H_
+#define _ODE_ROTATION_H_
+
+#include <ode/common.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+void dRSetIdentity (dMatrix3 R);
+
+void dRFromAxisAndAngle (dMatrix3 R, dReal ax, dReal ay, dReal az,
+                        dReal angle);
+
+void dRFromEulerAngles (dMatrix3 R, dReal phi, dReal theta, dReal psi);
+
+void dRFrom2Axes (dMatrix3 R, dReal ax, dReal ay, dReal az,
+                 dReal bx, dReal by, dReal bz);
+
+void dQSetIdentity (dQuaternion q);
+
+void dQFromAxisAndAngle (dQuaternion q, dReal ax, dReal ay, dReal az,
+                        dReal angle);
+
+void dQMultiply0 (dQuaternion qa, const dQuaternion qb, const dQuaternion qc);
+void dQMultiply1 (dQuaternion qa, const dQuaternion qb, const dQuaternion qc);
+void dQMultiply2 (dQuaternion qa, const dQuaternion qb, const dQuaternion qc);
+void dQMultiply3 (dQuaternion qa, const dQuaternion qb, const dQuaternion qc);
+
+void dQtoR (const dQuaternion q, dMatrix3 R);
+
+void dRtoQ (const dMatrix3 R, dQuaternion q);
+
+void dWtoDQ (const dVector3 w, const dQuaternion q, dVector4 dq);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/extern/ode/dist/include/ode/space.h b/extern/ode/dist/include/ode/space.h
new file mode 100644 (file)
index 0000000..21107fe
--- /dev/null
@@ -0,0 +1,77 @@
+/*************************************************************************
+ *                                                                       *
+ * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith.       *
+ * All rights reserved.  Email: russ@q12.org   Web: www.q12.org          *
+ *                                                                       *
+ * This library is free software; you can redistribute it and/or         *
+ * modify it under the terms of EITHER:                                  *
+ *   (1) The GNU Lesser General Public License as published by the Free  *
+ *       Software Foundation; either version 2.1 of the License, or (at  *
+ *       your option) any later version. The text of the GNU Lesser      *
+ *       General Public License is included with this library in the     *
+ *       file LICENSE.TXT.                                               *
+ *   (2) The BSD-style license that is included with this library in     *
+ *       the file LICENSE-BSD.TXT.                                       *
+ *                                                                       *
+ * This library is distributed in the hope that it will be useful,       *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files    *
+ * LICENSE.TXT and LICENSE-BSD.TXT for more details.                     *
+ *                                                                       *
+ *************************************************************************/
+
+#ifndef _ODE_SPACE_H_
+#define _ODE_SPACE_H_
+
+#include <ode/common.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct dContactGeom;
+
+typedef void dNearCallback (void *data, dGeomID o1, dGeomID o2);
+
+
+/* extra information the space needs in every geometry object */
+
+typedef struct dGeomSpaceData {
+  dGeomID next;
+} dGeomSpaceData;
+
+
+dSpaceID dSimpleSpaceCreate();
+dSpaceID dHashSpaceCreate();
+
+void dSpaceDestroy (dSpaceID);
+void dSpaceAdd (dSpaceID, dGeomID);
+void dSpaceRemove (dSpaceID, dGeomID);
+void dSpaceCollide (dSpaceID space, void *data, dNearCallback *callback);
+int dSpaceQuery (dSpaceID, dGeomID);
+
+void dHashSpaceSetLevels (dSpaceID space, int minlevel, int maxlevel);
+
+
+/* @@@ NOT FLEXIBLE ENOUGH
+ *
+ * generate contacts for those objects in the space that touch each other.
+ * an array of contacts is created on the alternative stack using
+ * StackAlloc(), and a pointer to the array is returned. the size of the
+ * array is returned by the function.
+ */
+/* int dSpaceCollide (dSpaceID space, dContactGeom **contact_array); */
+
+
+/* HMMMMM... i dont think so.
+ * tell the space that an object has moved, so its representation in the
+ * space should be changed.
+ */
+/* void dSpaceObjectMoved (dSpaceID, dGeomID); */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/extern/ode/dist/include/ode/timer.h b/extern/ode/dist/include/ode/timer.h
new file mode 100644 (file)
index 0000000..dcae5b5
--- /dev/null
@@ -0,0 +1,76 @@
+/*************************************************************************
+ *                                                                       *
+ * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith.       *
+ * All rights reserved.  Email: russ@q12.org   Web: www.q12.org          *
+ *                                                                       *
+ * This library is free software; you can redistribute it and/or         *
+ * modify it under the terms of EITHER:                                  *
+ *   (1) The GNU Lesser General Public License as published by the Free  *
+ *       Software Foundation; either version 2.1 of the License, or (at  *
+ *       your option) any later version. The text of the GNU Lesser      *
+ *       General Public License is included with this library in the     *
+ *       file LICENSE.TXT.                                               *
+ *   (2) The BSD-style license that is included with this library in     *
+ *       the file LICENSE-BSD.TXT.                                       *
+ *                                                                       *
+ * This library is distributed in the hope that it will be useful,       *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files    *
+ * LICENSE.TXT and LICENSE-BSD.TXT for more details.                     *
+ *                                                                       *
+ *************************************************************************/
+
+#ifndef _ODE_TIMER_H_
+#define _ODE_TIMER_H_
+
+#include <ode/config.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/* stop watch objects */
+
+typedef struct dStopwatch {
+  double time;                 /* total clock count */
+  unsigned long cc[2];         /* clock count since last `start' */
+} dStopwatch;
+
+void dStopwatchReset (dStopwatch *);
+void dStopwatchStart (dStopwatch *);
+void dStopwatchStop  (dStopwatch *);
+double dStopwatchTime (dStopwatch *);  /* returns total time in secs */
+
+
+/* code timers */
+
+void dTimerStart (const char *description);    /* pass a static string here */
+void dTimerNow (const char *description);      /* pass a static string here */
+void dTimerEnd();
+
+/* print out a timer report. if `average' is nonzero, print out the average
+ * time for each slot (this is only meaningful if the same start-now-end
+ * calls are being made repeatedly.
+ */
+void dTimerReport (FILE *fout, int average);
+
+
+/* resolution */
+
+/* returns the timer ticks per second implied by the timing hardware or API.
+ * the actual timer resolution may not be this great.
+ */
+double dTimerTicksPerSecond();
+
+/* returns an estimate of the actual timer resolution, in seconds. this may
+ * be greater than 1/ticks_per_second.
+ */
+double dTimerResolution();
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/extern/ode/dist/ode/README b/extern/ode/dist/ode/README
new file mode 100644 (file)
index 0000000..dd4596f
--- /dev/null
@@ -0,0 +1,158 @@
+Dynamics Library.
+=================
+
+CONVENTIONS
+-----------
+
+matrix storage
+--------------
+
+matrix operations like factorization are expensive, so we must store the data
+in a way that is most useful to the matrix code. we want the ability to update
+the dynamics library without recompiling applications, e.g. so users can take
+advantage of new floating point hardware. so we must settle on a single
+format. because of the prevalence of 4-way SIMD, the format is this: store
+the matrix by rows or columns, and each column is rounded up to a multiple of
+4 elements. the extra "padding" elements at the end of each row/column are set
+to 0. this is called the "standard format". to indicate if the data is stored
+by rows or columns, we will say "standard row format" or "standard column
+format". hopefully this decision will remain good in the future, as more and
+more processors have 4-way SIMD, and 3D graphics always needs fast 4x4
+matrices.
+
+exception: matrices that have only one column or row (vectors), are always
+stored as consecutive elements in standard row format, i.e. there is no
+interior padding, only padding at the end.
+
+thus: all 3x1 floating point vectors are stored as 4x1 vectors: (x,x,x,0).
+also: all 6x1 spatial velocities and accelerations are split into 3x1 position
+  and angular components, which are stored as contiguous 4x1 vectors.
+
+ALL matrices are stored by in standard row format.
+
+
+arguments
+---------
+
+3x1 vector arguments to set() functions are supplied as x,y,z.
+3x1 vector result arguments to get() function are pointers to arrays.
+larger vectors are always supplied and returned as pointers.
+all coordinates are in the global frame except where otherwise specified.
+output-only arguments are usually supplied at the end.
+
+
+memory allocation
+-----------------
+
+with many C/C++ libraries memory allocation is a difficult problem to solve.
+who allocates the memory? who frees it? must objects go on the heap or can
+they go on the stack or in static storage? to provide the maximum flexibility,
+the dynamics and collision libraries do not do their own memory allocation.
+you must pass in pointers to externally allocated chunks of the right sizes.
+the body, joint and colllision object structures are all exported, so you
+can make instances of those structure and pass pointers to them.
+
+there are helper functions which allocate objects out of areans, in case you
+need loots of dynamic creation and deletion.
+
+BUT!!! this ties us down to the body/joint/collision representation.
+
+a better approach is to supply custom memory allocation functions
+(e.g. dlAlloc() etc).
+
+
+C versus C++ ... ?
+------------------
+
+everything should be C linkable, and there should be C header files for
+everything. but we want to develop in C++. so do this:
+  * all comments are "//". automatically convert to /**/ for distribution.
+  * structures derived from other structures --> automatically convert?
+
+
+WORLDS
+------
+
+might want better terminology here.
+
+the dynamics world (DWorld) is a list of systems. each system corresponds to
+one or more bodies, or perhaps some other kinds of physical object.
+each system corresponds to one or more objects in the collision world
+(there does not have to be a one-to-one correspondence between bodies and
+collision objects).
+
+systems are simulated separately, perhaps using completely different
+techniques. we must do something special when systems collide.
+systems collide when collision objects belonging to system A touch
+collision objects belonging to system B.
+
+for each collision point, the system must provide matrix equation data
+that is used to compute collision forces. once those forces are computed,
+the system must incorporate the forces into its timestep.
+PROBLEM: what if we intertwine the LCP problems of the two systems - then
+this simple approach wont work.
+
+the dynamics world contains two kinds of objects: bodies and joints.
+joints connect two bodies together.
+
+the world contains one of more partitions. each partition is a collection of
+bodies and joints such that each body is attached (through one or more joints)
+to every other body.
+
+Joints
+------
+
+a joint can be connected to one or two bodies.
+if the joint is only connected to one body, joint.node[1].body == 0.
+joint.node[0].body is always valid.
+
+
+Linkage
+-------
+
+this library will always be statically linked with the app, for these reasons:
+  * collision space is selected at compile time, it adds data to the geom
+    objects.
+
+
+Optimization
+------------
+
+doubles must be aligned on 8 byte boundaries!
+
+
+MinGW on Windows issues
+-----------------------
+
+* the .rc file for drawstuff needs a different include, try winresrc.h.
+
+* it seems we can't have both main() and WinMain() without the entry point
+  defaulting to main() and having resource loading problems. this screws up
+  what i was trying to do in the drawstuff library. perhaps main2() ?
+
+* remember to compile resources to COFF format RES files.
+
+
+
+Collision
+---------
+
+to plug in your own collision handling, replace (some of?) these functions
+with your own. collision should be a separate library that you can link in
+or not. your own library can call components in this collision library, e.g.
+if you want polymorphic spaces instead of a single statically called space.
+
+creating an object will automatically register the appropriate
+class (if necessary). how can we ensure that the minimum amount of code is
+linked in? e.g. only one space handler, and sphere-sphere and sphere-box and
+box-box collision code (if spheres and boxes instanced).
+
+the user creates a collision space, and for each dynamics object that is
+created a collision object is inserted into the space. the collision
+object's pos and R pointers are set to the corresponding dynamics
+variables.
+
+there should be utility functions which create the dynamics and collision
+objects at the same time, e.g. dMakeSphere().
+
+collision objects and dynamics objects keep pointers to each other.
diff --git a/extern/ode/dist/ode/fbuild/BuildDot b/extern/ode/dist/ode/fbuild/BuildDot
new file mode 100644 (file)
index 0000000..09b4927
--- /dev/null
@@ -0,0 +1,148 @@
+#!/usr/bin/perl
+#
+#########################################################################
+#                                                                       #
+# 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.                     #
+#                                                                       #
+#########################################################################
+
+# dot product code generator.
+#
+# code generation parameters, set in a parameters file:
+#    FNAME    : name of source file to generate - a .c file will be made
+#    UNROLL1  : inner loop unrolling factor (1..)
+#    FETCH    : max num of a[i]'s and b[i]'s to load ahead of muls
+#    LAT1     : load -> mul latency (>=1)
+#    LAT2     : mul -> add latency (>=1). if this is 1, use fused mul-add
+#
+#############################################################################
+
+require ("BuildUtil");
+
+# get and check code generation parameters
+error ("Usage: BuildDot <parameters-file>") if $#ARGV != 0;
+do $ARGV[0];
+
+if (!defined($FNAME) || !defined($UNROLL1) || !defined($FETCH) ||
+    !defined($LAT1) || !defined($LAT2)) {
+  error ("code generation parameters not defined");
+}
+
+# check parameters
+error ("bad UNROLL1") if $UNROLL1 < 1;
+error ("bad FETCH") if $FETCH < 1;
+error ("bad LAT1") if $LAT1 < 1;
+error ("bad LAT2") if $LAT2 < 1;
+
+#############################################################################
+
+open (FOUT,">$FNAME.c") or die "can't open $FNAME.c for writing";
+
+# file and function header
+output (<<END);
+/* generated code, do not edit. */
+
+#include "ode/matrix.h"
+
+
+dReal dDot (const dReal *a, const dReal *b, int n)
+{
+END
+
+output ("dReal ");
+for ($i=0; $i<$UNROLL1; $i++) {
+  output ("p$i,q$i,m$i,");
+}
+output ("sum;\n");
+
+output (<<END);
+sum = 0;
+n -= $UNROLL1;
+while (n >= 0) {
+END
+
+@load = ();            # slot where a[i]'s and b[i]'s loaded
+@mul = ();             # slot where multiply i happened
+@add = ();             # slow where add i happened
+
+# in the future we may want to reduce the number of variables declared,
+# so these arrays will be useful.
+@pqused = ();          # 1 if p/q[i] loaded with data, 0 once that data's used
+@mused = ();           # 1 if m[i] loaded with data, 0 once that data's used
+@pqmap = ();           # map virtual p/q variables to actual p/q variables
+@mmap = ();            # map virtual m variables to actual m variables
+
+output ("p0 = a[0]; q0 = b[0];\n");
+push (@load,0);
+
+$slot=0;               # one slot for every load/mul/add/nop issued
+for (;;) {
+  $startslot = $slot;
+
+  # do next load
+  if (($#load - $#mul) < $FETCH && ($#load+1) < $UNROLL1) {
+    push (@load,$slot);
+    output ("p$#load = a[$#load]; q$#load = b[$#load];\n");
+    $slot++;
+  }
+  # do next multiply
+  if ($#load > $#mul && $slot >= ($load[$#mul+1] + $LAT1) &&
+      ($#mul+1) < $UNROLL1) {
+    push (@mul,$slot);
+    if ($LAT2 > 1) {
+      output ("m$#mul = p$#mul * q$#mul;\n");
+    }
+    else {
+      output ("sum += p$#mul * q$#mul;\n");
+      last if ($#mul+1) >= $UNROLL1;
+    }
+    $slot++;
+  }
+  # do next add
+  if ($LAT2 > 1) {
+    if ($#mul > $#add && $slot >= ($mul[$#add+1] + $LAT2)) {
+      push (@add,$slot);
+      output ("sum += m$#add;\n");
+      $slot++;
+      last if ($#add+1) >= $UNROLL1;
+    }
+  }
+
+  if ($slot == $startslot) {
+    # comment ("nop");
+    $slot++;
+  }
+}
+
+output ("a += $UNROLL1;\n");
+output ("b += $UNROLL1;\n");
+output ("n -= $UNROLL1;\n");
+output ("}\n");
+
+output (<<END);
+n += $UNROLL1;
+while (n > 0) {
+sum += (*a) * (*b);
+a++;
+b++;
+n--;
+}
+return sum;
+}
+END
diff --git a/extern/ode/dist/ode/fbuild/BuildLDLT b/extern/ode/dist/ode/fbuild/BuildLDLT
new file mode 100644 (file)
index 0000000..fd74faf
--- /dev/null
@@ -0,0 +1,654 @@
+#!/usr/bin/perl
+#
+#########################################################################
+#                                                                       #
+# 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.                     #
+#                                                                       #
+#########################################################################
+
+#
+# triangular matrix solver and factorizer code generator.
+#
+# SOLVER
+# ------
+#
+# if L is an n x n lower triangular matrix (with ones on the diagonal), the
+# solver solves L*X=B where X and B are n x m matrices. this is the core
+# step in L*D*L' factorization. the algorithm is (in matlab):
+#
+#     for i=1:n
+#       for j=1:m
+#         X(i,j) = B(i,j) - L(i,1:i-1)*X(1:i-1,j);
+#       end
+#     end
+#
+# note that the ordering of the (i,j) loop is somewhat arbitrary. the only
+# prerequisite to calculating element (i,j) of X is that all X(1:i-1,j) have
+# have already been calcuated. this gives us some flexibility.
+#
+# the code generated below calculates X in N1 x N1 blocks. to speed up the
+# innermost dot product loop, the outer product trick is used. for instance,
+# to calculate the value of the 2x2 matrix ABCD below we first iterate over
+# the vectors (a,b,c,d) and (e,f,g,h), computing ABCD = a*e+b*f+c*g+d*h.
+# then A and B contain the dot product values needed in the algorithm, and
+# C and D have almost all of it. the outer product trick reduces the number
+# of memory loads required. in this example 16 loads are required, but if
+# the simple dot product in the above algorithm is used then 32 loads are
+# required. increasing N1 decreases the total number of loads, but only as long
+# as we have enough temporary registers to keep the matrix blocks and vectors.
+#
+#                L                     *    X     =     B
+#
+#  [ .                               ]   [ e e ]     [ . . ]
+#  [ . .                             ]   [ f f ]     [ . . ]
+#  [ . . .                           ]   [ g g ]     [ . . ]
+#  [ . . . .                         ]   [ h h ]     [ . . ]
+#  [ a b c d .                       ]   [ A B ]  =  [ . . ]
+#  [ a b c d . .                     ]   [ C D ]     [ . . ]
+#  [ . . . . . . .                   ]   [ . . ]     [ . . ]
+#  [ . . . . . . . .                 ]   [ . . ]     [ . . ]
+#  [ . . . . . . . . .               ]   [ . . ]     [ . . ]
+#
+# note that L is stored by rows but X and B are stored by columns.
+# the outer product loops are unrolled for extra speed.
+#
+# LDLT FACTORIZATION
+# ------------------
+#
+# the factorization algorithm builds L incrementally by repeatedly solving
+# the following equation:
+#
+#   [ L  0 ] [ D 0 ] [ L' l  ] = [ A  a ]    <-- n rows
+#   [ l' e ] [ 0 d ] [ 0  e' ]   [ a' b ]    <-- m rows
+#
+#   [ L*D*L'   L*D*l         ] = [ A  a ]
+#   [ l'*D*L'  l'*D*l+e*d*e' ]   [ a' b ]
+#
+# L*D*L'=A is an existing solution, and a,b are new rows/columns to add to A.
+# we compute:
+#
+#   L * (Dl) = a
+#   l = inv(D) * Dl
+#   e*d*e' = b - l'*Dl       (m*m LDLT factorization)
+#
+#
+# L-transpose solver
+# ------------------
+#
+# the LT (L-transpose) solver uses the same logic as the standard L-solver,
+# with a few tricks to make it work. to solve L^T*X=B we first remap:
+#    L to Lhat : Lhat(i,j) = L(n-j,n-i)
+#    X to Xhat : Xhat(i) = X(n-i)
+#    B to Bhat : Bhat(i) = B(n-i)
+# and then solve Lhat*Xhat = Bhat. the current LT solver only supports one
+# right hand side, but that's okay as it is not used in the factorizer.
+#
+#############################################################################
+#
+# code generation parameters, set in a parameters file:
+#    FNAME   : name of source file to generate - a .c file will be made
+#    TYPE    : 'f' to build factorizer, 's' to build solver, 't' to build the
+#              transpose solver.
+#    N1      : block size (size of outer product matrix) (1..9)
+#    UNROLL1 : solver inner loop unrolling factor (1..)
+#    UNROLL2 : factorizer inner loop unrolling factor (1..)
+#    MADD    : if nonzero, generate code for fused multiply-add (0,1)
+#    FETCH   : how to fetch data in the inner loop:
+#                0 - load in a batch (the `normal way')
+#                1 - delay inner loop loads until just before they're needed
+#
+#############################################################################
+#
+# TODO
+# ----
+#
+# * dFactorLDLT() is not so efficient for matrix sizes < block size, e.g.
+#   redundant calls, zero loads, adds etc
+#
+#############################################################################
+#
+# NOTES:
+#
+# * on the pentium we can prefetch like this:
+#     asm ("prefetcht0 %0" : : "m" (*Ai) );
+#   but it doesn't seem to help much
+
+require ("BuildUtil");
+
+# get and check code generation parameters
+error ("Usage: BuildLDLT <parameters-file>") if $#ARGV != 0;
+do $ARGV[0];
+
+if (!defined($FNAME) || !defined($TYPE) || !defined($N1) ||
+    !defined($UNROLL1) || !defined($UNROLL2) || !defined($MADD) ||
+    !defined($FETCH)) {
+  error ("code generation parameters not defined");
+}
+
+# check parameters
+error ("bad TYPE") if $TYPE ne 'f' && $TYPE ne 's' && $TYPE ne 't';
+error ("bad N1") if $N1 < 1 || $N1 > 9;
+error ("bad UNROLL1") if $UNROLL1 < 1;
+error ("bad UNROLL2") if $UNROLL2 < 1;
+error ("bad MADD") if $MADD != 0 && $MADD != 1;
+error ("bad FETCH") if $FETCH < 0 && $FETCH > 1;
+
+#############################################################################
+# utility
+
+# functions to handle delayed loading of p and q values.
+# bit in the the `ploaded' and `qloaded' numbers record what has been loaded,
+# so we dont load it again.
+
+sub newLoads
+{
+  # bits in these numbers say what registers p and q have been loaded so far
+  $ploaded = 0;
+  $qloaded = 0;
+}
+
+sub loadedEverything
+{
+  $ploaded = 0xffffffff;
+  $qloaded = 0xffffffff;
+}
+
+sub loadP # (i,loadcmd)
+{
+  my $i = $_[0];
+  my $loadcmd = $_[1];
+  return if ($ploaded & (1 << $i));
+  output ($loadcmd);
+  $ploaded |= (1 << $i);
+}
+
+sub loadQ # (i,loadcmd)
+{
+  my $i = $_[0];
+  my $loadcmd = $_[1];
+  return if ($qloaded & (1 << $i));
+  output ($loadcmd);
+  $qloaded |= (1 << $i);
+}
+
+#############################################################################
+# make a fast L solve function.
+# this function has a restriction that the leading dimension of X and B must
+# be a multiple of the block size.
+
+sub innerOuterProductLoop # (M,k,nrhs,increment)
+{
+  my $M=$_[0];
+  my $k=$_[1];
+  my $nrhs=$_[2];
+  my $increment=$_[3];
+  my ($i,$j);
+  newLoads;
+  if ($FETCH==0) {
+    comment ("load p and q values");
+    for ($i=1; $i<=$M; $i++) {
+      if ($TYPE eq 't') {
+        output ("p$i=ell[".ofs2(-($i-1),0,'lskip')."];\n");
+        output ("q$i=ex[".ofs2(-($k),$i-1,'lskip')."];\n") if $i <= $nrhs;
+      }
+      else {
+        output ("p$i=ell[".ofs2($k,$i-1,'lskip')."];\n");
+        output ("q$i=ex[".ofs2($k,$i-1,'lskip')."];\n") if $i <= $nrhs;
+      }
+    }
+    loadedEverything;
+  }
+
+  comment ("compute outer product and add it to the Z matrix");
+  for ($i=1; $i<=$M; $i++) {
+    for ($j=1; $j<=$nrhs; $j++) {
+      if ($TYPE eq 't') {
+        loadP ($i,"p$i=ell[".ofs2(-($i-1),0,'lskip')."];\n");
+        loadQ ($j,"q$j=ex[".ofs2(-($k),$j-1,'lskip')."];\n");
+      }
+      else {
+        loadP ($i,"p$i=ell[".ofs2($k,$i-1,'lskip')."];\n");
+        loadQ ($j,"q$j=ex[".ofs2($k,$j-1,'lskip')."];\n");
+      }
+      my $var = $MADD ? "Z$i$j +=" : "m$i$j =";
+      output ("$var p$i * q$j;\n");
+    }
+  }
+
+  if ($TYPE eq 't') {
+    if ($increment > 0) {
+      output ("ell += lskip1;\n");
+      output ("ex -= $increment;\n");
+    }
+    else {
+      output ("ell += lskip1;\n");
+    }
+  }
+  else {
+    if ($increment > 0) {
+      comment ("advance pointers");
+      output ("ell += $increment;\n");
+      output ("ex += $increment;\n");
+    }
+  }
+
+  if ($MADD==0) {
+    for ($i=1; $i<=$M; $i++) {
+      for ($j=1; $j<=$nrhs; $j++) {
+        output ("Z$i$j += m$i$j;\n");
+      }
+    }
+  }
+}
+
+
+sub computeRows # (nrhs,rows)
+{
+  my $nrhs = $_[0];
+  my $rows = $_[1];
+  my ($i,$j,$k);
+
+  comment ("compute all $rows x $nrhs block of X, from rows i..i+$rows-1");
+
+  comment ("set the Z matrix to 0");
+  for ($i=1; $i<=$rows; $i++) {
+    for ($j=1; $j<=$nrhs; $j++) {
+      output ("Z$i$j=0;\n");
+    }
+  }
+  if ($TYPE eq 't') {
+    output ("ell = L - i;\n");
+  }
+  else {
+    output ("ell = L + i*lskip1;\n");
+  }
+  output ("ex = B;\n");
+
+  comment ("the inner loop that computes outer products and adds them to Z");
+  output ("for (j=i-$UNROLL1; j >= 0; j -= $UNROLL1) {\n");
+  for ($k=0; $k < $UNROLL1; $k++) {
+    innerOuterProductLoop ($rows,$k,$nrhs,($k==$UNROLL1-1) ? $UNROLL1 : 0);
+  }
+
+  comment ("end of inner loop");
+  output ("}\n");
+
+  if ($UNROLL1 > 1) {
+    comment ("compute left-over iterations");
+    output ("j += $UNROLL1;\n");
+    output ("for (; j > 0; j--) {\n");
+    innerOuterProductLoop ($rows,'0',$nrhs,1);
+    output ("}\n");
+  }
+
+  comment ("finish computing the X(i) block");
+
+  for ($j=1; $j<=$nrhs; $j++) {
+    if ($TYPE eq 't') {
+      output ("Z1$j = ex[".ofs1(-($j-1),'lskip')."] - Z1$j;\n");
+      output ("ex[".ofs1(-($j-1),'lskip')."] = Z1$j;\n");
+    }
+    else {
+      output ("Z1$j = ex[".ofs1($j-1,'lskip')."] - Z1$j;\n");
+      output ("ex[".ofs1($j-1,'lskip')."] = Z1$j;\n");
+    }
+  }
+
+  for ($i=2; $i<=$rows; $i++) {
+    for ($j=1; $j<$i; $j++) {
+      if ($TYPE eq 't') {
+        output ("p$j = ell[".ofs2(-($i-1),$j-1,'lskip')."];\n");
+      }
+      else {
+        output ("p$j = ell[".ofs2($j-1,$i-1,'lskip')."];\n");
+      }
+    }
+    for ($j=1; $j<=$nrhs; $j++) {
+      if ($TYPE eq 't') {
+        output ("Z$i$j = ex[".ofs2(-($i-1),$j-1,'lskip')."] - Z$i$j");
+      }
+      else {
+        output ("Z$i$j = ex[".ofs2($i-1,$j-1,'lskip')."] - Z$i$j");
+      }
+      for ($k=1; $k < $i; $k++) {
+        output (" - p$k*Z$k$j");
+      }
+      output (";\n");
+      if ($TYPE eq 't') {
+        output ("ex[".ofs2(-($i-1),$j-1,'lskip')."] = Z$i$j;\n");
+      }
+      else {
+        output ("ex[".ofs2($i-1,$j-1,'lskip')."] = Z$i$j;\n");
+      }
+    }
+  }
+}
+
+
+sub makeFastL1Solve # ( number-of-right-hand-sides )
+{
+  my $nrhs = $_[0];
+  my ($i,$j,$k);
+  my $funcsuffix = ($TYPE eq 'f') ? "_$nrhs" : '';
+  my $staticvoid = ($TYPE eq 'f') ? 'static void' : 'void';
+
+  # function header
+  if ($TYPE eq 't') {
+    output (<<END);
+
+/* solve L^T * x=b, with b containing 1 right hand side.
+ * L is an n*n lower triangular matrix with ones on the diagonal.
+ * L is stored by rows and its leading dimension is lskip.
+ * b is an n*1 matrix that contains the right hand side.
+ * b is overwritten with x.
+ * this processes blocks of $N1.
+ */
+
+void dSolveL1T (const dReal *L, dReal *B, int n, int lskip1)
+{
+END
+  }
+  else {
+    output (<<END);
+
+/* solve L*X=B, with B containing $nrhs right hand sides.
+ * L is an n*n lower triangular matrix with ones on the diagonal.
+ * L is stored by rows and its leading dimension is lskip.
+ * B is an n*$nrhs matrix that contains the right hand sides.
+ * B is stored by columns and its leading dimension is also lskip.
+ * B is overwritten with X.
+ * this processes blocks of $N1*$N1.
+ * if this is in the factorizer source file, n must be a multiple of $N1.
+ */
+
+$staticvoid dSolveL1$funcsuffix (const dReal *L, dReal *B, int n, int lskip1)
+{
+END
+  }
+
+  comment ("declare variables - Z matrix, p and q vectors, etc");
+  output ("dReal ");
+  for ($i=1; $i<=$N1; $i++) {
+    for ($j=1; $j<=$nrhs; $j++) {
+      output ("Z$i$j,");               # Z matrix
+      output ("m$i$j,") if ! $MADD;    # temporary vars where multiplies put
+    }
+  }
+  for ($i=1; $i<=$N1; $i++) {
+    output ("p$i,");
+    output ("q$i,") if $i <= $nrhs;
+  }
+  output ("*ex;\nconst dReal *ell;\n");
+  output ("int ");
+  for ($i=2; $i<$N1; $i++) {
+    output ("lskip$i,");
+  }
+  output ("i,j;\n");
+
+  if ($TYPE eq 't') {
+    comment ("special handling for L and B because we're solving L1 *transpose*");
+    output ("L = L + (n-1)*(lskip1+1);\n");
+    output ("B = B + n-1;\n");
+    output ("lskip1 = -lskip1;\n");
+  }
+
+  if ($N1 > 2) {
+    comment ("compute lskip values");
+    for ($i=2; $i<$N1; $i++) {
+      output ("lskip$i = $i*lskip1;\n");
+    }
+  }
+
+  comment ("compute all $N1 x $nrhs blocks of X");
+  if ($TYPE eq 's' or $TYPE eq 't') {
+    output ("for (i=0; i <= n-$N1; i+=$N1) {\n");
+  }
+  else {
+    output ("for (i=0; i < n; i+=$N1) {\n");
+  }
+  computeRows ($nrhs,$N1);
+  comment ("end of outer loop");
+  output ("}\n");
+
+  if ($TYPE eq 's' or $TYPE eq 't') {
+    comment ("compute rows at end that are not a multiple of block size");
+    output ("for (; i < n; i++) {\n");
+    computeRows ($nrhs,1);
+    output ("}\n");
+  }
+
+  output ("}\n");
+}
+
+#############################################################################
+# make a fast L*D*L' factorizer
+
+# code fragment: this factors an M x M block. if A_or_Z is 0 then it works
+# on the $A matrix otherwise it works on the Z matrix. in either case it
+# writes the diagonal entries into the `dee' vector.
+# it is a simple implementation of the LDLT algorithm, with no tricks.
+
+sub getA # (i,j,A,A_or_Z)
+{
+  my $i = $_[0];
+  my $j = $_[1];
+  my $A = $_[2];
+  return $_[3] ? ('Z'.($i+1).($j+1)) : ($A.'['.ofs2($j,$i,'nskip').']');
+}
+
+sub miniLDLT # (A,A_or_Z,M)
+{
+  my ($i,$j,$k);
+  my $A = $_[0];
+  my $AZ = $_[1];
+  my $M = $_[2];
+  comment ("factorize $M x $M block " . ($AZ ? "Z,dee" : "$A,dee"));
+  comment ("factorize row 1");
+  output ("dee[0] = dRecip(".getA(0,0,$A,$AZ).");\n");
+  for ($i=1; $i<$M; $i++) {
+    comment ("factorize row ".($i+1));
+    for ($j=1; $j<$i; $j++) {
+      output (getA($i,$j,$A,$AZ)." -= ");
+      for ($k=0; $k<$j; $k++) {
+       output (" + ") if $k > 0;
+       output (getA($i,$k,$A,$AZ)."*".getA($j,$k,$A,$AZ));
+      }
+      output (";\n");
+    }
+    output ("sum = 0;\n");
+    for ($j=0; $j<$i; $j++) {
+      output ("q1 = ".getA($i,$j,$A,$AZ).";\n");
+      output ("q2 = q1 * dee[$j];\n");
+      output (getA($i,$j,$A,$AZ)." = q2;\n");
+      output ("sum += q1*q2;\n");
+    }
+    output ("dee[$i] = dRecip(".getA($i,$i,$A,$AZ)." - sum);\n");
+  }
+  comment ("done factorizing $M x $M block");
+}
+
+
+sub innerScaleAndOuterProductLoop # (M,k)
+{
+  my $M = $_[0];
+  my $k = $_[1];
+  my ($i,$j);
+  for ($i=1; $i<=$M; $i++) {
+    output ("p$i = ell[".ofs2($k,$i-1,'nskip')."];\n");
+  }
+  output ("dd = dee[$k];\n");
+  for ($i=1; $i<=$M; $i++) {
+    output ("q$i = p$i*dd;\n");
+  }
+  for ($i=1; $i<=$M; $i++) {
+    output ("ell[".ofs2($k,$i-1,'nskip')."] = q$i;\n");
+  }
+  for ($i=1; $i<=$M; $i++) {
+    for ($j=1; $j<=$i; $j++) {
+      my $var = $MADD ? "Z$i$j +=" : "m$i$j =";
+      output ("$var p$i*q$j;\n");
+    }
+  }
+  if ($MADD==0) {
+  for ($i=1; $i<=$M; $i++) {
+    for ($j=1; $j<=$i; $j++) {
+        output ("Z$i$j += m$i$j;\n");
+      }
+    }
+  }
+}
+
+
+sub diagRows # (M)
+{
+  my $M=$_[0];
+  comment ("scale the elements in a $M x i block at A(i,0), and also");
+  comment ("compute Z = the outer product matrix that we'll need.");
+  for ($i=1; $i<=$M; $i++) {
+    for ($j=1; $j<=$i; $j++) {
+      output ("Z$i$j = 0;\n");
+    }
+  }
+  output ("ell = A+i*nskip1;\n");
+  output ("dee = d;\n");
+  output ("for (j=i-$UNROLL2; j >= 0; j -= $UNROLL2) {\n");
+  for ($i=0; $i < $UNROLL2; $i++) {
+    innerScaleAndOuterProductLoop ($M,$i);
+  }
+  output ("ell += $UNROLL2;\n");
+  output ("dee += $UNROLL2;\n");
+  output ("}\n");
+
+  if ($UNROLL2 > 1) {
+    comment ("compute left-over iterations");
+    output ("j += $UNROLL2;\n");
+    output ("for (; j > 0; j--) {\n");
+    innerScaleAndOuterProductLoop ($M,0);
+    output ("ell++;\n");
+    output ("dee++;\n");
+    output ("}\n");
+  }
+}
+
+
+sub diagBlock # (M)
+{
+  my $M = $_[0];
+  comment ("solve for diagonal $M x $M block at A(i,i)");
+  for ($i=1; $i<=$M; $i++) {
+    for ($j=1; $j<=$i; $j++) {
+      output ("Z$i$j = ell[".ofs2($j-1,$i-1,'nskip')."] - Z$i$j;\n");
+    }
+  }
+  output ("dee = d + i;\n");
+  miniLDLT ('',1,$M);
+  for ($i=2; $i<=$M; $i++) {
+    for ($j=1; $j<$i; $j++) {
+      output ("ell[".ofs2($j-1,$i-1,'nskip')."] = Z$i$j;\n");
+    }
+  }
+}
+
+
+sub makeFastLDLT
+{
+  my ($i,$j,$k);
+
+  # function header
+  output (<<END);
+
+
+void dFactorLDLT (dReal *A, dReal *d, int n, int nskip1)
+{
+END
+  output ("int i,j");
+  for ($i=2; $i<$N1; $i++) {
+    output (",nskip$i");
+  }
+  output (";\n");
+  output ("dReal sum,*ell,*dee,dd,p1,p2");
+  for ($i=3; $i<=$N1; $i++) {
+    output (",p$i");
+  }
+  for ($i=1; $i<=$N1; $i++) {
+    output (",q$i");
+  }
+  for ($i=1; $i<=$N1; $i++) {
+    for ($j=1; $j<=$i; $j++) {
+      output (",Z$i$j");
+      output (",m$i$j") if ! $MADD;    # temporary vars where multiplies put
+    }
+  }
+  output (";\n");
+  output ("if (n < 1) return;\n");
+  # output ("nskip1 = dPAD(n);\n");   ... not any more
+  for ($i=2; $i<$N1; $i++) {
+    output ("nskip$i = $i*nskip1;\n");
+  }
+
+  output ("\nfor (i=0; i<=n-$N1; i += $N1) {\n");
+  comment ("solve L*(D*l)=a, l is scaled elements in $N1 x i block at A(i,0)");
+  output ("dSolveL1_$N1 (A,A+i*nskip1,i,nskip1);\n");
+
+  diagRows ($N1);
+  diagBlock ($N1);
+  output ("}\n");
+
+  comment ("compute the (less than $N1) rows at the bottom");
+  output ("switch (n-i) {\n");
+  output ("case 0:\n");
+  output ("break;\n\n");
+
+  for ($i=1; $i<$N1; $i++) {
+    output ("case $i:\n");
+    output ("dSolveL1_$i (A,A+i*nskip1,i,nskip1);\n");
+    diagRows ($i);
+    diagBlock ($i);
+    output ("break;\n\n");
+  }
+
+  output ("default: *((char*)0)=0;  /* this should never happen! */\n");
+  output ("}\n");
+
+  output ("}\n");
+}
+
+#############################################################################
+# write source code
+
+open (FOUT,">$FNAME.c") or die "can't open $FNAME.c for writing";
+
+# file and function header
+output (<<END);
+/* generated code, do not edit. */
+
+#include "ode/matrix.h"
+END
+
+if ($TYPE eq 'f') {
+  for ($i=1; $i <= $N1; $i++) {
+    makeFastL1Solve ($i);
+  }
+  makeFastLDLT;
+}
+else {
+  makeFastL1Solve (1);
+  makeRealFastL1Solve;
+}
+close FOUT;
diff --git a/extern/ode/dist/ode/fbuild/BuildMultidot b/extern/ode/dist/ode/fbuild/BuildMultidot
new file mode 100644 (file)
index 0000000..f6b1177
--- /dev/null
@@ -0,0 +1,174 @@
+#!/usr/bin/perl
+#
+#########################################################################
+#                                                                       #
+# 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.                     #
+#                                                                       #
+#########################################################################
+
+# multi-dot-product code generator. this code generator is based on the
+# dot-product code generator.
+#
+# code generation parameters, set in a parameters file:
+#    FNAME    : name of source file to generate - a .c file will be made
+#    N1       : block size (number of `a' vectors to dot)
+#    UNROLL1  : inner loop unrolling factor (1..)
+#    FETCH    : max num of a[i]'s and b[i]'s to load ahead of muls
+#    LAT1     : load -> mul latency (>=1)
+#    LAT2     : mul -> add latency (>=1). if this is 1, use fused mul-add
+#
+#############################################################################
+
+require ("BuildUtil");
+
+# get and check code generation parameters
+error ("Usage: BuildMultidot <parameters-file>") if $#ARGV != 0;
+do $ARGV[0];
+
+if (!defined($FNAME) || !defined($N1) || !defined($UNROLL1) ||
+    !defined($FETCH) || !defined($LAT1) || !defined($LAT2)) {
+  error ("code generation parameters not defined");
+}
+
+# check parameters
+error ("bad N1") if $N1 < 2;
+error ("bad UNROLL1") if $UNROLL1 < 1;
+error ("bad FETCH") if $FETCH < 1;
+error ("bad LAT1") if $LAT1 < 1;
+error ("bad LAT2") if $LAT2 < 1;
+
+#############################################################################
+
+open (FOUT,">$FNAME.c") or die "can't open $FNAME.c for writing";
+
+# file and function header
+output (<<END);
+/* generated code, do not edit. */
+
+#include "ode/matrix.h"
+
+
+END
+output ("void dMultidot$N1 (");
+for ($i=0; $i<$N1; $i++) {
+  output ("const dReal *a$i, ");
+}
+output ("const dReal *b, dReal *outsum, int n)\n{\n");
+
+output ("dReal ");
+for ($i=0; $i<$UNROLL1; $i++) {
+  for ($j=0; $j<$N1; $j++) {
+    output ("p$i$j,");
+    output ("m$i$j,") if $LAT2 > 1;
+  }
+  output ("q$i,");
+}
+for ($i=0; $i<$N1; $i++) {
+  output ("sum$i");
+  output (",") if $i < ($N1-1);
+}
+output (";\n");
+for ($i=0; $i<$N1; $i++) {
+  output ("sum$i = 0;\n");
+}
+output (<<END);
+n -= $UNROLL1;
+while (n >= 0) {
+END
+
+@load = ();            # slot where a[i]'s and b[i]'s loaded
+@mul = ();             # slot where multiply i happened
+@add = ();             # slow where add i happened
+
+for ($i=0; $i<$N1; $i++) {
+  output ("p0$i = a$i [0];\n");
+}
+output ("q0 = b[0];\n");
+push (@load,0);
+
+$slot=0;               # one slot for every load/mul/add/nop issued
+for (;;) {
+  $startslot = $slot;
+
+  # do next load
+  if (($#load - $#mul) < $FETCH && ($#load+1) < $UNROLL1) {
+    push (@load,$slot);
+    for ($j=0; $j<$N1; $j++) {
+      output ("p$#load$j = a$j [$#load];\n");
+    }
+    output ("q$#load = b[$#load];\n");
+    $slot++;
+  }
+
+  # do next multiply
+  if ($#load > $#mul && $slot >= ($load[$#mul+1] + $LAT1) &&
+      ($#mul+1) < $UNROLL1) {
+    push (@mul,$slot);
+    if ($LAT2 > 1) {
+      for ($j=0; $j<$N1; $j++) {
+        output ("m$#mul$j = p$#mul$j * q$#mul;\n");
+      }
+    }
+    else {
+      for ($j=0; $j<$N1; $j++) {
+        output ("sum$j += p$#mul$j * q$#mul;\n");
+      }
+      last if ($#mul+1) >= $UNROLL1;
+    }
+    $slot++;
+  }
+  # do next add
+  if ($LAT2 > 1) {
+    if ($#mul > $#add && $slot >= ($mul[$#add+1] + $LAT2)) {
+      push (@add,$slot);
+      for ($j=0; $j<$N1; $j++) {
+        output ("sum$j += m$#add$j;\n");
+      }
+      $slot++;
+      last if ($#add+1) >= $UNROLL1;
+    }
+  }
+
+  if ($slot == $startslot) {
+    # comment ("nop");
+    $slot++;
+  }
+}
+
+for ($j=0; $j<$N1; $j++) {
+  output ("a$j += $UNROLL1;\n");
+}
+output ("b += $UNROLL1;\n");
+output ("n -= $UNROLL1;\n");
+output ("}\n");
+
+output ("n += $UNROLL1;\n");
+output ("while (n > 0) {\n");
+output ("q0 = *b;\n");
+for ($j=0; $j<$N1; $j++) {
+  output ("sum$j += (*a$j) * q0;\n");
+  output ("a$j++;\n");
+}
+output ("b++;\n");
+output ("n--;\n");
+output ("}\n");
+for ($j=0; $j<$N1; $j++) {
+  output ("outsum[$j] = sum$j;\n");
+}
+output ("}\n");
diff --git a/extern/ode/dist/ode/fbuild/BuildUtil b/extern/ode/dist/ode/fbuild/BuildUtil
new file mode 100644 (file)
index 0000000..b0828ff
--- /dev/null
@@ -0,0 +1,99 @@
+#!/usr/bin/perl -w
+#
+#########################################################################
+#                                                                       #
+# 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.                     #
+#                                                                       #
+#########################################################################
+
+package BuildUtil;
+
+
+# print out code. after newlines, indent according to the number of curly
+# brackets we've seen
+
+my $indent = 0;
+my $startofline = 1;
+
+
+sub main::output
+{
+  my $line = $_[0];
+  my ($i,$j,$c);
+  for ($i=0; $i < length ($line); $i++) {
+    $c = substr ($line,$i,1);
+    print main::FOUT $c if $c eq '{';
+    $indent++ if $c eq '{';
+    $indent-- if $c eq '}';
+    if ($startofline) {
+      for ($j=0; $j < $indent; $j++) {
+       print main::FOUT "  ";
+      }
+      $startofline = 0;
+    }
+    print main::FOUT $c if $c ne '{';
+    $startofline = 1 if $c eq "\n";
+  }
+}
+
+
+# write a C comment with the correct indenting
+
+sub main::comment
+{
+  main::output ("/* $_[0] */\n");
+}
+
+
+# return an offset: N*skip = skipN where N=0,1,2,...
+
+sub main::ofs1 # (N,skip)
+{
+  my $N = $_[0];
+  my $skip = $_[1];
+  return '0' if $N==0;
+  return $skip . $N;
+}
+
+
+# return an offset: M+N*skip = M+skipN where N=0,1,2,...
+
+sub main::ofs2 # (M,N,skip)
+{
+  my $M = $_[0];
+  my $N = $_[1];
+  my $skip = $_[2];
+  $M = '0' if $M eq '-0';
+  my $a = $M;
+  $a .= '+' . $skip . $N if ($N > 0);
+  substr ($a,0,2)='' if substr ($a,0,2) eq '0+';
+  return $a;
+}
+
+
+# print an error message and exit
+
+sub main::error
+{
+  print "ERROR: $_[0]\n";
+  exit 1;
+}
+
+
+1;
diff --git a/extern/ode/dist/ode/fbuild/Dependencies b/extern/ode/dist/ode/fbuild/Dependencies
new file mode 100644 (file)
index 0000000..86f5cd4
--- /dev/null
@@ -0,0 +1,16 @@
+test_dot.o: test_dot.cpp ../../include/ode/ode.h \
+ ../../include/ode/config.h ../../include/ode/contact.h \
+ ../../include/ode/common.h ../../include/ode/error.h \
+ ../../include/ode/memory.h ../../include/ode/odemath.h \
+ ../../include/ode/matrix.h ../../include/ode/timer.h \
+ ../../include/ode/rotation.h ../../include/ode/mass.h \
+ ../../include/ode/space.h ../../include/ode/geom.h \
+ ../../include/ode/misc.h
+test_ldlt.o: test_ldlt.cpp ../../include/ode/ode.h \
+ ../../include/ode/config.h ../../include/ode/contact.h \
+ ../../include/ode/common.h ../../include/ode/error.h \
+ ../../include/ode/memory.h ../../include/ode/odemath.h \
+ ../../include/ode/matrix.h ../../include/ode/timer.h \
+ ../../include/ode/rotation.h ../../include/ode/mass.h \
+ ../../include/ode/space.h ../../include/ode/geom.h \
+ ../../include/ode/misc.h
diff --git a/extern/ode/dist/ode/fbuild/Makefile b/extern/ode/dist/ode/fbuild/Makefile
new file mode 100644 (file)
index 0000000..f988c37
--- /dev/null
@@ -0,0 +1,77 @@
+#########################################################################
+#                                                                       #
+# 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.                     #
+#                                                                       #
+#########################################################################
+
+# currently this only works under linux, and it's a bit of a mess!
+
+MAKEFILE_INC=../../build/Makefile.inc
+include $(MAKEFILE_INC)
+
+INCLUDE_PATHS=../../include
+LIB_PATHS = ../../lib
+DEFINES=dDOUBLE
+
+SOURCES_CPP=test_ldlt.cpp
+SOURCES_C=fastldlt.c fastlsolve.c fastltsolve.c
+APPS=$(call fEXENAME,test_ldlt) $(call fEXENAME,test_dot) $(call fEXENAME,test_multidot)
+EXTRA_CLEAN=test_ldlt test_dot test_multidot fastldlt.c fastlsolve.c fastltsolve.c fastdot.c fastmultidot.c
+
+
+all: $(APPS)
+
+$(call fEXENAME,test_ldlt): $(call fTARGETS,$(SOURCES_CPP) $(SOURCES_C))
+       gcc -o $@ $^ -L $(LIB_PATHS) $(call fLIB,ode) -lm
+
+$(call fEXENAME,test_dot): test_dot.o fastdot.o
+       gcc -o $@ test_dot.o fastdot.o -L $(LIB_PATHS) $(call fLIB,ode) -lm
+
+$(call fEXENAME,test_multidot): test_multidot.o fastmultidot.o
+       gcc -o $@ test_multidot.o fastmultidot.o -L $(LIB_PATHS) $(call fLIB,ode) -lm
+
+fastldlt.o: fastldlt.c
+       gcc -O1 -I$(INCLUDE_PATHS) -ffast-math -fomit-frame-pointer -c -D$(DEFINES) $<
+
+fastlsolve.o: fastlsolve.c
+       gcc -O1 -I$(INCLUDE_PATHS) -ffast-math -fomit-frame-pointer -c -D$(DEFINES) $<
+
+fastltsolve.o: fastltsolve.c
+       gcc -O1 -I$(INCLUDE_PATHS) -ffast-math -fomit-frame-pointer -c -D$(DEFINES) $<
+
+fastdot.o: fastdot.c
+       gcc -O1 -I$(INCLUDE_PATHS) -ffast-math -fomit-frame-pointer -c -D$(DEFINES) $<
+
+fastmultidot.o: fastmultidot.c
+       gcc -O1 -I$(INCLUDE_PATHS) -ffast-math -fomit-frame-pointer -c -D$(DEFINES) $<
+
+fastldlt.c: BuildLDLT BuildUtil ParametersF
+       ./BuildLDLT ParametersF
+
+fastlsolve.c: BuildLDLT BuildUtil ParametersS
+       ./BuildLDLT ParametersS
+
+fastltsolve.c: BuildLDLT BuildUtil ParametersT
+       ./BuildLDLT ParametersT
+
+fastdot.c: BuildDot BuildUtil ParametersD
+       ./BuildDot ParametersD
+
+fastmultidot.c: BuildMultidot BuildUtil ParametersM
+       ./BuildMultidot ParametersM
diff --git a/extern/ode/dist/ode/fbuild/OptimizeDot b/extern/ode/dist/ode/fbuild/OptimizeDot
new file mode 100644 (file)
index 0000000..1dc1782
--- /dev/null
@@ -0,0 +1,71 @@
+#!/usr/bin/perl
+#
+#########################################################################
+#                                                                       #
+# 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.                     #
+#                                                                       #
+#########################################################################
+
+# optimize the dot product built by BuildDot
+
+##############################################################################
+
+require ("OptimizeUtil");
+
+# unused standard parameters
+$TYPE='unused';
+$N1=0;                 # unused
+$UNROLL2=0;            # unused
+$MADD=0;               # unused
+
+##############################################################################
+
+sub testDot # (filename)
+{
+  my $filename = $_[0];
+  createParametersFile ('ParametersD');
+  $params = "$N1 $UNROLL1 $UNROLL2 $MADD $FETCH $LAT1 $LAT2";
+  print "***** TESTING $params\n";
+  doit ("rm -f fastdot.c fastdot.o test_dot");
+  doit ("make test_dot");
+  doit ("./test_dot >> $filename");
+  open (FILE,">>$filename");
+  print FILE " $params\n";
+  close FILE;
+}
+
+# find optimal parameters. write results to data4.txt
+
+open (FILE,">data4.txt");
+print FILE "# dot product data from OptimizeDot\n";
+close FILE;
+$FNAME='fastdot';
+
+for ($UNROLL1=1; $UNROLL1 <= 10; $UNROLL1++) {
+  for ($LAT1=1; $LAT1 <= 5; $LAT1++) {
+    for ($LAT2=1; $LAT2 <= 5; $LAT2++) {
+      for ($FETCH=1; $FETCH<=5; $FETCH++) {
+       testDot ('data4.txt');
+      }
+    }
+  }
+}
+
+readBackDataFile ('data4.txt');
+createParametersFile ('ParametersD');
diff --git a/extern/ode/dist/ode/fbuild/OptimizeLDLT b/extern/ode/dist/ode/fbuild/OptimizeLDLT
new file mode 100644 (file)
index 0000000..612633e
--- /dev/null
@@ -0,0 +1,91 @@
+#!/usr/bin/perl
+#
+#########################################################################
+#                                                                       #
+# 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.                     #
+#                                                                       #
+#########################################################################
+
+# optimize the factorizer built by BuildLDLT
+#
+#    FNAME   : name of source file to generate - .h and .c files will be made
+#    N1      : block size (size of outer product matrix) (1..9)
+#    UNROLL1 : solver inner loop unrolling factor (1..)
+#    UNROLL2 : factorizer inner loop unrolling factor (1..)
+#    MADD    : if nonzero, generate code for fused multiply-add (0,1)
+#    FETCH   : how to fetch data in the inner loop:
+#                0 - load in a batch (the `normal way')
+#                1 - delay inner loop loads until just before they're needed
+
+##############################################################################
+
+require ("OptimizeUtil");
+
+##############################################################################
+# optimize factorizer
+
+sub testFactorizer # (filename)
+{
+  my $filename = $_[0];
+  createParametersFile ('ParametersF');
+  $params = "$N1 $UNROLL1 $UNROLL2 $MADD $FETCH";
+  print "***** TESTING $params\n";
+  doit ("rm -f fastldlt.c fastldlt.o test_ldlt");
+  doit ("make test_ldlt");
+  doit ("./test_ldlt f >> $filename");
+  open (FILE,">>$filename");
+  print FILE " $params\n";
+  close FILE;
+}
+
+
+# first find optimal parameters ignoring UNROLL1 and UNROLL2, write results
+# to data1.txt
+
+open (FILE,">data1.txt");
+print FILE "# factorizer data from OptimizeLDLT\n";
+close FILE;
+$FNAME='fastldlt';
+$TYPE='f';
+$UNROLL1=4;
+$UNROLL2=4;
+for ($N1=1; $N1 <= 4; $N1++) {
+  for ($MADD=0; $MADD<=1; $MADD++) {
+    for ($FETCH=0; $FETCH<=1; $FETCH++) {
+      testFactorizer ('data1.txt');
+    }
+  }
+}
+
+readBackDataFile ('data1.txt');
+createParametersFile ('ParametersF');
+
+# now find optimal UNROLL1 and UNROLL2 values, write results to data2.txt
+
+open (FILE,">data2.txt");
+print FILE "# factorizer data from OptimizeLDLT\n";
+close FILE;
+for ($UNROLL1=1; $UNROLL1 <= 10; $UNROLL1++) {
+  for ($UNROLL2=1; $UNROLL2 <= 10; $UNROLL2++) {
+    testFactorizer ('data2.txt');
+  }
+}
+
+readBackDataFile ('data2.txt');
+createParametersFile ('ParametersF');
diff --git a/extern/ode/dist/ode/fbuild/OptimizeLSolve b/extern/ode/dist/ode/fbuild/OptimizeLSolve
new file mode 100644 (file)
index 0000000..bba6b49
--- /dev/null
@@ -0,0 +1,76 @@
+#!/usr/bin/perl
+#
+#########################################################################
+#                                                                       #
+# 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.                     #
+#                                                                       #
+#########################################################################
+
+# optimize the solver built by BuildLDLT
+#
+#    FNAME   : name of source file to generate - .h and .c files will be made
+#    N1      : block size (size of outer product matrix) (1..9)
+#    UNROLL1 : solver inner loop unrolling factor (1..)
+#    UNROLL2 : factorizer inner loop unrolling factor (1..)
+#    MADD    : if nonzero, generate code for fused multiply-add (0,1)
+#    FETCH   : how to fetch data in the inner loop:
+#                0 - load in a batch (the `normal way')
+#                1 - delay inner loop loads until just before they're needed
+
+##############################################################################
+
+require ("OptimizeUtil");
+
+##############################################################################
+# optimize solver
+
+sub testSolver # (filename)
+{
+  my $filename = $_[0];
+  createParametersFile ('ParametersS');
+  $params = "$N1 $UNROLL1 $UNROLL2 $MADD $FETCH";
+  print "***** TESTING $params\n";
+  doit ("rm -f fastlsolve.c fastlsolve.o test_ldlt");
+  doit ("make test_ldlt");
+  doit ("./test_ldlt s >> $filename");
+  open (FILE,">>$filename");
+  print FILE " $params\n";
+  close FILE;
+}
+
+# find optimal parameters. UNROLL2 has no effect. write results to data3.txt
+
+open (FILE,">data3.txt");
+print FILE "# solver data from OptimizeLDLT\n";
+close FILE;
+$FNAME='fastlsolve';
+$TYPE='s';
+$UNROLL2=1;
+for ($N1=1; $N1 <= 5; $N1++) {
+  for ($UNROLL1=1; $UNROLL1 <= 15; $UNROLL1++) {
+    for ($MADD=0; $MADD<=1; $MADD++) {
+      for ($FETCH=0; $FETCH<=1; $FETCH++) {
+       testSolver ('data3.txt');
+      }
+    }
+  }
+}
+
+readBackDataFile ('data3.txt');
+createParametersFile ('ParametersS');
diff --git a/extern/ode/dist/ode/fbuild/OptimizeLTSolve b/extern/ode/dist/ode/fbuild/OptimizeLTSolve
new file mode 100644 (file)
index 0000000..a10109e
--- /dev/null
@@ -0,0 +1,76 @@
+#!/usr/bin/perl
+#
+#########################################################################
+#                                                                       #
+# 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.                     #
+#                                                                       #
+#########################################################################
+
+# optimize the transpose solver built by BuildLDLT
+#
+#    FNAME   : name of source file to generate - .h and .c files will be made
+#    N1      : block size (size of outer product matrix) (1..9)
+#    UNROLL1 : solver inner loop unrolling factor (1..)
+#    UNROLL2 : factorizer inner loop unrolling factor (1..)
+#    MADD    : if nonzero, generate code for fused multiply-add (0,1)
+#    FETCH   : how to fetch data in the inner loop:
+#                0 - load in a batch (the `normal way')
+#                1 - delay inner loop loads until just before they're needed
+
+##############################################################################
+
+require ("OptimizeUtil");
+
+##############################################################################
+# optimize solver
+
+sub testSolver # (filename)
+{
+  my $filename = $_[0];
+  createParametersFile ('ParametersT');
+  $params = "$N1 $UNROLL1 $UNROLL2 $MADD $FETCH";
+  print "***** TESTING $params\n";
+  doit ("rm -f fastltsolve.c fastltsolve.o test_ldlt");
+  doit ("make test_ldlt");
+  doit ("./test_ldlt t >> $filename");
+  open (FILE,">>$filename");
+  print FILE " $params\n";
+  close FILE;
+}
+
+# find optimal parameters. UNROLL2 has no effect. write results to data5.txt
+
+open (FILE,">data5.txt");
+print FILE "# solver data from OptimizeLDLT\n";
+close FILE;
+$FNAME='fastltsolve';
+$TYPE='t';
+$UNROLL2=1;
+for ($N1=1; $N1 <= 5; $N1++) {
+  for ($UNROLL1=1; $UNROLL1 <= 15; $UNROLL1++) {
+    for ($MADD=0; $MADD<=1; $MADD++) {
+      for ($FETCH=0; $FETCH<=1; $FETCH++) {
+       testSolver ('data5.txt');
+      }
+    }
+  }
+}
+
+readBackDataFile ('data5.txt');
+createParametersFile ('ParametersT');
diff --git a/extern/ode/dist/ode/fbuild/OptimizeMultidot b/extern/ode/dist/ode/fbuild/OptimizeMultidot
new file mode 100644 (file)
index 0000000..f2b5438
--- /dev/null
@@ -0,0 +1,73 @@
+#!/usr/bin/perl
+#
+#########################################################################
+#                                                                       #
+# 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.                     #
+#                                                                       #
+#########################################################################
+
+# optimize the dot product built by BuildMultidot
+
+##############################################################################
+
+require ("OptimizeUtil");
+
+# multiple
+$N1=2;
+
+# unused standard parameters
+$TYPE='unused';
+$UNROLL2=0;            # unused
+$MADD=0;               # unused
+
+##############################################################################
+
+sub testMultidot # (filename)
+{
+  my $filename = $_[0];
+  createParametersFile ('ParametersM');
+  $params = "$N1 $UNROLL1 $UNROLL2 $MADD $FETCH $LAT1 $LAT2";
+  print "***** TESTING $params\n";
+  doit ("rm -f fastmultidot.c fastmultidot.o test_multidot");
+  doit ("make test_multidot");
+  doit ("./test_multidot >> $filename");
+  open (FILE,">>$filename");
+  print FILE " $params\n";
+  close FILE;
+}
+
+# find optimal parameters. write results to data6.txt
+
+open (FILE,">data6.txt");
+print FILE "# multi-dot product data from OptimizeMultidot\n";
+close FILE;
+$FNAME='fastmultidot';
+
+for ($UNROLL1=1; $UNROLL1 <= 10; $UNROLL1++) {
+  for ($LAT1=1; $LAT1 <= 5; $LAT1++) {
+    for ($LAT2=1; $LAT2 <= 5; $LAT2++) {
+      for ($FETCH=1; $FETCH<=5; $FETCH++) {
+       testMultidot ('data6.txt');
+      }
+    }
+  }
+}
+
+readBackDataFile ('data6.txt');
+createParametersFile ('ParametersM');
diff --git a/extern/ode/dist/ode/fbuild/OptimizeUtil b/extern/ode/dist/ode/fbuild/OptimizeUtil
new file mode 100644 (file)
index 0000000..2b882fc
--- /dev/null
@@ -0,0 +1,86 @@
+#!/usr/bin/perl -w
+#
+#########################################################################
+#                                                                       #
+# 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.                     #
+#                                                                       #
+#########################################################################
+
+package BuildUtil;
+
+
+sub main::doit
+{
+  my $cmd = $_[0];
+  print "$cmd\n";
+  system ($cmd)==0 or die "FAILED";
+}
+
+
+sub main::createParametersFile # (filename)
+{
+  open (PARAM,">$_[0]");
+  print PARAM "# perl script to set parameters required by the code generator\n";
+  print PARAM "\$FNAME=\"$main::FNAME\";\n" if defined($main::FNAME);
+  print PARAM "\$TYPE=\"$main::TYPE\";\n" if defined($main::TYPE);
+  print PARAM "\$N1=$main::N1;\n" if defined($main::N1);
+  print PARAM "\$UNROLL1=$main::UNROLL1;\n" if defined($main::UNROLL1);
+  print PARAM "\$UNROLL2=$main::UNROLL2;\n" if defined($main::UNROLL2);
+  print PARAM "\$MADD=$main::MADD;\n" if defined($main::MADD);
+  print PARAM "\$FETCH=$main::FETCH;\n" if defined($main::FETCH);
+  print PARAM "\$LAT1=$main::LAT1;\n" if defined($main::LAT1);
+  print PARAM "\$LAT2=$main::LAT2;\n" if defined($main::LAT2);
+  close PARAM;
+}
+
+
+# read back a data file and find best parameters
+
+sub main::readBackDataFile # (filename)
+{
+  my $filename = $_[0];
+  my $maxtime = 1e10;
+  open (FILE,$filename);
+  while (<FILE>) {
+    next if /^\#/;
+    my $line = lc $_;
+    if ($line =~ /error/) {
+      print "ERRORS FOUND IN $filename\n";
+      exit 1;
+    }
+    $line =~ s/^\s*//;
+    $line =~ s/\s*$//;
+    my @nums = split (/\s+/,$line);
+    $time = $nums[0];
+    if ($time < $maxtime) {
+      $main::N1 = $nums[1];
+      $main::UNROLL1 = $nums[2];
+      $main::UNROLL2 = $nums[3];
+      $main::MADD = $nums[4];
+      $main::FETCH = $nums[5];
+      $main::LAT1 = $nums[6];
+      $main::LAT2 = $nums[7];
+      $maxtime = $time;
+    }
+  }
+  close FILE;
+}
+
+
+1;
diff --git a/extern/ode/dist/ode/fbuild/ParametersD.example b/extern/ode/dist/ode/fbuild/ParametersD.example
new file mode 100644 (file)
index 0000000..e58f279
--- /dev/null
@@ -0,0 +1,32 @@
+#########################################################################
+#                                                                       #
+# 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.                     #
+#                                                                       #
+#########################################################################
+
+# perl script to set parameters required by the code generator
+$FNAME="fastdot";
+$TYPE="unused";
+$N1=0;
+$UNROLL1=2;
+$UNROLL2=0;
+$MADD=0;
+$FETCH=1;
+$LAT1=1;
+$LAT2=2;
diff --git a/extern/ode/dist/ode/fbuild/ParametersF.example b/extern/ode/dist/ode/fbuild/ParametersF.example
new file mode 100644 (file)
index 0000000..9881b09
--- /dev/null
@@ -0,0 +1,30 @@
+#########################################################################
+#                                                                       #
+# 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.                     #
+#                                                                       #
+#########################################################################
+
+# perl script to set parameters required by the code generator
+$FNAME="fastldlt";
+$TYPE="f";
+$N1=2;
+$UNROLL1=2;
+$UNROLL2=6;
+$MADD=0;
+$FETCH=1;
diff --git a/extern/ode/dist/ode/fbuild/ParametersM.example b/extern/ode/dist/ode/fbuild/ParametersM.example
new file mode 100644 (file)
index 0000000..bb81d6b
--- /dev/null
@@ -0,0 +1,32 @@
+#########################################################################
+#                                                                       #
+# 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.                     #
+#                                                                       #
+#########################################################################
+
+# perl script to set parameters required by the code generator
+$FNAME="fastmultidot";
+$TYPE="unused";
+$N1=2;
+$UNROLL1=1;
+$UNROLL2=0;
+$MADD=0;
+$FETCH=5;
+$LAT1=1;
+$LAT2=1;
diff --git a/extern/ode/dist/ode/fbuild/ParametersS.example b/extern/ode/dist/ode/fbuild/ParametersS.example
new file mode 100644 (file)
index 0000000..29c9a91
--- /dev/null
@@ -0,0 +1,30 @@
+#########################################################################
+#                                                                       #
+# 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.                     #
+#                                                                       #
+#########################################################################
+
+# perl script to set parameters required by the code generator
+$FNAME="fastlsolve";
+$TYPE="s";
+$N1=4;
+$UNROLL1=12;
+$UNROLL2=1;
+$MADD=1;
+$FETCH=0;
diff --git a/extern/ode/dist/ode/fbuild/ParametersT.example b/extern/ode/dist/ode/fbuild/ParametersT.example
new file mode 100644 (file)
index 0000000..3aa92a3
--- /dev/null
@@ -0,0 +1,30 @@
+#########################################################################
+#                                                                       #
+# 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.                     #
+#                                                                       #
+#########################################################################
+
+# perl script to set parameters required by the code generator
+$FNAME="fastltsolve";
+$TYPE="t";
+$N1=4;
+$UNROLL1=12;
+$UNROLL2=1;
+$MADD=1;
+$FETCH=0;
diff --git a/extern/ode/dist/ode/fbuild/README b/extern/ode/dist/ode/fbuild/README
new file mode 100644 (file)
index 0000000..bcf7f5a
--- /dev/null
@@ -0,0 +1,41 @@
+
+factorizer/solver builder
+
+before running `make', copy the following files:
+       ParametersD.example --> ParametersD
+       ParametersF.example --> ParametersF
+       ParametersS.example --> ParametersS
+
+the files Parameters[D|F|S] don't exist in the CVS archive because
+they are changable.
+
+
+
+STATS - for chol
+-----
+
+* all with -O1
+
+128x128 matrix
+atlas   = 1724779 clocks
+my chol = 1164629 clocks (parameters: 2 2 2 1)  with Ai++, Aj++
+my chol = 1140786 clocks (parameters: 2 6 8 0)  with Ai++, Aj++
+my chol = 1118968 clocks (parameters: 2 6 8 0)  with +ofs
+
+64x64 matrix
+atlas   = 374020 clocks
+my chol = 157076 clocks (parameters = 2 2 2 1)
+
+32x32 matrix (12961 flops)
+atlas   = 83827 clocks
+my chol = 25945 clocks (parameters: 2 2 2 1)
+
+
+
+
+TODO
+----
+
+* doc!
+
+* iterate blocks by partial rows to try and keep more data in cache
diff --git a/extern/ode/dist/ode/fbuild/ldlt.m b/extern/ode/dist/ode/fbuild/ldlt.m
new file mode 100644 (file)
index 0000000..19ae2d1
--- /dev/null
@@ -0,0 +1,26 @@
+function [L,d] = ldlt(A)
+
+n=length(A);
+d=zeros(n,1);
+
+d(1) = 1/A(1,1);
+for i=2:n
+  for j=2:i-1
+    A(i,j) = A(i,j) - A(j,1:j-1) * A(i,1:j-1)';
+  end
+  sum = 0;
+  for j=1:i-1
+    q1 = A(i,j);
+    q2 = q1 * d(j);
+    A(i,j) = q2;
+    sum = sum + q1*q2;
+  end
+  d(i) = 1/(A(i,i) - sum);
+end
+
+L=A;
+for i=1:n
+  L(i,i:n)=zeros(1,n+1-i);
+  L(i,i)=1;
+end
+d = d .\ 1;
diff --git a/extern/ode/dist/ode/fbuild/test_dot.cpp b/extern/ode/dist/ode/fbuild/test_dot.cpp
new file mode 100644 (file)
index 0000000..62aec32
--- /dev/null
@@ -0,0 +1,124 @@
+/*************************************************************************
+ *                                                                       *
+ * 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.                     *
+ *                                                                       *
+ *************************************************************************/
+
+#include <stdio.h>
+#include "ode/ode.h"
+
+#define ALLOCA dALLOCA16
+#define SIZE 1000
+
+
+// correct dot product, for accuracy testing
+
+dReal goodDot (dReal *a, dReal *b, int n)
+{
+  dReal sum=0;
+  while (n > 0) {
+    sum += (*a) * (*b);
+    a++;
+    b++;
+    n--;
+  }
+  return sum;
+}
+
+
+// test dot product accuracy
+
+void testAccuracy()
+{
+  // allocate vectors a and b and fill them with random data
+  dReal *a = (dReal*) ALLOCA (SIZE*sizeof(dReal));
+  dReal *b = (dReal*) ALLOCA (SIZE*sizeof(dReal));
+  dMakeRandomMatrix (a,1,SIZE,1.0);
+  dMakeRandomMatrix (b,1,SIZE,1.0);
+
+  for (int n=1; n<100; n++) {
+    dReal good = goodDot (a,b,n);
+    dReal test = dDot (a,b,n);
+    dReal diff = fabs(good-test);
+    //printf ("diff = %e\n",diff);
+    if (diff > 1e-10) printf ("ERROR: accuracy test failed\n");
+  }
+}
+
+
+// test dot product factorizer speed.
+
+void testSpeed()
+{
+  // allocate vectors a and b and fill them with random data
+  dReal *a = (dReal*) ALLOCA (SIZE*sizeof(dReal));
+  dReal *b = (dReal*) ALLOCA (SIZE*sizeof(dReal));
+  dMakeRandomMatrix (a,1,SIZE,1.0);
+  dMakeRandomMatrix (b,1,SIZE,1.0);
+
+  // time several dot products, return the minimum timing
+  double mintime = 1e100;
+  dStopwatch sw;
+  for (int i=0; i<1000; i++) {
+    dStopwatchReset (&sw);
+    dStopwatchStart (&sw);
+
+    // try a bunch of prime sizes up to 101
+    dDot (a,b,2);
+    dDot (a,b,3);
+    dDot (a,b,5);
+    dDot (a,b,7);
+    dDot (a,b,11);
+    dDot (a,b,13);
+    dDot (a,b,17);
+    dDot (a,b,19);
+    dDot (a,b,23);
+    dDot (a,b,29);
+    dDot (a,b,31);
+    dDot (a,b,37);
+    dDot (a,b,41);
+    dDot (a,b,43);
+    dDot (a,b,47);
+    dDot (a,b,53);
+    dDot (a,b,59);
+    dDot (a,b,61);
+    dDot (a,b,67);
+    dDot (a,b,71);
+    dDot (a,b,73);
+    dDot (a,b,79);
+    dDot (a,b,83);
+    dDot (a,b,89);
+    dDot (a,b,97);
+    dDot (a,b,101);
+
+    dStopwatchStop (&sw);
+    double time = dStopwatchTime (&sw);
+    if (time < mintime) mintime = time;
+  }
+
+  printf ("%.0f",mintime * dTimerTicksPerSecond());
+}
+
+
+int main()
+{
+  testAccuracy();
+  testSpeed();
+  return 0;
+}
diff --git a/extern/ode/dist/ode/fbuild/test_ldlt.cpp b/extern/ode/dist/ode/fbuild/test_ldlt.cpp
new file mode 100644 (file)
index 0000000..3b795b9
--- /dev/null
@@ -0,0 +1,299 @@
+/*************************************************************************
+ *                                                                       *
+ * 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.                     *
+ *                                                                       *
+ *************************************************************************/
+
+#include <stdio.h>
+#include <malloc.h>
+#include "ode/ode.h"
+
+#define ALLOCA dALLOCA16
+
+//****************************************************************************
+// constants
+
+#ifdef dSINGLE
+#define TOL (1e-4)
+#else
+#define TOL (1e-10)
+#endif
+
+//****************************************************************************
+// test L*X=B solver accuracy.
+
+void testSolverAccuracy (int n)
+{
+  int i;
+  int npad = dPAD(n);
+  dReal *L = (dReal*) ALLOCA (n*npad*sizeof(dReal));
+  dReal *B = (dReal*) ALLOCA (n*sizeof(dReal));
+  dReal *B2 = (dReal*) ALLOCA (n*sizeof(dReal));
+  dReal *X = (dReal*) ALLOCA (n*sizeof(dReal));
+
+  // L is a random lower triangular matrix with 1's on the diagonal
+  dMakeRandomMatrix (L,n,n,1.0);
+  dClearUpperTriangle (L,n);
+  for (i=0; i<n; i++) L[i*npad+i] = 1;
+
+  // B is the right hand side
+  dMakeRandomMatrix (B,n,1,1.0);
+  memcpy (X,B,n*sizeof(dReal));        // copy B to X
+
+  dSolveL1 (L,X,n,npad);
+
+  /*
+  dPrintMatrix (L,n,n);
+  printf ("\n");
+  dPrintMatrix (B,n,1);
+  printf ("\n");
+  dPrintMatrix (X,n,1);
+  printf ("\n");
+  */
+
+  dSetZero (B2,n);
+  dMultiply0 (B2,L,X,n,n,1);
+  dReal error = dMaxDifference (B,B2,1,n);
+  if (error > TOL) {
+    printf ("error = %e, size = %d\n",error,n);
+  }
+}
+
+//****************************************************************************
+// test L^T*X=B solver accuracy.
+
+void testTransposeSolverAccuracy (int n)
+{
+  int i;
+  int npad = dPAD(n);
+  dReal *L = (dReal*) ALLOCA (n*npad*sizeof(dReal));
+  dReal *B = (dReal*) ALLOCA (n*sizeof(dReal));
+  dReal *B2 = (dReal*) ALLOCA (n*sizeof(dReal));
+  dReal *X = (dReal*) ALLOCA (n*sizeof(dReal));
+
+  // L is a random lower triangular matrix with 1's on the diagonal
+  dMakeRandomMatrix (L,n,n,1.0);
+  dClearUpperTriangle (L,n);
+  for (i=0; i<n; i++) L[i*npad+i] = 1;
+
+  // B is the right hand side
+  dMakeRandomMatrix (B,n,1,1.0);
+  memcpy (X,B,n*sizeof(dReal));        // copy B to X
+
+  dSolveL1T (L,X,n,npad);
+
+  dSetZero (B2,n);
+  dMultiply1 (B2,L,X,n,n,1);
+  dReal error = dMaxDifference (B,B2,1,n);
+  if (error > TOL) {
+    printf ("error = %e, size = %d\n",error,n);
+  }
+}
+
+//****************************************************************************
+// test L*D*L' factorizer accuracy.
+
+void testLDLTAccuracy (int n)
+{
+  int i,j;
+  int npad = dPAD(n);
+  dReal *A = (dReal*) ALLOCA (n*npad*sizeof(dReal));
+  dReal *L = (dReal*) ALLOCA (n*npad*sizeof(dReal));
+  dReal *d = (dReal*) ALLOCA (n*sizeof(dReal));
+  dReal *Atest = (dReal*) ALLOCA (n*npad*sizeof(dReal));
+  dReal *DL = (dReal*) ALLOCA (n*npad*sizeof(dReal));
+
+  dMakeRandomMatrix (A,n,n,1.0);
+  dMultiply2 (L,A,A,n,n,n);
+  memcpy (A,L,n*npad*sizeof(dReal));
+  dSetZero (d,n);
+
+  dFactorLDLT (L,d,n,npad);
+
+  // make L lower triangular, and convert d into diagonal of D
+  dClearUpperTriangle (L,n);
+  for (i=0; i<n; i++) L[i*npad+i] = 1;
+  for (i=0; i<n; i++) d[i] = 1.0/d[i];
+
+  // form Atest = L*D*L'
+  dSetZero (Atest,n*npad);
+  dSetZero (DL,n*npad);
+  for (i=0; i<n; i++) {
+    for (j=0; j<n; j++) DL[i*npad+j] = L[i*npad+j] * d[j];
+  }
+  dMultiply2 (Atest,L,DL,n,n,n);
+  dReal error = dMaxDifference (A,Atest,n,n);
+  if (error > TOL) {
+    printf ("error = %e, size = %d\n",error,n);
+  }
+
+  /*
+  printf ("\n");
+  dPrintMatrix (A,n,n);
+  printf ("\n");
+  dPrintMatrix (L,n,n);
+  printf ("\n");
+  dPrintMatrix (d,1,n);
+  */
+}
+
+//****************************************************************************
+// test L*D*L' factorizer speed.
+
+void testLDLTSpeed (int n)
+{
+  int npad = dPAD(n);
+
+  // allocate A
+  dReal *A = (dReal*) ALLOCA (n*npad*sizeof(dReal));
+
+  // make B a symmetric positive definite matrix
+  dMakeRandomMatrix (A,n,n,1.0);
+  dReal *B = (dReal*) ALLOCA (n*npad*sizeof(dReal));
+  dSetZero (B,n*npad);
+  dMultiply2 (B,A,A,n,n,n);
+
+  // make d
+  dReal *d = (dReal*) ALLOCA (n*sizeof(dReal));
+  dSetZero (d,n);
+
+  // time several factorizations, return the minimum timing
+  double mintime = 1e100;
+  dStopwatch sw;
+  for (int i=0; i<100; i++) {
+    memcpy (A,B,n*npad*sizeof(dReal));
+    dStopwatchReset (&sw);
+    dStopwatchStart (&sw);
+
+    dFactorLDLT (A,d,n,npad);
+
+    dStopwatchStop (&sw);
+    double time = dStopwatchTime (&sw);
+    if (time < mintime) mintime = time;
+  }
+
+  printf ("%.0f",mintime * dTimerTicksPerSecond());
+}
+
+//****************************************************************************
+// test solver speed.
+
+void testSolverSpeed (int n, int transpose)
+{
+  int i;
+  int npad = dPAD(n);
+
+  // allocate L,B,X
+  dReal *L = (dReal*) ALLOCA (n*npad*sizeof(dReal));
+  dReal *B = (dReal*) ALLOCA (n*sizeof(dReal));
+  dReal *X = (dReal*) ALLOCA (n*sizeof(dReal));
+
+  // L is a random lower triangular matrix with 1's on the diagonal
+  dMakeRandomMatrix (L,n,n,1.0);
+  dClearUpperTriangle (L,n);
+  for (i=0; i<n; i++) L[i*npad+i] = 1;
+
+  // B is the right hand side
+  dMakeRandomMatrix (B,n,1,1.0);
+
+  // time several factorizations, return the minimum timing
+  double mintime = 1e100;
+  dStopwatch sw;
+  for (int i=0; i<100; i++) {
+    memcpy (X,B,n*sizeof(dReal));      // copy B to X
+
+    if (transpose) {
+      dStopwatchReset (&sw);
+      dStopwatchStart (&sw);
+      dSolveL1T (L,X,n,npad);
+      dStopwatchStop (&sw);
+    }
+    else {
+      dStopwatchReset (&sw);
+      dStopwatchStart (&sw);
+      dSolveL1 (L,X,n,npad);
+      dStopwatchStop (&sw);
+    }
+
+    double time = dStopwatchTime (&sw);
+    if (time < mintime) mintime = time;
+  }
+
+  printf ("%.0f",mintime * dTimerTicksPerSecond());
+}
+
+//****************************************************************************
+// the single command line argument is 'f' to test and time the factorizer,
+// or 's' to test and time the solver.
+
+
+void testAccuracy (int n, char type)
+{
+  if (type == 'f') testLDLTAccuracy (n);
+  if (type == 's') testSolverAccuracy (n);
+  if (type == 't') testTransposeSolverAccuracy (n);
+}
+
+
+void testSpeed (int n, char type)
+{
+  if (type == 'f') testLDLTSpeed (n);
+  if (type == 's') testSolverSpeed (n,0);
+  if (type == 't') testSolverSpeed (n,1);
+}
+
+
+int main (int argc, char **argv)
+{
+  if (argc != 2 || argv[1][0] == 0 || argv[1][1] != 0 ||
+      (argv[1][0] != 'f' && argv[1][0] != 's' && argv[1][0] != 't')) {
+    fprintf (stderr,"Usage: test_ldlt [f|s|t]\n");
+    exit (1);
+  }
+  char type = argv[1][0];
+
+  // accuracy test: test all sizes up to 20 then all prime sizes up to 101
+  int i;
+  for (i=1; i<20; i++) {
+    testAccuracy (i,type);
+  }
+  testAccuracy (23,type);
+  testAccuracy (29,type);
+  testAccuracy (31,type);
+  testAccuracy (37,type);
+  testAccuracy (41,type);
+  testAccuracy (43,type);
+  testAccuracy (47,type);
+  testAccuracy (53,type);
+  testAccuracy (59,type);
+  testAccuracy (61,type);
+  testAccuracy (67,type);
+  testAccuracy (71,type);
+  testAccuracy (73,type);
+  testAccuracy (79,type);
+  testAccuracy (83,type);
+  testAccuracy (89,type);
+  testAccuracy (97,type);
+  testAccuracy (101,type);
+
+  // test speed on a 127x127 matrix
+  testSpeed (127,type);
+
+  return 0;
+}
diff --git a/extern/ode/dist/ode/fbuild/test_multidot.cpp b/extern/ode/dist/ode/fbuild/test_multidot.cpp
new file mode 100644 (file)
index 0000000..0e96115
--- /dev/null
@@ -0,0 +1,144 @@
+/*************************************************************************
+ *                                                                       *
+ * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith.       *
+ * All rights reserved.  Email: russ@q12.org   Web: www.q12.org          *
+ *                                                                       *
+ * This library is free software; you can redistribute it and/or         *
+ * modify it under the terms of EITHER:                                  *
+ *   (1) The GNU Lesser General Public License as published by the Free  *
+ *       Software Foundation; either version 2.1 of the License, or (at  *
+ *       your option) any later version. The text of the GNU Lesser      *
+ *       General Public License is included with this library in the     *
+ *       file LICENSE.TXT.                                               *
+ *   (2) The BSD-style license that is included with this library in     *
+ *       the file LICENSE-BSD.TXT.                                       *
+ *                                                                       *
+ * This library is distributed in the hope that it will be useful,       *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files    *
+ * LICENSE.TXT and LICENSE-BSD.TXT for more details.                     *
+ *                                                                       *
+ *************************************************************************/
+
+#include <stdio.h>
+#include "ode/ode.h"
+
+#define NUM_A 2
+#define ALLOCA dALLOCA16
+#define SIZE 1000
+
+
+extern "C" void dMultidot2 (const dReal *a0, const dReal *a1,
+                           const dReal *b, dReal *outsum, int n);
+/*
+extern "C" void dMultidot4 (const dReal *a0, const dReal *a1,
+                           const dReal *a2, const dReal *a3,
+                           const dReal *b, dReal *outsum, int n);
+*/
+
+
+// correct dot product, for accuracy testing
+
+dReal goodDot (dReal *a, dReal *b, int n)
+{
+  dReal sum=0;
+  while (n > 0) {
+    sum += (*a) * (*b);
+    a++;
+    b++;
+    n--;
+  }
+  return sum;
+}
+
+
+// test multi-dot product accuracy
+
+void testAccuracy()
+{
+  int j;
+
+  // allocate vectors a and b and fill them with random data
+  dReal *a[NUM_A];
+  for (j=0; j<NUM_A; j++) a[j] = (dReal*) ALLOCA (SIZE*sizeof(dReal));
+  dReal *b = (dReal*) ALLOCA (SIZE*sizeof(dReal));
+  for (j=0; j<NUM_A; j++) dMakeRandomMatrix (a[j],1,SIZE,1.0);
+  dMakeRandomMatrix (b,1,SIZE,1.0);
+
+  for (int n=1; n<100; n++) {
+    dReal good[NUM_A];
+    for (j=0; j<NUM_A; j++) good[j] = goodDot (a[j],b,n);
+    dReal test[4];
+    dMultidot2 (a[0],a[1],b,test,n);
+    dReal diff = 0;
+    for (j=0; j<NUM_A; j++) diff += fabs(good[j]-test[j]);
+    // printf ("diff = %e\n",diff);
+    if (diff > 1e-10) printf ("ERROR: accuracy test failed\n");
+  }
+}
+
+
+// test multi-dot product factorizer speed.
+
+void testSpeed()
+{
+  int j;
+  dReal sum[NUM_A];
+
+  // allocate vectors a and b and fill them with random data
+  dReal *a[NUM_A];
+  for (j=0; j<NUM_A; j++) a[j] = (dReal*) ALLOCA (SIZE*sizeof(dReal));
+  dReal *b = (dReal*) ALLOCA (SIZE*sizeof(dReal));
+  for (j=0; j<NUM_A; j++) dMakeRandomMatrix (a[j],1,SIZE,1.0);
+  dMakeRandomMatrix (b,1,SIZE,1.0);
+
+  // time several dot products, return the minimum timing
+  double mintime = 1e100;
+  dStopwatch sw;
+  for (int i=0; i<1000; i++) {
+    dStopwatchReset (&sw);
+    dStopwatchStart (&sw);
+
+    // try a bunch of prime sizes up to 101
+    dMultidot2 (a[0],a[1],b,sum,2);
+    dMultidot2 (a[0],a[1],b,sum,3);
+    dMultidot2 (a[0],a[1],b,sum,5);
+    dMultidot2 (a[0],a[1],b,sum,7);
+    dMultidot2 (a[0],a[1],b,sum,11);
+    dMultidot2 (a[0],a[1],b,sum,13);
+    dMultidot2 (a[0],a[1],b,sum,17);
+    dMultidot2 (a[0],a[1],b,sum,19);
+    dMultidot2 (a[0],a[1],b,sum,23);
+    dMultidot2 (a[0],a[1],b,sum,29);
+    dMultidot2 (a[0],a[1],b,sum,31);
+    dMultidot2 (a[0],a[1],b,sum,37);
+    dMultidot2 (a[0],a[1],b,sum,41);
+    dMultidot2 (a[0],a[1],b,sum,43);
+    dMultidot2 (a[0],a[1],b,sum,47);
+    dMultidot2 (a[0],a[1],b,sum,53);
+    dMultidot2 (a[0],a[1],b,sum,59);
+    dMultidot2 (a[0],a[1],b,sum,61);
+    dMultidot2 (a[0],a[1],b,sum,67);
+    dMultidot2 (a[0],a[1],b,sum,71);
+    dMultidot2 (a[0],a[1],b,sum,73);
+    dMultidot2 (a[0],a[1],b,sum,79);
+    dMultidot2 (a[0],a[1],b,sum,83);
+    dMultidot2 (a[0],a[1],b,sum,89);
+    dMultidot2 (a[0],a[1],b,sum,97);
+    dMultidot2 (a[0],a[1],b,sum,101);
+
+    dStopwatchStop (&sw);
+    double time = dStopwatchTime (&sw);
+    if (time < mintime) mintime = time;
+  }
+
+  printf ("%.0f",mintime * dTimerTicksPerSecond());
+}
+
+
+int main()
+{
+  testAccuracy();
+  testSpeed();
+  return 0;
+}
diff --git a/extern/ode/dist/ode/src/array.cpp b/extern/ode/dist/ode/src/array.cpp
new file mode 100644 (file)
index 0000000..cbb1a6e
--- /dev/null
@@ -0,0 +1,80 @@
+/*************************************************************************
+ *                                                                       *
+ * 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.                     *
+ *                                                                       *
+ *************************************************************************/
+
+#include <ode/config.h>
+#include <ode/memory.h>
+#include <ode/error.h>
+#include "array.h"
+
+
+static inline int roundUpToPowerOfTwo (int x)
+{
+  int i = 1;
+  while (i < x) i <<= 1;
+  return i;
+}
+
+
+void dArrayBase::_freeAll (int sizeofT)
+{
+  if (_data) {
+    if (_data == this+1) return;       // if constructLocalArray() was called
+    dFree (_data,_anum * sizeofT);
+  }
+}
+
+
+void dArrayBase::_setSize (int newsize, int sizeofT)
+{
+  if (newsize < 0) return;
+  if (newsize > _anum) {
+    if (_data == this+1) {
+      // this is a no-no, because constructLocalArray() was called
+      dDebug (0,"setSize() out of space in LOCAL array");
+    }
+    int newanum = roundUpToPowerOfTwo (newsize);
+    if (_data) _data = dRealloc (_data, _anum*sizeofT, newanum*sizeofT);
+    else _data = dAlloc (newanum*sizeofT);
+    _anum = newanum;
+  }
+  _size = newsize;
+}
+
+
+void * dArrayBase::operator new (size_t size)
+{
+  return dAlloc (size);
+}
+
+
+void dArrayBase::operator delete (void *ptr, size_t size)
+{
+  dFree (ptr,size);
+}
+
+
+void dArrayBase::constructLocalArray (int __anum)
+{
+  _size = 0;
+  _anum = __anum;
+  _data = this+1;
+}
diff --git a/extern/ode/dist/ode/src/array.h b/extern/ode/dist/ode/src/array.h
new file mode 100644 (file)
index 0000000..ae5caf2
--- /dev/null
@@ -0,0 +1,135 @@
+/*************************************************************************
+ *                                                                       *
+ * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith.       *
+ * All rights reserved.  Email: russ@q12.org   Web: www.q12.org          *
+ *                                                                       *
+ * This library is free software; you can redistribute it and/or         *
+ * modify it under the terms of EITHER:                                  *
+ *   (1) The GNU Lesser General Public License as published by the Free  *
+ *       Software Foundation; either version 2.1 of the License, or (at  *
+ *       your option) any later version. The text of the GNU Lesser      *
+ *       General Public License is included with this library in the     *
+ *       file LICENSE.TXT.                                               *
+ *   (2) The BSD-style license that is included with this library in     *
+ *       the file LICENSE-BSD.TXT.                                       *
+ *                                                                       *
+ * This library is distributed in the hope that it will be useful,       *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files    *
+ * LICENSE.TXT and LICENSE-BSD.TXT for more details.                     *
+ *                                                                       *
+ *************************************************************************/
+
+/* this comes from the `reuse' library. copy any changes back to the source.
+ *
+ * Variable sized array template. The array is always stored in a contiguous
+ * chunk. The array can be resized. A size increase will cause more memory
+ * to be allocated, and may result in relocation of the array memory.
+ * A size decrease has no effect on the memory allocation.
+ *
+ * Array elements with constructors or destructors are not supported!
+ * But if you must have such elements, here's what to know/do:
+ *   - Bitwise copy is used when copying whole arrays.
+ *   - When copying individual items (via push(), insert() etc) the `='
+ *     (equals) operator is used. Thus you should define this operator to do
+ *     a bitwise copy. You should probably also define the copy constructor.
+ */
+
+
+#ifndef _ODE_ARRAY_H_
+#define _ODE_ARRAY_H_
+
+#include <ode/config.h>
+
+
+// this base class has no constructors or destructor, for your convenience.
+
+class dArrayBase {
+protected:
+  int _size;           // number of elements in `data'
+  int _anum;           // allocated number of elements in `data'
+  void *_data;         // array data
+
+  void _freeAll (int sizeofT);
+  void _setSize (int newsize, int sizeofT);
+  // set the array size to `newsize', allocating more memory if necessary.
+  // if newsize>_anum and is a power of two then this is guaranteed to
+  // set _size and _anum to newsize.
+
+public:
+  // not: dArrayBase () { _size=0; _anum=0; _data=0; }
+
+  int size() const { return _size; }
+  int allocatedSize() const { return _anum; }
+  void * operator new (size_t size);
+  void operator delete (void *ptr, size_t size);
+
+  void constructor() { _size=0; _anum=0; _data=0; }
+  // if this structure is allocated with malloc() instead of new, you can
+  // call this to set it up.
+
+  void constructLocalArray (int __anum);
+  // this helper function allows non-reallocating arrays to be constructed
+  // on the stack (or in the heap if necessary). this is something of a
+  // kludge and should be used with extreme care. this function acts like
+  // a constructor - it is called on uninitialized memory that will hold the
+  // Array structure and the data. __anum is the number of elements that
+  // are allocated. the memory MUST be allocated with size:
+  //   sizeof(ArrayBase) + __anum*sizeof(T)
+  // arrays allocated this way will never try to reallocate or free the
+  // memory - that's your job.
+};
+
+
+template <class T> class dArray : public dArrayBase {
+public:
+  void equals (const dArray<T> &x) {
+    setSize (x.size());
+    memcpy (_data,x._data,x._size * sizeof(T));
+  }
+
+  dArray () { constructor(); }
+  dArray (const dArray<T> &x) { constructor(); equals (x); }
+  ~dArray () { _freeAll(sizeof(T)); }
+  void setSize (int newsize) { _setSize (newsize,sizeof(T)); }
+  T *data() const { return (T*) _data; }
+  T & operator[] (int i) const { return ((T*)_data)[i]; }
+  void operator = (const dArray<T> &x) { equals (x); }
+
+  void push (const T item) {
+    if (_size < _anum) _size++; else _setSize (_size+1,sizeof(T));
+    ((T*)_data)[_size-1] = item;
+  }
+
+  void swap (dArray<T> &x) {
+    int tmp1;
+    void *tmp2;
+    tmp1=_size; _size=x._size; x._size=tmp1;
+    tmp1=_anum; _anum=x._anum; x._anum=tmp1;
+    tmp2=_data; _data=x._data; x._data=tmp2;
+  }
+
+  // insert the item at the position `i'. if i<0 then add the item to the
+  // start, if i >= size then add the item to the end of the array.
+  void insert (int i, const T item) {
+    if (_size < _anum) _size++; else _setSize (_size+1,sizeof(T));
+    if (i >= (_size-1)) i = _size-1;   // add to end
+    else {
+      if (i < 0) i=0;                  // add to start
+      int n = _size-1-i;
+      if (n>0) memmove (((T*)_data) + i+1, ((T*)_data) + i, n*sizeof(T));
+    }
+    ((T*)_data)[i] = item;
+  }
+
+  void remove (int i) {
+    if (i >= 0 && i < _size) { // passing this test guarantees size>0
+      int n = _size-1-i;
+      if (n>0) memmove (((T*)_data) + i, ((T*)_data) + i+1, n*sizeof(T));
+      _size--;
+    }
+  }
+};
+
+
+#endif
diff --git a/extern/ode/dist/ode/src/error.cpp b/extern/ode/dist/ode/src/error.cpp
new file mode 100644 (file)
index 0000000..9b33db5
--- /dev/null
@@ -0,0 +1,172 @@
+/*************************************************************************
+ *                                                                       *
+ * 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.                     *
+ *                                                                       *
+ *************************************************************************/
+
+#include <ode/config.h>
+#include <ode/error.h>
+
+
+static dMessageFunction *error_function = 0;
+static dMessageFunction *debug_function = 0;
+static dMessageFunction *message_function = 0;
+
+
+extern "C" void dSetErrorHandler (dMessageFunction *fn)
+{
+  error_function = fn;
+}
+
+
+extern "C" void dSetDebugHandler (dMessageFunction *fn)
+{
+  debug_function = fn;
+}
+
+
+extern "C" void dSetMessageHandler (dMessageFunction *fn)
+{
+  message_function = fn;
+}
+
+
+extern "C" dMessageFunction *dGetErrorHandler()
+{
+  return error_function;
+}
+
+
+extern "C" dMessageFunction *dGetDebugHandler()
+{
+  return debug_function;
+}
+
+
+extern "C" dMessageFunction *dGetMessageHandler()
+{
+  return message_function;
+}
+
+
+static void printMessage (int num, const char *msg1, const char *msg2,
+                         va_list ap)
+{
+  fflush (stderr);
+  fflush (stdout);
+  if (num) fprintf (stderr,"\n%s %d: ",msg1,num);
+  else fprintf (stderr,"\n%s: ",msg1);
+  vfprintf (stderr,msg2,ap);
+  fprintf (stderr,"\n");
+  fflush (stderr);
+}
+
+//****************************************************************************
+// unix
+
+#ifndef WIN32
+
+extern "C" void dError (int num, const char *msg, ...)
+{
+  va_list ap;
+  va_start (ap,msg);
+  if (error_function) error_function (num,msg,ap);
+  else printMessage (num,"ODE Error",msg,ap);
+  exit (1);
+}
+
+
+extern "C" void dDebug (int num, const char *msg, ...)
+{
+  va_list ap;
+  va_start (ap,msg);
+  if (debug_function) debug_function (num,msg,ap);
+  else printMessage (num,"ODE INTERNAL ERROR",msg,ap);
+  // *((char *)0) = 0;   ... commit SEGVicide
+  abort();
+}
+
+
+extern "C" void dMessage (int num, const char *msg, ...)
+{
+  va_list ap;
+  va_start (ap,msg);
+  if (message_function) message_function (num,msg,ap);
+  else printMessage (num,"ODE Message",msg,ap);
+}
+
+#endif
+
+//****************************************************************************
+// windows
+
+#ifdef WIN32
+
+// isn't cygwin annoying!
+#ifdef CYGWIN
+#define _snprintf snprintf
+#define _vsnprintf vsnprintf
+#endif
+
+
+#include "windows.h"
+
+
+extern "C" void dError (int num, const char *msg, ...)
+{
+  va_list ap;
+  va_start (ap,msg);
+  if (error_function) error_function (num,msg,ap);
+  else {
+    char s[1000],title[100];
+    _snprintf (title,sizeof(title),"ODE Error %d",num);
+    _vsnprintf (s,sizeof(s),msg,ap);
+    s[sizeof(s)-1] = 0;
+    MessageBox(0,s,title,MB_OK | MB_ICONWARNING);
+  }
+  exit (1);
+}
+
+
+extern "C" void dDebug (int num, const char *msg, ...)
+{
+  va_list ap;
+  va_start (ap,msg);
+  if (debug_function) debug_function (num,msg,ap);
+  else {
+    char s[1000],title[100];
+    _snprintf (title,sizeof(title),"ODE INTERNAL ERROR %d",num);
+    _vsnprintf (s,sizeof(s),msg,ap);
+    s[sizeof(s)-1] = 0;
+    MessageBox(0,s,title,MB_OK | MB_ICONSTOP);
+  }
+  abort();
+}
+
+
+extern "C" void dMessage (int num, const char *msg, ...)
+{
+  va_list ap;
+  va_start (ap,msg);
+  if (message_function) message_function (num,msg,ap);
+  else printMessage (num,"ODE Message",msg,ap);
+}
+
+
+#endif
diff --git a/extern/ode/dist/ode/src/fastdot.c b/extern/ode/dist/ode/src/fastdot.c
new file mode 100644 (file)
index 0000000..148d2dd
--- /dev/null
@@ -0,0 +1,30 @@
+/* generated code, do not edit. */
+
+#include "ode/matrix.h"
+
+
+dReal dDot (const dReal *a, const dReal *b, int n)
+{  
+  dReal p0,q0,m0,p1,q1,m1,sum;
+  sum = 0;
+  n -= 2;
+  while (n >= 0) {
+    p0 = a[0]; q0 = b[0];
+    m0 = p0 * q0;
+    p1 = a[1]; q1 = b[1];
+    m1 = p1 * q1;
+    sum += m0;
+    sum += m1;
+    a += 2;
+    b += 2;
+    n -= 2;
+  }
+  n += 2;
+  while (n > 0) {
+    sum += (*a) * (*b);
+    a++;
+    b++;
+    n--;
+  }
+  return sum;
+}
diff --git a/extern/ode/dist/ode/src/fastldlt.c b/extern/ode/dist/ode/src/fastldlt.c
new file mode 100644 (file)
index 0000000..df2ea6e
--- /dev/null
@@ -0,0 +1,381 @@
+/* generated code, do not edit. */
+
+#include "ode/matrix.h"
+
+/* solve L*X=B, with B containing 1 right hand sides.
+ * L is an n*n lower triangular matrix with ones on the diagonal.
+ * L is stored by rows and its leading dimension is lskip.
+ * B is an n*1 matrix that contains the right hand sides.
+ * B is stored by columns and its leading dimension is also lskip.
+ * B is overwritten with X.
+ * this processes blocks of 2*2.
+ * if this is in the factorizer source file, n must be a multiple of 2.
+ */
+
+static void dSolveL1_1 (const dReal *L, dReal *B, int n, int lskip1)
+{  
+  /* declare variables - Z matrix, p and q vectors, etc */
+  dReal Z11,m11,Z21,m21,p1,q1,p2,*ex;
+  const dReal *ell;
+  int i,j;
+  /* compute all 2 x 1 blocks of X */
+  for (i=0; i < n; i+=2) {
+    /* compute all 2 x 1 block of X, from rows i..i+2-1 */
+    /* set the Z matrix to 0 */
+    Z11=0;
+    Z21=0;
+    ell = L + i*lskip1;
+    ex = B;
+    /* the inner loop that computes outer products and adds them to Z */
+    for (j=i-2; j >= 0; j -= 2) {
+      /* compute outer product and add it to the Z matrix */
+      p1=ell[0];
+      q1=ex[0];
+      m11 = p1 * q1;
+      p2=ell[lskip1];
+      m21 = p2 * q1;
+      Z11 += m11;
+      Z21 += m21;
+      /* compute outer product and add it to the Z matrix */
+      p1=ell[1];
+      q1=ex[1];
+      m11 = p1 * q1;
+      p2=ell[1+lskip1];
+      m21 = p2 * q1;
+      /* advance pointers */
+      ell += 2;
+      ex += 2;
+      Z11 += m11;
+      Z21 += m21;
+      /* end of inner loop */
+    }
+    /* compute left-over iterations */
+    j += 2;
+    for (; j > 0; j--) {
+      /* compute outer product and add it to the Z matrix */
+      p1=ell[0];
+      q1=ex[0];
+      m11 = p1 * q1;
+      p2=ell[lskip1];
+      m21 = p2 * q1;
+      /* advance pointers */
+      ell += 1;
+      ex += 1;
+      Z11 += m11;
+      Z21 += m21;
+    }
+    /* finish computing the X(i) block */
+    Z11 = ex[0] - Z11;
+    ex[0] = Z11;
+    p1 = ell[lskip1];
+    Z21 = ex[1] - Z21 - p1*Z11;
+    ex[1] = Z21;
+    /* end of outer loop */
+  }
+}
+
+/* solve L*X=B, with B containing 2 right hand sides.
+ * L is an n*n lower triangular matrix with ones on the diagonal.
+ * L is stored by rows and its leading dimension is lskip.
+ * B is an n*2 matrix that contains the right hand sides.
+ * B is stored by columns and its leading dimension is also lskip.
+ * B is overwritten with X.
+ * this processes blocks of 2*2.
+ * if this is in the factorizer source file, n must be a multiple of 2.
+ */
+
+static void dSolveL1_2 (const dReal *L, dReal *B, int n, int lskip1)
+{  
+  /* declare variables - Z matrix, p and q vectors, etc */
+  dReal Z11,m11,Z12,m12,Z21,m21,Z22,m22,p1,q1,p2,q2,*ex;
+  const dReal *ell;
+  int i,j;
+  /* compute all 2 x 2 blocks of X */
+  for (i=0; i < n; i+=2) {
+    /* compute all 2 x 2 block of X, from rows i..i+2-1 */
+    /* set the Z matrix to 0 */
+    Z11=0;
+    Z12=0;
+    Z21=0;
+    Z22=0;
+    ell = L + i*lskip1;
+    ex = B;
+    /* the inner loop that computes outer products and adds them to Z */
+    for (j=i-2; j >= 0; j -= 2) {
+      /* compute outer product and add it to the Z matrix */
+      p1=ell[0];
+      q1=ex[0];
+      m11 = p1 * q1;
+      q2=ex[lskip1];
+      m12 = p1 * q2;
+      p2=ell[lskip1];
+      m21 = p2 * q1;
+      m22 = p2 * q2;
+      Z11 += m11;
+      Z12 += m12;
+      Z21 += m21;
+      Z22 += m22;
+      /* compute outer product and add it to the Z matrix */
+      p1=ell[1];
+      q1=ex[1];
+      m11 = p1 * q1;
+      q2=ex[1+lskip1];
+      m12 = p1 * q2;
+      p2=ell[1+lskip1];
+      m21 = p2 * q1;
+      m22 = p2 * q2;
+      /* advance pointers */
+      ell += 2;
+      ex += 2;
+      Z11 += m11;
+      Z12 += m12;
+      Z21 += m21;
+      Z22 += m22;
+      /* end of inner loop */
+    }
+    /* compute left-over iterations */
+    j += 2;
+    for (; j > 0; j--) {
+      /* compute outer product and add it to the Z matrix */
+      p1=ell[0];
+      q1=ex[0];
+      m11 = p1 * q1;
+      q2=ex[lskip1];
+      m12 = p1 * q2;
+      p2=ell[lskip1];
+      m21 = p2 * q1;
+      m22 = p2 * q2;
+      /* advance pointers */
+      ell += 1;
+      ex += 1;
+      Z11 += m11;
+      Z12 += m12;
+      Z21 += m21;
+      Z22 += m22;
+    }
+    /* finish computing the X(i) block */
+    Z11 = ex[0] - Z11;
+    ex[0] = Z11;
+    Z12 = ex[lskip1] - Z12;
+    ex[lskip1] = Z12;
+    p1 = ell[lskip1];
+    Z21 = ex[1] - Z21 - p1*Z11;
+    ex[1] = Z21;
+    Z22 = ex[1+lskip1] - Z22 - p1*Z12;
+    ex[1+lskip1] = Z22;
+    /* end of outer loop */
+  }
+}
+
+
+void dFactorLDLT (dReal *A, dReal *d, int n, int nskip1)
+{  
+  int i,j;
+  dReal sum,*ell,*dee,dd,p1,p2,q1,q2,Z11,m11,Z21,m21,Z22,m22;
+  if (n < 1) return;
+  
+  for (i=0; i<=n-2; i += 2) {
+    /* solve L*(D*l)=a, l is scaled elements in 2 x i block at A(i,0) */
+    dSolveL1_2 (A,A+i*nskip1,i,nskip1);
+    /* scale the elements in a 2 x i block at A(i,0), and also */
+    /* compute Z = the outer product matrix that we'll need. */
+    Z11 = 0;
+    Z21 = 0;
+    Z22 = 0;
+    ell = A+i*nskip1;
+    dee = d;
+    for (j=i-6; j >= 0; j -= 6) {
+      p1 = ell[0];
+      p2 = ell[nskip1];
+      dd = dee[0];
+      q1 = p1*dd;
+      q2 = p2*dd;
+      ell[0] = q1;
+      ell[nskip1] = q2;
+      m11 = p1*q1;
+      m21 = p2*q1;
+      m22 = p2*q2;
+      Z11 += m11;
+      Z21 += m21;
+      Z22 += m22;
+      p1 = ell[1];
+      p2 = ell[1+nskip1];
+      dd = dee[1];
+      q1 = p1*dd;
+      q2 = p2*dd;
+      ell[1] = q1;
+      ell[1+nskip1] = q2;
+      m11 = p1*q1;
+      m21 = p2*q1;
+      m22 = p2*q2;
+      Z11 += m11;
+      Z21 += m21;
+      Z22 += m22;
+      p1 = ell[2];
+      p2 = ell[2+nskip1];
+      dd = dee[2];
+      q1 = p1*dd;
+      q2 = p2*dd;
+      ell[2] = q1;
+      ell[2+nskip1] = q2;
+      m11 = p1*q1;
+      m21 = p2*q1;
+      m22 = p2*q2;
+      Z11 += m11;
+      Z21 += m21;
+      Z22 += m22;
+      p1 = ell[3];
+      p2 = ell[3+nskip1];
+      dd = dee[3];
+      q1 = p1*dd;
+      q2 = p2*dd;
+      ell[3] = q1;
+      ell[3+nskip1] = q2;
+      m11 = p1*q1;
+      m21 = p2*q1;
+      m22 = p2*q2;
+      Z11 += m11;
+      Z21 += m21;
+      Z22 += m22;
+      p1 = ell[4];
+      p2 = ell[4+nskip1];
+      dd = dee[4];
+      q1 = p1*dd;
+      q2 = p2*dd;
+      ell[4] = q1;
+      ell[4+nskip1] = q2;
+      m11 = p1*q1;
+      m21 = p2*q1;
+      m22 = p2*q2;
+      Z11 += m11;
+      Z21 += m21;
+      Z22 += m22;
+      p1 = ell[5];
+      p2 = ell[5+nskip1];
+      dd = dee[5];
+      q1 = p1*dd;
+      q2 = p2*dd;
+      ell[5] = q1;
+      ell[5+nskip1] = q2;
+      m11 = p1*q1;
+      m21 = p2*q1;
+      m22 = p2*q2;
+      Z11 += m11;
+      Z21 += m21;
+      Z22 += m22;
+      ell += 6;
+      dee += 6;
+    }
+    /* compute left-over iterations */
+    j += 6;
+    for (; j > 0; j--) {
+      p1 = ell[0];
+      p2 = ell[nskip1];
+      dd = dee[0];
+      q1 = p1*dd;
+      q2 = p2*dd;
+      ell[0] = q1;
+      ell[nskip1] = q2;
+      m11 = p1*q1;
+      m21 = p2*q1;
+      m22 = p2*q2;
+      Z11 += m11;
+      Z21 += m21;
+      Z22 += m22;
+      ell++;
+      dee++;
+    }
+    /* solve for diagonal 2 x 2 block at A(i,i) */
+    Z11 = ell[0] - Z11;
+    Z21 = ell[nskip1] - Z21;
+    Z22 = ell[1+nskip1] - Z22;
+    dee = d + i;
+    /* factorize 2 x 2 block Z,dee */
+    /* factorize row 1 */
+    dee[0] = dRecip(Z11);
+    /* factorize row 2 */
+    sum = 0;
+    q1 = Z21;
+    q2 = q1 * dee[0];
+    Z21 = q2;
+    sum += q1*q2;
+    dee[1] = dRecip(Z22 - sum);
+    /* done factorizing 2 x 2 block */
+    ell[nskip1] = Z21;
+  }
+  /* compute the (less than 2) rows at the bottom */
+  switch (n-i) {
+    case 0:
+    break;
+    
+    case 1:
+    dSolveL1_1 (A,A+i*nskip1,i,nskip1);
+    /* scale the elements in a 1 x i block at A(i,0), and also */
+    /* compute Z = the outer product matrix that we'll need. */
+    Z11 = 0;
+    ell = A+i*nskip1;
+    dee = d;
+    for (j=i-6; j >= 0; j -= 6) {
+      p1 = ell[0];
+      dd = dee[0];
+      q1 = p1*dd;
+      ell[0] = q1;
+      m11 = p1*q1;
+      Z11 += m11;
+      p1 = ell[1];
+      dd = dee[1];
+      q1 = p1*dd;
+      ell[1] = q1;
+      m11 = p1*q1;
+      Z11 += m11;
+      p1 = ell[2];
+      dd = dee[2];
+      q1 = p1*dd;
+      ell[2] = q1;
+      m11 = p1*q1;
+      Z11 += m11;
+      p1 = ell[3];
+      dd = dee[3];
+      q1 = p1*dd;
+      ell[3] = q1;
+      m11 = p1*q1;
+      Z11 += m11;
+      p1 = ell[4];
+      dd = dee[4];
+      q1 = p1*dd;
+      ell[4] = q1;
+      m11 = p1*q1;
+      Z11 += m11;
+      p1 = ell[5];
+      dd = dee[5];
+      q1 = p1*dd;
+      ell[5] = q1;
+      m11 = p1*q1;
+      Z11 += m11;
+      ell += 6;
+      dee += 6;
+    }
+    /* compute left-over iterations */
+    j += 6;
+    for (; j > 0; j--) {
+      p1 = ell[0];
+      dd = dee[0];
+      q1 = p1*dd;
+      ell[0] = q1;
+      m11 = p1*q1;
+      Z11 += m11;
+      ell++;
+      dee++;
+    }
+    /* solve for diagonal 1 x 1 block at A(i,i) */
+    Z11 = ell[0] - Z11;
+    dee = d + i;
+    /* factorize 1 x 1 block Z,dee */
+    /* factorize row 1 */
+    dee[0] = dRecip(Z11);
+    /* done factorizing 1 x 1 block */
+    break;
+    
+    default: *((char*)0)=0;  /* this should never happen! */
+  }
+}
diff --git a/extern/ode/dist/ode/src/fastlsolve.c b/extern/ode/dist/ode/src/fastlsolve.c
new file mode 100644 (file)
index 0000000..0ae99d6
--- /dev/null
@@ -0,0 +1,298 @@
+/* generated code, do not edit. */
+
+#include "ode/matrix.h"
+
+/* solve L*X=B, with B containing 1 right hand sides.
+ * L is an n*n lower triangular matrix with ones on the diagonal.
+ * L is stored by rows and its leading dimension is lskip.
+ * B is an n*1 matrix that contains the right hand sides.
+ * B is stored by columns and its leading dimension is also lskip.
+ * B is overwritten with X.
+ * this processes blocks of 4*4.
+ * if this is in the factorizer source file, n must be a multiple of 4.
+ */
+
+void dSolveL1 (const dReal *L, dReal *B, int n, int lskip1)
+{  
+  /* declare variables - Z matrix, p and q vectors, etc */
+  dReal Z11,Z21,Z31,Z41,p1,q1,p2,p3,p4,*ex;
+  const dReal *ell;
+  int lskip2,lskip3,i,j;
+  /* compute lskip values */
+  lskip2 = 2*lskip1;
+  lskip3 = 3*lskip1;
+  /* compute all 4 x 1 blocks of X */
+  for (i=0; i <= n-4; i+=4) {
+    /* compute all 4 x 1 block of X, from rows i..i+4-1 */
+    /* set the Z matrix to 0 */
+    Z11=0;
+    Z21=0;
+    Z31=0;
+    Z41=0;
+    ell = L + i*lskip1;
+    ex = B;
+    /* the inner loop that computes outer products and adds them to Z */
+    for (j=i-12; j >= 0; j -= 12) {
+      /* load p and q values */
+      p1=ell[0];
+      q1=ex[0];
+      p2=ell[lskip1];
+      p3=ell[lskip2];
+      p4=ell[lskip3];
+      /* compute outer product and add it to the Z matrix */
+      Z11 += p1 * q1;
+      Z21 += p2 * q1;
+      Z31 += p3 * q1;
+      Z41 += p4 * q1;
+      /* load p and q values */
+      p1=ell[1];
+      q1=ex[1];
+      p2=ell[1+lskip1];
+      p3=ell[1+lskip2];
+      p4=ell[1+lskip3];
+      /* compute outer product and add it to the Z matrix */
+      Z11 += p1 * q1;
+      Z21 += p2 * q1;
+      Z31 += p3 * q1;
+      Z41 += p4 * q1;
+      /* load p and q values */
+      p1=ell[2];
+      q1=ex[2];
+      p2=ell[2+lskip1];
+      p3=ell[2+lskip2];
+      p4=ell[2+lskip3];
+      /* compute outer product and add it to the Z matrix */
+      Z11 += p1 * q1;
+      Z21 += p2 * q1;
+      Z31 += p3 * q1;
+      Z41 += p4 * q1;
+      /* load p and q values */
+      p1=ell[3];
+      q1=ex[3];
+      p2=ell[3+lskip1];
+      p3=ell[3+lskip2];
+      p4=ell[3+lskip3];
+      /* compute outer product and add it to the Z matrix */
+      Z11 += p1 * q1;
+      Z21 += p2 * q1;
+      Z31 += p3 * q1;
+      Z41 += p4 * q1;
+      /* load p and q values */
+      p1=ell[4];
+      q1=ex[4];
+      p2=ell[4+lskip1];
+      p3=ell[4+lskip2];
+      p4=ell[4+lskip3];
+      /* compute outer product and add it to the Z matrix */
+      Z11 += p1 * q1;
+      Z21 += p2 * q1;
+      Z31 += p3 * q1;
+      Z41 += p4 * q1;
+      /* load p and q values */
+      p1=ell[5];
+      q1=ex[5];
+      p2=ell[5+lskip1];
+      p3=ell[5+lskip2];
+      p4=ell[5+lskip3];
+      /* compute outer product and add it to the Z matrix */
+      Z11 += p1 * q1;
+      Z21 += p2 * q1;
+      Z31 += p3 * q1;
+      Z41 += p4 * q1;
+      /* load p and q values */
+      p1=ell[6];
+      q1=ex[6];
+      p2=ell[6+lskip1];
+      p3=ell[6+lskip2];
+      p4=ell[6+lskip3];
+      /* compute outer product and add it to the Z matrix */
+      Z11 += p1 * q1;
+      Z21 += p2 * q1;
+      Z31 += p3 * q1;
+      Z41 += p4 * q1;
+      /* load p and q values */
+      p1=ell[7];
+      q1=ex[7];
+      p2=ell[7+lskip1];
+      p3=ell[7+lskip2];
+      p4=ell[7+lskip3];
+      /* compute outer product and add it to the Z matrix */
+      Z11 += p1 * q1;
+      Z21 += p2 * q1;
+      Z31 += p3 * q1;
+      Z41 += p4 * q1;
+      /* load p and q values */
+      p1=ell[8];
+      q1=ex[8];
+      p2=ell[8+lskip1];
+      p3=ell[8+lskip2];
+      p4=ell[8+lskip3];
+      /* compute outer product and add it to the Z matrix */
+      Z11 += p1 * q1;
+      Z21 += p2 * q1;
+      Z31 += p3 * q1;
+      Z41 += p4 * q1;
+      /* load p and q values */
+      p1=ell[9];
+      q1=ex[9];
+      p2=ell[9+lskip1];
+      p3=ell[9+lskip2];
+      p4=ell[9+lskip3];
+      /* compute outer product and add it to the Z matrix */
+      Z11 += p1 * q1;
+      Z21 += p2 * q1;
+      Z31 += p3 * q1;
+      Z41 += p4 * q1;
+      /* load p and q values */
+      p1=ell[10];
+      q1=ex[10];
+      p2=ell[10+lskip1];
+      p3=ell[10+lskip2];
+      p4=ell[10+lskip3];
+      /* compute outer product and add it to the Z matrix */
+      Z11 += p1 * q1;
+      Z21 += p2 * q1;
+      Z31 += p3 * q1;
+      Z41 += p4 * q1;
+      /* load p and q values */
+      p1=ell[11];
+      q1=ex[11];
+      p2=ell[11+lskip1];
+      p3=ell[11+lskip2];
+      p4=ell[11+lskip3];
+      /* compute outer product and add it to the Z matrix */
+      Z11 += p1 * q1;
+      Z21 += p2 * q1;
+      Z31 += p3 * q1;
+      Z41 += p4 * q1;
+      /* advance pointers */
+      ell += 12;
+      ex += 12;
+      /* end of inner loop */
+    }
+    /* compute left-over iterations */
+    j += 12;
+    for (; j > 0; j--) {
+      /* load p and q values */
+      p1=ell[0];
+      q1=ex[0];
+      p2=ell[lskip1];
+      p3=ell[lskip2];
+      p4=ell[lskip3];
+      /* compute outer product and add it to the Z matrix */
+      Z11 += p1 * q1;
+      Z21 += p2 * q1;
+      Z31 += p3 * q1;
+      Z41 += p4 * q1;
+      /* advance pointers */
+      ell += 1;
+      ex += 1;
+    }
+    /* finish computing the X(i) block */
+    Z11 = ex[0] - Z11;
+    ex[0] = Z11;
+    p1 = ell[lskip1];
+    Z21 = ex[1] - Z21 - p1*Z11;
+    ex[1] = Z21;
+    p1 = ell[lskip2];
+    p2 = ell[1+lskip2];
+    Z31 = ex[2] - Z31 - p1*Z11 - p2*Z21;
+    ex[2] = Z31;
+    p1 = ell[lskip3];
+    p2 = ell[1+lskip3];
+    p3 = ell[2+lskip3];
+    Z41 = ex[3] - Z41 - p1*Z11 - p2*Z21 - p3*Z31;
+    ex[3] = Z41;
+    /* end of outer loop */
+  }
+  /* compute rows at end that are not a multiple of block size */
+  for (; i < n; i++) {
+    /* compute all 1 x 1 block of X, from rows i..i+1-1 */
+    /* set the Z matrix to 0 */
+    Z11=0;
+    ell = L + i*lskip1;
+    ex = B;
+    /* the inner loop that computes outer products and adds them to Z */
+    for (j=i-12; j >= 0; j -= 12) {
+      /* load p and q values */
+      p1=ell[0];
+      q1=ex[0];
+      /* compute outer product and add it to the Z matrix */
+      Z11 += p1 * q1;
+      /* load p and q values */
+      p1=ell[1];
+      q1=ex[1];
+      /* compute outer product and add it to the Z matrix */
+      Z11 += p1 * q1;
+      /* load p and q values */
+      p1=ell[2];
+      q1=ex[2];
+      /* compute outer product and add it to the Z matrix */
+      Z11 += p1 * q1;
+      /* load p and q values */
+      p1=ell[3];
+      q1=ex[3];
+      /* compute outer product and add it to the Z matrix */
+      Z11 += p1 * q1;
+      /* load p and q values */
+      p1=ell[4];
+      q1=ex[4];
+      /* compute outer product and add it to the Z matrix */
+      Z11 += p1 * q1;
+      /* load p and q values */
+      p1=ell[5];
+      q1=ex[5];
+      /* compute outer product and add it to the Z matrix */
+      Z11 += p1 * q1;
+      /* load p and q values */
+      p1=ell[6];
+      q1=ex[6];
+      /* compute outer product and add it to the Z matrix */
+      Z11 += p1 * q1;
+      /* load p and q values */
+      p1=ell[7];
+      q1=ex[7];
+      /* compute outer product and add it to the Z matrix */
+      Z11 += p1 * q1;
+      /* load p and q values */
+      p1=ell[8];
+      q1=ex[8];
+      /* compute outer product and add it to the Z matrix */
+      Z11 += p1 * q1;
+      /* load p and q values */
+      p1=ell[9];
+      q1=ex[9];
+      /* compute outer product and add it to the Z matrix */
+      Z11 += p1 * q1;
+      /* load p and q values */
+      p1=ell[10];
+      q1=ex[10];
+      /* compute outer product and add it to the Z matrix */
+      Z11 += p1 * q1;
+      /* load p and q values */
+      p1=ell[11];
+      q1=ex[11];
+      /* compute outer product and add it to the Z matrix */
+      Z11 += p1 * q1;
+      /* advance pointers */
+      ell += 12;
+      ex += 12;
+      /* end of inner loop */
+    }
+    /* compute left-over iterations */
+    j += 12;
+    for (; j > 0; j--) {
+      /* load p and q values */
+      p1=ell[0];
+      q1=ex[0];
+      /* compute outer product and add it to the Z matrix */
+      Z11 += p1 * q1;
+      /* advance pointers */
+      ell += 1;
+      ex += 1;
+    }
+    /* finish computing the X(i) block */
+    Z11 = ex[0] - Z11;
+    ex[0] = Z11;
+  }
+}
diff --git a/extern/ode/dist/ode/src/fastltsolve.c b/extern/ode/dist/ode/src/fastltsolve.c
new file mode 100644 (file)
index 0000000..eb950f6
--- /dev/null
@@ -0,0 +1,199 @@
+/* generated code, do not edit. */
+
+#include "ode/matrix.h"
+
+/* solve L^T * x=b, with b containing 1 right hand side.