checkin of ODE library. Do not modify the ODE source code; instead, follow the

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.
This commit is contained in:
Norman Lin
2002-10-18 15:02:02 +00:00
parent 1b15961786
commit bdad961ce3
97 changed files with 21829 additions and 0 deletions

44
extern/ode/dist/INSTALL vendored Normal file
View File

@@ -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 * ?

34
extern/ode/dist/LICENSE-BSD.TXT vendored Normal file
View File

@@ -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.

502
extern/ode/dist/LICENSE.TXT vendored Normal file
View File

@@ -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.
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.
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.
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.
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.
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.
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.
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.
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
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!

280
extern/ode/dist/Makefile vendored Normal file
View File

@@ -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

456
extern/ode/dist/Makefile.deps vendored Normal file
View File

@@ -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

30
extern/ode/dist/README vendored Normal file
View File

@@ -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

18
extern/ode/dist/README_BLENDER vendored Normal file
View File

@@ -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.

41
extern/ode/dist/config/README vendored Normal file
View File

@@ -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

28
extern/ode/dist/config/makefile.cygwin vendored Normal file
View File

@@ -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

28
extern/ode/dist/config/makefile.mingw vendored Normal file
View File

@@ -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

27
extern/ode/dist/config/makefile.msvc vendored Normal file
View File

@@ -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

View File

@@ -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,$@)

26
extern/ode/dist/config/makefile.osx vendored Normal file
View File

@@ -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

View File

@@ -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

View File

@@ -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

228
extern/ode/dist/config/msvcdefs.def vendored Normal file
View File

@@ -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

31
extern/ode/dist/config/user-settings vendored Normal file
View File

@@ -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

View File

@@ -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

437
extern/ode/dist/configurator.c vendored Normal file
View File

@@ -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;
}

18
extern/ode/dist/include/ode/README vendored Normal file
View File

@@ -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!

306
extern/ode/dist/include/ode/common.h vendored Normal file
View File

@@ -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

90
extern/ode/dist/include/ode/contact.h vendored Normal file
View File

@@ -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

63
extern/ode/dist/include/ode/error.h vendored Normal file
View File

@@ -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

152
extern/ode/dist/include/ode/geom.h vendored Normal file
View File

@@ -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

97
extern/ode/dist/include/ode/mass.h vendored Normal file
View File

@@ -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

194
extern/ode/dist/include/ode/matrix.h vendored Normal file
View File

@@ -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

63
extern/ode/dist/include/ode/memory.h vendored Normal file
View File

@@ -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

85
extern/ode/dist/include/ode/misc.h vendored Normal file
View File

@@ -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

201
extern/ode/dist/include/ode/objects.h vendored Normal file
View File

@@ -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

44
extern/ode/dist/include/ode/ode.h vendored Normal file
View File

@@ -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

796
extern/ode/dist/include/ode/odecpp.h vendored Normal file
View File

@@ -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

316
extern/ode/dist/include/ode/odecpp_old.h vendored Normal file
View File

@@ -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

216
extern/ode/dist/include/ode/odemath.h vendored Normal file
View File

@@ -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

64
extern/ode/dist/include/ode/rotation.h vendored Normal file
View File

@@ -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

77
extern/ode/dist/include/ode/space.h vendored Normal file
View File

@@ -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

76
extern/ode/dist/include/ode/timer.h vendored Normal file
View File

@@ -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

158
extern/ode/dist/ode/README vendored Normal file
View File

@@ -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.

148
extern/ode/dist/ode/fbuild/BuildDot vendored Normal file
View File

@@ -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

654
extern/ode/dist/ode/fbuild/BuildLDLT vendored Normal file
View File

@@ -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;

174
extern/ode/dist/ode/fbuild/BuildMultidot vendored Normal file
View File

@@ -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");

99
extern/ode/dist/ode/fbuild/BuildUtil vendored Normal file
View File

@@ -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;

16
extern/ode/dist/ode/fbuild/Dependencies vendored Normal file
View File

@@ -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

77
extern/ode/dist/ode/fbuild/Makefile vendored Normal file
View File

@@ -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

71
extern/ode/dist/ode/fbuild/OptimizeDot vendored Normal file
View File

@@ -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');

91
extern/ode/dist/ode/fbuild/OptimizeLDLT vendored Normal file
View File

@@ -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');

View File

@@ -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');

View File

@@ -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');

View File

@@ -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');

86
extern/ode/dist/ode/fbuild/OptimizeUtil vendored Normal file
View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

41
extern/ode/dist/ode/fbuild/README vendored Normal file
View File

@@ -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

26
extern/ode/dist/ode/fbuild/ldlt.m vendored Normal file
View File

@@ -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;

124
extern/ode/dist/ode/fbuild/test_dot.cpp vendored Normal file
View File

@@ -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;
}

299
extern/ode/dist/ode/fbuild/test_ldlt.cpp vendored Normal file
View File

@@ -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;
}

View File

@@ -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;
}

80
extern/ode/dist/ode/src/array.cpp vendored Normal file
View File

@@ -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;
}

135
extern/ode/dist/ode/src/array.h vendored Normal file
View File

@@ -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

172
extern/ode/dist/ode/src/error.cpp vendored Normal file
View File

@@ -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

30
extern/ode/dist/ode/src/fastdot.c vendored Normal file
View File

@@ -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;
}

381
extern/ode/dist/ode/src/fastldlt.c vendored Normal file
View File

@@ -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! */
}
}

298
extern/ode/dist/ode/src/fastlsolve.c vendored Normal file
View File

@@ -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;
}
}

199
extern/ode/dist/ode/src/fastltsolve.c vendored Normal file
View File

@@ -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.
* 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 4.
*/
void dSolveL1T (const dReal *L, dReal *B, int n, int lskip1)
{
/* declare variables - Z matrix, p and q vectors, etc */
dReal Z11,m11,Z21,m21,Z31,m31,Z41,m41,p1,q1,p2,p3,p4,*ex;
const dReal *ell;
int lskip2,lskip3,i,j;
/* special handling for L and B because we're solving L1 *transpose* */
L = L + (n-1)*(lskip1+1);
B = B + n-1;
lskip1 = -lskip1;
/* 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;
ex = B;
/* the inner loop that computes outer products and adds them to Z */
for (j=i-4; j >= 0; j -= 4) {
/* load p and q values */
p1=ell[0];
q1=ex[0];
p2=ell[-1];
p3=ell[-2];
p4=ell[-3];
/* compute outer product and add it to the Z matrix */
m11 = p1 * q1;
m21 = p2 * q1;
m31 = p3 * q1;
m41 = p4 * q1;
ell += lskip1;
Z11 += m11;
Z21 += m21;
Z31 += m31;
Z41 += m41;
/* load p and q values */
p1=ell[0];
q1=ex[-1];
p2=ell[-1];
p3=ell[-2];
p4=ell[-3];
/* compute outer product and add it to the Z matrix */
m11 = p1 * q1;
m21 = p2 * q1;
m31 = p3 * q1;
m41 = p4 * q1;
ell += lskip1;
Z11 += m11;
Z21 += m21;
Z31 += m31;
Z41 += m41;
/* load p and q values */
p1=ell[0];
q1=ex[-2];
p2=ell[-1];
p3=ell[-2];
p4=ell[-3];
/* compute outer product and add it to the Z matrix */
m11 = p1 * q1;
m21 = p2 * q1;
m31 = p3 * q1;
m41 = p4 * q1;
ell += lskip1;
Z11 += m11;
Z21 += m21;
Z31 += m31;
Z41 += m41;
/* load p and q values */
p1=ell[0];
q1=ex[-3];
p2=ell[-1];
p3=ell[-2];
p4=ell[-3];
/* compute outer product and add it to the Z matrix */
m11 = p1 * q1;
m21 = p2 * q1;
m31 = p3 * q1;
m41 = p4 * q1;
ell += lskip1;
ex -= 4;
Z11 += m11;
Z21 += m21;
Z31 += m31;
Z41 += m41;
/* end of inner loop */
}
/* compute left-over iterations */
j += 4;
for (; j > 0; j--) {
/* load p and q values */
p1=ell[0];
q1=ex[0];
p2=ell[-1];
p3=ell[-2];
p4=ell[-3];
/* compute outer product and add it to the Z matrix */
m11 = p1 * q1;
m21 = p2 * q1;
m31 = p3 * q1;
m41 = p4 * q1;
ell += lskip1;
ex -= 1;
Z11 += m11;
Z21 += m21;
Z31 += m31;
Z41 += m41;
}
/* finish computing the X(i) block */
Z11 = ex[0] - Z11;
ex[0] = Z11;
p1 = ell[-1];
Z21 = ex[-1] - Z21 - p1*Z11;
ex[-1] = Z21;
p1 = ell[-2];
p2 = ell[-2+lskip1];
Z31 = ex[-2] - Z31 - p1*Z11 - p2*Z21;
ex[-2] = Z31;
p1 = ell[-3];
p2 = ell[-3+lskip1];
p3 = ell[-3+lskip2];
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;
ex = B;
/* the inner loop that computes outer products and adds them to Z */
for (j=i-4; j >= 0; j -= 4) {
/* load p and q values */
p1=ell[0];
q1=ex[0];
/* compute outer product and add it to the Z matrix */
m11 = p1 * q1;
ell += lskip1;
Z11 += m11;
/* load p and q values */
p1=ell[0];
q1=ex[-1];
/* compute outer product and add it to the Z matrix */
m11 = p1 * q1;
ell += lskip1;
Z11 += m11;
/* load p and q values */
p1=ell[0];
q1=ex[-2];
/* compute outer product and add it to the Z matrix */
m11 = p1 * q1;
ell += lskip1;
Z11 += m11;
/* load p and q values */
p1=ell[0];
q1=ex[-3];
/* compute outer product and add it to the Z matrix */
m11 = p1 * q1;
ell += lskip1;
ex -= 4;
Z11 += m11;
/* end of inner loop */
}
/* compute left-over iterations */
j += 4;
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 */
m11 = p1 * q1;
ell += lskip1;
ex -= 1;
Z11 += m11;
}
/* finish computing the X(i) block */
Z11 = ex[0] - Z11;
ex[0] = Z11;
}
}

2207
extern/ode/dist/ode/src/geom.cpp vendored Normal file

File diff suppressed because it is too large Load Diff

84
extern/ode/dist/ode/src/geom_internal.h vendored Normal file
View File

@@ -0,0 +1,84 @@
/*************************************************************************
* *
* 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_INTERNAL_H_
#define _ODE_GEOM_INTERNAL_H_
// mask for the number-of-contacts field in the dCollide() flags parameter
#define NUMC_MASK (0xffff)
// internal info for geometry class
struct dxGeomClass {
dGetColliderFnFn *collider;
dGetAABBFn *aabb;
dAABBTestFn *aabb_test;
dGeomDtorFn *dtor;
int num; // class number
int size; // total size of object, including extra data area
};
// position vector and rotation matrix for geometry objects that are not
// connected to bodies.
struct dxPosR {
dVector3 pos;
dMatrix3 R;
};
// common data for all geometry objects. the class-specific data area follows
// this structure. pos and R will either point to a separately allocated
// buffer (if body is 0 - pos points to the dxPosR object) or to the pos and
// R of the body (if body nonzero).
struct dxGeom { // a dGeomID is a pointer to this
dxGeomClass *_class; // class of this object
void *data; // user data pointer
dBodyID body; // dynamics body associated with this object (if any)
dReal *pos; // pointer to object's position vector
dReal *R; // pointer to object's rotation matrix
dSpaceID spaceid; // the space this object is in
dGeomSpaceData space; // reserved for use by space this object is in
dReal *space_aabb; // ptr to aabb array held by dSpaceCollide() fn
// class-specific data follows here, with proper alignment.
};
// this is the size of the dxGeom structure rounded up to a multiple of 16
// bytes. any class specific data that comes after this will have the correct
// alignment.
#define SIZEOF_DXGEOM dEFFICIENT_SIZE(sizeof(dxGeom))
// given a pointer to a dxGeom, return a pointer to the class data that
// follows it.
#define CLASSDATA(geomptr) (((char*)geomptr) + SIZEOF_DXGEOM)
#endif

2160
extern/ode/dist/ode/src/joint.cpp vendored Normal file

File diff suppressed because it is too large Load Diff

261
extern/ode/dist/ode/src/joint.h vendored Normal file
View File

@@ -0,0 +1,261 @@
/*************************************************************************
* *
* 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_JOINT_H_
#define _ODE_JOINT_H_
#include "objects.h"
#include <ode/contact.h>
#include "obstack.h"
// joint flags
enum {
// if this flag is set, the joint was allocated in a joint group
dJOINT_INGROUP = 1,
// if this flag is set, the joint was attached with arguments (0,body).
// our convention is to treat all attaches as (body,0), i.e. so node[0].body
// is always nonzero, so this flag records the fact that the arguments were
// swapped.
dJOINT_REVERSE = 2,
// if this flag is set, the joint can not have just one body attached to it,
// it must have either zero or two bodies attached.
dJOINT_TWOBODIES = 4
};
// there are two of these nodes in the joint, one for each connection to a
// body. these are node of a linked list kept by each body of it's connecting
// joints. but note that the body pointer in each node points to the body that
// makes use of the *other* node, not this node. this trick makes it a bit
// easier to traverse the body/joint graph.
struct dxJointNode {
dxJoint *joint; // pointer to enclosing dxJoint object
dxBody *body; // *other* body this joint is connected to
dxJointNode *next; // next node in body's list of connected joints
};
struct dxJoint : public dObject {
// naming convention: the "first" body this is connected to is node[0].body,
// and the "second" body is node[1].body. if this joint is only connected
// to one body then the second body is 0.
// info returned by getInfo1 function. the constraint dimension is m (<=6).
// i.e. that is the total number of rows in the jacobian. `nub' is the
// number of unbounded variables (which have lo,hi = -/+ infinity).
struct Info1 {
int m,nub;
};
// info returned by getInfo2 function
struct Info2 {
// integrator parameters: frames per second (1/stepsize), default error
// reduction parameter (0..1).
dReal fps,erp;
// for the first and second body, pointers to two (linear and angular)
// n*3 jacobian sub matrices, stored by rows. these matrices will have
// been initialized to 0 on entry. if the second body is zero then the
// J2xx pointers may be 0.
dReal *J1l,*J1a,*J2l,*J2a;
// elements to jump from one row to the next in J's
int rowskip;
// right hand sides of the equation J*v = c + cfm * lambda. cfm is the
// "constraint force mixing" vector. c is set to zero on entry, cfm is
// set to a constant value (typically very small or zero) value on entry.
dReal *c,*cfm;
// lo and hi limits for variables (set to -/+ infinity on entry).
dReal *lo,*hi;
// findex vector for variables. see the LCP solver interface for a
// description of what this does. this is set to -1 on entry.
// note that the returned indexes are relative to the first index of
// the constraint.
int *findex;
};
// virtual function table: size of the joint structure, function pointers.
// we do it this way instead of using C++ virtual functions because
// sometimes we need to allocate joints ourself within a memory pool.
typedef void init_fn (dxJoint *joint);
typedef void getInfo1_fn (dxJoint *joint, Info1 *info);
typedef void getInfo2_fn (dxJoint *joint, Info2 *info);
struct Vtable {
int size;
init_fn *init;
getInfo1_fn *getInfo1;
getInfo2_fn *getInfo2;
int typenum; // a dJointTypeXXX type number
};
Vtable *vtable; // virtual function table
int flags; // dJOINT_xxx flags
dxJointNode node[2]; // connections to bodies. node[1].body can be 0
dJointFeedback *feedback; // optional feedback structure
};
// joint group. NOTE: any joints in the group that have their world destroyed
// will have their world pointer set to 0.
struct dxJointGroup : public dBase {
int num; // number of joints on the stack
dObStack stack; // a stack of (possibly differently sized) dxJoint
}; // objects.
// common limit and motor information for a single joint axis of movement
struct dxJointLimitMotor {
dReal vel,fmax; // powered joint: velocity, max force
dReal lostop,histop; // joint limits, relative to initial position
dReal fudge_factor; // when powering away from joint limits
dReal normal_cfm; // cfm to use when not at a stop
dReal stop_erp,stop_cfm; // erp and cfm for when at joint limit
dReal bounce; // restitution factor
// variables used between getInfo1() and getInfo2()
int limit; // 0=free, 1=at lo limit, 2=at hi limit
dReal limit_err; // if at limit, amount over limit
void init (dxWorld *);
void set (int num, dReal value);
dReal get (int num);
int testRotationalLimit (dReal angle);
int addLimot (dxJoint *joint, dxJoint::Info2 *info, int row,
dVector3 ax1, int rotational);
};
// ball and socket
struct dxJointBall : public dxJoint {
dVector3 anchor1; // anchor w.r.t first body
dVector3 anchor2; // anchor w.r.t second body
};
extern struct dxJoint::Vtable __dball_vtable;
// hinge
struct dxJointHinge : public dxJoint {
dVector3 anchor1; // anchor w.r.t first body
dVector3 anchor2; // anchor w.r.t second body
dVector3 axis1; // axis w.r.t first body
dVector3 axis2; // axis w.r.t second body
dQuaternion qrel; // initial relative rotation body1 -> body2
dxJointLimitMotor limot; // limit and motor information
};
extern struct dxJoint::Vtable __dhinge_vtable;
// universal
struct dxJointUniversal : public dxJoint {
dVector3 anchor1; // anchor w.r.t first body
dVector3 anchor2; // anchor w.r.t second body
dVector3 axis1; // axis w.r.t first body
dVector3 axis2; // axis w.r.t second body
};
extern struct dxJoint::Vtable __duniversal_vtable;
// slider. if body2 is 0 then qrel is the absolute rotation of body1 and
// offset is the position of body1 center along axis1.
struct dxJointSlider : public dxJoint {
dVector3 axis1; // axis w.r.t first body
dQuaternion qrel; // initial relative rotation body1 -> body2
dVector3 offset; // point relative to body2 that should be
// aligned with body1 center along axis1
dxJointLimitMotor limot; // limit and motor information
};
extern struct dxJoint::Vtable __dslider_vtable;
// contact
struct dxJointContact : public dxJoint {
int the_m; // number of rows computed by getInfo1
dContact contact;
};
extern struct dxJoint::Vtable __dcontact_vtable;
// hinge 2
struct dxJointHinge2 : public dxJoint {
dVector3 anchor1; // anchor w.r.t first body
dVector3 anchor2; // anchor w.r.t second body
dVector3 axis1; // axis 1 w.r.t first body
dVector3 axis2; // axis 2 w.r.t second body
dReal c0,s0; // cos,sin of desired angle between axis 1,2
dVector3 v1,v2; // angle ref vectors embedded in first body
dxJointLimitMotor limot1; // limit+motor info for axis 1
dxJointLimitMotor limot2; // limit+motor info for axis 2
dReal susp_erp,susp_cfm; // suspension parameters (erp,cfm)
};
extern struct dxJoint::Vtable __dhinge2_vtable;
// angular motor
struct dxJointAMotor : public dxJoint {
int num; // number of axes (0..3)
int mode; // a dAMotorXXX constant
int rel[3]; // what the axes are relative to (global,b1,b2)
dVector3 axis[3]; // three axes
dxJointLimitMotor limot[3]; // limit+motor info for axes
dReal angle[3]; // user-supplied angles for axes
// these vectors are used for calculating euler angles
dVector3 reference1; // original axis[2], relative to body 1
dVector3 reference2; // original axis[0], relative to body 2
};
extern struct dxJoint::Vtable __damotor_vtable;
// fixed
struct dxJointFixed : public dxJoint {
dVector3 offset; // relative offset between the bodies
};
extern struct dxJoint::Vtable __dfixed_vtable;
// null joint, for testing only
struct dxJointNull : public dxJoint {
};
extern struct dxJoint::Vtable __dnull_vtable;
#endif

1455
extern/ode/dist/ode/src/lcp.cpp vendored Normal file

File diff suppressed because it is too large Load Diff

58
extern/ode/dist/ode/src/lcp.h vendored Normal file
View File

@@ -0,0 +1,58 @@
/*************************************************************************
* *
* 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. *
* *
*************************************************************************/
/*
given (A,b,lo,hi), solve the LCP problem: A*x = b+w, where each x(i),w(i)
satisfies one of
(1) x = lo, w >= 0
(2) x = hi, w <= 0
(3) lo < x < hi, w = 0
A is a matrix of dimension n*n, everything else is a vector of size n*1.
lo and hi can be +/- dInfinity as needed. the first `nub' variables are
unbounded, i.e. hi and lo are assumed to be +/- dInfinity.
we restrict lo(i) <= 0 and hi(i) >= 0.
the original data (A,b) may be modified by this function.
if the `findex' (friction index) parameter is nonzero, it points to an array
of index values. in this case constraints that have findex[i] >= 0 are
special. all non-special constraints are solved for, then the lo and hi values
for the special constraints are set:
hi[i] = abs( hi[i] * x[findex[i]] )
lo[i] = -hi[i]
and the solution continues. this mechanism allows a friction approximation
to be implemented.
*/
#ifndef _ODE_LCP_H_
#define _ODE_LCP_H_
void dSolveLCP (int n, dReal *A, dReal *x, dReal *b, dReal *w,
int nub, dReal *lo, dReal *hi, int *findex);
#endif

261
extern/ode/dist/ode/src/mass.cpp vendored Normal file
View File

@@ -0,0 +1,261 @@
/*************************************************************************
* *
* 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/mass.h>
#include <ode/odemath.h>
#include <ode/matrix.h>
#define _I(i,j) I[(i)*4+(j)]
// return 1 if ok, 0 if bad
static int checkMass (dMass *m)
{
if (m->mass <= 0) {
dDEBUGMSG ("mass must be > 0");
return 0;
}
if (!dIsPositiveDefinite (m->I,3)) {
dDEBUGMSG ("inertia must be positive definite");
return 0;
}
// verify that the center of mass position is consistent with the mass
// and inertia matrix. this is done by checking that the inertia around
// the center of mass is also positive definite. from the comment in
// dMassTranslate(), if the body is translated so that its center of mass
// is at the point of reference, then the new inertia is:
// I + mass*crossmat(c)^2
// note that requiring this to be positive definite is exactly equivalent
// to requiring that the spatial inertia matrix
// [ mass*eye(3,3) M*crossmat(c)^T ]
// [ M*crossmat(c) I ]
// is positive definite, given that I is PD and mass>0. see the theorem
// about partitioned PD matrices for proof.
dMatrix3 I2,chat;
dSetZero (chat,12);
dCROSSMAT (chat,m->c,4,+,-);
dMULTIPLY0_333 (I2,chat,chat);
for (int i=0; i<12; i++) I2[i] = m->I[i] + m->mass*I2[i];
if (!dIsPositiveDefinite (I2,3)) {
dDEBUGMSG ("center of mass inconsistent with mass parameters");
return 0;
}
return 1;
}
void dMassSetZero (dMass *m)
{
dAASSERT (m);
m->mass = REAL(0.0);
dSetZero (m->c,sizeof(m->c) / sizeof(dReal));
dSetZero (m->I,sizeof(m->I) / sizeof(dReal));
}
void dMassSetParameters (dMass *m, dReal themass,
dReal cgx, dReal cgy, dReal cgz,
dReal I11, dReal I22, dReal I33,
dReal I12, dReal I13, dReal I23)
{
dAASSERT (m);
dMassSetZero (m);
m->mass = themass;
m->c[0] = cgx;
m->c[1] = cgy;
m->c[2] = cgz;
m->_I(0,0) = I11;
m->_I(1,1) = I22;
m->_I(2,2) = I33;
m->_I(0,1) = I12;
m->_I(0,2) = I13;
m->_I(1,2) = I23;
m->_I(1,0) = I12;
m->_I(2,0) = I13;
m->_I(2,1) = I23;
checkMass (m);
}
void dMassSetSphere (dMass *m, dReal density, dReal radius)
{
dAASSERT (m);
dMassSetZero (m);
m->mass = (REAL(4.0)/REAL(3.0)) * M_PI * radius*radius*radius * density;
dReal II = REAL(0.4) * m->mass * radius*radius;
m->_I(0,0) = II;
m->_I(1,1) = II;
m->_I(2,2) = II;
# ifndef dNODEBUG
checkMass (m);
# endif
}
void dMassSetCappedCylinder (dMass *m, dReal density, int direction,
dReal a, dReal b)
{
dReal M1,M2,Ia,Ib;
dAASSERT (m);
dUASSERT (direction >= 1 && direction <= 3,"bad direction number");
dMassSetZero (m);
M1 = M_PI*a*a*b*density; // cylinder mass
M2 = (REAL(4.0)/REAL(3.0))*M_PI*a*a*a*density; // total cap mass
m->mass = M1+M2;
Ia = M1*(REAL(0.25)*a*a + (REAL(1.0)/REAL(12.0))*b*b) +
M2*(REAL(0.4)*a*a + REAL(0.5)*b*b);
Ib = (M1*REAL(0.5) + M2*REAL(0.4))*a*a;
m->_I(0,0) = Ia;
m->_I(1,1) = Ia;
m->_I(2,2) = Ia;
m->_I(direction-1,direction-1) = Ib;
# ifndef dNODEBUG
checkMass (m);
# endif
}
void dMassSetBox (dMass *m, dReal density,
dReal lx, dReal ly, dReal lz)
{
dAASSERT (m);
dMassSetZero (m);
dReal M = lx*ly*lz*density;
m->mass = M;
m->_I(0,0) = M/REAL(12.0) * (ly*ly + lz*lz);
m->_I(1,1) = M/REAL(12.0) * (lx*lx + lz*lz);
m->_I(2,2) = M/REAL(12.0) * (lx*lx + ly*ly);
# ifndef dNODEBUG
checkMass (m);
# endif
}
void dMassAdjust (dMass *m, dReal newmass)
{
dAASSERT (m);
dReal scale = newmass / m->mass;
m->mass = newmass;
for (int i=0; i<3; i++) for (int j=0; j<3; j++) m->_I(i,j) *= scale;
# ifndef dNODEBUG
checkMass (m);
# endif
}
void dMassTranslate (dMass *m, dReal x, dReal y, dReal z)
{
// if the body is translated by `a' relative to its point of reference,
// the new inertia about the point of reference is:
//
// I + mass*(crossmat(c)^2 - crossmat(c+a)^2)
//
// where c is the existing center of mass and I is the old inertia.
int i,j;
dMatrix3 ahat,chat,t1,t2;
dReal a[3];
dAASSERT (m);
// adjust inertia matrix
dSetZero (chat,12);
dCROSSMAT (chat,m->c,4,+,-);
a[0] = x + m->c[0];
a[1] = y + m->c[1];
a[2] = z + m->c[2];
dSetZero (ahat,12);
dCROSSMAT (ahat,a,4,+,-);
dMULTIPLY0_333 (t1,ahat,ahat);
dMULTIPLY0_333 (t2,chat,chat);
for (i=0; i<3; i++) for (j=0; j<3; j++)
m->_I(i,j) += m->mass * (t2[i*4+j]-t1[i*4+j]);
// ensure perfect symmetry
m->_I(1,0) = m->_I(0,1);
m->_I(2,0) = m->_I(0,2);
m->_I(2,1) = m->_I(1,2);
// adjust center of mass
m->c[0] += x;
m->c[1] += y;
m->c[2] += z;
# ifndef dNODEBUG
checkMass (m);
# endif
}
void dMassRotate (dMass *m, const dMatrix3 R)
{
// if the body is rotated by `R' relative to its point of reference,
// the new inertia about the point of reference is:
//
// R * I * R'
//
// where I is the old inertia.
dMatrix3 t1;
dReal t2[3];
dAASSERT (m);
// rotate inertia matrix
dMULTIPLY2_333 (t1,m->I,R);
dMULTIPLY0_333 (m->I,R,t1);
// ensure perfect symmetry
m->_I(1,0) = m->_I(0,1);
m->_I(2,0) = m->_I(0,2);
m->_I(2,1) = m->_I(1,2);
// rotate center of mass
dMULTIPLY0_331 (t2,R,m->c);
m->c[0] = t2[0];
m->c[1] = t2[1];
m->c[2] = t2[2];
# ifndef dNODEBUG
checkMass (m);
# endif
}
void dMassAdd (dMass *a, const dMass *b)
{
int i;
dAASSERT (a && b);
dReal denom = dRecip (a->mass + b->mass);
for (i=0; i<3; i++) a->c[i] = (a->c[i]*a->mass + b->c[i]*b->mass)*denom;
a->mass += b->mass;
for (i=0; i<12; i++) a->I[i] += b->I[i];
}

230
extern/ode/dist/ode/src/mat.cpp vendored Normal file
View File

@@ -0,0 +1,230 @@
/*************************************************************************
* *
* 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/misc.h>
#include <ode/matrix.h>
#include <ode/error.h>
#include <ode/memory.h>
#include "mat.h"
dMatrix::dMatrix()
{
n = 0;
m = 0;
data = 0;
}
dMatrix::dMatrix (int rows, int cols)
{
if (rows < 1 || cols < 1) dDebug (0,"bad matrix size");
n = rows;
m = cols;
data = (dReal*) dAlloc (n*m*sizeof(dReal));
dSetZero (data,n*m);
}
dMatrix::dMatrix (const dMatrix &a)
{
n = a.n;
m = a.m;
data = (dReal*) dAlloc (n*m*sizeof(dReal));
memcpy (data,a.data,n*m*sizeof(dReal));
}
dMatrix::dMatrix (int rows, int cols,
dReal *_data, int rowskip, int colskip)
{
if (rows < 1 || cols < 1) dDebug (0,"bad matrix size");
n = rows;
m = cols;
data = (dReal*) dAlloc (n*m*sizeof(dReal));
for (int i=0; i<n; i++) {
for (int j=0; j<m; j++) data[i*m+j] = _data[i*rowskip + j*colskip];
}
}
dMatrix::~dMatrix()
{
if (data) dFree (data,n*m*sizeof(dReal));
}
dReal & dMatrix::operator () (int i, int j)
{
if (i < 0 || i >= n || j < 0 || j >= m) dDebug (0,"bad matrix (i,j)");
return data [i*m+j];
}
void dMatrix::operator= (const dMatrix &a)
{
if (data) dFree (data,n*m*sizeof(dReal));
n = a.n;
m = a.m;
if (n > 0 && m > 0) {
data = (dReal*) dAlloc (n*m*sizeof(dReal));
memcpy (data,a.data,n*m*sizeof(dReal));
}
else data = 0;
}
void dMatrix::operator= (dReal a)
{
for (int i=0; i<n*m; i++) data[i] = a;
}
dMatrix dMatrix::transpose()
{
dMatrix r (m,n);
for (int i=0; i<n; i++) {
for (int j=0; j<m; j++) r.data[j*n+i] = data[i*m+j];
}
return r;
}
dMatrix dMatrix::select (int np, int *p, int nq, int *q)
{
if (np < 1 || nq < 1) dDebug (0,"Matrix select, bad index array sizes");
dMatrix r (np,nq);
for (int i=0; i<np; i++) {
for (int j=0; j<nq; j++) {
if (p[i] < 0 || p[i] >= n || q[i] < 0 || q[i] >= m)
dDebug (0,"Matrix select, bad index arrays");
r.data[i*nq+j] = data[p[i]*m+q[j]];
}
}
return r;
}
dMatrix dMatrix::operator + (const dMatrix &a)
{
if (n != a.n || m != a.m) dDebug (0,"matrix +, mismatched sizes");
dMatrix r (n,m);
for (int i=0; i<n*m; i++) r.data[i] = data[i] + a.data[i];
return r;
}
dMatrix dMatrix::operator - (const dMatrix &a)
{
if (n != a.n || m != a.m) dDebug (0,"matrix -, mismatched sizes");
dMatrix r (n,m);
for (int i=0; i<n*m; i++) r.data[i] = data[i] - a.data[i];
return r;
}
dMatrix dMatrix::operator - ()
{
dMatrix r (n,m);
for (int i=0; i<n*m; i++) r.data[i] = -data[i];
return r;
}
dMatrix dMatrix::operator * (const dMatrix &a)
{
if (m != a.n) dDebug (0,"matrix *, mismatched sizes");
dMatrix r (n,a.m);
for (int i=0; i<n; i++) {
for (int j=0; j<a.m; j++) {
dReal sum = 0;
for (int k=0; k<m; k++) sum += data[i*m+k] * a.data[k*a.m+j];
r.data [i*a.m+j] = sum;
}
}
return r;
}
void dMatrix::operator += (const dMatrix &a)
{
if (n != a.n || m != a.m) dDebug (0,"matrix +=, mismatched sizes");
for (int i=0; i<n*m; i++) data[i] += a.data[i];
}
void dMatrix::operator -= (const dMatrix &a)
{
if (n != a.n || m != a.m) dDebug (0,"matrix -=, mismatched sizes");
for (int i=0; i<n*m; i++) data[i] -= a.data[i];
}
void dMatrix::clearUpperTriangle()
{
if (n != m) dDebug (0,"clearUpperTriangle() only works on square matrices");
for (int i=0; i<n; i++) {
for (int j=i+1; j<m; j++) data[i*m+j] = 0;
}
}
void dMatrix::clearLowerTriangle()
{
if (n != m) dDebug (0,"clearLowerTriangle() only works on square matrices");
for (int i=0; i<n; i++) {
for (int j=0; j<i; j++) data[i*m+j] = 0;
}
}
void dMatrix::makeRandom (dReal range)
{
for (int i=0; i<n; i++) {
for (int j=0; j<m; j++)
data[i*m+j] = (dRandReal()*REAL(2.0)-REAL(1.0))*range;
}
}
void dMatrix::print (char *fmt, FILE *f)
{
for (int i=0; i<n; i++) {
for (int j=0; j<m; j++) fprintf (f,fmt,data[i*m+j]);
fprintf (f,"\n");
}
}
dReal dMatrix::maxDifference (const dMatrix &a)
{
if (n != a.n || m != a.m) dDebug (0,"maxDifference(), mismatched sizes");
dReal max = 0;
for (int i=0; i<n; i++) {
for (int j=0; j<m; j++) {
dReal diff = dFabs(data[i*m+j] - a.data[i*m+j]);
if (diff > max) max = diff;
}
}
return max;
}

71
extern/ode/dist/ode/src/mat.h vendored Normal file
View File

@@ -0,0 +1,71 @@
/*************************************************************************
* *
* 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. *
* *
*************************************************************************/
// matrix class. this is mostly for convenience in the testing code, it is
// not optimized at all. correctness is much more importance here.
#ifndef _ODE_MAT_H_
#define _ODE_MAT_H_
#include <ode/common.h>
class dMatrix {
int n,m; // matrix dimension, n,m >= 0
dReal *data; // if nonzero, n*m elements allocated on the heap
public:
// constructors, destructors
dMatrix(); // make default 0x0 matrix
dMatrix (int rows, int cols); // construct zero matrix of given size
dMatrix (const dMatrix &); // construct copy of given matrix
// create copy of given data - element (i,j) is data[i*rowskip+j*colskip]
dMatrix (int rows, int cols, dReal *_data, int rowskip, int colskip);
~dMatrix(); // destructor
// data movement
dReal & operator () (int i, int j); // reference an element
void operator= (const dMatrix &); // matrix = matrix
void operator= (dReal); // matrix = scalar
dMatrix transpose(); // return transposed matrix
// return a permuted submatrix of this matrix, made up of the rows in p
// and the columns in q. p has np elements, q has nq elements.
dMatrix select (int np, int *p, int nq, int *q);
// operators
dMatrix operator + (const dMatrix &);
dMatrix operator - (const dMatrix &);
dMatrix operator - ();
dMatrix operator * (const dMatrix &);
void operator += (const dMatrix &);
void operator -= (const dMatrix &);
// utility
void clearUpperTriangle();
void clearLowerTriangle();
void makeRandom (dReal range);
void print (char *fmt = "%10.4f ", FILE *f=stdout);
dReal maxDifference (const dMatrix &);
};
#endif

358
extern/ode/dist/ode/src/matrix.cpp vendored Normal file
View File

@@ -0,0 +1,358 @@
/*************************************************************************
* *
* 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/common.h>
#include <ode/matrix.h>
// misc defines
#define ALLOCA dALLOCA16
void dSetZero (dReal *a, int n)
{
dAASSERT (a && n >= 0);
while (n > 0) {
*(a++) = 0;
n--;
}
}
void dSetValue (dReal *a, int n, dReal value)
{
dAASSERT (a && n >= 0);
while (n > 0) {
*(a++) = value;
n--;
}
}
void dMultiply0 (dReal *A, const dReal *B, const dReal *C, int p, int q, int r)
{
int i,j,k,qskip,rskip,rpad;
dAASSERT (A && B && C && p>0 && q>0 && r>0);
qskip = dPAD(q);
rskip = dPAD(r);
rpad = rskip - r;
dReal sum;
const dReal *b,*c,*bb;
bb = B;
for (i=p; i; i--) {
for (j=0 ; j<r; j++) {
c = C + j;
b = bb;
sum = 0;
for (k=q; k; k--, c+=rskip) sum += (*(b++))*(*c);
*(A++) = sum;
}
A += rpad;
bb += qskip;
}
}
void dMultiply1 (dReal *A, const dReal *B, const dReal *C, int p, int q, int r)
{
int i,j,k,pskip,rskip;
dReal sum;
dAASSERT (A && B && C && p>0 && q>0 && r>0);
pskip = dPAD(p);
rskip = dPAD(r);
for (i=0; i<p; i++) {
for (j=0; j<r; j++) {
sum = 0;
for (k=0; k<q; k++) sum += B[i+k*pskip] * C[j+k*rskip];
A[i*rskip+j] = sum;
}
}
}
void dMultiply2 (dReal *A, const dReal *B, const dReal *C, int p, int q, int r)
{
int i,j,k,z,rpad,qskip;
dReal sum;
const dReal *bb,*cc;
dAASSERT (A && B && C && p>0 && q>0 && r>0);
rpad = dPAD(r) - r;
qskip = dPAD(q);
bb = B;
for (i=p; i; i--) {
cc = C;
for (j=r; j; j--) {
z = 0;
sum = 0;
for (k=q; k; k--,z++) sum += bb[z] * cc[z];
*(A++) = sum;
cc += qskip;
}
A += rpad;
bb += qskip;
}
}
int dFactorCholesky (dReal *A, int n)
{
int i,j,k,nskip;
dReal sum,*a,*b,*aa,*bb,*cc,*recip;
dAASSERT (n > 0 && A);
nskip = dPAD (n);
recip = (dReal*) ALLOCA (n * sizeof(dReal));
aa = A;
for (i=0; i<n; i++) {
bb = A;
cc = A + i*nskip;
for (j=0; j<i; j++) {
sum = *cc;
a = aa;
b = bb;
for (k=j; k; k--) sum -= (*(a++))*(*(b++));
*cc = sum * recip[j];
bb += nskip;
cc++;
}
sum = *cc;
a = aa;
for (k=i; k; k--, a++) sum -= (*a)*(*a);
if (sum <= REAL(0.0)) return 0;
*cc = dSqrt(sum);
recip[i] = dRecip (*cc);
aa += nskip;
}
return 1;
}
void dSolveCholesky (const dReal *L, dReal *b, int n)
{
int i,k,nskip;
dReal sum,*y;
dAASSERT (n > 0 && L && b);
nskip = dPAD (n);
y = (dReal*) ALLOCA (n*sizeof(dReal));
for (i=0; i<n; i++) {
sum = 0;
for (k=0; k < i; k++) sum += L[i*nskip+k]*y[k];
y[i] = (b[i]-sum)/L[i*nskip+i];
}
for (i=n-1; i >= 0; i--) {
sum = 0;
for (k=i+1; k < n; k++) sum += L[k*nskip+i]*b[k];
b[i] = (y[i]-sum)/L[i*nskip+i];
}
}
int dInvertPDMatrix (const dReal *A, dReal *Ainv, int n)
{
int i,j,nskip;
dReal *L,*x;
dAASSERT (n > 0 && A && Ainv);
nskip = dPAD (n);
L = (dReal*) ALLOCA (nskip*n*sizeof(dReal));
memcpy (L,A,nskip*n*sizeof(dReal));
x = (dReal*) ALLOCA (n*sizeof(dReal));
if (dFactorCholesky (L,n)==0) return 0;
dSetZero (Ainv,n*nskip); // make sure all padding elements set to 0
for (i=0; i<n; i++) {
for (j=0; j<n; j++) x[j] = 0;
x[i] = 1;
dSolveCholesky (L,x,n);
for (j=0; j<n; j++) Ainv[j*nskip+i] = x[j];
}
return 1;
}
int dIsPositiveDefinite (const dReal *A, int n)
{
dReal *Acopy;
dAASSERT (n > 0 && A);
int nskip = dPAD (n);
Acopy = (dReal*) ALLOCA (nskip*n * sizeof(dReal));
memcpy (Acopy,A,nskip*n * sizeof(dReal));
return dFactorCholesky (Acopy,n);
}
/***** this has been replaced by a faster version
void dSolveL1T (const dReal *L, dReal *b, int n, int nskip)
{
int i,j;
dAASSERT (L && b && n >= 0 && nskip >= n);
dReal sum;
for (i=n-2; i>=0; i--) {
sum = 0;
for (j=i+1; j<n; j++) sum += L[j*nskip+i]*b[j];
b[i] -= sum;
}
}
*/
void dVectorScale (dReal *a, const dReal *d, int n)
{
dAASSERT (a && d && n >= 0);
for (int i=0; i<n; i++) a[i] *= d[i];
}
void dSolveLDLT (const dReal *L, const dReal *d, dReal *b, int n, int nskip)
{
dAASSERT (L && d && b && n > 0 && nskip >= n);
dSolveL1 (L,b,n,nskip);
dVectorScale (b,d,n);
dSolveL1T (L,b,n,nskip);
}
void dLDLTAddTL (dReal *L, dReal *d, const dReal *a, int n, int nskip)
{
int j,p;
dReal *W1,*W2,W11,W21,alpha1,alpha2,alphanew,gamma1,gamma2,k1,k2,Wp,ell,dee;
dAASSERT (L && d && a && n > 0 && nskip >= n);
if (n < 2) return;
W1 = (dReal*) ALLOCA (n*sizeof(dReal));
W2 = (dReal*) ALLOCA (n*sizeof(dReal));
W1[0] = 0;
W2[0] = 0;
for (j=1; j<n; j++) W1[j] = W2[j] = a[j] * M_SQRT1_2;
W11 = (REAL(0.5)*a[0]+1)*M_SQRT1_2;
W21 = (REAL(0.5)*a[0]-1)*M_SQRT1_2;
alpha1=1;
alpha2=1;
dee = d[0];
alphanew = alpha1 + (W11*W11)*dee;
dee /= alphanew;
gamma1 = W11 * dee;
dee *= alpha1;
alpha1 = alphanew;
alphanew = alpha2 - (W21*W21)*dee;
dee /= alphanew;
gamma2 = W21 * dee;
alpha2 = alphanew;
k1 = REAL(1.0) - W21*gamma1;
k2 = W21*gamma1*W11 - W21;
for (p=1; p<n; p++) {
Wp = W1[p];
ell = L[p*nskip];
W1[p] = Wp - W11*ell;
W2[p] = k1*Wp + k2*ell;
}
for (j=1; j<n; j++) {
dee = d[j];
alphanew = alpha1 + (W1[j]*W1[j])*dee;
dee /= alphanew;
gamma1 = W1[j] * dee;
dee *= alpha1;
alpha1 = alphanew;
alphanew = alpha2 - (W2[j]*W2[j])*dee;
dee /= alphanew;
gamma2 = W2[j] * dee;
dee *= alpha2;
d[j] = dee;
alpha2 = alphanew;
k1 = W1[j];
k2 = W2[j];
for (p=j+1; p<n; p++) {
ell = L[p*nskip+j];
Wp = W1[p] - k1 * ell;
ell += gamma1 * Wp;
W1[p] = Wp;
Wp = W2[p] - k2 * ell;
ell -= gamma2 * Wp;
W2[p] = Wp;
L[p*nskip+j] = ell;
}
}
}
// macros for dLDLTRemove() for accessing A - either access the matrix
// directly or access it via row pointers. we are only supposed to reference
// the lower triangle of A (it is symmetric), but indexes i and j come from
// permutation vectors so they are not predictable. so do a test on the
// indexes - this should not slow things down too much, as we don't do this
// in an inner loop.
#define _GETA(i,j) (A[i][j])
//#define _GETA(i,j) (A[(i)*nskip+(j)])
#define GETA(i,j) ((i > j) ? _GETA(i,j) : _GETA(j,i))
void dLDLTRemove (dReal **A, const int *p, dReal *L, dReal *d,
int n1, int n2, int r, int nskip)
{
int i;
dAASSERT(A && p && L && d && n1 > 0 && n2 > 0 && r >= 0 && r < n2 &&
n1 >= n2 && nskip >= n1);
#ifndef dNODEBUG
for (i=0; i<n2; i++) dIASSERT(p[i] >= 0 && p[i] < n1);
#endif
if (r==n2-1) {
return; // deleting last row/col is easy
}
else if (r==0) {
dReal *a = (dReal*) ALLOCA (n2 * sizeof(dReal));
for (i=0; i<n2; i++) a[i] = -GETA(p[i],p[0]);
a[0] += REAL(1.0);
dLDLTAddTL (L,d,a,n2,nskip);
}
else {
dReal *t = (dReal*) ALLOCA (r * sizeof(dReal));
dReal *a = (dReal*) ALLOCA ((n2-r) * sizeof(dReal));
for (i=0; i<r; i++) t[i] = L[r*nskip+i] / d[i];
for (i=0; i<(n2-r); i++)
a[i] = dDot(L+(r+i)*nskip,t,r) - GETA(p[r+i],p[r]);
a[0] += REAL(1.0);
dLDLTAddTL (L + r*nskip+r, d+r, a, n2-r, nskip);
}
// snip out row/column r from L and d
dRemoveRowCol (L,n2,nskip,r);
if (r < (n2-1)) memmove (d+r,d+r+1,(n2-r-1)*sizeof(dReal));
}
void dRemoveRowCol (dReal *A, int n, int nskip, int r)
{
int i;
dAASSERT(A && n > 0 && nskip >= n && r >= 0 && r < n);
if (r >= n-1) return;
if (r > 0) {
for (i=0; i<r; i++)
memmove (A+i*nskip+r,A+i*nskip+r+1,(n-r-1)*sizeof(dReal));
for (i=r; i<(n-1); i++)
memcpy (A+i*nskip,A+i*nskip+nskip,r*sizeof(dReal));
}
for (i=r; i<(n-1); i++)
memcpy (A+i*nskip+r,A+i*nskip+nskip+r+1,(n-r-1)*sizeof(dReal));
}

278
extern/ode/dist/ode/src/memory.cpp vendored Normal file
View File

@@ -0,0 +1,278 @@
/*************************************************************************
* *
* 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. *
* *
*************************************************************************/
// if the dDEBUG_ALLOC macro is defined, the following tests are performed in
// the default allocator:
// - size > 0 for alloc and realloc
// - realloc and free operate on uncorrupted blocks
// - realloc and free with the correct sizes
// - on exit, report of block allocation statistics
// - on exit, report of unfreed blocks and if they are corrupted
// the allocator will also call Debug() when it allocates a block with
// sequence number `_d_seqstop' or pointer value `_d_ptrstop'. these variables
// are global and can be set in the debugger.
#include <ode/config.h>
#include <ode/memory.h>
#include <ode/error.h>
#ifdef dDEBUG_ALLOC
// when debugging, this is a header that it put at start of all blocks.
// it contains `padding', which are PADSIZE elements of known value just
// before the user memory starts. another PADSIZE padding elements are put
// at the end of the user memory. the idea is that if the user accidentally
// steps outside the allocated memory, it can hopefully be detected by
// examining the padding elements.
#define PADSIZE 10
struct blockHeader {
long pad1; // protective padding
long seq; // sequence number
long size; // data size
long flags; // bit 0 = ignore this block in final report
blockHeader *next,*prev; // next & previous blocks
long pad[PADSIZE]; // protective padding
};
// compute the memory block size, including padding. the user memory block is
// rounded up to a multiple of 4 bytes, to get alignment for the padding at
// the end of the block.
#define BSIZE(size) (((((size)-1) | 3)+1) + sizeof(blockHeader) + \
PADSIZE * sizeof(long))
static blockHeader dummyblock = {0,0,0,0,&dummyblock,&dummyblock,
{0,0,0,0,0,0,0,0,0,0}};
static blockHeader *firstblock = &dummyblock;
static long num_blocks_alloced = 0;
static long num_bytes_alloced = 0;
static long total_num_blocks_alloced = 0;
static long total_num_bytes_alloced = 0;
static long max_blocks_alloced = 0;
static long max_bytes_alloced = 0;
long _d_seqstop = 0;
void *_d_ptrstop = 0;
static int checkBlockOk (void *ptr, int fatal)
{
if (ptr==0) dDebug (0,"0 passed to checkBlockOk()");
blockHeader *b = ((blockHeader*) ptr) - 1;
int i,ok = 1;
if (b->pad1 != (long)0xdeadbeef || b->seq < 0 || b->size < 0) ok = 0;
if (ok) {
for (i=0; i<PADSIZE; i++) if (b->pad[i] != (long)0xdeadbeef) ok = 0;
}
if (ok) {
long *endpad = (long*) (((char*)ptr) + (((b->size-1) | 3)+1));
for (i=0; i<PADSIZE; i++) if (endpad[i] != (long)0xdeadbeef) ok = 0;
}
if (!ok && fatal)
dDebug (0,"corrupted memory block found, ptr=%p, size=%d, "
"seq=%ld", ptr,b->size,b->seq);
return ok;
}
#endif
static dAllocFunction *allocfn = 0;
static dReallocFunction *reallocfn = 0;
static dFreeFunction *freefn = 0;
void dSetAllocHandler (dAllocFunction *fn)
{
allocfn = fn;
}
void dSetReallocHandler (dReallocFunction *fn)
{
reallocfn = fn;
}
void dSetFreeHandler (dFreeFunction *fn)
{
freefn = fn;
}
dAllocFunction *dGetAllocHandler()
{
return allocfn;
}
dReallocFunction *dGetReallocHandler()
{
return reallocfn;
}
dFreeFunction *dGetFreeHandler()
{
return freefn;
}
void * dAlloc (int size)
{
#ifdef dDEBUG_ALLOC
if (size < 1) dDebug (0,"bad block size to Alloc()");
num_blocks_alloced++;
num_bytes_alloced += size;
total_num_blocks_alloced++;
total_num_bytes_alloced += size;
if (num_blocks_alloced > max_blocks_alloced)
max_blocks_alloced = num_blocks_alloced;
if (num_bytes_alloced > max_bytes_alloced)
max_bytes_alloced = num_bytes_alloced;
if (total_num_blocks_alloced == _d_seqstop)
dDebug (0,"ALLOCATOR TRAP ON SEQUENCE NUMBER %d",_d_seqstop);
long size2 = BSIZE(size);
blockHeader *b = (blockHeader*) malloc (size2);
if (b+1 == _d_ptrstop)
dDebug (0,"ALLOCATOR TRAP ON BLOCK POINTER %p",_d_ptrstop);
for (unsigned int i=0; i < (size2/sizeof(long)); i++)
((long*)b)[i] = 0xdeadbeef;
b->seq = total_num_blocks_alloced;
b->size = size;
b->flags = 0;
b->next = firstblock->next;
b->prev = firstblock;
firstblock->next->prev = b;
firstblock->next = b;
return b + 1;
#else
if (allocfn) return allocfn (size); else return malloc (size);
#endif
}
void * dRealloc (void *ptr, int oldsize, int newsize)
{
#ifdef dDEBUG_ALLOC
if (ptr==0) dDebug (0,"Realloc() called with ptr==0");
checkBlockOk (ptr,1);
blockHeader *b = ((blockHeader*) ptr) - 1;
if (b->size != oldsize)
dDebug (0,"Realloc(%p,%d,%d) has bad old size, good size "
"is %ld, seq=%ld",ptr,oldsize,newsize,b->size,b->seq);
void *p = dAlloc (newsize);
blockHeader *newb = ((blockHeader*) p) - 1;
newb->flags = b->flags;
if (oldsize>=1) memcpy (p,ptr,oldsize);
dFree (ptr,oldsize);
return p;
#else
if (reallocfn) return reallocfn (ptr,oldsize,newsize);
else return realloc (ptr,newsize);
#endif
}
void dFree (void *ptr, int size)
{
if (!ptr) return;
#ifdef dDEBUG_ALLOC
checkBlockOk (ptr,1);
blockHeader *b = ((blockHeader*) ptr) - 1;
if (b->size != size)
dDebug (0,"Free(%p,%d) has bad size, good size "
"is %ld, seq=%ld",ptr,size,b->size,b->seq);
num_blocks_alloced--;
num_bytes_alloced -= b->size;
if (num_blocks_alloced < 0 || num_bytes_alloced < 0)
dDebug (0,"Free called too many times");
b->next->prev = b->prev;
b->prev->next = b->next;
memset (b,0,BSIZE(b->size));
free (b);
#else
if (freefn) freefn (ptr,size); else free (ptr);
#endif
}
void dAllocDontReport (void *ptr)
{
#ifdef dDEBUG_ALLOC
checkBlockOk (ptr,1);
blockHeader *b = ((blockHeader*) ptr) - 1;
b->flags |= 1;
#endif
}
#ifdef dDEBUG_ALLOC
static void printReport()
{
// subtract the "dont report" blocks from the totals
blockHeader *b = firstblock;
do {
if (b != &dummyblock && (b->flags & 1)) {
num_blocks_alloced--;
num_bytes_alloced -= b->size;
if (!checkBlockOk (b+1,0))
fprintf (stderr,"\tCORRUPTED: %p, size=%ld, seq=%ld\n",b+1,
b->size,b->seq);
}
b = b->prev;
}
while (b != firstblock);
fprintf (stderr,"\nALLOCATOR REPORT\n");
fprintf (stderr,"\tblocks still allocated: %ld\n",num_blocks_alloced);
fprintf (stderr,"\tbytes still allocated: %ld\n",num_bytes_alloced);
fprintf (stderr,"\ttotal blocks allocated: %ld\n",total_num_blocks_alloced);
fprintf (stderr,"\ttotal bytes allocated: %ld\n",total_num_bytes_alloced);
fprintf (stderr,"\tmax blocks allocated: %ld\n",max_blocks_alloced);
fprintf (stderr,"\tmax bytes allocated: %ld\n",max_bytes_alloced);
b = firstblock;
do {
if (b != &dummyblock && (b->flags & 1)==0) {
int ok = checkBlockOk (b+1,0);
fprintf (stderr,"\tUNFREED: %p, size=%ld, seq=%ld (%s)\n",b+1,
b->size,b->seq, ok ? "ok" : "CORUPTED");
}
b = b->prev;
}
while (b != firstblock);
fprintf (stderr,"\n");
}
struct dMemoryReportPrinter {
~dMemoryReportPrinter() { printReport(); }
} _dReportPrinter;
#endif

147
extern/ode/dist/ode/src/misc.cpp vendored Normal file
View File

@@ -0,0 +1,147 @@
/*************************************************************************
* *
* 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/misc.h>
#include <ode/matrix.h>
//****************************************************************************
// random numbers
static unsigned long seed = 0;
unsigned long dRand()
{
seed = (1664525L*seed + 1013904223L) & 0xffffffff;
return seed;
}
unsigned long dRandGetSeed()
{
return seed;
}
void dRandSetSeed (unsigned long s)
{
seed = s;
}
int dTestRand()
{
unsigned long oldseed = seed;
int ret = 1;
seed = 0;
if (dRand() != 0x3c6ef35f || dRand() != 0x47502932 ||
dRand() != 0xd1ccf6e9 || dRand() != 0xaaf95334 ||
dRand() != 0x6252e503) ret = 0;
seed = oldseed;
return ret;
}
int dRandInt (int n)
{
double a = double(n) / 4294967296.0;
return (int) (double(dRand()) * a);
}
dReal dRandReal()
{
return ((dReal) dRand()) / ((dReal) 0xffffffff);
}
//****************************************************************************
// matrix utility stuff
void dPrintMatrix (dReal *A, int n, int m, char *fmt, FILE *f)
{
int i,j;
int skip = dPAD(m);
for (i=0; i<n; i++) {
for (j=0; j<m; j++) fprintf (f,fmt,A[i*skip+j]);
fprintf (f,"\n");
}
}
void dMakeRandomVector (dReal *A, int n, dReal range)
{
int i;
for (i=0; i<n; i++) A[i] = (dRandReal()*REAL(2.0)-REAL(1.0))*range;
}
void dMakeRandomMatrix (dReal *A, int n, int m, dReal range)
{
int i,j;
int skip = dPAD(m);
dSetZero (A,n*skip);
for (i=0; i<n; i++) {
for (j=0; j<m; j++) A[i*skip+j] = (dRandReal()*REAL(2.0)-REAL(1.0))*range;
}
}
void dClearUpperTriangle (dReal *A, int n)
{
int i,j;
int skip = dPAD(n);
for (i=0; i<n; i++) {
for (j=i+1; j<n; j++) A[i*skip+j] = 0;
}
}
dReal dMaxDifference (const dReal *A, const dReal *B, int n, int m)
{
int i,j;
int skip = dPAD(m);
dReal diff,max;
max = 0;
for (i=0; i<n; i++) {
for (j=0; j<m; j++) {
diff = dFabs(A[i*skip+j] - B[i*skip+j]);
if (diff > max) max = diff;
}
}
return max;
}
dReal dMaxDifferenceLowerTriangle (const dReal *A, const dReal *B, int n)
{
int i,j;
int skip = dPAD(n);
dReal diff,max;
max = 0;
for (i=0; i<n; i++) {
for (j=0; j<=i; j++) {
diff = dFabs(A[i*skip+j] - B[i*skip+j]);
if (diff > max) max = diff;
}
}
return max;
}

91
extern/ode/dist/ode/src/objects.h vendored Normal file
View File

@@ -0,0 +1,91 @@
/*************************************************************************
* *
* 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. *
* *
*************************************************************************/
// object, body, and world structs.
#ifndef _ODE_OBJECT_H_
#define _ODE_OBJECT_H_
#include <ode/common.h>
#include <ode/memory.h>
#include <ode/mass.h>
#include "array.h"
// some body flags
enum {
dxBodyFlagFiniteRotation = 1, // use finite rotations
dxBodyFlagFiniteRotationAxis = 2, // use finite rotations only along axis
dxBodyDisabled = 4, // body is disabled
dxBodyNoGravity = 8 // body is not influenced by gravity
};
// base class that does correct object allocation / deallocation
struct dBase {
void *operator new (size_t size) { return dAlloc (size); }
void operator delete (void *ptr, size_t size) { dFree (ptr,size); }
void *operator new[] (size_t size) { return dAlloc (size); }
void operator delete[] (void *ptr, size_t size) { dFree (ptr,size); }
};
// base class for bodies and joints
struct dObject : public dBase {
dxWorld *world; // world this object is in
dObject *next; // next object of this type in list
dObject **tome; // pointer to previous object's next ptr
void *userdata; // user settable data
int tag; // used by dynamics algorithms
};
struct dxBody : public dObject {
dxJointNode *firstjoint; // list of attached joints
int flags; // some dxBodyFlagXXX flags
dMass mass; // mass parameters about POR
dMatrix3 invI; // inverse of mass.I
dReal invMass; // 1 / mass.mass
dVector3 pos; // position of POR (point of reference)
dQuaternion q; // orientation quaternion
dMatrix3 R; // rotation matrix, always corresponds to q
dVector3 lvel,avel; // linear and angular velocity of POR
dVector3 facc,tacc; // force and torque accululators
dVector3 finite_rot_axis; // finite rotation axis, unit length or 0=none
};
struct dxWorld : public dBase {
dxBody *firstbody; // body linked list
dxJoint *firstjoint; // joint linked list
int nb,nj; // number of bodies and joints in lists
dVector3 gravity; // gravity vector (m/s/s)
dReal global_erp; // global error reduction parameter
dReal global_cfm; // global costraint force mixing parameter
};
#endif

130
extern/ode/dist/ode/src/obstack.cpp vendored Normal file
View File

@@ -0,0 +1,130 @@
/*************************************************************************
* *
* 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/common.h>
#include <ode/error.h>
#include <ode/memory.h>
#include "obstack.h"
//****************************************************************************
// macros and constants
#define ROUND_UP_OFFSET_TO_EFFICIENT_SIZE(arena,ofs) \
ofs = (int) (dEFFICIENT_SIZE( ((intP)(arena)) + ofs ) - ((intP)(arena)) );
#define MAX_ALLOC_SIZE \
((int)(dOBSTACK_ARENA_SIZE - sizeof (Arena) - EFFICIENT_ALIGNMENT + 1))
//****************************************************************************
// dObStack
dObStack::dObStack()
{
first = 0;
last = 0;
current_arena = 0;
current_ofs = 0;
}
dObStack::~dObStack()
{
// free all arenas
Arena *a,*nexta;
a = first;
while (a) {
nexta = a->next;
dFree (a,dOBSTACK_ARENA_SIZE);
a = nexta;
}
}
void *dObStack::alloc (int num_bytes)
{
if (num_bytes > MAX_ALLOC_SIZE) dDebug (0,"num_bytes too large");
// allocate or move to a new arena if necessary
if (!first) {
// allocate the first arena if necessary
first = last = (Arena *) dAlloc (dOBSTACK_ARENA_SIZE);
first->next = 0;
first->used = sizeof (Arena);
ROUND_UP_OFFSET_TO_EFFICIENT_SIZE (first,first->used);
}
else {
// we already have one or more arenas, see if a new arena must be used
if ((last->used + num_bytes) > dOBSTACK_ARENA_SIZE) {
if (!last->next) {
last->next = (Arena *) dAlloc (dOBSTACK_ARENA_SIZE);
last->next->next = 0;
}
last = last->next;
last->used = sizeof (Arena);
ROUND_UP_OFFSET_TO_EFFICIENT_SIZE (last,last->used);
}
}
// allocate an area in the arena
char *c = ((char*) last) + last->used;
last->used += num_bytes;
ROUND_UP_OFFSET_TO_EFFICIENT_SIZE (last,last->used);
return c;
}
void dObStack::freeAll()
{
last = first;
if (first) {
first->used = sizeof(Arena);
ROUND_UP_OFFSET_TO_EFFICIENT_SIZE (first,first->used);
}
}
void *dObStack::rewind()
{
current_arena = first;
current_ofs = sizeof (Arena);
if (current_arena) {
ROUND_UP_OFFSET_TO_EFFICIENT_SIZE (current_arena,current_ofs)
return ((char*) current_arena) + current_ofs;
}
else return 0;
}
void *dObStack::next (int num_bytes)
{
// this functions like alloc, except that no new storage is ever allocated
if (!current_arena) return 0;
current_ofs += num_bytes;
ROUND_UP_OFFSET_TO_EFFICIENT_SIZE (current_arena,current_ofs);
if (current_ofs >= current_arena->used) {
current_arena = current_arena->next;
if (!current_arena) return 0;
current_ofs = sizeof (Arena);
ROUND_UP_OFFSET_TO_EFFICIENT_SIZE (current_arena,current_ofs);
}
return ((char*) current_arena) + current_ofs;
}

68
extern/ode/dist/ode/src/obstack.h vendored Normal file
View File

@@ -0,0 +1,68 @@
/*************************************************************************
* *
* 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_OBSTACK_H_
#define _ODE_OBSTACK_H_
#include "objects.h"
// each obstack Arena pointer points to a block of this many bytes
#define dOBSTACK_ARENA_SIZE 16384
struct dObStack : public dBase {
struct Arena {
Arena *next; // next arena in linked list
int used; // total number of bytes used in this arena, counting
}; // this header
Arena *first; // head of the arena linked list. 0 if no arenas yet
Arena *last; // arena where blocks are currently being allocated
// used for iterator
Arena *current_arena;
int current_ofs;
dObStack();
~dObStack();
void *alloc (int num_bytes);
// allocate a block in the last arena, allocating a new arena if necessary.
// it is a runtime error if num_bytes is larger than the arena size.
void freeAll();
// free all blocks in all arenas. this does not deallocate the arenas
// themselves, so future alloc()s will reuse them.
void *rewind();
// rewind the obstack iterator, and return the address of the first
// allocated block. return 0 if there are no allocated blocks.
void *next (int num_bytes);
// return the address of the next allocated block. 'num_bytes' is the size
// of the previous block. this returns null if there are no more arenas.
// the sequence of 'num_bytes' parameters passed to next() during a
// traversal of the list must exactly match the parameters passed to alloc().
};
#endif

1341
extern/ode/dist/ode/src/ode.cpp vendored Normal file

File diff suppressed because it is too large Load Diff

173
extern/ode/dist/ode/src/odemath.cpp vendored Normal file
View File

@@ -0,0 +1,173 @@
/*************************************************************************
* *
* 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. *
* *
*************************************************************************/
#define SHARED_CONFIG_H_INCLUDED_FROM_DEFINING_FILE 1
#include <ode/common.h>
#include <ode/odemath.h>
// get some math functions under windows
#ifdef WIN32
#include <float.h>
#ifndef CYGWIN // added by andy for cygwin
#define copysign(a,b) ((dReal)_copysign(a,b))
#endif // added by andy for cygwin
#endif
// infinity declaration
#ifdef DINFINITY_DECL
DINFINITY_DECL
#endif
// this may be called for vectors `a' with extremely small magnitude, for
// example the result of a cross product on two nearly perpendicular vectors.
// we must be robust to these small vectors. to prevent numerical error,
// first find the component a[i] with the largest magnitude and then scale
// all the components by 1/a[i]. then we can compute the length of `a' and
// scale the components by 1/l. this has been verified to work with vectors
// containing the smallest representable numbers.
void dNormalize3 (dVector3 a)
{
dReal a0,a1,a2,aa0,aa1,aa2,l;
dAASSERT (a);
a0 = a[0];
a1 = a[1];
a2 = a[2];
aa0 = dFabs(a0);
aa1 = dFabs(a1);
aa2 = dFabs(a2);
if (aa1 > aa0) {
if (aa2 > aa1) {
goto aa2_largest;
}
else { // aa1 is largest
a0 /= aa1;
a2 /= aa1;
l = dRecipSqrt (a0*a0 + a2*a2 + 1);
a[0] = a0*l;
a[1] = copysign(l,a1);
a[2] = a2*l;
}
}
else {
if (aa2 > aa0) {
aa2_largest: // aa2 is largest
a0 /= aa2;
a1 /= aa2;
l = dRecipSqrt (a0*a0 + a1*a1 + 1);
a[0] = a0*l;
a[1] = a1*l;
a[2] = copysign(l,a2);
}
else { // aa0 is largest
if (aa0 <= 0) {
dDEBUGMSG ("vector has zero size");
a[0] = 1; // if all a's are zero, this is where we'll end up.
a[1] = 0; // return a default unit length vector.
a[2] = 0;
return;
}
a1 /= aa0;
a2 /= aa0;
l = dRecipSqrt (a1*a1 + a2*a2 + 1);
a[0] = copysign(l,a0);
a[1] = a1*l;
a[2] = a2*l;
}
}
}
/* OLD VERSION */
/*
void dNormalize3 (dVector3 a)
{
dASSERT (a);
dReal l = dDOT(a,a);
if (l > 0) {
l = dRecipSqrt(l);
a[0] *= l;
a[1] *= l;
a[2] *= l;
}
else {
a[0] = 1;
a[1] = 0;
a[2] = 0;
}
}
*/
void dNormalize4 (dVector4 a)
{
dAASSERT (a);
dReal l = dDOT(a,a)+a[3]*a[3];
if (l > 0) {
l = dRecipSqrt(l);
a[0] *= l;
a[1] *= l;
a[2] *= l;
a[3] *= l;
}
else {
dDEBUGMSG ("vector has zero size");
a[0] = 1;
a[1] = 0;
a[2] = 0;
a[3] = 0;
}
}
void dPlaneSpace (const dVector3 n, dVector3 p, dVector3 q)
{
dAASSERT (n && p && q);
if (dFabs(n[2]) > M_SQRT1_2) {
// choose p in y-z plane
dReal a = n[1]*n[1] + n[2]*n[2];
dReal k = dRecipSqrt (a);
p[0] = 0;
p[1] = -n[2]*k;
p[2] = n[1]*k;
// set q = n x p
q[0] = a*k;
q[1] = -n[0]*p[2];
q[2] = n[0]*p[1];
}
else {
// choose p in x-y plane
dReal a = n[0]*n[0] + n[1]*n[1];
dReal k = dRecipSqrt (a);
p[0] = -n[1]*k;
p[1] = n[0]*k;
p[2] = 0;
// set q = n x p
q[0] = -n[2]*p[1];
q[1] = n[2]*p[0];
q[2] = a*k;
}
}

283
extern/ode/dist/ode/src/rotation.cpp vendored Normal file
View File

@@ -0,0 +1,283 @@
/*************************************************************************
* *
* 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. *
* *
*************************************************************************/
/*
quaternions have the format: (s,vx,vy,vz) where (vx,vy,vz) is the
"rotation axis" and s is the "rotation angle".
*/
#include <ode/rotation.h>
#define _R(i,j) R[(i)*4+(j)]
#define SET_3x3_IDENTITY \
_R(0,0) = REAL(1.0); \
_R(0,1) = REAL(0.0); \
_R(0,2) = REAL(0.0); \
_R(0,3) = REAL(0.0); \
_R(1,0) = REAL(0.0); \
_R(1,1) = REAL(1.0); \
_R(1,2) = REAL(0.0); \
_R(1,3) = REAL(0.0); \
_R(2,0) = REAL(0.0); \
_R(2,1) = REAL(0.0); \
_R(2,2) = REAL(1.0); \
_R(2,3) = REAL(0.0);
void dRSetIdentity (dMatrix3 R)
{
dAASSERT (R);
SET_3x3_IDENTITY;
}
void dRFromAxisAndAngle (dMatrix3 R, dReal ax, dReal ay, dReal az,
dReal angle)
{
dAASSERT (R);
dQuaternion q;
dQFromAxisAndAngle (q,ax,ay,az,angle);
dQtoR (q,R);
}
void dRFromEulerAngles (dMatrix3 R, dReal phi, dReal theta, dReal psi)
{
dReal sphi,cphi,stheta,ctheta,spsi,cpsi;
dAASSERT (R);
sphi = dSin(phi);
cphi = dCos(phi);
stheta = dSin(theta);
ctheta = dCos(theta);
spsi = dSin(psi);
cpsi = dCos(psi);
_R(0,0) = cpsi*ctheta;
_R(0,1) = spsi*ctheta;
_R(0,2) =-stheta;
_R(1,0) = cpsi*stheta*sphi - spsi*cphi;
_R(1,1) = spsi*stheta*sphi + cpsi*cphi;
_R(1,2) = ctheta*sphi;
_R(2,0) = cpsi*stheta*cphi + spsi*sphi;
_R(2,1) = spsi*stheta*cphi - cpsi*sphi;
_R(2,2) = ctheta*cphi;
}
void dRFrom2Axes (dMatrix3 R, dReal ax, dReal ay, dReal az,
dReal bx, dReal by, dReal bz)
{
dReal l,k;
dAASSERT (R);
l = dSqrt (ax*ax + ay*ay + az*az);
if (l <= REAL(0.0)) {
dDEBUGMSG ("zero length vector");
return;
}
l = dRecip(l);
ax *= l;
ay *= l;
az *= l;
k = ax*bx + ay*by + az*bz;
bx -= k*ax;
by -= k*ay;
bz -= k*az;
l = dSqrt (bx*bx + by*by + bz*bz);
if (l <= REAL(0.0)) {
dDEBUGMSG ("zero length vector");
return;
}
l = dRecip(l);
bx *= l;
by *= l;
bz *= l;
_R(0,0) = ax;
_R(1,0) = ay;
_R(2,0) = az;
_R(0,1) = bx;
_R(1,1) = by;
_R(2,1) = bz;
_R(0,2) = - by*az + ay*bz;
_R(1,2) = - bz*ax + az*bx;
_R(2,2) = - bx*ay + ax*by;
}
void dQSetIdentity (dQuaternion q)
{
dAASSERT (q);
q[0] = 1;
q[1] = 0;
q[2] = 0;
q[3] = 0;
}
void dQFromAxisAndAngle (dQuaternion q, dReal ax, dReal ay, dReal az,
dReal angle)
{
dAASSERT (q);
dReal l = ax*ax + ay*ay + az*az;
if (l > REAL(0.0)) {
angle *= REAL(0.5);
q[0] = dCos (angle);
l = dSin(angle) * dRecipSqrt(l);
q[1] = ax*l;
q[2] = ay*l;
q[3] = az*l;
}
else {
q[0] = 1;
q[1] = 0;
q[2] = 0;
q[3] = 0;
}
}
void dQMultiply0 (dQuaternion qa, const dQuaternion qb, const dQuaternion qc)
{
dAASSERT (qa && qb && qc);
qa[0] = qb[0]*qc[0] - qb[1]*qc[1] - qb[2]*qc[2] - qb[3]*qc[3];
qa[1] = qb[0]*qc[1] + qb[1]*qc[0] + qb[2]*qc[3] - qb[3]*qc[2];
qa[2] = qb[0]*qc[2] + qb[2]*qc[0] + qb[3]*qc[1] - qb[1]*qc[3];
qa[3] = qb[0]*qc[3] + qb[3]*qc[0] + qb[1]*qc[2] - qb[2]*qc[1];
}
void dQMultiply1 (dQuaternion qa, const dQuaternion qb, const dQuaternion qc)
{
dAASSERT (qa && qb && qc);
qa[0] = qb[0]*qc[0] + qb[1]*qc[1] + qb[2]*qc[2] + qb[3]*qc[3];
qa[1] = qb[0]*qc[1] - qb[1]*qc[0] - qb[2]*qc[3] + qb[3]*qc[2];
qa[2] = qb[0]*qc[2] - qb[2]*qc[0] - qb[3]*qc[1] + qb[1]*qc[3];
qa[3] = qb[0]*qc[3] - qb[3]*qc[0] - qb[1]*qc[2] + qb[2]*qc[1];
}
void dQMultiply2 (dQuaternion qa, const dQuaternion qb, const dQuaternion qc)
{
dAASSERT (qa && qb && qc);
qa[0] = qb[0]*qc[0] + qb[1]*qc[1] + qb[2]*qc[2] + qb[3]*qc[3];
qa[1] = -qb[0]*qc[1] + qb[1]*qc[0] - qb[2]*qc[3] + qb[3]*qc[2];
qa[2] = -qb[0]*qc[2] + qb[2]*qc[0] - qb[3]*qc[1] + qb[1]*qc[3];
qa[3] = -qb[0]*qc[3] + qb[3]*qc[0] - qb[1]*qc[2] + qb[2]*qc[1];
}
void dQMultiply3 (dQuaternion qa, const dQuaternion qb, const dQuaternion qc)
{
dAASSERT (qa && qb && qc);
qa[0] = qb[0]*qc[0] - qb[1]*qc[1] - qb[2]*qc[2] - qb[3]*qc[3];
qa[1] = -qb[0]*qc[1] - qb[1]*qc[0] + qb[2]*qc[3] - qb[3]*qc[2];
qa[2] = -qb[0]*qc[2] - qb[2]*qc[0] + qb[3]*qc[1] - qb[1]*qc[3];
qa[3] = -qb[0]*qc[3] - qb[3]*qc[0] + qb[1]*qc[2] - qb[2]*qc[1];
}
// QtoR(), RtoQ() and WtoDQ() are derived from equations in "An Introduction
// to Physically Based Modeling: Rigid Body Simulation - 1: Unconstrained
// Rigid Body Dynamics" by David Baraff, Robotics Institute, Carnegie Mellon
// University, 1997.
void dQtoR (const dQuaternion q, dMatrix3 R)
{
dAASSERT (q && R);
// q = (s,vx,vy,vz)
dReal qq1 = 2*q[1]*q[1];
dReal qq2 = 2*q[2]*q[2];
dReal qq3 = 2*q[3]*q[3];
_R(0,0) = 1 - qq2 - qq3;
_R(0,1) = 2*(q[1]*q[2] - q[0]*q[3]);
_R(0,2) = 2*(q[1]*q[3] + q[0]*q[2]);
_R(1,0) = 2*(q[1]*q[2] + q[0]*q[3]);
_R(1,1) = 1 - qq1 - qq3;
_R(1,2) = 2*(q[2]*q[3] - q[0]*q[1]);
_R(2,0) = 2*(q[1]*q[3] - q[0]*q[2]);
_R(2,1) = 2*(q[2]*q[3] + q[0]*q[1]);
_R(2,2) = 1 - qq1 - qq2;
}
void dRtoQ (const dMatrix3 R, dQuaternion q)
{
dAASSERT (q && R);
dReal tr,s;
tr = _R(0,0) + _R(1,1) + _R(2,2);
if (tr >= 0) {
s = dSqrt (tr + 1);
q[0] = REAL(0.5) * s;
s = REAL(0.5) * dRecip(s);
q[1] = (_R(2,1) - _R(1,2)) * s;
q[2] = (_R(0,2) - _R(2,0)) * s;
q[3] = (_R(1,0) - _R(0,1)) * s;
}
else {
// find the largest diagonal element and jump to the appropriate case
if (_R(1,1) > _R(0,0)) {
if (_R(2,2) > _R(1,1)) goto case_2;
goto case_1;
}
if (_R(2,2) > _R(0,0)) goto case_2;
goto case_0;
case_0:
s = dSqrt((_R(0,0) - (_R(1,1) + _R(2,2))) + 1);
q[1] = REAL(0.5) * s;
s = REAL(0.5) * dRecip(s);
q[2] = (_R(0,1) + _R(1,0)) * s;
q[3] = (_R(2,0) + _R(0,2)) * s;
q[0] = (_R(2,1) - _R(1,2)) * s;
return;
case_1:
s = dSqrt((_R(1,1) - (_R(2,2) + _R(0,0))) + 1);
q[2] = REAL(0.5) * s;
s = REAL(0.5) * dRecip(s);
q[3] = (_R(1,2) + _R(2,1)) * s;
q[1] = (_R(0,1) + _R(1,0)) * s;
q[0] = (_R(0,2) - _R(2,0)) * s;
return;
case_2:
s = dSqrt((_R(2,2) - (_R(0,0) + _R(1,1))) + 1);
q[3] = REAL(0.5) * s;
s = REAL(0.5) * dRecip(s);
q[1] = (_R(2,0) + _R(0,2)) * s;
q[2] = (_R(1,2) + _R(2,1)) * s;
q[0] = (_R(1,0) - _R(0,1)) * s;
return;
}
}
void dWtoDQ (const dVector3 w, const dQuaternion q, dVector4 dq)
{
dAASSERT (w && q && dq);
dq[0] = REAL(0.5)*(- w[0]*q[1] - w[1]*q[2] - w[2]*q[3]);
dq[1] = REAL(0.5)*( w[0]*q[0] + w[1]*q[3] - w[2]*q[2]);
dq[2] = REAL(0.5)*(- w[0]*q[3] + w[1]*q[0] + w[2]*q[1]);
dq[3] = REAL(0.5)*( w[0]*q[2] - w[1]*q[1] + w[2]*q[0]);
}

270
extern/ode/dist/ode/src/scrapbook.cpp vendored Normal file
View File

@@ -0,0 +1,270 @@
/*
this is code that was once useful but has now been obseleted.
this file should not be compiled as part of ODE!
*/
//***************************************************************************
// intersect a line segment with a plane
extern "C" int dClipLineToBox (const dVector3 p1, const dVector3 p2,
const dVector3 p, const dMatrix3 R,
const dVector3 side)
{
// compute the start and end of the line (p1 and p2) relative to the box.
// we will do all subsequent computations in this box-relative coordinate
// system. we have to do a translation and rotation for each point.
dVector3 tmp,s,e;
tmp[0] = p1[0] - p[0];
tmp[1] = p1[1] - p[1];
tmp[2] = p1[2] - p[2];
dMULTIPLY1_331 (s,R,tmp);
tmp[0] = p2[0] - p[0];
tmp[1] = p2[1] - p[1];
tmp[2] = p2[2] - p[2];
dMULTIPLY1_331 (e,R,tmp);
// compute the vector 'v' from the start point to the end point
dVector3 v;
v[0] = e[0] - s[0];
v[1] = e[1] - s[1];
v[2] = e[2] - s[2];
// a point on the line is defined by the parameter 't'. t=0 corresponds
// to the start of the line, t=1 corresponds to the end of the line.
// we will clip the line to the box by finding the range of t where a
// point on the line is inside the box. the currently known bounds for
// t and tlo..thi.
dReal tlo=0,thi=1;
// clip in the X/Y/Z direction
for (int i=0; i<3; i++) {
// first adjust s,e for the current t range. this is redundant for the
// first iteration, but never mind.
e[i] = s[i] + thi*v[i];
s[i] = s[i] + tlo*v[i];
// compute where t intersects the positive and negative sides.
dReal tp = ( side[i] - s[i])/v[i]; // @@@ handle case where denom=0
dReal tm = (-side[i] - s[i])/v[i];
// handle 9 intersection cases
if (s[i] <= -side[i]) {
tlo = tm;
if (e[i] <= -side[i]) return 0;
else if (e[i] >= side[i]) thi = tp;
}
else if (s[i] <= side[i]) {
if (e[i] <= -side[i]) thi = tm;
else if (e[i] >= side[i]) thi = tp;
}
else {
tlo = tp;
if (e[i] <= -side[i]) thi = tm;
else if (e[i] >= side[i]) return 0;
}
}
//... @@@ AT HERE @@@
return 1;
}
//***************************************************************************
// a nice try at C-B collision. unfortunately it doesn't work. the logic
// for testing for line-box intersection is correct, but unfortunately the
// closest-point distance estimates are often too large. as a result contact
// points are placed incorrectly.
int dCollideCB (const dxGeom *o1, const dxGeom *o2, int flags,
dContactGeom *contact, int skip)
{
int i;
dIASSERT (skip >= (int)sizeof(dContactGeom));
dIASSERT (o1->_class->num == dCCylinderClass);
dIASSERT (o2->_class->num == dBoxClass);
contact->g1 = const_cast<dxGeom*> (o1);
contact->g2 = const_cast<dxGeom*> (o2);
dxCCylinder *cyl = (dxCCylinder*) CLASSDATA(o1);
dxBox *box = (dxBox*) CLASSDATA(o2);
// get p1,p2 = cylinder axis endpoints, get radius
dVector3 p1,p2;
dReal clen = cyl->lz * REAL(0.5);
p1[0] = o1->pos[0] + clen * o1->R[2];
p1[1] = o1->pos[1] + clen * o1->R[6];
p1[2] = o1->pos[2] + clen * o1->R[10];
p2[0] = o1->pos[0] - clen * o1->R[2];
p2[1] = o1->pos[1] - clen * o1->R[6];
p2[2] = o1->pos[2] - clen * o1->R[10];
dReal radius = cyl->radius;
// copy out box center, rotation matrix, and side array
dReal *c = o2->pos;
dReal *R = o2->R;
dReal *side = box->side;
// compute the start and end of the line (p1 and p2) relative to the box.
// we will do all subsequent computations in this box-relative coordinate
// system. we have to do a translation and rotation for each point.
dVector3 tmp3,s,e;
tmp3[0] = p1[0] - c[0];
tmp3[1] = p1[1] - c[1];
tmp3[2] = p1[2] - c[2];
dMULTIPLY1_331 (s,R,tmp3);
tmp3[0] = p2[0] - c[0];
tmp3[1] = p2[1] - c[1];
tmp3[2] = p2[2] - c[2];
dMULTIPLY1_331 (e,R,tmp3);
// compute the vector 'v' from the start point to the end point
dVector3 v;
v[0] = e[0] - s[0];
v[1] = e[1] - s[1];
v[2] = e[2] - s[2];
// compute the half-sides of the box
dReal S0 = side[0] * REAL(0.5);
dReal S1 = side[1] * REAL(0.5);
dReal S2 = side[2] * REAL(0.5);
// compute the size of the bounding box around the line segment
dReal B0 = dFabs (v[0]);
dReal B1 = dFabs (v[1]);
dReal B2 = dFabs (v[2]);
// for all 6 separation axes, measure the penetration depth. if any depth is
// less than 0 then the objects don't penetrate at all so we can just
// return 0. find the axis with the smallest depth, and record its normal.
// note: normalR is set to point to a column of R if that is the smallest
// depth normal so far. otherwise normalR is 0 and normalC is set to a
// vector relative to the box. invert_normal is 1 if the sign of the normal
// should be flipped.
dReal depth,trial_depth,tmp,length;
const dReal *normalR=0;
dVector3 normalC;
int invert_normal = 0;
int code = 0; // 0=no contact, 1-3=face contact, 4-6=edge contact
depth = dInfinity;
// look at face-normal axes
#undef TEST
#define TEST(center,depth_expr,norm,contact_code) \
tmp = (center); \
trial_depth = radius + REAL(0.5) * ((depth_expr) - dFabs(tmp)); \
if (trial_depth < 0) return 0; \
if (trial_depth < depth) { \
depth = trial_depth; \
normalR = (norm); \
invert_normal = (tmp < 0); \
code = contact_code; \
}
TEST (s[0]+e[0], side[0] + B0, R+0, 1);
TEST (s[1]+e[1], side[1] + B1, R+1, 2);
TEST (s[2]+e[2], side[2] + B2, R+2, 3);
// look at v x box-edge axes
#undef TEST
#define TEST(box_radius,line_offset,nx,ny,nz,contact_code) \
tmp = (line_offset); \
trial_depth = (box_radius) - dFabs(tmp); \
length = dSqrt ((nx)*(nx) + (ny)*(ny) + (nz)*(nz)); \
if (length > 0) { \
length = dRecip(length); \
trial_depth = trial_depth * length + radius; \
if (trial_depth < 0) return 0; \
if (trial_depth < depth) { \
depth = trial_depth; \
normalR = 0; \
normalC[0] = (nx)*length; \
normalC[1] = (ny)*length; \
normalC[2] = (nz)*length; \
invert_normal = (tmp < 0); \
code = contact_code; \
} \
}
TEST (B2*S1+B1*S2,v[1]*s[2]-v[2]*s[1], 0,-v[2],v[1], 4);
TEST (B2*S0+B0*S2,v[2]*s[0]-v[0]*s[2], v[2],0,-v[0], 5);
TEST (B1*S0+B0*S1,v[0]*s[1]-v[1]*s[0], -v[1],v[0],0, 6);
#undef TEST
// if we get to this point, the box and ccylinder interpenetrate.
// compute the normal in global coordinates.
dReal *normal = contact[0].normal;
if (normalR) {
normal[0] = normalR[0];
normal[1] = normalR[4];
normal[2] = normalR[8];
}
else {
dMULTIPLY0_331 (normal,R,normalC);
}
if (invert_normal) {
normal[0] = -normal[0];
normal[1] = -normal[1];
normal[2] = -normal[2];
}
// set the depth
contact[0].depth = depth;
if (code == 0) {
return 0; // should never get here
}
else if (code >= 4) {
// handle edge contacts
// find an endpoint q1 on the intersecting edge of the box
dVector3 q1;
dReal sign[3];
for (i=0; i<3; i++) q1[i] = c[i];
sign[0] = (dDOT14(normal,R+0) > 0) ? REAL(1.0) : REAL(-1.0);
for (i=0; i<3; i++) q1[i] += sign[0] * S0 * R[i*4];
sign[1] = (dDOT14(normal,R+1) > 0) ? REAL(1.0) : REAL(-1.0);
for (i=0; i<3; i++) q1[i] += sign[1] * S1 * R[i*4+1];
sign[2] = (dDOT14(normal,R+2) > 0) ? REAL(1.0) : REAL(-1.0);
for (i=0; i<3; i++) q1[i] += sign[2] * S2 * R[i*4+2];
// find the other endpoint q2 of the intersecting edge
dVector3 q2;
for (i=0; i<3; i++)
q2[i] = q1[i] - R[code-4 + i*4] * (sign[code-4] * side[code-4]);
// determine the closest point between the box edge and the line segment
dVector3 cp1,cp2;
dClosestLineSegmentPoints (q1,q2, p1,p2, cp1,cp2);
for (i=0; i<3; i++) contact[0].pos[i] = cp1[i] - REAL(0.5)*normal[i]*depth;
return 1;
}
else {
// handle face contacts.
// @@@ temporary: make deepest vertex on the line the contact point.
// @@@ this kind of works, but we sometimes need two contact points for
// @@@ stability.
// compute 'v' in global coordinates
dVector3 gv;
for (i=0; i<3; i++) gv[i] = p2[i] - p1[i];
if (dDOT (normal,gv) > 0) {
for (i=0; i<3; i++)
contact[0].pos[i] = p1[i] + (depth*REAL(0.5)-radius)*normal[i];
}
else {
for (i=0; i<3; i++)
contact[0].pos[i] = p2[i] + (depth*REAL(0.5)-radius)*normal[i];
}
return 1;
}
}

621
extern/ode/dist/ode/src/space.cpp vendored Normal file
View File

@@ -0,0 +1,621 @@
/*************************************************************************
* *
* 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. *
* *
*************************************************************************/
/*
simple space
------------
reports all n^2 object intersections
multi-resolution hash table
---------------------------
the current implementation rebuilds a new hash table each time collide()
is called. we don't keep any state between calls. this is wasteful if there
are unmoving objects in the space.
TODO
----
less memory wasting may to prevent multiple collision callbacks for the
same pair?
better virtual address function.
the collision search can perhaps be optimized - as we search chains we can
come across other candidate intersections at other levels, perhaps we should
do the intersection check straight away? --> save on list searching time only,
which is not too significant.
*/
//****************************************************************************
#include <ode/common.h>
#include <ode/space.h>
#include <ode/geom.h>
#include <ode/error.h>
#include <ode/memory.h>
#include "objects.h"
#include "geom_internal.h"
//****************************************************************************
// space base class
struct dxSpace : public dBase {
int type; // don't want to use RTTI
virtual void destroy()=0;
virtual void add (dGeomID)=0;
virtual void remove (dGeomID)=0;
virtual void collide (void *data, dNearCallback *callback)=0;
virtual int query (dGeomID)=0;
};
#define TYPE_SIMPLE 0xbad
#define TYPE_HASH 0xbabe
//****************************************************************************
// stuff common to all spaces
#define ALLOCA(x) dALLOCA16(x)
// collide two AABBs together. for the hash table space, this is called if
// the two AABBs inhabit the same hash table cells. this only calls the
// callback function if the boxes actually intersect. if a geom has an
// AABB test function, that is called to provide a further refinement of
// the intersection.
static inline void collideAABBs (dReal bounds1[6], dReal bounds2[6],
dxGeom *g1, dxGeom *g2,
void *data, dNearCallback *callback)
{
// no contacts if both geoms on the same body, and the body is not 0
if (g1->body == g2->body && g1->body) return;
if (bounds1[0] > bounds2[1] ||
bounds1[1] < bounds2[0] ||
bounds1[2] > bounds2[3] ||
bounds1[3] < bounds2[2] ||
bounds1[4] > bounds2[5] ||
bounds1[5] < bounds2[4]) return;
if (g1->_class->aabb_test) {
if (g1->_class->aabb_test (g1,g2,bounds2) == 0) return;
}
if (g2->_class->aabb_test) {
if (g2->_class->aabb_test (g2,g1,bounds1) == 0) return;
}
callback (data,g1,g2);
}
//****************************************************************************
// simple space - reports all n^2 object intersections
struct dxSimpleSpace : public dxSpace {
dGeomID first;
void destroy();
void add (dGeomID);
void remove (dGeomID);
void collide (void *data, dNearCallback *callback);
int query (dGeomID);
};
dSpaceID dSimpleSpaceCreate()
{
dxSimpleSpace *w = new dxSimpleSpace;
w->type = TYPE_SIMPLE;
w->first = 0;
return w;
}
void dxSimpleSpace::destroy()
{
// destroying each geom will call remove(). this will be efficient if
// we destroy geoms in list order.
dAASSERT (this);
dGeomID g,n;
g = first;
while (g) {
n = g->space.next;
dGeomDestroy (g);
g = n;
}
delete this;
}
void dxSimpleSpace::add (dGeomID obj)
{
dAASSERT (this && obj);
dUASSERT (obj->spaceid == 0 && obj->space.next == 0,
"object is already in a space");
obj->space.next = first;
first = obj;
obj->spaceid = this;
}
void dxSimpleSpace::remove (dGeomID geom_to_remove)
{
dAASSERT (this && geom_to_remove);
dUASSERT (geom_to_remove->spaceid,"object is not in a space");
dGeomID last=0,g=first;
while (g) {
if (g==geom_to_remove) {
if (last) last->space.next = g->space.next;
else first = g->space.next;
geom_to_remove->space.next = 0;
geom_to_remove->spaceid = 0;
return;
}
last = g;
g = g->space.next;
}
}
void dxSimpleSpace::collide (void *data, dNearCallback *callback)
{
dAASSERT (this && callback);
dxGeom *g1,*g2;
int i,j,n;
// count the number of objects
n=0;
for (g1=first; g1; g1=g1->space.next) n++;
// allocate and fill bounds array
dReal *bounds = (dReal*) ALLOCA (6 * n * sizeof(dReal));
i=0;
for (g1=first; g1; g1=g1->space.next) {
g1->_class->aabb (g1,bounds + i);
g1->space_aabb = bounds + i;
i += 6;
}
// intersect all bounding boxes
i=0;
for (g1=first; g1; g1=g1->space.next) {
j=i+6;
for (g2=g1->space.next; g2; g2=g2->space.next) {
collideAABBs (bounds+i,bounds+j,g1,g2,data,callback);
j += 6;
}
i += 6;
}
// reset the aabb fields of the geoms back to 0
for (g1=first; g1; g1=g1->space.next) g1->space_aabb = 0;
}
// @@@ NOT FLEXIBLE ENOUGH
//
//int dSpaceCollide (dSpaceID space, dContactGeom **contact_array)
//{
// int n = 0;
// dContactGeom *base = (dContact*) dStackAlloc (sizeof(dContact));
// dContactGeom *c = base;
// for (dxGeom *g1=space->first; g1; g1=g1->space.next) {
// for (dxGeom *g2=g1->space.next; g2; g2=g2->space.next) {
// // generate at most 1 contact for this pair
// c->o1 = g1;
// c->o2 = g2;
// if (dCollide (0,c)) {
// c = (dContactGeom*) dStackAlloc (sizeof(dContactGeom));
// n++;
// }
// }
// }
// *contact_array = base;
// return n;
//}
int dxSimpleSpace::query (dGeomID obj)
{
dAASSERT (this && obj);
if (obj->spaceid != this) return 0;
dGeomID compare = first;
while (compare) {
if (compare == obj) return 1;
compare = compare->space.next;
}
dDebug (0,"object is not in the space it thinks it is in");
return 0;
}
//****************************************************************************
// hash table space
// kind of silly, but oh well...
#define MAXINT ((int)((((unsigned int)(-1)) << 1) >> 1))
// prime[i] is the largest prime smaller than 2^i
#define NUM_PRIMES 31
static long int prime[NUM_PRIMES] = {1L,2L,3L,7L,13L,31L,61L,127L,251L,509L,
1021L,2039L,4093L,8191L,16381L,32749L,65521L,131071L,262139L,
524287L,1048573L,2097143L,4194301L,8388593L,16777213L,33554393L,
67108859L,134217689L,268435399L,536870909L,1073741789L};
// currently the space 'container' is just a list of the geoms in the space.
struct dxHashSpace : public dxSpace {
dxGeom *first;
int global_minlevel; // smallest hash table level to put AABBs in
int global_maxlevel; // objects that need a level larger than this will be
// put in a "big objects" list instead of a hash table
void destroy();
void add (dGeomID);
void remove (dGeomID);
void collide (void *data, dNearCallback *callback);
int query (dGeomID);
};
// an axis aligned bounding box
struct dxAABB {
dxAABB *next; // next in the list of all AABBs
dReal bounds[6]; // minx, maxx, miny, maxy, minz, maxz
int level; // the level this is stored in (cell size = 2^level)
int dbounds[6]; // AABB bounds, discretized to cell size
dxGeom *geom; // corresponding geometry object
int index; // index of this AABB, starting from 0
};
// a hash table node that represents an AABB that intersects a particular cell
// at a particular level
struct Node {
Node *next; // next node in hash table collision list, 0 if none
int x,y,z; // cell position in space, discretized to cell size
dxAABB *aabb; // axis aligned bounding box that intersects this cell
};
// return the `level' of an AABB. the AABB will be put into cells at this
// level - the cell size will be 2^level. the level is chosen to be the
// smallest value such that the AABB occupies no more than 8 cells, regardless
// of its placement. this means that:
// size/2 < q <= size
// where q is the maximum AABB dimension.
static int findLevel (dReal bounds[6])
{
// compute q
dReal q,q2;
q = bounds[1] - bounds[0]; // x bounds
q2 = bounds[3] - bounds[2]; // y bounds
if (q2 > q) q = q2;
q2 = bounds[5] - bounds[4]; // z bounds
if (q2 > q) q = q2;
if (q == dInfinity) return MAXINT;
// find level such that 0.5 * 2^level < q <= 2^level
int level;
frexp (q,&level); // q = (0.5 .. 1.0) * 2^level (definition of frexp)
return level;
}
// find a virtual memory address for a cell at the given level and x,y,z
// position.
// @@@ currently this is not very sophisticated, e.g. the scaling
// factors could be better designed to avoid collisions, and they should
// probably depend on the hash table physical size.
static unsigned long getVirtualAddress (int level, int x, int y, int z)
{
return level*1000 + x*100 + y*10 + z;
}
//****************************************************************************
// hash space public functions
dSpaceID dHashSpaceCreate()
{
dxHashSpace *w = new dxHashSpace;
w->type = TYPE_HASH;
w->first = 0;
w->global_minlevel = -3;
w->global_maxlevel = 10;
return w;
}
void dxHashSpace::destroy()
{
// destroying each geom will call remove(). this will be efficient if
// we destroy geoms in list order.
dAASSERT (this);
dGeomID g,n;
g = first;
while (g) {
n = g->space.next;
dGeomDestroy (g);
g = n;
}
delete this;
}
void dHashSpaceSetLevels (dxSpace *space, int minlevel, int maxlevel)
{
dUASSERT (minlevel <= maxlevel,"must have minlevel <= maxlevel");
dUASSERT (space->type == TYPE_HASH,"must be a hash space");
dxHashSpace *hspace = (dxHashSpace*) space;
hspace->global_minlevel = minlevel;
hspace->global_maxlevel = maxlevel;
}
void dxHashSpace::add (dGeomID obj)
{
dAASSERT (this && obj);
dUASSERT (obj->spaceid == 0 && obj->space.next == 0,
"object is already in a space");
obj->space.next = first;
first = obj;
obj->spaceid = this;
}
void dxHashSpace::remove (dGeomID geom_to_remove)
{
dAASSERT (this && geom_to_remove);
dUASSERT (geom_to_remove->spaceid,"object is not in a space");
dGeomID last=0,g=first;
while (g) {
if (g==geom_to_remove) {
if (last) last->space.next = g->space.next;
else first = g->space.next;
geom_to_remove->space.next = 0;
geom_to_remove->spaceid = 0;
return;
}
last = g;
g = g->space.next;
}
}
void dxHashSpace::collide (void *data, dNearCallback *callback)
{
dAASSERT(this && callback);
dxGeom *geom;
dxAABB *aabb;
int i,maxlevel;
// create a list of axis aligned bounding boxes for all geoms. count the
// number of AABBs as we go. set the level for all AABBs. put AABBs larger
// than the space's global_maxlevel in the big_boxes list, check everything
// else against that list at the end. for AABBs that are not too big,
// record the maximum level that we need.
int n = 0; // number of AABBs in main list
int ntotal = 0; // total number of AABBs
dxAABB *first_aabb = 0; // list of AABBs in hash table
dxAABB *big_boxes = 0; // list of AABBs too big for hash table
maxlevel = global_minlevel - 1;
for (geom = first; geom; geom=geom->space.next) {
ntotal++;
dxAABB *aabb = (dxAABB*) ALLOCA (sizeof(dxAABB));
geom->_class->aabb (geom,aabb->bounds);
geom->space_aabb = aabb->bounds;
aabb->geom = geom;
// compute level, but prevent cells from getting too small
int level = findLevel (aabb->bounds);
if (level < global_minlevel) level = global_minlevel;
if (level <= global_maxlevel) {
// aabb goes in main list
aabb->next = first_aabb;
first_aabb = aabb;
aabb->level = level;
if (level > maxlevel) maxlevel = level;
// cellsize = 2^level
dReal cellsize = (dReal) ldexp (1.0,level);
// discretize AABB position to cell size
for (i=0; i < 6; i++) aabb->dbounds[i] = (int)
floor (aabb->bounds[i]/cellsize);
// set AABB index
aabb->index = n;
n++;
}
else {
// aabb is too big, put it in the big_boxes list. we don't care about
// setting level, dbounds, index, or the maxlevel
aabb->next = big_boxes;
big_boxes = aabb;
}
}
// 0 or 1 boxes can't collide with anything
if (ntotal < 2) return;
// for `n' objects, an n*n array of bits is used to record if those objects
// have been intersection-tested against each other yet. this array can
// grow large with high n, but oh well...
int tested_rowsize = (n+7) >> 3; // number of bytes needed for n bits
unsigned char *tested = (unsigned char *) alloca (n * tested_rowsize);
memset (tested,0,n * tested_rowsize);
// create a hash table to store all AABBs. each AABB may take up to 8 cells.
// we use chaining to resolve collisions, but we use a relatively large table
// to reduce the chance of collisions.
// compute hash table size sz to be a prime > 8*n
for (i=0; i<NUM_PRIMES; i++) {
if (prime[i] >= (8*n)) break;
}
if (i >= NUM_PRIMES) i = NUM_PRIMES-1; // probably pointless
int sz = prime[i];
// allocate and initialize hash table node pointers
Node **table = (Node **) ALLOCA (sizeof(Node*) * sz);
for (i=0; i<sz; i++) table[i] = 0;
// add each AABB to the hash table (may need to add it to up to 8 cells)
for (aabb=first_aabb; aabb; aabb=aabb->next) {
int *dbounds = aabb->dbounds;
for (int xi = dbounds[0]; xi <= dbounds[1]; xi++) {
for (int yi = dbounds[2]; yi <= dbounds[3]; yi++) {
for (int zi = dbounds[4]; zi <= dbounds[5]; zi++) {
// get the hash index
unsigned long hi = getVirtualAddress (aabb->level,xi,yi,zi) % sz;
// add a new node to the hash table
Node *node = (Node*) alloca (sizeof (Node));
node->x = xi;
node->y = yi;
node->z = zi;
node->aabb = aabb;
node->next = table[hi];
table[hi] = node;
}
}
}
}
// now that all AABBs are loaded into the hash table, we do the actual
// collision detection. for all AABBs, check for other AABBs in the
// same cells for collisions, and then check for other AABBs in all
// intersecting higher level cells.
int db[6]; // discrete bounds at current level
for (aabb=first_aabb; aabb; aabb=aabb->next) {
// we are searching for collisions with aabb
for (i=0; i<6; i++) db[i] = aabb->dbounds[i];
for (int level = aabb->level; level <= maxlevel; level++) {
for (int xi = db[0]; xi <= db[1]; xi++) {
for (int yi = db[2]; yi <= db[3]; yi++) {
for (int zi = db[4]; zi <= db[5]; zi++) {
// get the hash index
unsigned long hi = getVirtualAddress (level,xi,yi,zi) % sz;
// search all nodes at this index
Node *node;
for (node = table[hi]; node; node=node->next) {
// node points to an AABB that may intersect aabb
if (node->aabb == aabb) continue;
if (node->aabb->level == level &&
node->x == xi && node->y == yi && node->z == zi) {
// see if aabb and node->aabb have already been tested
// against each other
unsigned char mask;
if (aabb->index <= node->aabb->index) {
i = (aabb->index * tested_rowsize)+(node->aabb->index >> 3);
mask = 1 << (node->aabb->index & 7);
}
else {
i = (node->aabb->index * tested_rowsize)+(aabb->index >> 3);
mask = 1 << (aabb->index & 7);
}
dIASSERT (i >= 0 && i < (tested_rowsize*n));
if ((tested[i] & mask)==0) {
collideAABBs (aabb->bounds,node->aabb->bounds,
aabb->geom,node->aabb->geom,
data,callback);
}
tested[i] |= mask;
}
}
}
}
}
// get the discrete bounds for the next level up
for (i=0; i<6; i++) db[i] >>= 1;
}
}
// every AABB in the normal list must now be intersected against every
// AABB in the big_boxes list. so let's hope there are not too many objects
// in the big_boxes list.
for (aabb=first_aabb; aabb; aabb=aabb->next) {
for (dxAABB *aabb2=big_boxes; aabb2; aabb2=aabb2->next) {
collideAABBs (aabb->bounds,aabb2->bounds,aabb->geom,aabb2->geom,
data,callback);
}
}
// intersected all AABBs in the big_boxes list together
for (aabb=big_boxes; aabb; aabb=aabb->next) {
for (dxAABB *aabb2=aabb->next; aabb2; aabb2=aabb2->next) {
collideAABBs (aabb->bounds,aabb2->bounds,aabb->geom,aabb2->geom,
data,callback);
}
}
// reset the aabb fields of the geoms back to 0
for (geom=first; geom; geom=geom->space.next) geom->space_aabb = 0;
}
int dxHashSpace::query (dGeomID obj)
{
dAASSERT (this && obj);
if (obj->spaceid != this) return 0;
dGeomID compare = first;
while (compare) {
if (compare == obj) return 1;
compare = compare->space.next;
}
dDebug (0,"object is not in the space it thinks it is in");
return 0;
}
//****************************************************************************
// space functions
void dSpaceDestroy (dxSpace * space)
{
space->destroy();
}
void dSpaceAdd (dxSpace * space, dxGeom *g)
{
space->add (g);
}
void dSpaceRemove (dxSpace * space, dxGeom *g)
{
space->remove (g);
}
int dSpaceQuery (dxSpace * space, dxGeom *g)
{
return space->query (g);
}
void dSpaceCollide (dxSpace * space, void *data, dNearCallback *callback)
{
space->collide (data,callback);
}

114
extern/ode/dist/ode/src/stack.cpp vendored Normal file
View File

@@ -0,0 +1,114 @@
/*************************************************************************
* *
* Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. *
* All rights reserved. Email: russ@q12.org Web: www.q12.org *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of EITHER: *
* (1) The GNU Lesser General Public License as published by the Free *
* Software Foundation; either version 2.1 of the License, or (at *
* your option) any later version. The text of the GNU Lesser *
* General Public License is included with this library in the *
* file LICENSE.TXT. *
* (2) The BSD-style license that is included with this library in *
* the file LICENSE-BSD.TXT. *
* *
* This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files *
* LICENSE.TXT and LICENSE-BSD.TXT for more details. *
* *
*************************************************************************/
@@@ this file should not be compiled any more @@@
#include <string.h>
#include <errno.h>
#include "stack.h"
#include "ode/error.h"
#include "ode/config.h"
//****************************************************************************
// unix version that uses mmap(). some systems have anonymous mmaps and some
// need to mmap /dev/zero.
#ifndef WIN32
#include <unistd.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
void dStack::init (int max_size)
{
if (sizeof(long int) != sizeof(char*)) dDebug (0,"internal");
if (max_size <= 0) dDebug (0,"Stack::init() given size <= 0");
#ifndef MMAP_ANONYMOUS
static int dev_zero_fd = -1; // cached file descriptor for /dev/zero
if (dev_zero_fd < 0) dev_zero_fd = open ("/dev/zero", O_RDWR);
if (dev_zero_fd < 0) dError (0,"can't open /dev/zero (%s)",strerror(errno));
base = (char*) mmap (0,max_size, PROT_READ | PROT_WRITE, MAP_PRIVATE,
dev_zero_fd,0);
#else
base = (char*) mmap (0,max_size, PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANON,0,0);
#endif
if (int(base) == -1) dError (0,"Stack::init(), mmap() failed, "
"max_size=%d (%s)",max_size,strerror(errno));
size = max_size;
pointer = base;
frame = 0;
}
void dStack::destroy()
{
munmap (base,size);
base = 0;
size = 0;
pointer = 0;
frame = 0;
}
#endif
//****************************************************************************
#ifdef WIN32
#include "windows.h"
void dStack::init (int max_size)
{
if (sizeof(LPVOID) != sizeof(char*)) dDebug (0,"internal");
if (max_size <= 0) dDebug (0,"Stack::init() given size <= 0");
base = (char*) VirtualAlloc (NULL,max_size,MEM_RESERVE,PAGE_READWRITE);
if (base == 0) dError (0,"Stack::init(), VirtualAlloc() failed, "
"max_size=%d",max_size);
size = max_size;
pointer = base;
frame = 0;
committed = 0;
// get page size
SYSTEM_INFO info;
GetSystemInfo (&info);
pagesize = info.dwPageSize;
}
void dStack::destroy()
{
VirtualFree (base,0,MEM_RELEASE);
base = 0;
size = 0;
pointer = 0;
frame = 0;
}
#endif

138
extern/ode/dist/ode/src/stack.h vendored Normal file
View File

@@ -0,0 +1,138 @@
/*************************************************************************
* *
* 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.
these stack allocation functions are a replacement for alloca(), except that
they allocate memory from a separate pool.
advantages over alloca():
- consecutive allocations are guaranteed to be contiguous with increasing
address.
- functions can allocate stack memory that is returned to the caller,
in other words pushing and popping stack frames is optional.
disadvantages compared to alloca():
- less portable
- slightly slower, although still orders of magnitude faster than malloc().
- longjmp() and exceptions do not deallocate stack memory (but who cares?).
just like alloca():
- using too much stack memory does not fail gracefully, it fails with a
segfault.
*/
#ifndef _ODE_STACK_H_
#define _ODE_STACK_H_
#ifdef WIN32
#include "windows.h"
#endif
struct dStack {
char *base; // bottom of the stack
int size; // maximum size of the stack
char *pointer; // current top of the stack
char *frame; // linked list of stack frame ptrs
# ifdef WIN32 // stuff for windows:
int pagesize; // - page size - this is ASSUMED to be a power of 2
int committed; // - bytes committed in allocated region
#endif
// initialize the stack. `max_size' is the maximum size that the stack can
// reach. on unix and windows a `virtual' memory block of this size is
// mapped into the address space but does not actually consume physical
// memory until it is referenced - so it is safe to set this to a high value.
void init (int max_size);
// destroy the stack. this unmaps any virtual memory that was allocated.
void destroy();
// allocate `size' bytes from the stack and return a pointer to the allocated
// memory. `size' must be >= 0. the returned pointer will be aligned to the
// size of a long int.
char * alloc (int size)
{
char *ret = pointer;
pointer += ((size-1) | (sizeof(long int)-1) )+1;
# ifdef WIN32
// for windows we need to commit pages as they are required
if ((pointer-base) > committed) {
committed = ((pointer-base-1) | (pagesize-1))+1; // round up to pgsize
VirtualAlloc (base,committed,MEM_COMMIT,PAGE_READWRITE);
}
# endif
return ret;
}
// return the address that will be returned by the next call to alloc()
char *nextAlloc()
{
return pointer;
}
// push and pop the current size of the stack. pushFrame() saves the current
// frame pointer on the stack, and popFrame() retrieves it. a typical
// stack-using function will bracket alloc() calls with pushFrame() and
// popFrame(). both functions return the current stack pointer - this should
// be the same value for the two bracketing calls. calling popFrame() too
// many times will result in a segfault.
char * pushFrame()
{
char *newframe = pointer;
char **addr = (char**) alloc (sizeof(char*));
*addr = frame;
frame = newframe;
return newframe;
/* OLD CODE
*((char**)pointer) = frame;
frame = pointer;
char *ret = pointer;
pointer += sizeof(char*);
return ret;
*/
}
char * popFrame()
{
pointer = frame;
frame = *((char**)pointer);
return pointer;
}
};
#endif

1085
extern/ode/dist/ode/src/step.cpp vendored Normal file

File diff suppressed because it is too large Load Diff

36
extern/ode/dist/ode/src/step.h vendored Normal file
View File

@@ -0,0 +1,36 @@
/*************************************************************************
* *
* 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_STEP_H_
#define _ODE_STEP_H_
#include <ode/common.h>
void dInternalStepIsland (dxWorld *world,
dxBody * const *body, int nb,
dxJoint * const *joint, int nj,
dReal stepsize);
#endif

243
extern/ode/dist/ode/src/testing.cpp vendored Normal file
View File

@@ -0,0 +1,243 @@
/*************************************************************************
* *
* 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/misc.h>
#include <ode/memory.h>
#include "testing.h"
#ifdef dDOUBLE
static const dReal tol = 1.0e-9;
#else
static const dReal tol = 1.0e-5f;
#endif
// matrix header on the stack
struct dMatrixComparison::dMatInfo {
int n,m; // size of matrix
char name[128]; // name of the matrix
dReal *data; // matrix data
int size; // size of `data'
};
dMatrixComparison::dMatrixComparison()
{
afterfirst = 0;
index = 0;
}
dMatrixComparison::~dMatrixComparison()
{
reset();
}
dReal dMatrixComparison::nextMatrix (dReal *A, int n, int m, int lower_tri,
char *name, ...)
{
if (A==0 || n < 1 || m < 1 || name==0) dDebug (0,"bad args to nextMatrix");
int num = n*dPAD(m);
if (afterfirst==0) {
dMatInfo *mi = (dMatInfo*) dAlloc (sizeof(dMatInfo));
mi->n = n;
mi->m = m;
mi->size = num * sizeof(dReal);
mi->data = (dReal*) dAlloc (mi->size);
memcpy (mi->data,A,mi->size);
va_list ap;
va_start (ap,name);
vsprintf (mi->name,name,ap);
if (strlen(mi->name) >= sizeof (mi->name)) dDebug (0,"name too long");
mat.push (mi);
return 0;
}
else {
if (lower_tri && n != m)
dDebug (0,"dMatrixComparison, lower triangular matrix must be square");
if (index >= mat.size()) dDebug (0,"dMatrixComparison, too many matrices");
dMatInfo *mp = mat[index];
index++;
dMatInfo mi;
va_list ap;
va_start (ap,name);
vsprintf (mi.name,name,ap);
if (strlen(mi.name) >= sizeof (mi.name)) dDebug (0,"name too long");
if (strcmp(mp->name,mi.name) != 0)
dDebug (0,"dMatrixComparison, name mismatch (\"%s\" and \"%s\")",
mp->name,mi.name);
if (mp->n != n || mp->m != m)
dDebug (0,"dMatrixComparison, size mismatch (%dx%d and %dx%d)",
mp->n,mp->m,n,m);
dReal maxdiff;
if (lower_tri) {
maxdiff = dMaxDifferenceLowerTriangle (A,mp->data,n);
}
else {
maxdiff = dMaxDifference (A,mp->data,n,m);
}
if (maxdiff > tol)
dDebug (0,"dMatrixComparison, matrix error (size=%dx%d, name=\"%s\", "
"error=%.4e)",n,m,mi.name,maxdiff);
return maxdiff;
}
}
void dMatrixComparison::end()
{
if (mat.size() <= 0) dDebug (0,"no matrices in sequence");
afterfirst = 1;
index = 0;
}
void dMatrixComparison::reset()
{
for (int i=0; i<mat.size(); i++) {
dFree (mat[i]->data,mat[i]->size);
dFree (mat[i],sizeof(dMatInfo));
}
mat.setSize (0);
afterfirst = 0;
index = 0;
}
void dMatrixComparison::dump()
{
for (int i=0; i<mat.size(); i++)
printf ("%d: %s (%dx%d)\n",i,mat[i]->name,mat[i]->n,mat[i]->m);
}
//****************************************************************************
// unit test
#include <setjmp.h>
static jmp_buf jump_buffer;
static void myDebug (int num, const char *msg, va_list ap)
{
// printf ("(Error %d: ",num);
// vprintf (msg,ap);
// printf (")\n");
longjmp (jump_buffer,1);
}
extern "C" void dTestMatrixComparison()
{
volatile int i;
printf ("dTestMatrixComparison()\n");
dMessageFunction *orig_debug = dGetDebugHandler();
dMatrixComparison mc;
dReal A[50*50];
// make first sequence
unsigned long seed = dRandGetSeed();
for (i=1; i<49; i++) {
dMakeRandomMatrix (A,i,i+1,1.0);
mc.nextMatrix (A,i,i+1,0,"A%d",i);
}
mc.end();
//mc.dump();
// test identical sequence
dSetDebugHandler (&myDebug);
dRandSetSeed (seed);
if (setjmp (jump_buffer)) {
printf ("\tFAILED (1)\n");
}
else {
for (i=1; i<49; i++) {
dMakeRandomMatrix (A,i,i+1,1.0);
mc.nextMatrix (A,i,i+1,0,"A%d",i);
}
mc.end();
printf ("\tpassed (1)\n");
}
dSetDebugHandler (orig_debug);
// test broken sequences (with matrix error)
dRandSetSeed (seed);
volatile int passcount = 0;
for (i=1; i<49; i++) {
if (setjmp (jump_buffer)) {
passcount++;
}
else {
dSetDebugHandler (&myDebug);
dMakeRandomMatrix (A,i,i+1,1.0);
A[(i-1)*dPAD(i+1)+i] += REAL(0.01);
mc.nextMatrix (A,i,i+1,0,"A%d",i);
dSetDebugHandler (orig_debug);
}
}
mc.end();
printf ("\t%s (2)\n",(passcount == 48) ? "passed" : "FAILED");
// test broken sequences (with name error)
dRandSetSeed (seed);
passcount = 0;
for (i=1; i<49; i++) {
if (setjmp (jump_buffer)) {
passcount++;
}
else {
dSetDebugHandler (&myDebug);
dMakeRandomMatrix (A,i,i+1,1.0);
mc.nextMatrix (A,i,i+1,0,"B%d",i);
dSetDebugHandler (orig_debug);
}
}
mc.end();
printf ("\t%s (3)\n",(passcount == 48) ? "passed" : "FAILED");
// test identical sequence again
dSetDebugHandler (&myDebug);
dRandSetSeed (seed);
if (setjmp (jump_buffer)) {
printf ("\tFAILED (4)\n");
}
else {
for (i=1; i<49; i++) {
dMakeRandomMatrix (A,i,i+1,1.0);
mc.nextMatrix (A,i,i+1,0,"A%d",i);
}
mc.end();
printf ("\tpassed (4)\n");
}
dSetDebugHandler (orig_debug);
}

65
extern/ode/dist/ode/src/testing.h vendored Normal file
View File

@@ -0,0 +1,65 @@
/*************************************************************************
* *
* 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. *
* *
*************************************************************************/
/* stuff used for testing */
#ifndef _ODE_TESTING_H_
#define _ODE_TESTING_H_
#include <ode/common.h>
#include "array.h"
// compare a sequence of named matrices/vectors, i.e. to make sure that two
// different pieces of code are giving the same results.
class dMatrixComparison {
struct dMatInfo;
dArray<dMatInfo*> mat;
int afterfirst,index;
public:
dMatrixComparison();
~dMatrixComparison();
dReal nextMatrix (dReal *A, int n, int m, int lower_tri, char *name, ...);
// add a new n*m matrix A to the sequence. the name of the matrix is given
// by the printf-style arguments (name,...). if this is the first sequence
// then this object will simply record the matrices and return 0.
// if this the second or subsequent sequence then this object will compare
// the matrices with the first sequence, and report any differences.
// the matrix error will be returned. if `lower_tri' is 1 then only the
// lower triangle of the matrix (including the diagonal) will be compared
// (the matrix must be square).
void end();
// end a sequence.
void reset();
// restarts the object, so the next sequence will be the first sequence.
void dump();
// print out info about all the matrices in the sequence
};
#endif

397
extern/ode/dist/ode/src/timer.cpp vendored Normal file
View File

@@ -0,0 +1,397 @@
/*************************************************************************
* *
* 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. *
* *
*************************************************************************/
/*
TODO
----
* gettimeofday() and the pentium time stamp counter return the real time,
not the process time. fix this somehow!
*/
#include <ode/common.h>
#include <ode/timer.h>
// misc defines
#define ALLOCA dALLOCA16
//****************************************************************************
// implementation for windows based on the multimedia performance counter.
#ifdef WIN32
#include "windows.h"
static inline void getClockCount (unsigned long cc[2])
{
LARGE_INTEGER a;
QueryPerformanceCounter (&a);
cc[0] = a.LowPart;
cc[1] = a.HighPart;
}
static inline void serialize()
{
}
static inline double loadClockCount (unsigned long cc[2])
{
LARGE_INTEGER a;
a.LowPart = cc[0];
a.HighPart = cc[1];
return double(a.QuadPart);
}
double dTimerResolution()
{
return 1.0/dTimerTicksPerSecond();
}
double dTimerTicksPerSecond()
{
static int query=0;
static double hz=0.0;
if (!query) {
LARGE_INTEGER a;
QueryPerformanceFrequency (&a);
hz = double(a.QuadPart);
query = 1;
}
return hz;
}
#endif
//****************************************************************************
// implementation based on the pentium time stamp counter. the timer functions
// can be serializing or non-serializing. serializing will ensure that all
// instructions have executed and data has been written back before the cpu
// time stamp counter is read. the CPUID instruction is used to serialize.
#if defined(PENTIUM) && !defined(WIN32)
// we need to know the clock rate so that the timing function can report
// accurate times. this number only needs to be set accurately if we're
// doing performance tests and care about real-world time numbers - otherwise,
// just ignore this. i have not worked out how to determine this number
// automatically yet.
#define PENTIUM_HZ (500e6)
static inline void getClockCount (unsigned long cc[2])
{
asm volatile ("
rdtsc
movl %%eax,(%%esi)
movl %%edx,4(%%esi)"
: : "S" (cc) : "%eax","%edx","cc","memory");
}
static inline void serialize()
{
asm volatile ("
mov $0,%%eax
cpuid"
: : : "%eax","%ebx","%ecx","%edx","cc","memory");
}
static inline double loadClockCount (unsigned long a[2])
{
double ret;
asm volatile ("fildll %1; fstpl %0" : "=m" (ret) : "m" (a[0]) :
"cc","memory");
return ret;
}
double dTimerResolution()
{
return 1.0/PENTIUM_HZ;
}
double dTimerTicksPerSecond()
{
return PENTIUM_HZ;
}
#endif
//****************************************************************************
// otherwise, do the implementation based on gettimeofday().
#if !defined(PENTIUM) && !defined(WIN32)
#ifndef macintosh
#include <sys/time.h>
#include <unistd.h>
static inline void getClockCount (unsigned long cc[2])
{
struct timeval tv;
gettimeofday (&tv,0);
cc[0] = tv.tv_usec;
cc[1] = tv.tv_sec;
}
#else // macintosh
#include <MacTypes.h>
#include <Timer.h>
static inline void getClockCount (unsigned long cc[2])
{
UnsignedWide ms;
Microseconds (&ms);
cc[1] = ms.lo / 1000000;
cc[0] = ms.lo - ( cc[1] * 1000000 );
}
#endif
static inline void serialize()
{
}
static inline double loadClockCount (unsigned long a[2])
{
return a[1]*1.0e6 + a[0];
}
double dTimerResolution()
{
unsigned long cc1[2],cc2[2];
getClockCount (cc1);
do {
getClockCount (cc2);
}
while (cc1[0]==cc2[0] && cc1[1]==cc2[1]);
do {
getClockCount (cc1);
}
while (cc1[0]==cc2[0] && cc1[1]==cc2[1]);
double t1 = loadClockCount (cc1);
double t2 = loadClockCount (cc2);
return (t1-t2) / dTimerTicksPerSecond();
}
double dTimerTicksPerSecond()
{
return 1000000;
}
#endif
//****************************************************************************
// stop watches
void dStopwatchReset (dStopwatch *s)
{
s->time = 0;
s->cc[0] = 0;
s->cc[1] = 0;
}
void dStopwatchStart (dStopwatch *s)
{
serialize();
getClockCount (s->cc);
}
void dStopwatchStop (dStopwatch *s)
{
unsigned long cc[2];
serialize();
getClockCount (cc);
double t1 = loadClockCount (s->cc);
double t2 = loadClockCount (cc);
s->time += t2-t1;
}
double dStopwatchTime (dStopwatch *s)
{
return s->time / dTimerTicksPerSecond();
}
//****************************************************************************
// code timers
// maximum number of events to record
#define MAXNUM 100
static int num = 0; // number of entries used in event array
static struct {
unsigned long cc[2]; // clock counts
double total_t; // total clocks used in this slot.
double total_p; // total percentage points used in this slot.
int count; // number of times this slot has been updated.
char *description; // pointer to static string
} event[MAXNUM];
// make sure all slot totals and counts reset to 0 at start
static void initSlots()
{
static int initialized=0;
if (!initialized) {
for (int i=0; i<MAXNUM; i++) {
event[i].count = 0;
event[i].total_t = 0;
event[i].total_p = 0;
}
initialized = 1;
}
}
void dTimerStart (const char *description)
{
initSlots();
event[0].description = const_cast<char*> (description);
num = 1;
serialize();
getClockCount (event[0].cc);
}
void dTimerNow (const char *description)
{
if (num < MAXNUM) {
// do not serialize
getClockCount (event[num].cc);
event[num].description = const_cast<char*> (description);
num++;
}
}
void dTimerEnd()
{
if (num < MAXNUM) {
serialize();
getClockCount (event[num].cc);
event[num].description = "TOTAL";
num++;
}
}
//****************************************************************************
// print report
static void fprintDoubleWithPrefix (FILE *f, double a, char *fmt)
{
if (a >= 0.999999) {
fprintf (f,fmt,a);
return;
}
a *= 1000.0;
if (a >= 0.999999) {
fprintf (f,fmt,a);
fprintf (f,"m");
return;
}
a *= 1000.0;
if (a >= 0.999999) {
fprintf (f,fmt,a);
fprintf (f,"u");
return;
}
a *= 1000.0;
fprintf (f,fmt,a);
fprintf (f,"n");
}
void dTimerReport (FILE *fout, int average)
{
int i,maxl;
double ccunit = 1.0/dTimerTicksPerSecond();
fprintf (fout,"\nTimer Report (");
fprintDoubleWithPrefix (fout,ccunit,"%.2f ");
fprintf (fout,"s resolution)\n------------\n");
if (num < 1) return;
// get maximum description length
maxl = 0;
for (i=0; i<num; i++) {
int l = strlen (event[i].description);
if (l > maxl) maxl = l;
}
// calculate total time
double t1 = loadClockCount (event[0].cc);
double t2 = loadClockCount (event[num-1].cc);
double total = t2 - t1;
if (total <= 0) total = 1;
// compute time difference for all slots except the last one. update totals
double *times = (double*) ALLOCA (num * sizeof(double));
for (i=0; i < (num-1); i++) {
double t1 = loadClockCount (event[i].cc);
double t2 = loadClockCount (event[i+1].cc);
times[i] = t2 - t1;
event[i].count++;
event[i].total_t += times[i];
event[i].total_p += times[i]/total * 100.0;
}
// print report (with optional averages)
for (i=0; i<num; i++) {
double t,p;
if (i < (num-1)) {
t = times[i];
p = t/total * 100.0;
}
else {
t = total;
p = 100.0;
}
fprintf (fout,"%-*s %7.2fms %6.2f%%",maxl,event[i].description,
t*ccunit * 1000.0, p);
if (average && i < (num-1)) {
fprintf (fout," (avg %7.2fms %6.2f%%)",
(event[i].total_t / event[i].count)*ccunit * 1000.0,
event[i].total_p / event[i].count);
}
fprintf (fout,"\n");
}
fprintf (fout,"\n");
}

42
extern/ode/dist/tools/build4 vendored Executable file
View File

@@ -0,0 +1,42 @@
#!/bin/sh
#
# build all four precision/release configurations and log the build messages
# (used for debugging).
PLATFORM=unix-gcc
SETTINGS=config/user-settings
if [ ! -f ode/src/ode.cpp ]; then
echo "run this from the ODE root directory"
exit 1
fi
function build() {
echo -e "$PRECISION $MODE\n\n" >> BUILD_LOG
cat <<END > $SETTINGS
PLATFORM=$PLATFORM
PRECISION=$PRECISION
BUILD=$MODE
END
make clean
make >> BUILD_LOG 2>&1
echo -e "\n\n---------------------------------------------\n\n" >> BUILD_LOG
}
echo > BUILD_LOG
PRECISION=SINGLE
MODE=debug
build
PRECISION=SINGLE
MODE=release
build
PRECISION=DOUBLE
MODE=debug
build
PRECISION=DOUBLE
MODE=release
build
make clean
rm -f $SETTINGS

43
extern/ode/dist/tools/build4.bat vendored Executable file
View File

@@ -0,0 +1,43 @@
@echo off
rem build all four precision/release configurations and log the build messages
rem (used for debugging).
setlocal
set PLATFORM=cygwin
set SETTINGS=config\user-settings
echo SINGLE debug > BUILD_LOG
echo PLATFORM=%PLATFORM%> %SETTINGS%
echo PRECISION=SINGLE>> %SETTINGS%
echo BUILD=debug>> %SETTINGS%
make clean
make >> BUILD_LOG
echo --------------------------------------------- >> BUILD_LOG
echo DOUBLE debug >> BUILD_LOG
echo PLATFORM=%PLATFORM%> %SETTINGS%
echo PRECISION=DOUBLE>> %SETTINGS%
echo BUILD=debug>> %SETTINGS%
make clean
make >> BUILD_LOG
echo --------------------------------------------- >> BUILD_LOG
echo SINGLE release >> BUILD_LOG
echo PLATFORM=%PLATFORM%> %SETTINGS%
echo PRECISION=SINGLE>> %SETTINGS%
echo BUILD=release>> %SETTINGS%
make clean
make >> BUILD_LOG
echo --------------------------------------------- >> BUILD_LOG
echo DOUBLE release >> BUILD_LOG
echo PLATFORM=%PLATFORM%> %SETTINGS%
echo PRECISION=DOUBLE>> %SETTINGS%
echo BUILD=release>> %SETTINGS%
make clean
make >> BUILD_LOG
echo --------------------------------------------- >> BUILD_LOG
make clean
del %SETTINGS%

45
extern/ode/dist/tools/make_distribution vendored Executable file
View File

@@ -0,0 +1,45 @@
#!/bin/sh
VER=0.03
# VER=`date +%y%m%d`
if [ ! -f ode/src/ode.cpp ]; then
echo "run this from the ODE root directory"
exit 1
fi
ODE_DIR=`pwd`
cd /tmp
if [ -d /tmp/ode-$VER ]; then
echo "remove /tmp/ode-$VER first"
exit 1
fi
mkdir /tmp/ode-$VER
cp -av $ODE_DIR/* /tmp/ode-$VER
find /tmp/ode-$VER -type d -name CVS -exec rm -rf {} \; -print
find /tmp/ode-$VER -type f -name *~ -exec rm -f {} \; -print
rmdir /tmp/ode-$VER/build
cd /tmp/ode-$VER
make clean
cp config/user-settings.example config/user-settings
cd ode/doc
./doccer ode.doc > ode.html
cd /tmp/ode-$VER
echo -e "\n\nMake any modifications you want, then exit the shell:"
bash
cd /tmp
tar cfvz ode-$VER.tgz ode-$VER
rm -rf /tmp/ode-$VER
echo -e "\ntype <return> to exit or 'c' to copy to q12"
read Q
if [ $Q ]; then
echo copying...
scp1 ode-$VER.tgz q12.org:~/q12/ode/release/
fi

11
extern/ode/dist/tools/process_deps vendored Executable file
View File

@@ -0,0 +1,11 @@
#!/usr/bin/perl
$a = join ('',<STDIN>);
$a =~ s/\\\n/ /g; # join continued lines
$a =~ s/(^\S+:)/$ARGV[0]$1/gm; # put prefix in front of rules
$a =~ s/\s+\/\S+/ /g; # remove absolute path dependencies
$a =~ s/\s+\n/\n/g; # remove whitespace at end of lines
$a =~ s/[ \t]+/ /g; # clean up interior whitespace
$a =~ s/ / \\\n /g; # put back line continuations
print $a;