summaryrefslogtreecommitdiff
path: root/libs/ode-0.16.1/GIMPACT
diff options
context:
space:
mode:
authorsanine <sanine.not@pm.me>2022-10-01 20:59:36 -0500
committersanine <sanine.not@pm.me>2022-10-01 20:59:36 -0500
commitc5fc66ee58f2c60f2d226868bb1cf5b91badaf53 (patch)
tree277dd280daf10bf77013236b8edfa5f88708c7e0 /libs/ode-0.16.1/GIMPACT
parent1cf9cc3408af7008451f9133fb95af66a9697d15 (diff)
add ode
Diffstat (limited to 'libs/ode-0.16.1/GIMPACT')
-rw-r--r--libs/ode-0.16.1/GIMPACT/GIMPACT-LICENSE-BSD.TXT29
-rw-r--r--libs/ode-0.16.1/GIMPACT/GIMPACT-LICENSE-LGPL.TXT502
-rw-r--r--libs/ode-0.16.1/GIMPACT/Makefile.am4
-rw-r--r--libs/ode-0.16.1/GIMPACT/Makefile.in641
-rw-r--r--libs/ode-0.16.1/GIMPACT/include/GIMPACT/Makefile.am6
-rw-r--r--libs/ode-0.16.1/GIMPACT/include/GIMPACT/Makefile.in533
-rw-r--r--libs/ode-0.16.1/GIMPACT/include/GIMPACT/gim_boxpruning.h323
-rw-r--r--libs/ode-0.16.1/GIMPACT/include/GIMPACT/gim_contact.h115
-rw-r--r--libs/ode-0.16.1/GIMPACT/include/GIMPACT/gim_geometry.h1885
-rw-r--r--libs/ode-0.16.1/GIMPACT/include/GIMPACT/gim_math.h164
-rw-r--r--libs/ode-0.16.1/GIMPACT/include/GIMPACT/gim_memory.h1056
-rw-r--r--libs/ode-0.16.1/GIMPACT/include/GIMPACT/gim_radixsort.h258
-rw-r--r--libs/ode-0.16.1/GIMPACT/include/GIMPACT/gim_tri_capsule_collision.h111
-rw-r--r--libs/ode-0.16.1/GIMPACT/include/GIMPACT/gim_tri_collision.h253
-rw-r--r--libs/ode-0.16.1/GIMPACT/include/GIMPACT/gim_tri_sphere_collision.h51
-rw-r--r--libs/ode-0.16.1/GIMPACT/include/GIMPACT/gim_trimesh.h544
-rw-r--r--libs/ode-0.16.1/GIMPACT/include/GIMPACT/gimpact.h45
-rw-r--r--libs/ode-0.16.1/GIMPACT/include/Makefile.am1
-rw-r--r--libs/ode-0.16.1/GIMPACT/include/Makefile.in640
-rw-r--r--libs/ode-0.16.1/GIMPACT/src/Makefile.am19
-rw-r--r--libs/ode-0.16.1/GIMPACT/src/Makefile.in638
-rw-r--r--libs/ode-0.16.1/GIMPACT/src/gim_boxpruning.cpp519
-rw-r--r--libs/ode-0.16.1/GIMPACT/src/gim_contact.cpp132
-rw-r--r--libs/ode-0.16.1/GIMPACT/src/gim_math.cpp60
-rw-r--r--libs/ode-0.16.1/GIMPACT/src/gim_memory.cpp878
-rw-r--r--libs/ode-0.16.1/GIMPACT/src/gim_tri_tri_overlap.cpp251
-rw-r--r--libs/ode-0.16.1/GIMPACT/src/gim_trimesh.cpp391
-rw-r--r--libs/ode-0.16.1/GIMPACT/src/gim_trimesh_capsule_collision.cpp285
-rw-r--r--libs/ode-0.16.1/GIMPACT/src/gim_trimesh_ray_collision.cpp149
-rw-r--r--libs/ode-0.16.1/GIMPACT/src/gim_trimesh_sphere_collision.cpp196
-rw-r--r--libs/ode-0.16.1/GIMPACT/src/gim_trimesh_trimesh_collision.cpp348
-rw-r--r--libs/ode-0.16.1/GIMPACT/src/gimpact.cpp40
32 files changed, 11067 insertions, 0 deletions
diff --git a/libs/ode-0.16.1/GIMPACT/GIMPACT-LICENSE-BSD.TXT b/libs/ode-0.16.1/GIMPACT/GIMPACT-LICENSE-BSD.TXT
new file mode 100644
index 0000000..95545aa
--- /dev/null
+++ b/libs/ode-0.16.1/GIMPACT/GIMPACT-LICENSE-BSD.TXT
@@ -0,0 +1,29 @@
+GIMPACT : Geometric tools for VR.
+
+Copyright (c) 2006 , Francisco León.
+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 name of the GIMPACT 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. \ No newline at end of file
diff --git a/libs/ode-0.16.1/GIMPACT/GIMPACT-LICENSE-LGPL.TXT b/libs/ode-0.16.1/GIMPACT/GIMPACT-LICENSE-LGPL.TXT
new file mode 100644
index 0000000..60b8156
--- /dev/null
+++ b/libs/ode-0.16.1/GIMPACT/GIMPACT-LICENSE-LGPL.TXT
@@ -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!
diff --git a/libs/ode-0.16.1/GIMPACT/Makefile.am b/libs/ode-0.16.1/GIMPACT/Makefile.am
new file mode 100644
index 0000000..7a4f8e5
--- /dev/null
+++ b/libs/ode-0.16.1/GIMPACT/Makefile.am
@@ -0,0 +1,4 @@
+EXTRA_DIST = GIMPACT-LICENSE-BSD.TXT GIMPACT-LICENSE-LGPL.TXT
+
+SUBDIRS = include src
+
diff --git a/libs/ode-0.16.1/GIMPACT/Makefile.in b/libs/ode-0.16.1/GIMPACT/Makefile.in
new file mode 100644
index 0000000..e8aa375
--- /dev/null
+++ b/libs/ode-0.16.1/GIMPACT/Makefile.in
@@ -0,0 +1,641 @@
+# Makefile.in generated by automake 1.15 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2014 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+VPATH = @srcdir@
+am__is_gnu_make = { \
+ if test -z '$(MAKELEVEL)'; then \
+ false; \
+ elif test -n '$(MAKE_HOST)'; then \
+ true; \
+ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+ true; \
+ else \
+ false; \
+ fi; \
+}
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = GIMPACT
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \
+ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
+ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
+ $(top_srcdir)/m4/pkg.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/ode/src/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 =
+SOURCES =
+DIST_SOURCES =
+RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \
+ ctags-recursive dvi-recursive html-recursive info-recursive \
+ install-data-recursive install-dvi-recursive \
+ install-exec-recursive install-html-recursive \
+ install-info-recursive install-pdf-recursive \
+ install-ps-recursive install-recursive installcheck-recursive \
+ installdirs-recursive pdf-recursive ps-recursive \
+ tags-recursive uninstall-recursive
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \
+ distclean-recursive maintainer-clean-recursive
+am__recursive_targets = \
+ $(RECURSIVE_TARGETS) \
+ $(RECURSIVE_CLEAN_TARGETS) \
+ $(am__extra_recursive_targets)
+AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \
+ distdir
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates. Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+ BEGIN { nonempty = 0; } \
+ { items[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique. This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+ list='$(am__tagged_files)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+DIST_SUBDIRS = $(SUBDIRS)
+am__DIST_COMMON = $(srcdir)/Makefile.in
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+am__relativize = \
+ dir0=`pwd`; \
+ sed_first='s,^\([^/]*\)/.*$$,\1,'; \
+ sed_rest='s,^[^/]*/*,,'; \
+ sed_last='s,^.*/\([^/]*\)$$,\1,'; \
+ sed_butlast='s,/*[^/]*$$,,'; \
+ while test -n "$$dir1"; do \
+ first=`echo "$$dir1" | sed -e "$$sed_first"`; \
+ if test "$$first" != "."; then \
+ if test "$$first" = ".."; then \
+ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \
+ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \
+ else \
+ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \
+ if test "$$first2" = "$$first"; then \
+ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \
+ else \
+ dir2="../$$dir2"; \
+ fi; \
+ dir0="$$dir0"/"$$first"; \
+ fi; \
+ fi; \
+ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \
+ done; \
+ reldir="$$dir2"
+ACLOCAL = @ACLOCAL@
+ALLOCA = @ALLOCA@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AS = @AS@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CCD_CFLAGS = @CCD_CFLAGS@
+CCD_LIBS = @CCD_LIBS@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DOXYGEN = @DOXYGEN@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+EXTRA_LIBTOOL_LDFLAGS = @EXTRA_LIBTOOL_LDFLAGS@
+FGREP = @FGREP@
+GL_LIBS = @GL_LIBS@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBSTDCXX = @LIBSTDCXX@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+ODE_PRECISION = @ODE_PRECISION@
+ODE_VERSION = @ODE_VERSION@
+ODE_VERSION_INFO = @ODE_VERSION_INFO@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+RANLIB = @RANLIB@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+VERSION = @VERSION@
+WINDRES = @WINDRES@
+X11_CFLAGS = @X11_CFLAGS@
+X11_LIBS = @X11_LIBS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+ac_ct_WINDRES = @ac_ct_WINDRES@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+runstatedir = @runstatedir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+subdirs = @subdirs@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+EXTRA_DIST = GIMPACT-LICENSE-BSD.TXT GIMPACT-LICENSE-LGPL.TXT
+SUBDIRS = include src
+all: all-recursive
+
+.SUFFIXES:
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign GIMPACT/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --foreign GIMPACT/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+# This directory's subdirectories are mostly independent; you can cd
+# into them and run 'make' without going through this Makefile.
+# To change the values of 'make' variables: instead of editing Makefiles,
+# (1) if the variable is set in 'config.status', edit 'config.status'
+# (which will cause the Makefiles to be regenerated when you run 'make');
+# (2) otherwise, pass the desired values on the 'make' command line.
+$(am__recursive_targets):
+ @fail=; \
+ if $(am__make_keepgoing); then \
+ failcom='fail=yes'; \
+ else \
+ failcom='exit 1'; \
+ fi; \
+ dot_seen=no; \
+ target=`echo $@ | sed s/-recursive//`; \
+ case "$@" in \
+ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
+ *) list='$(SUBDIRS)' ;; \
+ esac; \
+ for subdir in $$list; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ dot_seen=yes; \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || eval $$failcom; \
+ done; \
+ if test "$$dot_seen" = "no"; then \
+ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
+ fi; test -z "$$fail"
+
+ID: $(am__tagged_files)
+ $(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-recursive
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ set x; \
+ here=`pwd`; \
+ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
+ include_option=--etags-include; \
+ empty_fix=.; \
+ else \
+ include_option=--include; \
+ empty_fix=; \
+ fi; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ test ! -f $$subdir/TAGS || \
+ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \
+ fi; \
+ done; \
+ $(am__define_uniq_tagged_files); \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: ctags-recursive
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ $(am__define_uniq_tagged_files); \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-recursive
+
+cscopelist-am: $(am__tagged_files)
+ list='$(am__tagged_files)'; \
+ case "$(srcdir)" in \
+ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+ *) sdir=$(subdir)/$(srcdir) ;; \
+ esac; \
+ for i in $$list; do \
+ if test -f "$$i"; then \
+ echo "$(subdir)/$$i"; \
+ else \
+ echo "$$sdir/$$i"; \
+ fi; \
+ done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+ @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ $(am__make_dryrun) \
+ || test -d "$(distdir)/$$subdir" \
+ || $(MKDIR_P) "$(distdir)/$$subdir" \
+ || exit 1; \
+ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \
+ $(am__relativize); \
+ new_distdir=$$reldir; \
+ dir1=$$subdir; dir2="$(top_distdir)"; \
+ $(am__relativize); \
+ new_top_distdir=$$reldir; \
+ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \
+ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \
+ ($(am__cd) $$subdir && \
+ $(MAKE) $(AM_MAKEFLAGS) \
+ top_distdir="$$new_top_distdir" \
+ distdir="$$new_distdir" \
+ am__remove_distdir=: \
+ am__skip_length_check=: \
+ am__skip_mode_fix=: \
+ distdir) \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-recursive
+all-am: Makefile
+installdirs: installdirs-recursive
+installdirs-am:
+install: install-recursive
+install-exec: install-exec-recursive
+install-data: install-data-recursive
+uninstall: uninstall-recursive
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-recursive
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-recursive
+
+clean-am: clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-recursive
+ -rm -f Makefile
+distclean-am: clean-am distclean-generic distclean-tags
+
+dvi: dvi-recursive
+
+dvi-am:
+
+html: html-recursive
+
+html-am:
+
+info: info-recursive
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-recursive
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-recursive
+
+install-html-am:
+
+install-info: install-info-recursive
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-recursive
+
+install-pdf-am:
+
+install-ps: install-ps-recursive
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-recursive
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-recursive
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+pdf: pdf-recursive
+
+pdf-am:
+
+ps: ps-recursive
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: $(am__recursive_targets) install-am install-strip
+
+.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \
+ check-am clean clean-generic clean-libtool cscopelist-am ctags \
+ ctags-am distclean distclean-generic distclean-libtool \
+ distclean-tags distdir dvi dvi-am html html-am info info-am \
+ install install-am install-data install-data-am install-dvi \
+ install-dvi-am install-exec install-exec-am install-html \
+ install-html-am install-info install-info-am install-man \
+ install-pdf install-pdf-am install-ps install-ps-am \
+ install-strip installcheck installcheck-am installdirs \
+ installdirs-am maintainer-clean maintainer-clean-generic \
+ mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \
+ ps ps-am tags tags-am uninstall uninstall-am
+
+.PRECIOUS: Makefile
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/libs/ode-0.16.1/GIMPACT/include/GIMPACT/Makefile.am b/libs/ode-0.16.1/GIMPACT/include/GIMPACT/Makefile.am
new file mode 100644
index 0000000..347ae72
--- /dev/null
+++ b/libs/ode-0.16.1/GIMPACT/include/GIMPACT/Makefile.am
@@ -0,0 +1,6 @@
+noinst_HEADERS = \
+ gim_boxpruning.h gim_contact.h gim_geometry.h \
+ gim_math.h gim_memory.h gimpact.h \
+ gim_radixsort.h gim_tri_capsule_collision.h gim_tri_collision.h \
+ gim_trimesh.h gim_tri_sphere_collision.h
+
diff --git a/libs/ode-0.16.1/GIMPACT/include/GIMPACT/Makefile.in b/libs/ode-0.16.1/GIMPACT/include/GIMPACT/Makefile.in
new file mode 100644
index 0000000..78758f7
--- /dev/null
+++ b/libs/ode-0.16.1/GIMPACT/include/GIMPACT/Makefile.in
@@ -0,0 +1,533 @@
+# Makefile.in generated by automake 1.15 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2014 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+VPATH = @srcdir@
+am__is_gnu_make = { \
+ if test -z '$(MAKELEVEL)'; then \
+ false; \
+ elif test -n '$(MAKE_HOST)'; then \
+ true; \
+ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+ true; \
+ else \
+ false; \
+ fi; \
+}
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = GIMPACT/include/GIMPACT
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \
+ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
+ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
+ $(top_srcdir)/m4/pkg.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(noinst_HEADERS) \
+ $(am__DIST_COMMON)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/ode/src/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 =
+SOURCES =
+DIST_SOURCES =
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+HEADERS = $(noinst_HEADERS)
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates. Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+ BEGIN { nonempty = 0; } \
+ { items[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique. This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+ list='$(am__tagged_files)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+am__DIST_COMMON = $(srcdir)/Makefile.in
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ALLOCA = @ALLOCA@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AS = @AS@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CCD_CFLAGS = @CCD_CFLAGS@
+CCD_LIBS = @CCD_LIBS@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DOXYGEN = @DOXYGEN@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+EXTRA_LIBTOOL_LDFLAGS = @EXTRA_LIBTOOL_LDFLAGS@
+FGREP = @FGREP@
+GL_LIBS = @GL_LIBS@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBSTDCXX = @LIBSTDCXX@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+ODE_PRECISION = @ODE_PRECISION@
+ODE_VERSION = @ODE_VERSION@
+ODE_VERSION_INFO = @ODE_VERSION_INFO@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+RANLIB = @RANLIB@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+VERSION = @VERSION@
+WINDRES = @WINDRES@
+X11_CFLAGS = @X11_CFLAGS@
+X11_LIBS = @X11_LIBS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+ac_ct_WINDRES = @ac_ct_WINDRES@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+runstatedir = @runstatedir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+subdirs = @subdirs@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+noinst_HEADERS = \
+ gim_boxpruning.h gim_contact.h gim_geometry.h \
+ gim_math.h gim_memory.h gimpact.h \
+ gim_radixsort.h gim_tri_capsule_collision.h gim_tri_collision.h \
+ gim_trimesh.h gim_tri_sphere_collision.h
+
+all: all-am
+
+.SUFFIXES:
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign GIMPACT/include/GIMPACT/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --foreign GIMPACT/include/GIMPACT/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+ID: $(am__tagged_files)
+ $(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ set x; \
+ here=`pwd`; \
+ $(am__define_uniq_tagged_files); \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ $(am__define_uniq_tagged_files); \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+ list='$(am__tagged_files)'; \
+ case "$(srcdir)" in \
+ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+ *) sdir=$(subdir)/$(srcdir) ;; \
+ esac; \
+ for i in $$list; do \
+ if test -f "$$i"; then \
+ echo "$(subdir)/$$i"; \
+ else \
+ echo "$$sdir/$$i"; \
+ fi; \
+ done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(HEADERS)
+installdirs:
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-am
+ -rm -f Makefile
+distclean-am: clean-am distclean-generic distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \
+ clean-libtool cscopelist-am ctags ctags-am distclean \
+ distclean-generic distclean-libtool distclean-tags distdir dvi \
+ dvi-am html html-am info info-am install install-am \
+ install-data install-data-am install-dvi install-dvi-am \
+ install-exec install-exec-am install-html install-html-am \
+ install-info install-info-am install-man install-pdf \
+ install-pdf-am install-ps install-ps-am install-strip \
+ installcheck installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-generic \
+ mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \
+ uninstall-am
+
+.PRECIOUS: Makefile
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/libs/ode-0.16.1/GIMPACT/include/GIMPACT/gim_boxpruning.h b/libs/ode-0.16.1/GIMPACT/include/GIMPACT/gim_boxpruning.h
new file mode 100644
index 0000000..cfa6c79
--- /dev/null
+++ b/libs/ode-0.16.1/GIMPACT/include/GIMPACT/gim_boxpruning.h
@@ -0,0 +1,323 @@
+#ifndef GIM_BOXPRUNING_H_INCLUDED
+#define GIM_BOXPRUNING_H_INCLUDED
+
+/*! \file gim_boxpruning.h
+\author Francisco León
+*/
+/*
+-----------------------------------------------------------------------------
+This source file is part of GIMPACT Library.
+
+For the latest info, see http://gimpact.sourceforge.net/
+
+Copyright (c) 2006 Francisco Leon. C.C. 80087371.
+email: projectileman@yahoo.com
+
+ 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 GIMPACT-LICENSE-LGPL.TXT.
+ (2) The BSD-style license that is included with this library in
+ the file GIMPACT-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
+ GIMPACT-LICENSE-LGPL.TXT and GIMPACT-LICENSE-BSD.TXT for more details.
+
+-----------------------------------------------------------------------------
+*/
+
+
+#include "GIMPACT/gim_radixsort.h"
+#include "GIMPACT/gim_geometry.h"
+
+/*! \defgroup BOX_PRUNNING
+
+\brief
+Tools for find overlapping objects on a scenary. These functions sort boxes for faster collisioin queries, using radix sort or quick sort as convenience. See \ref SORTING .
+<ul>
+<li> For using these collision routines, you must create a \ref GIM_AABB_SET by using this function : \ref gim_aabbset_alloc.
+<li> The GIM_AABB_SET objects must be updated on their boxes on each query, and they must be update by calling \ref gim_aabbset_update
+<li> Before calling collision functions, you must create a pair set with \ref GIM_CREATE_PAIR_SET
+<li> For finding collision pairs on a scene (common space for objects), call \ref gim_aabbset_self_intersections
+<li> For finding collision pairs between two box sets , call \ref gim_aabbset_box_collision
+<li> After using collision routines, you must destroy the pairset with \ref GIM_DESTROY_PAIR_SET
+<li> When the box set is no longer used, you must destroy it by calling \ref gim_aabbset_destroy
+</ul>
+*/
+//! @{
+//! Overlapping pair
+struct GIM_PAIR
+{
+ GUINT32 m_index1;
+ GUINT32 m_index2;
+};
+//typedef struct _GIM_PAIR GIM_PAIR;
+
+//! Box container
+struct GIM_AABB_SET
+{
+ GUINT32 m_count;
+ aabb3f m_global_bound;//!< Global calculated bound of all boxes
+ aabb3f * m_boxes;
+ GUINT32 * m_maxcoords;//!<Upper corners of the boxes, in integer representation
+ GIM_RSORT_TOKEN * m_sorted_mincoords;//!< sorted min coords (lower corners), with their coord value as the m_key and m_value as the box index
+ char m_shared;//!< if m_shared == 0 then the memory is allocated and the set must be destroyed, else the pointers are shared and the set should't be destroyed
+};
+//typedef struct _GIM_AABB_SET GIM_AABB_SET;
+
+//! Function for creating an overlapping pair set
+#define GIM_CREATE_PAIR_SET(dynarray) GIM_DYNARRAY_CREATE(GIM_PAIR,dynarray,G_ARRAY_GROW_SIZE)
+//! Function for destroying an overlapping pair set
+#define GIM_DESTROY_PAIR_SET(dynarray) GIM_DYNARRAY_DESTROY(dynarray)
+
+//! Allocate memory for all aabb set.
+void gim_aabbset_alloc(GIM_AABB_SET * aabbset, GUINT32 count);
+
+//! Destroys the aabb set.
+void gim_aabbset_destroy(GIM_AABB_SET * aabbset);
+
+//! Calcs the global bound only
+/*!
+\pre aabbset must be allocated. And the boxes must be already set.
+*/
+void gim_aabbset_calc_global_bound(GIM_AABB_SET * aabbset);
+
+//! Sorts the boxes for box prunning.
+/*!
+1) find the integer representation of the aabb coords
+2) Sorts the min coords
+3) Calcs the global bound
+\pre aabbset must be allocated. And the boxes must be already set.
+\param aabbset
+\param calc_global_bound If 1 , calcs the global bound
+\post If aabbset->m_sorted_mincoords == 0, then it allocs the sorted coordinates
+*/
+void gim_aabbset_sort(GIM_AABB_SET * aabbset, char calc_global_bound);
+
+//! log(N) Complete box pruning. Returns a list of overlapping pairs of boxes, each box of the pair belongs to the same set.
+/*!
+\pre aabbset must be allocated and sorted, the boxes must be already set.
+\param aabbset Must be sorted. Global bound isn't required
+\param collision_pairs Array of GIM_PAIR elements. Must be initialized before (Reserve size ~ 100)
+*/
+void gim_aabbset_self_intersections_sorted(GIM_AABB_SET * aabbset, GDYNAMIC_ARRAY * collision_pairs);
+
+//! NxN Complete box pruning. Returns a list of overlapping pairs of boxes, each box of the pair belongs to the same set.
+/*!
+\pre aabbset must be allocated, the boxes must be already set.
+\param aabbset Global bound isn't required. Doen't need to be sorted.
+\param collision_pairs Array of GIM_PAIR elements. Must be initialized before (Reserve size ~ 100)
+*/
+void gim_aabbset_self_intersections_brute_force(GIM_AABB_SET * aabbset, GDYNAMIC_ARRAY * collision_pairs);
+
+//! log(N) Bipartite box pruning. Returns a list of overlapping pairs of boxes, each box of the pair belongs to a different set.
+/*!
+\pre aabbset1 and aabbset2 must be allocated and sorted, the boxes must be already set.
+\param aabbset1 Must be sorted, Global bound is required.
+\param aabbset2 Must be sorted, Global bound is required.
+\param collision_pairs Array of GIM_PAIR elements. Must be initialized before (Reserve size ~ 100)
+*/
+void gim_aabbset_bipartite_intersections_sorted(GIM_AABB_SET * aabbset1, GIM_AABB_SET * aabbset2, GDYNAMIC_ARRAY * collision_pairs);
+
+//! NxM Bipartite box pruning. Returns a list of overlapping pairs of boxes, each box of the pair belongs to a different set.
+/*!
+\pre aabbset1 and aabbset2 must be allocated and sorted, the boxes must be already set.
+\param aabbset1 Must be sorted, Global bound is required.
+\param aabbset2 Must be sorted, Global bound is required.
+\param collision_pairs Array of GIM_PAIR elements. Must be initialized before (Reserve size ~ 100)
+*/
+void gim_aabbset_bipartite_intersections_brute_force(GIM_AABB_SET * aabbset1,GIM_AABB_SET * aabbset2, GDYNAMIC_ARRAY * collision_pairs);
+
+
+/*
+ Brute-Force Vs Sorted pruning
+Different approaches must be applied when colliding sets with different number of
+elements. When sets have less of 100 boxes, is often better to apply force brute
+approach instead of sorted methods, because at lowlevel bruteforce routines gives
+better perormance and consumes less resources, due of their simplicity.
+But when sets are larger, the complexiity of bruteforce increases exponencially.
+In the case of large sets, sorted approach is applied. So GIMPACT has the following
+strategies:
+
+On Sorting sets:
+!) When sets have more of 140 boxes, the boxes are sorted by its coded min coord
+and the global box is calculated. But when sets are smaller (less of 140 boxes),
+Is convenient to apply brute force approach.
+
+*******************************************************************************/
+
+//! Constant for apply approaches between brute force and sorted pruning on bipartite queries
+#define GIM_MIN_SORTED_BIPARTITE_PRUNING_BOXES 600
+//! Constant for apply approaches between brute force and sorted pruning for box collision
+#define GIM_MIN_SORTED_PRUNING_BOXES 140
+
+
+//Use these functions for general initialization
+
+//! Initalizes the set. Sort Boxes if needed.
+/*!
+\pre aabbset must be allocated. And the boxes must be already set.
+\post If the set has less of GIM_MIN_SORTED_BIPARTITE_PRUNING_BOXES boxes, only calcs the global box,
+ else it Sorts the entire set( Only applicable for large sets)
+*/
+void gim_aabbset_update(GIM_AABB_SET * aabbset);
+
+///Use these functions for general collision
+
+//! Complete box pruning. Returns a list of overlapping pairs of boxes, each box of the pair belongs to the same set.
+/*!
+This function sorts the set and then it calls to gim_aabbset_self_intersections_brute_force or gim_aabbset_self_intersections_sorted. This is an example of how to use this function:
+\code
+//Create contact list
+GDYNAMIC_ARRAY collision_pairs;
+GIM_CREATE_PAIR_SET(collision_pairs);
+//Do collision
+gim_aabbset_self_intersections(&aabbset,&collision_pairs);
+if(collision_pairs.m_size==0)
+{
+ GIM_DYNARRAY_DESTROY(collision_pairs);//
+ return; //no collisioin
+}
+
+//pair pointer
+GIM_PAIR *pairs = GIM_DYNARRAY_POINTER(GIM_PAIR,collision_pairs);
+GUINT i, ti1,ti2;
+for (i=0;i<collision_pairs.m_size; i++)
+{
+ ti1 = pairs[i].m_index1;
+ ti2 = pairs[i].m_index2;
+ //Do something with the pairs
+ ....
+ ....
+ ...
+
+}
+//Terminate
+GIM_DYNARRAY_DESTROY(dummycontacts);
+GIM_DYNARRAY_DESTROY(collision_pairs);
+\endcode
+\param aabbset Set of boxes. Sorting isn't required.
+\param collision_pairs Array of GIM_PAIR elements. Must be initialized before (Reserve size ~ 100)
+\pre aabbset must be allocated and initialized.
+\post If aabbset->m_count >= GIM_MIN_SORTED_PRUNING_BOXES, then it calls to gim_aabbset_sort and then to gim_aabbset_self_intersections_sorted. Global box won't be calculated.
+*/
+void gim_aabbset_self_intersections(GIM_AABB_SET * aabbset, GDYNAMIC_ARRAY * collision_pairs);
+
+//! Collides two sets. Returns a list of overlapping pairs of boxes, each box of the pair belongs to a different set.
+/*!
+\pre aabbset1 and aabbset2 must be allocated and updated. See gim_aabbset_update.
+\param aabbset1 Must be updated.
+\param aabbset2 Must be updated.
+\param collision_pairs Array of GIM_PAIR elements. Must be initialized before (Reserve size ~ 100)
+*/
+void gim_aabbset_bipartite_intersections(GIM_AABB_SET * aabbset1, GIM_AABB_SET * aabbset2, GDYNAMIC_ARRAY * collision_pairs);
+
+///Function for create Box collision result set
+
+#define GIM_CREATE_BOXQUERY_LIST(dynarray) GIM_DYNARRAY_CREATE(GUINT32,dynarray,G_ARRAY_GROW_SIZE)
+
+//! Finds intersections between a box and a set. Return the colliding boxes of the set
+/*!
+\pre aabbset must be allocated and initialized.
+\param test_aabb Box for collision query
+\param aabbset Set of boxes .Global bound is required.
+\param collided Array of GUINT elements, indices of boxes. Must be initialized before (Reserve size ~ 100)
+*/
+void gim_aabbset_box_collision(aabb3f *test_aabb, GIM_AABB_SET * aabbset, GDYNAMIC_ARRAY * collided);
+
+//! Finds intersections between a box and a set. Return the colliding boxes of the set
+/*!
+\pre aabbset must be allocated and initialized.
+\param vorigin Origin point of ray.
+\param vdir Direction vector of ray.
+\param tmax Max distance param for ray.
+\param aabbset Set of boxes .Global bound is required.
+\param collided Array of GUINT elements, indices of boxes. Must be initialized before (Reserve size ~ 100)
+*/
+void gim_aabbset_ray_collision(vec3f vorigin,vec3f vdir, GREAL tmax, GIM_AABB_SET * aabbset, GDYNAMIC_ARRAY * collided);
+
+
+/*
+For sorting, each box corner must be discretized to a 32 bit integer.
+For this, we take the x and z coordinates from the box corner (a vector vec3f)
+Then convert the (x,z) pair to an integer. For convenience, we choose an error
+constant for converting the coordinates (0.05).
+*******************************************************************************/
+
+/**
+ For fitting the coordinate to an integer, we need to constraint the range of its values. So each coord component (x, z) must lie between 0 and 65536.
+ 20 give us a 0.05 floating point error
+*/
+#define ERROR_AABB 20.0f
+
+/**
+An error of 0.05 allows to make coordinates up to 1638.0f and no less of -1638.0f.
+So the maximum size of a room should be about 3276x3276 . Its dimensions must lie between [-1638,1638.0f]
+*/
+#define MAX_AABB_SIZE 1638.0f
+
+//! Converts a vector coordinate to an integer for box sorting
+/*!
+\param vx X component
+\param vz Z component
+\param uint_key a GUINT
+*/
+#define GIM_CONVERT_VEC3F_GUINT_XZ(vx,vz,uint_key)\
+{\
+ GUINT32 _z = ((GUINT32)(vz*ERROR_AABB))+32768;\
+ uint_key = ((GUINT32)(vx*ERROR_AABB))+32768;\
+ uint_key = (uint_key<<16) + _z;\
+}\
+
+//! Converts a vector coordinate to an integer for box sorting,rounding to the upper int
+/*!
+\param vx X component
+\param vz Z component
+\param uint_key a GUINT
+*/
+#define GIM_CONVERT_VEC3F_GUINT_XZ_UPPER(vx,vz,uint_key)\
+{\
+ GUINT32 _z = ((GUINT32)ceilf(vz*ERROR_AABB))+32768;\
+ uint_key = ((GUINT32)ceilf(vx*ERROR_AABB))+32768;\
+ uint_key = (uint_key<<16) + _z;\
+}\
+
+
+//! Converts a vector coordinate to an integer for box sorting. Secure clamped
+/*!
+\param vx X component
+\param vz Z component
+\param uint_key a GUINT
+*/
+#define GIM_CONVERT_VEC3F_GUINT_XZ_CLAMPED(vx,vz,uint_key)\
+{\
+ GREAL _cx = CLAMP(vx,-MAX_AABB_SIZE,MAX_AABB_SIZE);\
+ GREAL _cz = CLAMP(vz,-MAX_AABB_SIZE,MAX_AABB_SIZE);\
+ GUINT32 _z = ((GUINT32)(_cz*ERROR_AABB))+32768;\
+ uint_key = ((GUINT32)(_cx*ERROR_AABB))+32768;\
+ uint_key = (uint_key<<16) + _z;\
+}\
+
+//! Converts a vector coordinate to an integer for box sorting. Secure clamped, rounded
+/*!
+\param vx X component
+\param vz Z component
+\param uint_key a GUINT
+*/
+#define GIM_CONVERT_VEC3F_GUINT_XZ_UPPER_CLAMPED(vx,vz,uint_key)\
+{\
+ GREAL _cx = CLAMP(vx,-MAX_AABB_SIZE,MAX_AABB_SIZE);\
+ GREAL _cz = CLAMP(vz,-MAX_AABB_SIZE,MAX_AABB_SIZE);\
+ GUINT32 _z = ((GUINT32)ceilf(_cz*ERROR_AABB))+32768;\
+ uint_key = ((GUINT32)ceilf(_cx*ERROR_AABB))+32768;\
+ uint_key = (uint_key<<16) + _z;\
+}\
+
+//! @}
+
+#endif // GIM_BOXPRUNING_H_INCLUDED
diff --git a/libs/ode-0.16.1/GIMPACT/include/GIMPACT/gim_contact.h b/libs/ode-0.16.1/GIMPACT/include/GIMPACT/gim_contact.h
new file mode 100644
index 0000000..e7f5b5e
--- /dev/null
+++ b/libs/ode-0.16.1/GIMPACT/include/GIMPACT/gim_contact.h
@@ -0,0 +1,115 @@
+#ifndef GIM_CONTACT_H_INCLUDED
+#define GIM_CONTACT_H_INCLUDED
+
+/*! \file gim_contact.h
+\author Francisco León
+*/
+/*
+-----------------------------------------------------------------------------
+This source file is part of GIMPACT Library.
+
+For the latest info, see http://gimpact.sourceforge.net/
+
+Copyright (c) 2006 Francisco Leon. C.C. 80087371.
+email: projectileman@yahoo.com
+
+ 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 GIMPACT-LICENSE-LGPL.TXT.
+ (2) The BSD-style license that is included with this library in
+ the file GIMPACT-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
+ GIMPACT-LICENSE-LGPL.TXT and GIMPACT-LICENSE-BSD.TXT for more details.
+
+-----------------------------------------------------------------------------
+*/
+
+
+#include "GIMPACT/gim_geometry.h"
+#include "GIMPACT/gim_radixsort.h"
+
+/*! \defgroup CONTACTS
+\brief
+Functions for managing and sorting contacts resulting from a collision query.
+<ul>
+<li> Contact lists must be create by calling \ref GIM_CREATE_CONTACT_LIST
+<li> After querys, contact lists must be destroy by calling \ref GIM_DYNARRAY_DESTROY
+<li> Contacts can be merge for avoid duplicate results by calling \ref gim_merge_contacts
+</ul>
+
+*/
+//! @{
+/// Structure for collision results
+struct GIM_CONTACT
+{
+ vec3f m_point;
+ vec3f m_normal;
+ GREAL m_depth;//Positive value indicates interpenetration
+ void * m_handle1;
+ void * m_handle2;
+ GUINT32 m_feature1;//Face number
+ GUINT32 m_feature2;//Face number
+};
+//typedef struct _GIM_CONTACT GIM_CONTACT;
+
+#define CONTACT_DIFF_EPSILON 0.00001f
+
+#define GIM_CALC_KEY_CONTACT(pos,hash)\
+{\
+ GINT32 _coords[] = {(GINT32)(pos[0]*1000.0f+1.0f),(GINT32)(pos[1]*1333.0f),(GINT32)(pos[2]*2133.0f+3.0f)};\
+ GUINT32 _hash=0;\
+ GUINT32 *_uitmp = (GUINT32 *)(&_coords[0]);\
+ _hash = *_uitmp;\
+ _uitmp++;\
+ _hash += (*_uitmp)<<4;\
+ _uitmp++;\
+ _hash += (*_uitmp)<<8;\
+ hash = _hash;\
+}\
+
+///Creates a contact list for queries
+#define GIM_CREATE_CONTACT_LIST(contact_array) GIM_DYNARRAY_CREATE(GIM_CONTACT,contact_array,100)
+
+#define GIM_PUSH_CONTACT(contact_array, point, normal, deep,handle1, handle2, feat1, feat2)\
+{\
+ GIM_DYNARRAY_PUSH_EMPTY(GIM_CONTACT,contact_array);\
+ GIM_CONTACT * _last = GIM_DYNARRAY_POINTER_LAST(GIM_CONTACT,contact_array);\
+ VEC_COPY(_last->m_point,point);\
+ VEC_COPY(_last->m_normal,normal);\
+ _last->m_depth = deep;\
+ _last->m_handle1 = handle1;\
+ _last->m_handle2 = handle2;\
+ _last->m_feature1 = feat1;\
+ _last->m_feature2 = feat2;\
+}\
+
+///Receive pointer to contacts
+#define GIM_COPY_CONTACTS(dest_contact, source_contact)\
+{\
+ VEC_COPY(dest_contact->m_point,source_contact->m_point);\
+ VEC_COPY(dest_contact->m_normal,source_contact->m_normal);\
+ dest_contact->m_depth = source_contact->m_depth;\
+ dest_contact->m_handle1 = source_contact->m_handle1;\
+ dest_contact->m_handle2 = source_contact->m_handle2;\
+ dest_contact->m_feature1 = source_contact->m_feature1;\
+ dest_contact->m_feature2 = source_contact->m_feature2;\
+}\
+
+//! Merges duplicate contacts with minimum depth criterion
+void gim_merge_contacts(GDYNAMIC_ARRAY * source_contacts,
+ GDYNAMIC_ARRAY * dest_contacts);
+
+
+//! Merges to an unique contact
+void gim_merge_contacts_unique(GDYNAMIC_ARRAY * source_contacts,
+ GDYNAMIC_ARRAY * dest_contacts);
+
+//! @}
+#endif // GIM_CONTACT_H_INCLUDED
diff --git a/libs/ode-0.16.1/GIMPACT/include/GIMPACT/gim_geometry.h b/libs/ode-0.16.1/GIMPACT/include/GIMPACT/gim_geometry.h
new file mode 100644
index 0000000..f2b5ccb
--- /dev/null
+++ b/libs/ode-0.16.1/GIMPACT/include/GIMPACT/gim_geometry.h
@@ -0,0 +1,1885 @@
+#ifndef GIM_VECTOR_H_INCLUDED
+#define GIM_VECTOR_H_INCLUDED
+
+/*! \file gim_geometry.h
+\author Francisco León
+*/
+/*
+-----------------------------------------------------------------------------
+This source file is part of GIMPACT Library.
+
+For the latest info, see http://gimpact.sourceforge.net/
+
+Copyright (c) 2006 Francisco Leon. C.C. 80087371.
+email: projectileman@yahoo.com
+
+ 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 GIMPACT-LICENSE-LGPL.TXT.
+ (2) The BSD-style license that is included with this library in
+ the file GIMPACT-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
+ GIMPACT-LICENSE-LGPL.TXT and GIMPACT-LICENSE-BSD.TXT for more details.
+
+-----------------------------------------------------------------------------
+*/
+
+
+#include "GIMPACT/gim_math.h"
+
+/*! \defgroup GEOMETRIC_TYPES
+\brief
+Basic types and constants for geometry
+*/
+//! @{
+
+//! Integer vector 2D
+typedef GINT32 vec2i[2];
+//! Integer vector 3D
+typedef GINT32 vec3i[3];
+//! Integer vector 4D
+typedef GINT32 vec4i[4];
+
+//! Float vector 2D
+typedef GREAL vec2f[2];
+//! Float vector 3D
+typedef GREAL vec3f[3];
+//! Float vector 4D
+typedef GREAL vec4f[4];
+
+//! Matrix 2D, row ordered
+typedef GREAL mat2f[2][2];
+//! Matrix 3D, row ordered
+typedef GREAL mat3f[3][3];
+//! Matrix 4D, row ordered
+typedef GREAL mat4f[4][4];
+
+//! Quaternion
+typedef GREAL quatf[4];
+
+//! Axis aligned box
+struct aabb3f{
+ aabb3f() {}
+
+ template<typename tboundfloat>
+ aabb3f(const tboundfloat &_minX, const tboundfloat &_maxX, const tboundfloat &_minY, const tboundfloat &_maxY, const tboundfloat &_minZ, const tboundfloat &_maxZ):
+ minX((GREAL)_minX),
+ maxX((GREAL)_maxX),
+ minY((GREAL)_minY),
+ maxY((GREAL)_maxY),
+ minZ((GREAL)_minZ),
+ maxZ((GREAL)_maxZ)
+ {
+ }
+
+ GREAL minX;
+ GREAL maxX;
+ GREAL minY;
+ GREAL maxY;
+ GREAL minZ;
+ GREAL maxZ;
+};
+//typedef struct _aabb3f aabb3f;
+//! @}
+
+
+/*! \defgroup VECTOR_OPERATIONS
+Operations for vectors : vec2f,vec3f and vec4f
+*/
+//! @{
+
+//! Zero out a 2D vector
+#define VEC_ZERO_2(a) \
+{ \
+ (a)[0] = (a)[1] = 0.0f; \
+}\
+
+
+//! Zero out a 3D vector
+#define VEC_ZERO(a) \
+{ \
+ (a)[0] = (a)[1] = (a)[2] = 0.0f; \
+}\
+
+
+/// Zero out a 4D vector
+#define VEC_ZERO_4(a) \
+{ \
+ (a)[0] = (a)[1] = (a)[2] = (a)[3] = 0.0f; \
+}\
+
+
+/// Vector copy
+#define VEC_COPY_2(b,a) \
+{ \
+ (b)[0] = (a)[0]; \
+ (b)[1] = (a)[1]; \
+}\
+
+
+/// Copy 3D vector
+#define VEC_COPY(b,a) \
+{ \
+ (b)[0] = (a)[0]; \
+ (b)[1] = (a)[1]; \
+ (b)[2] = (a)[2]; \
+}\
+
+
+/// Copy 4D vector
+#define VEC_COPY_4(b,a) \
+{ \
+ (b)[0] = (a)[0]; \
+ (b)[1] = (a)[1]; \
+ (b)[2] = (a)[2]; \
+ (b)[3] = (a)[3]; \
+}\
+
+
+/// Vector difference
+#define VEC_DIFF_2(v21,v2,v1) \
+{ \
+ (v21)[0] = (v2)[0] - (v1)[0]; \
+ (v21)[1] = (v2)[1] - (v1)[1]; \
+}\
+
+
+/// Vector difference
+#define VEC_DIFF(v21,v2,v1) \
+{ \
+ (v21)[0] = (v2)[0] - (v1)[0]; \
+ (v21)[1] = (v2)[1] - (v1)[1]; \
+ (v21)[2] = (v2)[2] - (v1)[2]; \
+}\
+
+
+/// Vector difference
+#define VEC_DIFF_4(v21,v2,v1) \
+{ \
+ (v21)[0] = (v2)[0] - (v1)[0]; \
+ (v21)[1] = (v2)[1] - (v1)[1]; \
+ (v21)[2] = (v2)[2] - (v1)[2]; \
+ (v21)[3] = (v2)[3] - (v1)[3]; \
+}\
+
+
+/// Vector sum
+#define VEC_SUM_2(v21,v2,v1) \
+{ \
+ (v21)[0] = (v2)[0] + (v1)[0]; \
+ (v21)[1] = (v2)[1] + (v1)[1]; \
+}\
+
+
+/// Vector sum
+#define VEC_SUM(v21,v2,v1) \
+{ \
+ (v21)[0] = (v2)[0] + (v1)[0]; \
+ (v21)[1] = (v2)[1] + (v1)[1]; \
+ (v21)[2] = (v2)[2] + (v1)[2]; \
+}\
+
+
+/// Vector sum
+#define VEC_SUM_4(v21,v2,v1) \
+{ \
+ (v21)[0] = (v2)[0] + (v1)[0]; \
+ (v21)[1] = (v2)[1] + (v1)[1]; \
+ (v21)[2] = (v2)[2] + (v1)[2]; \
+ (v21)[3] = (v2)[3] + (v1)[3]; \
+}\
+
+
+/// scalar times vector
+#define VEC_SCALE_2(c,a,b) \
+{ \
+ (c)[0] = (a)*(b)[0]; \
+ (c)[1] = (a)*(b)[1]; \
+}\
+
+
+/// scalar times vector
+#define VEC_SCALE(c,a,b) \
+{ \
+ (c)[0] = (a)*(b)[0]; \
+ (c)[1] = (a)*(b)[1]; \
+ (c)[2] = (a)*(b)[2]; \
+}\
+
+
+/// scalar times vector
+#define VEC_SCALE_4(c,a,b) \
+{ \
+ (c)[0] = (a)*(b)[0]; \
+ (c)[1] = (a)*(b)[1]; \
+ (c)[2] = (a)*(b)[2]; \
+ (c)[3] = (a)*(b)[3]; \
+}\
+
+
+/// accumulate scaled vector
+#define VEC_ACCUM_2(c,a,b) \
+{ \
+ (c)[0] += (a)*(b)[0]; \
+ (c)[1] += (a)*(b)[1]; \
+}\
+
+
+/// accumulate scaled vector
+#define VEC_ACCUM(c,a,b) \
+{ \
+ (c)[0] += (a)*(b)[0]; \
+ (c)[1] += (a)*(b)[1]; \
+ (c)[2] += (a)*(b)[2]; \
+}\
+
+
+/// accumulate scaled vector
+#define VEC_ACCUM_4(c,a,b) \
+{ \
+ (c)[0] += (a)*(b)[0]; \
+ (c)[1] += (a)*(b)[1]; \
+ (c)[2] += (a)*(b)[2]; \
+ (c)[3] += (a)*(b)[3]; \
+}\
+
+
+/// Vector dot product
+#define VEC_DOT_2(a,b) ((a)[0]*(b)[0] + (a)[1]*(b)[1])
+
+
+/// Vector dot product
+#define VEC_DOT(a,b) ((a)[0]*(b)[0] + (a)[1]*(b)[1] + (a)[2]*(b)[2])
+
+/// Vector dot product
+#define VEC_DOT_4(a,b) ((a)[0]*(b)[0] + (a)[1]*(b)[1] + (a)[2]*(b)[2] + (a)[3]*(b)[3])
+
+/// vector impact parameter (squared)
+#define VEC_IMPACT_SQ(bsq,direction,position) {\
+ GREAL _llel_ = VEC_DOT(direction, position);\
+ bsq = VEC_DOT(position, position) - _llel_*_llel_;\
+}\
+
+
+/// vector impact parameter
+#define VEC_IMPACT(bsq,direction,position) {\
+ VEC_IMPACT_SQ(bsq,direction,position); \
+ GIM_SQRT(bsq,bsq); \
+}\
+
+/// Vector length
+#define VEC_LENGTH_2(a,l)\
+{\
+ GREAL _pp = VEC_DOT_2(a,a);\
+ GIM_SQRT(_pp,l);\
+}\
+
+
+/// Vector length
+#define VEC_LENGTH(a,l)\
+{\
+ GREAL _pp = VEC_DOT(a,a);\
+ GIM_SQRT(_pp,l);\
+}\
+
+
+/// Vector length
+#define VEC_LENGTH_4(a,l)\
+{\
+ GREAL _pp = VEC_DOT_4(a,a);\
+ GIM_SQRT(_pp,l);\
+}\
+
+/// Vector inv length
+#define VEC_INV_LENGTH_2(a,l)\
+{\
+ GREAL _pp = VEC_DOT_2(a,a);\
+ GIM_INV_SQRT(_pp,l);\
+}\
+
+
+/// Vector inv length
+#define VEC_INV_LENGTH(a,l)\
+{\
+ GREAL _pp = VEC_DOT(a,a);\
+ GIM_INV_SQRT(_pp,l);\
+}\
+
+
+/// Vector inv length
+#define VEC_INV_LENGTH_4(a,l)\
+{\
+ GREAL _pp = VEC_DOT_4(a,a);\
+ GIM_INV_SQRT(_pp,l);\
+}\
+
+
+
+/// distance between two points
+#define VEC_DISTANCE(_len,_va,_vb) {\
+ vec3f _tmp_; \
+ VEC_DIFF(_tmp_, _vb, _va); \
+ VEC_LENGTH(_tmp_,_len); \
+}\
+
+
+/// Vector length
+#define VEC_CONJUGATE_LENGTH(a,l)\
+{\
+ GREAL _pp = 1.0 - a[0]*a[0] - a[1]*a[1] - a[2]*a[2];\
+ GIM_SQRT(_pp,l);\
+}\
+
+
+/// Vector length
+#define VEC_NORMALIZE(a) { \
+ GREAL len;\
+ VEC_INV_LENGTH(a,len); \
+ if(len<G_REAL_INFINITY)\
+ {\
+ a[0] *= len; \
+ a[1] *= len; \
+ a[2] *= len; \
+ } \
+}\
+
+/// Set Vector size
+#define VEC_RENORMALIZE(a,newlen) { \
+ GREAL len;\
+ VEC_INV_LENGTH(a,len); \
+ if(len<G_REAL_INFINITY)\
+ {\
+ len *= newlen;\
+ a[0] *= len; \
+ a[1] *= len; \
+ a[2] *= len; \
+ } \
+}\
+
+/// Vector cross
+#define VEC_CROSS(c,a,b) \
+{ \
+ c[0] = (a)[1] * (b)[2] - (a)[2] * (b)[1]; \
+ c[1] = (a)[2] * (b)[0] - (a)[0] * (b)[2]; \
+ c[2] = (a)[0] * (b)[1] - (a)[1] * (b)[0]; \
+}\
+
+
+/*! Vector perp -- assumes that n is of unit length
+ * accepts vector v, subtracts out any component parallel to n */
+#define VEC_PERPENDICULAR(vp,v,n) \
+{ \
+ GREAL dot = VEC_DOT(v, n); \
+ vp[0] = (v)[0] - dot*(n)[0]; \
+ vp[1] = (v)[1] - dot*(n)[1]; \
+ vp[2] = (v)[2] - dot*(n)[2]; \
+}\
+
+
+/*! Vector parallel -- assumes that n is of unit length */
+#define VEC_PARALLEL(vp,v,n) \
+{ \
+ GREAL dot = VEC_DOT(v, n); \
+ vp[0] = (dot) * (n)[0]; \
+ vp[1] = (dot) * (n)[1]; \
+ vp[2] = (dot) * (n)[2]; \
+}\
+
+/*! Same as Vector parallel -- n can have any length
+ * accepts vector v, subtracts out any component perpendicular to n */
+#define VEC_PROJECT(vp,v,n) \
+{ \
+ GREAL scalar = VEC_DOT(v, n); \
+ scalar/= VEC_DOT(n, n); \
+ vp[0] = (scalar) * (n)[0]; \
+ vp[1] = (scalar) * (n)[1]; \
+ vp[2] = (scalar) * (n)[2]; \
+}\
+
+
+/*! accepts vector v*/
+#define VEC_UNPROJECT(vp,v,n) \
+{ \
+ GREAL scalar = VEC_DOT(v, n); \
+ scalar = VEC_DOT(n, n)/scalar; \
+ vp[0] = (scalar) * (n)[0]; \
+ vp[1] = (scalar) * (n)[1]; \
+ vp[2] = (scalar) * (n)[2]; \
+}\
+
+
+/*! Vector reflection -- assumes n is of unit length
+ Takes vector v, reflects it against reflector n, and returns vr */
+#define VEC_REFLECT(vr,v,n) \
+{ \
+ GREAL dot = VEC_DOT(v, n); \
+ vr[0] = (v)[0] - 2.0 * (dot) * (n)[0]; \
+ vr[1] = (v)[1] - 2.0 * (dot) * (n)[1]; \
+ vr[2] = (v)[2] - 2.0 * (dot) * (n)[2]; \
+}\
+
+
+/*! Vector blending
+Takes two vectors a, b, blends them together with two scalars */
+#define VEC_BLEND_AB(vr,sa,a,sb,b) \
+{ \
+ vr[0] = (sa) * (a)[0] + (sb) * (b)[0]; \
+ vr[1] = (sa) * (a)[1] + (sb) * (b)[1]; \
+ vr[2] = (sa) * (a)[2] + (sb) * (b)[2]; \
+}\
+
+/*! Vector blending
+Takes two vectors a, b, blends them together with s <=1 */
+#define VEC_BLEND(vr,a,b,s) VEC_BLEND_AB(vr,1-s,a,sb,s)
+
+#define VEC_SET3(a,b,op,c) a[0]=b[0] op c[0]; a[1]=b[1] op c[1]; a[2]=b[2] op c[2];
+//! @}
+
+
+/*! \defgroup MATRIX_OPERATIONS
+Operations for matrices : mat2f, mat3f and mat4f
+*/
+//! @{
+
+/// initialize matrix
+#define IDENTIFY_MATRIX_3X3(m) \
+{ \
+ m[0][0] = 1.0; \
+ m[0][1] = 0.0; \
+ m[0][2] = 0.0; \
+ \
+ m[1][0] = 0.0; \
+ m[1][1] = 1.0; \
+ m[1][2] = 0.0; \
+ \
+ m[2][0] = 0.0; \
+ m[2][1] = 0.0; \
+ m[2][2] = 1.0; \
+}\
+
+/*! initialize matrix */
+#define IDENTIFY_MATRIX_4X4(m) \
+{ \
+ m[0][0] = 1.0; \
+ m[0][1] = 0.0; \
+ m[0][2] = 0.0; \
+ m[0][3] = 0.0; \
+ \
+ m[1][0] = 0.0; \
+ m[1][1] = 1.0; \
+ m[1][2] = 0.0; \
+ m[1][3] = 0.0; \
+ \
+ m[2][0] = 0.0; \
+ m[2][1] = 0.0; \
+ m[2][2] = 1.0; \
+ m[2][3] = 0.0; \
+ \
+ m[3][0] = 0.0; \
+ m[3][1] = 0.0; \
+ m[3][2] = 0.0; \
+ m[3][3] = 1.0; \
+}\
+
+/*! initialize matrix */
+#define ZERO_MATRIX_4X4(m) \
+{ \
+ m[0][0] = 0.0; \
+ m[0][1] = 0.0; \
+ m[0][2] = 0.0; \
+ m[0][3] = 0.0; \
+ \
+ m[1][0] = 0.0; \
+ m[1][1] = 0.0; \
+ m[1][2] = 0.0; \
+ m[1][3] = 0.0; \
+ \
+ m[2][0] = 0.0; \
+ m[2][1] = 0.0; \
+ m[2][2] = 0.0; \
+ m[2][3] = 0.0; \
+ \
+ m[3][0] = 0.0; \
+ m[3][1] = 0.0; \
+ m[3][2] = 0.0; \
+ m[3][3] = 0.0; \
+}\
+
+/*! matrix rotation X */
+#define ROTX_CS(m,cosine,sine) \
+{ \
+ /* rotation about the x-axis */ \
+ \
+ m[0][0] = 1.0; \
+ m[0][1] = 0.0; \
+ m[0][2] = 0.0; \
+ m[0][3] = 0.0; \
+ \
+ m[1][0] = 0.0; \
+ m[1][1] = (cosine); \
+ m[1][2] = (sine); \
+ m[1][3] = 0.0; \
+ \
+ m[2][0] = 0.0; \
+ m[2][1] = -(sine); \
+ m[2][2] = (cosine); \
+ m[2][3] = 0.0; \
+ \
+ m[3][0] = 0.0; \
+ m[3][1] = 0.0; \
+ m[3][2] = 0.0; \
+ m[3][3] = 1.0; \
+}\
+
+/*! matrix rotation Y */
+#define ROTY_CS(m,cosine,sine) \
+{ \
+ /* rotation about the y-axis */ \
+ \
+ m[0][0] = (cosine); \
+ m[0][1] = 0.0; \
+ m[0][2] = -(sine); \
+ m[0][3] = 0.0; \
+ \
+ m[1][0] = 0.0; \
+ m[1][1] = 1.0; \
+ m[1][2] = 0.0; \
+ m[1][3] = 0.0; \
+ \
+ m[2][0] = (sine); \
+ m[2][1] = 0.0; \
+ m[2][2] = (cosine); \
+ m[2][3] = 0.0; \
+ \
+ m[3][0] = 0.0; \
+ m[3][1] = 0.0; \
+ m[3][2] = 0.0; \
+ m[3][3] = 1.0; \
+}\
+
+/*! matrix rotation Z */
+#define ROTZ_CS(m,cosine,sine) \
+{ \
+ /* rotation about the z-axis */ \
+ \
+ m[0][0] = (cosine); \
+ m[0][1] = (sine); \
+ m[0][2] = 0.0; \
+ m[0][3] = 0.0; \
+ \
+ m[1][0] = -(sine); \
+ m[1][1] = (cosine); \
+ m[1][2] = 0.0; \
+ m[1][3] = 0.0; \
+ \
+ m[2][0] = 0.0; \
+ m[2][1] = 0.0; \
+ m[2][2] = 1.0; \
+ m[2][3] = 0.0; \
+ \
+ m[3][0] = 0.0; \
+ m[3][1] = 0.0; \
+ m[3][2] = 0.0; \
+ m[3][3] = 1.0; \
+}\
+
+/*! matrix copy */
+#define COPY_MATRIX_2X2(b,a) \
+{ \
+ b[0][0] = a[0][0]; \
+ b[0][1] = a[0][1]; \
+ \
+ b[1][0] = a[1][0]; \
+ b[1][1] = a[1][1]; \
+ \
+}\
+
+
+/*! matrix copy */
+#define COPY_MATRIX_2X3(b,a) \
+{ \
+ b[0][0] = a[0][0]; \
+ b[0][1] = a[0][1]; \
+ b[0][2] = a[0][2]; \
+ \
+ b[1][0] = a[1][0]; \
+ b[1][1] = a[1][1]; \
+ b[1][2] = a[1][2]; \
+}\
+
+
+/*! matrix copy */
+#define COPY_MATRIX_3X3(b,a) \
+{ \
+ b[0][0] = a[0][0]; \
+ b[0][1] = a[0][1]; \
+ b[0][2] = a[0][2]; \
+ \
+ b[1][0] = a[1][0]; \
+ b[1][1] = a[1][1]; \
+ b[1][2] = a[1][2]; \
+ \
+ b[2][0] = a[2][0]; \
+ b[2][1] = a[2][1]; \
+ b[2][2] = a[2][2]; \
+}\
+
+
+/*! matrix copy */
+#define COPY_MATRIX_4X4(b,a) \
+{ \
+ b[0][0] = a[0][0]; \
+ b[0][1] = a[0][1]; \
+ b[0][2] = a[0][2]; \
+ b[0][3] = a[0][3]; \
+ \
+ b[1][0] = a[1][0]; \
+ b[1][1] = a[1][1]; \
+ b[1][2] = a[1][2]; \
+ b[1][3] = a[1][3]; \
+ \
+ b[2][0] = a[2][0]; \
+ b[2][1] = a[2][1]; \
+ b[2][2] = a[2][2]; \
+ b[2][3] = a[2][3]; \
+ \
+ b[3][0] = a[3][0]; \
+ b[3][1] = a[3][1]; \
+ b[3][2] = a[3][2]; \
+ b[3][3] = a[3][3]; \
+}\
+
+
+/*! matrix transpose */
+#define TRANSPOSE_MATRIX_2X2(b,a) \
+{ \
+ b[0][0] = a[0][0]; \
+ b[0][1] = a[1][0]; \
+ \
+ b[1][0] = a[0][1]; \
+ b[1][1] = a[1][1]; \
+}\
+
+
+/*! matrix transpose */
+#define TRANSPOSE_MATRIX_3X3(b,a) \
+{ \
+ b[0][0] = a[0][0]; \
+ b[0][1] = a[1][0]; \
+ b[0][2] = a[2][0]; \
+ \
+ b[1][0] = a[0][1]; \
+ b[1][1] = a[1][1]; \
+ b[1][2] = a[2][1]; \
+ \
+ b[2][0] = a[0][2]; \
+ b[2][1] = a[1][2]; \
+ b[2][2] = a[2][2]; \
+}\
+
+
+/*! matrix transpose */
+#define TRANSPOSE_MATRIX_4X4(b,a) \
+{ \
+ b[0][0] = a[0][0]; \
+ b[0][1] = a[1][0]; \
+ b[0][2] = a[2][0]; \
+ b[0][3] = a[3][0]; \
+ \
+ b[1][0] = a[0][1]; \
+ b[1][1] = a[1][1]; \
+ b[1][2] = a[2][1]; \
+ b[1][3] = a[3][1]; \
+ \
+ b[2][0] = a[0][2]; \
+ b[2][1] = a[1][2]; \
+ b[2][2] = a[2][2]; \
+ b[2][3] = a[3][2]; \
+ \
+ b[3][0] = a[0][3]; \
+ b[3][1] = a[1][3]; \
+ b[3][2] = a[2][3]; \
+ b[3][3] = a[3][3]; \
+}\
+
+
+/*! multiply matrix by scalar */
+#define SCALE_MATRIX_2X2(b,s,a) \
+{ \
+ b[0][0] = (s) * a[0][0]; \
+ b[0][1] = (s) * a[0][1]; \
+ \
+ b[1][0] = (s) * a[1][0]; \
+ b[1][1] = (s) * a[1][1]; \
+}\
+
+
+/*! multiply matrix by scalar */
+#define SCALE_MATRIX_3X3(b,s,a) \
+{ \
+ b[0][0] = (s) * a[0][0]; \
+ b[0][1] = (s) * a[0][1]; \
+ b[0][2] = (s) * a[0][2]; \
+ \
+ b[1][0] = (s) * a[1][0]; \
+ b[1][1] = (s) * a[1][1]; \
+ b[1][2] = (s) * a[1][2]; \
+ \
+ b[2][0] = (s) * a[2][0]; \
+ b[2][1] = (s) * a[2][1]; \
+ b[2][2] = (s) * a[2][2]; \
+}\
+
+
+/*! multiply matrix by scalar */
+#define SCALE_MATRIX_4X4(b,s,a) \
+{ \
+ b[0][0] = (s) * a[0][0]; \
+ b[0][1] = (s) * a[0][1]; \
+ b[0][2] = (s) * a[0][2]; \
+ b[0][3] = (s) * a[0][3]; \
+ \
+ b[1][0] = (s) * a[1][0]; \
+ b[1][1] = (s) * a[1][1]; \
+ b[1][2] = (s) * a[1][2]; \
+ b[1][3] = (s) * a[1][3]; \
+ \
+ b[2][0] = (s) * a[2][0]; \
+ b[2][1] = (s) * a[2][1]; \
+ b[2][2] = (s) * a[2][2]; \
+ b[2][3] = (s) * a[2][3]; \
+ \
+ b[3][0] = s * a[3][0]; \
+ b[3][1] = s * a[3][1]; \
+ b[3][2] = s * a[3][2]; \
+ b[3][3] = s * a[3][3]; \
+}\
+
+
+/*! multiply matrix by scalar */
+#define ACCUM_SCALE_MATRIX_2X2(b,s,a) \
+{ \
+ b[0][0] += (s) * a[0][0]; \
+ b[0][1] += (s) * a[0][1]; \
+ \
+ b[1][0] += (s) * a[1][0]; \
+ b[1][1] += (s) * a[1][1]; \
+}\
+
+
+/*! multiply matrix by scalar */
+#define ACCUM_SCALE_MATRIX_3X3(b,s,a) \
+{ \
+ b[0][0] += (s) * a[0][0]; \
+ b[0][1] += (s) * a[0][1]; \
+ b[0][2] += (s) * a[0][2]; \
+ \
+ b[1][0] += (s) * a[1][0]; \
+ b[1][1] += (s) * a[1][1]; \
+ b[1][2] += (s) * a[1][2]; \
+ \
+ b[2][0] += (s) * a[2][0]; \
+ b[2][1] += (s) * a[2][1]; \
+ b[2][2] += (s) * a[2][2]; \
+}\
+
+
+/*! multiply matrix by scalar */
+#define ACCUM_SCALE_MATRIX_4X4(b,s,a) \
+{ \
+ b[0][0] += (s) * a[0][0]; \
+ b[0][1] += (s) * a[0][1]; \
+ b[0][2] += (s) * a[0][2]; \
+ b[0][3] += (s) * a[0][3]; \
+ \
+ b[1][0] += (s) * a[1][0]; \
+ b[1][1] += (s) * a[1][1]; \
+ b[1][2] += (s) * a[1][2]; \
+ b[1][3] += (s) * a[1][3]; \
+ \
+ b[2][0] += (s) * a[2][0]; \
+ b[2][1] += (s) * a[2][1]; \
+ b[2][2] += (s) * a[2][2]; \
+ b[2][3] += (s) * a[2][3]; \
+ \
+ b[3][0] += (s) * a[3][0]; \
+ b[3][1] += (s) * a[3][1]; \
+ b[3][2] += (s) * a[3][2]; \
+ b[3][3] += (s) * a[3][3]; \
+}\
+
+/*! matrix product */
+/*! c[x][y] = a[x][0]*b[0][y]+a[x][1]*b[1][y]+a[x][2]*b[2][y]+a[x][3]*b[3][y];*/
+#define MATRIX_PRODUCT_2X2(c,a,b) \
+{ \
+ c[0][0] = a[0][0]*b[0][0]+a[0][1]*b[1][0]; \
+ c[0][1] = a[0][0]*b[0][1]+a[0][1]*b[1][1]; \
+ \
+ c[1][0] = a[1][0]*b[0][0]+a[1][1]*b[1][0]; \
+ c[1][1] = a[1][0]*b[0][1]+a[1][1]*b[1][1]; \
+ \
+}\
+
+/*! matrix product */
+/*! c[x][y] = a[x][0]*b[0][y]+a[x][1]*b[1][y]+a[x][2]*b[2][y]+a[x][3]*b[3][y];*/
+#define MATRIX_PRODUCT_3X3(c,a,b) \
+{ \
+ c[0][0] = a[0][0]*b[0][0]+a[0][1]*b[1][0]+a[0][2]*b[2][0]; \
+ c[0][1] = a[0][0]*b[0][1]+a[0][1]*b[1][1]+a[0][2]*b[2][1]; \
+ c[0][2] = a[0][0]*b[0][2]+a[0][1]*b[1][2]+a[0][2]*b[2][2]; \
+ \
+ c[1][0] = a[1][0]*b[0][0]+a[1][1]*b[1][0]+a[1][2]*b[2][0]; \
+ c[1][1] = a[1][0]*b[0][1]+a[1][1]*b[1][1]+a[1][2]*b[2][1]; \
+ c[1][2] = a[1][0]*b[0][2]+a[1][1]*b[1][2]+a[1][2]*b[2][2]; \
+ \
+ c[2][0] = a[2][0]*b[0][0]+a[2][1]*b[1][0]+a[2][2]*b[2][0]; \
+ c[2][1] = a[2][0]*b[0][1]+a[2][1]*b[1][1]+a[2][2]*b[2][1]; \
+ c[2][2] = a[2][0]*b[0][2]+a[2][1]*b[1][2]+a[2][2]*b[2][2]; \
+}\
+
+
+/*! matrix product */
+/*! c[x][y] = a[x][0]*b[0][y]+a[x][1]*b[1][y]+a[x][2]*b[2][y]+a[x][3]*b[3][y];*/
+#define MATRIX_PRODUCT_4X4(c,a,b) \
+{ \
+ c[0][0] = a[0][0]*b[0][0]+a[0][1]*b[1][0]+a[0][2]*b[2][0]+a[0][3]*b[3][0];\
+ c[0][1] = a[0][0]*b[0][1]+a[0][1]*b[1][1]+a[0][2]*b[2][1]+a[0][3]*b[3][1];\
+ c[0][2] = a[0][0]*b[0][2]+a[0][1]*b[1][2]+a[0][2]*b[2][2]+a[0][3]*b[3][2];\
+ c[0][3] = a[0][0]*b[0][3]+a[0][1]*b[1][3]+a[0][2]*b[2][3]+a[0][3]*b[3][3];\
+ \
+ c[1][0] = a[1][0]*b[0][0]+a[1][1]*b[1][0]+a[1][2]*b[2][0]+a[1][3]*b[3][0];\
+ c[1][1] = a[1][0]*b[0][1]+a[1][1]*b[1][1]+a[1][2]*b[2][1]+a[1][3]*b[3][1];\
+ c[1][2] = a[1][0]*b[0][2]+a[1][1]*b[1][2]+a[1][2]*b[2][2]+a[1][3]*b[3][2];\
+ c[1][3] = a[1][0]*b[0][3]+a[1][1]*b[1][3]+a[1][2]*b[2][3]+a[1][3]*b[3][3];\
+ \
+ c[2][0] = a[2][0]*b[0][0]+a[2][1]*b[1][0]+a[2][2]*b[2][0]+a[2][3]*b[3][0];\
+ c[2][1] = a[2][0]*b[0][1]+a[2][1]*b[1][1]+a[2][2]*b[2][1]+a[2][3]*b[3][1];\
+ c[2][2] = a[2][0]*b[0][2]+a[2][1]*b[1][2]+a[2][2]*b[2][2]+a[2][3]*b[3][2];\
+ c[2][3] = a[2][0]*b[0][3]+a[2][1]*b[1][3]+a[2][2]*b[2][3]+a[2][3]*b[3][3];\
+ \
+ c[3][0] = a[3][0]*b[0][0]+a[3][1]*b[1][0]+a[3][2]*b[2][0]+a[3][3]*b[3][0];\
+ c[3][1] = a[3][0]*b[0][1]+a[3][1]*b[1][1]+a[3][2]*b[2][1]+a[3][3]*b[3][1];\
+ c[3][2] = a[3][0]*b[0][2]+a[3][1]*b[1][2]+a[3][2]*b[2][2]+a[3][3]*b[3][2];\
+ c[3][3] = a[3][0]*b[0][3]+a[3][1]*b[1][3]+a[3][2]*b[2][3]+a[3][3]*b[3][3];\
+}\
+
+
+/*! matrix times vector */
+#define MAT_DOT_VEC_2X2(p,m,v) \
+{ \
+ p[0] = m[0][0]*v[0] + m[0][1]*v[1]; \
+ p[1] = m[1][0]*v[0] + m[1][1]*v[1]; \
+}\
+
+
+/*! matrix times vector */
+#define MAT_DOT_VEC_3X3(p,m,v) \
+{ \
+ p[0] = m[0][0]*v[0] + m[0][1]*v[1] + m[0][2]*v[2]; \
+ p[1] = m[1][0]*v[0] + m[1][1]*v[1] + m[1][2]*v[2]; \
+ p[2] = m[2][0]*v[0] + m[2][1]*v[1] + m[2][2]*v[2]; \
+}\
+
+
+/*! matrix times vector
+v is a vec4f
+*/
+#define MAT_DOT_VEC_4X4(p,m,v) \
+{ \
+ p[0] = m[0][0]*v[0] + m[0][1]*v[1] + m[0][2]*v[2] + m[0][3]*v[3]; \
+ p[1] = m[1][0]*v[0] + m[1][1]*v[1] + m[1][2]*v[2] + m[1][3]*v[3]; \
+ p[2] = m[2][0]*v[0] + m[2][1]*v[1] + m[2][2]*v[2] + m[2][3]*v[3]; \
+ p[3] = m[3][0]*v[0] + m[3][1]*v[1] + m[3][2]*v[2] + m[3][3]*v[3]; \
+}\
+
+/*! matrix times vector
+v is a vec3f
+and m is a mat4f<br>
+Last column is added as the position
+*/
+#define MAT_DOT_VEC_3X4(p,m,v) \
+{ \
+ p[0] = m[0][0]*v[0] + m[0][1]*v[1] + m[0][2]*v[2] + m[0][3]; \
+ p[1] = m[1][0]*v[0] + m[1][1]*v[1] + m[1][2]*v[2] + m[1][3]; \
+ p[2] = m[2][0]*v[0] + m[2][1]*v[1] + m[2][2]*v[2] + m[2][3]; \
+}\
+
+/*! vector transpose times matrix */
+/*! p[j] = v[0]*m[0][j] + v[1]*m[1][j] + v[2]*m[2][j]; */
+#define VEC_DOT_MAT_3X3(p,v,m) \
+{ \
+ p[0] = v[0]*m[0][0] + v[1]*m[1][0] + v[2]*m[2][0]; \
+ p[1] = v[0]*m[0][1] + v[1]*m[1][1] + v[2]*m[2][1]; \
+ p[2] = v[0]*m[0][2] + v[1]*m[1][2] + v[2]*m[2][2]; \
+}\
+
+
+/*! affine matrix times vector */
+/** The matrix is assumed to be an affine matrix, with last two
+ * entries representing a translation */
+#define MAT_DOT_VEC_2X3(p,m,v) \
+{ \
+ p[0] = m[0][0]*v[0] + m[0][1]*v[1] + m[0][2]; \
+ p[1] = m[1][0]*v[0] + m[1][1]*v[1] + m[1][2]; \
+}\
+
+
+/** inverse transpose of matrix times vector
+ *
+ * This macro computes inverse transpose of matrix m,
+ * and multiplies vector v into it, to yeild vector p
+ *
+ * DANGER !!! Do Not use this on normal vectors!!!
+ * It will leave normals the wrong length !!!
+ * See macro below for use on normals.
+ */
+#define INV_TRANSP_MAT_DOT_VEC_2X2(p,m,v) \
+{ \
+ GREAL det; \
+ \
+ det = m[0][0]*m[1][1] - m[0][1]*m[1][0]; \
+ p[0] = m[1][1]*v[0] - m[1][0]*v[1]; \
+ p[1] = - m[0][1]*v[0] + m[0][0]*v[1]; \
+ \
+ /* if matrix not singular, and not orthonormal, then renormalize */ \
+ if ((det!=1.0f) && (det != 0.0f)) { \
+ det = 1.0f / det; \
+ p[0] *= det; \
+ p[1] *= det; \
+ } \
+}\
+
+
+/** transform normal vector by inverse transpose of matrix
+ * and then renormalize the vector
+ *
+ * This macro computes inverse transpose of matrix m,
+ * and multiplies vector v into it, to yeild vector p
+ * Vector p is then normalized.
+ */
+#define NORM_XFORM_2X2(p,m,v) \
+{ \
+ double len; \
+ \
+ /* do nothing if off-diagonals are zero and diagonals are \
+ * equal */ \
+ if ((m[0][1] != 0.0) || (m[1][0] != 0.0) || (m[0][0] != m[1][1])) { \
+ p[0] = m[1][1]*v[0] - m[1][0]*v[1]; \
+ p[1] = - m[0][1]*v[0] + m[0][0]*v[1]; \
+ \
+ len = p[0]*p[0] + p[1]*p[1]; \
+ GIM_INV_SQRT(len,len); \
+ p[0] *= len; \
+ p[1] *= len; \
+ } else { \
+ VEC_COPY_2 (p, v); \
+ } \
+}\
+
+
+/** outer product of vector times vector transpose
+ *
+ * The outer product of vector v and vector transpose t yeilds
+ * dyadic matrix m.
+ */
+#define OUTER_PRODUCT_2X2(m,v,t) \
+{ \
+ m[0][0] = v[0] * t[0]; \
+ m[0][1] = v[0] * t[1]; \
+ \
+ m[1][0] = v[1] * t[0]; \
+ m[1][1] = v[1] * t[1]; \
+}\
+
+
+/** outer product of vector times vector transpose
+ *
+ * The outer product of vector v and vector transpose t yeilds
+ * dyadic matrix m.
+ */
+#define OUTER_PRODUCT_3X3(m,v,t) \
+{ \
+ m[0][0] = v[0] * t[0]; \
+ m[0][1] = v[0] * t[1]; \
+ m[0][2] = v[0] * t[2]; \
+ \
+ m[1][0] = v[1] * t[0]; \
+ m[1][1] = v[1] * t[1]; \
+ m[1][2] = v[1] * t[2]; \
+ \
+ m[2][0] = v[2] * t[0]; \
+ m[2][1] = v[2] * t[1]; \
+ m[2][2] = v[2] * t[2]; \
+}\
+
+
+/** outer product of vector times vector transpose
+ *
+ * The outer product of vector v and vector transpose t yeilds
+ * dyadic matrix m.
+ */
+#define OUTER_PRODUCT_4X4(m,v,t) \
+{ \
+ m[0][0] = v[0] * t[0]; \
+ m[0][1] = v[0] * t[1]; \
+ m[0][2] = v[0] * t[2]; \
+ m[0][3] = v[0] * t[3]; \
+ \
+ m[1][0] = v[1] * t[0]; \
+ m[1][1] = v[1] * t[1]; \
+ m[1][2] = v[1] * t[2]; \
+ m[1][3] = v[1] * t[3]; \
+ \
+ m[2][0] = v[2] * t[0]; \
+ m[2][1] = v[2] * t[1]; \
+ m[2][2] = v[2] * t[2]; \
+ m[2][3] = v[2] * t[3]; \
+ \
+ m[3][0] = v[3] * t[0]; \
+ m[3][1] = v[3] * t[1]; \
+ m[3][2] = v[3] * t[2]; \
+ m[3][3] = v[3] * t[3]; \
+}\
+
+
+/** outer product of vector times vector transpose
+ *
+ * The outer product of vector v and vector transpose t yeilds
+ * dyadic matrix m.
+ */
+#define ACCUM_OUTER_PRODUCT_2X2(m,v,t) \
+{ \
+ m[0][0] += v[0] * t[0]; \
+ m[0][1] += v[0] * t[1]; \
+ \
+ m[1][0] += v[1] * t[0]; \
+ m[1][1] += v[1] * t[1]; \
+}\
+
+
+/** outer product of vector times vector transpose
+ *
+ * The outer product of vector v and vector transpose t yeilds
+ * dyadic matrix m.
+ */
+#define ACCUM_OUTER_PRODUCT_3X3(m,v,t) \
+{ \
+ m[0][0] += v[0] * t[0]; \
+ m[0][1] += v[0] * t[1]; \
+ m[0][2] += v[0] * t[2]; \
+ \
+ m[1][0] += v[1] * t[0]; \
+ m[1][1] += v[1] * t[1]; \
+ m[1][2] += v[1] * t[2]; \
+ \
+ m[2][0] += v[2] * t[0]; \
+ m[2][1] += v[2] * t[1]; \
+ m[2][2] += v[2] * t[2]; \
+}\
+
+
+/** outer product of vector times vector transpose
+ *
+ * The outer product of vector v and vector transpose t yeilds
+ * dyadic matrix m.
+ */
+#define ACCUM_OUTER_PRODUCT_4X4(m,v,t) \
+{ \
+ m[0][0] += v[0] * t[0]; \
+ m[0][1] += v[0] * t[1]; \
+ m[0][2] += v[0] * t[2]; \
+ m[0][3] += v[0] * t[3]; \
+ \
+ m[1][0] += v[1] * t[0]; \
+ m[1][1] += v[1] * t[1]; \
+ m[1][2] += v[1] * t[2]; \
+ m[1][3] += v[1] * t[3]; \
+ \
+ m[2][0] += v[2] * t[0]; \
+ m[2][1] += v[2] * t[1]; \
+ m[2][2] += v[2] * t[2]; \
+ m[2][3] += v[2] * t[3]; \
+ \
+ m[3][0] += v[3] * t[0]; \
+ m[3][1] += v[3] * t[1]; \
+ m[3][2] += v[3] * t[2]; \
+ m[3][3] += v[3] * t[3]; \
+}\
+
+
+/** determinant of matrix
+ *
+ * Computes determinant of matrix m, returning d
+ */
+#define DETERMINANT_2X2(d,m) \
+{ \
+ d = m[0][0] * m[1][1] - m[0][1] * m[1][0]; \
+}\
+
+
+/** determinant of matrix
+ *
+ * Computes determinant of matrix m, returning d
+ */
+#define DETERMINANT_3X3(d,m) \
+{ \
+ d = m[0][0] * (m[1][1]*m[2][2] - m[1][2] * m[2][1]); \
+ d -= m[0][1] * (m[1][0]*m[2][2] - m[1][2] * m[2][0]); \
+ d += m[0][2] * (m[1][0]*m[2][1] - m[1][1] * m[2][0]); \
+}\
+
+
+/** i,j,th cofactor of a 4x4 matrix
+ *
+ */
+#define COFACTOR_4X4_IJ(fac,m,i,j) \
+{ \
+ int __ii[4], __jj[4], __k; \
+ \
+ for (__k=0; __k<i; __k++) __ii[__k] = __k; \
+ for (__k=i; __k<3; __k++) __ii[__k] = __k+1; \
+ for (__k=0; __k<j; __k++) __jj[__k] = __k; \
+ for (__k=j; __k<3; __k++) __jj[__k] = __k+1; \
+ \
+ (fac) = m[__ii[0]][__jj[0]] * (m[__ii[1]][__jj[1]]*m[__ii[2]][__jj[2]] \
+ - m[__ii[1]][__jj[2]]*m[__ii[2]][__jj[1]]); \
+ (fac) -= m[__ii[0]][__jj[1]] * (m[__ii[1]][__jj[0]]*m[__ii[2]][__jj[2]] \
+ - m[__ii[1]][__jj[2]]*m[__ii[2]][__jj[0]]);\
+ (fac) += m[__ii[0]][__jj[2]] * (m[__ii[1]][__jj[0]]*m[__ii[2]][__jj[1]] \
+ - m[__ii[1]][__jj[1]]*m[__ii[2]][__jj[0]]);\
+ \
+ __k = i+j; \
+ if ( __k != (__k/2)*2) { \
+ (fac) = -(fac); \
+ } \
+}\
+
+
+/** determinant of matrix
+ *
+ * Computes determinant of matrix m, returning d
+ */
+#define DETERMINANT_4X4(d,m) \
+{ \
+ double cofac; \
+ COFACTOR_4X4_IJ (cofac, m, 0, 0); \
+ d = m[0][0] * cofac; \
+ COFACTOR_4X4_IJ (cofac, m, 0, 1); \
+ d += m[0][1] * cofac; \
+ COFACTOR_4X4_IJ (cofac, m, 0, 2); \
+ d += m[0][2] * cofac; \
+ COFACTOR_4X4_IJ (cofac, m, 0, 3); \
+ d += m[0][3] * cofac; \
+}\
+
+
+/** cofactor of matrix
+ *
+ * Computes cofactor of matrix m, returning a
+ */
+#define COFACTOR_2X2(a,m) \
+{ \
+ a[0][0] = (m)[1][1]; \
+ a[0][1] = - (m)[1][0]; \
+ a[1][0] = - (m)[0][1]; \
+ a[1][1] = (m)[0][0]; \
+}\
+
+
+/** cofactor of matrix
+ *
+ * Computes cofactor of matrix m, returning a
+ */
+#define COFACTOR_3X3(a,m) \
+{ \
+ a[0][0] = m[1][1]*m[2][2] - m[1][2]*m[2][1]; \
+ a[0][1] = - (m[1][0]*m[2][2] - m[2][0]*m[1][2]); \
+ a[0][2] = m[1][0]*m[2][1] - m[1][1]*m[2][0]; \
+ a[1][0] = - (m[0][1]*m[2][2] - m[0][2]*m[2][1]); \
+ a[1][1] = m[0][0]*m[2][2] - m[0][2]*m[2][0]; \
+ a[1][2] = - (m[0][0]*m[2][1] - m[0][1]*m[2][0]); \
+ a[2][0] = m[0][1]*m[1][2] - m[0][2]*m[1][1]; \
+ a[2][1] = - (m[0][0]*m[1][2] - m[0][2]*m[1][0]); \
+ a[2][2] = m[0][0]*m[1][1] - m[0][1]*m[1][0]); \
+}\
+
+
+/** cofactor of matrix
+ *
+ * Computes cofactor of matrix m, returning a
+ */
+#define COFACTOR_4X4(a,m) \
+{ \
+ int i,j; \
+ \
+ for (i=0; i<4; i++) { \
+ for (j=0; j<4; j++) { \
+ COFACTOR_4X4_IJ (a[i][j], m, i, j); \
+ } \
+ } \
+}\
+
+
+/** adjoint of matrix
+ *
+ * Computes adjoint of matrix m, returning a
+ * (Note that adjoint is just the transpose of the cofactor matrix)
+ */
+#define ADJOINT_2X2(a,m) \
+{ \
+ a[0][0] = (m)[1][1]; \
+ a[1][0] = - (m)[1][0]; \
+ a[0][1] = - (m)[0][1]; \
+ a[1][1] = (m)[0][0]; \
+}\
+
+
+/** adjoint of matrix
+ *
+ * Computes adjoint of matrix m, returning a
+ * (Note that adjoint is just the transpose of the cofactor matrix)
+ */
+#define ADJOINT_3X3(a,m) \
+{ \
+ a[0][0] = m[1][1]*m[2][2] - m[1][2]*m[2][1]; \
+ a[1][0] = - (m[1][0]*m[2][2] - m[2][0]*m[1][2]); \
+ a[2][0] = m[1][0]*m[2][1] - m[1][1]*m[2][0]; \
+ a[0][1] = - (m[0][1]*m[2][2] - m[0][2]*m[2][1]); \
+ a[1][1] = m[0][0]*m[2][2] - m[0][2]*m[2][0]; \
+ a[2][1] = - (m[0][0]*m[2][1] - m[0][1]*m[2][0]); \
+ a[0][2] = m[0][1]*m[1][2] - m[0][2]*m[1][1]; \
+ a[1][2] = - (m[0][0]*m[1][2] - m[0][2]*m[1][0]); \
+ a[2][2] = m[0][0]*m[1][1] - m[0][1]*m[1][0]); \
+}\
+
+
+/** adjoint of matrix
+ *
+ * Computes adjoint of matrix m, returning a
+ * (Note that adjoint is just the transpose of the cofactor matrix)
+ */
+#define ADJOINT_4X4(a,m) \
+{ \
+ char _i_,_j_; \
+ \
+ for (_i_=0; _i_<4; _i_++) { \
+ for (_j_=0; _j_<4; _j_++) { \
+ COFACTOR_4X4_IJ (a[_j_][_i_], m, _i_, _j_); \
+ } \
+ } \
+}\
+
+
+/** compute adjoint of matrix and scale
+ *
+ * Computes adjoint of matrix m, scales it by s, returning a
+ */
+#define SCALE_ADJOINT_2X2(a,s,m) \
+{ \
+ a[0][0] = (s) * m[1][1]; \
+ a[1][0] = - (s) * m[1][0]; \
+ a[0][1] = - (s) * m[0][1]; \
+ a[1][1] = (s) * m[0][0]; \
+}\
+
+
+/** compute adjoint of matrix and scale
+ *
+ * Computes adjoint of matrix m, scales it by s, returning a
+ */
+#define SCALE_ADJOINT_3X3(a,s,m) \
+{ \
+ a[0][0] = (s) * (m[1][1] * m[2][2] - m[1][2] * m[2][1]); \
+ a[1][0] = (s) * (m[1][2] * m[2][0] - m[1][0] * m[2][2]); \
+ a[2][0] = (s) * (m[1][0] * m[2][1] - m[1][1] * m[2][0]); \
+ \
+ a[0][1] = (s) * (m[0][2] * m[2][1] - m[0][1] * m[2][2]); \
+ a[1][1] = (s) * (m[0][0] * m[2][2] - m[0][2] * m[2][0]); \
+ a[2][1] = (s) * (m[0][1] * m[2][0] - m[0][0] * m[2][1]); \
+ \
+ a[0][2] = (s) * (m[0][1] * m[1][2] - m[0][2] * m[1][1]); \
+ a[1][2] = (s) * (m[0][2] * m[1][0] - m[0][0] * m[1][2]); \
+ a[2][2] = (s) * (m[0][0] * m[1][1] - m[0][1] * m[1][0]); \
+}\
+
+
+/** compute adjoint of matrix and scale
+ *
+ * Computes adjoint of matrix m, scales it by s, returning a
+ */
+#define SCALE_ADJOINT_4X4(a,s,m) \
+{ \
+ char _i_,_j_; \
+ for (_i_=0; _i_<4; _i_++) { \
+ for (_j_=0; _j_<4; _j_++) { \
+ COFACTOR_4X4_IJ (a[_j_][_i_], m, _i_, _j_); \
+ a[_j_][_i_] *= s; \
+ } \
+ } \
+}\
+
+/** inverse of matrix
+ *
+ * Compute inverse of matrix a, returning determinant m and
+ * inverse b
+ */
+#define INVERT_2X2(b,det,a) \
+{ \
+ GREAL _tmp_; \
+ DETERMINANT_2X2 (det, a); \
+ _tmp_ = 1.0 / (det); \
+ SCALE_ADJOINT_2X2 (b, _tmp_, a); \
+}\
+
+
+/** inverse of matrix
+ *
+ * Compute inverse of matrix a, returning determinant m and
+ * inverse b
+ */
+#define INVERT_3X3(b,det,a) \
+{ \
+ GREAL _tmp_; \
+ DETERMINANT_3X3 (det, a); \
+ _tmp_ = 1.0 / (det); \
+ SCALE_ADJOINT_3X3 (b, _tmp_, a); \
+}\
+
+
+/** inverse of matrix
+ *
+ * Compute inverse of matrix a, returning determinant m and
+ * inverse b
+ */
+#define INVERT_4X4(b,det,a) \
+{ \
+ GREAL _tmp_; \
+ DETERMINANT_4X4 (det, a); \
+ _tmp_ = 1.0 / (det); \
+ SCALE_ADJOINT_4X4 (b, _tmp_, a); \
+}\
+
+//! @}
+
+/*! \defgroup BOUND_AABB_OPERATIONS
+*/
+//! @{
+
+//!Initializes an AABB
+#define INVALIDATE_AABB(aabb) {\
+ (aabb).minX = G_REAL_INFINITY;\
+ (aabb).maxX = -G_REAL_INFINITY;\
+ (aabb).minY = G_REAL_INFINITY;\
+ (aabb).maxY = -G_REAL_INFINITY;\
+ (aabb).minZ = G_REAL_INFINITY;\
+ (aabb).maxZ = -G_REAL_INFINITY;\
+}\
+
+#define AABB_GET_MIN(aabb,vmin) {\
+ vmin[0] = (aabb).minX;\
+ vmin[1] = (aabb).minY;\
+ vmin[2] = (aabb).minZ;\
+}\
+
+#define AABB_GET_MAX(aabb,vmax) {\
+ vmax[0] = (aabb).maxX;\
+ vmax[1] = (aabb).maxY;\
+ vmax[2] = (aabb).maxZ;\
+}\
+
+//!Copy boxes
+#define AABB_COPY(dest_aabb,src_aabb)\
+{\
+ (dest_aabb).minX = (src_aabb).minX;\
+ (dest_aabb).maxX = (src_aabb).maxX;\
+ (dest_aabb).minY = (src_aabb).minY;\
+ (dest_aabb).maxY = (src_aabb).maxY;\
+ (dest_aabb).minZ = (src_aabb).minZ;\
+ (dest_aabb).maxZ = (src_aabb).maxZ;\
+}\
+
+//! Computes an Axis aligned box from a triangle
+#define COMPUTEAABB_FOR_TRIANGLE(aabb,V1,V2,V3) {\
+ (aabb).minX = MIN3(V1[0],V2[0],V3[0]);\
+ (aabb).maxX = MAX3(V1[0],V2[0],V3[0]);\
+ (aabb).minY = MIN3(V1[1],V2[1],V3[1]);\
+ (aabb).maxY = MAX3(V1[1],V2[1],V3[1]);\
+ (aabb).minZ = MIN3(V1[2],V2[2],V3[2]);\
+ (aabb).maxZ = MAX3(V1[2],V2[2],V3[2]);\
+}\
+
+//! Merge two boxes to destaabb
+#define MERGEBOXES(destaabb,aabb) {\
+ (destaabb).minX = MIN((aabb).minX,(destaabb).minX);\
+ (destaabb).minY = MIN((aabb).minY,(destaabb).minY);\
+ (destaabb).minZ = MIN((aabb).minZ,(destaabb).minZ);\
+ (destaabb).maxX = MAX((aabb).maxX,(destaabb).maxX);\
+ (destaabb).maxY = MAX((aabb).maxY,(destaabb).maxY);\
+ (destaabb).maxZ = MAX((aabb).maxZ,(destaabb).maxZ);\
+}\
+
+//! Extends the box
+#define AABB_POINT_EXTEND(destaabb,p) {\
+ (destaabb).minX = MIN(p[0],(destaabb).minX);\
+ (destaabb).maxX = MAX(p[0],(destaabb).maxX);\
+ (destaabb).minY = MIN(p[1],(destaabb).minY);\
+ (destaabb).maxY = MAX(p[1],(destaabb).maxY);\
+ (destaabb).minZ = MIN(p[2],(destaabb).minZ);\
+ (destaabb).maxZ = MAX(p[2],(destaabb).maxZ);\
+}\
+
+//! Finds the intersection box of two boxes
+#define BOXINTERSECTION(aabb1, aabb2, iaabb) {\
+ (iaabb).minX = MAX((aabb1).minX,(aabb2).minX);\
+ (iaabb).minY = MAX((aabb1).minY,(aabb2).minY);\
+ (iaabb).minZ = MAX((aabb1).minZ,(aabb2).minZ);\
+ (iaabb).maxX = MIN((aabb1).maxX,(aabb2).maxX);\
+ (iaabb).maxY = MIN((aabb1).maxY,(aabb2).maxY);\
+ (iaabb).maxZ = MIN((aabb1).maxZ,(aabb2).maxZ);\
+}\
+
+//! Determines if two aligned boxes do intersect
+#define AABBCOLLISION(intersected,aabb1,aabb2) {\
+ intersected = 1;\
+ if ((aabb1).minX > (aabb2).maxX ||\
+ (aabb1).maxX < (aabb2).minX ||\
+ (aabb1).minY > (aabb2).maxY ||\
+ (aabb1).maxY < (aabb2).minY ||\
+ (aabb1).minZ > (aabb2).maxZ ||\
+ (aabb1).maxZ < (aabb2).minZ )\
+ {\
+ intersected = 0;\
+ }\
+}\
+
+#define AXIS_INTERSECT(min,max, a, d,tfirst, tlast,is_intersected) {\
+ if(IS_ZERO(d))\
+ {\
+ is_intersected = !(a < min || a > max);\
+ }\
+ else\
+ {\
+ GREAL a0, a1;\
+ a0 = (min - a) / (d);\
+ a1 = (max - a) / (d);\
+ if(a0 > a1) SWAP_NUMBERS(a0, a1);\
+ tfirst = MAX(a0, tfirst);\
+ tlast = MIN(a1, tlast);\
+ if (tlast < tfirst)\
+ {\
+ is_intersected = 0;\
+ }\
+ else\
+ {\
+ is_intersected = 1;\
+ }\
+ }\
+}\
+
+/*! \brief Finds the Ray intersection parameter.
+
+\param aabb Aligned box
+\param vorigin A vec3f with the origin of the ray
+\param vdir A vec3f with the direction of the ray
+\param tparam Output parameter
+\param tmax Max lenght of the ray
+\param is_intersected 1 if the ray collides the box, else false
+
+*/
+#define BOX_INTERSECTS_RAY(aabb, vorigin, vdir, tparam, tmax,is_intersected) { \
+ GREAL _tfirst = 0.0f, _tlast = tmax;\
+ AXIS_INTERSECT(aabb.minX,aabb.maxX,vorigin[0], vdir[0], _tfirst, _tlast,is_intersected);\
+ if(is_intersected)\
+ {\
+ AXIS_INTERSECT(aabb.minY,aabb.maxY,vorigin[1], vdir[1], _tfirst, _tlast,is_intersected);\
+ }\
+ if(is_intersected)\
+ {\
+ AXIS_INTERSECT(aabb.minZ,aabb.maxZ,vorigin[2], vdir[2], _tfirst, _tlast,is_intersected);\
+ }\
+ tparam = _tfirst;\
+}\
+
+#define AABB_PROJECTION_INTERVAL(aabb,direction, vmin, vmax)\
+{\
+ GREAL _center[] = {(aabb.minX + aabb.maxX)*0.5f, (aabb.minY + aabb.maxY)*0.5f, (aabb.minZ + aabb.maxZ)*0.5f};\
+ \
+ GREAL _extend[] = {aabb.maxX-_center[0],aabb.maxY-_center[1],aabb.maxZ-_center[2]};\
+ GREAL _fOrigin = VEC_DOT(direction,_center);\
+ GREAL _fMaximumExtent = _extend[0]*fabsf(direction[0]) + \
+ _extend[1]*fabsf(direction[1]) + \
+ _extend[2]*fabsf(direction[2]); \
+\
+ vmin = _fOrigin - _fMaximumExtent; \
+ vmax = _fOrigin + _fMaximumExtent; \
+}\
+
+/*!
+classify values:
+<ol>
+<li> 0 : In back of plane
+<li> 1 : Spanning
+<li> 2 : In front of
+</ol>
+*/
+#define PLANE_CLASSIFY_BOX(plane,aabb,classify)\
+{\
+ GREAL _fmin,_fmax; \
+ AABB_PROJECTION_INTERVAL(aabb,plane, _fmin, _fmax); \
+ if(plane[3] >= _fmax) \
+ { \
+ classify = 0;/*In back of*/ \
+ } \
+ else \
+ { \
+ if(plane[3]+0.000001f>=_fmin) \
+ { \
+ classify = 1;/*Spanning*/ \
+ } \
+ else \
+ { \
+ classify = 2;/*In front of*/ \
+ } \
+ } \
+}\
+//! @}
+
+/*! \defgroup GEOMETRIC_OPERATIONS
+*/
+//! @{
+
+
+#define PLANEDIREPSILON 0.0000001f
+#define PARALELENORMALS 0.000001f
+
+#define TRIANGLE_NORMAL(v1,v2,v3,n){\
+ vec3f _dif1,_dif2; \
+ VEC_DIFF(_dif1,v2,v1); \
+ VEC_DIFF(_dif2,v3,v1); \
+ VEC_CROSS(n,_dif1,_dif2); \
+ VEC_NORMALIZE(n); \
+}\
+
+/// plane is a vec4f
+#define TRIANGLE_PLANE(v1,v2,v3,plane) {\
+ TRIANGLE_NORMAL(v1,v2,v3,plane);\
+ plane[3] = VEC_DOT(v1,plane);\
+}\
+
+/// Calc a plane from an edge an a normal. plane is a vec4f
+#define EDGE_PLANE(e1,e2,n,plane) {\
+ vec3f _dif; \
+ VEC_DIFF(_dif,e2,e1); \
+ VEC_CROSS(plane,_dif,n); \
+ VEC_NORMALIZE(plane); \
+ plane[3] = VEC_DOT(e1,plane);\
+}\
+
+#define DISTANCE_PLANE_POINT(plane,point) (VEC_DOT(plane,point) - plane[3])
+
+#define PROJECT_POINT_PLANE(point,plane,projected) {\
+ GREAL _dis;\
+ _dis = DISTANCE_PLANE_POINT(plane,point);\
+ VEC_SCALE(projected,-_dis,plane);\
+ VEC_SUM(projected,projected,point); \
+}\
+
+#define POINT_IN_HULL(point,planes,plane_count,outside)\
+{\
+ GREAL _dis;\
+ outside = 0;\
+ GUINT32 _i = 0;\
+ do\
+ {\
+ _dis = DISTANCE_PLANE_POINT(planes[_i],point);\
+ if(_dis>0.0f) outside = 1;\
+ _i++;\
+ }while(_i<plane_count&&outside==0);\
+}\
+
+
+#define PLANE_CLIP_SEGMENT(s1,s2,plane,clipped) {\
+ GREAL _dis1,_dis2;\
+ _dis1 = DISTANCE_PLANE_POINT(plane,s1);\
+ VEC_DIFF(clipped,s2,s1);\
+ _dis2 = VEC_DOT(clipped,plane);\
+ VEC_SCALE(clipped,-_dis1/_dis2,clipped);\
+ VEC_SUM(clipped,clipped,s1); \
+}\
+
+//! Confirms if the plane intersect the edge or nor
+/*!
+intersection type must have the following values
+<ul>
+<li> 0 : Segment in front of plane, s1 closest
+<li> 1 : Segment in front of plane, s2 closest
+<li> 2 : Segment in back of plane, s1 closest
+<li> 3 : Segment in back of plane, s2 closest
+<li> 4 : Segment collides plane, s1 in back
+<li> 5 : Segment collides plane, s2 in back
+</ul>
+*/
+#define PLANE_CLIP_SEGMENT2(s1,s2,plane,clipped,intersection_type) \
+{\
+ GREAL _dis1,_dis2;\
+ _dis1 = DISTANCE_PLANE_POINT(plane,s1);\
+ _dis2 = DISTANCE_PLANE_POINT(plane,s2);\
+ if(_dis1 >-G_EPSILON && _dis2 >-G_EPSILON)\
+ {\
+ if(_dis1<_dis2) intersection_type = 0;\
+ else intersection_type = 1;\
+ }\
+ else if(_dis1 <G_EPSILON && _dis2 <G_EPSILON)\
+ {\
+ if(_dis1>_dis2) intersection_type = 2;\
+ else intersection_type = 3; \
+ }\
+ else\
+ {\
+ if(_dis1<_dis2) intersection_type = 4;\
+ else intersection_type = 5;\
+ VEC_DIFF(clipped,s2,s1);\
+ _dis2 = VEC_DOT(clipped,plane);\
+ VEC_SCALE(clipped,-_dis1/_dis2,clipped);\
+ VEC_SUM(clipped,clipped,s1); \
+ }\
+}\
+
+//! Confirms if the plane intersect the edge or not
+/*!
+clipped1 and clipped2 are the vertices behind the plane.
+clipped1 is the closest
+
+intersection_type must have the following values
+<ul>
+<li> 0 : Segment in front of plane, s1 closest
+<li> 1 : Segment in front of plane, s2 closest
+<li> 2 : Segment in back of plane, s1 closest
+<li> 3 : Segment in back of plane, s2 closest
+<li> 4 : Segment collides plane, s1 in back
+<li> 5 : Segment collides plane, s2 in back
+</ul>
+*/
+#define PLANE_CLIP_SEGMENT_CLOSEST(s1,s2,plane,clipped1,clipped2,intersection_type)\
+{\
+ PLANE_CLIP_SEGMENT2(s1,s2,plane,clipped1,intersection_type);\
+ if(intersection_type == 0)\
+ {\
+ VEC_COPY(clipped1,s1);\
+ VEC_COPY(clipped2,s2);\
+ }\
+ else if(intersection_type == 1)\
+ {\
+ VEC_COPY(clipped1,s2);\
+ VEC_COPY(clipped2,s1);\
+ }\
+ else if(intersection_type == 2)\
+ {\
+ VEC_COPY(clipped1,s1);\
+ VEC_COPY(clipped2,s2);\
+ }\
+ else if(intersection_type == 3)\
+ {\
+ VEC_COPY(clipped1,s2);\
+ VEC_COPY(clipped2,s1);\
+ }\
+ else if(intersection_type == 4)\
+ { \
+ VEC_COPY(clipped2,s1);\
+ }\
+ else if(intersection_type == 5)\
+ { \
+ VEC_COPY(clipped2,s2);\
+ }\
+}\
+
+
+//! Finds the 2 smallest cartesian coordinates of a plane normal
+#define PLANE_MINOR_AXES(plane, i0, i1)\
+{\
+ GREAL A[] = {fabs(plane[0]),fabs(plane[1]),fabs(plane[2])};\
+ if(A[0]>A[1])\
+ {\
+ if(A[0]>A[2])\
+ {\
+ i0=1; /* A[0] is greatest */ \
+ i1=2;\
+ }\
+ else \
+ {\
+ i0=0; /* A[2] is greatest */ \
+ i1=1; \
+ }\
+ }\
+ else /* A[0]<=A[1] */ \
+ {\
+ if(A[2]>A[1]) \
+ { \
+ i0=0; /* A[2] is greatest */ \
+ i1=1; \
+ }\
+ else \
+ {\
+ i0=0; /* A[1] is greatest */ \
+ i1=2; \
+ }\
+ } \
+}\
+
+//! Ray plane collision
+#define RAY_PLANE_COLLISION(plane,vDir,vPoint,pout,tparam,does_intersect)\
+{\
+ GREAL _dis,_dotdir; \
+ _dotdir = VEC_DOT(plane,vDir);\
+ if(_dotdir<PLANEDIREPSILON)\
+ {\
+ does_intersect = 0;\
+ }\
+ else\
+ {\
+ _dis = DISTANCE_PLANE_POINT(plane,vPoint); \
+ tparam = -_dis/_dotdir;\
+ VEC_SCALE(pout,tparam,vDir);\
+ VEC_SUM(pout,vPoint,pout); \
+ does_intersect = 1;\
+ }\
+}\
+
+//! Bidireccional ray
+#define LINE_PLANE_COLLISION(plane,vDir,vPoint,pout,tparam, tmin, tmax)\
+{\
+ tparam = -DISTANCE_PLANE_POINT(plane,vPoint);\
+ tparam /= VEC_DOT(plane,vDir);\
+ tparam = CLAMP(tparam,tmin,tmax);\
+ VEC_SCALE(pout,tparam,vDir);\
+ VEC_SUM(pout,vPoint,pout); \
+}\
+
+/*! \brief Returns the Ray on which 2 planes intersect if they do.
+ Written by Rodrigo Hernandez on ODE convex collision
+
+ \param p1 Plane 1
+ \param p2 Plane 2
+ \param p Contains the origin of the ray upon returning if planes intersect
+ \param d Contains the direction of the ray upon returning if planes intersect
+ \param dointersect 1 if the planes intersect, 0 if paralell.
+
+*/
+#define INTERSECT_PLANES(p1,p2,p,d,dointersect) \
+{ \
+ VEC_CROSS(d,p1,p2); \
+ GREAL denom = VEC_DOT(d, d);\
+ if (IS_ZERO(denom)) \
+ { \
+ dointersect = 0; \
+ } \
+ else \
+ { \
+ vec3f _n;\
+ _n[0]=p1[3]*p2[0] - p2[3]*p1[0]; \
+ _n[1]=p1[3]*p2[1] - p2[3]*p1[1]; \
+ _n[2]=p1[3]*p2[2] - p2[3]*p1[2]; \
+ VEC_CROSS(p,_n,d); \
+ p[0]/=denom; \
+ p[1]/=denom; \
+ p[2]/=denom; \
+ dointersect = 1; \
+ }\
+}\
+
+//***************** SEGMENT and LINE FUNCTIONS **********************************///
+
+/*! Finds the closest point(cp) to (v) on a segment (e1,e2)
+ */
+#define CLOSEST_POINT_ON_SEGMENT(cp,v,e1,e2) \
+{ \
+ vec3f _n;\
+ VEC_DIFF(_n,e2,e1);\
+ VEC_DIFF(cp,v,e1);\
+ GREAL _scalar = VEC_DOT(cp, _n); \
+ _scalar/= VEC_DOT(_n, _n); \
+ if(_scalar <0.0f)\
+ {\
+ VEC_COPY(cp,e1);\
+ }\
+ else if(_scalar >1.0f)\
+ {\
+ VEC_COPY(cp,e2);\
+ }\
+ else \
+ {\
+ VEC_SCALE(cp,_scalar,_n);\
+ VEC_SUM(cp,cp,e1);\
+ } \
+}\
+
+
+/*! \brief Finds the line params where these lines intersect.
+
+\param dir1 Direction of line 1
+\param point1 Point of line 1
+\param dir2 Direction of line 2
+\param point2 Point of line 2
+\param t1 Result Parameter for line 1
+\param t2 Result Parameter for line 2
+\param dointersect 0 if the lines won't intersect, else 1
+
+*/
+#define LINE_INTERSECTION_PARAMS(dir1,point1, dir2, point2,t1,t2,dointersect) {\
+ GREAL det;\
+ GREAL e1e1 = VEC_DOT(dir1,dir1);\
+ GREAL e1e2 = VEC_DOT(dir1,dir2);\
+ GREAL e2e2 = VEC_DOT(dir2,dir2);\
+ vec3f p1p2;\
+ VEC_DIFF(p1p2,point1,point2);\
+ GREAL p1p2e1 = VEC_DOT(p1p2,dir1);\
+ GREAL p1p2e2 = VEC_DOT(p1p2,dir2);\
+ det = e1e2*e1e2 - e1e1*e2e2;\
+ if(IS_ZERO(det))\
+ {\
+ dointersect = 0;\
+ }\
+ else\
+ {\
+ t1 = (e1e2*p1p2e2 - e2e2*p1p2e1)/det;\
+ t2 = (e1e1*p1p2e2 - e1e2*p1p2e1)/det;\
+ dointersect = 1;\
+ }\
+}\
+
+//! Find closest points on segments
+#define SEGMENT_COLLISION(vA1,vA2,vB1,vB2,vPointA,vPointB)\
+{\
+ vec3f _AD,_BD,_N;\
+ vec4f _M;\
+ VEC_DIFF(_AD,vA2,vA1);\
+ VEC_DIFF(_BD,vB2,vB1);\
+ VEC_CROSS(_N,_AD,_BD);\
+ VEC_CROSS(_M,_N,_BD);\
+ _M[3] = VEC_DOT(_M,vB1);\
+ float _tp; \
+ LINE_PLANE_COLLISION(_M,_AD,vA1,vPointA,_tp,0.0f, 1.0f);\
+ /*Closest point on segment*/ \
+ VEC_DIFF(vPointB,vPointA,vB1);\
+ _tp = VEC_DOT(vPointB, _BD); \
+ _tp/= VEC_DOT(_BD, _BD); \
+ _tp = CLAMP(_tp,0.0f,1.0f); \
+ VEC_SCALE(vPointB,_tp,_BD);\
+ VEC_SUM(vPointB,vPointB,vB1);\
+}\
+
+//! @}
+
+///Additional Headers for Collision
+#include "GIMPACT/gim_tri_collision.h"
+#include "GIMPACT/gim_tri_sphere_collision.h"
+#include "GIMPACT/gim_tri_capsule_collision.h"
+
+#endif // GIM_VECTOR_H_INCLUDED
diff --git a/libs/ode-0.16.1/GIMPACT/include/GIMPACT/gim_math.h b/libs/ode-0.16.1/GIMPACT/include/GIMPACT/gim_math.h
new file mode 100644
index 0000000..97fdad2
--- /dev/null
+++ b/libs/ode-0.16.1/GIMPACT/include/GIMPACT/gim_math.h
@@ -0,0 +1,164 @@
+#ifndef GIM_MATH_H_INCLUDED
+#define GIM_MATH_H_INCLUDED
+
+/*! \file gim_math.h
+\author Francisco León
+*/
+/*
+-----------------------------------------------------------------------------
+This source file is part of GIMPACT Library.
+
+For the latest info, see http://gimpact.sourceforge.net/
+
+Copyright (c) 2006 Francisco Leon. C.C. 80087371.
+email: projectileman@yahoo.com
+
+ 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 GIMPACT-LICENSE-LGPL.TXT.
+ (2) The BSD-style license that is included with this library in
+ the file GIMPACT-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
+ GIMPACT-LICENSE-LGPL.TXT and GIMPACT-LICENSE-BSD.TXT for more details.
+
+-----------------------------------------------------------------------------
+*/
+
+#include "config.h"
+
+#include <math.h>
+#include <float.h>
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#elif defined(_MSC_VER)
+typedef __int32 int32_t;
+typedef unsigned __int32 uint32_t;
+#elif defined(__GNUC__)
+#include <inttypes.h>
+#else
+#error "GIMPACT: Must define int32_t and uint32_t"
+#endif
+
+
+/*! \defgroup BASIC_TYPES
+Basic types and constants
+Conventions:
+Types starting with G
+Constants starting with G_
+*/
+//! @{
+/*! Types */
+#define GREAL float
+#define GINT32 int32_t
+#define GUINT32 uint32_t
+
+#ifdef GPTR
+#undef GPTR
+#endif
+#define GPTR void*
+
+/*! Constants for integers*/
+#define GUINT32_BIT_COUNT 32
+#define GUINT32_EXPONENT 5
+
+#define G_FASTMATH 1
+#define G_PI 3.14159265358979f
+#define G_HALF_PI 1.5707963f
+//267948966
+#define G_TWO_PI 6.28318530f
+//71795864
+#define G_ROOT3 1.73205f
+#define G_ROOT2 1.41421f
+#define G_UINT_INFINITY 65534
+#define G_REAL_INFINITY FLT_MAX
+#define G_SIGN_BITMASK 0x80000000
+#define G_USE_EPSILON_TEST
+#define G_EPSILON 0.0000001f
+//! @}
+
+/*! \defgroup MATH_FUNCTIONS
+mathematical functions
+*/
+//! @{
+#define G_DEGTORAD(X) ((X)*3.1415926f/180.0f)
+#define G_RADTODEG(X) ((X)*180.0f/3.1415926f)
+
+//! Integer representation of a floating-point value.
+#define IR(x) ((GUINT32&)(x))
+
+//! Signed integer representation of a floating-point value.
+#define SIR(x) ((GINT32&)(x))
+
+//! Absolute integer representation of a floating-point value
+#define AIR(x) (IR(x)&0x7fffffff)
+
+//! Floating-point representation of an integer value.
+#define FR(x) ((GREAL&)(x))
+
+#define MAX(a,b) ((a)<(b)?(b):(a))
+#define MIN(a,b) ((a)>(b)?(b):(a))
+
+#define MAX3(a,b,c) MAX(a,MAX(b,c))
+#define MIN3(a,b,c) MIN(a,MIN(b,c))
+
+#define IS_ZERO(value) ((value) < G_EPSILON && (value) > -G_EPSILON)
+
+#define IS_NEGATIVE(value) ((value) <= -G_EPSILON)
+
+#define IS_POSISITVE(value) ((value) >= G_EPSILON)
+
+///returns a clamped number
+#define CLAMP(number,minval,maxval) ((number)<(minval)?(minval):((number)>(maxval)?(maxval):(number)))
+
+///Swap numbers
+#define SWAP_NUMBERS(a,b){ \
+ (a) = (a)+(b); \
+ (b) = (a)-(b); \
+ (a) = (a)-(b); \
+}\
+
+#define GIM_INV_SQRT(va,isva)\
+{\
+ if((va)<=0.0000001f)\
+ {\
+ (isva) = G_REAL_INFINITY;\
+ }\
+ else\
+ {\
+ GREAL _x = (va) * 0.5f;\
+ GUINT32 _y = 0x5f3759df - ( IR(va) >> 1);\
+ (isva) = FR(_y);\
+ (isva) = (isva) * ( 1.5f - ( _x * (isva) * (isva) ) );\
+ }\
+}\
+
+#define GIM_SQRT(va,sva)\
+{\
+ GIM_INV_SQRT(va,sva);\
+ (sva) = 1.0f/(sva);\
+}\
+
+//! Computes 1.0f / sqrtf(x). Comes from Quake3. See http://www.magic-software.com/3DGEDInvSqrt.html
+GREAL gim_inv_sqrt(GREAL f);
+
+//! Computes sqrtf(x) faster.
+/*!
+\sa gim_inv_sqrt
+*/
+GREAL gim_sqrt(GREAL f);
+
+//!Initializes mathematical functions
+void gim_init_math();
+
+//! Generates an unit random
+GREAL gim_unit_random();
+//! @}
+
+#endif // GIM_MATH_H_INCLUDED
diff --git a/libs/ode-0.16.1/GIMPACT/include/GIMPACT/gim_memory.h b/libs/ode-0.16.1/GIMPACT/include/GIMPACT/gim_memory.h
new file mode 100644
index 0000000..d007bda
--- /dev/null
+++ b/libs/ode-0.16.1/GIMPACT/include/GIMPACT/gim_memory.h
@@ -0,0 +1,1056 @@
+#ifndef GIM_MEMORY_H_INCLUDED
+#define GIM_MEMORY_H_INCLUDED
+/*! \file gim_memory.h
+\author Francisco León
+*/
+/*
+-----------------------------------------------------------------------------
+This source file is part of GIMPACT Library.
+
+For the latest info, see http://gimpact.sourceforge.net/
+
+Copyright (c) 2006 Francisco Leon. C.C. 80087371.
+email: projectileman@yahoo.com
+
+ 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 GIMPACT-LICENSE-LGPL.TXT.
+ (2) The BSD-style license that is included with this library in
+ the file GIMPACT-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
+ GIMPACT-LICENSE-LGPL.TXT and GIMPACT-LICENSE-BSD.TXT for more details.
+
+-----------------------------------------------------------------------------
+*/
+
+
+#include "GIMPACT/gim_math.h"
+#include <memory.h>
+
+//#define PREFETCH 1
+//! \defgroup PREFETCH
+//! @{
+#ifdef PREFETCH
+#include <xmmintrin.h> // for prefetch
+#define pfval 64
+#define pfval2 128
+//! Prefetch 64
+#define pf(_x,_i) _mm_prefetch((void *)(_x + _i + pfval), 0)
+//! Prefetch 128
+#define pf2(_x,_i) _mm_prefetch((void *)(_x + _i + pfval2), 0)
+#else
+//! Prefetch 64
+#define pf(_x,_i)
+//! Prefetch 128
+#define pf2(_x,_i)
+#endif
+//! @}
+
+/*! \defgroup ARRAY_UTILITIES
+\brief
+Functions for manip packed arrays of numbers
+*/
+//! @{
+#define GIM_COPY_ARRAYS(dest_array, source_array, element_count)\
+{\
+ GUINT32 _i_;\
+ for (_i_ = 0; _i_ < (element_count); _i_++)\
+ {\
+ (dest_array)[_i_] = (source_array)[_i_];\
+ }\
+}\
+
+#define GIM_COPY_ARRAYS_1(dest_array, source_array, element_count, copy_macro)\
+{\
+ GUINT32 _i_;\
+ for (_i_=0; _i_ < (element_count); _i_++)\
+ {\
+ copy_macro((dest_array)[_i_], (source_array)[_i_]);\
+ }\
+}\
+
+
+#define GIM_ZERO_ARRAY(array, element_count)\
+{\
+ GUINT32 _i_;\
+ for (_i_=0; _i_ < (element_count); _i_++)\
+ {\
+ (array)[_i_] = 0;\
+ }\
+}\
+
+#define GIM_CONSTANT_ARRAY(array, element_count, constant)\
+{\
+ GUINT32 _i_;\
+ for (_i_ = 0; _i_ < (element_count); _i_++)\
+ {\
+ (array)[_i_] = (constant);\
+ }\
+}\
+//! @}
+
+/*! \defgroup MEMORY_FUNCTION_PROTOTYPES
+Function prototypes to allocate and free memory.
+*/
+//! @{
+typedef void * gim_alloc_function (size_t size);
+typedef void * gim_alloca_function (size_t size);//Allocs on the heap
+typedef void * gim_realloc_function (void *ptr, size_t oldsize, size_t newsize);
+typedef void gim_free_function (void *ptr, size_t size);
+//! @}
+
+/*! \defgroup MEMORY_FUNCTION_HANDLERS
+\brief
+Memory Function Handlers
+ set new memory management functions. if fn is 0, the default handlers are
+ used. */
+//! @{
+void gim_set_alloc_handler (gim_alloc_function *fn);
+// void gim_set_alloca_handler (gim_alloca_function *fn); -- a nonsense
+void gim_set_realloc_handler (gim_realloc_function *fn);
+void gim_set_free_handler (gim_free_function *fn);
+//! @}
+
+/*! \defgroup MEMORY_FUNCTION_GET_HANDLERS
+\brief
+get current memory management functions.
+*/
+//! @{
+gim_alloc_function *gim_get_alloc_handler (void);
+// gim_alloca_function *gim_get_alloca_handler(void); -- a nonsense
+gim_realloc_function *gim_get_realloc_handler (void);
+gim_free_function *gim_get_free_handler (void);
+//! @}
+
+/*! \defgroup MEMORY_FUNCTIONS
+Standar Memory functions
+*/
+//! @{
+void * gim_alloc(size_t size);
+// void * gim_alloca(size_t size); -- a nonsense
+void * gim_realloc(void *ptr, size_t oldsize, size_t newsize);
+void gim_free(void *ptr, size_t size);
+//! @}
+
+/*! \defgroup DYNAMIC_ARRAYS
+\brief
+Dynamic Arrays. Allocated from system memory.
+<ul>
+<li> For initializes a dynamic array, use GIM_DYNARRAY_CREATE or GIM_DYNARRAY_CREATE_SIZED.
+<li> When an array is no longer used, must be terminated with the macro GIM_DYNARRAY_DESTROY.
+</ul>
+*/
+//! @{
+#define G_ARRAY_GROW_SIZE 64
+#define G_ARRAY_BUFFERMANAGER_INIT_SIZE 2
+
+//! Dynamic array handle.
+struct GDYNAMIC_ARRAY
+{
+ char * m_pdata;
+ GUINT32 m_size;
+ GUINT32 m_reserve_size;
+};
+//typedef struct _GDYNAMIC_ARRAY GDYNAMIC_ARRAY;
+
+//! Creates a dynamic array zero sized
+#define GIM_DYNARRAY_CREATE(type, array_data, reserve_size) \
+{ \
+ (array_data).m_pdata = (char *)gim_alloc((reserve_size) * sizeof(type)); \
+ (array_data).m_size = 0; \
+ (array_data).m_reserve_size = (reserve_size); \
+} \
+
+//! Creates a dynamic array with n = size elements
+#define GIM_DYNARRAY_CREATE_SIZED(type, array_data, size) \
+{ \
+ (array_data).m_pdata = (char *)gim_alloc((size) * sizeof(type)); \
+ (array_data).m_size = (size); \
+ (array_data).m_reserve_size = (size); \
+} \
+
+//! Reserves memory for a dynamic array.
+#define GIM_DYNARRAY_RESERVE_SIZE(type, array_data, old_size, reserve_size) \
+{ \
+ if ((reserve_size) > (array_data).m_reserve_size) \
+ { \
+ (array_data).m_pdata = (char *) gim_realloc((array_data).m_pdata, (old_size) * sizeof(type), (reserve_size) * sizeof(type)); \
+ (array_data).m_reserve_size = (reserve_size); \
+ } \
+} \
+
+//! Set the size of the array
+#define GIM_DYNARRAY_SET_SIZE(type, array_data, size) \
+{ \
+ GIM_DYNARRAY_RESERVE_SIZE(type, array_data, (array_data).m_size, size); \
+ (array_data).m_size = size; \
+} \
+
+//! Gets a pointer from the beginning of the array
+#define GIM_DYNARRAY_POINTER(type, array_data) ((type *)((array_data).m_pdata))
+
+//! Gets a pointer from the last elemento of the array
+#define GIM_DYNARRAY_POINTER_LAST(type, array_data) (((type *)(array_data).m_pdata) + ((array_data).m_size - 1))
+
+//! Inserts an element at the last position
+#define GIM_DYNARRAY_PUSH_ITEM(type, array_data, item)\
+{ \
+ if ((array_data).m_reserve_size <= (array_data).m_size)\
+ {\
+ GIM_DYNARRAY_RESERVE_SIZE(type, array_data, (array_data).m_size, (array_data).m_size + G_ARRAY_GROW_SIZE); \
+ }\
+ type * _pt = GIM_DYNARRAY_POINTER(type, array_data); \
+ memcpy(&_pt[(array_data).m_size], &(item), sizeof(type)); \
+ (array_data).m_size++; \
+} \
+
+//! Inserts an element at the last position
+#define GIM_DYNARRAY_PUSH_EMPTY(type, array_data) \
+{ \
+ if ((array_data).m_reserve_size <= (array_data).m_size) \
+ { \
+ GIM_DYNARRAY_RESERVE_SIZE(type, array_data, (array_data).m_size, (array_data).m_size + G_ARRAY_GROW_SIZE); \
+ } \
+ (array_data).m_size++; \
+} \
+
+//! Inserts an element
+#define GIM_DYNARRAY_INSERT_ITEM(type, array_data, item, index) \
+{ \
+ if ((array_data).m_reserve_size <= (array_data).m_size) \
+ { \
+ GIM_DYNARRAY_RESERVE_SIZE(type, array_data, (array_data).m_size, (array_data).m_size + G_ARRAY_GROW_SIZE); \
+ } \
+ type * _pt = GIM_DYNARRAY_POINTER(type, array_data); \
+ if ((index) < (array_data).m_size - 1) \
+ { \
+ memmove(&_pt[(index) + 1], &_pt[(index)], ((array_data).m_size - (index)) * sizeof(type)); \
+ } \
+ memcpy(&_pt[(index)], &(item), sizeof(type)); \
+ array_data.m_size++; \
+} \
+
+//! Removes an element
+#define GIM_DYNARRAY_DELETE_ITEM(type, array_data, index) \
+{ \
+ if ((index) < (array_data).m_size - 1) \
+ { \
+ type * _pt = GIM_DYNARRAY_POINTER(type, array_data);\
+ memmove(&_pt[(index)], &_pt[(index) + 1], ((array_data).m_size - (index) - 1) * sizeof(type)); \
+ } \
+ (array_data).m_size--; \
+} \
+
+//! Removes an element at the last position
+#define GIM_DYNARRAY_POP_ITEM(array_data) \
+{ \
+ if ((array_data).m_size > 0) \
+ { \
+ (array_data).m_size--; \
+ } \
+}\
+
+//! Destroys the array
+void GIM_DYNARRAY_DESTROY(GDYNAMIC_ARRAY & array_data);
+//! @}
+
+/*! \defgroup BITSET
+\brief
+Bitsets , based on \ref DYNAMIC_ARRAYS .
+<ul>
+<li> For initializes a bitset array, use \ref GIM_BITSET_CREATE or \ref GIM_BITSET_CREATE_SIZED.
+<li> When the bitset is no longer used, must be terminated with the macro \ref GIM_DYNARRAY_DESTROY.
+<li> For putting a mark on the bitset, call \ref GIM_BITSET_SET
+<li> For clearing a mark on the bitset, call \ref GIM_BITSET_CLEAR
+<li> For retrieving a bit value from a bitset, call \ref GIM_BITSET_GET-
+</ul>
+*/
+//! @{
+
+//! Creates a bitset
+#define GIM_BITSET_CREATE(array_data) GIM_DYNARRAY_CREATE(GUINT32, array_data, G_ARRAY_GROW_SIZE)
+
+//! Creates a bitset, with their bits set to 0.
+#define GIM_BITSET_CREATE_SIZED(array_data, bits_count) \
+{ \
+ GUINT32 array_size = (bits_count) / GUINT32_BIT_COUNT + 1; \
+ GIM_DYNARRAY_CREATE(GUINT32, array_data, array_size); \
+ GUINT32 * _pt = GIM_DYNARRAY_POINTER(GUINT32, array_data); \
+ memset(_pt, 0, sizeof(GUINT32) * ((array_data).m_size)); \
+} \
+
+//! Gets the bitset bit count.
+#define GIM_BITSET_SIZE(array_data) ((array_data).m_size * GUINT32_BIT_COUNT)
+
+//! Resizes a bitset, with their bits set to 0.
+#define GIM_BITSET_RESIZE(array_data, new_bits_count) \
+{ \
+ GUINT32 _oldsize = (array_data).m_size; \
+ (array_data).m_size = (new_bits_count) / GUINT32_BIT_COUNT + 1; \
+ if (_oldsize < (array_data).m_size) \
+ { \
+ if ((array_data).m_size > (array_data).m_reserve_size) \
+ { \
+ GIM_DYNARRAY_RESERVE_SIZE(GUINT32, array_data, _oldsize, (array_data).m_size + G_ARRAY_GROW_SIZE); \
+ } \
+ GUINT32 * _pt = GIM_DYNARRAY_POINTER(GUINT32, array_data); \
+ memset(&_pt[_oldsize], 0, sizeof(GUINT32) * ((array_data).m_size - _oldsize)); \
+ } \
+} \
+
+//! Sets all bitset bit to 0.
+#define GIM_BITSET_CLEAR_ALL(array_data) \
+{ \
+ memset((array_data).m_pdata, 0, sizeof(GUINT32) * (array_data).m_size); \
+} \
+
+//! Sets all bitset bit to 1.
+#define GIM_BITSET_SET_ALL(array_data) \
+{ \
+ memset((array_data).m_pdata, 0xFF, sizeof(GUINT32) * (array_data).m_size); \
+} \
+
+///Sets the desired bit to 1
+#define GIM_BITSET_SET(array_data, bit_index) \
+{ \
+ if ((bit_index) >= GIM_BITSET_SIZE(array_data)) \
+ { \
+ GIM_BITSET_RESIZE(array_data, bit_index); \
+ } \
+ GUINT32 * _pt = GIM_DYNARRAY_POINTER(GUINT32, array_data); \
+ _pt[(bit_index) >> GUINT32_EXPONENT] |= (1 << ((bit_index) & (GUINT32_BIT_COUNT - 1))); \
+} \
+
+///Return 0 or 1
+#define GIM_BITSET_GET(array_data, bit_index, get_value) \
+{ \
+ if ((bit_index) >= GIM_BITSET_SIZE(array_data)) \
+ { \
+ (get_value) = 0; \
+ } \
+ else \
+ { \
+ GUINT32 * _pt = GIM_DYNARRAY_POINTER(GUINT32, array_data); \
+ (get_value) = _pt[(bit_index) >> GUINT32_EXPONENT] & (1 << ((bit_index) & (GUINT32_BIT_COUNT - 1))); \
+ } \
+} \
+
+///Sets the desired bit to 0
+#define GIM_BITSET_CLEAR(array_data, bit_index) \
+{ \
+ if ((bit_index) < GIM_BITSET_SIZE(array_data)) \
+ { \
+ GUINT32 * _pt = GIM_DYNARRAY_POINTER(GUINT32, array_data); \
+ _pt[(bit_index) >> GUINT32_EXPONENT] &= ~(1 << ((bit_index) & (GUINT32_BIT_COUNT - 1))); \
+ } \
+} \
+//! @}
+
+/*! \defgroup MEMORY_ACCESS_CONSTANTS
+\brief
+Memory Access constants.
+\sa BUFFERS
+*/
+//! @{
+#define G_MA_READ_ONLY 1
+#define G_MA_WRITE_ONLY 2
+#define G_MA_READ_WRITE 3
+//! @}
+
+/*! \defgroup MEMORY_USAGE_CONSTANTS
+\brief
+Memory usage constants.
+\sa BUFFERS
+*/
+//! @{
+/// Don't care how memory is used
+#define G_MU_EITHER 0
+/// specified once, doesn't allow read information
+#define G_MU_STATIC_WRITE 1
+/// specified once, allows to read information from a shadow buffer
+#define G_MU_STATIC_READ 2
+/// write directly on buffer, allows to read information from a shadow buffer
+#define G_MU_STATIC_READ_DYNAMIC_WRITE 3
+/// upload data to buffer from the shadow buffer, allows to read information from a shadow buffer
+#define G_MU_STATIC_READ_DYNAMIC_WRITE_COPY 4
+/// specified once, allows to read information directly from memory
+#define G_MU_STATIC_WRITE_DYNAMIC_READ 5
+/// write directly on buffer, allows to read information directly from memory
+#define G_MU_DYNAMIC_READ_WRITE 6
+//! @}
+
+/*! \defgroup BUFFER_ERRORS
+\brief
+Buffer operation errors
+\sa BUFFERS
+*/
+//! @{
+#define G_BUFFER_OP_SUCCESS 0
+#define G_BUFFER_OP_INVALID 1
+#define G_BUFFER_OP_STILLREFCOUNTED 2
+//! @}
+
+/*! \defgroup BUFFER_MANAGER_IDS
+\brief
+Buffer manager identifiers
+\sa BUFFERS, BUFFER_MANAGERS
+*/
+//! @{
+enum
+{
+ G_BUFFER_MANAGER_SYSTEM,
+ G_BUFFER_MANAGER_SHARED,
+
+ G_BUFFER_MANAGER__MAX
+};
+//! @}
+
+/*! \defgroup BUFFERS
+\brief
+Buffer operations and structs.
+<ul>
+<li> Before using buffers you must initializes GIMPACT buffer managers by calling \ref gimpact_init.
+<li> For initializes a buffer, use \ref gim_create_buffer, \ref gim_create_buffer_from_data , \ref gim_create_common_buffer, \ref gim_create_common_buffer_from_data or \ref gim_create_shared_buffer_from_data.
+<li> For accessing to the buffer memory, you must call \ref gim_lock_buffer, and then \ref gim_unlock_buffer for finish the access.
+<li> When a buffer is no longer needed, you must free it by calling \ref gim_buffer_free.
+<li> You must call \ref gimpact_terminate when finish your application.
+<li> For a safe manipulation of buffers, use \ref BUFFER_ARRAYS
+</ul>
+\sa BUFFER_MANAGERS, BUFFER_ARRAYS
+*/
+//! @{
+
+struct GBUFFER_MANAGER_DATA;
+
+//! Buffer handle.
+struct GBUFFER_ID
+{
+ GBUFFER_MANAGER_DATA * m_bm_data;
+ GUINT32 m_buffer_id;
+};
+//typedef struct _GBUFFER_ID GBUFFER_ID;
+
+//! Buffer internal data
+struct GBUFFER_DATA
+{
+ GPTR m_buffer_handle;//!< if 0, buffer doesn't exists
+ GUINT32 m_size;
+ GUINT32 m_usage;
+ GINT32 m_access;
+ GUINT32 m_lock_count;
+ char * m_mapped_pointer;
+ GBUFFER_ID m_shadow_buffer;
+ GUINT32 m_refcount;//! Reference counting for safe garbage collection
+};
+//typedef struct _GBUFFER_DATA GBUFFER_DATA;
+//! @}
+
+/*! \defgroup BUFFERS_MANAGER_PROTOTYPES
+\brief
+Function prototypes to allocate and free memory for buffers
+\sa BUFFER_MANAGERS, BUFFERS
+*/
+//! @{
+
+//! Returns a Buffer handle
+typedef GPTR gim_buffer_alloc_function(GUINT32 size,int usage);
+
+//! Returns a Buffer handle, and copies the pdata to the buffer
+typedef GPTR gim_buffer_alloc_data_function(const void * pdata,GUINT32 size,int usage);
+
+//! Changes the size of the buffer preserving the content, and returns the new buffer id
+typedef GPTR gim_buffer_realloc_function(GPTR buffer_handle,GUINT32 oldsize,int old_usage,GUINT32 newsize,int new_usage);
+
+//! It changes the m_buffer_handle member to 0/0
+typedef void gim_buffer_free_function(GPTR buffer_handle,GUINT32 size);
+
+//! It maps the m_mapped_pointer. Returns a pointer
+typedef char * gim_lock_buffer_function(GPTR buffer_handle,int access);
+
+//! It sets the m_mapped_pointer to 0
+typedef void gim_unlock_buffer_function(GPTR buffer_handle);
+
+typedef void gim_download_from_buffer_function(
+ GPTR source_buffer_handle,
+ GUINT32 source_pos,
+ void * destdata,
+ GUINT32 copysize);
+
+typedef void gim_upload_to_buffer_function(
+ GPTR dest_buffer_handle,
+ GUINT32 dest_pos,
+ void * sourcedata,
+ GUINT32 copysize);
+
+typedef void gim_copy_buffers_function(
+ GPTR source_buffer_handle,
+ GUINT32 source_pos,
+ GPTR dest_buffer_handle,
+ GUINT32 dest_pos,
+ GUINT32 copysize);
+//! @}
+
+
+/*! \defgroup BUFFER_MANAGERS
+\brief
+Buffer Manager operations
+*/
+//! @{
+//! Buffer manager prototype
+struct GBUFFER_MANAGER_PROTOTYPE
+{
+ gim_buffer_alloc_function * alloc_fn;
+ gim_buffer_alloc_data_function *alloc_data_fn;
+ gim_buffer_realloc_function * realloc_fn;
+ gim_buffer_free_function * free_fn;
+ gim_lock_buffer_function * lock_buffer_fn;
+ gim_unlock_buffer_function * unlock_buffer_fn;
+ gim_download_from_buffer_function * download_from_buffer_fn;
+ gim_upload_to_buffer_function * upload_to_buffer_fn;
+ gim_copy_buffers_function * copy_buffers_fn;
+};
+//typedef struct _GBUFFER_MANAGER_PROTOTYPE GBUFFER_MANAGER_PROTOTYPE;
+
+//! Buffer manager
+struct GBUFFER_MANAGER_DATA
+{
+ GDYNAMIC_ARRAY m_buffer_array;//!< Array of GBUFFER_DATA objects
+ GDYNAMIC_ARRAY m_free_positions;//!< Array of GUINT elements. Free positions
+ const GBUFFER_MANAGER_PROTOTYPE *m_prototype;//!< Prototype of functions
+ GUINT32 m_buffer_manager_id;//!< Buffer manager id
+};
+//typedef struct _GBUFFER_MANAGER_DATA GBUFFER_MANAGER_DATA;
+
+//! Checks if buffer manager is used
+int gim_is_buffer_manager_active(GBUFFER_MANAGER_DATA buffer_managers[],
+ GUINT32 buffer_manager_id);
+//! Adds a buffer Manager to the Memory Singleton
+void gim_create_buffer_manager(GBUFFER_MANAGER_DATA buffer_managers[],
+ GUINT32 buffer_manager_id);
+//! Destroys a buffer manager
+void gim_destroy_buffer_manager(GBUFFER_MANAGER_DATA buffer_managers[], GUINT32 buffer_manager_id);
+void gim_get_buffer_manager_data(GBUFFER_MANAGER_DATA buffer_managers[],
+ GUINT32 buffer_manager_id,GBUFFER_MANAGER_DATA ** pbm_data);
+void gim_init_buffer_managers(GBUFFER_MANAGER_DATA buffer_managers[]);
+void gim_terminate_buffer_managers(GBUFFER_MANAGER_DATA buffer_managers[]);
+
+//! @}
+
+
+/*! \addtogroup BUFFERS
+*/
+//! @{
+
+//!Creates a buffer on the buffer manager specified by buffer_manager_id
+/*!
+\param buffer_manager_id
+\param buffer_size
+\param usage An usage constant. Use G_MU_DYNAMIC_READ_WRITE as default.
+\param buffer_id a pointer for receive the new buffer id
+\return An error code. 0 if success.
+\post m_refcount = 0
+*/
+GUINT32 gim_create_buffer(
+ GBUFFER_MANAGER_DATA buffer_managers[],
+ GUINT32 buffer_manager_id,
+ GUINT32 buffer_size,
+ int usage,
+ GBUFFER_ID * buffer_id);
+
+//!Creates a buffer on the buffer manager specified by buffer_manager_id
+/*!
+\param buffer_manager_id
+\param pdata Data for allocating
+\param buffer_size Size of the data buffer
+\param usage An usage constant. Use G_MU_DYNAMIC_READ_WRITE as default.
+\param buffer_id a pointer for receive the new buffer id
+\return An error code. 0 if success.
+\post m_refcount = 0
+*/
+GUINT32 gim_create_buffer_from_data(
+ GBUFFER_MANAGER_DATA buffer_managers[],
+ GUINT32 buffer_manager_id,
+ const void * pdata,
+ GUINT32 buffer_size,
+ int usage,
+ GBUFFER_ID * buffer_id);
+
+//!Allocates on the G_BUFFER_MANAGER_SYSTEM
+GUINT32 gim_create_common_buffer(GBUFFER_MANAGER_DATA buffer_managers[],
+ GUINT32 buffer_size, GBUFFER_ID * buffer_id);
+//!Allocates on the G_BUFFER_MANAGER_SYSTEM, and copies the data
+GUINT32 gim_create_common_buffer_from_data(GBUFFER_MANAGER_DATA buffer_managers[],
+ const void * pdata, GUINT32 buffer_size, GBUFFER_ID * buffer_id);
+//!Creates a buffer with shared data
+GUINT32 gim_create_shared_buffer_from_data(GBUFFER_MANAGER_DATA buffer_managers[],
+ const void * pdata, GUINT32 buffer_size, GBUFFER_ID * buffer_id);
+
+
+//! Add reference counting to buffer.
+GINT32 gim_buffer_add_ref(GBUFFER_ID * buffer_id);
+
+//! Function for resize buffer, preserving the content
+/*!
+\param buffer_id
+\param newsize
+\return An error code. 0 if success.
+\post If m_refcount>0 then it decrements it.
+*/
+GINT32 gim_buffer_realloc(GBUFFER_ID * buffer_id,GUINT32 newsize);
+
+//! Eliminates the buffer.
+/*!
+If the buffer reference counting is <= 1 and is unlocked, then it eliminates the buffer.
+*/
+GINT32 gim_buffer_free(GBUFFER_ID * buffer_id);
+
+//! Locks the buffer for memory access.
+/*!
+\param buffer_id Id from buffer.
+\param access Must have the following values: G_MA_READ_ONLY,G_MA_WRITE_ONLY or G_MA_READ_WRITE.
+\param map_pointer Dest Pointer of the memory address from buffer.
+\post m_lock_count increases.
+*/
+GINT32 gim_lock_buffer(GBUFFER_ID * buffer_id,int access,char ** map_pointer);
+
+//! Unlocks the buffer for memory access.
+GINT32 gim_unlock_buffer(GBUFFER_ID * buffer_id);
+
+//! Gets the buffer size in bytes
+GINT32 gim_get_buffer_size(GBUFFER_ID * buffer_id,GUINT32 * buffer_size);
+
+//! Determines if the buffer is locked
+GINT32 gim_get_buffer_is_locked(GBUFFER_ID * buffer_id,GUINT32 * lock_count);
+
+//! Copies the content of the buffer to a dest pointer
+GINT32 gim_download_from_buffer(
+ GBUFFER_ID * buffer_id,
+ GUINT32 source_pos,
+ void * destdata,
+ GUINT32 copysize);
+
+//! Copies the content of a memory pointer to the buffer
+GINT32 gim_upload_to_buffer(
+ GBUFFER_ID * buffer_id,
+ GUINT32 dest_pos,
+ void * sourcedata,
+ GUINT32 copysize);
+
+//! Copies two buffers.
+GINT32 gim_copy_buffers(
+ GBUFFER_ID * source_buffer_id,
+ GUINT32 source_pos,
+ GBUFFER_ID * dest_buffer_id,
+ GUINT32 dest_pos,
+ GUINT32 copysize);
+//! @}
+
+
+/*! \defgroup BUFFER_ARRAYS
+
+\brief
+Buffered Arrays, for manip elements on a buffer and treat it as an array.
+<ul>
+<li> Before using buffer arrays you must initializes GIMPACT buffer managers by calling gimpact_init.
+<li> Before creating buffer arrays, you must create a buffer. see \ref BUFFERS.
+<li> Create a buffer narray by calling \ref GIM_BUFFER_ARRAY_INIT_TYPE, \ref GIM_BUFFER_ARRAY_INIT_TYPE_OFFSET or \ref GIM_BUFFER_ARRAY_INIT_OFFSET_STRIDE.
+<li> For accessing to the array elements, you must call \ref gim_buffer_array_lock, and then \ref gim_buffer_array_unlock for finish the access.
+<li> When a buffer array is no longer needed, you must free it by calling \ref GIM_BUFFER_ARRAY_DESTROY.
+</ul>
+The following example shows how Buffer arrays can be used:
+
+\code
+int main()
+{
+ //init gimpact
+ gimpact_init();
+
+ //Buffer handle to use
+ GBUFFER_ID bufferhandle;
+
+ //Create a memory buffer of 100 float numbers
+ gim_create_common_buffer(100*sizeof(float), &bufferhandle);
+
+ //Create a buffer array from the bufferhandle
+ GBUFFER_ARRAY buffer_float_array;
+ GIM_BUFFER_ARRAY_INIT_TYPE(float,buffer_float_array,bufferhandle,100);
+
+ ////Access to the buffer data, set all elements of the array
+
+ int i, count;
+ count = buffer_float_array.m_element_count;
+ //Locks the array
+ gim_buffer_array_lock(&buffer_float_array,G_MA_READ_WRITE);
+ float * pelements = GIM_BUFFER_ARRAY_POINTER(float, buffer_float_array, 0); // A pointer to the buffer memory
+
+ //fill the array with random numbers
+ for (i = 0;i < count;i++ )
+ {
+ pelements[i] = gim_unit_random();
+ }
+ //unlock buffer
+ gim_buffer_array_unlock(&buffer_float_array);
+
+ //Program code
+ ....
+ ....
+
+ //Destroy array
+ GIM_BUFFER_ARRAY_DESTROY(buffer_float_array);
+
+ //terminate gimpact
+ gimpact_terminate();
+}
+\endcode
+
+\sa BUFFERS
+*/
+//! @{
+
+//! Buffer managed array struct.
+struct GBUFFER_ARRAY
+{
+ GBUFFER_ID m_buffer_id;
+ char * m_buffer_data;
+ char m_byte_stride;
+ GUINT32 m_byte_offset;
+ GUINT32 m_element_count;
+};
+//typedef struct _GBUFFER_ARRAY GBUFFER_ARRAY;
+
+//! Sets offset for a buffered array.
+#define GIM_BUFFER_ARRAY_SET_OFFSET(_array_data,_offset) (_array_data).m_byte_offset = (_offset)*(_array_data).m_byte_stride;
+
+//! Sets offset for a buffered array.
+#define GIM_BUFFER_ARRAY_GET_OFFSET(_array_data,_offset) (_offset) = (_array_data).m_byte_offset/(_array_data).m_byte_stride;
+
+//!Return a pointer of the element at the _index
+#define GIM_BUFFER_ARRAY_POINTER(_type,_array_data,_index) (_type *)((_array_data).m_buffer_data + (_index)*(_array_data).m_byte_stride)
+
+//! Sets stride for a buffered array.
+#define GIM_BUFFER_ARRAY_SET_STRIDE(_type,_array_data) (_array_data).m_byte_stride = sizeof(_type);
+
+//! Is array stride equal to the size of the type ?
+#define GIM_BUFFER_ARRAY_IS_ALIGNED(_type,_array_data) ((_array_data).m_byte_stride == sizeof(_type))
+
+///Verify if two arrays have the same data
+#define GIM_BUFFER_ARRAY_ARE_SAME(_array_data1,_array_data2,aresame) \
+{ \
+ (aresame) = 1; \
+ if ((_array_data1).m_buffer_id.m_buffer_id != (_array_data2).m_buffer_id.m_buffer_id || (_array_data1).m_buffer_id.m_buffer_manager_id != (_array_data2).m_buffer_id.m_buffer_manager_id || (_array_data1).m_byte_offset != (_array_data2).m_byte_offset) \
+ { \
+ (aresame) = 0; \
+ } \
+} \
+
+//! Reserve size for a buffered array.
+/*!
+\pre array_data must be unlocked, and must be the aligned (GIM_BUFFER_ARRAY_IS_ALIGNED )
+*/
+#define GIM_BUFFER_ARRAY_RESERVE_SIZE(type, array_data, reserve_size) \
+{ \
+ if ((reserve_size) > (array_data).m_element_count) \
+ { \
+ GUINT32 _buffer_size, _newarray_size; \
+ gim_get_buffer_size(&(array_data).m_buffer_id, _buffer_size); \
+ _newarray_size = (reserve_size) * (array_data).m_byte_stride; \
+ if(_newarray_size > _buffer_size) \
+ { \
+ _newarray_size += G_ARRAY_GROW_SIZE * (array_data).m_byte_stride; \
+ gim_buffer_realloc(&(array_data).m_buffer_id, _newarray_size); \
+ } \
+ } \
+} \
+
+//! Pushes an element at last position
+/*!
+\pre array_data must be unlocked, and must be the aligned (GIM_BUFFER_ARRAY_IS_ALIGNED )
+*/
+#define GIM_BUFFER_ARRAY_PUSH_ITEM(type, array_data, item) \
+{ \
+ GIM_BUFFER_ARRAY_RESERVE_SIZE(type, array_data, (array_data).m_element_count + 1); \
+ gim_buffer_array_lock(&(array_data), G_MA_WRITE_ONLY); \
+ type * _pt = GIM_BUFFER_ARRAY_POINTER(type, array_data, (array_data).m_element_count); \
+ memcpy(_pt, &(item), sizeof(type)); \
+ gim_buffer_array_unlock(&(array_data)); \
+ (array_data)->m_element_count++; \
+} \
+
+//! Pushes a new element at last position
+/*!
+\pre array_data must be unlocked, and must be the aligned (GIM_BUFFER_ARRAY_IS_ALIGNED )
+*/
+#define GIM_BUFFER_ARRAY_PUSH_EMPTY(type, array_data) \
+{\
+ GIM_BUFFER_ARRAY_RESERVE_SIZE(type, array_data, (array_data).m_element_count + 1); \
+ (array_data)->m_element_count++; \
+}\
+
+//! Inserts an element
+/*!
+\pre array_data must be unlocked, and must be the aligned (GIM_BUFFER_ARRAY_IS_ALIGNED )
+*/
+#define GIM_BUFFER_ARRAY_INSERT_ITEM(type, array_data, item, index) \
+{ \
+ GIM_BUFFER_ARRAY_RESERVE_SIZE(type, array_data, (array_data).m_element_count + 1); \
+ gim_buffer_array_lock(&(array_data), G_MA_WRITE_ONLY); \
+ type * _pt = GIM_BUFFER_ARRAY_POINTER(type, array_data, 0); \
+ if ((index) < (array_data)->m_element_count - 1) \
+ { \
+ memmove(&_pt[(index) + 1], &_pt[(index)], ((array_data).m_element_count - (index)) * sizeof(type)); \
+ } \
+ memcpy(&_pt[(index)], &(item), sizeof(type)); \
+ gim_buffer_array_unlock(&(array_data)); \
+ (array_data).m_element_count++; \
+} \
+
+//! Deletes an element
+/*!
+\pre array_data must be unlocked, and must be the aligned (GIM_BUFFER_ARRAY_IS_ALIGNED )
+*/
+#define GIM_BUFFER_ARRAY_DELETE_ITEM(type, array_data, index) \
+{ \
+ if ((index) < (array_data).m_element_count - 1) \
+ { \
+ gim_buffer_array_lock(&(array_data), G_MA_WRITE_ONLY); \
+ type * _pt = GIM_BUFFER_ARRAY_POINTER(type, array_data, 0); \
+ memmove(&_pt[(index)], &_pt[(index) + 1],((array_data).m_element_count - (index) - 1) * sizeof(type)); \
+ gim_buffer_array_unlock(&(array_data)); \
+ } \
+ (array_data).m_element_count--; \
+} \
+
+//! Deletes an element at last position
+/*!
+\pre array_data must be unlocked, and must be the aligned (GIM_BUFFER_ARRAY_IS_ALIGNED )
+*/
+#define GIM_BUFFER_ARRAY_POP_ITEM(array_data) \
+{ \
+ if ((array_data).m_element_count > 0) \
+ { \
+ (array_data).m_element_count--; \
+ } \
+} \
+
+
+//! Initializes an GBUFFER_ARRAY object from a buffer ID
+/*!
+m_buffer_data will be 0, for acces to the elements, you'd need to call lock_array
+\param array_data Array structure to be filled
+\param buffer_id A GBUFFER_ID structure which this array_daya will refer to
+\param element_count Number of elements
+\param offset element offset, it isn't byte offset. 0 is recomended
+\param byte_stride size of each element. 0 is recomended.
+\post Adds reference to the buffer
+\sa gim_buffer_add_ref
+*/
+#define GIM_BUFFER_ARRAY_INIT_OFFSET_STRIDE(array_data, buffer_id, element_count, offset, byte_stride) \
+{ \
+ (array_data).m_buffer_id.m_buffer_id = (buffer_id).m_buffer_id; \
+ (array_data).m_buffer_id.m_buffer_manager_id = (buffer_id).m_buffer_manager_id; \
+ (array_data).m_buffer_data = 0; \
+ (array_data).m_element_count = (element_count); \
+ (array_data).m_byte_stride = (byte_stride); \
+ GIM_BUFFER_ARRAY_SET_OFFSET(array_data, offset); \
+ gim_buffer_add_ref(&(buffer_id)); \
+} \
+
+//! Initializes an GBUFFER_ARRAY object from a buffer ID and a Given type
+/*!
+m_buffer_data will be 0, for acces to the elements, you'd need to call lock_array
+\param type Type of the Array. It determines the stride.
+\param array_data Array structure to be filled
+\param buffer_id A GBUFFER_ID structure which this array_daya will refer to
+\param element_count Number of elements
+\param offset element offset, it isn't byte offset. 0 is recomended
+\post Adds reference to the buffer
+\sa gim_buffer_add_ref
+*/
+#define GIM_BUFFER_ARRAY_INIT_TYPE_OFFSET(type, array_data, buffer_id, element_count, offset) \
+{ \
+ (array_data).m_buffer_id.m_buffer_id = (buffer_id).m_buffer_id; \
+ (array_data).m_buffer_id.m_bm_data = (buffer_id).m_bm_data; \
+ (array_data).m_buffer_data = 0; \
+ (array_data).m_element_count = (element_count);\
+ GIM_BUFFER_ARRAY_SET_STRIDE(type, array_data); \
+ GIM_BUFFER_ARRAY_SET_OFFSET(array_data, offset); \
+ gim_buffer_add_ref(&(buffer_id)); \
+}\
+
+//! Initializes a buffer array giving a data type and a buffer id
+/*!
+m_buffer_data will be 0, for acces to the elements, you'd need to call lock_array.
+\param type Type of the Array. It determines the stride.
+\param array_data Array structure to be filled
+\param buffer_id A GBUFFER_ID structure which this array_daya will refer to
+\param element_count Number of elements
+\post Adds reference to the buffer
+\sa gim_buffer_add_ref
+*/
+#define GIM_BUFFER_ARRAY_INIT_TYPE(type, array_data, buffer_id, element_count) GIM_BUFFER_ARRAY_INIT_TYPE_OFFSET(type, array_data, buffer_id, element_count, 0)
+
+//! Gain access to the array buffer through the m_buffer_data element
+/*!
+m_buffer_data pointer will be located at the m_byte_offset position of the buffer m_buffer
+Then, You'd need to call unlock_array when finish to using the array access.
+
+\pre if m_buffer_data != 0, the function returns
+\param array_data Array structure to be locked
+\param access A constant for access to the buffer. can be G_MA_READ_ONLY,G_MA_WRITE_ONLY or G_MA_READ_WRITE
+\return an Buffer error code
+*/
+GINT32 gim_buffer_array_lock(GBUFFER_ARRAY * array_data, int access);
+
+//! close the access to the array buffer through the m_buffer_data element
+/*!
+\param array_data Array structure to be locked
+\return an Buffer error code
+*/
+GINT32 gim_buffer_array_unlock(GBUFFER_ARRAY * array_data);
+
+//! Copy an array by reference
+/*!
+\post A reference to the m_buffer_id is increased.
+*/
+void gim_buffer_array_copy_ref(GBUFFER_ARRAY * source_data,GBUFFER_ARRAY * dest_data);
+
+
+//! Copy an array by value
+/*!
+\post A new buffer is created
+*/
+void gim_buffer_array_copy_value(GBUFFER_ARRAY * source_data,
+ GBUFFER_MANAGER_DATA dest_buffer_managers[],GBUFFER_ARRAY * dest_data,
+ GUINT32 buffer_manager_id,int usage);
+
+//! Destroys an GBUFFER_ARRAY object
+/*!
+\post Attemps to destroy the buffer, decreases reference counting
+*/
+void GIM_BUFFER_ARRAY_DESTROY(GBUFFER_ARRAY & array_data);
+
+//! Copy the content of the array to a pointer
+/*!
+\pre dest_data must have the same size as the array_data
+\param type
+\param array_data A GBUFFERED_ARRAY structure
+\param dest_data A type pointer
+*/
+#define GIM_BUFFER_ARRAY_DOWNLOAD(type,array_data,dest_data) \
+{ \
+ if (GIM_BUFFER_ARRAY_IS_ALIGNED(type, array_data)) \
+ { \
+ gim_download_from_buffer(&(array_data).m_buffer_id, (array_data).m_byte_offset, (void *)(dest_data), (array_data).m_element_count * (array_data).m_byte_stride); \
+ } \
+ else \
+ { \
+ GUINT32 _k_, _ecount_= (array_data).m_element_count; \
+ type * _source_vert_; \
+ type * _dest_vert_ = (dest_data); \
+ gim_buffer_array_lock(&(array_data), G_MA_READ_ONLY); \
+ for (_k_ = 0; _k_ < _ecount_; _k_++) \
+ { \
+ _source_vert_ = GIM_BUFFER_ARRAY_POINTER(type, array_data, _k_); \
+ memcpy(_dest_vert_, _source_vert_, sizeof(type)); \
+ _dest_vert_++; \
+ } \
+ gim_buffer_array_unlock(&(array_data)); \
+ } \
+} \
+
+//! Upload the content of a a pointer to a buffered array
+/*!
+\pre source_data must have the same size as the array_data
+\param type
+\param array_data A GBUFFERED_ARRAY structure
+\param source_data A void pointer
+*/
+#define GIM_BUFFER_ARRAY_UPLOAD(type, array_data, source_data) \
+{ \
+ if (GIM_BUFFER_ARRAY_IS_ALIGNED(type, array_data)) \
+ { \
+ gim_upload_to_buffer(&(array_data).m_buffer_id, (array_data).m_byte_offset, (void *)(source_data), (array_data).m_element_count * (array_data).m_byte_stride); \
+ } \
+ else \
+ { \
+ GUINT32 _k_, _ecount_= (array_data).m_element_count; \
+ type * _source_vert_ = (source_data); \
+ type * _dest_vert_; \
+ gim_buffer_array_lock(&(array_data), G_MA_WRITE_ONLY); \
+ for (_k_ = 0; _k_ < _ecount_; _k_++) \
+ { \
+ _dest_vert_ = GIM_BUFFER_ARRAY_POINTER(type, array_data, _k_); \
+ memcpy(_dest_vert_, _source_vert_, sizeof(type)); \
+ _source_vert_++; \
+ } \
+ gim_buffer_array_unlock(&(array_data)); \
+ } \
+} \
+
+
+//!Kernel function prototype for process streams, given a buffered array as source and
+/*!
+\param 1 the uniform arguments
+\param 2 the source stream
+\param 3 the destination stream
+*/
+typedef void (* gim_kernel_func)(void *,GBUFFER_ARRAY *,GBUFFER_ARRAY *);
+
+//! Generic Stream Processingp loop
+/*!
+
+This macro executes a kernel macro or function for each element of the streams
+\pre _src_array->m_count <= _dst_array->m_count
+
+\param _uniform_data An argument to be passed to the Kernel function
+\param _src_array An GBUFFER_ARRAY structure passed as the source stream
+\param _dst_array An GBUFFER_ARRAY structure passed as the source stream
+\param _kernel Macro or function of the kernel
+\param _src_type Required. Type of all elements of the source stream
+\param _dst_type Required. Type of all elements of the dest stream
+*/
+#define GIM_PROCESS_BUFFER_ARRAY(_uniform_data, _src_array, _dst_array, _kernel, _src_type, _dst_type) \
+{ \
+\
+ gim_buffer_array_lock(&(_src_array), G_MA_READ_ONLY); \
+ gim_buffer_array_lock(&(_dst_array), G_MA_WRITE_ONLY); \
+\
+ GUINT32 _i_, _count_=(_src_array).m_element_count; \
+\
+ _src_type * _source_vert_; \
+ _dst_type * _dest_vert_; \
+ if (GIM_BUFFER_ARRAY_IS_ALIGNED(_src_type, _src_array) && GIM_BUFFER_ARRAY_IS_ALIGNED(_dst_type, _dst_array)) \
+ { \
+\
+ _source_vert_ = GIM_BUFFER_ARRAY_POINTER(_src_type, _src_array, 0); \
+ _dest_vert_ = GIM_BUFFER_ARRAY_POINTER(_dst_type, _dst_array, 0); \
+ for (_i_ = 0;_i_< _count_; _i_++) \
+ { \
+ _kernel(_uniform_data, *_source_vert_, *_dest_vert_); \
+ _source_vert_++; \
+ _dest_vert_++; \
+ } \
+ } \
+ else \
+ { \
+ for (_i_ = 0; _i_ < _count_; _i_++) \
+ { \
+ _source_vert_ = GIM_BUFFER_ARRAY_POINTER(_src_type, _src_array, _i_); \
+ _dest_vert_ = GIM_BUFFER_ARRAY_POINTER(_dst_type, _dst_array, _i_); \
+ _kernel(_uniform_data, *_source_vert_, *_dest_vert_); \
+ } \
+ } \
+ gim_buffer_array_unlock(&(_src_array)); \
+ gim_buffer_array_unlock(&(_dst_array)); \
+} \
+
+//! @}
+
+#endif // GIM_MEMORY_H_INCLUDED
diff --git a/libs/ode-0.16.1/GIMPACT/include/GIMPACT/gim_radixsort.h b/libs/ode-0.16.1/GIMPACT/include/GIMPACT/gim_radixsort.h
new file mode 100644
index 0000000..8572b92
--- /dev/null
+++ b/libs/ode-0.16.1/GIMPACT/include/GIMPACT/gim_radixsort.h
@@ -0,0 +1,258 @@
+#ifndef GIM_RADIXSORT_H_INCLUDED
+#define GIM_RADIXSORT_H_INCLUDED
+/*! \file gim_radixsort.h
+\author Francisco León.
+Based on the work of Michael Herf : "fast floating-point radix sort"
+Avaliable on http://www.stereopsis.com/radix.html
+*/
+/*
+-----------------------------------------------------------------------------
+This source file is part of GIMPACT Library.
+
+For the latest info, see http://gimpact.sourceforge.net/
+
+Copyright (c) 2006 Francisco Leon. C.C. 80087371.
+email: projectileman@yahoo.com
+
+ 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 GIMPACT-LICENSE-LGPL.TXT.
+ (2) The BSD-style license that is included with this library in
+ the file GIMPACT-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
+ GIMPACT-LICENSE-LGPL.TXT and GIMPACT-LICENSE-BSD.TXT for more details.
+
+-----------------------------------------------------------------------------
+*/
+
+#include "GIMPACT/gim_memory.h"
+
+/*! \defgroup SORTING
+\brief
+Macros for sorting.
+*/
+//! @{
+struct GIM_RSORT_TOKEN
+{
+ GUINT32 m_key;
+ GUINT32 m_value;
+};
+//typedef struct _GIM_RSORT_TOKEN GIM_RSORT_TOKEN;
+
+//comparator for sorting
+#define RSORT_TOKEN_COMPARATOR(x, y) ((int)((x.m_key) - (y.m_key)))
+
+// ---- utils for accessing 11-bit quantities
+#define D11_0(x) (x & 0x7FF)
+#define D11_1(x) (x >> 11 & 0x7FF)
+#define D11_2(x) (x >> 22 )
+
+
+//COMMON FUNCTIONS FOR ACCESSING THE KEY OF AN ELEMENT
+
+
+//For the type of your array, you need to declare a macro for obtaining the key, like these:
+#define SIMPLE_GET_FLOAT32KEY(e,key) {key =(GREAL)(e);}
+
+#define SIMPLE_GET_INTKEY(e,key) {key =(GINT32)(e);}
+
+#define SIMPLE_GET_UINTKEY(e,key) {key =(GUINT32)(e);}
+
+//For the type of your array, you need to declare a macro for copy elements, like this:
+
+#define SIMPLE_COPY_ELEMENTS(dest,src) {dest = src;}
+
+#define kHist 2048
+
+///Radix sort for unsigned integer keys
+
+#define GIM_RADIX_SORT_RTOKENS(array,sorted,element_count)\
+{\
+ GUINT32 i;\
+ GUINT32 b0[kHist * 3];\
+ GUINT32 *b1 = b0 + kHist;\
+ GUINT32 *b2 = b1 + kHist;\
+ for (i = 0; i < kHist * 3; i++)\
+ {\
+ b0[i] = 0;\
+ }\
+ GUINT32 fi;\
+ GUINT32 pos;\
+ for (i = 0; i < element_count; i++)\
+ {\
+ fi = array[i].m_key;\
+ b0[D11_0(fi)] ++;\
+ b1[D11_1(fi)] ++;\
+ b2[D11_2(fi)] ++;\
+ }\
+ {\
+ GUINT32 sum0 = 0, sum1 = 0, sum2 = 0;\
+ GUINT32 tsum;\
+ for (i = 0; i < kHist; i++)\
+ {\
+ tsum = b0[i] + sum0;\
+ b0[i] = sum0 - 1;\
+ sum0 = tsum;\
+ tsum = b1[i] + sum1;\
+ b1[i] = sum1 - 1;\
+ sum1 = tsum;\
+ tsum = b2[i] + sum2;\
+ b2[i] = sum2 - 1;\
+ sum2 = tsum;\
+ }\
+ }\
+ for (i = 0; i < element_count; i++)\
+ {\
+ fi = array[i].m_key;\
+ pos = D11_0(fi);\
+ pos = ++b0[pos];\
+ sorted[pos].m_key = array[i].m_key;\
+ sorted[pos].m_value = array[i].m_value;\
+ }\
+ for (i = 0; i < element_count; i++)\
+ {\
+ fi = sorted[i].m_key;\
+ pos = D11_1(fi);\
+ pos = ++b1[pos];\
+ array[pos].m_key = sorted[i].m_key;\
+ array[pos].m_value = sorted[i].m_value;\
+ }\
+ for (i = 0; i < element_count; i++)\
+ {\
+ fi = array[i].m_key;\
+ pos = D11_2(fi);\
+ pos = ++b2[pos];\
+ sorted[pos].m_key = array[i].m_key;\
+ sorted[pos].m_value = array[i].m_value;\
+ }\
+}\
+
+/// Get the sorted tokens from an array. For generic use. Tokens are GIM_RSORT_TOKEN
+#define GIM_RADIX_SORT_ARRAY_TOKENS(array, sorted_tokens, element_count, get_uintkey_macro)\
+{\
+ GIM_RSORT_TOKEN * _unsorted = (GIM_RSORT_TOKEN *) gim_alloc(sizeof(GIM_RSORT_TOKEN )*element_count);\
+ GUINT32 _i;\
+ for (_i=0;_i<element_count;_i++)\
+ {\
+ get_uintkey_macro(array[_i],_unsorted[_i].m_key);\
+ _unsorted[_i].m_value = _i;\
+ }\
+ GIM_RADIX_SORT_RTOKENS(_unsorted,sorted_tokens,element_count);\
+ gim_free(_unsorted,sizeof(GIM_RSORT_TOKEN )*element_count);\
+}\
+
+/// Sorts array in place. For generic use
+#define GIM_RADIX_SORT(type,array,element_count,get_uintkey_macro,copy_elements_macro)\
+{\
+ GIM_RSORT_TOKEN * _sorted = (GIM_RSORT_TOKEN *) gim_alloc(sizeof(GIM_RSORT_TOKEN )*element_count);\
+ GIM_RADIX_SORT_ARRAY_TOKENS(array,_sorted,element_count,get_uintkey_macro);\
+ type * _original_array = (type *) gim_alloc(sizeof(type)*element_count); \
+ memcpy(_original_array,array,sizeof(type)*element_count);\
+ GUINT32 _i;\
+ for (_i=0;_i<element_count;_i++)\
+ {\
+ copy_elements_macro(array[_i],_original_array[_sorted[_i].m_value]);\
+ }\
+ gim_free(_original_array,sizeof(type)*element_count);\
+ gim_free(_sorted,sizeof(GIM_RSORT_TOKEN )*element_count);\
+}\
+
+/// Sorts array in place using quick sort
+#define GIM_QUICK_SORT_ARRAY(type, array, array_count, comp_macro, exchange_macro) \
+{\
+ GINT32 _i_, _j_, _p_, _stack_index_, _start_, _end_;\
+ GINT32 _start_stack_[64]; \
+ GINT32 _end_stack_[64];\
+ _start_stack_[0] = 0;\
+ _end_stack_[0] = (array_count);\
+ _stack_index_ = 1;\
+ while (_stack_index_ > 0)\
+ {\
+ _stack_index_ --;\
+ _start_ = _start_stack_[_stack_index_];\
+ _end_ = _end_stack_[_stack_index_];\
+ while (_end_ - _start_ > 2)\
+ {\
+ _p_ = _start_;\
+ _i_ = _start_ + 1;\
+ _j_ = _end_ - 1;\
+ while (_i_<_j_) \
+ {\
+ for(; _i_<=_j_ && comp_macro(((array)[_i_]),((array)[_p_]))<=0; _i_++) ;\
+ if (_i_ > _j_) \
+ {\
+ exchange_macro(type, array, _j_, _p_);\
+ _i_ = _j_;\
+ }\
+ else\
+ {\
+ for(; _i_<=_j_ && comp_macro(((array)[_j_]),((array)[_p_]))>=0; _j_--) ;\
+ if (_i_ > _j_) \
+ {\
+ exchange_macro(type, array, _j_, _p_);\
+ _i_ = _j_;\
+ }\
+ else if (_i_ < _j_)\
+ {\
+ exchange_macro(type, array, _i_, _j_);\
+ if (_i_+2 < _j_) {_i_++; _j_--;}\
+ else if (_i_+1 < _j_) _i_++;\
+ }\
+ }\
+ }\
+ if (_i_-_start_ > 1 && _end_-_j_ > 1) \
+ {\
+ if (_i_-_start_ < _end_-_j_-1) \
+ {\
+ _start_stack_[_stack_index_] = _j_+1;\
+ _end_stack_[_stack_index_] = _end_;\
+ _stack_index_ ++;\
+ _end_ = _i_;\
+ }\
+ else\
+ {\
+ _start_stack_[_stack_index_] = _start_;\
+ _end_stack_[_stack_index_] = _i_;\
+ _stack_index_ ++;\
+ _start_ = _j_+1;\
+ }\
+ }\
+ else\
+ {\
+ if (_i_-_start_ > 1)\
+ {\
+ _end_ = _i_;\
+ }\
+ else \
+ {\
+ _start_ = _j_+1;\
+ }\
+ }\
+ }\
+ if (_end_ - _start_ == 2) \
+ {\
+ if (comp_macro(((array)[_start_]),((array)[_end_-1])) > 0) \
+ {\
+ exchange_macro(type, array, _start_, _end_-1);\
+ }\
+ }\
+ }\
+}\
+
+#define GIM_DEF_EXCHANGE_MACRO(type, _array, _i, _j)\
+{\
+ type _e_tmp_ =(_array)[(_i)];\
+ (_array)[(_i)]=(_array)[(_j)];\
+ (_array)[(_j)]= _e_tmp_;\
+}\
+
+#define GIM_COMP_MACRO(x, y) ((GINT32)((x) - (y)))
+//! @}
+#endif // GIM_RADIXSORT_H_INCLUDED
diff --git a/libs/ode-0.16.1/GIMPACT/include/GIMPACT/gim_tri_capsule_collision.h b/libs/ode-0.16.1/GIMPACT/include/GIMPACT/gim_tri_capsule_collision.h
new file mode 100644
index 0000000..2b31604
--- /dev/null
+++ b/libs/ode-0.16.1/GIMPACT/include/GIMPACT/gim_tri_capsule_collision.h
@@ -0,0 +1,111 @@
+#ifndef GIM_TRI_CAPSULE_COLLISION_H_INCLUDED
+#define GIM_TRI_CAPSULE_COLLISION_H_INCLUDED
+
+/*! \file gim_tri_capsule_collision.h
+\author Francisco León
+*/
+/*
+-----------------------------------------------------------------------------
+This source file is part of GIMPACT Library.
+
+For the latest info, see http://gimpact.sourceforge.net/
+
+Copyright (c) 2006 Francisco Leon. C.C. 80087371.
+email: projectileman@yahoo.com
+
+ 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 GIMPACT-LICENSE-LGPL.TXT.
+ (2) The BSD-style license that is included with this library in
+ the file GIMPACT-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
+ GIMPACT-LICENSE-LGPL.TXT and GIMPACT-LICENSE-BSD.TXT for more details.
+
+-----------------------------------------------------------------------------
+*/
+
+#include "GIMPACT/gim_memory.h"
+
+/*! \addtogroup GEOMETRIC_OPERATIONS
+*/
+//! @{
+
+//! Capsule struct
+struct GIM_CAPSULE_DATA
+{
+ GREAL m_radius;
+ vec3f m_point1;
+ vec3f m_point2;
+};
+//typedef struct _GIM_CAPSULE_DATA GIM_CAPSULE_DATA;
+
+#define CALC_CAPSULE_AABB(capsule,aabb)\
+{\
+ if(capsule.m_point1[0]<capsule.m_point2[0])\
+ {\
+ aabb.minX = capsule.m_point1[0] - capsule.m_radius;\
+ aabb.maxX = capsule.m_point2[0] + capsule.m_radius;\
+ }\
+ else\
+ {\
+ aabb.minX = capsule.m_point2[0] - capsule.m_radius;\
+ aabb.maxX = capsule.m_point1[0] + capsule.m_radius;\
+ }\
+ if(capsule.m_point1[1]<capsule.m_point2[1])\
+ {\
+ aabb.minY = capsule.m_point1[1] - capsule.m_radius;\
+ aabb.maxY = capsule.m_point2[1] + capsule.m_radius;\
+ }\
+ else\
+ {\
+ aabb.minY = capsule.m_point2[1] - capsule.m_radius;\
+ aabb.maxY = capsule.m_point1[1] + capsule.m_radius;\
+ }\
+ if(capsule.m_point1[2]<capsule.m_point2[2])\
+ {\
+ aabb.minZ = capsule.m_point1[2] - capsule.m_radius;\
+ aabb.maxZ = capsule.m_point2[2] + capsule.m_radius;\
+ }\
+ else\
+ {\
+ aabb.minZ = capsule.m_point2[2] - capsule.m_radius;\
+ aabb.maxZ = capsule.m_point1[2] + capsule.m_radius;\
+ }\
+}\
+
+//! Utility function for find the closest point between a segment and a triangle
+/*!
+
+\param triangle
+\param s1
+\param s2
+\param contacts Contains the closest points on the segment (1,2), and the normal points to segment, and m_depth contains the distance
+
+\post The contacts array is not set to 0. It adds aditional contacts
+*/
+void gim_closest_point_triangle_segment(GIM_TRIANGLE_DATA * triangle, vec3f s1,vec3f s2, GDYNAMIC_ARRAY * contacts);
+
+
+
+
+
+//! Utility function for find the closest point between a capsule and a triangle
+/*!
+
+\param triangle
+\param capsule
+\param contacts Contains the closest points on the capsule, and the normal points to triangle
+\return 1 if the triangle collides the capsule
+\post The contacts array is not set to 0. It adds aditional contacts
+*/
+int gim_triangle_capsule_collision(GIM_TRIANGLE_DATA * triangle, GIM_CAPSULE_DATA * capsule, GDYNAMIC_ARRAY * contacts);
+//! @}
+
+#endif // GIM_TRI_CAPSULE_COLLISION_H_INCLUDED
diff --git a/libs/ode-0.16.1/GIMPACT/include/GIMPACT/gim_tri_collision.h b/libs/ode-0.16.1/GIMPACT/include/GIMPACT/gim_tri_collision.h
new file mode 100644
index 0000000..ae63252
--- /dev/null
+++ b/libs/ode-0.16.1/GIMPACT/include/GIMPACT/gim_tri_collision.h
@@ -0,0 +1,253 @@
+#ifndef GIM_TRI_COLLISION_H_INCLUDED
+#define GIM_TRI_COLLISION_H_INCLUDED
+
+/*! \file gim_tri_collision.h
+\author Francisco León Nájera
+*/
+/*
+-----------------------------------------------------------------------------
+This source file is part of GIMPACT Library.
+
+For the latest info, see http://gimpact.sourceforge.net/
+
+Copyright (c) 2006 Francisco Leon Najera. C.C. 80087371.
+email: projectileman@yahoo.com
+
+ 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 GIMPACT-LICENSE-LGPL.TXT.
+ (2) The BSD-style license that is included with this library in
+ the file GIMPACT-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
+ GIMPACT-LICENSE-LGPL.TXT and GIMPACT-LICENSE-BSD.TXT for more details.
+
+-----------------------------------------------------------------------------
+*/
+
+/*! \addtogroup GEOMETRIC_OPERATIONS
+*/
+//! @{
+
+
+#define MAX_TRI_CLIPPING 8
+
+//! Clips a polygon by a plane
+#define PLANE_CLIP_POLYGON(plane,polygon_points,polygon_point_count,clipped,clipped_count,max_clipped) \
+{ \
+ clipped_count = 0; \
+ GUINT32 _i, _vi, _prevclassif=32000, _classif; \
+ GREAL _d; \
+ for(_i=0;_i<=polygon_point_count;_i++) \
+ { \
+ _vi = _i%polygon_point_count; \
+ _d = DISTANCE_PLANE_POINT(plane,polygon_points[_vi]); \
+ _classif = _d>G_EPSILON ?1:0; \
+ if(_classif == 0) \
+ { \
+ if(_prevclassif==1) \
+ {\
+ if(clipped_count<max_clipped) \
+ {\
+ PLANE_CLIP_SEGMENT(polygon_points[_i-1],polygon_points[_vi],plane,clipped[clipped_count]); \
+ clipped_count++; \
+ } \
+ } \
+ if(clipped_count<max_clipped&&_i<polygon_point_count) \
+ { \
+ VEC_COPY(clipped[clipped_count],polygon_points[_vi]); \
+ clipped_count++; \
+ } \
+ } \
+ else \
+ { \
+ if(_prevclassif==0) \
+ { \
+ if(clipped_count<max_clipped) \
+ { \
+ PLANE_CLIP_SEGMENT(polygon_points[_i-1],polygon_points[_vi],plane,clipped[clipped_count]); \
+ clipped_count++; \
+ } \
+ } \
+ } \
+ _prevclassif = _classif; \
+ } \
+}\
+
+
+struct GIM_TRIPLANES_CACHE
+{
+ /*!
+ Planes are:
+ 0 : Face normal plane (0,3)
+ 1 : Edge 1 plane (4,7)
+ 2 : Edge 2 plane (8,11)
+ 3 : Edge 3 plane (12,15)
+ */
+ vec4f m_planes[4];
+};
+//typedef struct _GIM_TRIPLANES_CACHE GIM_TRIPLANES_CACHE;
+
+
+struct GIM_TRIANGLE_DATA
+{
+ vec3f m_vertices[3];
+ GIM_TRIPLANES_CACHE m_planes;
+};
+//typedef struct _GIM_TRIANGLE_DATA GIM_TRIANGLE_DATA;
+
+//! tri_data is a GIM_TRIANGLE_DATA
+#define GIM_CALC_TRIANGLE_DATA_PLANES(tri_data)\
+{\
+ TRIANGLE_PLANE((tri_data).m_vertices[0],(tri_data).m_vertices[1],(tri_data).m_vertices[2],(tri_data).m_planes.m_planes[0]);\
+ EDGE_PLANE((tri_data).m_vertices[0],(tri_data).m_vertices[1],((tri_data).m_planes.m_planes[0]),((tri_data).m_planes.m_planes[1]));\
+ EDGE_PLANE((tri_data).m_vertices[1],(tri_data).m_vertices[2],((tri_data).m_planes.m_planes[0]),((tri_data).m_planes.m_planes[2]));\
+ EDGE_PLANE((tri_data).m_vertices[2],(tri_data).m_vertices[0],((tri_data).m_planes.m_planes[0]), ((tri_data).m_planes.m_planes[3]));\
+}\
+
+//Structure for collision
+
+struct GIM_TRIANGLE_CONTACT_DATA
+{
+ GREAL m_penetration_depth;
+ GUINT32 m_point_count;
+ vec3f m_separating_normal;
+ vec3f m_points[MAX_TRI_CLIPPING];
+};
+//typedef struct _GIM_TRIANGLE_CONTACT_DATA GIM_TRIANGLE_CONTACT_DATA;
+
+struct GIM_TRIANGLE_RAY_CONTACT_DATA
+{
+ GREAL u;
+ GREAL v;
+ GREAL tparam;
+ GUINT32 m_face_id;
+ vec3f m_point;
+ vec3f m_normal;
+};
+//typedef struct _GIM_TRIANGLE_RAY_CONTACT_DATA GIM_TRIANGLE_RAY_CONTACT_DATA;
+
+//! Fast Triangle Triangle overlapping test
+int gim_triangle_triangle_overlap(
+ GIM_TRIANGLE_DATA *tri1,
+ GIM_TRIANGLE_DATA *tri2);
+
+
+//! Fast but inacurate conservative Triangle Triangle overlapping test
+int gim_triangle_triangle_overlap_fast(
+ GIM_TRIANGLE_DATA *tri1,
+ GIM_TRIANGLE_DATA *tri2);
+
+
+//! Finds the contact points from a collision of two triangles
+/*!
+Returns the contact points, the penetration depth and the separating normal of the collision
+between two triangles. The normal is pointing toward triangle 1 from triangle 2
+*/
+int gim_triangle_triangle_collision(
+ GIM_TRIANGLE_DATA *tri1,
+ GIM_TRIANGLE_DATA *tri2,
+ GIM_TRIANGLE_CONTACT_DATA * contact_data);
+
+//Ray triangle
+
+
+/*!
+ Solve the System for u,v parameters:
+
+ u*axe1[i1] + v*axe2[i1] = vecproj[i1]
+ u*axe1[i2] + v*axe2[i2] = vecproj[i2]
+
+ sustitute:
+ v = (vecproj[i2] - u*axe1[i2])/axe2[i2]
+
+ then the first equation in terms of 'u':
+
+ --> u*axe1[i1] + ((vecproj[i2] - u*axe1[i2])/axe2[i2])*axe2[i1] = vecproj[i1]
+
+ --> u*axe1[i1] + vecproj[i2]*axe2[i1]/axe2[i2] - u*axe1[i2]*axe2[i1]/axe2[i2] = vecproj[i1]
+
+ --> u*(axe1[i1] - axe1[i2]*axe2[i1]/axe2[i2]) = vecproj[i1] - vecproj[i2]*axe2[i1]/axe2[i2]
+
+ --> u*((axe1[i1]*axe2[i2] - axe1[i2]*axe2[i1])/axe2[i2]) = (vecproj[i1]*axe2[i2] - vecproj[i2]*axe2[i1])/axe2[i2]
+
+ --> u*(axe1[i1]*axe2[i2] - axe1[i2]*axe2[i1]) = vecproj[i1]*axe2[i2] - vecproj[i2]*axe2[i1]
+
+ --> u = (vecproj[i1]*axe2[i2] - vecproj[i2]*axe2[i1]) /(axe1[i1]*axe2[i2] - axe1[i2]*axe2[i1])
+
+if 0.0<= u+v <=1.0 then they are inside of triangle
+
+ */
+#define TRIANGLE_GET_UVPARAMETERS(point,vec1,vec2,vec3,tri_plane,u,v,outside)\
+{\
+ vec3f _axe1, _axe2, _vecproj;\
+ VEC_DIFF(_axe1,vec2,vec1);\
+ VEC_DIFF(_axe2,vec3,vec1);\
+ VEC_DIFF(_vecproj,point,vec1);\
+ GUINT32 _i1,_i2;\
+ PLANE_MINOR_AXES(tri_plane, _i1, _i2);\
+ if(fabsf(_axe2[_i2])<G_EPSILON)\
+ {\
+ u = (_vecproj[_i2]*_axe2[_i1] - _vecproj[_i1]*_axe2[_i2]) /(_axe1[_i2]*_axe2[_i1] - _axe1[_i1]*_axe2[_i2]);\
+ v = (_vecproj[_i1] - u*_axe1[_i1])/_axe2[_i1];\
+ }\
+ else\
+ {\
+ u = (_vecproj[_i1]*_axe2[_i2] - _vecproj[_i2]*_axe2[_i1]) /(_axe1[_i1]*_axe2[_i2] - _axe1[_i2]*_axe2[_i1]);\
+ v = (_vecproj[_i2] - u*_axe1[_i2])/_axe2[_i2];\
+ }\
+ if(u<-G_EPSILON)\
+ {\
+ outside = 1;\
+ }\
+ else if(v<-G_EPSILON)\
+ {\
+ outside = 1;\
+ }\
+ else\
+ {\
+ float sumuv;\
+ sumuv = u+v;\
+ if(sumuv<-G_EPSILON)\
+ {\
+ outside = 1;\
+ }\
+ else if(sumuv-1.0f>G_EPSILON)\
+ {\
+ outside = 1;\
+ }\
+ else\
+ {\
+ outside = 0;\
+ }\
+ }\
+}\
+
+//! Finds the collision of a ray and a triangle.
+#define RAY_TRIANGLE_INTERSECTION(vOrigin,vDir,vec1,vec2,vec3,tri_plane,pout,u,v,tparam,tmax,does_intersect)\
+{\
+ RAY_PLANE_COLLISION(tri_plane,vDir,vOrigin,pout,tparam,does_intersect);\
+ if(does_intersect != 0)\
+ {\
+ if(tparam<-G_EPSILON||tparam>tmax+G_EPSILON)\
+ {\
+ does_intersect = 0;\
+ }\
+ else\
+ {\
+ TRIANGLE_GET_UVPARAMETERS(pout,vec1,vec2,vec3,tri_plane,u,v,does_intersect);\
+ does_intersect = !does_intersect;\
+ }\
+ }\
+}\
+
+
+//! @}
+
+#endif // GIM_TRI_COLLISION_H_INCLUDED
diff --git a/libs/ode-0.16.1/GIMPACT/include/GIMPACT/gim_tri_sphere_collision.h b/libs/ode-0.16.1/GIMPACT/include/GIMPACT/gim_tri_sphere_collision.h
new file mode 100644
index 0000000..a2a81d6
--- /dev/null
+++ b/libs/ode-0.16.1/GIMPACT/include/GIMPACT/gim_tri_sphere_collision.h
@@ -0,0 +1,51 @@
+#ifndef GIM_TRI_SPHERE_COLLISION_H_INCLUDED
+#define GIM_TRI_SPHERE_COLLISION_H_INCLUDED
+
+/*! \file gim_tri_sphere_collision.h
+\author Francisco León
+*/
+/*
+-----------------------------------------------------------------------------
+This source file is part of GIMPACT Library.
+
+For the latest info, see http://gimpact.sourceforge.net/
+
+Copyright (c) 2006 Francisco Leon. C.C. 80087371.
+email: projectileman@yahoo.com
+
+ 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 GIMPACT-LICENSE-LGPL.TXT.
+ (2) The BSD-style license that is included with this library in
+ the file GIMPACT-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
+ GIMPACT-LICENSE-LGPL.TXT and GIMPACT-LICENSE-BSD.TXT for more details.
+
+-----------------------------------------------------------------------------
+*/
+
+/*! \addtogroup GEOMETRIC_OPERATIONS
+*/
+//! @{
+
+//! Finds the contact points from a collision of a triangle and a sphere
+/*!
+\param tri
+\param center
+\param radius
+\param contact_data Contains the closest points on the Sphere, and the normal is pointing to triangle
+*/
+int gim_triangle_sphere_collision(
+ GIM_TRIANGLE_DATA *tri,
+ vec3f center, GREAL radius,
+ GIM_TRIANGLE_CONTACT_DATA * contact_data);
+
+//! @}
+#endif // GIM_TRI_SPHERE_COLLISION_H_INCLUDED
diff --git a/libs/ode-0.16.1/GIMPACT/include/GIMPACT/gim_trimesh.h b/libs/ode-0.16.1/GIMPACT/include/GIMPACT/gim_trimesh.h
new file mode 100644
index 0000000..2983fca
--- /dev/null
+++ b/libs/ode-0.16.1/GIMPACT/include/GIMPACT/gim_trimesh.h
@@ -0,0 +1,544 @@
+#ifndef GIM_TRIMESH_H_INCLUDED
+#define GIM_TRIMESH_H_INCLUDED
+/*! \file gim_trimesh.h
+\author Francisco León
+*/
+/*
+-----------------------------------------------------------------------------
+This source file is part of GIMPACT Library.
+
+For the latest info, see http://gimpact.sourceforge.net/
+
+Copyright (c) 2006 Francisco Leon. C.C. 80087371.
+email: projectileman@yahoo.com
+
+ 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 GIMPACT-LICENSE-LGPL.TXT.
+ (2) The BSD-style license that is included with this library in
+ the file GIMPACT-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
+ GIMPACT-LICENSE-LGPL.TXT and GIMPACT-LICENSE-BSD.TXT for more details.
+
+-----------------------------------------------------------------------------
+*/
+
+#include "GIMPACT/gim_boxpruning.h"
+#include "GIMPACT/gim_contact.h"
+
+
+///MAsk defines
+#define GIM_TRIMESH_TRANSFORMED_REPLY 1
+#define GIM_TRIMESH_NEED_UPDATE 2
+
+/*! \addtogroup TRIMESH
+\brief
+A Trimesh is the basic geometric structure for representing solid objects.
+<p><strong>CREATING TRIMESHES</strong></p>
+<ul>
+<li> For creating trimeshes, you must initialize Buffer managers by calling \ref gimpact_init
+<li> Then you must define the vertex and index sources by creating them with \ref BUFFER_ARRAYS routines, and then call \ref gim_trimesh_create_from_arrays.
+<li> An alternative way for creaing trimesh objects is calling \ref gim_trimesh_create_from_data.
+<li> For access to the trimesh data (vertices, triangle indices), you must call \ref gim_trimesh_locks_work_data , and \ref gim_trimesh_unlocks_work_data for finish the access.
+<li> Each time when the trimesh data is modified, you must call \ref gim_trimesh_update after.
+<li> When a trimesh is no longer needed, you must call \ref gim_trimesh_destroy.
+</ul>
+
+<p>This is an example of how to create a deformable trimesh that shares vertices with the user application:</p>
+\code
+//Declaration of vertices
+vec3f trimeshvertices[200];
+//Declaration of indices
+GUINT trimeshindices[100];
+
+... Initializing vertices and triangle indices at beginning
+
+//Then create trimesh
+GIM_TRIMESH mytrimesh;
+
+//Calling trimesh create function
+
+gim_trimesh_create_from_data(
+&mytrimesh,
+trimeshvertices,200,
+0 ,//copy_vertices is 0
+trimeshindices,
+100,
+0, //copy_indices is 0
+0 //transformed_reply is 0
+);
+\endcode
+<p>Note that parameter transformed_reply is 0, that means that m_transformed_vertex_buffer is a reference to m_source_vertex on the trimesh, and transformations are not avaliable. Use that configuration if you have to simulate a deformable trimesh like cloth or elastic bodies.</p>
+<p>When the trimesh is no longer needed, destroy it safely with gim_trimesh_destroy()</p>
+<p><strong>UPDATING TRIMESHES</strong></p>
+<p>On simulation loops, is needed to update trimeshes every time for update vertices althought updating triangle boxes and planes cache. There is two ways for update trimeshes: </p>
+<ul>
+<li> Updating vertices directly. You need to access to the \ref GIM_TRIMESH.m_source_vertex_buffer member; a vertex buffer which has access to the source vertices.
+\code
+// Access to the source vertices
+gim_buffer_array_lock(&mytrimesh.m_source_vertex_buffer, G_MA_READ_WRITE);
+
+//Get a pointer to the vertex buffer
+vec3f * vertexpointer = GIM_BUFFER_ARRAY_POINTER(vec3f,mytrimesh.m_source_vertex_buffer,0);
+
+//Get the amount of vertices
+int veccount = mytrimesh.m_source_vertex_buffer.m_element_count;
+
+//Modify vertices
+for (int i=0;i<veccount ;i++ )
+{
+ .....
+ .....
+ processing vertices
+ .....
+ .....
+}
+
+// Don't forget to unlock the source vertex array
+gim_buffer_array_unlock(&mytrimesh.m_source_vertex_buffer);
+
+// Notify that the state of the trimesh is changed
+gim_trimesh_post_update(&mytrimesh.m_source_vertex_buffer);
+
+\endcode
+For making trimeshes that allow to update their vertices, use \ref gim_trimesh_create_from_data with parameter <strong>transformed_reply</strong> = 0.
+</ul>
+<ul>
+<li> Aplying a transformation. Simply use \ref gim_trimesh_set_tranform . Remember that with this method trimeshes must be created with \ref gim_trimesh_create_from_data with parameter <strong>transformed_reply</strong> = 1.
+</ul>
+<p> After updating vertices, you must call \ref gim_trimesh_update()</p>
+<p><strong>TRIMESHES COLLISION</strong></p>
+<p>Before collide trimeshes, you need to update them first.</p>
+<p>Then you must use \ref gim_trimesh_trimesh_collision().</p>
+
+*/
+//! @{
+
+//! Prototype for updating vertices
+typedef void * gim_update_trimesh_function(struct _GIM_TRIMESH *);
+
+//! Trimesh
+struct GIM_TRIMESH
+{
+ ///Original
+ //@{
+ GBUFFER_ARRAY m_source_vertex_buffer;//!< Buffer of vec3f coordinates
+
+ //! (GUINT) Indices of triangles,groups of three elements.
+ /*!
+ Array of GUINT. Triangle indices. Each triple contains indices of the vertices for each triangle.
+ \invariant must be aligned
+ */
+ GBUFFER_ARRAY m_tri_index_buffer;
+ //@}
+ ///Allocated
+ //@{
+ char m_mask;//!< Don't use directly
+
+ //! Allocated transformed vertices vec3f
+ /*!
+ Array of vec3f.If gim_trimesh_has_tranformed_reply(this) == 1 then it refers to the m_source_vertex_buffer
+ \invariant must be aligned
+ */
+ GBUFFER_ARRAY m_transformed_vertex_buffer;
+ //@}
+ ///Auxiliary data
+ //@{
+ GIM_AABB_SET m_aabbset;
+ GDYNAMIC_ARRAY m_planes_cache_buffer;//! Allocated GIM_TRIPLANES_CACHE
+ GDYNAMIC_ARRAY m_planes_cache_bitset;
+ gim_update_trimesh_function * m_update_callback;//! If null, then m_transform is applied.
+ mat4f m_transform;
+ //@}
+};
+//typedef struct _GIM_TRIMESH GIM_TRIMESH;
+
+/// Info about mesh
+//! Return the trimesh triangle count
+GUINT32 gim_trimesh_get_triangle_count(GIM_TRIMESH * trimesh);
+
+//! Returns 1 if the m_transformed_vertex_buffer is a reply of m_source_vertex_buffer
+char gim_trimesh_has_tranformed_reply(GIM_TRIMESH * trimesh);
+
+//! Returns 1 if the trimesh needs to update their aabbset and the planes cache.
+char gim_trimesh_needs_update(GIM_TRIMESH * trimesh);
+
+//! Change the state of the trimesh for force it to update
+/*!
+Call it after made changes to the trimesh.
+\post gim_trimesh_need_update(trimesh) will return 1
+\sa gim_trimesh_needs_update,gim_trimesh_has_tranformed_reply
+*/
+void gim_trimesh_post_update(GIM_TRIMESH * trimesh);
+
+//! Creates the aabb set and the triangles cache
+/*!
+
+\param trimesh
+\param vertex_array
+\param triindex_array
+\param transformed_reply If 1, then the m_transformed_vertices is a reply of the source vertices. Else it just be a reference to the original array.
+\post it copies the arrays by reference, and creates the auxiliary data (m_aabbset,m_planes_cache_buffer)
+*/
+void gim_trimesh_create_from_arrays(GBUFFER_MANAGER_DATA buffer_managers[],
+ GIM_TRIMESH * trimesh, GBUFFER_ARRAY * vertex_array, GBUFFER_ARRAY * triindex_array,char transformed_reply);
+
+
+
+//! Create a trimesh from vertex array and an index array
+/*!
+\param trimesh An uninitialized GIM_TRIMESH structure
+\param vertex_array A buffer to a vec3f array
+\param vertex_count
+\param triindex_array
+\param index_count
+\param copy_vertices If 1, it copies the source vertices in another buffer. Else (0) it constructs a reference to the data.
+\param copy_indices If 1, it copies the source vertices in another buffer. Else (0) it constructs a reference to the data.
+\param transformed_reply If 1, then the m_transformed_vertices is a reply of the source vertices. Else it just be a reference to the original array. Use 1 if you will apply transformations to the trimesh. See \ref gim_trimesh_set_tranform().
+*/
+void gim_trimesh_create_from_data(GBUFFER_MANAGER_DATA buffer_managers[],
+ GIM_TRIMESH * trimesh, vec3f * vertex_array, GUINT32 vertex_count,char copy_vertices,
+ GUINT32 * triindex_array, GUINT32 index_count,char copy_indices,char transformed_reply);
+
+//! Clears auxiliary data and releases buffer arrays
+void gim_trimesh_destroy(GIM_TRIMESH * trimesh);
+
+//! Copies two meshes
+/*!
+\param source_trimesh
+\param dest_trimesh
+\param copy_by_reference If 1, it attach a reference to the source vertices, else it copies the vertices
+\param transformed_reply If 1, transformed vertices are reply of source vertives. 1 Is recommended
+*/
+void gim_trimesh_copy(GIM_TRIMESH * source_trimesh,
+ GBUFFER_MANAGER_DATA dest_buffer_managers[], GIM_TRIMESH * dest_trimesh,
+ char copy_by_reference, char transformed_reply);
+
+
+//! Locks the trimesh for working with it
+/*!
+\post locks m_tri_index_buffer and m_transformed_vertex_buffer.
+\param trimesh
+*/
+void gim_trimesh_locks_work_data(GIM_TRIMESH * trimesh);
+
+
+//! unlocks the trimesh
+/*!
+\post unlocks m_tri_index_buffer and m_transformed_vertex_buffer.
+\param trimesh
+*/
+void gim_trimesh_unlocks_work_data(GIM_TRIMESH * trimesh);
+
+//! Updates m_transformed_vertex_buffer
+/*!
+\pre m_transformed_vertex_buffer must be unlocked
+*/
+void gim_trimesh_update_vertices(GIM_TRIMESH * trimesh);
+
+//! Updates m_aabbset and m_planes_cache_bitset
+/*!
+\pre gim_trimesh_locks_work_data must be called before
+*/
+void gim_trimesh_update_aabbset(GIM_TRIMESH * trimesh);
+
+//! Calls before perfom collisions. Updates the trimesh if needed
+/*!
+\post If gim_trimesh_needs_update returns 1, then it calls gim_trimesh_update_vertices and gim_trimesh_update_aabbset
+*/
+void gim_trimesh_update(GIM_TRIMESH * trimesh);
+
+//! Set the transform of a trimesh
+/*!
+\post This function calls to gim_trimesh_post_update
+*/
+void gim_trimesh_set_tranform(GIM_TRIMESH * trimesh, mat4f transform);
+
+//! Fetch triangle data
+/*!
+\pre gim_trimesh_locks_work_data must be called before
+*/
+void gim_trimesh_get_triangle_data(GIM_TRIMESH * trimesh, GUINT32 triangle_index, GIM_TRIANGLE_DATA * tri_data);
+
+//! Fetch triangle vertices
+/*!
+\pre gim_trimesh_locks_work_data must be called before
+*/
+void gim_trimesh_get_triangle_vertices(GIM_TRIMESH * trimesh, GUINT32 triangle_index, vec3f v1,vec3f v2,vec3f v3);
+
+//! Trimesh Trimesh Collisions
+/*!
+Before use this function you must update each trimesh:
+\code
+gim_trimesh_update(TriMesh1);
+gim_trimesh_update(TriMesh2);
+\endcode
+Then you must use the trimesh collision in this way:
+\code
+int collide_trimeshes(GIM_TRIMESH * TriMesh1, GIM_TRIMESH * TriMesh2)
+{
+ //Create contact list
+ GDYNAMIC_ARRAY trimeshcontacts;
+ GIM_CREATE_CONTACT_LIST(trimeshcontacts);
+
+ //Collide trimeshes
+ gim_trimesh_trimesh_collision(TriMesh1,TriMesh2,&trimeshcontacts);
+
+ if(trimeshcontacts.m_size == 0) //do nothing
+ {
+ GIM_DYNARRAY_DESTROY(trimeshcontacts);//clean contact array
+ return 0;
+ }
+
+ //Getting a pointer to the contact array
+ GIM_CONTACT * ptrimeshcontacts = GIM_DYNARRAY_POINTER(GIM_CONTACT,trimeshcontacts);
+
+ int contactcount = trimeshcontacts.m_size;
+ int i;
+ //Process contacts
+ for (i=0;i<contactcount ;i++)
+ {
+ //Do something with the contact (ptrimeshcontacts)
+ ......
+ ......
+ // Like creating joints or anything else
+ ......
+ ......
+ ptrimeshcontacts++;
+ }
+ GIM_DYNARRAY_DESTROY(trimeshcontacts);
+ return contactcount;
+}
+\endcode
+In each contact
+<ul>
+<li> m_handle1 points to trimesh1.
+<li> m_handle2 points to trimesh2.
+<li> m_feature1 Is a triangle index of trimesh1.
+<li> m_feature2 Is a triangle index of trimesh2.
+</ul>
+
+\param trimesh1 Collider
+\param trimesh2 Collidee
+\param contacts A GIM_CONTACT array. Must be initialized
+*/
+void gim_trimesh_trimesh_collision(GIM_TRIMESH * trimesh1, GIM_TRIMESH * trimesh2, GDYNAMIC_ARRAY * contacts);
+
+
+//! Trimesh Sphere Collisions
+/*!
+Before use this function you must update the trimesh:
+\code
+gim_trimesh_update(trimesh);
+\endcode
+Then you must use this function in this way:
+\code
+int collide_trimesh_sphere(GIM_TRIMESH * trimesh, vec3f center,GREAL radius)
+{
+ //Create contact list
+ GDYNAMIC_ARRAY trimeshcontacts;
+ GIM_CREATE_CONTACT_LIST(trimeshcontacts);
+
+ //Collide trimeshes
+ gim_trimesh_sphere_collision(trimesh,center,radius,&trimeshcontacts);
+
+ if(trimeshcontacts.m_size == 0) //do nothing
+ {
+ GIM_DYNARRAY_DESTROY(trimeshcontacts);//clean contact array
+ return 0;
+ }
+
+ //Getting a pointer to the contact array
+ GIM_CONTACT * ptrimeshcontacts = GIM_DYNARRAY_POINTER(GIM_CONTACT,trimeshcontacts);
+
+ int contactcount = trimeshcontacts.m_size;
+ int i;
+ //Process contacts
+ for (i=0;i<contactcount ;i++)
+ {
+ //Do something with the contact (ptrimeshcontacts)
+ ......
+ ......
+ // Like creating joints or anything else
+ ......
+ ......
+ ptrimeshcontacts++;
+ }
+ GIM_DYNARRAY_DESTROY(trimeshcontacts);
+ return contactcount;
+}
+\endcode
+
+In each contact
+<ul>
+<li> m_handle1 points to trimesh.
+<li> m_handle2 points to NULL.
+<li> m_feature1 Is a triangle index of trimesh.
+</ul>
+
+\param trimesh
+\param center
+\param radius
+\param contacts A GIM_CONTACT array. Must be initialized
+*/
+void gim_trimesh_sphere_collision(GIM_TRIMESH * trimesh,vec3f center,GREAL radius, GDYNAMIC_ARRAY * contacts);
+
+
+//! Trimesh Capsule collision
+/*!
+Find the closest primitive collided by the ray.
+
+Before use this function you must update the trimesh:
+\code
+gim_trimesh_update(trimesh);
+\endcode
+Then you must use this function in this way:
+\code
+int collide_trimesh_capsule(GIM_TRIMESH * trimesh, GIM_CAPSULE_DATA * capsule)
+{
+ //Create contact list
+ GDYNAMIC_ARRAY trimeshcontacts;
+ GIM_CREATE_CONTACT_LIST(trimeshcontacts);
+
+ //Collide trimeshes
+ gim_trimesh_capsule_collision(trimesh,capsule,&trimeshcontacts);
+
+ if(trimeshcontacts.m_size == 0) //do nothing
+ {
+ GIM_DYNARRAY_DESTROY(trimeshcontacts);//clean contact array
+ return 0;
+ }
+
+ //Getting a pointer to the contact array
+ GIM_CONTACT * ptrimeshcontacts = GIM_DYNARRAY_POINTER(GIM_CONTACT,trimeshcontacts);
+
+ int contactcount = trimeshcontacts.m_size;
+ int i;
+ //Process contacts
+ for (i=0;i<contactcount ;i++)
+ {
+ //Do something with the contact (ptrimeshcontacts)
+ ......
+ ......
+ // Like creating joints or anything else
+ ......
+ ......
+ ptrimeshcontacts++;
+ }
+ GIM_DYNARRAY_DESTROY(trimeshcontacts);
+ return contactcount;
+}
+\endcode
+
+In each contact
+<ul>
+<li> m_handle1 points to trimesh.
+<li> m_handle2 points to NULL.
+<li> m_feature1 Is a triangle index of trimesh.
+</ul>
+
+\param trimesh
+\param capsule
+\param contacts A GIM_CONTACT array. Must be initialized
+*/
+void gim_trimesh_capsule_collision(GIM_TRIMESH * trimesh, GIM_CAPSULE_DATA * capsule, GDYNAMIC_ARRAY * contacts);
+
+
+///Function for create Trimesh Plane collision result
+#define GIM_CREATE_TRIMESHPLANE_CONTACTS(dynarray) GIM_DYNARRAY_CREATE(vec4f,dynarray,G_ARRAY_GROW_SIZE)
+
+//! Trimesh Plane Collisions
+/*!
+
+Before use this function you must update the trimesh:
+\code
+gim_trimesh_update(trimesh);
+\endcode
+Then you must use this function in this way:
+\code
+int collide_trimesh_plane(GIM_TRIMESH * trimesh, vec4f plane)
+{
+ //Create contact list
+ GDYNAMIC_ARRAY tri_plane_contacts;
+ GIM_CREATE_TRIMESHPLANE_CONTACTS(tri_plane_contacts);
+
+ //Collide trimeshes
+ gim_trimesh_plane_collision(trimesh,plane,&tri_plane_contacts);
+
+ if(tri_plane_contacts.m_size == 0) //do nothing
+ {
+ GIM_DYNARRAY_DESTROY(tri_plane_contacts);//clean contact array
+ return 0;
+ }
+
+ //Getting a pointer to the contact array
+ vec4f * planecontacts = GIM_DYNARRAY_POINTER(vec4f,tri_plane_contacts);
+
+ int contactcount = tri_plane_contacts.m_size;
+ int i;
+ //Process contacts
+ for (i=0;i<contactcount ;i++)
+ {
+ vec3f contactpoint;
+ GREAL contactdis;
+
+ VEC_COPY(contactpoint,planecontacts[i]); //Get contact point
+ contactdis = planecontacts[i][3]; // Get distance depth
+
+ //Do something with the contact
+ ......
+ ......
+ // Like creating joints or anything else
+ ......
+ ......
+ }
+ GIM_DYNARRAY_DESTROY(tri_plane_contacts);
+ return contactcount;
+}
+\endcode
+
+In each contact the 3 first coordinates refers to the contact point, the fourth refers to the distance depth and the normal is the normal of the plane.
+
+\param trimesh
+\param plane vec4f plane
+\param contacts A vec4f array. Must be initialized (~100). Each element have the coordinate point in the first 3 elements, and vec4f[3] has the penetration depth.
+*/
+void gim_trimesh_plane_collision(GIM_TRIMESH * trimesh,vec4f plane, GDYNAMIC_ARRAY * contacts);
+
+
+//! Trimesh Ray Collisions
+/*!
+\param trimesh
+\param origin
+\param dir
+\param tmax
+\param contact
+\return 1 if the ray collides, else 0
+*/
+int gim_trimesh_ray_collision(GIM_TRIMESH * trimesh,vec3f origin,vec3f dir, GREAL tmax, GIM_TRIANGLE_RAY_CONTACT_DATA * contact);
+
+
+//! Trimesh Ray Collisions closest
+/*!
+Find the closest primitive collided by the ray
+\param trimesh
+\param origin
+\param dir
+\param tmax
+\param contact
+\return 1 if the ray collides, else 0
+*/
+int gim_trimesh_ray_closest_collision(GIM_TRIMESH * trimesh,vec3f origin,vec3f dir, GREAL tmax, GIM_TRIANGLE_RAY_CONTACT_DATA * contact);
+
+//! @}
+
+
+
+#endif // GIM_TRIMESH_H_INCLUDED
diff --git a/libs/ode-0.16.1/GIMPACT/include/GIMPACT/gimpact.h b/libs/ode-0.16.1/GIMPACT/include/GIMPACT/gimpact.h
new file mode 100644
index 0000000..bcd22a1
--- /dev/null
+++ b/libs/ode-0.16.1/GIMPACT/include/GIMPACT/gimpact.h
@@ -0,0 +1,45 @@
+#ifndef GIMPACT_H_INCLUDED
+#define GIMPACT_H_INCLUDED
+
+/*! \file gimpact.h
+\author Francisco León
+*/
+/*
+-----------------------------------------------------------------------------
+This source file is part of GIMPACT Library.
+
+For the latest info, see http://gimpact.sourceforge.net/
+
+Copyright (c) 2006 Francisco Leon. C.C. 80087371.
+email: projectileman@yahoo.com
+
+ 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 GIMPACT-LICENSE-LGPL.TXT.
+ (2) The BSD-style license that is included with this library in
+ the file GIMPACT-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
+ GIMPACT-LICENSE-LGPL.TXT and GIMPACT-LICENSE-BSD.TXT for more details.
+
+-----------------------------------------------------------------------------
+*/
+
+
+#include "GIMPACT/gim_trimesh.h"
+
+/*! \defgroup GIMPACT_INIT
+*/
+//! @{
+//! Call this for initialize GIMPACT system structures.
+void gimpact_init();
+//! Call this for clean GIMPACT system structures.
+void gimpact_terminate();
+//! @}
+#endif // GIMPACT_H_INCLUDED
diff --git a/libs/ode-0.16.1/GIMPACT/include/Makefile.am b/libs/ode-0.16.1/GIMPACT/include/Makefile.am
new file mode 100644
index 0000000..e247258
--- /dev/null
+++ b/libs/ode-0.16.1/GIMPACT/include/Makefile.am
@@ -0,0 +1 @@
+SUBDIRS = GIMPACT
diff --git a/libs/ode-0.16.1/GIMPACT/include/Makefile.in b/libs/ode-0.16.1/GIMPACT/include/Makefile.in
new file mode 100644
index 0000000..79b367d
--- /dev/null
+++ b/libs/ode-0.16.1/GIMPACT/include/Makefile.in
@@ -0,0 +1,640 @@
+# Makefile.in generated by automake 1.15 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2014 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+VPATH = @srcdir@
+am__is_gnu_make = { \
+ if test -z '$(MAKELEVEL)'; then \
+ false; \
+ elif test -n '$(MAKE_HOST)'; then \
+ true; \
+ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+ true; \
+ else \
+ false; \
+ fi; \
+}
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = GIMPACT/include
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \
+ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
+ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
+ $(top_srcdir)/m4/pkg.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/ode/src/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 =
+SOURCES =
+DIST_SOURCES =
+RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \
+ ctags-recursive dvi-recursive html-recursive info-recursive \
+ install-data-recursive install-dvi-recursive \
+ install-exec-recursive install-html-recursive \
+ install-info-recursive install-pdf-recursive \
+ install-ps-recursive install-recursive installcheck-recursive \
+ installdirs-recursive pdf-recursive ps-recursive \
+ tags-recursive uninstall-recursive
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \
+ distclean-recursive maintainer-clean-recursive
+am__recursive_targets = \
+ $(RECURSIVE_TARGETS) \
+ $(RECURSIVE_CLEAN_TARGETS) \
+ $(am__extra_recursive_targets)
+AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \
+ distdir
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates. Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+ BEGIN { nonempty = 0; } \
+ { items[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique. This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+ list='$(am__tagged_files)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+DIST_SUBDIRS = $(SUBDIRS)
+am__DIST_COMMON = $(srcdir)/Makefile.in
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+am__relativize = \
+ dir0=`pwd`; \
+ sed_first='s,^\([^/]*\)/.*$$,\1,'; \
+ sed_rest='s,^[^/]*/*,,'; \
+ sed_last='s,^.*/\([^/]*\)$$,\1,'; \
+ sed_butlast='s,/*[^/]*$$,,'; \
+ while test -n "$$dir1"; do \
+ first=`echo "$$dir1" | sed -e "$$sed_first"`; \
+ if test "$$first" != "."; then \
+ if test "$$first" = ".."; then \
+ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \
+ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \
+ else \
+ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \
+ if test "$$first2" = "$$first"; then \
+ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \
+ else \
+ dir2="../$$dir2"; \
+ fi; \
+ dir0="$$dir0"/"$$first"; \
+ fi; \
+ fi; \
+ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \
+ done; \
+ reldir="$$dir2"
+ACLOCAL = @ACLOCAL@
+ALLOCA = @ALLOCA@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AS = @AS@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CCD_CFLAGS = @CCD_CFLAGS@
+CCD_LIBS = @CCD_LIBS@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DOXYGEN = @DOXYGEN@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+EXTRA_LIBTOOL_LDFLAGS = @EXTRA_LIBTOOL_LDFLAGS@
+FGREP = @FGREP@
+GL_LIBS = @GL_LIBS@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBSTDCXX = @LIBSTDCXX@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+ODE_PRECISION = @ODE_PRECISION@
+ODE_VERSION = @ODE_VERSION@
+ODE_VERSION_INFO = @ODE_VERSION_INFO@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+RANLIB = @RANLIB@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+VERSION = @VERSION@
+WINDRES = @WINDRES@
+X11_CFLAGS = @X11_CFLAGS@
+X11_LIBS = @X11_LIBS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+ac_ct_WINDRES = @ac_ct_WINDRES@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+runstatedir = @runstatedir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+subdirs = @subdirs@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+SUBDIRS = GIMPACT
+all: all-recursive
+
+.SUFFIXES:
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign GIMPACT/include/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --foreign GIMPACT/include/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+# This directory's subdirectories are mostly independent; you can cd
+# into them and run 'make' without going through this Makefile.
+# To change the values of 'make' variables: instead of editing Makefiles,
+# (1) if the variable is set in 'config.status', edit 'config.status'
+# (which will cause the Makefiles to be regenerated when you run 'make');
+# (2) otherwise, pass the desired values on the 'make' command line.
+$(am__recursive_targets):
+ @fail=; \
+ if $(am__make_keepgoing); then \
+ failcom='fail=yes'; \
+ else \
+ failcom='exit 1'; \
+ fi; \
+ dot_seen=no; \
+ target=`echo $@ | sed s/-recursive//`; \
+ case "$@" in \
+ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
+ *) list='$(SUBDIRS)' ;; \
+ esac; \
+ for subdir in $$list; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ dot_seen=yes; \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || eval $$failcom; \
+ done; \
+ if test "$$dot_seen" = "no"; then \
+ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
+ fi; test -z "$$fail"
+
+ID: $(am__tagged_files)
+ $(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-recursive
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ set x; \
+ here=`pwd`; \
+ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
+ include_option=--etags-include; \
+ empty_fix=.; \
+ else \
+ include_option=--include; \
+ empty_fix=; \
+ fi; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ test ! -f $$subdir/TAGS || \
+ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \
+ fi; \
+ done; \
+ $(am__define_uniq_tagged_files); \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: ctags-recursive
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ $(am__define_uniq_tagged_files); \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-recursive
+
+cscopelist-am: $(am__tagged_files)
+ list='$(am__tagged_files)'; \
+ case "$(srcdir)" in \
+ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+ *) sdir=$(subdir)/$(srcdir) ;; \
+ esac; \
+ for i in $$list; do \
+ if test -f "$$i"; then \
+ echo "$(subdir)/$$i"; \
+ else \
+ echo "$$sdir/$$i"; \
+ fi; \
+ done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+ @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ $(am__make_dryrun) \
+ || test -d "$(distdir)/$$subdir" \
+ || $(MKDIR_P) "$(distdir)/$$subdir" \
+ || exit 1; \
+ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \
+ $(am__relativize); \
+ new_distdir=$$reldir; \
+ dir1=$$subdir; dir2="$(top_distdir)"; \
+ $(am__relativize); \
+ new_top_distdir=$$reldir; \
+ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \
+ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \
+ ($(am__cd) $$subdir && \
+ $(MAKE) $(AM_MAKEFLAGS) \
+ top_distdir="$$new_top_distdir" \
+ distdir="$$new_distdir" \
+ am__remove_distdir=: \
+ am__skip_length_check=: \
+ am__skip_mode_fix=: \
+ distdir) \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-recursive
+all-am: Makefile
+installdirs: installdirs-recursive
+installdirs-am:
+install: install-recursive
+install-exec: install-exec-recursive
+install-data: install-data-recursive
+uninstall: uninstall-recursive
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-recursive
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-recursive
+
+clean-am: clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-recursive
+ -rm -f Makefile
+distclean-am: clean-am distclean-generic distclean-tags
+
+dvi: dvi-recursive
+
+dvi-am:
+
+html: html-recursive
+
+html-am:
+
+info: info-recursive
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-recursive
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-recursive
+
+install-html-am:
+
+install-info: install-info-recursive
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-recursive
+
+install-pdf-am:
+
+install-ps: install-ps-recursive
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-recursive
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-recursive
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+pdf: pdf-recursive
+
+pdf-am:
+
+ps: ps-recursive
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: $(am__recursive_targets) install-am install-strip
+
+.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \
+ check-am clean clean-generic clean-libtool cscopelist-am ctags \
+ ctags-am distclean distclean-generic distclean-libtool \
+ distclean-tags distdir dvi dvi-am html html-am info info-am \
+ install install-am install-data install-data-am install-dvi \
+ install-dvi-am install-exec install-exec-am install-html \
+ install-html-am install-info install-info-am install-man \
+ install-pdf install-pdf-am install-ps install-ps-am \
+ install-strip installcheck installcheck-am installdirs \
+ installdirs-am maintainer-clean maintainer-clean-generic \
+ mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \
+ ps ps-am tags tags-am uninstall uninstall-am
+
+.PRECIOUS: Makefile
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/libs/ode-0.16.1/GIMPACT/src/Makefile.am b/libs/ode-0.16.1/GIMPACT/src/Makefile.am
new file mode 100644
index 0000000..2cd230b
--- /dev/null
+++ b/libs/ode-0.16.1/GIMPACT/src/Makefile.am
@@ -0,0 +1,19 @@
+noinst_LTLIBRARIES = libGIMPACT.la
+AM_CPPFLAGS = -fno-strict-aliasing \
+ -I$(top_srcdir)/include \
+ -I$(top_builddir)/include \
+ -I$(top_srcdir)/ode/src \
+ -I$(top_srcdir)/GIMPACT/include
+
+libGIMPACT_la_SOURCES = gim_boxpruning.cpp \
+ gim_contact.cpp \
+ gim_math.cpp \
+ gim_memory.cpp \
+ gim_tri_tri_overlap.cpp \
+ gim_trimesh.cpp \
+ gim_trimesh_capsule_collision.cpp \
+ gim_trimesh_ray_collision.cpp \
+ gim_trimesh_sphere_collision.cpp \
+ gim_trimesh_trimesh_collision.cpp \
+ gimpact.cpp
+
diff --git a/libs/ode-0.16.1/GIMPACT/src/Makefile.in b/libs/ode-0.16.1/GIMPACT/src/Makefile.in
new file mode 100644
index 0000000..70ab49e
--- /dev/null
+++ b/libs/ode-0.16.1/GIMPACT/src/Makefile.in
@@ -0,0 +1,638 @@
+# Makefile.in generated by automake 1.15 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2014 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+VPATH = @srcdir@
+am__is_gnu_make = { \
+ if test -z '$(MAKELEVEL)'; then \
+ false; \
+ elif test -n '$(MAKE_HOST)'; then \
+ true; \
+ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+ true; \
+ else \
+ false; \
+ fi; \
+}
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = GIMPACT/src
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \
+ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
+ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
+ $(top_srcdir)/m4/pkg.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/ode/src/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+LTLIBRARIES = $(noinst_LTLIBRARIES)
+libGIMPACT_la_LIBADD =
+am_libGIMPACT_la_OBJECTS = gim_boxpruning.lo gim_contact.lo \
+ gim_math.lo gim_memory.lo gim_tri_tri_overlap.lo \
+ gim_trimesh.lo gim_trimesh_capsule_collision.lo \
+ gim_trimesh_ray_collision.lo gim_trimesh_sphere_collision.lo \
+ gim_trimesh_trimesh_collision.lo gimpact.lo
+libGIMPACT_la_OBJECTS = $(am_libGIMPACT_la_OBJECTS)
+AM_V_lt = $(am__v_lt_@AM_V@)
+am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+am__v_lt_1 =
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 =
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/ode/src
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CXXFLAGS) $(CXXFLAGS)
+AM_V_CXX = $(am__v_CXX_@AM_V@)
+am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@)
+am__v_CXX_0 = @echo " CXX " $@;
+am__v_CXX_1 =
+CXXLD = $(CXX)
+CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
+ $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CXXLD = $(am__v_CXXLD_@AM_V@)
+am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@)
+am__v_CXXLD_0 = @echo " CXXLD " $@;
+am__v_CXXLD_1 =
+SOURCES = $(libGIMPACT_la_SOURCES)
+DIST_SOURCES = $(libGIMPACT_la_SOURCES)
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates. Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+ BEGIN { nonempty = 0; } \
+ { items[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique. This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+ list='$(am__tagged_files)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ALLOCA = @ALLOCA@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AS = @AS@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CCD_CFLAGS = @CCD_CFLAGS@
+CCD_LIBS = @CCD_LIBS@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DOXYGEN = @DOXYGEN@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+EXTRA_LIBTOOL_LDFLAGS = @EXTRA_LIBTOOL_LDFLAGS@
+FGREP = @FGREP@
+GL_LIBS = @GL_LIBS@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBSTDCXX = @LIBSTDCXX@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+ODE_PRECISION = @ODE_PRECISION@
+ODE_VERSION = @ODE_VERSION@
+ODE_VERSION_INFO = @ODE_VERSION_INFO@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+RANLIB = @RANLIB@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+VERSION = @VERSION@
+WINDRES = @WINDRES@
+X11_CFLAGS = @X11_CFLAGS@
+X11_LIBS = @X11_LIBS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+ac_ct_WINDRES = @ac_ct_WINDRES@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+runstatedir = @runstatedir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+subdirs = @subdirs@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+noinst_LTLIBRARIES = libGIMPACT.la
+AM_CPPFLAGS = -fno-strict-aliasing \
+ -I$(top_srcdir)/include \
+ -I$(top_builddir)/include \
+ -I$(top_srcdir)/ode/src \
+ -I$(top_srcdir)/GIMPACT/include
+
+libGIMPACT_la_SOURCES = gim_boxpruning.cpp \
+ gim_contact.cpp \
+ gim_math.cpp \
+ gim_memory.cpp \
+ gim_tri_tri_overlap.cpp \
+ gim_trimesh.cpp \
+ gim_trimesh_capsule_collision.cpp \
+ gim_trimesh_ray_collision.cpp \
+ gim_trimesh_sphere_collision.cpp \
+ gim_trimesh_trimesh_collision.cpp \
+ gimpact.cpp
+
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .cpp .lo .o .obj
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign GIMPACT/src/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --foreign GIMPACT/src/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+clean-noinstLTLIBRARIES:
+ -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
+ @list='$(noinst_LTLIBRARIES)'; \
+ locs=`for p in $$list; do echo $$p; done | \
+ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+ sort -u`; \
+ test -z "$$locs" || { \
+ echo rm -f $${locs}; \
+ rm -f $${locs}; \
+ }
+
+libGIMPACT.la: $(libGIMPACT_la_OBJECTS) $(libGIMPACT_la_DEPENDENCIES) $(EXTRA_libGIMPACT_la_DEPENDENCIES)
+ $(AM_V_CXXLD)$(CXXLINK) $(libGIMPACT_la_OBJECTS) $(libGIMPACT_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gim_boxpruning.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gim_contact.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gim_math.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gim_memory.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gim_tri_tri_overlap.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gim_trimesh.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gim_trimesh_capsule_collision.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gim_trimesh_ray_collision.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gim_trimesh_sphere_collision.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gim_trimesh_trimesh_collision.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gimpact.Plo@am__quote@
+
+.cpp.o:
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $<
+
+.cpp.obj:
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.cpp.lo:
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LTCXXCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+ID: $(am__tagged_files)
+ $(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ set x; \
+ here=`pwd`; \
+ $(am__define_uniq_tagged_files); \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ $(am__define_uniq_tagged_files); \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+ list='$(am__tagged_files)'; \
+ case "$(srcdir)" in \
+ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+ *) sdir=$(subdir)/$(srcdir) ;; \
+ esac; \
+ for i in $$list; do \
+ if test -f "$$i"; then \
+ echo "$(subdir)/$$i"; \
+ else \
+ echo "$$sdir/$$i"; \
+ fi; \
+ done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(LTLIBRARIES)
+installdirs:
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \
+ clean-libtool clean-noinstLTLIBRARIES cscopelist-am ctags \
+ ctags-am distclean distclean-compile distclean-generic \
+ distclean-libtool distclean-tags distdir dvi dvi-am html \
+ html-am info info-am install install-am install-data \
+ install-data-am install-dvi install-dvi-am install-exec \
+ install-exec-am install-html install-html-am install-info \
+ install-info-am install-man install-pdf install-pdf-am \
+ install-ps install-ps-am install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ tags tags-am uninstall uninstall-am
+
+.PRECIOUS: Makefile
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/libs/ode-0.16.1/GIMPACT/src/gim_boxpruning.cpp b/libs/ode-0.16.1/GIMPACT/src/gim_boxpruning.cpp
new file mode 100644
index 0000000..f2e77d7
--- /dev/null
+++ b/libs/ode-0.16.1/GIMPACT/src/gim_boxpruning.cpp
@@ -0,0 +1,519 @@
+
+/*
+-----------------------------------------------------------------------------
+This source file is part of GIMPACT Library.
+
+For the latest info, see http://gimpact.sourceforge.net/
+
+Copyright (c) 2006 Francisco Leon. C.C. 80087371.
+email: projectileman@yahoo.com
+
+ 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 GIMPACT-LICENSE-LGPL.TXT.
+ (2) The BSD-style license that is included with this library in
+ the file GIMPACT-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
+ GIMPACT-LICENSE-LGPL.TXT and GIMPACT-LICENSE-BSD.TXT for more details.
+
+-----------------------------------------------------------------------------
+*/
+
+
+#include "GIMPACT/gim_boxpruning.h"
+
+
+
+//! Allocate memory for all aabb set.
+void gim_aabbset_alloc(GIM_AABB_SET * aabbset, GUINT32 count)
+{
+ aabbset->m_count = count;
+ aabbset->m_boxes = (aabb3f *)gim_alloc(sizeof(aabb3f)*count);
+
+ if(count<GIM_MIN_SORTED_BIPARTITE_PRUNING_BOXES)
+ {
+ aabbset->m_maxcoords = 0;
+ aabbset->m_sorted_mincoords = 0;
+ }
+ else
+ {
+ aabbset->m_maxcoords = (GUINT32 *)gim_alloc(sizeof(GUINT32)*aabbset->m_count );
+ aabbset->m_sorted_mincoords = (GIM_RSORT_TOKEN *)gim_alloc(sizeof(GIM_RSORT_TOKEN)*aabbset->m_count);
+ }
+ aabbset->m_shared = 0;
+ INVALIDATE_AABB(aabbset->m_global_bound);
+}
+
+//! Destroys the aabb set.
+void gim_aabbset_destroy(GIM_AABB_SET * aabbset)
+{
+ aabbset->m_count = 0;
+ if(aabbset->m_shared==0)
+ {
+ gim_free(aabbset->m_boxes,0);
+ gim_free(aabbset->m_maxcoords,0);
+ gim_free(aabbset->m_sorted_mincoords,0);
+ }
+ aabbset->m_boxes = 0;
+ aabbset->m_sorted_mincoords = 0;
+ aabbset->m_maxcoords = 0;
+}
+
+void gim_aabbset_calc_global_bound(GIM_AABB_SET * aabbset)
+{
+ aabb3f * paabb = aabbset->m_boxes;
+ aabb3f * globalbox = &aabbset->m_global_bound;
+ AABB_COPY((*globalbox),(*paabb));
+
+ GUINT32 count = aabbset->m_count-1;
+ paabb++;
+ while(count)
+ {
+ MERGEBOXES(*globalbox,*paabb)
+ paabb++;
+ count--;
+ }
+}
+
+
+//! Sorts the boxes for box prunning.
+/*!
+1) find the integer representation of the aabb coords
+2) Sorts the min coords
+3) Calcs the global bound
+\pre aabbset must be allocated. And the boxes must be already set.
+\param aabbset
+\param calc_global_bound If 1 , calcs the global bound
+\post If aabbset->m_sorted_mincoords == 0, then it allocs the sorted coordinates
+*/
+void gim_aabbset_sort(GIM_AABB_SET * aabbset, char calc_global_bound)
+{
+ if(aabbset->m_sorted_mincoords == 0)
+ {//allocate
+ aabbset->m_maxcoords = (GUINT32 *)gim_alloc(sizeof(GUINT32)*aabbset->m_count );
+ aabbset->m_sorted_mincoords = (GIM_RSORT_TOKEN *)gim_alloc(sizeof(GIM_RSORT_TOKEN)*aabbset->m_count);
+ }
+
+ GUINT32 i, count = aabbset->m_count;
+ aabb3f * paabb = aabbset->m_boxes;
+ GUINT32 * maxcoords = aabbset->m_maxcoords;
+ GIM_RSORT_TOKEN * sorted_tokens = aabbset->m_sorted_mincoords;
+
+ if(count<860)//Calibrated on a Pentium IV
+ {
+ //Sort by quick sort
+ //Calculate keys
+ for(i=0;i<count;i++)
+ {
+ GIM_CONVERT_VEC3F_GUINT_XZ_UPPER(paabb[i].maxX,paabb[i].maxZ,maxcoords[i]);
+ GIM_CONVERT_VEC3F_GUINT_XZ(paabb[i].minX,paabb[i].minZ,sorted_tokens[i].m_key);
+ sorted_tokens[i].m_value = i;
+ }
+ GIM_QUICK_SORT_ARRAY(GIM_RSORT_TOKEN , sorted_tokens, count, RSORT_TOKEN_COMPARATOR,GIM_DEF_EXCHANGE_MACRO);
+ }
+ else
+ {
+ //Sort by radix sort
+ GIM_RSORT_TOKEN * unsorted = (GIM_RSORT_TOKEN *)gim_alloc(sizeof(GIM_RSORT_TOKEN )*count);
+ //Calculate keys
+ for(i=0;i<count;i++)
+ {
+ GIM_CONVERT_VEC3F_GUINT_XZ_UPPER(paabb[i].maxX,paabb[i].maxZ,maxcoords[i]);
+ GIM_CONVERT_VEC3F_GUINT_XZ(paabb[i].minX,paabb[i].minZ,unsorted[i].m_key);
+ unsorted[i].m_value = i;
+ }
+ GIM_RADIX_SORT_RTOKENS(unsorted,sorted_tokens,count);
+ gim_free(unsorted,0);
+ }
+
+ if(calc_global_bound) gim_aabbset_calc_global_bound(aabbset);
+}
+
+//utility macros
+
+/*#define PUSH_PAIR(i,j,pairset)\
+{\
+ GIM_PAIR _pair={i,j};\
+ GIM_DYNARRAY_PUSH_ITEM(GIM_PAIR,pairset,_pair);\
+}*/
+
+#define PUSH_PAIR(i,j,pairset)\
+{\
+ GIM_DYNARRAY_PUSH_EMPTY(GIM_PAIR,pairset);\
+ GIM_PAIR * _pair = GIM_DYNARRAY_POINTER(GIM_PAIR,pairset) + (pairset).m_size - 1;\
+ _pair->m_index1 = i;\
+ _pair->m_index2 = j;\
+}
+
+#define PUSH_PAIR_INV(i,j,pairset)\
+{\
+ GIM_DYNARRAY_PUSH_EMPTY(GIM_PAIR,pairset);\
+ GIM_PAIR * _pair = GIM_DYNARRAY_POINTER(GIM_PAIR,pairset) + (pairset).m_size - 1;\
+ _pair->m_index1 = j;\
+ _pair->m_index2 = i;\
+}
+
+#define FIND_OVERLAPPING_FOWARD(\
+ curr_index,\
+ test_count,\
+ test_aabb,\
+ max_coord_uint,\
+ sorted_tokens,\
+ aabbarray,\
+ pairset,\
+ push_pair_macro)\
+{\
+ GUINT32 _i = test_count;\
+ char _intersected;\
+ GIM_RSORT_TOKEN * _psorted_tokens = sorted_tokens;\
+ while(_i>0 && max_coord_uint >= _psorted_tokens->m_key)\
+ {\
+ AABBCOLLISION(_intersected,test_aabb,aabbarray[_psorted_tokens->m_value]);\
+ if(_intersected)\
+ {\
+ push_pair_macro(curr_index, _psorted_tokens->m_value,pairset);\
+ }\
+ _psorted_tokens++;\
+ _i--;\
+ }\
+}
+
+//! log(N) Complete box pruning. Returns a list of overlapping pairs of boxes, each box of the pair belongs to the same set.
+/*!
+\pre aabbset must be allocated and sorted, the boxes must be already set.
+\param aabbset Must be sorted. Global bound isn't required
+\param collision_pairs Array of GIM_PAIR elements. Must be initialized before (Reserve size ~ 100)
+*/
+void gim_aabbset_self_intersections_sorted(GIM_AABB_SET * aabbset, GDYNAMIC_ARRAY * collision_pairs)
+{
+ collision_pairs->m_size = 0;
+ GUINT32 count = aabbset->m_count;
+ aabb3f * paabb = aabbset->m_boxes;
+ GUINT32 * maxcoords = aabbset->m_maxcoords;
+ GIM_RSORT_TOKEN * sorted_tokens = aabbset->m_sorted_mincoords;
+ aabb3f test_aabb;
+ while(count>1)
+ {
+ ///current cache variables
+ GUINT32 curr_index = sorted_tokens->m_value;
+ GUINT32 max_coord_uint = maxcoords[curr_index];
+ AABB_COPY(test_aabb,paabb[curr_index]);
+
+ ///next pairs
+ sorted_tokens++;
+ count--;
+ FIND_OVERLAPPING_FOWARD( curr_index, count, test_aabb, max_coord_uint, sorted_tokens , paabb, (*collision_pairs),PUSH_PAIR);
+ }
+}
+
+//! NxN Complete box pruning. Returns a list of overlapping pairs of boxes, each box of the pair belongs to the same set.
+/*!
+\pre aabbset must be allocated, the boxes must be already set.
+\param aabbset Global bound isn't required. Doen't need to be sorted.
+\param collision_pairs Array of GIM_PAIR elements. Must be initialized before (Reserve size ~ 100)
+*/
+void gim_aabbset_self_intersections_brute_force(GIM_AABB_SET * aabbset, GDYNAMIC_ARRAY * collision_pairs)
+{
+ collision_pairs->m_size = 0;
+ GUINT32 i,j;
+ GUINT32 count = aabbset->m_count;
+ aabb3f * paabb = aabbset->m_boxes;
+ char intersected;
+ for (i=0;i< count-1 ;i++ )
+ {
+ for (j=i+1;j<count ;j++ )
+ {
+ AABBCOLLISION(intersected,paabb[i],paabb[j]);
+ if(intersected)
+ {
+ PUSH_PAIR(i,j,(*collision_pairs));
+ }
+ }
+ }
+}
+
+//! log(N) Bipartite box pruning. Returns a list of overlapping pairs of boxes, each box of the pair belongs to a different set.
+/*!
+\pre aabbset1 and aabbset2 must be allocated and sorted, the boxes must be already set.
+\param aabbset1 Must be sorted, Global bound is required.
+\param aabbset2 Must be sorted, Global bound is required.
+\param collision_pairs Array of GIM_PAIR elements. Must be initialized before (Reserve size ~ 100)
+*/
+void gim_aabbset_bipartite_intersections_sorted(GIM_AABB_SET * aabbset1, GIM_AABB_SET * aabbset2, GDYNAMIC_ARRAY * collision_pairs)
+{
+ char intersected;
+ collision_pairs->m_size = 0;
+
+ AABBCOLLISION(intersected,aabbset1->m_global_bound,aabbset2->m_global_bound);
+ if(intersected == 0) return;
+
+ GUINT32 count1 = aabbset1->m_count;
+ aabb3f * paabb1 = aabbset1->m_boxes;
+ GUINT32 * maxcoords1 = aabbset1->m_maxcoords;
+ GIM_RSORT_TOKEN * sorted_tokens1 = aabbset1->m_sorted_mincoords;
+
+ GUINT32 count2 = aabbset2->m_count;
+ aabb3f * paabb2 = aabbset2->m_boxes;
+ GUINT32 * maxcoords2 = aabbset2->m_maxcoords;
+ GIM_RSORT_TOKEN * sorted_tokens2 = aabbset2->m_sorted_mincoords;
+
+ GUINT32 curr_index;
+
+ GUINT32 max_coord_uint;
+ aabb3f test_aabb;
+
+ //Classify boxes
+ //Find Set intersection
+ aabb3f int_abbb;
+ BOXINTERSECTION(aabbset1->m_global_bound,aabbset2->m_global_bound, int_abbb);
+
+ //Clasify set 1
+ GIM_RSORT_TOKEN * classified_tokens1 = (GIM_RSORT_TOKEN *) gim_alloc(sizeof(GIM_RSORT_TOKEN)*count1);
+ GUINT32 i,classified_count1 = 0,classified_count2 = 0;
+
+
+ for (i=0;i<count1;i++ )
+ {
+ curr_index = sorted_tokens1[i].m_value;
+ AABBCOLLISION(intersected,paabb1[curr_index],int_abbb);
+ if(intersected)
+ {
+ classified_tokens1[classified_count1] = sorted_tokens1[i];
+ classified_count1++;
+ }
+ }
+
+ if(classified_count1==0)
+ {
+ gim_free(classified_tokens1 ,0);
+ return; // no pairs
+ }
+
+ //Clasify set 2
+ GIM_RSORT_TOKEN * classified_tokens2 = (GIM_RSORT_TOKEN *) gim_alloc(sizeof(GIM_RSORT_TOKEN)*count2);
+
+ for (i=0;i<count2;i++ )
+ {
+ curr_index = sorted_tokens2[i].m_value;
+ AABBCOLLISION(intersected,paabb2[curr_index],int_abbb);
+ if(intersected)
+ {
+ classified_tokens2[classified_count2] = sorted_tokens2[i];
+ classified_count2++;
+ }
+ }
+
+ if(classified_count2==0)
+ {
+ gim_free(classified_tokens1 ,0);
+ gim_free(classified_tokens2 ,0);
+ return; // no pairs
+ }
+
+ sorted_tokens1 = classified_tokens1;
+ sorted_tokens2 = classified_tokens2;
+
+ while(classified_count1>0&&classified_count2>0)
+ {
+ if(sorted_tokens1->m_key <= sorted_tokens2->m_key)
+ {
+ ///current cache variables
+ curr_index = sorted_tokens1->m_value;
+ max_coord_uint = maxcoords1[curr_index];
+ AABB_COPY(test_aabb,paabb1[curr_index]);
+ ///next pairs
+ sorted_tokens1++;
+ classified_count1--;
+ FIND_OVERLAPPING_FOWARD( curr_index, classified_count2, test_aabb, max_coord_uint, sorted_tokens2 , paabb2, (*collision_pairs), PUSH_PAIR);
+ }
+ else ///Switch test
+ {
+ ///current cache variables
+ curr_index = sorted_tokens2->m_value;
+ max_coord_uint = maxcoords2[curr_index];
+ AABB_COPY(test_aabb,paabb2[curr_index]);
+ ///next pairs
+ sorted_tokens2++;
+ classified_count2--;
+ FIND_OVERLAPPING_FOWARD( curr_index, classified_count1, test_aabb, max_coord_uint, sorted_tokens1 , paabb1, (*collision_pairs), PUSH_PAIR_INV );
+ }
+ }
+ gim_free(classified_tokens1 ,0);
+ gim_free(classified_tokens2 ,0);
+}
+
+//! NxM Bipartite box pruning. Returns a list of overlapping pairs of boxes, each box of the pair belongs to a different set.
+/*!
+\pre aabbset1 and aabbset2 must be allocated and sorted, the boxes must be already set.
+\param aabbset1 Must be sorted, Global bound is required.
+\param aabbset2 Must be sorted, Global bound is required.
+\param collision_pairs Array of GIM_PAIR elements. Must be initialized before (Reserve size ~ 100)
+*/
+void gim_aabbset_bipartite_intersections_brute_force(GIM_AABB_SET * aabbset1,GIM_AABB_SET * aabbset2, GDYNAMIC_ARRAY * collision_pairs)
+{
+ char intersected;
+ collision_pairs->m_size = 0;
+ AABBCOLLISION(intersected,aabbset1->m_global_bound,aabbset2->m_global_bound);
+ if(intersected == 0) return;
+
+ aabb3f int_abbb;
+ //Find Set intersection
+ BOXINTERSECTION(aabbset1->m_global_bound,aabbset2->m_global_bound, int_abbb);
+ //Clasify set 1
+ GUINT32 i,j;
+ GUINT32 classified_count = 0;
+
+ GUINT32 count = aabbset1->m_count;
+ aabb3f * paabb1 = aabbset1->m_boxes;
+ aabb3f * paabb2 = aabbset2->m_boxes;
+
+ GUINT32 * classified = (GUINT32 *) gim_alloc(sizeof(GUINT32)*count);
+
+ for (i=0;i<count;i++ )
+ {
+ AABBCOLLISION(intersected,paabb1[i],int_abbb);
+ if(intersected)
+ {
+ classified[classified_count] = i;
+ classified_count++;
+ }
+ }
+
+ if(classified_count==0)
+ {
+ gim_free(classified,0);
+ return; // no pairs
+ }
+
+ //intesect set2
+ count = aabbset2->m_count;
+ for (i=0;i<count;i++)
+ {
+ AABBCOLLISION(intersected,paabb2[i],int_abbb);
+ if(intersected)
+ {
+ for (j=0;j<classified_count;j++)
+ {
+ AABBCOLLISION(intersected,paabb2[i],paabb1[classified[j]]);
+ if(intersected)
+ {
+ PUSH_PAIR(classified[j],i,(*collision_pairs));
+ }
+ }
+ }
+ }
+ gim_free(classified,0);
+}
+
+
+//! Initalizes the set. Sort Boxes if needed.
+/*!
+\pre aabbset must be allocated. And the boxes must be already set.
+\post If the set has less of GIM_MIN_SORTED_BIPARTITE_PRUNING_BOXES boxes, only calcs the global box,
+ else it Sorts the entire set( Only applicable for large sets)
+*/
+void gim_aabbset_update(GIM_AABB_SET * aabbset)
+{
+ if(aabbset->m_count < GIM_MIN_SORTED_BIPARTITE_PRUNING_BOXES)
+ {//Brute force approach
+ gim_aabbset_calc_global_bound(aabbset);
+ }
+ else
+ {//Sorted force approach
+ gim_aabbset_sort(aabbset,1);
+ }
+}
+
+//! Complete box pruning. Returns a list of overlapping pairs of boxes, each box of the pair belongs to the same set.
+/*!
+This function sorts the set and then it calls to gim_aabbset_self_intersections_brute_force or gim_aabbset_self_intersections_sorted.
+
+\param aabbset Set of boxes. Sorting isn't required.
+\param collision_pairs Array of GIM_PAIR elements. Must be initialized before (Reserve size ~ 100)
+\pre aabbset must be allocated and initialized.
+\post If aabbset->m_count >= GIM_MIN_SORTED_PRUNING_BOXES, then it calls to gim_aabbset_sort and then to gim_aabbset_self_intersections_sorted.
+*/
+void gim_aabbset_self_intersections(GIM_AABB_SET * aabbset, GDYNAMIC_ARRAY * collision_pairs)
+{
+ if(aabbset->m_count < GIM_MIN_SORTED_PRUNING_BOXES)
+ {//Brute force approach
+ gim_aabbset_self_intersections_brute_force(aabbset,collision_pairs);
+ }
+ else
+ {//Sorted force approach
+ gim_aabbset_sort(aabbset,0);
+ gim_aabbset_self_intersections_sorted(aabbset,collision_pairs);
+ }
+}
+
+//! Collides two sets. Returns a list of overlapping pairs of boxes, each box of the pair belongs to a different set.
+/*!
+\pre aabbset1 and aabbset2 must be allocated and updated. See .
+\param aabbset1 Must be sorted, Global bound is required.
+\param aabbset2 Must be sorted, Global bound is required.
+\param collision_pairs Array of GIM_PAIR elements. Must be initialized before (Reserve size ~ 100)
+*/
+void gim_aabbset_bipartite_intersections(GIM_AABB_SET * aabbset1, GIM_AABB_SET * aabbset2, GDYNAMIC_ARRAY * collision_pairs)
+{
+ if(aabbset1->m_sorted_mincoords == 0||aabbset2->m_sorted_mincoords == 0)
+ {//Brute force approach
+ gim_aabbset_bipartite_intersections_brute_force(aabbset1,aabbset2,collision_pairs);
+ }
+ else
+ {//Sorted force approach
+ gim_aabbset_bipartite_intersections_sorted(aabbset1,aabbset2,collision_pairs);
+ }
+}
+
+void gim_aabbset_box_collision(aabb3f *test_aabb, GIM_AABB_SET * aabbset, GDYNAMIC_ARRAY * collided)
+{
+ collided->m_size = 0;
+ char intersected;
+ AABBCOLLISION(intersected,aabbset->m_global_bound,(*test_aabb));
+ if(intersected == 0) return;
+
+ GUINT32 i;
+ GUINT32 count = aabbset->m_count;
+ aabb3f * paabb = aabbset->m_boxes;
+ aabb3f _testaabb;
+ AABB_COPY(_testaabb,*test_aabb);
+
+ for (i=0;i< count;i++ )
+ {
+ AABBCOLLISION(intersected,paabb[i],_testaabb);
+ if(intersected)
+ {
+ GIM_DYNARRAY_PUSH_ITEM(GUINT32,(*collided),i);
+ }
+ }
+}
+
+void gim_aabbset_ray_collision(vec3f vorigin,vec3f vdir, GREAL tmax, GIM_AABB_SET * aabbset, GDYNAMIC_ARRAY * collided)
+{
+ collided->m_size = 0;
+ char intersected;
+ GREAL tparam = 0;
+ BOX_INTERSECTS_RAY(aabbset->m_global_bound, vorigin, vdir, tparam, tmax,intersected);
+ if(intersected==0) return;
+
+ GUINT32 i;
+ GUINT32 count = aabbset->m_count;
+ aabb3f * paabb = aabbset->m_boxes;
+
+ for (i=0;i< count;i++ )
+ {
+ BOX_INTERSECTS_RAY(paabb[i], vorigin, vdir, tparam, tmax,intersected);
+ if(intersected)
+ {
+ GIM_DYNARRAY_PUSH_ITEM(GUINT32,(*collided),i);
+ }
+ }
+ (void)tparam;
+}
diff --git a/libs/ode-0.16.1/GIMPACT/src/gim_contact.cpp b/libs/ode-0.16.1/GIMPACT/src/gim_contact.cpp
new file mode 100644
index 0000000..4b61298
--- /dev/null
+++ b/libs/ode-0.16.1/GIMPACT/src/gim_contact.cpp
@@ -0,0 +1,132 @@
+
+/*
+-----------------------------------------------------------------------------
+This source file is part of GIMPACT Library.
+
+For the latest info, see http://gimpact.sourceforge.net/
+
+Copyright (c) 2006 Francisco Leon. C.C. 80087371.
+email: projectileman@yahoo.com
+
+ 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 GIMPACT-LICENSE-LGPL.TXT.
+ (2) The BSD-style license that is included with this library in
+ the file GIMPACT-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
+ GIMPACT-LICENSE-LGPL.TXT and GIMPACT-LICENSE-BSD.TXT for more details.
+
+-----------------------------------------------------------------------------
+*/
+
+#include "GIMPACT/gim_contact.h"
+
+void gim_merge_contacts(GDYNAMIC_ARRAY * source_contacts,
+ GDYNAMIC_ARRAY * dest_contacts)
+{
+ dest_contacts->m_size = 0;
+
+ GUINT32 source_count = source_contacts->m_size;
+ GIM_CONTACT * psource_contacts = GIM_DYNARRAY_POINTER(GIM_CONTACT,(*source_contacts));
+ //create keys
+ GIM_RSORT_TOKEN * keycontacts = (GIM_RSORT_TOKEN * )gim_alloc(sizeof(GIM_RSORT_TOKEN)*source_count);
+
+ GUINT32 i;
+ for(i=0;i<source_count;i++)
+ {
+ keycontacts[i].m_value = i;
+ GIM_CALC_KEY_CONTACT(psource_contacts[i].m_point,keycontacts[i].m_key);
+ }
+
+ //sort keys
+ GIM_QUICK_SORT_ARRAY(GIM_RSORT_TOKEN , keycontacts, source_count, RSORT_TOKEN_COMPARATOR,GIM_DEF_EXCHANGE_MACRO);
+
+ // Merge contacts
+ GIM_CONTACT * pcontact = 0;
+ GIM_CONTACT * scontact = 0;
+ GUINT32 key,last_key=0;
+
+ for(i=0;i<source_contacts->m_size;i++)
+ {
+ key = keycontacts[i].m_key;
+ scontact = &psource_contacts[keycontacts[i].m_value];
+
+ if(i>0 && last_key == key)
+ {
+ //merge contact
+ if(pcontact->m_depth > scontact->m_depth + CONTACT_DIFF_EPSILON)
+ {
+ GIM_COPY_CONTACTS(pcontact, scontact);
+ }
+ }
+ else
+ {//add new contact
+ GIM_DYNARRAY_PUSH_EMPTY(GIM_CONTACT,(*dest_contacts));
+ pcontact = GIM_DYNARRAY_POINTER_LAST(GIM_CONTACT,(*dest_contacts));
+ GIM_COPY_CONTACTS(pcontact, scontact);
+ }
+ last_key = key;
+ }
+ gim_free(keycontacts,0);
+}
+
+void gim_merge_contacts_unique(GDYNAMIC_ARRAY * source_contacts,
+ GDYNAMIC_ARRAY * dest_contacts)
+{
+ dest_contacts->m_size = 0;
+ //Traverse the source contacts
+ GUINT32 source_count = source_contacts->m_size;
+ if(source_count==0) return;
+
+ GIM_CONTACT * psource_contacts = GIM_DYNARRAY_POINTER(GIM_CONTACT,(*source_contacts));
+
+ //add the unique contact
+ GIM_CONTACT * pcontact = 0;
+ GIM_DYNARRAY_PUSH_EMPTY(GIM_CONTACT,(*dest_contacts));
+ pcontact = GIM_DYNARRAY_POINTER_LAST(GIM_CONTACT,(*dest_contacts));
+ //set the first contact
+ GIM_COPY_CONTACTS(pcontact, psource_contacts);
+
+ if(source_count==1) return;
+ //scale the first contact
+ VEC_SCALE(pcontact->m_normal,pcontact->m_depth,pcontact->m_normal);
+
+ psource_contacts++;
+
+ //Average the contacts
+ GUINT32 i;
+ for(i=1;i<source_count;i++)
+ {
+ VEC_SUM(pcontact->m_point,pcontact->m_point,psource_contacts->m_point);
+ VEC_ACCUM(pcontact->m_normal,psource_contacts->m_depth,psource_contacts->m_normal);
+ psource_contacts++;
+ }
+
+ GREAL divide_average = 1.0f/((GREAL)source_count);
+
+ VEC_SCALE(pcontact->m_point,divide_average,pcontact->m_point);
+
+ pcontact->m_depth = VEC_DOT(pcontact->m_normal,pcontact->m_normal)*divide_average;
+ GIM_SQRT(pcontact->m_depth,pcontact->m_depth);
+
+ VEC_NORMALIZE(pcontact->m_normal);
+
+ /*GREAL normal_len;
+ VEC_INV_LENGTH(pcontact->m_normal,normal_len);
+ VEC_SCALE(pcontact->m_normal,normal_len,pcontact->m_normal);
+
+ //Deep = LEN(normal)/SQRT(source_count)
+ GIM_SQRT(divide_average,divide_average);
+ pcontact->m_depth = divide_average/normal_len;
+ */
+}
+
+
+
diff --git a/libs/ode-0.16.1/GIMPACT/src/gim_math.cpp b/libs/ode-0.16.1/GIMPACT/src/gim_math.cpp
new file mode 100644
index 0000000..18efb2c
--- /dev/null
+++ b/libs/ode-0.16.1/GIMPACT/src/gim_math.cpp
@@ -0,0 +1,60 @@
+/*
+-----------------------------------------------------------------------------
+This source file is part of GIMPACT Library.
+
+For the latest info, see http://gimpact.sourceforge.net/
+
+Copyright (c) 2006 Francisco Leon. C.C. 80087371.
+email: projectileman@yahoo.com
+
+ 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 GIMPACT-LICENSE-LGPL.TXT.
+ (2) The BSD-style license that is included with this library in
+ the file GIMPACT-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
+ GIMPACT-LICENSE-LGPL.TXT and GIMPACT-LICENSE-BSD.TXT for more details.
+
+-----------------------------------------------------------------------------
+*/
+
+
+#include "GIMPACT/gim_math.h"
+#include "stdlib.h"
+#include "time.h"
+
+
+GREAL gim_inv_sqrt(GREAL f)
+{
+ GREAL r;
+ GIM_INV_SQRT(f,r);
+ return r;
+}
+
+GREAL gim_sqrt(GREAL f)
+{
+ GREAL r;
+ GIM_SQRT(f,r);
+ return r;
+}
+
+//!Initializes mathematical functions
+void gim_init_math()
+{
+ srand( static_cast< unsigned int >( time( 0 ) ) );
+}
+
+//! Generates an unit random
+GREAL gim_unit_random()
+{
+ GREAL rn = static_cast< GREAL >( rand() );
+ rn/=(GREAL)RAND_MAX;
+ return rn;
+}
diff --git a/libs/ode-0.16.1/GIMPACT/src/gim_memory.cpp b/libs/ode-0.16.1/GIMPACT/src/gim_memory.cpp
new file mode 100644
index 0000000..cc5188d
--- /dev/null
+++ b/libs/ode-0.16.1/GIMPACT/src/gim_memory.cpp
@@ -0,0 +1,878 @@
+
+/*
+-----------------------------------------------------------------------------
+This source file is part of GIMPACT Library.
+
+For the latest info, see http://gimpact.sourceforge.net/
+
+Copyright (c) 2006 Francisco Leon. C.C. 80087371.
+email: projectileman@yahoo.com
+
+ 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 GIMPACT-LICENSE-LGPL.TXT.
+ (2) The BSD-style license that is included with this library in
+ the file GIMPACT-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
+ GIMPACT-LICENSE-LGPL.TXT and GIMPACT-LICENSE-BSD.TXT for more details.
+
+-----------------------------------------------------------------------------
+*/
+
+
+#include <assert.h>
+#include <stdlib.h>
+#include "GIMPACT/gim_memory.h"
+#include <ode/odeconfig.h>
+#include "config.h"
+//#include "malloc.h"
+//#include "mm_malloc.h"
+
+static gim_alloc_function *g_allocfn = 0;
+// static gim_alloca_function *g_allocafn = 0; -- a nonsense
+static gim_realloc_function *g_reallocfn = 0;
+static gim_free_function *g_freefn = 0;
+
+
+#define VALIDATE_BUFFER_MANAGER(buffer_managers,buffer_manager_id)\
+ if(buffer_manager_id>=G_BUFFER_MANAGER__MAX) return G_BUFFER_OP_INVALID;\
+ GBUFFER_MANAGER_DATA * bm_data;\
+ gim_get_buffer_manager_data(buffer_managers,buffer_manager_id,&bm_data);\
+ if(bm_data == 0) return G_BUFFER_OP_INVALID;\
+
+#define VALIDATE_BUFFER_ID_PT(buffer_id)\
+ GBUFFER_MANAGER_DATA * bm_data = buffer_id->m_bm_data;\
+ if(bm_data == 0) return G_BUFFER_OP_INVALID;\
+ if(buffer_id->m_buffer_id>=bm_data->m_buffer_array.m_size) return G_BUFFER_OP_INVALID;\
+ GBUFFER_DATA * pbuffer = GIM_DYNARRAY_POINTER(GBUFFER_DATA,bm_data->m_buffer_array);\
+ pbuffer += buffer_id->m_buffer_id;\
+ if(pbuffer->m_buffer_handle==0) return G_BUFFER_OP_INVALID;\
+
+
+void GIM_BUFFER_ARRAY_DESTROY(GBUFFER_ARRAY & array_data)
+{
+ gim_buffer_array_unlock(&array_data);
+ gim_buffer_free(&(array_data).m_buffer_id);
+}
+
+void GIM_DYNARRAY_DESTROY(GDYNAMIC_ARRAY & array_data)
+{
+ if(array_data.m_pdata != 0)
+ {
+ gim_free(array_data.m_pdata,0);
+ array_data.m_reserve_size = 0;
+ array_data.m_size = 0;
+ array_data.m_pdata = 0;
+ }
+}
+
+void gim_set_alloc_handler (gim_alloc_function *fn)
+{
+ g_allocfn = fn;
+}
+
+/* -- a nonsense
+void gim_set_alloca_handler (gim_alloca_function *fn)
+{
+ g_allocafn = fn;
+}
+*/
+
+void gim_set_realloc_handler (gim_realloc_function *fn)
+{
+ g_reallocfn = fn;
+}
+
+void gim_set_free_handler (gim_free_function *fn)
+{
+ g_freefn = fn;
+}
+
+gim_alloc_function *gim_get_alloc_handler()
+{
+ return g_allocfn;
+}
+
+/* -- a nonsense
+gim_alloca_function *gim_get_alloca_handler()
+{
+ return g_allocafn;
+}
+*/
+
+gim_realloc_function *gim_get_realloc_handler ()
+{
+ return g_reallocfn;
+}
+
+
+gim_free_function *gim_get_free_handler ()
+{
+ return g_freefn;
+}
+
+
+void * gim_alloc(size_t size)
+{
+ void * ptr;
+/*
+ if (g_allocfn)
+ {
+ ptr = g_allocfn(size);
+ }
+ else
+*/
+ {
+ ptr = malloc(size);//_mm_malloc(size,0);*/
+ }
+ assert(ptr);
+ return ptr;
+}
+
+/* -- a nonsense
+void * gim_alloca(size_t size)
+{
+ if (g_allocafn) return g_allocafn(size); else return alloca(size);
+}
+*/
+
+void * gim_realloc(void *ptr, size_t oldsize, size_t newsize)
+{
+ /*if (g_reallocfn) return g_reallocfn(ptr,oldsize,newsize);
+ else return realloc(ptr,newsize);*/
+ //return realloc(ptr,newsize);
+ void * newptr = gim_alloc(newsize);
+ size_t copysize = newsize> oldsize? oldsize: newsize;
+ memcpy(newptr,ptr,copysize);
+ gim_free(ptr,oldsize);
+ return newptr;
+}
+
+void gim_free(void *ptr, size_t size)
+{
+ if (!ptr) return;
+/* -- if custom allocation function is not used, custom free must not be used too
+ if (g_freefn)
+ {
+ g_freefn(ptr,size);
+ }
+ else
+*/
+ {
+ free(ptr);//_mm_free(ptr);
+ }
+}
+
+///******************************* BUFFER MANAGERS ******************************///
+
+//!** Basic buffer prototype functions
+
+static GPTR _system_buffer_alloc_function(GUINT32 size,int usage)
+{
+ void * newdata = gim_alloc(size);
+ memset(newdata,0,size);
+ return (GPTR)newdata;
+}
+
+static GPTR _system_buffer_alloc_data_function(const void * pdata,GUINT32 size,int usage)
+{
+ void * newdata = gim_alloc(size);
+ memcpy(newdata,pdata,size);
+ return (GPTR)(newdata);
+}
+
+static GPTR _system_buffer_realloc_function(GPTR buffer_handle,GUINT32 oldsize,int old_usage,GUINT32 newsize,int new_usage)
+{
+ void * newdata = gim_realloc(buffer_handle,oldsize,newsize);
+ return (GPTR)(newdata);
+}
+
+static void _system_buffer_free_function(GPTR buffer_handle,GUINT32 size)
+{
+ gim_free(buffer_handle,size);
+}
+
+static char * _system_lock_buffer_function(GPTR buffer_handle,int access)
+{
+ return (char * )(buffer_handle);
+}
+
+
+static void _system_unlock_buffer_function(GPTR buffer_handle)
+{
+}
+
+static void _system_download_from_buffer_function(
+ GPTR source_buffer_handle,
+ GUINT32 source_pos,
+ void * destdata,
+ GUINT32 copysize)
+{
+ char * pdata;
+ pdata = (char *)source_buffer_handle;
+ memcpy(destdata,pdata+source_pos,copysize);
+}
+
+static void _system_upload_to_buffer_function(
+ GPTR dest_buffer_handle,
+ GUINT32 dest_pos,
+ void * sourcedata,
+ GUINT32 copysize)
+{
+ char * pdata;
+ pdata = (char * )dest_buffer_handle;
+ memcpy(pdata+dest_pos,sourcedata,copysize);
+}
+
+static void _system_copy_buffers_function(
+ GPTR source_buffer_handle,
+ GUINT32 source_pos,
+ GPTR dest_buffer_handle,
+ GUINT32 dest_pos,
+ GUINT32 copysize)
+{
+ char * pdata1,*pdata2;
+ pdata1 = (char *)source_buffer_handle;
+ pdata2 = (char *)dest_buffer_handle;
+ memcpy(pdata2+dest_pos,pdata1+source_pos,copysize);
+}
+
+static GPTR _shared_buffer_alloc_function(GUINT32 size,int usage)
+{
+ return 0;
+}
+
+static GPTR _shared_buffer_alloc_data_function(const void * pdata,GUINT32 size,int usage)
+{
+ return (GPTR)pdata;
+}
+
+#if 0
+static GPTR _shared_buffer_realloc_function(GPTR buffer_handle,GUINT32 oldsize,int old_usage,GUINT32 newsize,int new_usage)
+{
+ return 0;
+}
+#endif
+
+static void _shared_buffer_free_function(GPTR buffer_handle,GUINT32 size)
+{
+}
+
+static inline int _is_buffer_manager_data_active(GBUFFER_MANAGER_DATA * bm_data)
+{
+ return bm_data->m_buffer_array.m_pdata != 0;
+}
+
+static inline void _init_buffer_manager_data(GBUFFER_MANAGER_DATA * bm_data)
+{
+ bm_data->m_buffer_array.m_pdata = 0;
+}
+
+static const GBUFFER_MANAGER_PROTOTYPE g_bm_prototypes[G_BUFFER_MANAGER__MAX] =
+{
+ {
+ &_system_buffer_alloc_function, // alloc_fn;
+ &_system_buffer_alloc_data_function, // alloc_data_fn;
+ &_system_buffer_realloc_function, // realloc_fn;
+ &_system_buffer_free_function, // free_fn;
+ &_system_lock_buffer_function, // lock_buffer_fn;
+ &_system_unlock_buffer_function, // unlock_buffer_fn;
+ &_system_download_from_buffer_function, // download_from_buffer_fn;
+ &_system_upload_to_buffer_function, // upload_to_buffer_fn;
+ &_system_copy_buffers_function, // copy_buffers_fn;
+ }, // G_BUFFER_MANAGER_SYSTEM
+
+ {
+ &_shared_buffer_alloc_function, // alloc_fn;
+ &_shared_buffer_alloc_data_function, // alloc_data_fn;
+ &_system_buffer_realloc_function, // realloc_fn;
+ &_shared_buffer_free_function, // free_fn;
+ &_system_lock_buffer_function, // lock_buffer_fn;
+ &_system_unlock_buffer_function, // unlock_buffer_fn;
+ &_system_download_from_buffer_function, // download_from_buffer_fn;
+ &_system_upload_to_buffer_function, // upload_to_buffer_fn;
+ &_system_copy_buffers_function, // copy_buffers_fn;
+ }, // G_BUFFER_MANAGER_SHARED
+};
+
+int gim_is_buffer_manager_active(GBUFFER_MANAGER_DATA buffer_managers[],
+ GUINT32 buffer_manager_id)
+{
+ GBUFFER_MANAGER_DATA * bm_data;
+ bm_data = &buffer_managers[buffer_manager_id];
+ return _is_buffer_manager_data_active(bm_data);
+}
+
+//!** Buffer manager operations
+void gim_create_buffer_manager(GBUFFER_MANAGER_DATA buffer_managers[],
+ GUINT32 buffer_manager_id)
+{
+ GBUFFER_MANAGER_DATA * bm_data;
+ bm_data = &buffer_managers[buffer_manager_id];
+
+ if (_is_buffer_manager_data_active(bm_data))
+ {
+ gim_destroy_buffer_manager(buffer_managers, buffer_manager_id);
+ }
+
+ //CREATE ARRAYS
+ GIM_DYNARRAY_CREATE(GBUFFER_DATA,bm_data->m_buffer_array,G_ARRAY_BUFFERMANAGER_INIT_SIZE);
+ GIM_DYNARRAY_CREATE(GUINT32,bm_data->m_free_positions,G_ARRAY_BUFFERMANAGER_INIT_SIZE);
+ bm_data->m_prototype = g_bm_prototypes + buffer_manager_id;
+ bm_data->m_buffer_manager_id = buffer_manager_id;
+}
+
+void gim_destroy_buffer_manager(GBUFFER_MANAGER_DATA buffer_managers[], GUINT32 buffer_manager_id)
+{
+ GBUFFER_MANAGER_DATA * bm_data;
+ gim_get_buffer_manager_data(buffer_managers,buffer_manager_id,&bm_data);
+ if(bm_data == 0) return;
+ //Destroy all buffers
+
+ GBUFFER_DATA * buffers = GIM_DYNARRAY_POINTER(GBUFFER_DATA,bm_data->m_buffer_array);
+ GUINT32 i, buffer_count = bm_data->m_buffer_array.m_size;
+ for (i=0;i<buffer_count ;i++ )
+ {
+ GBUFFER_DATA * current_buffer = buffers + i;
+ if(current_buffer->m_buffer_handle!=0) //Is active
+ {
+ // free handle
+ bm_data->m_prototype->free_fn(current_buffer->m_buffer_handle,current_buffer->m_size);
+ }
+ }
+
+ //destroy buffer array
+ GIM_DYNARRAY_DESTROY(bm_data->m_buffer_array);
+ //destroy free positions
+ GIM_DYNARRAY_DESTROY(bm_data->m_free_positions);
+}
+void gim_get_buffer_manager_data(GBUFFER_MANAGER_DATA buffer_managers[],
+ GUINT32 buffer_manager_id,GBUFFER_MANAGER_DATA ** pbm_data)
+{
+ GBUFFER_MANAGER_DATA * bm_data;
+ bm_data = &buffer_managers[buffer_manager_id];
+
+ if (_is_buffer_manager_data_active(bm_data))
+ {
+ *pbm_data = bm_data;
+ }
+ else
+ {
+ *pbm_data = 0;
+ }
+}
+
+void gim_init_buffer_managers(GBUFFER_MANAGER_DATA buffer_managers[])
+{
+ GUINT32 i;
+ for (i=0;i<G_BUFFER_MANAGER__MAX;i++)
+ {
+ _init_buffer_manager_data(buffer_managers + i);
+ }
+
+ // Add the two most important buffer managers
+
+ //add system buffer manager
+ gim_create_buffer_manager(buffer_managers,G_BUFFER_MANAGER_SYSTEM );
+
+ //add shared buffer manager
+ gim_create_buffer_manager(buffer_managers,G_BUFFER_MANAGER_SHARED);
+}
+
+void gim_terminate_buffer_managers(GBUFFER_MANAGER_DATA buffer_managers[])
+{
+ GUINT32 i;
+ for (i=0;i<G_BUFFER_MANAGER__MAX;i++)
+ {
+ gim_destroy_buffer_manager(buffer_managers,i);
+ }
+}
+
+//!** Buffer operations
+
+void GET_AVALIABLE_BUFFER_ID(GBUFFER_MANAGER_DATA * buffer_manager, GUINT32 & buffer_id)
+{
+ if(buffer_manager->m_free_positions.m_size>0)\
+ {
+ GUINT32 * _pointer = GIM_DYNARRAY_POINTER(GUINT32,buffer_manager->m_free_positions);
+ buffer_id = _pointer[buffer_manager->m_free_positions.m_size-1];
+ GIM_DYNARRAY_POP_ITEM(buffer_manager->m_free_positions);
+ }
+ else
+ {
+ buffer_id = buffer_manager->m_buffer_array.m_size;
+ GIM_DYNARRAY_PUSH_EMPTY(GBUFFER_DATA,buffer_manager->m_buffer_array);
+ }
+}
+
+GINT32 _validate_buffer_id(GBUFFER_ID * buffer_id,GBUFFER_DATA ** ppbuffer,GBUFFER_MANAGER_DATA ** pbm_data)
+{
+ VALIDATE_BUFFER_ID_PT(buffer_id)
+ *ppbuffer = pbuffer;
+ *pbm_data = bm_data;
+ return G_BUFFER_OP_SUCCESS;
+}
+
+GUINT32 gim_create_buffer(
+ GBUFFER_MANAGER_DATA buffer_managers[],
+ GUINT32 buffer_manager_id,
+ GUINT32 buffer_size,
+ int usage,
+ GBUFFER_ID * buffer_id)
+{
+ VALIDATE_BUFFER_MANAGER(buffer_managers,buffer_manager_id)
+
+ GPTR newbufferhandle = bm_data->m_prototype->alloc_fn(buffer_size,usage);
+ if(newbufferhandle==0) return G_BUFFER_OP_INVALID;
+
+ GET_AVALIABLE_BUFFER_ID(bm_data,buffer_id->m_buffer_id);
+ buffer_id->m_bm_data = bm_data;
+
+ GBUFFER_DATA * pbuffer = GIM_DYNARRAY_POINTER(GBUFFER_DATA,bm_data->m_buffer_array);
+ pbuffer += buffer_id->m_buffer_id ;
+ pbuffer->m_buffer_handle = newbufferhandle;
+ pbuffer->m_size = buffer_size;
+ pbuffer->m_usage = usage;
+ pbuffer->m_lock_count = 0;
+ pbuffer->m_refcount = 0;
+ pbuffer->m_mapped_pointer = 0;
+
+ //set shadow buffer if needed
+
+ if(usage == G_MU_STATIC_READ ||
+ usage == G_MU_STATIC_READ_DYNAMIC_WRITE||
+ usage == G_MU_STATIC_READ_DYNAMIC_WRITE_COPY)
+ {
+ gim_create_common_buffer(buffer_managers,buffer_size,&pbuffer->m_shadow_buffer);
+ }
+ else
+ {
+ pbuffer->m_shadow_buffer.m_bm_data = 0;
+ pbuffer->m_shadow_buffer.m_buffer_id = G_UINT_INFINITY;
+ }
+ return G_BUFFER_OP_SUCCESS;
+}
+
+
+GUINT32 gim_create_buffer_from_data(
+ GBUFFER_MANAGER_DATA buffer_managers[],
+ GUINT32 buffer_manager_id,
+ const void * pdata,
+ GUINT32 buffer_size,
+ int usage,
+ GBUFFER_ID * buffer_id)
+{
+ VALIDATE_BUFFER_MANAGER(buffer_managers,buffer_manager_id)
+
+ GPTR newbufferhandle = bm_data->m_prototype->alloc_data_fn(pdata,buffer_size,usage);
+ if(newbufferhandle==0) return G_BUFFER_OP_INVALID;
+
+ GET_AVALIABLE_BUFFER_ID(bm_data,buffer_id->m_buffer_id);
+ buffer_id->m_bm_data = bm_data;
+
+ GBUFFER_DATA * pbuffer = GIM_DYNARRAY_POINTER(GBUFFER_DATA,bm_data->m_buffer_array);
+ pbuffer += buffer_id->m_buffer_id ;
+ pbuffer->m_buffer_handle = newbufferhandle;
+ pbuffer->m_size = buffer_size;
+ pbuffer->m_usage = usage;
+ pbuffer->m_lock_count = 0;
+ pbuffer->m_mapped_pointer = 0;
+ pbuffer->m_refcount = 0;
+
+ //set shadow buffer if needed
+
+ if(usage == G_MU_STATIC_READ ||
+ usage == G_MU_STATIC_READ_DYNAMIC_WRITE||
+ usage == G_MU_STATIC_READ_DYNAMIC_WRITE_COPY)
+ {
+ gim_create_common_buffer_from_data(buffer_managers,pdata,buffer_size,&pbuffer->m_shadow_buffer);
+ }
+ else
+ {
+ pbuffer->m_shadow_buffer.m_bm_data = 0;
+ pbuffer->m_shadow_buffer.m_buffer_id = G_UINT_INFINITY;
+ }
+ return G_BUFFER_OP_SUCCESS;
+}
+
+GUINT32 gim_create_common_buffer(GBUFFER_MANAGER_DATA buffer_managers[],
+ GUINT32 buffer_size, GBUFFER_ID * buffer_id)
+{
+ return gim_create_buffer(buffer_managers,G_BUFFER_MANAGER_SYSTEM,buffer_size,G_MU_DYNAMIC_READ_WRITE,buffer_id);
+}
+
+GUINT32 gim_create_common_buffer_from_data(GBUFFER_MANAGER_DATA buffer_managers[],
+ const void * pdata, GUINT32 buffer_size, GBUFFER_ID * buffer_id)
+{
+ return gim_create_buffer_from_data(buffer_managers,G_BUFFER_MANAGER_SYSTEM,pdata,buffer_size,G_MU_DYNAMIC_READ_WRITE,buffer_id);
+}
+
+GUINT32 gim_create_shared_buffer_from_data(GBUFFER_MANAGER_DATA buffer_managers[],
+ const void * pdata, GUINT32 buffer_size, GBUFFER_ID * buffer_id)
+{
+ return gim_create_buffer_from_data(buffer_managers,G_BUFFER_MANAGER_SHARED,pdata,buffer_size,G_MU_DYNAMIC_READ_WRITE,buffer_id);
+}
+
+GINT32 gim_buffer_realloc(GBUFFER_ID * buffer_id,GUINT32 newsize)
+{
+ VALIDATE_BUFFER_ID_PT(buffer_id)
+ if(pbuffer->m_lock_count>0) return G_BUFFER_OP_INVALID;
+ GPTR newhandle = buffer_id->m_bm_data->m_prototype->realloc_fn(
+ pbuffer->m_buffer_handle,pbuffer->m_size,pbuffer->m_usage,newsize,pbuffer->m_usage);
+ if(newhandle==0) return G_BUFFER_OP_INVALID;
+ pbuffer->m_buffer_handle = newhandle;
+ //realloc shadow buffer if any
+ gim_buffer_realloc(&pbuffer->m_shadow_buffer,newsize);
+ return G_BUFFER_OP_SUCCESS;
+}
+
+GINT32 gim_buffer_add_ref(GBUFFER_ID * buffer_id)
+{
+ VALIDATE_BUFFER_ID_PT(buffer_id)
+ pbuffer->m_refcount++;
+ return G_BUFFER_OP_SUCCESS;
+}
+
+GINT32 gim_buffer_free(GBUFFER_ID * buffer_id)
+{
+ VALIDATE_BUFFER_ID_PT(buffer_id)
+ if(pbuffer->m_lock_count>0) return G_BUFFER_OP_INVALID;
+ if(pbuffer->m_refcount>0) pbuffer->m_refcount--;
+ if(pbuffer->m_refcount>0) return G_BUFFER_OP_STILLREFCOUNTED;
+
+ buffer_id->m_bm_data->m_prototype->free_fn(
+ pbuffer->m_buffer_handle,pbuffer->m_size);
+ //destroy shadow buffer if needed
+ gim_buffer_free(&pbuffer->m_shadow_buffer);
+ // Obtain a free slot index for a new buffer
+ GIM_DYNARRAY_PUSH_ITEM(GUINT32,bm_data->m_free_positions,buffer_id->m_buffer_id);
+ pbuffer->m_buffer_handle = 0;
+ pbuffer->m_size = 0;
+ pbuffer->m_shadow_buffer.m_bm_data = 0;
+ pbuffer->m_shadow_buffer.m_buffer_id = G_UINT_INFINITY;
+ return G_BUFFER_OP_SUCCESS;
+}
+
+GINT32 gim_lock_buffer(GBUFFER_ID * buffer_id,int access,char ** map_pointer)
+{
+ VALIDATE_BUFFER_ID_PT(buffer_id)
+ if(pbuffer->m_lock_count>0)
+ {
+ if(pbuffer->m_access!=access) return G_BUFFER_OP_INVALID;
+ pbuffer->m_lock_count++;
+ *map_pointer = pbuffer->m_mapped_pointer;
+ return G_BUFFER_OP_SUCCESS;
+ }
+
+ pbuffer->m_access = access;
+
+ GUINT32 result;
+ if(pbuffer->m_usage==G_MU_STATIC_WRITE)
+ {
+ *map_pointer = 0;///no access
+ return G_BUFFER_OP_INVALID;
+ }
+ else if(pbuffer->m_usage==G_MU_STATIC_READ)
+ {
+ if(pbuffer->m_access == G_MA_READ_ONLY)
+ {
+ result = gim_lock_buffer(&pbuffer->m_shadow_buffer,access,map_pointer);
+ if(result!= G_BUFFER_OP_SUCCESS) return G_BUFFER_OP_INVALID;
+ pbuffer->m_mapped_pointer = *map_pointer;
+ pbuffer->m_lock_count++;
+ }
+ else
+ {
+ *map_pointer = 0;
+ return G_BUFFER_OP_INVALID;
+ }
+ }
+ else if(pbuffer->m_usage==G_MU_STATIC_READ_DYNAMIC_WRITE)
+ {
+ if(pbuffer->m_access == G_MA_READ_ONLY)
+ {
+ result = gim_lock_buffer(&pbuffer->m_shadow_buffer,access,map_pointer);
+ if(result!= G_BUFFER_OP_SUCCESS) return G_BUFFER_OP_INVALID;
+ pbuffer->m_mapped_pointer = *map_pointer;
+ pbuffer->m_lock_count++;
+ }
+ else if(pbuffer->m_access == G_MA_WRITE_ONLY)
+ {
+ pbuffer->m_mapped_pointer = buffer_id->m_bm_data->m_prototype->lock_buffer_fn(
+ pbuffer->m_buffer_handle,access);
+ *map_pointer = pbuffer->m_mapped_pointer;
+ pbuffer->m_lock_count++;
+ }
+ else if(pbuffer->m_access == G_MA_READ_WRITE)
+ {
+ *map_pointer = 0;
+ return G_BUFFER_OP_INVALID;
+ }
+ }
+ else if(pbuffer->m_usage==G_MU_STATIC_READ_DYNAMIC_WRITE_COPY)
+ {
+ result = gim_lock_buffer(&pbuffer->m_shadow_buffer,access,map_pointer);
+ if(result!= G_BUFFER_OP_SUCCESS) return G_BUFFER_OP_INVALID;
+ pbuffer->m_mapped_pointer = *map_pointer;
+ pbuffer->m_lock_count++;
+ }
+ else if(pbuffer->m_usage==G_MU_STATIC_WRITE_DYNAMIC_READ)
+ {
+ if(pbuffer->m_access == G_MA_READ_ONLY)
+ {
+ pbuffer->m_mapped_pointer = buffer_id->m_bm_data->m_prototype->lock_buffer_fn(
+ pbuffer->m_buffer_handle,access);
+ *map_pointer = pbuffer->m_mapped_pointer;
+ pbuffer->m_lock_count++;
+ }
+ else
+ {
+ *map_pointer = 0;
+ return G_BUFFER_OP_INVALID;
+ }
+ }
+ else if(pbuffer->m_usage==G_MU_DYNAMIC_READ_WRITE)
+ {
+ pbuffer->m_mapped_pointer = buffer_id->m_bm_data->m_prototype->lock_buffer_fn(
+ pbuffer->m_buffer_handle,access);
+ *map_pointer = pbuffer->m_mapped_pointer;
+ pbuffer->m_lock_count++;
+ }
+ return G_BUFFER_OP_SUCCESS;
+}
+
+GINT32 gim_unlock_buffer(GBUFFER_ID * buffer_id)
+{
+ VALIDATE_BUFFER_ID_PT(buffer_id)
+ if(pbuffer->m_lock_count==0) return G_BUFFER_OP_INVALID;
+
+ if(pbuffer->m_lock_count>1)
+ {
+ pbuffer->m_lock_count--;
+ return G_BUFFER_OP_SUCCESS;
+ }
+
+
+ GUINT32 result;
+ if(pbuffer->m_usage==G_MU_STATIC_WRITE)
+ {
+ pbuffer->m_mapped_pointer = 0;
+ pbuffer->m_lock_count=0;
+ return G_BUFFER_OP_INVALID;
+ }
+ else if(pbuffer->m_usage==G_MU_STATIC_READ)
+ {
+ if(pbuffer->m_access == G_MA_READ_ONLY)
+ {
+ result = gim_unlock_buffer(&pbuffer->m_shadow_buffer);
+ if(result!= G_BUFFER_OP_SUCCESS) return G_BUFFER_OP_INVALID;
+ pbuffer->m_mapped_pointer = 0;
+ pbuffer->m_lock_count=0;
+ }
+ else
+ {
+ pbuffer->m_mapped_pointer = 0;
+ pbuffer->m_lock_count=0;
+ return G_BUFFER_OP_INVALID;
+ }
+ }
+ else if(pbuffer->m_usage==G_MU_STATIC_READ_DYNAMIC_WRITE)
+ {
+ if(pbuffer->m_access == G_MA_READ_ONLY)
+ {
+ result = gim_unlock_buffer(&pbuffer->m_shadow_buffer);
+ if(result!= G_BUFFER_OP_SUCCESS) return G_BUFFER_OP_INVALID;
+ pbuffer->m_mapped_pointer = 0;
+ pbuffer->m_lock_count=0;
+ }
+ else if(pbuffer->m_access == G_MA_WRITE_ONLY)
+ {
+ buffer_id->m_bm_data->m_prototype->unlock_buffer_fn(
+ pbuffer->m_buffer_handle);
+ pbuffer->m_mapped_pointer = 0;
+ pbuffer->m_lock_count=0;
+ }
+ else if(pbuffer->m_access == G_MA_READ_WRITE)
+ {
+ pbuffer->m_mapped_pointer = 0;
+ pbuffer->m_lock_count=0;
+ return G_BUFFER_OP_INVALID;
+ }
+ }
+ else if(pbuffer->m_usage==G_MU_STATIC_READ_DYNAMIC_WRITE_COPY)
+ {
+ result = gim_unlock_buffer(&pbuffer->m_shadow_buffer);
+ if(result!= G_BUFFER_OP_SUCCESS) return G_BUFFER_OP_INVALID;
+ pbuffer->m_mapped_pointer = 0;
+ pbuffer->m_lock_count=0;
+ if(pbuffer->m_access == G_MA_WRITE_ONLY||pbuffer->m_access == G_MA_READ_WRITE)
+ {
+ gim_copy_buffers(&pbuffer->m_shadow_buffer,0,buffer_id,0,pbuffer->m_size);
+ }
+ }
+ else if(pbuffer->m_usage==G_MU_STATIC_WRITE_DYNAMIC_READ)
+ {
+ if(pbuffer->m_access == G_MA_READ_ONLY)
+ {
+ buffer_id->m_bm_data->m_prototype->unlock_buffer_fn(
+ pbuffer->m_buffer_handle);
+ pbuffer->m_mapped_pointer = 0;
+ pbuffer->m_lock_count=0;
+ }
+ else
+ {
+ pbuffer->m_mapped_pointer = 0;
+ pbuffer->m_lock_count=0;
+ return G_BUFFER_OP_INVALID;
+ }
+ }
+ else if(pbuffer->m_usage==G_MU_DYNAMIC_READ_WRITE)
+ {
+ buffer_id->m_bm_data->m_prototype->unlock_buffer_fn(
+ pbuffer->m_buffer_handle);
+ pbuffer->m_mapped_pointer = 0;
+ pbuffer->m_lock_count=0;
+ }
+ return G_BUFFER_OP_SUCCESS;
+}
+
+GINT32 gim_get_buffer_size(GBUFFER_ID * buffer_id,GUINT32 * buffer_size)
+{
+ VALIDATE_BUFFER_ID_PT(buffer_id)
+ *buffer_size = pbuffer->m_size;
+ return G_BUFFER_OP_SUCCESS;
+}
+
+GINT32 gim_get_buffer_is_locked(GBUFFER_ID * buffer_id,GUINT32 * lock_count)
+{
+ VALIDATE_BUFFER_ID_PT(buffer_id)
+ *lock_count = pbuffer->m_lock_count;
+ return G_BUFFER_OP_SUCCESS;
+}
+
+
+GINT32 gim_download_from_buffer(
+ GBUFFER_ID * buffer_id,
+ GUINT32 source_pos,
+ void * destdata,
+ GUINT32 copysize)
+{
+ VALIDATE_BUFFER_ID_PT(buffer_id)
+ buffer_id->m_bm_data->m_prototype->download_from_buffer_fn(
+ pbuffer->m_buffer_handle,source_pos,destdata,copysize);
+ return G_BUFFER_OP_SUCCESS;
+}
+
+GINT32 gim_upload_to_buffer(
+ GBUFFER_ID * buffer_id,
+ GUINT32 dest_pos,
+ void * sourcedata,
+ GUINT32 copysize)
+{
+ VALIDATE_BUFFER_ID_PT(buffer_id)
+ buffer_id->m_bm_data->m_prototype->upload_to_buffer_fn(
+ pbuffer->m_buffer_handle,dest_pos,sourcedata,copysize);
+ return G_BUFFER_OP_SUCCESS;
+}
+
+GINT32 gim_copy_buffers(
+ GBUFFER_ID * source_buffer_id,
+ GUINT32 source_pos,
+ GBUFFER_ID * dest_buffer_id,
+ GUINT32 dest_pos,
+ GUINT32 copysize)
+{
+ GBUFFER_MANAGER_DATA * bm_data1,* bm_data2;
+ GBUFFER_DATA * pbuffer1, * pbuffer2;
+ void * tempdata;
+ if(_validate_buffer_id(source_buffer_id,&pbuffer1,&bm_data1)!= G_BUFFER_OP_SUCCESS) return G_BUFFER_OP_INVALID;
+
+ if(_validate_buffer_id(dest_buffer_id,&pbuffer2,&bm_data2)!= G_BUFFER_OP_SUCCESS) return G_BUFFER_OP_INVALID;
+
+ if((bm_data1->m_buffer_manager_id == bm_data2->m_buffer_manager_id)||
+ (bm_data1->m_buffer_manager_id == G_BUFFER_MANAGER_SYSTEM && bm_data2->m_buffer_manager_id == G_BUFFER_MANAGER_SHARED)||
+ (bm_data1->m_buffer_manager_id == G_BUFFER_MANAGER_SHARED && bm_data2->m_buffer_manager_id == G_BUFFER_MANAGER_SYSTEM)
+ )
+ {//smooth copy
+ bm_data1->m_prototype->copy_buffers_fn(
+ pbuffer1->m_buffer_handle,source_pos,pbuffer2->m_buffer_handle,dest_pos,copysize);
+ }
+ else if(bm_data1->m_buffer_manager_id == G_BUFFER_MANAGER_SYSTEM ||
+ bm_data1->m_buffer_manager_id == G_BUFFER_MANAGER_SHARED)
+ {
+ //hard copy
+ tempdata = (void *)pbuffer1->m_buffer_handle;
+ //upload data
+ bm_data2->m_prototype->upload_to_buffer_fn(
+ pbuffer2->m_buffer_handle,dest_pos,tempdata,copysize);
+ }
+ else
+ {
+ //very hard copy
+ void * tempdata = gim_alloc(copysize);
+ //download data
+ bm_data1->m_prototype->download_from_buffer_fn(
+ pbuffer1->m_buffer_handle,source_pos,tempdata,copysize);
+
+ //upload data
+ bm_data2->m_prototype->upload_to_buffer_fn(
+ pbuffer2->m_buffer_handle,dest_pos,tempdata,copysize);
+ //delete temp buffer
+ gim_free(tempdata,copysize);
+ }
+ return G_BUFFER_OP_SUCCESS;
+}
+
+GINT32 gim_buffer_array_lock(GBUFFER_ARRAY * array_data, int access)
+{
+ if(array_data->m_buffer_data != 0) return G_BUFFER_OP_SUCCESS;
+ GINT32 result = gim_lock_buffer(&array_data->m_buffer_id,access,&array_data->m_buffer_data);
+ if(result!= G_BUFFER_OP_SUCCESS) return result;
+ array_data->m_buffer_data += array_data->m_byte_offset;
+ return result;
+}
+
+GINT32 gim_buffer_array_unlock(GBUFFER_ARRAY * array_data)
+{
+ if(array_data->m_buffer_data == 0) return G_BUFFER_OP_SUCCESS;
+ GINT32 result = gim_unlock_buffer(&array_data->m_buffer_id);
+ if(result!= G_BUFFER_OP_SUCCESS) return result;
+ array_data->m_buffer_data = 0;
+ return result;
+}
+
+void gim_buffer_array_copy_ref(GBUFFER_ARRAY * source_data,GBUFFER_ARRAY * dest_data)
+{
+ dest_data->m_buffer_id.m_buffer_id = source_data->m_buffer_id.m_buffer_id;
+ dest_data->m_buffer_id.m_bm_data = source_data->m_buffer_id.m_bm_data;
+ dest_data->m_buffer_data = 0;
+ dest_data->m_byte_stride = source_data->m_byte_stride;
+ dest_data->m_byte_offset = source_data->m_byte_offset;
+ dest_data->m_element_count = source_data->m_element_count;
+ gim_buffer_add_ref(&dest_data->m_buffer_id);
+}
+
+void gim_buffer_array_copy_value(GBUFFER_ARRAY * source_data,
+ GBUFFER_MANAGER_DATA dest_buffer_managers[],GBUFFER_ARRAY * dest_data,
+ GUINT32 buffer_manager_id,int usage)
+{
+ //Create new buffer
+ GUINT32 buffsize = source_data->m_element_count*source_data->m_byte_stride;
+ gim_create_buffer(dest_buffer_managers,buffer_manager_id,buffsize,usage,&dest_data->m_buffer_id);
+
+ //copy ref data
+ dest_data->m_buffer_data = 0;
+ dest_data->m_byte_stride = source_data->m_byte_stride;
+ dest_data->m_byte_offset = 0;
+ dest_data->m_element_count = source_data->m_element_count;
+ gim_buffer_add_ref(&dest_data->m_buffer_id);
+ //copy buffers
+ gim_copy_buffers(&source_data->m_buffer_id,source_data->m_byte_offset,&dest_data->m_buffer_id,0,buffsize);
+}
diff --git a/libs/ode-0.16.1/GIMPACT/src/gim_tri_tri_overlap.cpp b/libs/ode-0.16.1/GIMPACT/src/gim_tri_tri_overlap.cpp
new file mode 100644
index 0000000..5b4e08d
--- /dev/null
+++ b/libs/ode-0.16.1/GIMPACT/src/gim_tri_tri_overlap.cpp
@@ -0,0 +1,251 @@
+
+/*
+-----------------------------------------------------------------------------
+This source file is part of GIMPACT Library.
+
+For the latest info, see http://gimpact.sourceforge.net/
+
+Copyright (c) 2006 Francisco Leon. C.C. 80087371.
+email: projectileman@yahoo.com
+
+ 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 GIMPACT-LICENSE-LGPL.TXT.
+ (2) The BSD-style license that is included with this library in
+ the file GIMPACT-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
+ GIMPACT-LICENSE-LGPL.TXT and GIMPACT-LICENSE-BSD.TXT for more details.
+
+-----------------------------------------------------------------------------
+*/
+
+#include "GIMPACT/gim_trimesh.h"
+
+
+#define FABS(x) (float(fabs(x))) /* implement as is fastest on your machine */
+
+/* some macros */
+
+#define CLASSIFY_TRIPOINTS_BY_FACE(v1,v2,v3,faceplane,out_of_face)\
+{ \
+ _distances[0] = DISTANCE_PLANE_POINT(faceplane,v1);\
+ _distances[1] = _distances[0] * DISTANCE_PLANE_POINT(faceplane,v2);\
+ _distances[2] = _distances[0] * DISTANCE_PLANE_POINT(faceplane,v3); \
+ if(_distances[1]>0.0f && _distances[2]>0.0f)\
+ {\
+ out_of_face = 1;\
+ }\
+ else\
+ {\
+ out_of_face = 0;\
+ }\
+}\
+
+/* sort so that a<=b */
+#define SORT(a,b) \
+ if(a>b) \
+ { \
+ float c; \
+ c=a; \
+ a=b; \
+ b=c; \
+ }
+
+
+/* this edge to edge test is based on Franlin Antonio's gem:
+ "Faster Line Segment Intersection", in Graphics Gems III,
+ pp. 199-202 */
+#define EDGE_EDGE_TEST(V0,U0,U1) \
+ Bx=U0[i0]-U1[i0]; \
+ By=U0[i1]-U1[i1]; \
+ Cx=V0[i0]-U0[i0]; \
+ Cy=V0[i1]-U0[i1]; \
+ f=Ay*Bx-Ax*By; \
+ d=By*Cx-Bx*Cy; \
+ if((f>0 && d>=0 && d<=f) || (f<0 && d<=0 && d>=f)) \
+ { \
+ e=Ax*Cy-Ay*Cx; \
+ if(f>0) \
+ { \
+ if(e>=0 && e<=f) return 1; \
+ } \
+ else \
+ { \
+ if(e<=0 && e>=f) return 1; \
+ } \
+ }
+
+#define EDGE_AGAINST_TRI_EDGES(V0,V1,U0,U1,U2) \
+{ \
+ float Ax,Ay,Bx,By,Cx,Cy,e,d,f; \
+ Ax=V1[i0]-V0[i0]; \
+ Ay=V1[i1]-V0[i1]; \
+ /* test edge U0,U1 against V0,V1 */ \
+ EDGE_EDGE_TEST(V0,U0,U1); \
+ /* test edge U1,U2 against V0,V1 */ \
+ EDGE_EDGE_TEST(V0,U1,U2); \
+ /* test edge U2,U1 against V0,V1 */ \
+ EDGE_EDGE_TEST(V0,U2,U0); \
+}
+
+#define POINT_IN_TRI(V0,U0,U1,U2) \
+{ \
+ float a,b,c,d0,d1,d2; \
+ /* is T1 completly inside T2? */ \
+ /* check if V0 is inside tri(U0,U1,U2) */ \
+ a=U1[i1]-U0[i1]; \
+ b=-(U1[i0]-U0[i0]); \
+ c=-a*U0[i0]-b*U0[i1]; \
+ d0=a*V0[i0]+b*V0[i1]+c; \
+ \
+ a=U2[i1]-U1[i1]; \
+ b=-(U2[i0]-U1[i0]); \
+ c=-a*U1[i0]-b*U1[i1]; \
+ d1=a*V0[i0]+b*V0[i1]+c; \
+ \
+ a=U0[i1]-U2[i1]; \
+ b=-(U0[i0]-U2[i0]); \
+ c=-a*U2[i0]-b*U2[i1]; \
+ d2=a*V0[i0]+b*V0[i1]+c; \
+ if(d0*d1>0.0) \
+ { \
+ if(d0*d2>0.0) return 1; \
+ } \
+}
+
+int coplanar_tri_tri(GIM_TRIANGLE_DATA *tri1,
+ GIM_TRIANGLE_DATA *tri2)
+{
+ short i0,i1;
+ /* first project onto an axis-aligned plane, that maximizes the area */
+ /* of the triangles, compute indices: i0,i1. */
+ PLANE_MINOR_AXES(tri1->m_planes.m_planes[0], i0, i1);
+
+ /* test all edges of triangle 1 against the edges of triangle 2 */
+ EDGE_AGAINST_TRI_EDGES(tri1->m_vertices[0],tri1->m_vertices[1],tri2->m_vertices[0],tri2->m_vertices[1],tri2->m_vertices[2]);
+ EDGE_AGAINST_TRI_EDGES(tri1->m_vertices[1],tri1->m_vertices[2],tri2->m_vertices[0],tri2->m_vertices[1],tri2->m_vertices[2]);
+ EDGE_AGAINST_TRI_EDGES(tri1->m_vertices[2],tri1->m_vertices[0],tri2->m_vertices[0],tri2->m_vertices[1],tri2->m_vertices[2]);
+
+ /* finally, test if tri1 is totally contained in tri2 or vice versa */
+ POINT_IN_HULL(tri1->m_vertices[0],(&tri2->m_planes.m_planes[1]),3,i0);
+ if(i0==0) return 1;
+
+ POINT_IN_HULL(tri2->m_vertices[0],(&tri1->m_planes.m_planes[1]),3,i0);
+ if(i0==0) return 1;
+
+ return 0;
+}
+
+
+
+#define NEWCOMPUTE_INTERVALS(VV0,VV1,VV2,D0,D1,D2,D0D1,D0D2,A,B,C,X0,X1) \
+{ \
+ if(D0D1>0.0f) \
+ { \
+ /* here we know that D0D2<=0.0 */ \
+ /* that is D0, D1 are on the same side, D2 on the other or on the plane */ \
+ A=VV2; B=(VV0-VV2)*D2; C=(VV1-VV2)*D2; X0=D2-D0; X1=D2-D1; \
+ } \
+ else if(D0D2>0.0f)\
+ { \
+ /* here we know that d0d1<=0.0 */ \
+ A=VV1; B=(VV0-VV1)*D1; C=(VV2-VV1)*D1; X0=D1-D0; X1=D1-D2; \
+ } \
+ else if(D1*D2>0.0f || D0!=0.0f) \
+ { \
+ /* here we know that d0d1<=0.0 or that D0!=0.0 */ \
+ A=VV0; B=(VV1-VV0)*D0; C=(VV2-VV0)*D0; X0=D0-D1; X1=D0-D2; \
+ } \
+ else if(D1!=0.0f) \
+ { \
+ A=VV1; B=(VV0-VV1)*D1; C=(VV2-VV1)*D1; X0=D1-D0; X1=D1-D2; \
+ } \
+ else if(D2!=0.0f) \
+ { \
+ A=VV2; B=(VV0-VV2)*D2; C=(VV1-VV2)*D2; X0=D2-D0; X1=D2-D1; \
+ } \
+ else \
+ { \
+ /* triangles are coplanar */ \
+ return coplanar_tri_tri(tri1,tri2); \
+ } \
+}\
+
+
+
+int gim_triangle_triangle_overlap(
+ GIM_TRIANGLE_DATA *tri1,
+ GIM_TRIANGLE_DATA *tri2)
+{
+ vec3f _distances;
+ char out_of_face;
+ CLASSIFY_TRIPOINTS_BY_FACE(tri1->m_vertices[0],tri1->m_vertices[1],tri1->m_vertices[2],tri2->m_planes.m_planes[0],out_of_face);
+ if(out_of_face==1) return 0;
+
+ CLASSIFY_TRIPOINTS_BY_FACE(tri2->m_vertices[0],tri2->m_vertices[1],tri2->m_vertices[2],tri1->m_planes.m_planes[0],out_of_face);
+ if(out_of_face==1) return 0;
+
+
+ float du0=0,du1=0,du2=0,dv0=0,dv1=0,dv2=0;
+ float D[3];
+ float isect1[2], isect2[2];
+ float du0du1=0,du0du2=0,dv0dv1=0,dv0dv2=0;
+ short index;
+ float vp0,vp1,vp2;
+ float up0,up1,up2;
+ float bb,cc,max;
+
+ /* compute direction of intersection line */
+ VEC_CROSS(D,tri1->m_planes.m_planes[0],tri2->m_planes.m_planes[0]);
+
+ /* compute and index to the largest component of D */
+ max=(float)FABS(D[0]);
+ index=0;
+ bb=(float)FABS(D[1]);
+ cc=(float)FABS(D[2]);
+ if(bb>max) max=bb,index=1;
+ if(cc>max) max=cc,index=2;
+
+ /* this is the simplified projection onto L*/
+ vp0= tri1->m_vertices[0][index];
+ vp1= tri1->m_vertices[1][index];
+ vp2= tri1->m_vertices[2][index];
+
+ up0= tri2->m_vertices[0][index];
+ up1= tri2->m_vertices[1][index];
+ up2= tri2->m_vertices[2][index];
+
+ /* compute interval for triangle 1 */
+ float a,b,c,x0,x1;
+ NEWCOMPUTE_INTERVALS(vp0,vp1,vp2,dv0,dv1,dv2,dv0dv1,dv0dv2,a,b,c,x0,x1);
+
+ /* compute interval for triangle 2 */
+ float d,e,f,y0,y1;
+ NEWCOMPUTE_INTERVALS(up0,up1,up2,du0,du1,du2,du0du1,du0du2,d,e,f,y0,y1);
+
+ float xx,yy,xxyy,tmp;
+ xx=x0*x1;
+ yy=y0*y1;
+ xxyy=xx*yy;
+
+ tmp=a*xxyy;
+ isect1[0]=tmp+b*x1*yy;
+ isect1[1]=tmp+c*x0*yy;
+
+ tmp=d*xxyy;
+ isect2[0]=tmp+e*xx*y1;
+ isect2[1]=tmp+f*xx*y0;
+
+ SORT(isect1[0],isect1[1]);
+ SORT(isect2[0],isect2[1]);
+
+ if(isect1[1]<isect2[0] || isect2[1]<isect1[0]) return 0;
+ return 1;
+}
diff --git a/libs/ode-0.16.1/GIMPACT/src/gim_trimesh.cpp b/libs/ode-0.16.1/GIMPACT/src/gim_trimesh.cpp
new file mode 100644
index 0000000..7be639b
--- /dev/null
+++ b/libs/ode-0.16.1/GIMPACT/src/gim_trimesh.cpp
@@ -0,0 +1,391 @@
+
+/*
+-----------------------------------------------------------------------------
+This source file is part of GIMPACT Library.
+
+For the latest info, see http://gimpact.sourceforge.net/
+
+Copyright (c) 2006 Francisco Leon. C.C. 80087371.
+email: projectileman@yahoo.com
+
+ 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 GIMPACT-LICENSE-LGPL.TXT.
+ (2) The BSD-style license that is included with this library in
+ the file GIMPACT-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
+ GIMPACT-LICENSE-LGPL.TXT and GIMPACT-LICENSE-BSD.TXT for more details.
+
+-----------------------------------------------------------------------------
+*/
+
+
+#include <assert.h>
+#include "GIMPACT/gim_trimesh.h"
+
+GUINT32 gim_trimesh_get_triangle_count(GIM_TRIMESH * trimesh)
+{
+ return trimesh->m_tri_index_buffer.m_element_count/3;
+}
+
+//! Creates the aabb set and the triangles cache
+/*!
+
+\param trimesh
+\param vertex_array
+\param triindex_array
+\param transformed_reply If 1, then the m_transformed_vertices is a reply of the source vertices. Else it just be a reference to the original array.
+\post it copies the arrays by reference, and creates the auxiliary data (m_aabbset,m_planes_cache_buffer)
+*/
+void gim_trimesh_create_from_arrays(GBUFFER_MANAGER_DATA buffer_managers[],
+ GIM_TRIMESH * trimesh, GBUFFER_ARRAY * vertex_array, GBUFFER_ARRAY * triindex_array,char transformed_reply)
+{
+ assert(trimesh);
+ assert(vertex_array);
+ assert(triindex_array);
+ gim_buffer_array_copy_ref(vertex_array,&trimesh->m_source_vertex_buffer);
+ gim_buffer_array_copy_ref(triindex_array,&trimesh->m_tri_index_buffer);
+
+ trimesh->m_mask = GIM_TRIMESH_NEED_UPDATE;//needs update
+ //Create the transformed vertices
+ if(transformed_reply==1)
+ {
+ trimesh->m_mask |= GIM_TRIMESH_TRANSFORMED_REPLY;
+ gim_buffer_array_copy_value(vertex_array,
+ buffer_managers,&trimesh->m_transformed_vertex_buffer,G_BUFFER_MANAGER_SYSTEM,G_MU_DYNAMIC_READ_WRITE);
+ }
+ else
+ {
+ gim_buffer_array_copy_ref(vertex_array,&trimesh->m_transformed_vertex_buffer);
+ }
+ //create the box set
+ GUINT32 facecount = gim_trimesh_get_triangle_count(trimesh);
+
+ gim_aabbset_alloc(&trimesh->m_aabbset,facecount);
+ //create the planes cache
+ GIM_DYNARRAY_CREATE_SIZED(GIM_TRIPLANES_CACHE,trimesh->m_planes_cache_buffer,facecount);
+ //Create the bitset
+ GIM_BITSET_CREATE_SIZED(trimesh->m_planes_cache_bitset,facecount);
+ //Callback is 0
+ trimesh->m_update_callback = 0;
+ //set to identity
+ IDENTIFY_MATRIX_4X4(trimesh->m_transform);
+}
+
+
+
+//! Create a trimesh from vertex array and an index array
+/*!
+
+\param trimesh An uninitialized GIM_TRIMESH structure
+\param vertex_array A buffer to a vec3f array
+\param vertex_count
+\param triindex_array
+\param index_count
+\param copy_vertices If 1, it copies the source vertices in another buffer. Else (0) it constructs a reference to the data.
+\param copy_indices If 1, it copies the source vertices in another buffer. Else (0) it constructs a reference to the data.
+\param transformed_reply If , then the m_transformed_vertices is a reply of the source vertices. Else it just be a reference to the original array.
+*/
+void gim_trimesh_create_from_data(GBUFFER_MANAGER_DATA buffer_managers[],
+ GIM_TRIMESH * trimesh, vec3f * vertex_array, GUINT32 vertex_count,char copy_vertices,
+ GUINT32 * triindex_array, GUINT32 index_count,char copy_indices,char transformed_reply)
+{
+ GBUFFER_ARRAY buffer_vertex_array;
+ GBUFFER_ARRAY buffer_triindex_array;
+
+ //Create vertices
+ if(copy_vertices == 1)
+ {
+ gim_create_common_buffer_from_data(buffer_managers,
+ vertex_array, vertex_count*sizeof(vec3f), &buffer_vertex_array.m_buffer_id);
+ }
+ else//Create a shared buffer
+ {
+ gim_create_shared_buffer_from_data(buffer_managers,
+ vertex_array, vertex_count*sizeof(vec3f), &buffer_vertex_array.m_buffer_id);
+ }
+ GIM_BUFFER_ARRAY_INIT_TYPE(vec3f,buffer_vertex_array,buffer_vertex_array.m_buffer_id,vertex_count);
+
+
+ //Create vertices
+ if(copy_indices == 1)
+ {
+ gim_create_common_buffer_from_data(buffer_managers,
+ triindex_array, index_count*sizeof(GUINT32), &buffer_triindex_array.m_buffer_id);
+ }
+ else//Create a shared buffer
+ {
+ gim_create_shared_buffer_from_data(buffer_managers,
+ triindex_array, index_count*sizeof(GUINT32), &buffer_triindex_array.m_buffer_id);
+ }
+ GIM_BUFFER_ARRAY_INIT_TYPE(GUINT32,buffer_triindex_array,buffer_triindex_array.m_buffer_id,index_count);
+
+ gim_trimesh_create_from_arrays(buffer_managers, trimesh,
+ &buffer_vertex_array, &buffer_triindex_array,transformed_reply);
+
+ ///always call this after create a buffer_array
+ GIM_BUFFER_ARRAY_DESTROY(buffer_vertex_array);
+ GIM_BUFFER_ARRAY_DESTROY(buffer_triindex_array);
+}
+
+//! Clears auxiliary data and releases buffer arrays
+void gim_trimesh_destroy(GIM_TRIMESH * trimesh)
+{
+ gim_aabbset_destroy(&trimesh->m_aabbset);
+
+ GIM_DYNARRAY_DESTROY(trimesh->m_planes_cache_buffer);
+ GIM_DYNARRAY_DESTROY(trimesh->m_planes_cache_bitset);
+
+ GIM_BUFFER_ARRAY_DESTROY(trimesh->m_transformed_vertex_buffer);
+ GIM_BUFFER_ARRAY_DESTROY(trimesh->m_source_vertex_buffer);
+ GIM_BUFFER_ARRAY_DESTROY(trimesh->m_tri_index_buffer);
+}
+
+//! Copies two meshes
+/*!
+\pre dest_trimesh shouldn't be created
+\post dest_trimesh will be created
+\param source_trimesh
+\param dest_trimesh
+\param copy_by_reference If 1, it attach a reference to the source vertices, else it copies the vertices
+\param transformed_reply IF 1, then it forces the m_trasnformed_vertices to be a reply of the source vertices
+*/
+void gim_trimesh_copy(GIM_TRIMESH * source_trimesh,
+ GBUFFER_MANAGER_DATA dest_buffer_managers[], GIM_TRIMESH * dest_trimesh,
+ char copy_by_reference, char transformed_reply)
+{
+/* -- trimesh can not be copied by reference until GBUFFER_MANAGER_DATA is rewritten
+ to be thread safe and until it is moved back to global variables.
+ if(copy_by_reference==1)
+ {
+ gim_trimesh_create_from_arrays(dest_trimesh, &source_trimesh->m_source_vertex_buffer, &source_trimesh->m_tri_index_buffer,transformed_reply);
+ }
+ else
+*/
+ {
+ GBUFFER_ARRAY buffer_vertex_array;
+ GBUFFER_ARRAY buffer_triindex_array;
+
+ gim_buffer_array_copy_value(&source_trimesh->m_source_vertex_buffer,
+ dest_buffer_managers,&buffer_vertex_array,G_BUFFER_MANAGER_SYSTEM,G_MU_DYNAMIC_READ_WRITE);
+
+ gim_buffer_array_copy_value(&source_trimesh->m_tri_index_buffer,
+ dest_buffer_managers,&buffer_triindex_array,G_BUFFER_MANAGER_SYSTEM,G_MU_DYNAMIC_READ_WRITE);
+
+ gim_trimesh_create_from_arrays(dest_buffer_managers, dest_trimesh,
+ &buffer_vertex_array, &buffer_triindex_array,transformed_reply);
+
+ ///always call this after create a buffer_array
+ GIM_BUFFER_ARRAY_DESTROY(buffer_vertex_array);
+ GIM_BUFFER_ARRAY_DESTROY(buffer_triindex_array);
+ }
+}
+//! Locks the trimesh for working with it
+/*!
+\post locks m_tri_index_buffer and m_transformed_vertex_buffer.
+\param trimesh
+*/
+void gim_trimesh_locks_work_data(GIM_TRIMESH * trimesh)
+{
+ GINT32 res;
+ res=gim_buffer_array_lock(&trimesh->m_tri_index_buffer,G_MA_READ_ONLY);
+ assert(res==G_BUFFER_OP_SUCCESS);
+ res=gim_buffer_array_lock(&trimesh->m_transformed_vertex_buffer,G_MA_READ_ONLY);
+ assert(res==G_BUFFER_OP_SUCCESS);
+}
+
+//! unlocks the trimesh
+/*!
+\post unlocks m_tri_index_buffer and m_transformed_vertex_buffer.
+\param trimesh
+*/
+void gim_trimesh_unlocks_work_data(GIM_TRIMESH * trimesh)
+{
+ gim_buffer_array_unlock(&trimesh->m_tri_index_buffer);
+ gim_buffer_array_unlock(&trimesh->m_transformed_vertex_buffer);
+}
+
+
+//! Returns 1 if the m_transformed_vertex_buffer is a reply of m_source_vertex_buffer
+char gim_trimesh_has_tranformed_reply(GIM_TRIMESH * trimesh)
+{
+ if(trimesh->m_mask&GIM_TRIMESH_TRANSFORMED_REPLY) return 1;
+ return 0;
+}
+
+//! Returns 1 if the trimesh needs to update their aabbset and the planes cache.
+char gim_trimesh_needs_update(GIM_TRIMESH * trimesh)
+{
+ if(trimesh->m_mask&GIM_TRIMESH_NEED_UPDATE) return 1;
+ return 0;
+}
+
+//! Change the state of the trimesh for force it to update
+/*!
+Call it after made changes to the trimesh.
+\post gim_trimesh_need_update(trimesh) will return 1
+*/
+void gim_trimesh_post_update(GIM_TRIMESH * trimesh)
+{
+ trimesh->m_mask |= GIM_TRIMESH_NEED_UPDATE;
+}
+
+//kernel
+#define MULT_MAT_VEC4_KERNEL(_mat,_src,_dst) MAT_DOT_VEC_3X4((_dst),(_mat),(_src))
+
+//! Updates m_transformed_vertex_buffer
+/*!
+\pre m_transformed_vertex_buffer must be unlocked
+*/
+void gim_trimesh_update_vertices(GIM_TRIMESH * trimesh)
+{
+ if(gim_trimesh_has_tranformed_reply(trimesh) == 0) return; //Don't perform transformation
+
+ //Vertices
+ GBUFFER_ARRAY * psource_vertex_buffer = &trimesh->m_source_vertex_buffer;
+ GBUFFER_ARRAY * ptransformed_vertex_buffer = &trimesh->m_transformed_vertex_buffer;
+ //Temp transform
+ mat4f transform;
+ COPY_MATRIX_4X4(transform,trimesh->m_transform);
+
+ GIM_PROCESS_BUFFER_ARRAY(transform,(*psource_vertex_buffer),(*ptransformed_vertex_buffer),MULT_MAT_VEC4_KERNEL,vec3f,vec3f);
+}
+
+//! Updates m_aabbset and m_planes_cache_bitset
+/*!
+\pre gim_trimesh_locks_work_data must be called before
+*/
+void gim_trimesh_update_aabbset(GIM_TRIMESH * trimesh)
+{
+ vec3f * transformed_vertices = GIM_BUFFER_ARRAY_POINTER(vec3f,trimesh->m_transformed_vertex_buffer,0);
+ assert(transformed_vertices);
+
+ GUINT32 * triangle_indices = GIM_BUFFER_ARRAY_POINTER(GUINT32,trimesh->m_tri_index_buffer,0);
+ assert(triangle_indices);
+ // box set
+ aabb3f * paabb = trimesh->m_aabbset.m_boxes;
+ GUINT32 triangle_count = gim_trimesh_get_triangle_count(trimesh);
+ float * v1,*v2,*v3;
+ GUINT32 i;
+ for (i=0; i<triangle_count;i++)
+ {
+ v1 = &transformed_vertices[triangle_indices[0]][0];
+ v2 = &transformed_vertices[triangle_indices[1]][0];
+ v3 = &transformed_vertices[triangle_indices[2]][0];
+ COMPUTEAABB_FOR_TRIANGLE((*paabb),v1,v2,v3);
+ triangle_indices+=3;
+ paabb++;
+ }
+ //Clear planes cache
+ GIM_BITSET_CLEAR_ALL(trimesh->m_planes_cache_bitset);
+ //Sorts set
+ gim_aabbset_update(&trimesh->m_aabbset);
+}
+
+//! Updates the trimesh if needed
+/*!
+\post If gim_trimesh_needs_update returns 1, then it calls gim_trimesh_update_vertices and gim_trimesh_update_aabbset
+*/
+void gim_trimesh_update(GIM_TRIMESH * trimesh)
+{
+ if(gim_trimesh_needs_update(trimesh)==0) return;
+ gim_trimesh_update_vertices(trimesh);
+ gim_trimesh_locks_work_data(trimesh);
+ gim_trimesh_update_aabbset(trimesh);
+ gim_trimesh_unlocks_work_data(trimesh);
+
+ //Clear update flag
+ trimesh->m_mask &= ~GIM_TRIMESH_NEED_UPDATE;
+}
+
+void gim_trimesh_set_tranform(GIM_TRIMESH * trimesh, mat4f transform)
+{
+ GREAL diff = 0.0f;
+ float * originaltrans = &trimesh->m_transform[0][0];
+ float * newtrans = &transform[0][0];
+ GUINT32 i;
+ for (i=0;i<16;i++)
+ {
+ diff += fabs(originaltrans[i]-newtrans[i]);
+ }
+
+// if(IS_ZERO(diff)) return ;///don't need to update
+ if(diff< 0.00001f) return ;///don't need to update
+
+ COPY_MATRIX_4X4(trimesh->m_transform,transform);
+
+ gim_trimesh_post_update(trimesh);
+}
+
+void gim_trimesh_get_triangle_data(GIM_TRIMESH * trimesh, GUINT32 triangle_index, GIM_TRIANGLE_DATA * tri_data)
+{
+ vec3f * transformed_vertices = GIM_BUFFER_ARRAY_POINTER(vec3f,trimesh->m_transformed_vertex_buffer,0);
+
+ GUINT32 * triangle_indices = GIM_BUFFER_ARRAY_POINTER(GUINT32,trimesh->m_tri_index_buffer,triangle_index*3);
+
+
+ //Copy the vertices
+ VEC_COPY(tri_data->m_vertices[0],transformed_vertices[triangle_indices[0]]);
+ VEC_COPY(tri_data->m_vertices[1],transformed_vertices[triangle_indices[1]]);
+ VEC_COPY(tri_data->m_vertices[2],transformed_vertices[triangle_indices[2]]);
+
+ //Get the planes
+ GIM_TRIPLANES_CACHE * planes = GIM_DYNARRAY_POINTER(GIM_TRIPLANES_CACHE,trimesh->m_planes_cache_buffer);
+ planes += triangle_index;
+
+ //verify planes cache
+ GUINT32 bit_eval;
+ GIM_BITSET_GET(trimesh->m_planes_cache_bitset,triangle_index,bit_eval);
+ if(bit_eval == 0)// Needs to calc the planes
+ {
+ //Calc the face plane
+ TRIANGLE_PLANE(tri_data->m_vertices[0],tri_data->m_vertices[1],tri_data->m_vertices[2],planes->m_planes[0]);
+ //Calc the edge 1
+ EDGE_PLANE(tri_data->m_vertices[0],tri_data->m_vertices[1],(planes->m_planes[0]),(planes->m_planes[1]));
+
+ //Calc the edge 2
+ EDGE_PLANE(tri_data->m_vertices[1],tri_data->m_vertices[2],(planes->m_planes[0]),(planes->m_planes[2]));
+
+ //Calc the edge 3
+ EDGE_PLANE(tri_data->m_vertices[2],tri_data->m_vertices[0],(planes->m_planes[0]), (planes->m_planes[3]));
+
+ //mark
+ GIM_BITSET_SET(trimesh->m_planes_cache_bitset,triangle_index);
+ }
+
+
+ VEC_COPY_4((tri_data->m_planes.m_planes[0]),(planes->m_planes[0]));//face plane
+ VEC_COPY_4((tri_data->m_planes.m_planes[1]),(planes->m_planes[1]));//edge1
+ VEC_COPY_4((tri_data->m_planes.m_planes[2]),(planes->m_planes[2]));//edge2
+ VEC_COPY_4((tri_data->m_planes.m_planes[3]),(planes->m_planes[3]));//edge3
+}
+
+void gim_trimesh_get_triangle_vertices(GIM_TRIMESH * trimesh, GUINT32 triangle_index, vec3f v1, vec3f v2, vec3f v3)
+{
+ vec3f * transformed_vertices = GIM_BUFFER_ARRAY_POINTER(vec3f,trimesh->m_transformed_vertex_buffer,0);
+
+ GUINT32 * triangle_indices = GIM_BUFFER_ARRAY_POINTER(GUINT32,trimesh->m_tri_index_buffer,triangle_index*3);
+
+ //Copy the vertices
+ if (v1 != NULL)
+ {
+ VEC_COPY(v1,transformed_vertices[triangle_indices[0]]);
+ }
+
+ if (v2 != NULL)
+ {
+ VEC_COPY(v2,transformed_vertices[triangle_indices[1]]);
+ }
+
+ if (v3 != NULL)
+ {
+ VEC_COPY(v3,transformed_vertices[triangle_indices[2]]);
+ }
+}
diff --git a/libs/ode-0.16.1/GIMPACT/src/gim_trimesh_capsule_collision.cpp b/libs/ode-0.16.1/GIMPACT/src/gim_trimesh_capsule_collision.cpp
new file mode 100644
index 0000000..bc48aa5
--- /dev/null
+++ b/libs/ode-0.16.1/GIMPACT/src/gim_trimesh_capsule_collision.cpp
@@ -0,0 +1,285 @@
+
+/*
+-----------------------------------------------------------------------------
+This source file is part of GIMPACT Library.
+
+For the latest info, see http://gimpact.sourceforge.net/
+
+Copyright (c) 2006 Francisco Leon. C.C. 80087371.
+email: projectileman@yahoo.com
+
+ 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 GIMPACT-LICENSE-LGPL.TXT.
+ (2) The BSD-style license that is included with this library in
+ the file GIMPACT-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
+ GIMPACT-LICENSE-LGPL.TXT and GIMPACT-LICENSE-BSD.TXT for more details.
+
+-----------------------------------------------------------------------------
+*/
+
+#include "GIMPACT/gim_trimesh.h"
+
+//! Utility function for find the closest point between a segment and a triangle
+/*!
+
+\param triangle
+\param s1
+\param s2
+\param contacts Contains the closest points on the segment (1,2), and the normal points to segment, and m_depth contains the distance
+
+\post The contacts array is not set to 0. It adds aditional contacts
+*/
+void gim_closest_point_triangle_segment(GIM_TRIANGLE_DATA * triangle, vec3f s1,vec3f s2, GDYNAMIC_ARRAY * contacts)
+{
+ vec3f segment_points[4] = {{0}};
+ vec3f closest_points[2] = {{0}};
+ GUINT32 intersection_type, out_edge= 10;
+ GREAL dis, dis_temp,perpend;
+ vec4f sdiff;
+
+ dis = DISTANCE_PLANE_POINT(triangle->m_planes.m_planes[0],s1);
+ dis_temp = DISTANCE_PLANE_POINT(triangle->m_planes.m_planes[0],s2);
+
+ if(dis<=0.0f && dis_temp<=0.0f) return;
+
+ VEC_DIFF(sdiff,s2,s1);
+ perpend = VEC_DOT(sdiff,triangle->m_planes.m_planes[0]);
+
+ if(!IS_ZERO(perpend)) // Not perpendicular
+ {
+ if(dis<dis_temp)
+ {
+ VEC_COPY(closest_points[0],s1);
+ }
+ else
+ {
+ dis = dis_temp;
+ VEC_COPY(closest_points[0],s2);
+ }
+
+ //Testing segment vertices over triangle
+ if(dis>=0.0f && dis_temp>=0.0f)
+ {
+ POINT_IN_HULL(closest_points[0],(&triangle->m_planes.m_planes[1]),3,out_edge);
+
+ if(out_edge==0)//Point over face
+ {
+ GIM_PUSH_CONTACT((*contacts),closest_points[0] ,triangle->m_planes.m_planes[0] ,dis,0, 0, 0,0);
+ return;
+ }
+ }
+ else
+ {
+
+ PLANE_CLIP_SEGMENT(s1,s2,triangle->m_planes.m_planes[0],closest_points[1]);
+
+ POINT_IN_HULL(closest_points[1],(&triangle->m_planes.m_planes[1]),3,out_edge);
+
+ if(out_edge==0)//Point over face
+ {
+ GIM_PUSH_CONTACT((*contacts),closest_points[0] ,triangle->m_planes.m_planes[0] ,dis,0, 0, 0,0);
+ return;
+ }
+ }
+
+ }
+ else // Perpendicular Face
+ {
+ //out_edge=10
+ //Clip segment by triangle
+ // Edge1
+ PLANE_CLIP_SEGMENT_CLOSEST(s1,s2,triangle->m_planes.m_planes[1],segment_points[0],segment_points[1],intersection_type);
+ if(intersection_type==0||intersection_type==1)
+ {
+ out_edge = 0;
+ VEC_COPY(closest_points[0],segment_points[0]);
+ }
+ else
+ {
+ //Edge2
+ PLANE_CLIP_SEGMENT_CLOSEST(segment_points[0],segment_points[1],triangle->m_planes.m_planes[2],segment_points[2],segment_points[3],intersection_type);
+ if(intersection_type==0||intersection_type==1)
+ {
+ out_edge = 1;
+ VEC_COPY(closest_points[0],segment_points[3]);
+ }
+ else
+ {
+ //Edge3
+ PLANE_CLIP_SEGMENT_CLOSEST(segment_points[2],segment_points[3],triangle->m_planes.m_planes[3],closest_points[0],closest_points[1],intersection_type);
+ if(intersection_type==0||intersection_type==1)
+ {
+ out_edge = 2;
+ }
+ }
+ }
+ //POST closest_points[0] and closest_points[1] are inside the triangle, if out_edge>2
+ if(out_edge>2) // Over triangle
+ {
+ dis = DISTANCE_PLANE_POINT(triangle->m_planes.m_planes[0],closest_points[0]);
+ GIM_PUSH_CONTACT((*contacts),closest_points[0] ,triangle->m_planes.m_planes[0] ,dis,0, 0, 0,0);
+ GIM_PUSH_CONTACT((*contacts),closest_points[1] ,triangle->m_planes.m_planes[0] ,dis,0, 0, 0,0);
+ return;
+ }
+ }
+
+ //Find closest edges
+ out_edge = 10;
+ dis = G_REAL_INFINITY;
+ GUINT32 i;
+ for(i=0;i<3;i++)
+ {
+ SEGMENT_COLLISION(s1,s2,triangle->m_vertices[i],triangle->m_vertices[(i+1)%3],segment_points[0],segment_points[1]);
+ VEC_DIFF(sdiff,segment_points[0],segment_points[1]);
+ dis_temp = VEC_DOT(sdiff,sdiff);
+ if(dis_temp< dis)
+ {
+ dis = dis_temp;
+ out_edge = i;
+ VEC_COPY(closest_points[0],segment_points[0]);
+ VEC_COPY(closest_points[1],sdiff);//normal
+ }
+ }
+ if(out_edge>2) return ;// ???? ASSERT this please
+
+ if(IS_ZERO(dis))
+ {
+ //Set face plane
+ GIM_PUSH_CONTACT((*contacts),closest_points[0] ,triangle->m_planes.m_planes[0] ,0.0f,0, 0, 0,0);
+
+ }
+ else
+ {
+ GIM_SQRT(dis,dis);
+ VEC_SCALE(closest_points[1],(1.0f/dis),closest_points[1]);//normal
+ GIM_PUSH_CONTACT((*contacts),closest_points[0] ,closest_points[1],dis,0, 0, 0,0);
+ }
+}
+
+
+//! Utility function for find the closest point between a capsule and a triangle
+/*!
+
+\param triangle
+\param capsule
+\param contacts Contains the closest points on the capsule, and the normal points to triangle
+
+\post The contacts array is not set to 0. It adds aditional contacts
+*/
+int gim_triangle_capsule_collision(GIM_TRIANGLE_DATA * triangle, GIM_CAPSULE_DATA * capsule, GDYNAMIC_ARRAY * contacts)
+{
+ GUINT32 old_contact_size = contacts->m_size;
+ gim_closest_point_triangle_segment(triangle,capsule->m_point1,capsule->m_point2,contacts);
+
+ if (contacts->m_size == old_contact_size)
+ {
+ return 0;
+ }
+
+ GIM_CONTACT * pcontact = GIM_DYNARRAY_POINTER(GIM_CONTACT ,(*contacts));
+ pcontact+= old_contact_size;
+
+ if(pcontact->m_depth > capsule->m_radius)
+ {
+ contacts->m_size = old_contact_size;
+ return 0;
+ }
+
+ vec3f vec;
+ while(old_contact_size<contacts->m_size)
+ {
+ //Scale the normal for pointing to triangle
+ VEC_SCALE(pcontact->m_normal,-1.0f,pcontact->m_normal);
+ //Fix the contact point
+ VEC_SCALE(vec,capsule->m_radius,pcontact->m_normal);
+ VEC_SUM(pcontact->m_point,vec,pcontact->m_point);
+ //Fix the depth
+ pcontact->m_depth = capsule->m_radius - pcontact->m_depth;
+
+ pcontact++;
+ old_contact_size++;
+ }
+
+ return 1;
+}
+
+
+//! Trimesh Capsule collision
+/*!
+Find the closest primitive collided by the ray
+\param trimesh
+\param capsule
+\param contact
+\param contacts A GIM_CONTACT array. Must be initialized
+*/
+void gim_trimesh_capsule_collision(GIM_TRIMESH * trimesh, GIM_CAPSULE_DATA * capsule, GDYNAMIC_ARRAY * contacts)
+{
+ contacts->m_size = 0;
+
+ aabb3f test_aabb;
+ CALC_CAPSULE_AABB((*capsule),test_aabb);
+
+ GDYNAMIC_ARRAY collision_result;
+ GIM_CREATE_BOXQUERY_LIST(collision_result);
+
+ gim_aabbset_box_collision(&test_aabb, &trimesh->m_aabbset , &collision_result);
+
+ if(collision_result.m_size==0)
+ {
+ GIM_DYNARRAY_DESTROY(collision_result);
+ }
+
+ //collide triangles
+ //Locks trimesh
+ gim_trimesh_locks_work_data(trimesh);
+ //dummy contacts
+ GDYNAMIC_ARRAY dummycontacts;
+ GIM_CREATE_CONTACT_LIST(dummycontacts);
+
+ int cresult;
+ unsigned int i;
+ GUINT32 * boxesresult = GIM_DYNARRAY_POINTER(GUINT32,collision_result);
+ GIM_TRIANGLE_DATA tri_data;
+ GUINT32 old_contact_size;
+ GIM_CONTACT * pcontact;
+
+ for(i=0;i<collision_result.m_size;i++)
+ {
+ old_contact_size = dummycontacts.m_size;
+ gim_trimesh_get_triangle_data(trimesh,boxesresult[i],&tri_data);
+ cresult = gim_triangle_capsule_collision(&tri_data, capsule, &dummycontacts);
+ if(cresult!=0)
+ {
+ pcontact = GIM_DYNARRAY_POINTER(GIM_CONTACT ,dummycontacts);
+ pcontact+= old_contact_size;
+ while(old_contact_size<dummycontacts.m_size)
+ {
+ pcontact->m_handle1 = trimesh;
+ pcontact->m_handle2 = capsule;
+ pcontact->m_feature1 = boxesresult[i];
+ pcontact->m_feature2 = 0;
+ pcontact++;
+ old_contact_size++;
+ }
+ }
+ }
+ ///unlocks
+ gim_trimesh_unlocks_work_data(trimesh);
+ ///Destroy box result
+ GIM_DYNARRAY_DESTROY(collision_result);
+
+ //merge contacts
+ gim_merge_contacts(&dummycontacts,contacts);
+
+ //Destroy dummy
+ GIM_DYNARRAY_DESTROY(dummycontacts);
+}
diff --git a/libs/ode-0.16.1/GIMPACT/src/gim_trimesh_ray_collision.cpp b/libs/ode-0.16.1/GIMPACT/src/gim_trimesh_ray_collision.cpp
new file mode 100644
index 0000000..e83993e
--- /dev/null
+++ b/libs/ode-0.16.1/GIMPACT/src/gim_trimesh_ray_collision.cpp
@@ -0,0 +1,149 @@
+
+/*
+-----------------------------------------------------------------------------
+This source file is part of GIMPACT Library.
+
+For the latest info, see http://gimpact.sourceforge.net/
+
+Copyright (c) 2006 Francisco Leon. C.C. 80087371.
+email: projectileman@yahoo.com
+
+ 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 GIMPACT-LICENSE-LGPL.TXT.
+ (2) The BSD-style license that is included with this library in
+ the file GIMPACT-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
+ GIMPACT-LICENSE-LGPL.TXT and GIMPACT-LICENSE-BSD.TXT for more details.
+
+-----------------------------------------------------------------------------
+*/
+
+#include "GIMPACT/gim_trimesh.h"
+
+
+//! Trimesh Ray Collisions
+/*!
+
+\param trimesh
+\param contact
+\return 1 if the ray collides, else 0
+*/
+int gim_trimesh_ray_collision(GIM_TRIMESH * trimesh,vec3f origin,vec3f dir, GREAL tmax, GIM_TRIANGLE_RAY_CONTACT_DATA * contact)
+{
+ GDYNAMIC_ARRAY collision_result;
+ GIM_CREATE_BOXQUERY_LIST(collision_result);
+
+ gim_aabbset_ray_collision(origin,dir,tmax,&trimesh->m_aabbset,&collision_result);
+
+ if(collision_result.m_size==0)
+ {
+ GIM_DYNARRAY_DESTROY(collision_result);
+ return 0;
+ }
+
+ //collide triangles
+
+ GUINT32 * boxesresult = GIM_DYNARRAY_POINTER(GUINT32,collision_result);
+ GIM_TRIANGLE_DATA tridata;
+ vec3f pout;
+ GREAL tparam,u,v;
+ char does_intersect;
+
+ gim_trimesh_locks_work_data(trimesh);
+
+ for(unsigned int i=0;i<collision_result.m_size;i++)
+ {
+ gim_trimesh_get_triangle_data(trimesh,boxesresult[i],&tridata);
+
+ // flip plane for correct result in ODE
+ // for more info: martijn@bytehazard.com
+ vec4f flippedPlane;
+ VEC_SCALE_4(flippedPlane, -1.0f, tridata.m_planes.m_planes[0]);
+
+ RAY_TRIANGLE_INTERSECTION(origin,dir,tridata.m_vertices[0],tridata.m_vertices[1],tridata.m_vertices[2],flippedPlane,pout,u,v,tparam,tmax,does_intersect);
+ if(does_intersect)
+ {
+ contact->tparam = tparam;
+ contact->u = u;
+ contact->v = v;
+ contact->m_face_id = boxesresult[i];
+ VEC_COPY(contact->m_point,pout);
+ VEC_COPY(contact->m_normal,flippedPlane);
+
+ gim_trimesh_unlocks_work_data(trimesh);
+ GIM_DYNARRAY_DESTROY(collision_result);
+ return 1;
+ }
+ }
+
+ gim_trimesh_unlocks_work_data(trimesh);
+ GIM_DYNARRAY_DESTROY(collision_result);
+ return 0;//no collisiion
+}
+
+
+//! Trimesh Ray Collisions closest
+/*!
+Find the closest primitive collided by the ray
+\param trimesh
+\param contact
+\return 1 if the ray collides, else 0
+*/
+int gim_trimesh_ray_closest_collision(GIM_TRIMESH * trimesh,vec3f origin,vec3f dir, GREAL tmax, GIM_TRIANGLE_RAY_CONTACT_DATA * contact)
+{
+ GDYNAMIC_ARRAY collision_result;
+ GIM_CREATE_BOXQUERY_LIST(collision_result);
+
+ gim_aabbset_ray_collision(origin,dir,tmax,&trimesh->m_aabbset,&collision_result);
+
+ if(collision_result.m_size==0)
+ {
+ GIM_DYNARRAY_DESTROY(collision_result);
+ return 0;
+ }
+
+ //collide triangles
+
+ GUINT32 * boxesresult = GIM_DYNARRAY_POINTER(GUINT32,collision_result);
+ GIM_TRIANGLE_DATA tridata;
+ vec3f pout;
+ GREAL tparam,u,v;
+ char does_intersect;
+ contact->tparam = tmax + 0.1f;
+
+ gim_trimesh_locks_work_data(trimesh);
+
+ for(unsigned int i=0;i<collision_result.m_size;i++)
+ {
+ gim_trimesh_get_triangle_data(trimesh,boxesresult[i],&tridata);
+
+ // flip plane for correct result in ODE
+ // for more info: martijn@bytehazard.com
+ vec4f flippedPlane;
+ VEC_SCALE_4(flippedPlane, -1.0f, tridata.m_planes.m_planes[0]);
+
+ RAY_TRIANGLE_INTERSECTION(origin,dir,tridata.m_vertices[0],tridata.m_vertices[1],tridata.m_vertices[2],flippedPlane,pout,u,v,tparam,tmax,does_intersect);
+ if(does_intersect && (tparam < contact->tparam))
+ {
+ contact->tparam = tparam;
+ contact->u = u;
+ contact->v = v;
+ contact->m_face_id = boxesresult[i];
+ VEC_COPY(contact->m_point,pout);
+ VEC_COPY(contact->m_normal,flippedPlane);
+ }
+ }
+
+ gim_trimesh_unlocks_work_data(trimesh);
+ GIM_DYNARRAY_DESTROY(collision_result);
+ if(contact->tparam > tmax) return 0;
+ return 1;
+}
diff --git a/libs/ode-0.16.1/GIMPACT/src/gim_trimesh_sphere_collision.cpp b/libs/ode-0.16.1/GIMPACT/src/gim_trimesh_sphere_collision.cpp
new file mode 100644
index 0000000..0d61715
--- /dev/null
+++ b/libs/ode-0.16.1/GIMPACT/src/gim_trimesh_sphere_collision.cpp
@@ -0,0 +1,196 @@
+
+/*
+-----------------------------------------------------------------------------
+This source file is part of GIMPACT Library.
+
+For the latest info, see http://gimpact.sourceforge.net/
+
+Copyright (c) 2006 Francisco Leon. C.C. 80087371.
+email: projectileman@yahoo.com
+
+ 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 GIMPACT-LICENSE-LGPL.TXT.
+ (2) The BSD-style license that is included with this library in
+ the file GIMPACT-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
+ GIMPACT-LICENSE-LGPL.TXT and GIMPACT-LICENSE-BSD.TXT for more details.
+
+-----------------------------------------------------------------------------
+*/
+
+#include "GIMPACT/gim_trimesh.h"
+
+int gim_triangle_sphere_collision(
+ GIM_TRIANGLE_DATA *tri,
+ vec3f center, GREAL radius,
+ GIM_TRIANGLE_CONTACT_DATA * contact_data)
+{
+ contact_data->m_point_count = 0;
+
+ //Find Face plane distance
+ GREAL dis = DISTANCE_PLANE_POINT(tri->m_planes.m_planes[0],center);
+ if(dis>radius) return 0; //out
+ if(dis<-radius) return 0;//Out of triangle
+ contact_data->m_penetration_depth = dis;
+
+ //Find the most edge
+ GUINT32 most_edge = 4;//no edge
+ GREAL max_dis = 0.0f;
+ dis = DISTANCE_PLANE_POINT(tri->m_planes.m_planes[1],center);
+ if(dis>radius) return 0;//Out of triangle
+ if(dis>0.0f)
+ {
+ max_dis = dis;
+ most_edge = 0;
+ }
+
+ dis = DISTANCE_PLANE_POINT(tri->m_planes.m_planes[2],center);
+ if(dis>radius) return 0;//Out of triangle
+ if(dis>max_dis)// && dis>0.0f)
+ {
+ max_dis = dis;
+ most_edge = 1;
+ }
+
+ dis = DISTANCE_PLANE_POINT(tri->m_planes.m_planes[3],center);
+ if(dis>radius) return 0;//Out of triangle
+ if(dis>max_dis)// && dis>0.0f)
+ {
+ max_dis = dis;
+ most_edge = 2;
+ }
+
+ if(most_edge == 4) //Box is into triangle
+ {
+ //contact_data->m_penetration_depth = dis is set above
+ //Find Face plane point
+ VEC_COPY(contact_data->m_separating_normal,tri->m_planes.m_planes[0]);
+ //Find point projection on plane
+ if(contact_data->m_penetration_depth>=0.0f)
+ {
+ VEC_SCALE(contact_data->m_points[0],-radius,contact_data->m_separating_normal);
+ }
+ else
+ {
+ VEC_SCALE(contact_data->m_points[0],radius,contact_data->m_separating_normal);
+ }
+ contact_data->m_penetration_depth = radius - contact_data->m_penetration_depth;
+
+ VEC_SUM(contact_data->m_points[0],contact_data->m_points[0],center);
+ //Scale normal for pointing to triangle
+ VEC_SCALE(contact_data->m_separating_normal,-1.0f,contact_data->m_separating_normal);
+ contact_data->m_point_count = 1;
+ return 1;
+ }
+ //find the edge
+ vec3f e1,e2;
+ VEC_COPY(e1,tri->m_vertices[most_edge]);
+ VEC_COPY(e2,tri->m_vertices[(most_edge+1)%3]);
+
+ CLOSEST_POINT_ON_SEGMENT(contact_data->m_points[0],center,e1,e2);
+ //find distance
+ VEC_DIFF(e1,center,contact_data->m_points[0]);
+ VEC_LENGTH(e1,dis);
+ if(dis>radius) return 0;
+
+ contact_data->m_penetration_depth = radius - dis;
+
+ if(IS_ZERO(dis))
+ {
+ VEC_COPY(contact_data->m_separating_normal,tri->m_planes.m_planes[most_edge+1]);
+ VEC_SCALE(contact_data->m_points[0],-radius,contact_data->m_separating_normal);
+ VEC_SUM(contact_data->m_points[0],contact_data->m_points[0],center);
+ }
+ else
+ {
+ VEC_SCALE(contact_data->m_separating_normal,1.0f/dis,e1);
+ VEC_SCALE(contact_data->m_points[0],-radius,contact_data->m_separating_normal);
+ VEC_SUM(contact_data->m_points[0],contact_data->m_points[0],center);
+ }
+
+ //Scale normal for pointing to triangle
+ VEC_SCALE(contact_data->m_separating_normal,-1.0f,contact_data->m_separating_normal);
+
+ contact_data->m_point_count = 1;
+ return 1;
+
+}
+
+//! Trimesh Sphere Collisions
+/*!
+In each contact
+<ul>
+<li> m_handle1 points to trimesh.
+<li> m_handle2 points to NULL.
+<li> m_feature1 Is a triangle index of trimesh.
+</ul>
+
+\param trimesh
+\param center
+\param radius
+\param contacts A GIM_CONTACT array. Must be initialized
+*/
+void gim_trimesh_sphere_collision(GIM_TRIMESH * trimesh,vec3f center,GREAL radius, GDYNAMIC_ARRAY * contacts)
+{
+ contacts->m_size = 0;
+
+ aabb3f test_aabb;
+ test_aabb.minX = center[0]-radius;
+ test_aabb.maxX = center[0]+radius;
+ test_aabb.minY = center[1]-radius;
+ test_aabb.maxY = center[1]+radius;
+ test_aabb.minZ = center[2]-radius;
+ test_aabb.maxZ = center[2]+radius;
+
+ GDYNAMIC_ARRAY collision_result;
+ GIM_CREATE_BOXQUERY_LIST(collision_result);
+
+ gim_aabbset_box_collision(&test_aabb, &trimesh->m_aabbset , &collision_result);
+
+ if(collision_result.m_size==0)
+ {
+ GIM_DYNARRAY_DESTROY(collision_result);
+ }
+
+ //collide triangles
+ //Locks trimesh
+ gim_trimesh_locks_work_data(trimesh);
+ //dummy contacts
+ GDYNAMIC_ARRAY dummycontacts;
+ GIM_CREATE_CONTACT_LIST(dummycontacts);
+
+ int cresult;
+ unsigned int i;
+ GUINT32 * boxesresult = GIM_DYNARRAY_POINTER(GUINT32,collision_result);
+ GIM_TRIANGLE_CONTACT_DATA tri_contact_data;
+ GIM_TRIANGLE_DATA tri_data;
+
+ for(i=0;i<collision_result.m_size;i++)
+ {
+ gim_trimesh_get_triangle_data(trimesh,boxesresult[i],&tri_data);
+ cresult = gim_triangle_sphere_collision(&tri_data,center,radius,&tri_contact_data);
+ if(cresult!=0)
+ {
+ GIM_PUSH_CONTACT(dummycontacts, tri_contact_data.m_points[0],tri_contact_data.m_separating_normal ,tri_contact_data.m_penetration_depth,trimesh, 0, boxesresult[i],0);
+ }
+ }
+ ///unlocks
+ gim_trimesh_unlocks_work_data(trimesh);
+ ///Destroy box result
+ GIM_DYNARRAY_DESTROY(collision_result);
+
+ //merge contacts
+ gim_merge_contacts(&dummycontacts,contacts);
+
+ //Destroy dummy
+ GIM_DYNARRAY_DESTROY(dummycontacts);
+}
+
diff --git a/libs/ode-0.16.1/GIMPACT/src/gim_trimesh_trimesh_collision.cpp b/libs/ode-0.16.1/GIMPACT/src/gim_trimesh_trimesh_collision.cpp
new file mode 100644
index 0000000..e5e3c06
--- /dev/null
+++ b/libs/ode-0.16.1/GIMPACT/src/gim_trimesh_trimesh_collision.cpp
@@ -0,0 +1,348 @@
+
+/*
+-----------------------------------------------------------------------------
+This source file is part of GIMPACT Library.
+
+For the latest info, see http://gimpact.sourceforge.net/
+
+Copyright (c) 2006 Francisco Leon. C.C. 80087371.
+email: projectileman@yahoo.com
+
+ 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 GIMPACT-LICENSE-LGPL.TXT.
+ (2) The BSD-style license that is included with this library in
+ the file GIMPACT-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
+ GIMPACT-LICENSE-LGPL.TXT and GIMPACT-LICENSE-BSD.TXT for more details.
+
+-----------------------------------------------------------------------------
+*/
+
+#include "GIMPACT/gim_trimesh.h"
+
+#define CLASSIFY_TRI_BY_FACE(v1,v2,v3,faceplane,out_of_face)\
+{ \
+ _distances[0] = DISTANCE_PLANE_POINT(faceplane,v1);\
+ _distances[1] = _distances[0] * DISTANCE_PLANE_POINT(faceplane,v2);\
+ _distances[2] = _distances[0] * DISTANCE_PLANE_POINT(faceplane,v3); \
+ if(_distances[1]>0.0f && _distances[2]>0.0f)\
+ {\
+ out_of_face = 1;\
+ }\
+ else\
+ {\
+ out_of_face = 0;\
+ }\
+}\
+
+
+//! Receives the 3 edge planes
+#define MOST_DEEP_POINTS(plane,points,point_count,deep_points,deep_points_count,maxdeep)\
+{\
+ maxdeep=-1000.0f;\
+ GUINT32 _k;\
+ GREAL _dist;\
+ deep_points_count = 0;\
+ for(_k=0;_k<point_count;_k++)\
+ {\
+ _dist = -DISTANCE_PLANE_POINT(plane,points[_k]);\
+ if(_dist>maxdeep)\
+ {\
+ maxdeep = _dist;\
+ _max_candidates[0] = _k;\
+ deep_points_count=1;\
+ }\
+ else if((_dist+G_EPSILON)>=maxdeep)\
+ {\
+ _max_candidates[deep_points_count] = _k;\
+ deep_points_count++;\
+ }\
+ }\
+ if(maxdeep<0.0f)\
+ {\
+ deep_points_count = 0;\
+ }\
+ else\
+ {\
+ for(_k=0;_k<deep_points_count;_k++)\
+ {\
+ VEC_COPY(deep_points[_k],points[_max_candidates[_k]]);\
+ }\
+ }\
+}\
+
+//! Receives the 3 edge planes
+#define CLIP_TRI_POINTS_BY_TRI_EDGE_PLANES(tri_points,tri_edge_planes, clipped_points, clipped_point_count)\
+{\
+ clipped_point_count = 0; \
+ _temp_clip_count = 0;\
+ PLANE_CLIP_POLYGON(tri_edge_planes[0],tri_points,3,_temp_clip,_temp_clip_count,MAX_TRI_CLIPPING);\
+ if(_temp_clip_count>0)\
+ {\
+ _temp_clip_count2 = 0;\
+ PLANE_CLIP_POLYGON(tri_edge_planes[1],_temp_clip,_temp_clip_count,_temp_clip2,_temp_clip_count2,MAX_TRI_CLIPPING);\
+ if(_temp_clip_count2>0)\
+ {\
+ PLANE_CLIP_POLYGON(tri_edge_planes[2],_temp_clip2,_temp_clip_count2,clipped_points,clipped_point_count,MAX_TRI_CLIPPING);\
+ }\
+ }\
+}\
+
+
+
+int _gim_triangle_triangle_collision(
+ GIM_TRIANGLE_DATA *tri1,
+ GIM_TRIANGLE_DATA *tri2,
+ GIM_TRIANGLE_CONTACT_DATA * contact_data)
+{
+ //Cache variables for triangle intersection
+ GUINT32 _max_candidates[MAX_TRI_CLIPPING];
+ vec3f _temp_clip[MAX_TRI_CLIPPING];
+ GUINT32 _temp_clip_count = 0;
+ vec3f _temp_clip2[MAX_TRI_CLIPPING];
+ GUINT32 _temp_clip_count2 = 0;
+ vec3f clipped_points2[MAX_TRI_CLIPPING];
+ vec3f deep_points2[MAX_TRI_CLIPPING];
+ vec3f clipped_points1[MAX_TRI_CLIPPING];
+ vec3f deep_points1[MAX_TRI_CLIPPING];
+
+
+
+ //State variabnles
+ GUINT32 mostdir=0;
+ GUINT32 clipped2_count=0;
+
+ //Clip tri2 by tri1 edges
+
+ CLIP_TRI_POINTS_BY_TRI_EDGE_PLANES(tri2->m_vertices,(&tri1->m_planes.m_planes[1]), clipped_points2, clipped2_count);
+
+ if(clipped2_count == 0 )
+ {
+ return 0;//Reject
+ }
+
+ //find most deep interval face1
+ GUINT32 deep2_count=0;
+
+ GREAL maxdeep;
+
+ MOST_DEEP_POINTS((tri1->m_planes.m_planes[0]), clipped_points2, clipped2_count, deep_points2, deep2_count, maxdeep);
+ if(deep2_count==0)
+ {
+// *perror = 0.0f;
+ return 0;//Reject
+ }
+
+ //Normal pointing to triangle1
+ VEC_SCALE(contact_data->m_separating_normal,-1.0f,(tri1->m_planes.m_planes[0]));
+
+
+ //Clip tri1 by tri2 edges
+
+ GUINT32 clipped1_count=0;
+
+ CLIP_TRI_POINTS_BY_TRI_EDGE_PLANES(tri1->m_vertices,(&tri2->m_planes.m_planes[1]), clipped_points1, clipped1_count);
+
+ if(clipped2_count == 0 )
+ {
+// *perror = 0.0f;
+ return 0;//Reject
+ }
+
+
+ //find interval face2
+ GUINT32 deep1_count=0;
+
+ GREAL dist;
+
+ MOST_DEEP_POINTS((tri2->m_planes.m_planes[0]), clipped_points1, clipped1_count, deep_points1, deep1_count, dist);
+
+ if(deep1_count==0)
+ {
+// *perror = 0.0f;
+ return 0;
+ }
+
+ if(dist<maxdeep)
+ {
+ maxdeep = dist;
+ mostdir = 1;
+ VEC_COPY(contact_data->m_separating_normal,(tri2->m_planes.m_planes[0]));
+ }
+ //set deep
+ contact_data->m_penetration_depth = maxdeep;
+
+ ////check most dir for contacts
+ if(mostdir==0)
+ {
+ contact_data->m_point_count = deep2_count;
+ for(mostdir=0;mostdir<deep2_count;mostdir++)
+ {
+ VEC_COPY(contact_data->m_points[mostdir] ,deep_points2[mostdir]);
+ }
+ }
+ else
+ {
+ contact_data->m_point_count = deep1_count;
+ for(mostdir=0;mostdir<deep1_count;mostdir++)
+ {
+ VEC_COPY(contact_data->m_points[mostdir] ,deep_points1[mostdir]);
+ }
+ }
+ return 1;
+}
+
+
+
+//! Finds the contact points from a collision of two triangles
+/*!
+Returns the contact points, the penetration depth and the separating normal of the collision
+between two triangles. The normal is pointing toward triangle 1 from triangle 2
+*/
+int gim_triangle_triangle_collision(
+ GIM_TRIANGLE_DATA *tri1,
+ GIM_TRIANGLE_DATA *tri2,
+ GIM_TRIANGLE_CONTACT_DATA * contact_data)
+{
+ vec3f _distances;
+ char out_of_face=0;
+
+ CLASSIFY_TRI_BY_FACE(tri1->m_vertices[0],tri1->m_vertices[1],tri1->m_vertices[2],tri2->m_planes.m_planes[0],out_of_face);
+ if(out_of_face==1) return 0;
+
+ CLASSIFY_TRI_BY_FACE(tri2->m_vertices[0],tri2->m_vertices[1],tri2->m_vertices[2],tri1->m_planes.m_planes[0],out_of_face);
+ if(out_of_face==1) return 0;
+
+ return _gim_triangle_triangle_collision(tri1,tri2,contact_data);
+}
+
+//! Trimesh Trimesh Collisions
+/*!
+
+In each contact
+<ul>
+<li> m_handle1 points to trimesh1.
+<li> m_handle2 points to trimesh2.
+<li> m_feature1 Is a triangle index of trimesh1.
+<li> m_feature2 Is a triangle index of trimesh2.
+</ul>
+
+\param trimesh1 Collider
+\param trimesh2 Collidee
+\param contacts A GIM_CONTACT array. Must be initialized
+*/
+void gim_trimesh_trimesh_collision(GIM_TRIMESH * trimesh1, GIM_TRIMESH * trimesh2, GDYNAMIC_ARRAY * contacts)
+{
+ contacts->m_size = 0;
+ GDYNAMIC_ARRAY collision_pairs;
+ GIM_CREATE_PAIR_SET(collision_pairs)
+
+ gim_aabbset_bipartite_intersections(&trimesh1->m_aabbset,&trimesh2->m_aabbset,&collision_pairs);
+
+ if(collision_pairs.m_size==0)
+ {
+ GIM_DYNARRAY_DESTROY(collision_pairs);
+ return; //no collisioin
+ }
+
+ //Locks meshes
+ gim_trimesh_locks_work_data(trimesh1);
+ gim_trimesh_locks_work_data(trimesh2);
+
+
+ //pair pointer
+ GIM_PAIR *pairs = GIM_DYNARRAY_POINTER(GIM_PAIR,collision_pairs);
+ //dummy contacts
+ GDYNAMIC_ARRAY dummycontacts;
+ GIM_CREATE_CONTACT_LIST(dummycontacts);
+
+ //Auxiliary triangle data
+ GIM_TRIANGLE_CONTACT_DATA tri_contact_data;
+ GIM_TRIANGLE_DATA tri1data,tri2data;
+
+
+ GUINT32 i, ti1,ti2,ci;
+ int colresult;
+ for (i=0;i<collision_pairs.m_size; i++)
+ {
+ ti1 = pairs[i].m_index1;
+ ti2 = pairs[i].m_index2;
+ //Get triangles data
+ gim_trimesh_get_triangle_data(trimesh1,ti1,&tri1data);
+ gim_trimesh_get_triangle_data(trimesh2,ti2,&tri2data);
+
+ //collide triangles
+ colresult = gim_triangle_triangle_collision(&tri1data,&tri2data,&tri_contact_data);
+ if(colresult == 1)
+ {
+ //Add contacts
+ for (ci=0;ci<tri_contact_data.m_point_count ;ci++ )
+ {
+ GIM_PUSH_CONTACT(dummycontacts, tri_contact_data.m_points[ci],tri_contact_data.m_separating_normal ,tri_contact_data.m_penetration_depth,trimesh1, trimesh2, ti1, ti2);
+ }
+ }
+ }
+
+ if(dummycontacts.m_size == 0) //reject
+ {
+ GIM_DYNARRAY_DESTROY(dummycontacts);
+ GIM_DYNARRAY_DESTROY(collision_pairs);
+ return;
+ }
+ //merge contacts
+ gim_merge_contacts(&dummycontacts,contacts);
+
+ //Terminate
+ GIM_DYNARRAY_DESTROY(dummycontacts);
+ GIM_DYNARRAY_DESTROY(collision_pairs);
+
+ //Unlocks meshes
+ gim_trimesh_unlocks_work_data(trimesh1);
+ gim_trimesh_unlocks_work_data(trimesh2);
+}
+
+
+//! Trimesh Plane Collisions
+/*!
+
+\param trimesh
+\param plane vec4f plane
+\param contacts A vec4f array. Must be initialized (~100). Each element have the coordinate point in the first 3 elements, and vec4f[3] has the penetration depth.
+*/
+void gim_trimesh_plane_collision(GIM_TRIMESH * trimesh,vec4f plane, GDYNAMIC_ARRAY * contacts)
+{
+ contacts->m_size = 0;
+ char classify;
+ PLANE_CLASSIFY_BOX(plane,trimesh->m_aabbset.m_global_bound,classify);
+ if(classify>1) return; // in front of plane
+
+ //Locks mesh
+ gim_trimesh_locks_work_data(trimesh);
+ //Get vertices
+ GUINT32 i, vertcount = trimesh->m_transformed_vertex_buffer.m_element_count;
+ vec3f * vertices = GIM_BUFFER_ARRAY_POINTER(vec3f,trimesh->m_transformed_vertex_buffer,0);
+
+ GREAL dist;
+ vec4f * result_contact;
+
+ for (i=0;i<vertcount;i++)
+ {
+ dist = DISTANCE_PLANE_POINT(plane,vertices[i]);
+ if(dist<=0.0f)
+ {
+ GIM_DYNARRAY_PUSH_EMPTY(vec4f,(*contacts));
+ result_contact = GIM_DYNARRAY_POINTER_LAST(vec4f,(*contacts));
+ VEC_COPY((*result_contact),vertices[i]);
+ (*result_contact)[3] = -dist;
+ }
+ }
+ gim_trimesh_unlocks_work_data(trimesh);
+}
diff --git a/libs/ode-0.16.1/GIMPACT/src/gimpact.cpp b/libs/ode-0.16.1/GIMPACT/src/gimpact.cpp
new file mode 100644
index 0000000..b7fdf42
--- /dev/null
+++ b/libs/ode-0.16.1/GIMPACT/src/gimpact.cpp
@@ -0,0 +1,40 @@
+
+/*
+-----------------------------------------------------------------------------
+This source file is part of GIMPACT Library.
+
+For the latest info, see http://gimpact.sourceforge.net/
+
+Copyright (c) 2006 Francisco Leon. C.C. 80087371.
+email: projectileman@yahoo.com
+
+ 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 GIMPACT-LICENSE-LGPL.TXT.
+ (2) The BSD-style license that is included with this library in
+ the file GIMPACT-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
+ GIMPACT-LICENSE-LGPL.TXT and GIMPACT-LICENSE-BSD.TXT for more details.
+
+-----------------------------------------------------------------------------
+*/
+
+#include "GIMPACT/gimpact.h"
+
+
+
+void gimpact_init()
+{
+ gim_init_math();
+}
+
+void gimpact_terminate()
+{
+}