aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/ode-0.9/GIMPACT
diff options
context:
space:
mode:
authordan miller2007-10-19 05:24:38 +0000
committerdan miller2007-10-19 05:24:38 +0000
commitf205de7847da7ae1c10212d82e7042d0100b4ce0 (patch)
tree9acc9608a6880502aaeda43af52c33e278e95b9c /libraries/ode-0.9/GIMPACT
parenttrying to fix my screwup part deux (diff)
downloadopensim-SC_OLD-f205de7847da7ae1c10212d82e7042d0100b4ce0.zip
opensim-SC_OLD-f205de7847da7ae1c10212d82e7042d0100b4ce0.tar.gz
opensim-SC_OLD-f205de7847da7ae1c10212d82e7042d0100b4ce0.tar.bz2
opensim-SC_OLD-f205de7847da7ae1c10212d82e7042d0100b4ce0.tar.xz
from the start... checking in ode-0.9
Diffstat (limited to 'libraries/ode-0.9/GIMPACT')
-rw-r--r--libraries/ode-0.9/GIMPACT/GIMPACT-LICENSE-BSD.TXT29
-rw-r--r--libraries/ode-0.9/GIMPACT/GIMPACT-LICENSE-LGPL.TXT502
-rw-r--r--libraries/ode-0.9/GIMPACT/include/GIMPACT/gim_boxpruning.h323
-rw-r--r--libraries/ode-0.9/GIMPACT/include/GIMPACT/gim_contact.h115
-rw-r--r--libraries/ode-0.9/GIMPACT/include/GIMPACT/gim_geometry.h1872
-rw-r--r--libraries/ode-0.9/GIMPACT/include/GIMPACT/gim_math.h147
-rw-r--r--libraries/ode-0.9/GIMPACT/include/GIMPACT/gim_memory.h1040
-rw-r--r--libraries/ode-0.9/GIMPACT/include/GIMPACT/gim_radixsort.h258
-rw-r--r--libraries/ode-0.9/GIMPACT/include/GIMPACT/gim_tri_capsule_collision.h111
-rw-r--r--libraries/ode-0.9/GIMPACT/include/GIMPACT/gim_tri_collision.h253
-rw-r--r--libraries/ode-0.9/GIMPACT/include/GIMPACT/gim_tri_sphere_collision.h51
-rw-r--r--libraries/ode-0.9/GIMPACT/include/GIMPACT/gim_trimesh.h539
-rw-r--r--libraries/ode-0.9/GIMPACT/include/GIMPACT/gimpact.h45
-rw-r--r--libraries/ode-0.9/GIMPACT/src/gim_boxpruning.cpp514
-rw-r--r--libraries/ode-0.9/GIMPACT/src/gim_contact.cpp132
-rw-r--r--libraries/ode-0.9/GIMPACT/src/gim_math.cpp60
-rw-r--r--libraries/ode-0.9/GIMPACT/src/gim_memory.cpp848
-rw-r--r--libraries/ode-0.9/GIMPACT/src/gim_tri_tri_overlap.cpp251
-rw-r--r--libraries/ode-0.9/GIMPACT/src/gim_trimesh.cpp364
-rw-r--r--libraries/ode-0.9/GIMPACT/src/gim_trimesh_capsule_collision.cpp279
-rw-r--r--libraries/ode-0.9/GIMPACT/src/gim_trimesh_ray_collision.cpp140
-rw-r--r--libraries/ode-0.9/GIMPACT/src/gim_trimesh_sphere_collision.cpp196
-rw-r--r--libraries/ode-0.9/GIMPACT/src/gim_trimesh_trimesh_collision.cpp348
-rw-r--r--libraries/ode-0.9/GIMPACT/src/gimpact.cpp39
24 files changed, 8456 insertions, 0 deletions
diff --git a/libraries/ode-0.9/GIMPACT/GIMPACT-LICENSE-BSD.TXT b/libraries/ode-0.9/GIMPACT/GIMPACT-LICENSE-BSD.TXT
new file mode 100644
index 0000000..95545aa
--- /dev/null
+++ b/libraries/ode-0.9/GIMPACT/GIMPACT-LICENSE-BSD.TXT
@@ -0,0 +1,29 @@
1GIMPACT : Geometric tools for VR.
2
3Copyright (c) 2006 , Francisco León.
4All rights reserved.
5
6Redistribution and use in source and binary forms, with or without modification,
7 are permitted provided that the following conditions are met:
8
9 * Redistributions of source code must retain the above copyright notice, this list of
10 conditions and the following disclaimer.
11
12 * Redistributions in binary form must reproduce the above copyright notice, this list
13 of conditions and the following disclaimer in the documentation and/or other materials
14 provided with the distribution.
15
16 * Neither the name of the GIMPACT nor the names of its contributors may be used
17 to endorse or promote products derived from this software without specific prior
18 written permission.
19
20THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
21OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
22MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
23IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
24INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
25(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
27 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
28 IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
29 DAMAGE. \ No newline at end of file
diff --git a/libraries/ode-0.9/GIMPACT/GIMPACT-LICENSE-LGPL.TXT b/libraries/ode-0.9/GIMPACT/GIMPACT-LICENSE-LGPL.TXT
new file mode 100644
index 0000000..60b8156
--- /dev/null
+++ b/libraries/ode-0.9/GIMPACT/GIMPACT-LICENSE-LGPL.TXT
@@ -0,0 +1,502 @@
1 GNU LESSER GENERAL PUBLIC LICENSE
2 Version 2.1, February 1999
3
4 Copyright (C) 1991, 1999 Free Software Foundation, Inc.
5 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
6 Everyone is permitted to copy and distribute verbatim copies
7 of this license document, but changing it is not allowed.
8
9[This is the first released version of the Lesser GPL. It also counts
10 as the successor of the GNU Library Public License, version 2, hence
11 the version number 2.1.]
12
13 Preamble
14
15 The licenses for most software are designed to take away your
16freedom to share and change it. By contrast, the GNU General Public
17Licenses are intended to guarantee your freedom to share and change
18free software--to make sure the software is free for all its users.
19
20 This license, the Lesser General Public License, applies to some
21specially designated software packages--typically libraries--of the
22Free Software Foundation and other authors who decide to use it. You
23can use it too, but we suggest you first think carefully about whether
24this license or the ordinary General Public License is the better
25strategy to use in any particular case, based on the explanations below.
26
27 When we speak of free software, we are referring to freedom of use,
28not price. Our General Public Licenses are designed to make sure that
29you have the freedom to distribute copies of free software (and charge
30for this service if you wish); that you receive source code or can get
31it if you want it; that you can change the software and use pieces of
32it in new free programs; and that you are informed that you can do
33these things.
34
35 To protect your rights, we need to make restrictions that forbid
36distributors to deny you these rights or to ask you to surrender these
37rights. These restrictions translate to certain responsibilities for
38you if you distribute copies of the library or if you modify it.
39
40 For example, if you distribute copies of the library, whether gratis
41or for a fee, you must give the recipients all the rights that we gave
42you. You must make sure that they, too, receive or can get the source
43code. If you link other code with the library, you must provide
44complete object files to the recipients, so that they can relink them
45with the library after making changes to the library and recompiling
46it. And you must show them these terms so they know their rights.
47
48 We protect your rights with a two-step method: (1) we copyright the
49library, and (2) we offer you this license, which gives you legal
50permission to copy, distribute and/or modify the library.
51
52 To protect each distributor, we want to make it very clear that
53there is no warranty for the free library. Also, if the library is
54modified by someone else and passed on, the recipients should know
55that what they have is not the original version, so that the original
56author's reputation will not be affected by problems that might be
57introduced by others.
58
59 Finally, software patents pose a constant threat to the existence of
60any free program. We wish to make sure that a company cannot
61effectively restrict the users of a free program by obtaining a
62restrictive license from a patent holder. Therefore, we insist that
63any patent license obtained for a version of the library must be
64consistent with the full freedom of use specified in this license.
65
66 Most GNU software, including some libraries, is covered by the
67ordinary GNU General Public License. This license, the GNU Lesser
68General Public License, applies to certain designated libraries, and
69is quite different from the ordinary General Public License. We use
70this license for certain libraries in order to permit linking those
71libraries into non-free programs.
72
73 When a program is linked with a library, whether statically or using
74a shared library, the combination of the two is legally speaking a
75combined work, a derivative of the original library. The ordinary
76General Public License therefore permits such linking only if the
77entire combination fits its criteria of freedom. The Lesser General
78Public License permits more lax criteria for linking other code with
79the library.
80
81 We call this license the "Lesser" General Public License because it
82does Less to protect the user's freedom than the ordinary General
83Public License. It also provides other free software developers Less
84of an advantage over competing non-free programs. These disadvantages
85are the reason we use the ordinary General Public License for many
86libraries. However, the Lesser license provides advantages in certain
87special circumstances.
88
89 For example, on rare occasions, there may be a special need to
90encourage the widest possible use of a certain library, so that it becomes
91a de-facto standard. To achieve this, non-free programs must be
92allowed to use the library. A more frequent case is that a free
93library does the same job as widely used non-free libraries. In this
94case, there is little to gain by limiting the free library to free
95software only, so we use the Lesser General Public License.
96
97 In other cases, permission to use a particular library in non-free
98programs enables a greater number of people to use a large body of
99free software. For example, permission to use the GNU C Library in
100non-free programs enables many more people to use the whole GNU
101operating system, as well as its variant, the GNU/Linux operating
102system.
103
104 Although the Lesser General Public License is Less protective of the
105users' freedom, it does ensure that the user of a program that is
106linked with the Library has the freedom and the wherewithal to run
107that program using a modified version of the Library.
108
109 The precise terms and conditions for copying, distribution and
110modification follow. Pay close attention to the difference between a
111"work based on the library" and a "work that uses the library". The
112former contains code derived from the library, whereas the latter must
113be combined with the library in order to run.
114
115 GNU LESSER GENERAL PUBLIC LICENSE
116 TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
117
118 0. This License Agreement applies to any software library or other
119program which contains a notice placed by the copyright holder or
120other authorized party saying it may be distributed under the terms of
121this Lesser General Public License (also called "this License").
122Each licensee is addressed as "you".
123
124 A "library" means a collection of software functions and/or data
125prepared so as to be conveniently linked with application programs
126(which use some of those functions and data) to form executables.
127
128 The "Library", below, refers to any such software library or work
129which has been distributed under these terms. A "work based on the
130Library" means either the Library or any derivative work under
131copyright law: that is to say, a work containing the Library or a
132portion of it, either verbatim or with modifications and/or translated
133straightforwardly into another language. (Hereinafter, translation is
134included without limitation in the term "modification".)
135
136 "Source code" for a work means the preferred form of the work for
137making modifications to it. For a library, complete source code means
138all the source code for all modules it contains, plus any associated
139interface definition files, plus the scripts used to control compilation
140and installation of the library.
141
142 Activities other than copying, distribution and modification are not
143covered by this License; they are outside its scope. The act of
144running a program using the Library is not restricted, and output from
145such a program is covered only if its contents constitute a work based
146on the Library (independent of the use of the Library in a tool for
147writing it). Whether that is true depends on what the Library does
148and what the program that uses the Library does.
149
150 1. You may copy and distribute verbatim copies of the Library's
151complete source code as you receive it, in any medium, provided that
152you conspicuously and appropriately publish on each copy an
153appropriate copyright notice and disclaimer of warranty; keep intact
154all the notices that refer to this License and to the absence of any
155warranty; and distribute a copy of this License along with the
156Library.
157
158 You may charge a fee for the physical act of transferring a copy,
159and you may at your option offer warranty protection in exchange for a
160fee.
161
162 2. You may modify your copy or copies of the Library or any portion
163of it, thus forming a work based on the Library, and copy and
164distribute such modifications or work under the terms of Section 1
165above, provided that you also meet all of these conditions:
166
167 a) The modified work must itself be a software library.
168
169 b) You must cause the files modified to carry prominent notices
170 stating that you changed the files and the date of any change.
171
172 c) You must cause the whole of the work to be licensed at no
173 charge to all third parties under the terms of this License.
174
175 d) If a facility in the modified Library refers to a function or a
176 table of data to be supplied by an application program that uses
177 the facility, other than as an argument passed when the facility
178 is invoked, then you must make a good faith effort to ensure that,
179 in the event an application does not supply such function or
180 table, the facility still operates, and performs whatever part of
181 its purpose remains meaningful.
182
183 (For example, a function in a library to compute square roots has
184 a purpose that is entirely well-defined independent of the
185 application. Therefore, Subsection 2d requires that any
186 application-supplied function or table used by this function must
187 be optional: if the application does not supply it, the square
188 root function must still compute square roots.)
189
190These requirements apply to the modified work as a whole. If
191identifiable sections of that work are not derived from the Library,
192and can be reasonably considered independent and separate works in
193themselves, then this License, and its terms, do not apply to those
194sections when you distribute them as separate works. But when you
195distribute the same sections as part of a whole which is a work based
196on the Library, the distribution of the whole must be on the terms of
197this License, whose permissions for other licensees extend to the
198entire whole, and thus to each and every part regardless of who wrote
199it.
200
201Thus, it is not the intent of this section to claim rights or contest
202your rights to work written entirely by you; rather, the intent is to
203exercise the right to control the distribution of derivative or
204collective works based on the Library.
205
206In addition, mere aggregation of another work not based on the Library
207with the Library (or with a work based on the Library) on a volume of
208a storage or distribution medium does not bring the other work under
209the scope of this License.
210
211 3. You may opt to apply the terms of the ordinary GNU General Public
212License instead of this License to a given copy of the Library. To do
213this, you must alter all the notices that refer to this License, so
214that they refer to the ordinary GNU General Public License, version 2,
215instead of to this License. (If a newer version than version 2 of the
216ordinary GNU General Public License has appeared, then you can specify
217that version instead if you wish.) Do not make any other change in
218these notices.
219
220 Once this change is made in a given copy, it is irreversible for
221that copy, so the ordinary GNU General Public License applies to all
222subsequent copies and derivative works made from that copy.
223
224 This option is useful when you wish to copy part of the code of
225the Library into a program that is not a library.
226
227 4. You may copy and distribute the Library (or a portion or
228derivative of it, under Section 2) in object code or executable form
229under the terms of Sections 1 and 2 above provided that you accompany
230it with the complete corresponding machine-readable source code, which
231must be distributed under the terms of Sections 1 and 2 above on a
232medium customarily used for software interchange.
233
234 If distribution of object code is made by offering access to copy
235from a designated place, then offering equivalent access to copy the
236source code from the same place satisfies the requirement to
237distribute the source code, even though third parties are not
238compelled to copy the source along with the object code.
239
240 5. A program that contains no derivative of any portion of the
241Library, but is designed to work with the Library by being compiled or
242linked with it, is called a "work that uses the Library". Such a
243work, in isolation, is not a derivative work of the Library, and
244therefore falls outside the scope of this License.
245
246 However, linking a "work that uses the Library" with the Library
247creates an executable that is a derivative of the Library (because it
248contains portions of the Library), rather than a "work that uses the
249library". The executable is therefore covered by this License.
250Section 6 states terms for distribution of such executables.
251
252 When a "work that uses the Library" uses material from a header file
253that is part of the Library, the object code for the work may be a
254derivative work of the Library even though the source code is not.
255Whether this is true is especially significant if the work can be
256linked without the Library, or if the work is itself a library. The
257threshold for this to be true is not precisely defined by law.
258
259 If such an object file uses only numerical parameters, data
260structure layouts and accessors, and small macros and small inline
261functions (ten lines or less in length), then the use of the object
262file is unrestricted, regardless of whether it is legally a derivative
263work. (Executables containing this object code plus portions of the
264Library will still fall under Section 6.)
265
266 Otherwise, if the work is a derivative of the Library, you may
267distribute the object code for the work under the terms of Section 6.
268Any executables containing that work also fall under Section 6,
269whether or not they are linked directly with the Library itself.
270
271 6. As an exception to the Sections above, you may also combine or
272link a "work that uses the Library" with the Library to produce a
273work containing portions of the Library, and distribute that work
274under terms of your choice, provided that the terms permit
275modification of the work for the customer's own use and reverse
276engineering for debugging such modifications.
277
278 You must give prominent notice with each copy of the work that the
279Library is used in it and that the Library and its use are covered by
280this License. You must supply a copy of this License. If the work
281during execution displays copyright notices, you must include the
282copyright notice for the Library among them, as well as a reference
283directing the user to the copy of this License. Also, you must do one
284of these things:
285
286 a) Accompany the work with the complete corresponding
287 machine-readable source code for the Library including whatever
288 changes were used in the work (which must be distributed under
289 Sections 1 and 2 above); and, if the work is an executable linked
290 with the Library, with the complete machine-readable "work that
291 uses the Library", as object code and/or source code, so that the
292 user can modify the Library and then relink to produce a modified
293 executable containing the modified Library. (It is understood
294 that the user who changes the contents of definitions files in the
295 Library will not necessarily be able to recompile the application
296 to use the modified definitions.)
297
298 b) Use a suitable shared library mechanism for linking with the
299 Library. A suitable mechanism is one that (1) uses at run time a
300 copy of the library already present on the user's computer system,
301 rather than copying library functions into the executable, and (2)
302 will operate properly with a modified version of the library, if
303 the user installs one, as long as the modified version is
304 interface-compatible with the version that the work was made with.
305
306 c) Accompany the work with a written offer, valid for at
307 least three years, to give the same user the materials
308 specified in Subsection 6a, above, for a charge no more
309 than the cost of performing this distribution.
310
311 d) If distribution of the work is made by offering access to copy
312 from a designated place, offer equivalent access to copy the above
313 specified materials from the same place.
314
315 e) Verify that the user has already received a copy of these
316 materials or that you have already sent this user a copy.
317
318 For an executable, the required form of the "work that uses the
319Library" must include any data and utility programs needed for
320reproducing the executable from it. However, as a special exception,
321the materials to be distributed need not include anything that is
322normally distributed (in either source or binary form) with the major
323components (compiler, kernel, and so on) of the operating system on
324which the executable runs, unless that component itself accompanies
325the executable.
326
327 It may happen that this requirement contradicts the license
328restrictions of other proprietary libraries that do not normally
329accompany the operating system. Such a contradiction means you cannot
330use both them and the Library together in an executable that you
331distribute.
332
333 7. You may place library facilities that are a work based on the
334Library side-by-side in a single library together with other library
335facilities not covered by this License, and distribute such a combined
336library, provided that the separate distribution of the work based on
337the Library and of the other library facilities is otherwise
338permitted, and provided that you do these two things:
339
340 a) Accompany the combined library with a copy of the same work
341 based on the Library, uncombined with any other library
342 facilities. This must be distributed under the terms of the
343 Sections above.
344
345 b) Give prominent notice with the combined library of the fact
346 that part of it is a work based on the Library, and explaining
347 where to find the accompanying uncombined form of the same work.
348
349 8. You may not copy, modify, sublicense, link with, or distribute
350the Library except as expressly provided under this License. Any
351attempt otherwise to copy, modify, sublicense, link with, or
352distribute the Library is void, and will automatically terminate your
353rights under this License. However, parties who have received copies,
354or rights, from you under this License will not have their licenses
355terminated so long as such parties remain in full compliance.
356
357 9. You are not required to accept this License, since you have not
358signed it. However, nothing else grants you permission to modify or
359distribute the Library or its derivative works. These actions are
360prohibited by law if you do not accept this License. Therefore, by
361modifying or distributing the Library (or any work based on the
362Library), you indicate your acceptance of this License to do so, and
363all its terms and conditions for copying, distributing or modifying
364the Library or works based on it.
365
366 10. Each time you redistribute the Library (or any work based on the
367Library), the recipient automatically receives a license from the
368original licensor to copy, distribute, link with or modify the Library
369subject to these terms and conditions. You may not impose any further
370restrictions on the recipients' exercise of the rights granted herein.
371You are not responsible for enforcing compliance by third parties with
372this License.
373
374 11. If, as a consequence of a court judgment or allegation of patent
375infringement or for any other reason (not limited to patent issues),
376conditions are imposed on you (whether by court order, agreement or
377otherwise) that contradict the conditions of this License, they do not
378excuse you from the conditions of this License. If you cannot
379distribute so as to satisfy simultaneously your obligations under this
380License and any other pertinent obligations, then as a consequence you
381may not distribute the Library at all. For example, if a patent
382license would not permit royalty-free redistribution of the Library by
383all those who receive copies directly or indirectly through you, then
384the only way you could satisfy both it and this License would be to
385refrain entirely from distribution of the Library.
386
387If any portion of this section is held invalid or unenforceable under any
388particular circumstance, the balance of the section is intended to apply,
389and the section as a whole is intended to apply in other circumstances.
390
391It is not the purpose of this section to induce you to infringe any
392patents or other property right claims or to contest validity of any
393such claims; this section has the sole purpose of protecting the
394integrity of the free software distribution system which is
395implemented by public license practices. Many people have made
396generous contributions to the wide range of software distributed
397through that system in reliance on consistent application of that
398system; it is up to the author/donor to decide if he or she is willing
399to distribute software through any other system and a licensee cannot
400impose that choice.
401
402This section is intended to make thoroughly clear what is believed to
403be a consequence of the rest of this License.
404
405 12. If the distribution and/or use of the Library is restricted in
406certain countries either by patents or by copyrighted interfaces, the
407original copyright holder who places the Library under this License may add
408an explicit geographical distribution limitation excluding those countries,
409so that distribution is permitted only in or among countries not thus
410excluded. In such case, this License incorporates the limitation as if
411written in the body of this License.
412
413 13. The Free Software Foundation may publish revised and/or new
414versions of the Lesser General Public License from time to time.
415Such new versions will be similar in spirit to the present version,
416but may differ in detail to address new problems or concerns.
417
418Each version is given a distinguishing version number. If the Library
419specifies a version number of this License which applies to it and
420"any later version", you have the option of following the terms and
421conditions either of that version or of any later version published by
422the Free Software Foundation. If the Library does not specify a
423license version number, you may choose any version ever published by
424the Free Software Foundation.
425
426 14. If you wish to incorporate parts of the Library into other free
427programs whose distribution conditions are incompatible with these,
428write to the author to ask for permission. For software which is
429copyrighted by the Free Software Foundation, write to the Free
430Software Foundation; we sometimes make exceptions for this. Our
431decision will be guided by the two goals of preserving the free status
432of all derivatives of our free software and of promoting the sharing
433and reuse of software generally.
434
435 NO WARRANTY
436
437 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
438WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
439EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
440OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
441KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
442IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
443PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
444LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
445THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
446
447 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
448WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
449AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
450FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
451CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
452LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
453RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
454FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
455SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
456DAMAGES.
457
458 END OF TERMS AND CONDITIONS
459
460 How to Apply These Terms to Your New Libraries
461
462 If you develop a new library, and you want it to be of the greatest
463possible use to the public, we recommend making it free software that
464everyone can redistribute and change. You can do so by permitting
465redistribution under these terms (or, alternatively, under the terms of the
466ordinary General Public License).
467
468 To apply these terms, attach the following notices to the library. It is
469safest to attach them to the start of each source file to most effectively
470convey the exclusion of warranty; and each file should have at least the
471"copyright" line and a pointer to where the full notice is found.
472
473 <one line to give the library's name and a brief idea of what it does.>
474 Copyright (C) <year> <name of author>
475
476 This library is free software; you can redistribute it and/or
477 modify it under the terms of the GNU Lesser General Public
478 License as published by the Free Software Foundation; either
479 version 2.1 of the License, or (at your option) any later version.
480
481 This library is distributed in the hope that it will be useful,
482 but WITHOUT ANY WARRANTY; without even the implied warranty of
483 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
484 Lesser General Public License for more details.
485
486 You should have received a copy of the GNU Lesser General Public
487 License along with this library; if not, write to the Free Software
488 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
489
490Also add information on how to contact you by electronic and paper mail.
491
492You should also get your employer (if you work as a programmer) or your
493school, if any, to sign a "copyright disclaimer" for the library, if
494necessary. Here is a sample; alter the names:
495
496 Yoyodyne, Inc., hereby disclaims all copyright interest in the
497 library `Frob' (a library for tweaking knobs) written by James Random Hacker.
498
499 <signature of Ty Coon>, 1 April 1990
500 Ty Coon, President of Vice
501
502That's all there is to it!
diff --git a/libraries/ode-0.9/GIMPACT/include/GIMPACT/gim_boxpruning.h b/libraries/ode-0.9/GIMPACT/include/GIMPACT/gim_boxpruning.h
new file mode 100644
index 0000000..68b68d0
--- /dev/null
+++ b/libraries/ode-0.9/GIMPACT/include/GIMPACT/gim_boxpruning.h
@@ -0,0 +1,323 @@
1#ifndef GIM_BOXPRUNING_H_INCLUDED
2#define GIM_BOXPRUNING_H_INCLUDED
3
4/*! \file gim_boxpruning.h
5\author Francisco León
6*/
7/*
8-----------------------------------------------------------------------------
9This source file is part of GIMPACT Library.
10
11For the latest info, see http://gimpact.sourceforge.net/
12
13Copyright (c) 2006 Francisco Leon. C.C. 80087371.
14email: projectileman@yahoo.com
15
16 This library is free software; you can redistribute it and/or
17 modify it under the terms of EITHER:
18 (1) The GNU Lesser General Public License as published by the Free
19 Software Foundation; either version 2.1 of the License, or (at
20 your option) any later version. The text of the GNU Lesser
21 General Public License is included with this library in the
22 file GIMPACT-LICENSE-LGPL.TXT.
23 (2) The BSD-style license that is included with this library in
24 the file GIMPACT-LICENSE-BSD.TXT.
25
26 This library is distributed in the hope that it will be useful,
27 but WITHOUT ANY WARRANTY; without even the implied warranty of
28 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files
29 GIMPACT-LICENSE-LGPL.TXT and GIMPACT-LICENSE-BSD.TXT for more details.
30
31-----------------------------------------------------------------------------
32*/
33
34
35#include "GIMPACT/gim_radixsort.h"
36#include "GIMPACT/gim_geometry.h"
37
38/*! \defgroup BOX_PRUNNING
39
40\brief
41Tools 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 .
42<ul>
43<li> For using these collision routines, you must create a \ref GIM_AABB_SET by using this function : \ref gim_aabbset_alloc.
44<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
45<li> Before calling collision functions, you must create a pair set with \ref GIM_CREATE_PAIR_SET
46<li> For finding collision pairs on a scene (common space for objects), call \ref gim_aabbset_self_intersections
47<li> For finding collision pairs between two box sets , call \ref gim_aabbset_box_collision
48<li> After using collision routines, you must destroy the pairset with \ref GIM_DESTROY_PAIR_SET
49<li> When the box set is no longer used, you must destroy it by calling \ref gim_aabbset_destroy
50</ul>
51*/
52//! @{
53//! Overlapping pair
54struct GIM_PAIR
55{
56 GUINT m_index1;
57 GUINT m_index2;
58};
59//typedef struct _GIM_PAIR GIM_PAIR;
60
61//! Box container
62struct GIM_AABB_SET
63{
64 GUINT m_count;
65 aabb3f m_global_bound;//!< Global calculated bound of all boxes
66 aabb3f * m_boxes;
67 GUINT * m_maxcoords;//!<Upper corners of the boxes, in integer representation
68 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
69 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
70};
71//typedef struct _GIM_AABB_SET GIM_AABB_SET;
72
73//! Function for creating an overlapping pair set
74#define GIM_CREATE_PAIR_SET(dynarray) GIM_DYNARRAY_CREATE(GIM_PAIR,dynarray,G_ARRAY_GROW_SIZE)
75//! Function for destroying an overlapping pair set
76#define GIM_DESTROY_PAIR_SET(dynarray) GIM_DYNARRAY_DESTROY(dynarray)
77
78//! Allocate memory for all aabb set.
79void gim_aabbset_alloc(GIM_AABB_SET * aabbset, GUINT count);
80
81//! Destroys the aabb set.
82void gim_aabbset_destroy(GIM_AABB_SET * aabbset);
83
84//! Calcs the global bound only
85/*!
86\pre aabbset must be allocated. And the boxes must be already set.
87*/
88void gim_aabbset_calc_global_bound(GIM_AABB_SET * aabbset);
89
90//! Sorts the boxes for box prunning.
91/*!
921) find the integer representation of the aabb coords
932) Sorts the min coords
943) Calcs the global bound
95\pre aabbset must be allocated. And the boxes must be already set.
96\param aabbset
97\param calc_global_bound If 1 , calcs the global bound
98\post If aabbset->m_sorted_mincoords == 0, then it allocs the sorted coordinates
99*/
100void gim_aabbset_sort(GIM_AABB_SET * aabbset, char calc_global_bound);
101
102//! log(N) Complete box pruning. Returns a list of overlapping pairs of boxes, each box of the pair belongs to the same set.
103/*!
104\pre aabbset must be allocated and sorted, the boxes must be already set.
105\param aabbset Must be sorted. Global bound isn't required
106\param collision_pairs Array of GIM_PAIR elements. Must be initialized before (Reserve size ~ 100)
107*/
108void gim_aabbset_self_intersections_sorted(GIM_AABB_SET * aabbset, GDYNAMIC_ARRAY * collision_pairs);
109
110//! NxN Complete box pruning. Returns a list of overlapping pairs of boxes, each box of the pair belongs to the same set.
111/*!
112\pre aabbset must be allocated, the boxes must be already set.
113\param aabbset Global bound isn't required. Doen't need to be sorted.
114\param collision_pairs Array of GIM_PAIR elements. Must be initialized before (Reserve size ~ 100)
115*/
116void gim_aabbset_self_intersections_brute_force(GIM_AABB_SET * aabbset, GDYNAMIC_ARRAY * collision_pairs);
117
118//! log(N) Bipartite box pruning. Returns a list of overlapping pairs of boxes, each box of the pair belongs to a different set.
119/*!
120\pre aabbset1 and aabbset2 must be allocated and sorted, the boxes must be already set.
121\param aabbset1 Must be sorted, Global bound is required.
122\param aabbset2 Must be sorted, Global bound is required.
123\param collision_pairs Array of GIM_PAIR elements. Must be initialized before (Reserve size ~ 100)
124*/
125void gim_aabbset_bipartite_intersections_sorted(GIM_AABB_SET * aabbset1, GIM_AABB_SET * aabbset2, GDYNAMIC_ARRAY * collision_pairs);
126
127//! NxM Bipartite box pruning. Returns a list of overlapping pairs of boxes, each box of the pair belongs to a different set.
128/*!
129\pre aabbset1 and aabbset2 must be allocated and sorted, the boxes must be already set.
130\param aabbset1 Must be sorted, Global bound is required.
131\param aabbset2 Must be sorted, Global bound is required.
132\param collision_pairs Array of GIM_PAIR elements. Must be initialized before (Reserve size ~ 100)
133*/
134void gim_aabbset_bipartite_intersections_brute_force(GIM_AABB_SET * aabbset1,GIM_AABB_SET * aabbset2, GDYNAMIC_ARRAY * collision_pairs);
135
136
137/*
138 Brute-Force Vs Sorted pruning
139Different approaches must be applied when colliding sets with different number of
140elements. When sets have less of 100 boxes, is often better to apply force brute
141approach instead of sorted methods, because at lowlevel bruteforce routines gives
142better perormance and consumes less resources, due of their simplicity.
143But when sets are larger, the complexiity of bruteforce increases exponencially.
144In the case of large sets, sorted approach is applied. So GIMPACT has the following
145strategies:
146
147On Sorting sets:
148!) When sets have more of 140 boxes, the boxes are sorted by its coded min coord
149and the global box is calculated. But when sets are smaller (less of 140 boxes),
150Is convenient to apply brute force approach.
151
152*******************************************************************************/
153
154//! Constant for apply approaches between brute force and sorted pruning on bipartite queries
155#define GIM_MIN_SORTED_BIPARTITE_PRUNING_BOXES 600
156//! Constant for apply approaches between brute force and sorted pruning for box collision
157#define GIM_MIN_SORTED_PRUNING_BOXES 140
158
159
160//Use these functions for general initialization
161
162//! Initalizes the set. Sort Boxes if needed.
163/*!
164\pre aabbset must be allocated. And the boxes must be already set.
165\post If the set has less of GIM_MIN_SORTED_BIPARTITE_PRUNING_BOXES boxes, only calcs the global box,
166 else it Sorts the entire set( Only applicable for large sets)
167*/
168void gim_aabbset_update(GIM_AABB_SET * aabbset);
169
170///Use these functions for general collision
171
172//! Complete box pruning. Returns a list of overlapping pairs of boxes, each box of the pair belongs to the same set.
173/*!
174This 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:
175\code
176//Create contact list
177GDYNAMIC_ARRAY collision_pairs;
178GIM_CREATE_PAIR_SET(collision_pairs);
179//Do collision
180gim_aabbset_self_intersections(&aabbset,&collision_pairs);
181if(collision_pairs.m_size==0)
182{
183 GIM_DYNARRAY_DESTROY(collision_pairs);//
184 return; //no collisioin
185}
186
187//pair pointer
188GIM_PAIR *pairs = GIM_DYNARRAY_POINTER(GIM_PAIR,collision_pairs);
189GUINT i, ti1,ti2;
190for (i=0;i<collision_pairs.m_size; i++)
191{
192 ti1 = pairs[i].m_index1;
193 ti2 = pairs[i].m_index2;
194 //Do something with the pairs
195 ....
196 ....
197 ...
198
199}
200//Terminate
201GIM_DYNARRAY_DESTROY(dummycontacts);
202GIM_DYNARRAY_DESTROY(collision_pairs);
203\endcode
204\param aabbset Set of boxes. Sorting isn't required.
205\param collision_pairs Array of GIM_PAIR elements. Must be initialized before (Reserve size ~ 100)
206\pre aabbset must be allocated and initialized.
207\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.
208*/
209void gim_aabbset_self_intersections(GIM_AABB_SET * aabbset, GDYNAMIC_ARRAY * collision_pairs);
210
211//! Collides two sets. Returns a list of overlapping pairs of boxes, each box of the pair belongs to a different set.
212/*!
213\pre aabbset1 and aabbset2 must be allocated and updated. See gim_aabbset_update.
214\param aabbset1 Must be updated.
215\param aabbset2 Must be updated.
216\param collision_pairs Array of GIM_PAIR elements. Must be initialized before (Reserve size ~ 100)
217*/
218void gim_aabbset_bipartite_intersections(GIM_AABB_SET * aabbset1, GIM_AABB_SET * aabbset2, GDYNAMIC_ARRAY * collision_pairs);
219
220///Function for create Box collision result set
221
222#define GIM_CREATE_BOXQUERY_LIST(dynarray) GIM_DYNARRAY_CREATE(GUINT,dynarray,G_ARRAY_GROW_SIZE)
223
224//! Finds intersections between a box and a set. Return the colliding boxes of the set
225/*!
226\pre aabbset must be allocated and initialized.
227\param test_aabb Box for collision query
228\param aabbset Set of boxes .Global bound is required.
229\param collided Array of GUINT elements, indices of boxes. Must be initialized before (Reserve size ~ 100)
230*/
231void gim_aabbset_box_collision(aabb3f *test_aabb, GIM_AABB_SET * aabbset, GDYNAMIC_ARRAY * collided);
232
233//! Finds intersections between a box and a set. Return the colliding boxes of the set
234/*!
235\pre aabbset must be allocated and initialized.
236\param vorigin Origin point of ray.
237\param vdir Direction vector of ray.
238\param tmax Max distance param for ray.
239\param aabbset Set of boxes .Global bound is required.
240\param collided Array of GUINT elements, indices of boxes. Must be initialized before (Reserve size ~ 100)
241*/
242void gim_aabbset_ray_collision(vec3f vorigin,vec3f vdir, GREAL tmax, GIM_AABB_SET * aabbset, GDYNAMIC_ARRAY * collided);
243
244
245/*
246For sorting, each box corner must be discretized to a 32 bit integer.
247For this, we take the x and z coordinates from the box corner (a vector vec3f)
248Then convert the (x,z) pair to an integer. For convenience, we choose an error
249constant for converting the coordinates (0.05).
250*******************************************************************************/
251
252/**
253 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.
254 20 give us a 0.05 floating point error
255*/
256#define ERROR_AABB 20.0f
257
258/**
259An error of 0.05 allows to make coordinates up to 1638.0f and no less of -1638.0f.
260So the maximum size of a room should be about 3276x3276 . Its dimensions must lie between [-1638,1638.0f]
261*/
262#define MAX_AABB_SIZE 1638.0f
263
264//! Converts a vector coordinate to an integer for box sorting
265/*!
266\param vx X component
267\param vz Z component
268\param uint_key a GUINT
269*/
270#define GIM_CONVERT_VEC3F_GUINT_XZ(vx,vz,uint_key)\
271{\
272 GUINT _z = ((GUINT)(vz*ERROR_AABB))+32768;\
273 uint_key = ((GUINT)(vx*ERROR_AABB))+32768;\
274 uint_key = (uint_key<<16) + _z;\
275}\
276
277//! Converts a vector coordinate to an integer for box sorting,rounding to the upper int
278/*!
279\param vx X component
280\param vz Z component
281\param uint_key a GUINT
282*/
283#define GIM_CONVERT_VEC3F_GUINT_XZ_UPPER(vx,vz,uint_key)\
284{\
285 GUINT _z = ((GUINT)ceilf(vz*ERROR_AABB))+32768;\
286 uint_key = ((GUINT)ceilf(vx*ERROR_AABB))+32768;\
287 uint_key = (uint_key<<16) + _z;\
288}\
289
290
291//! Converts a vector coordinate to an integer for box sorting. Secure clamped
292/*!
293\param vx X component
294\param vz Z component
295\param uint_key a GUINT
296*/
297#define GIM_CONVERT_VEC3F_GUINT_XZ_CLAMPED(vx,vz,uint_key)\
298{\
299 GREAL _cx = CLAMP(vx,-MAX_AABB_SIZE,MAX_AABB_SIZE);\
300 GREAL _cz = CLAMP(vz,-MAX_AABB_SIZE,MAX_AABB_SIZE);\
301 GUINT _z = ((GUINT)(_cz*ERROR_AABB))+32768;\
302 uint_key = ((GUINT)(_cx*ERROR_AABB))+32768;\
303 uint_key = (uint_key<<16) + _z;\
304}\
305
306//! Converts a vector coordinate to an integer for box sorting. Secure clamped, rounded
307/*!
308\param vx X component
309\param vz Z component
310\param uint_key a GUINT
311*/
312#define GIM_CONVERT_VEC3F_GUINT_XZ_UPPER_CLAMPED(vx,vz,uint_key)\
313{\
314 GREAL _cx = CLAMP(vx,-MAX_AABB_SIZE,MAX_AABB_SIZE);\
315 GREAL _cz = CLAMP(vz,-MAX_AABB_SIZE,MAX_AABB_SIZE);\
316 GUINT _z = ((GUINT)ceilf(_cz*ERROR_AABB))+32768;\
317 uint_key = ((GUINT)ceilf(_cx*ERROR_AABB))+32768;\
318 uint_key = (uint_key<<16) + _z;\
319}\
320
321//! @}
322
323#endif // GIM_BOXPRUNING_H_INCLUDED
diff --git a/libraries/ode-0.9/GIMPACT/include/GIMPACT/gim_contact.h b/libraries/ode-0.9/GIMPACT/include/GIMPACT/gim_contact.h
new file mode 100644
index 0000000..bad8f0f
--- /dev/null
+++ b/libraries/ode-0.9/GIMPACT/include/GIMPACT/gim_contact.h
@@ -0,0 +1,115 @@
1#ifndef GIM_CONTACT_H_INCLUDED
2#define GIM_CONTACT_H_INCLUDED
3
4/*! \file gim_contact.h
5\author Francisco León
6*/
7/*
8-----------------------------------------------------------------------------
9This source file is part of GIMPACT Library.
10
11For the latest info, see http://gimpact.sourceforge.net/
12
13Copyright (c) 2006 Francisco Leon. C.C. 80087371.
14email: projectileman@yahoo.com
15
16 This library is free software; you can redistribute it and/or
17 modify it under the terms of EITHER:
18 (1) The GNU Lesser General Public License as published by the Free
19 Software Foundation; either version 2.1 of the License, or (at
20 your option) any later version. The text of the GNU Lesser
21 General Public License is included with this library in the
22 file GIMPACT-LICENSE-LGPL.TXT.
23 (2) The BSD-style license that is included with this library in
24 the file GIMPACT-LICENSE-BSD.TXT.
25
26 This library is distributed in the hope that it will be useful,
27 but WITHOUT ANY WARRANTY; without even the implied warranty of
28 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files
29 GIMPACT-LICENSE-LGPL.TXT and GIMPACT-LICENSE-BSD.TXT for more details.
30
31-----------------------------------------------------------------------------
32*/
33
34
35#include "GIMPACT/gim_geometry.h"
36#include "GIMPACT/gim_radixsort.h"
37
38/*! \defgroup CONTACTS
39\brief
40Functions for managing and sorting contacts resulting from a collision query.
41<ul>
42<li> Contact lists must be create by calling \ref GIM_CREATE_CONTACT_LIST
43<li> After querys, contact lists must be destroy by calling \ref GIM_DYNARRAY_DESTROY
44<li> Contacts can be merge for avoid duplicate results by calling \ref gim_merge_contacts
45</ul>
46
47*/
48//! @{
49/// Structure for collision results
50struct GIM_CONTACT
51{
52 vec3f m_point;
53 vec3f m_normal;
54 GREAL m_depth;//Positive value indicates interpenetration
55 void * m_handle1;
56 void * m_handle2;
57 GUINT m_feature1;//Face number
58 GUINT m_feature2;//Face number
59};
60//typedef struct _GIM_CONTACT GIM_CONTACT;
61
62#define CONTACT_DIFF_EPSILON 0.00001f
63
64#define GIM_CALC_KEY_CONTACT(pos,hash)\
65{\
66 GINT _coords[] = {(GINT)(pos[0]*1000.0f+1.0f),(GINT)(pos[1]*1333.0f),(GINT)(pos[2]*2133.0f+3.0f)};\
67 GUINT _hash=0;\
68 GUINT *_uitmp = (GUINT *)(&_coords[0]);\
69 _hash = *_uitmp;\
70 _uitmp++;\
71 _hash += (*_uitmp)<<4;\
72 _uitmp++;\
73 _hash += (*_uitmp)<<8;\
74 hash = _hash;\
75}\
76
77///Creates a contact list for queries
78#define GIM_CREATE_CONTACT_LIST(contact_array) GIM_DYNARRAY_CREATE(GIM_CONTACT,contact_array,100)
79
80#define GIM_PUSH_CONTACT(contact_array, point, normal, deep,handle1, handle2, feat1, feat2)\
81{\
82 GIM_DYNARRAY_PUSH_EMPTY(GIM_CONTACT,contact_array);\
83 GIM_CONTACT * _last = GIM_DYNARRAY_POINTER_LAST(GIM_CONTACT,contact_array);\
84 VEC_COPY(_last->m_point,point);\
85 VEC_COPY(_last->m_normal,normal);\
86 _last->m_depth = deep;\
87 _last->m_handle1 = handle1;\
88 _last->m_handle2 = handle2;\
89 _last->m_feature1 = feat1;\
90 _last->m_feature2 = feat2;\
91}\
92
93///Receive pointer to contacts
94#define GIM_COPY_CONTACTS(dest_contact, source_contact)\
95{\
96 VEC_COPY(dest_contact->m_point,source_contact->m_point);\
97 VEC_COPY(dest_contact->m_normal,source_contact->m_normal);\
98 dest_contact->m_depth = source_contact->m_depth;\
99 dest_contact->m_handle1 = source_contact->m_handle1;\
100 dest_contact->m_handle2 = source_contact->m_handle2;\
101 dest_contact->m_feature1 = source_contact->m_feature1;\
102 dest_contact->m_feature2 = source_contact->m_feature2;\
103}\
104
105//! Merges duplicate contacts with minimum depth criterion
106void gim_merge_contacts(GDYNAMIC_ARRAY * source_contacts,
107 GDYNAMIC_ARRAY * dest_contacts);
108
109
110//! Merges to an unique contact
111void gim_merge_contacts_unique(GDYNAMIC_ARRAY * source_contacts,
112 GDYNAMIC_ARRAY * dest_contacts);
113
114//! @}
115#endif // GIM_CONTACT_H_INCLUDED
diff --git a/libraries/ode-0.9/GIMPACT/include/GIMPACT/gim_geometry.h b/libraries/ode-0.9/GIMPACT/include/GIMPACT/gim_geometry.h
new file mode 100644
index 0000000..6d89a94
--- /dev/null
+++ b/libraries/ode-0.9/GIMPACT/include/GIMPACT/gim_geometry.h
@@ -0,0 +1,1872 @@
1#ifndef GIM_VECTOR_H_INCLUDED
2#define GIM_VECTOR_H_INCLUDED
3
4/*! \file gim_geometry.h
5\author Francisco León
6*/
7/*
8-----------------------------------------------------------------------------
9This source file is part of GIMPACT Library.
10
11For the latest info, see http://gimpact.sourceforge.net/
12
13Copyright (c) 2006 Francisco Leon. C.C. 80087371.
14email: projectileman@yahoo.com
15
16 This library is free software; you can redistribute it and/or
17 modify it under the terms of EITHER:
18 (1) The GNU Lesser General Public License as published by the Free
19 Software Foundation; either version 2.1 of the License, or (at
20 your option) any later version. The text of the GNU Lesser
21 General Public License is included with this library in the
22 file GIMPACT-LICENSE-LGPL.TXT.
23 (2) The BSD-style license that is included with this library in
24 the file GIMPACT-LICENSE-BSD.TXT.
25
26 This library is distributed in the hope that it will be useful,
27 but WITHOUT ANY WARRANTY; without even the implied warranty of
28 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files
29 GIMPACT-LICENSE-LGPL.TXT and GIMPACT-LICENSE-BSD.TXT for more details.
30
31-----------------------------------------------------------------------------
32*/
33
34
35#include "GIMPACT/gim_math.h"
36
37/*! \defgroup GEOMETRIC_TYPES
38\brief
39Basic types and constants for geometry
40*/
41//! @{
42
43//! Integer vector 2D
44typedef GINT vec2i[2];
45//! Integer vector 3D
46typedef GINT vec3i[3];
47//! Integer vector 4D
48typedef GINT vec4i[4];
49
50//! Float vector 2D
51typedef GREAL vec2f[2];
52//! Float vector 3D
53typedef GREAL vec3f[3];
54//! Float vector 4D
55typedef GREAL vec4f[4];
56
57//! Matrix 2D, row ordered
58typedef GREAL mat2f[2][2];
59//! Matrix 3D, row ordered
60typedef GREAL mat3f[3][3];
61//! Matrix 4D, row ordered
62typedef GREAL mat4f[4][4];
63
64//! Quaternion
65typedef GREAL quatf[4];
66
67//! Axis aligned box
68struct aabb3f{
69 GREAL minX;
70 GREAL maxX;
71 GREAL minY;
72 GREAL maxY;
73 GREAL minZ;
74 GREAL maxZ;
75};
76//typedef struct _aabb3f aabb3f;
77//! @}
78
79
80/*! \defgroup VECTOR_OPERATIONS
81Operations for vectors : vec2f,vec3f and vec4f
82*/
83//! @{
84
85//! Zero out a 2D vector
86#define VEC_ZERO_2(a) \
87{ \
88 (a)[0] = (a)[1] = 0.0f; \
89}\
90
91
92//! Zero out a 3D vector
93#define VEC_ZERO(a) \
94{ \
95 (a)[0] = (a)[1] = (a)[2] = 0.0f; \
96}\
97
98
99/// Zero out a 4D vector
100#define VEC_ZERO_4(a) \
101{ \
102 (a)[0] = (a)[1] = (a)[2] = (a)[3] = 0.0f; \
103}\
104
105
106/// Vector copy
107#define VEC_COPY_2(b,a) \
108{ \
109 (b)[0] = (a)[0]; \
110 (b)[1] = (a)[1]; \
111}\
112
113
114/// Copy 3D vector
115#define VEC_COPY(b,a) \
116{ \
117 (b)[0] = (a)[0]; \
118 (b)[1] = (a)[1]; \
119 (b)[2] = (a)[2]; \
120}\
121
122
123/// Copy 4D vector
124#define VEC_COPY_4(b,a) \
125{ \
126 (b)[0] = (a)[0]; \
127 (b)[1] = (a)[1]; \
128 (b)[2] = (a)[2]; \
129 (b)[3] = (a)[3]; \
130}\
131
132
133/// Vector difference
134#define VEC_DIFF_2(v21,v2,v1) \
135{ \
136 (v21)[0] = (v2)[0] - (v1)[0]; \
137 (v21)[1] = (v2)[1] - (v1)[1]; \
138}\
139
140
141/// Vector difference
142#define VEC_DIFF(v21,v2,v1) \
143{ \
144 (v21)[0] = (v2)[0] - (v1)[0]; \
145 (v21)[1] = (v2)[1] - (v1)[1]; \
146 (v21)[2] = (v2)[2] - (v1)[2]; \
147}\
148
149
150/// Vector difference
151#define VEC_DIFF_4(v21,v2,v1) \
152{ \
153 (v21)[0] = (v2)[0] - (v1)[0]; \
154 (v21)[1] = (v2)[1] - (v1)[1]; \
155 (v21)[2] = (v2)[2] - (v1)[2]; \
156 (v21)[3] = (v2)[3] - (v1)[3]; \
157}\
158
159
160/// Vector sum
161#define VEC_SUM_2(v21,v2,v1) \
162{ \
163 (v21)[0] = (v2)[0] + (v1)[0]; \
164 (v21)[1] = (v2)[1] + (v1)[1]; \
165}\
166
167
168/// Vector sum
169#define VEC_SUM(v21,v2,v1) \
170{ \
171 (v21)[0] = (v2)[0] + (v1)[0]; \
172 (v21)[1] = (v2)[1] + (v1)[1]; \
173 (v21)[2] = (v2)[2] + (v1)[2]; \
174}\
175
176
177/// Vector sum
178#define VEC_SUM_4(v21,v2,v1) \
179{ \
180 (v21)[0] = (v2)[0] + (v1)[0]; \
181 (v21)[1] = (v2)[1] + (v1)[1]; \
182 (v21)[2] = (v2)[2] + (v1)[2]; \
183 (v21)[3] = (v2)[3] + (v1)[3]; \
184}\
185
186
187/// scalar times vector
188#define VEC_SCALE_2(c,a,b) \
189{ \
190 (c)[0] = (a)*(b)[0]; \
191 (c)[1] = (a)*(b)[1]; \
192}\
193
194
195/// scalar times vector
196#define VEC_SCALE(c,a,b) \
197{ \
198 (c)[0] = (a)*(b)[0]; \
199 (c)[1] = (a)*(b)[1]; \
200 (c)[2] = (a)*(b)[2]; \
201}\
202
203
204/// scalar times vector
205#define VEC_SCALE_4(c,a,b) \
206{ \
207 (c)[0] = (a)*(b)[0]; \
208 (c)[1] = (a)*(b)[1]; \
209 (c)[2] = (a)*(b)[2]; \
210 (c)[3] = (a)*(b)[3]; \
211}\
212
213
214/// accumulate scaled vector
215#define VEC_ACCUM_2(c,a,b) \
216{ \
217 (c)[0] += (a)*(b)[0]; \
218 (c)[1] += (a)*(b)[1]; \
219}\
220
221
222/// accumulate scaled vector
223#define VEC_ACCUM(c,a,b) \
224{ \
225 (c)[0] += (a)*(b)[0]; \
226 (c)[1] += (a)*(b)[1]; \
227 (c)[2] += (a)*(b)[2]; \
228}\
229
230
231/// accumulate scaled vector
232#define VEC_ACCUM_4(c,a,b) \
233{ \
234 (c)[0] += (a)*(b)[0]; \
235 (c)[1] += (a)*(b)[1]; \
236 (c)[2] += (a)*(b)[2]; \
237 (c)[3] += (a)*(b)[3]; \
238}\
239
240
241/// Vector dot product
242#define VEC_DOT_2(a,b) ((a)[0]*(b)[0] + (a)[1]*(b)[1])
243
244
245/// Vector dot product
246#define VEC_DOT(a,b) ((a)[0]*(b)[0] + (a)[1]*(b)[1] + (a)[2]*(b)[2])
247
248/// Vector dot product
249#define VEC_DOT_4(a,b) ((a)[0]*(b)[0] + (a)[1]*(b)[1] + (a)[2]*(b)[2] + (a)[3]*(b)[3])
250
251/// vector impact parameter (squared)
252#define VEC_IMPACT_SQ(bsq,direction,position) {\
253 GREAL _llel_ = VEC_DOT(direction, position);\
254 bsq = VEC_DOT(position, position) - _llel_*_llel_;\
255}\
256
257
258/// vector impact parameter
259#define VEC_IMPACT(bsq,direction,position) {\
260 VEC_IMPACT_SQ(bsq,direction,position); \
261 GIM_SQRT(bsq,bsq); \
262}\
263
264/// Vector length
265#define VEC_LENGTH_2(a,l)\
266{\
267 GREAL _pp = VEC_DOT_2(a,a);\
268 GIM_SQRT(_pp,l);\
269}\
270
271
272/// Vector length
273#define VEC_LENGTH(a,l)\
274{\
275 GREAL _pp = VEC_DOT(a,a);\
276 GIM_SQRT(_pp,l);\
277}\
278
279
280/// Vector length
281#define VEC_LENGTH_4(a,l)\
282{\
283 GREAL _pp = VEC_DOT_4(a,a);\
284 GIM_SQRT(_pp,l);\
285}\
286
287/// Vector inv length
288#define VEC_INV_LENGTH_2(a,l)\
289{\
290 GREAL _pp = VEC_DOT_2(a,a);\
291 GIM_INV_SQRT(_pp,l);\
292}\
293
294
295/// Vector inv length
296#define VEC_INV_LENGTH(a,l)\
297{\
298 GREAL _pp = VEC_DOT(a,a);\
299 GIM_INV_SQRT(_pp,l);\
300}\
301
302
303/// Vector inv length
304#define VEC_INV_LENGTH_4(a,l)\
305{\
306 GREAL _pp = VEC_DOT_4(a,a);\
307 GIM_INV_SQRT(_pp,l);\
308}\
309
310
311
312/// distance between two points
313#define VEC_DISTANCE(_len,_va,_vb) {\
314 vec3f _tmp_; \
315 VEC_DIFF(_tmp_, _vb, _va); \
316 VEC_LENGTH(_tmp_,_len); \
317}\
318
319
320/// Vector length
321#define VEC_CONJUGATE_LENGTH(a,l)\
322{\
323 GREAL _pp = 1.0 - a[0]*a[0] - a[1]*a[1] - a[2]*a[2];\
324 GIM_SQRT(_pp,l);\
325}\
326
327
328/// Vector length
329#define VEC_NORMALIZE(a) { \
330 GREAL len;\
331 VEC_INV_LENGTH(a,len); \
332 if(len<G_REAL_INFINITY)\
333 {\
334 a[0] *= len; \
335 a[1] *= len; \
336 a[2] *= len; \
337 } \
338}\
339
340/// Set Vector size
341#define VEC_RENORMALIZE(a,newlen) { \
342 GREAL len;\
343 VEC_INV_LENGTH(a,len); \
344 if(len<G_REAL_INFINITY)\
345 {\
346 len *= newlen;\
347 a[0] *= len; \
348 a[1] *= len; \
349 a[2] *= len; \
350 } \
351}\
352
353/// Vector cross
354#define VEC_CROSS(c,a,b) \
355{ \
356 c[0] = (a)[1] * (b)[2] - (a)[2] * (b)[1]; \
357 c[1] = (a)[2] * (b)[0] - (a)[0] * (b)[2]; \
358 c[2] = (a)[0] * (b)[1] - (a)[1] * (b)[0]; \
359}\
360
361
362/*! Vector perp -- assumes that n is of unit length
363 * accepts vector v, subtracts out any component parallel to n */
364#define VEC_PERPENDICULAR(vp,v,n) \
365{ \
366 GREAL dot = VEC_DOT(v, n); \
367 vp[0] = (v)[0] - dot*(n)[0]; \
368 vp[1] = (v)[1] - dot*(n)[1]; \
369 vp[2] = (v)[2] - dot*(n)[2]; \
370}\
371
372
373/*! Vector parallel -- assumes that n is of unit length */
374#define VEC_PARALLEL(vp,v,n) \
375{ \
376 GREAL dot = VEC_DOT(v, n); \
377 vp[0] = (dot) * (n)[0]; \
378 vp[1] = (dot) * (n)[1]; \
379 vp[2] = (dot) * (n)[2]; \
380}\
381
382/*! Same as Vector parallel -- n can have any length
383 * accepts vector v, subtracts out any component perpendicular to n */
384#define VEC_PROJECT(vp,v,n) \
385{ \
386 GREAL scalar = VEC_DOT(v, n); \
387 scalar/= VEC_DOT(n, n); \
388 vp[0] = (scalar) * (n)[0]; \
389 vp[1] = (scalar) * (n)[1]; \
390 vp[2] = (scalar) * (n)[2]; \
391}\
392
393
394/*! accepts vector v*/
395#define VEC_UNPROJECT(vp,v,n) \
396{ \
397 GREAL scalar = VEC_DOT(v, n); \
398 scalar = VEC_DOT(n, n)/scalar; \
399 vp[0] = (scalar) * (n)[0]; \
400 vp[1] = (scalar) * (n)[1]; \
401 vp[2] = (scalar) * (n)[2]; \
402}\
403
404
405/*! Vector reflection -- assumes n is of unit length
406 Takes vector v, reflects it against reflector n, and returns vr */
407#define VEC_REFLECT(vr,v,n) \
408{ \
409 GREAL dot = VEC_DOT(v, n); \
410 vr[0] = (v)[0] - 2.0 * (dot) * (n)[0]; \
411 vr[1] = (v)[1] - 2.0 * (dot) * (n)[1]; \
412 vr[2] = (v)[2] - 2.0 * (dot) * (n)[2]; \
413}\
414
415
416/*! Vector blending
417Takes two vectors a, b, blends them together with two scalars */
418#define VEC_BLEND_AB(vr,sa,a,sb,b) \
419{ \
420 vr[0] = (sa) * (a)[0] + (sb) * (b)[0]; \
421 vr[1] = (sa) * (a)[1] + (sb) * (b)[1]; \
422 vr[2] = (sa) * (a)[2] + (sb) * (b)[2]; \
423}\
424
425/*! Vector blending
426Takes two vectors a, b, blends them together with s <=1 */
427#define VEC_BLEND(vr,a,b,s) VEC_BLEND_AB(vr,1-s,a,sb,s)
428
429#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];
430//! @}
431
432
433/*! \defgroup MATRIX_OPERATIONS
434Operations for matrices : mat2f, mat3f and mat4f
435*/
436//! @{
437
438/// initialize matrix
439#define IDENTIFY_MATRIX_3X3(m) \
440{ \
441 m[0][0] = 1.0; \
442 m[0][1] = 0.0; \
443 m[0][2] = 0.0; \
444 \
445 m[1][0] = 0.0; \
446 m[1][1] = 1.0; \
447 m[1][2] = 0.0; \
448 \
449 m[2][0] = 0.0; \
450 m[2][1] = 0.0; \
451 m[2][2] = 1.0; \
452}\
453
454/*! initialize matrix */
455#define IDENTIFY_MATRIX_4X4(m) \
456{ \
457 m[0][0] = 1.0; \
458 m[0][1] = 0.0; \
459 m[0][2] = 0.0; \
460 m[0][3] = 0.0; \
461 \
462 m[1][0] = 0.0; \
463 m[1][1] = 1.0; \
464 m[1][2] = 0.0; \
465 m[1][3] = 0.0; \
466 \
467 m[2][0] = 0.0; \
468 m[2][1] = 0.0; \
469 m[2][2] = 1.0; \
470 m[2][3] = 0.0; \
471 \
472 m[3][0] = 0.0; \
473 m[3][1] = 0.0; \
474 m[3][2] = 0.0; \
475 m[3][3] = 1.0; \
476}\
477
478/*! initialize matrix */
479#define ZERO_MATRIX_4X4(m) \
480{ \
481 m[0][0] = 0.0; \
482 m[0][1] = 0.0; \
483 m[0][2] = 0.0; \
484 m[0][3] = 0.0; \
485 \
486 m[1][0] = 0.0; \
487 m[1][1] = 0.0; \
488 m[1][2] = 0.0; \
489 m[1][3] = 0.0; \
490 \
491 m[2][0] = 0.0; \
492 m[2][1] = 0.0; \
493 m[2][2] = 0.0; \
494 m[2][3] = 0.0; \
495 \
496 m[3][0] = 0.0; \
497 m[3][1] = 0.0; \
498 m[3][2] = 0.0; \
499 m[3][3] = 0.0; \
500}\
501
502/*! matrix rotation X */
503#define ROTX_CS(m,cosine,sine) \
504{ \
505 /* rotation about the x-axis */ \
506 \
507 m[0][0] = 1.0; \
508 m[0][1] = 0.0; \
509 m[0][2] = 0.0; \
510 m[0][3] = 0.0; \
511 \
512 m[1][0] = 0.0; \
513 m[1][1] = (cosine); \
514 m[1][2] = (sine); \
515 m[1][3] = 0.0; \
516 \
517 m[2][0] = 0.0; \
518 m[2][1] = -(sine); \
519 m[2][2] = (cosine); \
520 m[2][3] = 0.0; \
521 \
522 m[3][0] = 0.0; \
523 m[3][1] = 0.0; \
524 m[3][2] = 0.0; \
525 m[3][3] = 1.0; \
526}\
527
528/*! matrix rotation Y */
529#define ROTY_CS(m,cosine,sine) \
530{ \
531 /* rotation about the y-axis */ \
532 \
533 m[0][0] = (cosine); \
534 m[0][1] = 0.0; \
535 m[0][2] = -(sine); \
536 m[0][3] = 0.0; \
537 \
538 m[1][0] = 0.0; \
539 m[1][1] = 1.0; \
540 m[1][2] = 0.0; \
541 m[1][3] = 0.0; \
542 \
543 m[2][0] = (sine); \
544 m[2][1] = 0.0; \
545 m[2][2] = (cosine); \
546 m[2][3] = 0.0; \
547 \
548 m[3][0] = 0.0; \
549 m[3][1] = 0.0; \
550 m[3][2] = 0.0; \
551 m[3][3] = 1.0; \
552}\
553
554/*! matrix rotation Z */
555#define ROTZ_CS(m,cosine,sine) \
556{ \
557 /* rotation about the z-axis */ \
558 \
559 m[0][0] = (cosine); \
560 m[0][1] = (sine); \
561 m[0][2] = 0.0; \
562 m[0][3] = 0.0; \
563 \
564 m[1][0] = -(sine); \
565 m[1][1] = (cosine); \
566 m[1][2] = 0.0; \
567 m[1][3] = 0.0; \
568 \
569 m[2][0] = 0.0; \
570 m[2][1] = 0.0; \
571 m[2][2] = 1.0; \
572 m[2][3] = 0.0; \
573 \
574 m[3][0] = 0.0; \
575 m[3][1] = 0.0; \
576 m[3][2] = 0.0; \
577 m[3][3] = 1.0; \
578}\
579
580/*! matrix copy */
581#define COPY_MATRIX_2X2(b,a) \
582{ \
583 b[0][0] = a[0][0]; \
584 b[0][1] = a[0][1]; \
585 \
586 b[1][0] = a[1][0]; \
587 b[1][1] = a[1][1]; \
588 \
589}\
590
591
592/*! matrix copy */
593#define COPY_MATRIX_2X3(b,a) \
594{ \
595 b[0][0] = a[0][0]; \
596 b[0][1] = a[0][1]; \
597 b[0][2] = a[0][2]; \
598 \
599 b[1][0] = a[1][0]; \
600 b[1][1] = a[1][1]; \
601 b[1][2] = a[1][2]; \
602}\
603
604
605/*! matrix copy */
606#define COPY_MATRIX_3X3(b,a) \
607{ \
608 b[0][0] = a[0][0]; \
609 b[0][1] = a[0][1]; \
610 b[0][2] = a[0][2]; \
611 \
612 b[1][0] = a[1][0]; \
613 b[1][1] = a[1][1]; \
614 b[1][2] = a[1][2]; \
615 \
616 b[2][0] = a[2][0]; \
617 b[2][1] = a[2][1]; \
618 b[2][2] = a[2][2]; \
619}\
620
621
622/*! matrix copy */
623#define COPY_MATRIX_4X4(b,a) \
624{ \
625 b[0][0] = a[0][0]; \
626 b[0][1] = a[0][1]; \
627 b[0][2] = a[0][2]; \
628 b[0][3] = a[0][3]; \
629 \
630 b[1][0] = a[1][0]; \
631 b[1][1] = a[1][1]; \
632 b[1][2] = a[1][2]; \
633 b[1][3] = a[1][3]; \
634 \
635 b[2][0] = a[2][0]; \
636 b[2][1] = a[2][1]; \
637 b[2][2] = a[2][2]; \
638 b[2][3] = a[2][3]; \
639 \
640 b[3][0] = a[3][0]; \
641 b[3][1] = a[3][1]; \
642 b[3][2] = a[3][2]; \
643 b[3][3] = a[3][3]; \
644}\
645
646
647/*! matrix transpose */
648#define TRANSPOSE_MATRIX_2X2(b,a) \
649{ \
650 b[0][0] = a[0][0]; \
651 b[0][1] = a[1][0]; \
652 \
653 b[1][0] = a[0][1]; \
654 b[1][1] = a[1][1]; \
655}\
656
657
658/*! matrix transpose */
659#define TRANSPOSE_MATRIX_3X3(b,a) \
660{ \
661 b[0][0] = a[0][0]; \
662 b[0][1] = a[1][0]; \
663 b[0][2] = a[2][0]; \
664 \
665 b[1][0] = a[0][1]; \
666 b[1][1] = a[1][1]; \
667 b[1][2] = a[2][1]; \
668 \
669 b[2][0] = a[0][2]; \
670 b[2][1] = a[1][2]; \
671 b[2][2] = a[2][2]; \
672}\
673
674
675/*! matrix transpose */
676#define TRANSPOSE_MATRIX_4X4(b,a) \
677{ \
678 b[0][0] = a[0][0]; \
679 b[0][1] = a[1][0]; \
680 b[0][2] = a[2][0]; \
681 b[0][3] = a[3][0]; \
682 \
683 b[1][0] = a[0][1]; \
684 b[1][1] = a[1][1]; \
685 b[1][2] = a[2][1]; \
686 b[1][3] = a[3][1]; \
687 \
688 b[2][0] = a[0][2]; \
689 b[2][1] = a[1][2]; \
690 b[2][2] = a[2][2]; \
691 b[2][3] = a[3][2]; \
692 \
693 b[3][0] = a[0][3]; \
694 b[3][1] = a[1][3]; \
695 b[3][2] = a[2][3]; \
696 b[3][3] = a[3][3]; \
697}\
698
699
700/*! multiply matrix by scalar */
701#define SCALE_MATRIX_2X2(b,s,a) \
702{ \
703 b[0][0] = (s) * a[0][0]; \
704 b[0][1] = (s) * a[0][1]; \
705 \
706 b[1][0] = (s) * a[1][0]; \
707 b[1][1] = (s) * a[1][1]; \
708}\
709
710
711/*! multiply matrix by scalar */
712#define SCALE_MATRIX_3X3(b,s,a) \
713{ \
714 b[0][0] = (s) * a[0][0]; \
715 b[0][1] = (s) * a[0][1]; \
716 b[0][2] = (s) * a[0][2]; \
717 \
718 b[1][0] = (s) * a[1][0]; \
719 b[1][1] = (s) * a[1][1]; \
720 b[1][2] = (s) * a[1][2]; \
721 \
722 b[2][0] = (s) * a[2][0]; \
723 b[2][1] = (s) * a[2][1]; \
724 b[2][2] = (s) * a[2][2]; \
725}\
726
727
728/*! multiply matrix by scalar */
729#define SCALE_MATRIX_4X4(b,s,a) \
730{ \
731 b[0][0] = (s) * a[0][0]; \
732 b[0][1] = (s) * a[0][1]; \
733 b[0][2] = (s) * a[0][2]; \
734 b[0][3] = (s) * a[0][3]; \
735 \
736 b[1][0] = (s) * a[1][0]; \
737 b[1][1] = (s) * a[1][1]; \
738 b[1][2] = (s) * a[1][2]; \
739 b[1][3] = (s) * a[1][3]; \
740 \
741 b[2][0] = (s) * a[2][0]; \
742 b[2][1] = (s) * a[2][1]; \
743 b[2][2] = (s) * a[2][2]; \
744 b[2][3] = (s) * a[2][3]; \
745 \
746 b[3][0] = s * a[3][0]; \
747 b[3][1] = s * a[3][1]; \
748 b[3][2] = s * a[3][2]; \
749 b[3][3] = s * a[3][3]; \
750}\
751
752
753/*! multiply matrix by scalar */
754#define ACCUM_SCALE_MATRIX_2X2(b,s,a) \
755{ \
756 b[0][0] += (s) * a[0][0]; \
757 b[0][1] += (s) * a[0][1]; \
758 \
759 b[1][0] += (s) * a[1][0]; \
760 b[1][1] += (s) * a[1][1]; \
761}\
762
763
764/*! multiply matrix by scalar */
765#define ACCUM_SCALE_MATRIX_3X3(b,s,a) \
766{ \
767 b[0][0] += (s) * a[0][0]; \
768 b[0][1] += (s) * a[0][1]; \
769 b[0][2] += (s) * a[0][2]; \
770 \
771 b[1][0] += (s) * a[1][0]; \
772 b[1][1] += (s) * a[1][1]; \
773 b[1][2] += (s) * a[1][2]; \
774 \
775 b[2][0] += (s) * a[2][0]; \
776 b[2][1] += (s) * a[2][1]; \
777 b[2][2] += (s) * a[2][2]; \
778}\
779
780
781/*! multiply matrix by scalar */
782#define ACCUM_SCALE_MATRIX_4X4(b,s,a) \
783{ \
784 b[0][0] += (s) * a[0][0]; \
785 b[0][1] += (s) * a[0][1]; \
786 b[0][2] += (s) * a[0][2]; \
787 b[0][3] += (s) * a[0][3]; \
788 \
789 b[1][0] += (s) * a[1][0]; \
790 b[1][1] += (s) * a[1][1]; \
791 b[1][2] += (s) * a[1][2]; \
792 b[1][3] += (s) * a[1][3]; \
793 \
794 b[2][0] += (s) * a[2][0]; \
795 b[2][1] += (s) * a[2][1]; \
796 b[2][2] += (s) * a[2][2]; \
797 b[2][3] += (s) * a[2][3]; \
798 \
799 b[3][0] += (s) * a[3][0]; \
800 b[3][1] += (s) * a[3][1]; \
801 b[3][2] += (s) * a[3][2]; \
802 b[3][3] += (s) * a[3][3]; \
803}\
804
805/*! matrix product */
806/*! 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];*/
807#define MATRIX_PRODUCT_2X2(c,a,b) \
808{ \
809 c[0][0] = a[0][0]*b[0][0]+a[0][1]*b[1][0]; \
810 c[0][1] = a[0][0]*b[0][1]+a[0][1]*b[1][1]; \
811 \
812 c[1][0] = a[1][0]*b[0][0]+a[1][1]*b[1][0]; \
813 c[1][1] = a[1][0]*b[0][1]+a[1][1]*b[1][1]; \
814 \
815}\
816
817/*! matrix product */
818/*! 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];*/
819#define MATRIX_PRODUCT_3X3(c,a,b) \
820{ \
821 c[0][0] = a[0][0]*b[0][0]+a[0][1]*b[1][0]+a[0][2]*b[2][0]; \
822 c[0][1] = a[0][0]*b[0][1]+a[0][1]*b[1][1]+a[0][2]*b[2][1]; \
823 c[0][2] = a[0][0]*b[0][2]+a[0][1]*b[1][2]+a[0][2]*b[2][2]; \
824 \
825 c[1][0] = a[1][0]*b[0][0]+a[1][1]*b[1][0]+a[1][2]*b[2][0]; \
826 c[1][1] = a[1][0]*b[0][1]+a[1][1]*b[1][1]+a[1][2]*b[2][1]; \
827 c[1][2] = a[1][0]*b[0][2]+a[1][1]*b[1][2]+a[1][2]*b[2][2]; \
828 \
829 c[2][0] = a[2][0]*b[0][0]+a[2][1]*b[1][0]+a[2][2]*b[2][0]; \
830 c[2][1] = a[2][0]*b[0][1]+a[2][1]*b[1][1]+a[2][2]*b[2][1]; \
831 c[2][2] = a[2][0]*b[0][2]+a[2][1]*b[1][2]+a[2][2]*b[2][2]; \
832}\
833
834
835/*! matrix product */
836/*! 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];*/
837#define MATRIX_PRODUCT_4X4(c,a,b) \
838{ \
839 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];\
840 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];\
841 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];\
842 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];\
843 \
844 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];\
845 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];\
846 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];\
847 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];\
848 \
849 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];\
850 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];\
851 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];\
852 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];\
853 \
854 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];\
855 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];\
856 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];\
857 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];\
858}\
859
860
861/*! matrix times vector */
862#define MAT_DOT_VEC_2X2(p,m,v) \
863{ \
864 p[0] = m[0][0]*v[0] + m[0][1]*v[1]; \
865 p[1] = m[1][0]*v[0] + m[1][1]*v[1]; \
866}\
867
868
869/*! matrix times vector */
870#define MAT_DOT_VEC_3X3(p,m,v) \
871{ \
872 p[0] = m[0][0]*v[0] + m[0][1]*v[1] + m[0][2]*v[2]; \
873 p[1] = m[1][0]*v[0] + m[1][1]*v[1] + m[1][2]*v[2]; \
874 p[2] = m[2][0]*v[0] + m[2][1]*v[1] + m[2][2]*v[2]; \
875}\
876
877
878/*! matrix times vector
879v is a vec4f
880*/
881#define MAT_DOT_VEC_4X4(p,m,v) \
882{ \
883 p[0] = m[0][0]*v[0] + m[0][1]*v[1] + m[0][2]*v[2] + m[0][3]*v[3]; \
884 p[1] = m[1][0]*v[0] + m[1][1]*v[1] + m[1][2]*v[2] + m[1][3]*v[3]; \
885 p[2] = m[2][0]*v[0] + m[2][1]*v[1] + m[2][2]*v[2] + m[2][3]*v[3]; \
886 p[3] = m[3][0]*v[0] + m[3][1]*v[1] + m[3][2]*v[2] + m[3][3]*v[3]; \
887}\
888
889/*! matrix times vector
890v is a vec3f
891and m is a mat4f<br>
892Last column is added as the position
893*/
894#define MAT_DOT_VEC_3X4(p,m,v) \
895{ \
896 p[0] = m[0][0]*v[0] + m[0][1]*v[1] + m[0][2]*v[2] + m[0][3]; \
897 p[1] = m[1][0]*v[0] + m[1][1]*v[1] + m[1][2]*v[2] + m[1][3]; \
898 p[2] = m[2][0]*v[0] + m[2][1]*v[1] + m[2][2]*v[2] + m[2][3]; \
899}\
900
901/*! vector transpose times matrix */
902/*! p[j] = v[0]*m[0][j] + v[1]*m[1][j] + v[2]*m[2][j]; */
903#define VEC_DOT_MAT_3X3(p,v,m) \
904{ \
905 p[0] = v[0]*m[0][0] + v[1]*m[1][0] + v[2]*m[2][0]; \
906 p[1] = v[0]*m[0][1] + v[1]*m[1][1] + v[2]*m[2][1]; \
907 p[2] = v[0]*m[0][2] + v[1]*m[1][2] + v[2]*m[2][2]; \
908}\
909
910
911/*! affine matrix times vector */
912/** The matrix is assumed to be an affine matrix, with last two
913 * entries representing a translation */
914#define MAT_DOT_VEC_2X3(p,m,v) \
915{ \
916 p[0] = m[0][0]*v[0] + m[0][1]*v[1] + m[0][2]; \
917 p[1] = m[1][0]*v[0] + m[1][1]*v[1] + m[1][2]; \
918}\
919
920
921/** inverse transpose of matrix times vector
922 *
923 * This macro computes inverse transpose of matrix m,
924 * and multiplies vector v into it, to yeild vector p
925 *
926 * DANGER !!! Do Not use this on normal vectors!!!
927 * It will leave normals the wrong length !!!
928 * See macro below for use on normals.
929 */
930#define INV_TRANSP_MAT_DOT_VEC_2X2(p,m,v) \
931{ \
932 GREAL det; \
933 \
934 det = m[0][0]*m[1][1] - m[0][1]*m[1][0]; \
935 p[0] = m[1][1]*v[0] - m[1][0]*v[1]; \
936 p[1] = - m[0][1]*v[0] + m[0][0]*v[1]; \
937 \
938 /* if matrix not singular, and not orthonormal, then renormalize */ \
939 if ((det!=1.0f) && (det != 0.0f)) { \
940 det = 1.0f / det; \
941 p[0] *= det; \
942 p[1] *= det; \
943 } \
944}\
945
946
947/** transform normal vector by inverse transpose of matrix
948 * and then renormalize the vector
949 *
950 * This macro computes inverse transpose of matrix m,
951 * and multiplies vector v into it, to yeild vector p
952 * Vector p is then normalized.
953 */
954#define NORM_XFORM_2X2(p,m,v) \
955{ \
956 double len; \
957 \
958 /* do nothing if off-diagonals are zero and diagonals are \
959 * equal */ \
960 if ((m[0][1] != 0.0) || (m[1][0] != 0.0) || (m[0][0] != m[1][1])) { \
961 p[0] = m[1][1]*v[0] - m[1][0]*v[1]; \
962 p[1] = - m[0][1]*v[0] + m[0][0]*v[1]; \
963 \
964 len = p[0]*p[0] + p[1]*p[1]; \
965 GIM_INV_SQRT(len,len); \
966 p[0] *= len; \
967 p[1] *= len; \
968 } else { \
969 VEC_COPY_2 (p, v); \
970 } \
971}\
972
973
974/** outer product of vector times vector transpose
975 *
976 * The outer product of vector v and vector transpose t yeilds
977 * dyadic matrix m.
978 */
979#define OUTER_PRODUCT_2X2(m,v,t) \
980{ \
981 m[0][0] = v[0] * t[0]; \
982 m[0][1] = v[0] * t[1]; \
983 \
984 m[1][0] = v[1] * t[0]; \
985 m[1][1] = v[1] * t[1]; \
986}\
987
988
989/** outer product of vector times vector transpose
990 *
991 * The outer product of vector v and vector transpose t yeilds
992 * dyadic matrix m.
993 */
994#define OUTER_PRODUCT_3X3(m,v,t) \
995{ \
996 m[0][0] = v[0] * t[0]; \
997 m[0][1] = v[0] * t[1]; \
998 m[0][2] = v[0] * t[2]; \
999 \
1000 m[1][0] = v[1] * t[0]; \
1001 m[1][1] = v[1] * t[1]; \
1002 m[1][2] = v[1] * t[2]; \
1003 \
1004 m[2][0] = v[2] * t[0]; \
1005 m[2][1] = v[2] * t[1]; \
1006 m[2][2] = v[2] * t[2]; \
1007}\
1008
1009
1010/** outer product of vector times vector transpose
1011 *
1012 * The outer product of vector v and vector transpose t yeilds
1013 * dyadic matrix m.
1014 */
1015#define OUTER_PRODUCT_4X4(m,v,t) \
1016{ \
1017 m[0][0] = v[0] * t[0]; \
1018 m[0][1] = v[0] * t[1]; \
1019 m[0][2] = v[0] * t[2]; \
1020 m[0][3] = v[0] * t[3]; \
1021 \
1022 m[1][0] = v[1] * t[0]; \
1023 m[1][1] = v[1] * t[1]; \
1024 m[1][2] = v[1] * t[2]; \
1025 m[1][3] = v[1] * t[3]; \
1026 \
1027 m[2][0] = v[2] * t[0]; \
1028 m[2][1] = v[2] * t[1]; \
1029 m[2][2] = v[2] * t[2]; \
1030 m[2][3] = v[2] * t[3]; \
1031 \
1032 m[3][0] = v[3] * t[0]; \
1033 m[3][1] = v[3] * t[1]; \
1034 m[3][2] = v[3] * t[2]; \
1035 m[3][3] = v[3] * t[3]; \
1036}\
1037
1038
1039/** outer product of vector times vector transpose
1040 *
1041 * The outer product of vector v and vector transpose t yeilds
1042 * dyadic matrix m.
1043 */
1044#define ACCUM_OUTER_PRODUCT_2X2(m,v,t) \
1045{ \
1046 m[0][0] += v[0] * t[0]; \
1047 m[0][1] += v[0] * t[1]; \
1048 \
1049 m[1][0] += v[1] * t[0]; \
1050 m[1][1] += v[1] * t[1]; \
1051}\
1052
1053
1054/** outer product of vector times vector transpose
1055 *
1056 * The outer product of vector v and vector transpose t yeilds
1057 * dyadic matrix m.
1058 */
1059#define ACCUM_OUTER_PRODUCT_3X3(m,v,t) \
1060{ \
1061 m[0][0] += v[0] * t[0]; \
1062 m[0][1] += v[0] * t[1]; \
1063 m[0][2] += v[0] * t[2]; \
1064 \
1065 m[1][0] += v[1] * t[0]; \
1066 m[1][1] += v[1] * t[1]; \
1067 m[1][2] += v[1] * t[2]; \
1068 \
1069 m[2][0] += v[2] * t[0]; \
1070 m[2][1] += v[2] * t[1]; \
1071 m[2][2] += v[2] * t[2]; \
1072}\
1073
1074
1075/** outer product of vector times vector transpose
1076 *
1077 * The outer product of vector v and vector transpose t yeilds
1078 * dyadic matrix m.
1079 */
1080#define ACCUM_OUTER_PRODUCT_4X4(m,v,t) \
1081{ \
1082 m[0][0] += v[0] * t[0]; \
1083 m[0][1] += v[0] * t[1]; \
1084 m[0][2] += v[0] * t[2]; \
1085 m[0][3] += v[0] * t[3]; \
1086 \
1087 m[1][0] += v[1] * t[0]; \
1088 m[1][1] += v[1] * t[1]; \
1089 m[1][2] += v[1] * t[2]; \
1090 m[1][3] += v[1] * t[3]; \
1091 \
1092 m[2][0] += v[2] * t[0]; \
1093 m[2][1] += v[2] * t[1]; \
1094 m[2][2] += v[2] * t[2]; \
1095 m[2][3] += v[2] * t[3]; \
1096 \
1097 m[3][0] += v[3] * t[0]; \
1098 m[3][1] += v[3] * t[1]; \
1099 m[3][2] += v[3] * t[2]; \
1100 m[3][3] += v[3] * t[3]; \
1101}\
1102
1103
1104/** determinant of matrix
1105 *
1106 * Computes determinant of matrix m, returning d
1107 */
1108#define DETERMINANT_2X2(d,m) \
1109{ \
1110 d = m[0][0] * m[1][1] - m[0][1] * m[1][0]; \
1111}\
1112
1113
1114/** determinant of matrix
1115 *
1116 * Computes determinant of matrix m, returning d
1117 */
1118#define DETERMINANT_3X3(d,m) \
1119{ \
1120 d = m[0][0] * (m[1][1]*m[2][2] - m[1][2] * m[2][1]); \
1121 d -= m[0][1] * (m[1][0]*m[2][2] - m[1][2] * m[2][0]); \
1122 d += m[0][2] * (m[1][0]*m[2][1] - m[1][1] * m[2][0]); \
1123}\
1124
1125
1126/** i,j,th cofactor of a 4x4 matrix
1127 *
1128 */
1129#define COFACTOR_4X4_IJ(fac,m,i,j) \
1130{ \
1131 int __ii[4], __jj[4], __k; \
1132 \
1133 for (__k=0; __k<i; __k++) __ii[__k] = __k; \
1134 for (__k=i; __k<3; __k++) __ii[__k] = __k+1; \
1135 for (__k=0; __k<j; __k++) __jj[__k] = __k; \
1136 for (__k=j; __k<3; __k++) __jj[__k] = __k+1; \
1137 \
1138 (fac) = m[__ii[0]][__jj[0]] * (m[__ii[1]][__jj[1]]*m[__ii[2]][__jj[2]] \
1139 - m[__ii[1]][__jj[2]]*m[__ii[2]][__jj[1]]); \
1140 (fac) -= m[__ii[0]][__jj[1]] * (m[__ii[1]][__jj[0]]*m[__ii[2]][__jj[2]] \
1141 - m[__ii[1]][__jj[2]]*m[__ii[2]][__jj[0]]);\
1142 (fac) += m[__ii[0]][__jj[2]] * (m[__ii[1]][__jj[0]]*m[__ii[2]][__jj[1]] \
1143 - m[__ii[1]][__jj[1]]*m[__ii[2]][__jj[0]]);\
1144 \
1145 __k = i+j; \
1146 if ( __k != (__k/2)*2) { \
1147 (fac) = -(fac); \
1148 } \
1149}\
1150
1151
1152/** determinant of matrix
1153 *
1154 * Computes determinant of matrix m, returning d
1155 */
1156#define DETERMINANT_4X4(d,m) \
1157{ \
1158 double cofac; \
1159 COFACTOR_4X4_IJ (cofac, m, 0, 0); \
1160 d = m[0][0] * cofac; \
1161 COFACTOR_4X4_IJ (cofac, m, 0, 1); \
1162 d += m[0][1] * cofac; \
1163 COFACTOR_4X4_IJ (cofac, m, 0, 2); \
1164 d += m[0][2] * cofac; \
1165 COFACTOR_4X4_IJ (cofac, m, 0, 3); \
1166 d += m[0][3] * cofac; \
1167}\
1168
1169
1170/** cofactor of matrix
1171 *
1172 * Computes cofactor of matrix m, returning a
1173 */
1174#define COFACTOR_2X2(a,m) \
1175{ \
1176 a[0][0] = (m)[1][1]; \
1177 a[0][1] = - (m)[1][0]; \
1178 a[1][0] = - (m)[0][1]; \
1179 a[1][1] = (m)[0][0]; \
1180}\
1181
1182
1183/** cofactor of matrix
1184 *
1185 * Computes cofactor of matrix m, returning a
1186 */
1187#define COFACTOR_3X3(a,m) \
1188{ \
1189 a[0][0] = m[1][1]*m[2][2] - m[1][2]*m[2][1]; \
1190 a[0][1] = - (m[1][0]*m[2][2] - m[2][0]*m[1][2]); \
1191 a[0][2] = m[1][0]*m[2][1] - m[1][1]*m[2][0]; \
1192 a[1][0] = - (m[0][1]*m[2][2] - m[0][2]*m[2][1]); \
1193 a[1][1] = m[0][0]*m[2][2] - m[0][2]*m[2][0]; \
1194 a[1][2] = - (m[0][0]*m[2][1] - m[0][1]*m[2][0]); \
1195 a[2][0] = m[0][1]*m[1][2] - m[0][2]*m[1][1]; \
1196 a[2][1] = - (m[0][0]*m[1][2] - m[0][2]*m[1][0]); \
1197 a[2][2] = m[0][0]*m[1][1] - m[0][1]*m[1][0]); \
1198}\
1199
1200
1201/** cofactor of matrix
1202 *
1203 * Computes cofactor of matrix m, returning a
1204 */
1205#define COFACTOR_4X4(a,m) \
1206{ \
1207 int i,j; \
1208 \
1209 for (i=0; i<4; i++) { \
1210 for (j=0; j<4; j++) { \
1211 COFACTOR_4X4_IJ (a[i][j], m, i, j); \
1212 } \
1213 } \
1214}\
1215
1216
1217/** adjoint of matrix
1218 *
1219 * Computes adjoint of matrix m, returning a
1220 * (Note that adjoint is just the transpose of the cofactor matrix)
1221 */
1222#define ADJOINT_2X2(a,m) \
1223{ \
1224 a[0][0] = (m)[1][1]; \
1225 a[1][0] = - (m)[1][0]; \
1226 a[0][1] = - (m)[0][1]; \
1227 a[1][1] = (m)[0][0]; \
1228}\
1229
1230
1231/** adjoint of matrix
1232 *
1233 * Computes adjoint of matrix m, returning a
1234 * (Note that adjoint is just the transpose of the cofactor matrix)
1235 */
1236#define ADJOINT_3X3(a,m) \
1237{ \
1238 a[0][0] = m[1][1]*m[2][2] - m[1][2]*m[2][1]; \
1239 a[1][0] = - (m[1][0]*m[2][2] - m[2][0]*m[1][2]); \
1240 a[2][0] = m[1][0]*m[2][1] - m[1][1]*m[2][0]; \
1241 a[0][1] = - (m[0][1]*m[2][2] - m[0][2]*m[2][1]); \
1242 a[1][1] = m[0][0]*m[2][2] - m[0][2]*m[2][0]; \
1243 a[2][1] = - (m[0][0]*m[2][1] - m[0][1]*m[2][0]); \
1244 a[0][2] = m[0][1]*m[1][2] - m[0][2]*m[1][1]; \
1245 a[1][2] = - (m[0][0]*m[1][2] - m[0][2]*m[1][0]); \
1246 a[2][2] = m[0][0]*m[1][1] - m[0][1]*m[1][0]); \
1247}\
1248
1249
1250/** adjoint of matrix
1251 *
1252 * Computes adjoint of matrix m, returning a
1253 * (Note that adjoint is just the transpose of the cofactor matrix)
1254 */
1255#define ADJOINT_4X4(a,m) \
1256{ \
1257 char _i_,_j_; \
1258 \
1259 for (_i_=0; _i_<4; _i_++) { \
1260 for (_j_=0; _j_<4; _j_++) { \
1261 COFACTOR_4X4_IJ (a[_j_][_i_], m, _i_, _j_); \
1262 } \
1263 } \
1264}\
1265
1266
1267/** compute adjoint of matrix and scale
1268 *
1269 * Computes adjoint of matrix m, scales it by s, returning a
1270 */
1271#define SCALE_ADJOINT_2X2(a,s,m) \
1272{ \
1273 a[0][0] = (s) * m[1][1]; \
1274 a[1][0] = - (s) * m[1][0]; \
1275 a[0][1] = - (s) * m[0][1]; \
1276 a[1][1] = (s) * m[0][0]; \
1277}\
1278
1279
1280/** compute adjoint of matrix and scale
1281 *
1282 * Computes adjoint of matrix m, scales it by s, returning a
1283 */
1284#define SCALE_ADJOINT_3X3(a,s,m) \
1285{ \
1286 a[0][0] = (s) * (m[1][1] * m[2][2] - m[1][2] * m[2][1]); \
1287 a[1][0] = (s) * (m[1][2] * m[2][0] - m[1][0] * m[2][2]); \
1288 a[2][0] = (s) * (m[1][0] * m[2][1] - m[1][1] * m[2][0]); \
1289 \
1290 a[0][1] = (s) * (m[0][2] * m[2][1] - m[0][1] * m[2][2]); \
1291 a[1][1] = (s) * (m[0][0] * m[2][2] - m[0][2] * m[2][0]); \
1292 a[2][1] = (s) * (m[0][1] * m[2][0] - m[0][0] * m[2][1]); \
1293 \
1294 a[0][2] = (s) * (m[0][1] * m[1][2] - m[0][2] * m[1][1]); \
1295 a[1][2] = (s) * (m[0][2] * m[1][0] - m[0][0] * m[1][2]); \
1296 a[2][2] = (s) * (m[0][0] * m[1][1] - m[0][1] * m[1][0]); \
1297}\
1298
1299
1300/** compute adjoint of matrix and scale
1301 *
1302 * Computes adjoint of matrix m, scales it by s, returning a
1303 */
1304#define SCALE_ADJOINT_4X4(a,s,m) \
1305{ \
1306 char _i_,_j_; \
1307 for (_i_=0; _i_<4; _i_++) { \
1308 for (_j_=0; _j_<4; _j_++) { \
1309 COFACTOR_4X4_IJ (a[_j_][_i_], m, _i_, _j_); \
1310 a[_j_][_i_] *= s; \
1311 } \
1312 } \
1313}\
1314
1315/** inverse of matrix
1316 *
1317 * Compute inverse of matrix a, returning determinant m and
1318 * inverse b
1319 */
1320#define INVERT_2X2(b,det,a) \
1321{ \
1322 GREAL _tmp_; \
1323 DETERMINANT_2X2 (det, a); \
1324 _tmp_ = 1.0 / (det); \
1325 SCALE_ADJOINT_2X2 (b, _tmp_, a); \
1326}\
1327
1328
1329/** inverse of matrix
1330 *
1331 * Compute inverse of matrix a, returning determinant m and
1332 * inverse b
1333 */
1334#define INVERT_3X3(b,det,a) \
1335{ \
1336 GREAL _tmp_; \
1337 DETERMINANT_3X3 (det, a); \
1338 _tmp_ = 1.0 / (det); \
1339 SCALE_ADJOINT_3X3 (b, _tmp_, a); \
1340}\
1341
1342
1343/** inverse of matrix
1344 *
1345 * Compute inverse of matrix a, returning determinant m and
1346 * inverse b
1347 */
1348#define INVERT_4X4(b,det,a) \
1349{ \
1350 GREAL _tmp_; \
1351 DETERMINANT_4X4 (det, a); \
1352 _tmp_ = 1.0 / (det); \
1353 SCALE_ADJOINT_4X4 (b, _tmp_, a); \
1354}\
1355
1356//! @}
1357
1358/*! \defgroup BOUND_AABB_OPERATIONS
1359*/
1360//! @{
1361
1362//!Initializes an AABB
1363#define INVALIDATE_AABB(aabb) {\
1364 (aabb).minX = G_REAL_INFINITY;\
1365 (aabb).maxX = -G_REAL_INFINITY;\
1366 (aabb).minY = G_REAL_INFINITY;\
1367 (aabb).maxY = -G_REAL_INFINITY;\
1368 (aabb).minZ = G_REAL_INFINITY;\
1369 (aabb).maxZ = -G_REAL_INFINITY;\
1370}\
1371
1372#define AABB_GET_MIN(aabb,vmin) {\
1373 vmin[0] = (aabb).minX;\
1374 vmin[1] = (aabb).minY;\
1375 vmin[2] = (aabb).minZ;\
1376}\
1377
1378#define AABB_GET_MAX(aabb,vmax) {\
1379 vmax[0] = (aabb).maxX;\
1380 vmax[1] = (aabb).maxY;\
1381 vmax[2] = (aabb).maxZ;\
1382}\
1383
1384//!Copy boxes
1385#define AABB_COPY(dest_aabb,src_aabb)\
1386{\
1387 (dest_aabb).minX = (src_aabb).minX;\
1388 (dest_aabb).maxX = (src_aabb).maxX;\
1389 (dest_aabb).minY = (src_aabb).minY;\
1390 (dest_aabb).maxY = (src_aabb).maxY;\
1391 (dest_aabb).minZ = (src_aabb).minZ;\
1392 (dest_aabb).maxZ = (src_aabb).maxZ;\
1393}\
1394
1395//! Computes an Axis aligned box from a triangle
1396#define COMPUTEAABB_FOR_TRIANGLE(aabb,V1,V2,V3) {\
1397 (aabb).minX = MIN3(V1[0],V2[0],V3[0]);\
1398 (aabb).maxX = MAX3(V1[0],V2[0],V3[0]);\
1399 (aabb).minY = MIN3(V1[1],V2[1],V3[1]);\
1400 (aabb).maxY = MAX3(V1[1],V2[1],V3[1]);\
1401 (aabb).minZ = MIN3(V1[2],V2[2],V3[2]);\
1402 (aabb).maxZ = MAX3(V1[2],V2[2],V3[2]);\
1403}\
1404
1405//! Merge two boxes to destaabb
1406#define MERGEBOXES(destaabb,aabb) {\
1407 (destaabb).minX = MIN((aabb).minX,(destaabb).minX);\
1408 (destaabb).minY = MIN((aabb).minY,(destaabb).minY);\
1409 (destaabb).minZ = MIN((aabb).minZ,(destaabb).minZ);\
1410 (destaabb).maxX = MAX((aabb).maxX,(destaabb).maxX);\
1411 (destaabb).maxY = MAX((aabb).maxY,(destaabb).maxY);\
1412 (destaabb).maxZ = MAX((aabb).maxZ,(destaabb).maxZ);\
1413}\
1414
1415//! Extends the box
1416#define AABB_POINT_EXTEND(destaabb,p) {\
1417 (destaabb).minX = MIN(p[0],(destaabb).minX);\
1418 (destaabb).maxX = MAX(p[0],(destaabb).maxX);\
1419 (destaabb).minY = MIN(p[1],(destaabb).minY);\
1420 (destaabb).maxY = MAX(p[1],(destaabb).maxY);\
1421 (destaabb).minZ = MIN(p[2],(destaabb).minZ);\
1422 (destaabb).maxZ = MAX(p[2],(destaabb).maxZ);\
1423}\
1424
1425//! Finds the intersection box of two boxes
1426#define BOXINTERSECTION(aabb1, aabb2, iaabb) {\
1427 (iaabb).minX = MAX((aabb1).minX,(aabb2).minX);\
1428 (iaabb).minY = MAX((aabb1).minY,(aabb2).minY);\
1429 (iaabb).minZ = MAX((aabb1).minZ,(aabb2).minZ);\
1430 (iaabb).maxX = MIN((aabb1).maxX,(aabb2).maxX);\
1431 (iaabb).maxY = MIN((aabb1).maxY,(aabb2).maxY);\
1432 (iaabb).maxZ = MIN((aabb1).maxZ,(aabb2).maxZ);\
1433}\
1434
1435//! Determines if two aligned boxes do intersect
1436#define AABBCOLLISION(intersected,aabb1,aabb2) {\
1437 intersected = 1;\
1438 if ((aabb1).minX > (aabb2).maxX ||\
1439 (aabb1).maxX < (aabb2).minX ||\
1440 (aabb1).minY > (aabb2).maxY ||\
1441 (aabb1).maxY < (aabb2).minY ||\
1442 (aabb1).minZ > (aabb2).maxZ ||\
1443 (aabb1).maxZ < (aabb2).minZ )\
1444 {\
1445 intersected = 0;\
1446 }\
1447}\
1448
1449#define AXIS_INTERSECT(min,max, a, d,tfirst, tlast,is_intersected) {\
1450 if(IS_ZERO(d))\
1451 {\
1452 is_intersected = !(a < min || a > max);\
1453 }\
1454 else\
1455 {\
1456 GREAL a0, a1;\
1457 a0 = (min - a) / (d);\
1458 a1 = (max - a) / (d);\
1459 if(a0 > a1) SWAP_NUMBERS(a0, a1);\
1460 tfirst = MAX(a0, tfirst);\
1461 tlast = MIN(a1, tlast);\
1462 if (tlast < tfirst)\
1463 {\
1464 is_intersected = 0;\
1465 }\
1466 else\
1467 {\
1468 is_intersected = 1;\
1469 }\
1470 }\
1471}\
1472
1473/*! \brief Finds the Ray intersection parameter.
1474
1475\param aabb Aligned box
1476\param vorigin A vec3f with the origin of the ray
1477\param vdir A vec3f with the direction of the ray
1478\param tparam Output parameter
1479\param tmax Max lenght of the ray
1480\param is_intersected 1 if the ray collides the box, else false
1481
1482*/
1483#define BOX_INTERSECTS_RAY(aabb, vorigin, vdir, tparam, tmax,is_intersected) { \
1484 GREAL _tfirst = 0.0f, _tlast = tmax;\
1485 AXIS_INTERSECT(aabb.minX,aabb.maxX,vorigin[0], vdir[0], _tfirst, _tlast,is_intersected);\
1486 if(is_intersected)\
1487 {\
1488 AXIS_INTERSECT(aabb.minY,aabb.maxY,vorigin[1], vdir[1], _tfirst, _tlast,is_intersected);\
1489 }\
1490 if(is_intersected)\
1491 {\
1492 AXIS_INTERSECT(aabb.minZ,aabb.maxZ,vorigin[2], vdir[2], _tfirst, _tlast,is_intersected);\
1493 }\
1494 tparam = _tfirst;\
1495}\
1496
1497#define AABB_PROJECTION_INTERVAL(aabb,direction, vmin, vmax)\
1498{\
1499 GREAL _center[] = {(aabb.minX + aabb.maxX)*0.5f, (aabb.minY + aabb.maxY)*0.5f, (aabb.minZ + aabb.maxZ)*0.5f};\
1500 \
1501 GREAL _extend[] = {aabb.maxX-_center[0],aabb.maxY-_center[1],aabb.maxZ-_center[2]};\
1502 GREAL _fOrigin = VEC_DOT(direction,_center);\
1503 GREAL _fMaximumExtent = _extend[0]*fabsf(direction[0]) + \
1504 _extend[1]*fabsf(direction[1]) + \
1505 _extend[2]*fabsf(direction[2]); \
1506\
1507 vmin = _fOrigin - _fMaximumExtent; \
1508 vmax = _fOrigin + _fMaximumExtent; \
1509}\
1510
1511/*!
1512classify values:
1513<ol>
1514<li> 0 : In back of plane
1515<li> 1 : Spanning
1516<li> 2 : In front of
1517</ol>
1518*/
1519#define PLANE_CLASSIFY_BOX(plane,aabb,classify)\
1520{\
1521 GREAL _fmin,_fmax; \
1522 AABB_PROJECTION_INTERVAL(aabb,plane, _fmin, _fmax); \
1523 if(plane[3] >= _fmax) \
1524 { \
1525 classify = 0;/*In back of*/ \
1526 } \
1527 else \
1528 { \
1529 if(plane[3]+0.000001f>=_fmin) \
1530 { \
1531 classify = 1;/*Spanning*/ \
1532 } \
1533 else \
1534 { \
1535 classify = 2;/*In front of*/ \
1536 } \
1537 } \
1538}\
1539//! @}
1540
1541/*! \defgroup GEOMETRIC_OPERATIONS
1542*/
1543//! @{
1544
1545
1546#define PLANEDIREPSILON 0.0000001f
1547#define PARALELENORMALS 0.000001f
1548
1549#define TRIANGLE_NORMAL(v1,v2,v3,n){\
1550 vec3f _dif1,_dif2; \
1551 VEC_DIFF(_dif1,v2,v1); \
1552 VEC_DIFF(_dif2,v3,v1); \
1553 VEC_CROSS(n,_dif1,_dif2); \
1554 VEC_NORMALIZE(n); \
1555}\
1556
1557/// plane is a vec4f
1558#define TRIANGLE_PLANE(v1,v2,v3,plane) {\
1559 TRIANGLE_NORMAL(v1,v2,v3,plane);\
1560 plane[3] = VEC_DOT(v1,plane);\
1561}\
1562
1563/// Calc a plane from an edge an a normal. plane is a vec4f
1564#define EDGE_PLANE(e1,e2,n,plane) {\
1565 vec3f _dif; \
1566 VEC_DIFF(_dif,e2,e1); \
1567 VEC_CROSS(plane,_dif,n); \
1568 VEC_NORMALIZE(plane); \
1569 plane[3] = VEC_DOT(e1,plane);\
1570}\
1571
1572#define DISTANCE_PLANE_POINT(plane,point) (VEC_DOT(plane,point) - plane[3])
1573
1574#define PROJECT_POINT_PLANE(point,plane,projected) {\
1575 GREAL _dis;\
1576 _dis = DISTANCE_PLANE_POINT(plane,point);\
1577 VEC_SCALE(projected,-_dis,plane);\
1578 VEC_SUM(projected,projected,point); \
1579}\
1580
1581#define POINT_IN_HULL(point,planes,plane_count,outside)\
1582{\
1583 GREAL _dis;\
1584 outside = 0;\
1585 GUINT _i = 0;\
1586 do\
1587 {\
1588 _dis = DISTANCE_PLANE_POINT(planes[_i],point);\
1589 if(_dis>0.0f) outside = 1;\
1590 _i++;\
1591 }while(_i<plane_count&&outside==0);\
1592}\
1593
1594
1595#define PLANE_CLIP_SEGMENT(s1,s2,plane,clipped) {\
1596 GREAL _dis1,_dis2;\
1597 _dis1 = DISTANCE_PLANE_POINT(plane,s1);\
1598 VEC_DIFF(clipped,s2,s1);\
1599 _dis2 = VEC_DOT(clipped,plane);\
1600 VEC_SCALE(clipped,-_dis1/_dis2,clipped);\
1601 VEC_SUM(clipped,clipped,s1); \
1602}\
1603
1604//! Confirms if the plane intersect the edge or nor
1605/*!
1606intersection type must have the following values
1607<ul>
1608<li> 0 : Segment in front of plane, s1 closest
1609<li> 1 : Segment in front of plane, s2 closest
1610<li> 2 : Segment in back of plane, s1 closest
1611<li> 3 : Segment in back of plane, s2 closest
1612<li> 4 : Segment collides plane, s1 in back
1613<li> 5 : Segment collides plane, s2 in back
1614</ul>
1615*/
1616#define PLANE_CLIP_SEGMENT2(s1,s2,plane,clipped,intersection_type) \
1617{\
1618 GREAL _dis1,_dis2;\
1619 _dis1 = DISTANCE_PLANE_POINT(plane,s1);\
1620 _dis2 = DISTANCE_PLANE_POINT(plane,s2);\
1621 if(_dis1 >-G_EPSILON && _dis2 >-G_EPSILON)\
1622 {\
1623 if(_dis1<_dis2) intersection_type = 0;\
1624 else intersection_type = 1;\
1625 }\
1626 else if(_dis1 <G_EPSILON && _dis2 <G_EPSILON)\
1627 {\
1628 if(_dis1>_dis2) intersection_type = 2;\
1629 else intersection_type = 3; \
1630 }\
1631 else\
1632 {\
1633 if(_dis1<_dis2) intersection_type = 4;\
1634 else intersection_type = 5;\
1635 VEC_DIFF(clipped,s2,s1);\
1636 _dis2 = VEC_DOT(clipped,plane);\
1637 VEC_SCALE(clipped,-_dis1/_dis2,clipped);\
1638 VEC_SUM(clipped,clipped,s1); \
1639 }\
1640}\
1641
1642//! Confirms if the plane intersect the edge or not
1643/*!
1644clipped1 and clipped2 are the vertices behind the plane.
1645clipped1 is the closest
1646
1647intersection_type must have the following values
1648<ul>
1649<li> 0 : Segment in front of plane, s1 closest
1650<li> 1 : Segment in front of plane, s2 closest
1651<li> 2 : Segment in back of plane, s1 closest
1652<li> 3 : Segment in back of plane, s2 closest
1653<li> 4 : Segment collides plane, s1 in back
1654<li> 5 : Segment collides plane, s2 in back
1655</ul>
1656*/
1657#define PLANE_CLIP_SEGMENT_CLOSEST(s1,s2,plane,clipped1,clipped2,intersection_type)\
1658{\
1659 PLANE_CLIP_SEGMENT2(s1,s2,plane,clipped1,intersection_type);\
1660 if(intersection_type == 0)\
1661 {\
1662 VEC_COPY(clipped1,s1);\
1663 VEC_COPY(clipped2,s2);\
1664 }\
1665 else if(intersection_type == 1)\
1666 {\
1667 VEC_COPY(clipped1,s2);\
1668 VEC_COPY(clipped2,s1);\
1669 }\
1670 else if(intersection_type == 2)\
1671 {\
1672 VEC_COPY(clipped1,s1);\
1673 VEC_COPY(clipped2,s2);\
1674 }\
1675 else if(intersection_type == 3)\
1676 {\
1677 VEC_COPY(clipped1,s2);\
1678 VEC_COPY(clipped2,s1);\
1679 }\
1680 else if(intersection_type == 4)\
1681 { \
1682 VEC_COPY(clipped2,s1);\
1683 }\
1684 else if(intersection_type == 5)\
1685 { \
1686 VEC_COPY(clipped2,s2);\
1687 }\
1688}\
1689
1690
1691//! Finds the 2 smallest cartesian coordinates of a plane normal
1692#define PLANE_MINOR_AXES(plane, i0, i1)\
1693{\
1694 GREAL A[] = {fabs(plane[0]),fabs(plane[1]),fabs(plane[2])};\
1695 if(A[0]>A[1])\
1696 {\
1697 if(A[0]>A[2])\
1698 {\
1699 i0=1; /* A[0] is greatest */ \
1700 i1=2;\
1701 }\
1702 else \
1703 {\
1704 i0=0; /* A[2] is greatest */ \
1705 i1=1; \
1706 }\
1707 }\
1708 else /* A[0]<=A[1] */ \
1709 {\
1710 if(A[2]>A[1]) \
1711 { \
1712 i0=0; /* A[2] is greatest */ \
1713 i1=1; \
1714 }\
1715 else \
1716 {\
1717 i0=0; /* A[1] is greatest */ \
1718 i1=2; \
1719 }\
1720 } \
1721}\
1722
1723//! Ray plane collision
1724#define RAY_PLANE_COLLISION(plane,vDir,vPoint,pout,tparam,does_intersect)\
1725{\
1726 GREAL _dis,_dotdir; \
1727 _dotdir = VEC_DOT(plane,vDir);\
1728 if(_dotdir<PLANEDIREPSILON)\
1729 {\
1730 does_intersect = 0;\
1731 }\
1732 else\
1733 {\
1734 _dis = DISTANCE_PLANE_POINT(plane,vPoint); \
1735 tparam = -_dis/_dotdir;\
1736 VEC_SCALE(pout,tparam,vDir);\
1737 VEC_SUM(pout,vPoint,pout); \
1738 does_intersect = 1;\
1739 }\
1740}\
1741
1742//! Bidireccional ray
1743#define LINE_PLANE_COLLISION(plane,vDir,vPoint,pout,tparam, tmin, tmax)\
1744{\
1745 tparam = -DISTANCE_PLANE_POINT(plane,vPoint);\
1746 tparam /= VEC_DOT(plane,vDir);\
1747 tparam = CLAMP(tparam,tmin,tmax);\
1748 VEC_SCALE(pout,tparam,vDir);\
1749 VEC_SUM(pout,vPoint,pout); \
1750}\
1751
1752/*! \brief Returns the Ray on which 2 planes intersect if they do.
1753 Written by Rodrigo Hernandez on ODE convex collision
1754
1755 \param p1 Plane 1
1756 \param p2 Plane 2
1757 \param p Contains the origin of the ray upon returning if planes intersect
1758 \param d Contains the direction of the ray upon returning if planes intersect
1759 \param dointersect 1 if the planes intersect, 0 if paralell.
1760
1761*/
1762#define INTERSECT_PLANES(p1,p2,p,d,dointersect) \
1763{ \
1764 VEC_CROSS(d,p1,p2); \
1765 GREAL denom = VEC_DOT(d, d);\
1766 if (IS_ZERO(denom)) \
1767 { \
1768 dointersect = 0; \
1769 } \
1770 else \
1771 { \
1772 vec3f _n;\
1773 _n[0]=p1[3]*p2[0] - p2[3]*p1[0]; \
1774 _n[1]=p1[3]*p2[1] - p2[3]*p1[1]; \
1775 _n[2]=p1[3]*p2[2] - p2[3]*p1[2]; \
1776 VEC_CROSS(p,_n,d); \
1777 p[0]/=denom; \
1778 p[1]/=denom; \
1779 p[2]/=denom; \
1780 dointersect = 1; \
1781 }\
1782}\
1783
1784//***************** SEGMENT and LINE FUNCTIONS **********************************///
1785
1786/*! Finds the closest point(cp) to (v) on a segment (e1,e2)
1787 */
1788#define CLOSEST_POINT_ON_SEGMENT(cp,v,e1,e2) \
1789{ \
1790 vec3f _n;\
1791 VEC_DIFF(_n,e2,e1);\
1792 VEC_DIFF(cp,v,e1);\
1793 GREAL _scalar = VEC_DOT(cp, _n); \
1794 _scalar/= VEC_DOT(_n, _n); \
1795 if(_scalar <0.0f)\
1796 {\
1797 VEC_COPY(cp,e1);\
1798 }\
1799 else if(_scalar >1.0f)\
1800 {\
1801 VEC_COPY(cp,e2);\
1802 }\
1803 else \
1804 {\
1805 VEC_SCALE(cp,_scalar,_n);\
1806 VEC_SUM(cp,cp,e1);\
1807 } \
1808}\
1809
1810
1811/*! \brief Finds the line params where these lines intersect.
1812
1813\param dir1 Direction of line 1
1814\param point1 Point of line 1
1815\param dir2 Direction of line 2
1816\param point2 Point of line 2
1817\param t1 Result Parameter for line 1
1818\param t2 Result Parameter for line 2
1819\param dointersect 0 if the lines won't intersect, else 1
1820
1821*/
1822#define LINE_INTERSECTION_PARAMS(dir1,point1, dir2, point2,t1,t2,dointersect) {\
1823 GREAL det;\
1824 GREAL e1e1 = VEC_DOT(dir1,dir1);\
1825 GREAL e1e2 = VEC_DOT(dir1,dir2);\
1826 GREAL e2e2 = VEC_DOT(dir2,dir2);\
1827 vec3f p1p2;\
1828 VEC_DIFF(p1p2,point1,point2);\
1829 GREAL p1p2e1 = VEC_DOT(p1p2,dir1);\
1830 GREAL p1p2e2 = VEC_DOT(p1p2,dir2);\
1831 det = e1e2*e1e2 - e1e1*e2e2;\
1832 if(IS_ZERO(det))\
1833 {\
1834 dointersect = 0;\
1835 }\
1836 else\
1837 {\
1838 t1 = (e1e2*p1p2e2 - e2e2*p1p2e1)/det;\
1839 t2 = (e1e1*p1p2e2 - e1e2*p1p2e1)/det;\
1840 dointersect = 1;\
1841 }\
1842}\
1843
1844//! Find closest points on segments
1845#define SEGMENT_COLLISION(vA1,vA2,vB1,vB2,vPointA,vPointB)\
1846{\
1847 vec3f _AD,_BD,_N;\
1848 vec4f _M;\
1849 VEC_DIFF(_AD,vA2,vA1);\
1850 VEC_DIFF(_BD,vB2,vB1);\
1851 VEC_CROSS(_N,_AD,_BD);\
1852 VEC_CROSS(_M,_N,_BD);\
1853 _M[3] = VEC_DOT(_M,vB1);\
1854 float _tp; \
1855 LINE_PLANE_COLLISION(_M,_AD,vA1,vPointA,_tp,0.0f, 1.0f);\
1856 /*Closest point on segment*/ \
1857 VEC_DIFF(vPointB,vPointA,vB1);\
1858 _tp = VEC_DOT(vPointB, _BD); \
1859 _tp/= VEC_DOT(_BD, _BD); \
1860 _tp = CLAMP(_tp,0.0f,1.0f); \
1861 VEC_SCALE(vPointB,_tp,_BD);\
1862 VEC_SUM(vPointB,vPointB,vB1);\
1863}\
1864
1865//! @}
1866
1867///Additional Headers for Collision
1868#include "GIMPACT/gim_tri_collision.h"
1869#include "GIMPACT/gim_tri_sphere_collision.h"
1870#include "GIMPACT/gim_tri_capsule_collision.h"
1871
1872#endif // GIM_VECTOR_H_INCLUDED
diff --git a/libraries/ode-0.9/GIMPACT/include/GIMPACT/gim_math.h b/libraries/ode-0.9/GIMPACT/include/GIMPACT/gim_math.h
new file mode 100644
index 0000000..68f226e
--- /dev/null
+++ b/libraries/ode-0.9/GIMPACT/include/GIMPACT/gim_math.h
@@ -0,0 +1,147 @@
1#ifndef GIM_MATH_H_INCLUDED
2#define GIM_MATH_H_INCLUDED
3
4/*! \file gim_math.h
5\author Francisco León
6*/
7/*
8-----------------------------------------------------------------------------
9This source file is part of GIMPACT Library.
10
11For the latest info, see http://gimpact.sourceforge.net/
12
13Copyright (c) 2006 Francisco Leon. C.C. 80087371.
14email: projectileman@yahoo.com
15
16 This library is free software; you can redistribute it and/or
17 modify it under the terms of EITHER:
18 (1) The GNU Lesser General Public License as published by the Free
19 Software Foundation; either version 2.1 of the License, or (at
20 your option) any later version. The text of the GNU Lesser
21 General Public License is included with this library in the
22 file GIMPACT-LICENSE-LGPL.TXT.
23 (2) The BSD-style license that is included with this library in
24 the file GIMPACT-LICENSE-BSD.TXT.
25
26 This library is distributed in the hope that it will be useful,
27 but WITHOUT ANY WARRANTY; without even the implied warranty of
28 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files
29 GIMPACT-LICENSE-LGPL.TXT and GIMPACT-LICENSE-BSD.TXT for more details.
30
31-----------------------------------------------------------------------------
32*/
33
34
35#include <math.h>
36#include <float.h>
37
38
39/*! \defgroup BASIC_TYPES
40Basic types and constants
41Conventions:
42Types starting with G
43Constants starting with G_
44*/
45//! @{
46/*! Types */
47#define GREAL float
48#define GINT long
49#define GUINT unsigned long
50/*! Constants for integers*/
51#define GUINT_BIT_COUNT 32
52#define GUINT_EXPONENT 5
53
54#define G_FASTMATH 1
55#define G_PI 3.14159265358979f
56#define G_HALF_PI 1.5707963f
57//267948966
58#define G_TWO_PI 6.28318530f
59//71795864
60#define G_ROOT3 1.73205f
61#define G_ROOT2 1.41421f
62#define G_UINT_INFINITY 65534
63#define G_REAL_INFINITY FLT_MAX
64#define G_SIGN_BITMASK 0x80000000
65#define G_USE_EPSILON_TEST
66#define G_EPSILON 0.0000001f
67//! @}
68
69/*! \defgroup MATH_FUNCTIONS
70mathematical functions
71*/
72//! @{
73#define G_DEGTORAD(X) ((X)*3.1415926f/180.0f)
74#define G_RADTODEG(X) ((X)*180.0f/3.1415926f)
75
76//! Integer representation of a floating-point value.
77#define IR(x) ((GUINT&)(x))
78
79//! Signed integer representation of a floating-point value.
80#define SIR(x) ((GINT&)(x))
81
82//! Absolute integer representation of a floating-point value
83#define AIR(x) (IR(x)&0x7fffffff)
84
85//! Floating-point representation of an integer value.
86#define FR(x) ((GREAL&)(x))
87
88#define MAX(a,b) (a<b?b:a)
89#define MIN(a,b) (a>b?b:a)
90
91#define MAX3(a,b,c) MAX(a,MAX(b,c))
92#define MIN3(a,b,c) MIN(a,MIN(b,c))
93
94#define IS_ZERO(value) (value < G_EPSILON && value > -G_EPSILON)
95
96#define IS_NEGATIVE(value) (value <= -G_EPSILON)
97
98#define IS_POSISITVE(value) (value >= G_EPSILON)
99
100///returns a clamped number
101#define CLAMP(number,minval,maxval) (number<minval?minval:(number>maxval?maxval:number))
102
103///Swap numbers
104#define SWAP_NUMBERS(a,b){ \
105 a = a+b; \
106 b = a-b; \
107 a = a-b; \
108}\
109
110#define GIM_INV_SQRT(va,isva)\
111{\
112 if(va<=0.0000001f)\
113 {\
114 isva = G_REAL_INFINITY;\
115 }\
116 else\
117 {\
118 GREAL _x = va * 0.5f;\
119 GUINT _y = 0x5f3759df - ( IR(va) >> 1);\
120 isva = FR(_y);\
121 isva = isva * ( 1.5f - ( _x * isva * isva ) );\
122 }\
123}\
124
125#define GIM_SQRT(va,sva)\
126{\
127 GIM_INV_SQRT(va,sva);\
128 sva = 1.0f/sva;\
129}\
130
131//! Computes 1.0f / sqrtf(x). Comes from Quake3. See http://www.magic-software.com/3DGEDInvSqrt.html
132GREAL gim_inv_sqrt(GREAL f);
133
134//! Computes sqrtf(x) faster.
135/*!
136\sa gim_inv_sqrt
137*/
138GREAL gim_sqrt(GREAL f);
139
140//!Initializes mathematical functions
141void gim_init_math();
142
143//! Generates an unit random
144GREAL gim_unit_random();
145//! @}
146
147#endif // GIM_MATH_H_INCLUDED
diff --git a/libraries/ode-0.9/GIMPACT/include/GIMPACT/gim_memory.h b/libraries/ode-0.9/GIMPACT/include/GIMPACT/gim_memory.h
new file mode 100644
index 0000000..58661f1
--- /dev/null
+++ b/libraries/ode-0.9/GIMPACT/include/GIMPACT/gim_memory.h
@@ -0,0 +1,1040 @@
1#ifndef GIM_MEMORY_H_INCLUDED
2#define GIM_MEMORY_H_INCLUDED
3/*! \file gim_memory.h
4\author Francisco León
5*/
6/*
7-----------------------------------------------------------------------------
8This source file is part of GIMPACT Library.
9
10For the latest info, see http://gimpact.sourceforge.net/
11
12Copyright (c) 2006 Francisco Leon. C.C. 80087371.
13email: projectileman@yahoo.com
14
15 This library is free software; you can redistribute it and/or
16 modify it under the terms of EITHER:
17 (1) The GNU Lesser General Public License as published by the Free
18 Software Foundation; either version 2.1 of the License, or (at
19 your option) any later version. The text of the GNU Lesser
20 General Public License is included with this library in the
21 file GIMPACT-LICENSE-LGPL.TXT.
22 (2) The BSD-style license that is included with this library in
23 the file GIMPACT-LICENSE-BSD.TXT.
24
25 This library is distributed in the hope that it will be useful,
26 but WITHOUT ANY WARRANTY; without even the implied warranty of
27 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files
28 GIMPACT-LICENSE-LGPL.TXT and GIMPACT-LICENSE-BSD.TXT for more details.
29
30-----------------------------------------------------------------------------
31*/
32
33
34#include "GIMPACT/gim_math.h"
35#include <memory.h>
36
37//#define PREFETCH 1
38//! \defgroup PREFETCH
39//! @{
40#ifdef PREFETCH
41#include <xmmintrin.h> // for prefetch
42#define pfval 64
43#define pfval2 128
44//! Prefetch 64
45#define pf(_x,_i) _mm_prefetch((void *)(_x + _i + pfval), 0)
46//! Prefetch 128
47#define pf2(_x,_i) _mm_prefetch((void *)(_x + _i + pfval2), 0)
48#else
49//! Prefetch 64
50#define pf(_x,_i)
51//! Prefetch 128
52#define pf2(_x,_i)
53#endif
54//! @}
55
56/*! \defgroup ARRAY_UTILITIES
57\brief
58Functions for manip packed arrays of numbers
59*/
60//! @{
61#define GIM_COPY_ARRAYS(dest_array,source_array,element_count)\
62{\
63 GUINT _i_;\
64 for (_i_=0;_i_<element_count ;_i_++)\
65 {\
66 dest_array[_i_] = source_array[_i_];\
67 }\
68}\
69
70#define GIM_COPY_ARRAYS_1(dest_array,source_array,element_count,copy_macro)\
71{\
72 GUINT _i_;\
73 for (_i_=0;_i_<element_count ;_i_++)\
74 {\
75 copy_macro(dest_array[_i_],source_array[_i_]);\
76 }\
77}\
78
79
80#define GIM_ZERO_ARRAY(array,element_count)\
81{\
82 GUINT _i_;\
83 for (_i_=0;_i_<element_count ;_i_++)\
84 {\
85 array[_i_] = 0;\
86 }\
87}\
88
89#define GIM_CONSTANT_ARRAY(array,element_count,constant)\
90{\
91 GUINT _i_;\
92 for (_i_=0;_i_<element_count ;_i_++)\
93 {\
94 array[_i_] = constant;\
95 }\
96}\
97//! @}
98
99/*! \defgroup MEMORY_FUNCTION_PROTOTYPES
100Function prototypes to allocate and free memory.
101*/
102//! @{
103typedef void * gim_alloc_function (size_t size);
104typedef void * gim_alloca_function (size_t size);//Allocs on the heap
105typedef void * gim_realloc_function (void *ptr, size_t oldsize, size_t newsize);
106typedef void gim_free_function (void *ptr, size_t size);
107//! @}
108
109/*! \defgroup MEMORY_FUNCTION_HANDLERS
110\brief
111Memory Function Handlers
112 set new memory management functions. if fn is 0, the default handlers are
113 used. */
114//! @{
115void gim_set_alloc_handler (gim_alloc_function *fn);
116void gim_set_alloca_handler (gim_alloca_function *fn);
117void gim_set_realloc_handler (gim_realloc_function *fn);
118void gim_set_free_handler (gim_free_function *fn);
119//! @}
120
121/*! \defgroup MEMORY_FUNCTION_GET_HANDLERS
122\brief
123get current memory management functions.
124*/
125//! @{
126gim_alloc_function *gim_get_alloc_handler (void);
127gim_alloca_function *gim_get_alloca_handler(void);
128gim_realloc_function *gim_get_realloc_handler (void);
129gim_free_function *gim_get_free_handler (void);
130//! @}
131
132/*! \defgroup MEMORY_FUNCTIONS
133Standar Memory functions
134*/
135//! @{
136void * gim_alloc(size_t size);
137void * gim_alloca(size_t size);
138void * gim_realloc(void *ptr, size_t oldsize, size_t newsize);
139void gim_free(void *ptr, size_t size);
140//! @}
141
142/*! \defgroup DYNAMIC_ARRAYS
143\brief
144Dynamic Arrays. Allocated from system memory.
145<ul>
146<li> For initializes a dynamic array, use GIM_DYNARRAY_CREATE or GIM_DYNARRAY_CREATE_SIZED.
147<li> When an array is no longer used, must be terminated with the macro GIM_DYNARRAY_DESTROY.
148</ul>
149*/
150//! @{
151#define G_ARRAY_GROW_SIZE 100
152
153//! Dynamic array handle.
154struct GDYNAMIC_ARRAY
155{
156 char * m_pdata;
157 GUINT m_size;
158 GUINT m_reserve_size;
159};
160//typedef struct _GDYNAMIC_ARRAY GDYNAMIC_ARRAY;
161
162//! Creates a dynamic array zero sized
163#define GIM_DYNARRAY_CREATE(type,array_data,reserve_size) \
164{ \
165 array_data.m_pdata = (char *)gim_alloc(reserve_size*sizeof(type)); \
166 array_data.m_size = 0; \
167 array_data.m_reserve_size = reserve_size; \
168}\
169
170//! Creates a dynamic array with n = size elements
171#define GIM_DYNARRAY_CREATE_SIZED(type,array_data,size) \
172{ \
173 array_data.m_pdata = (char *)gim_alloc(size*sizeof(type)); \
174 array_data.m_size = size; \
175 array_data.m_reserve_size = size; \
176}\
177
178//! Reserves memory for a dynamic array.
179#define GIM_DYNARRAY_RESERVE_SIZE(type,array_data,reserve_size) \
180{ \
181 if(reserve_size>array_data.m_reserve_size )\
182 { \
183 array_data.m_pdata = (char *) gim_realloc(array_data.m_pdata,array_data.m_size*sizeof(type),reserve_size*sizeof(type));\
184 array_data.m_reserve_size = reserve_size; \
185 }\
186}\
187
188//! Set the size of the array
189#define GIM_DYNARRAY_SET_SIZE(type,array_data,size) \
190{ \
191 GIM_DYNARRAY_RESERVE_SIZE(type,array_data,size);\
192 array_data.m_size = size;\
193}\
194
195//! Gets a pointer from the beginning of the array
196#define GIM_DYNARRAY_POINTER(type,array_data) (type *)(array_data.m_pdata)
197
198//! Gets a pointer from the last elemento of the array
199#define GIM_DYNARRAY_POINTER_LAST(type,array_data) (((type *)array_data.m_pdata)+array_data.m_size-1)
200
201//! Inserts an element at the last position
202#define GIM_DYNARRAY_PUSH_ITEM(type,array_data,item)\
203{\
204 if(array_data.m_reserve_size<=array_data.m_size)\
205 {\
206 GIM_DYNARRAY_RESERVE_SIZE(type,array_data,(array_data.m_size+G_ARRAY_GROW_SIZE));\
207 }\
208 type * _pt = GIM_DYNARRAY_POINTER(type,array_data);\
209 memcpy(&_pt[array_data.m_size],&item,sizeof(type));\
210 array_data.m_size++; \
211}\
212
213//! Inserts an element at the last position
214#define GIM_DYNARRAY_PUSH_EMPTY(type,array_data)\
215{\
216 if(array_data.m_reserve_size<=array_data.m_size)\
217 {\
218 GIM_DYNARRAY_RESERVE_SIZE(type,array_data,(array_data.m_size+G_ARRAY_GROW_SIZE));\
219 }\
220 array_data.m_size++; \
221}\
222
223//! Inserts an element
224#define GIM_DYNARRAY_INSERT_ITEM(type,array_data,item,index) \
225{ \
226 if(array_data.m_reserve_size<=array_data.m_size)\
227 {\
228 GIM_DYNARRAY_RESERVE_SIZE(type,array_data,(array_data.m_size+G_ARRAY_GROW_SIZE));\
229 }\
230 type * _pt = GIM_DYNARRAY_POINTER(type,array_data);\
231 if(index<array_data.m_size-1) \
232 { \
233 memcpy(&_pt[index+1],&_pt[index],(array_data.m_size-index)*sizeof(type));\
234 } \
235 memcpy(&_pt[index],&item,sizeof(type));\
236 array_data.m_size++; \
237}\
238
239//! Removes an element
240#define GIM_DYNARRAY_DELETE_ITEM(type,array_data,index) \
241{ \
242 if(index<array_data.m_size-1) \
243 { \
244 type * _pt = GIM_DYNARRAY_POINTER(type,array_data);\
245 memcpy(&_pt[index],&_pt[index+1],(array_data.m_size-index-1)*sizeof(type));\
246 } \
247 array_data.m_size--; \
248}\
249
250//! Removes an element at the last position
251#define GIM_DYNARRAY_POP_ITEM(array_data) \
252{ \
253 if(array_data.m_size>0) \
254 { \
255 array_data.m_size--; \
256 } \
257}\
258
259//! Destroys the array
260void GIM_DYNARRAY_DESTROY(GDYNAMIC_ARRAY & array_data);
261//! @}
262
263/*! \defgroup BITSET
264\brief
265Bitsets , based on \ref DYNAMIC_ARRAYS .
266<ul>
267<li> For initializes a bitset array, use \ref GIM_BITSET_CREATE or \ref GIM_BITSET_CREATE_SIZED.
268<li> When the bitset is no longer used, must be terminated with the macro \ref GIM_DYNARRAY_DESTROY.
269<li> For putting a mark on the bitset, call \ref GIM_BITSET_SET
270<li> For clearing a mark on the bitset, call \ref GIM_BITSET_CLEAR
271<li> For retrieving a bit value from a bitset, call \ref GIM_BITSET_GET-
272</ul>
273*/
274//! @{
275
276//! Creates a bitset
277#define GIM_BITSET_CREATE(array_data) GIM_DYNARRAY_CREATE(GUINT,array_data,G_ARRAY_GROW_SIZE)
278
279//! Creates a bitset, with their bits set to 0.
280#define GIM_BITSET_CREATE_SIZED(array_data,bits_count)\
281{\
282 array_data.m_size = bits_count/GUINT_BIT_COUNT + 1;\
283 GIM_DYNARRAY_CREATE(GUINT,array_data,array_data.m_size);\
284 GUINT * _pt = GIM_DYNARRAY_POINTER(GUINT,array_data);\
285 memset(_pt,0,sizeof(GUINT)*(array_data.m_size));\
286}\
287
288//! Gets the bitset bit count.
289#define GIM_BITSET_SIZE(array_data) (array_data.m_size*GUINT_BIT_COUNT)
290
291//! Resizes a bitset, with their bits set to 0.
292#define GIM_BITSET_RESIZE(array_data,new_bits_count)\
293{ \
294 GUINT _oldsize = array_data.m_size;\
295 array_data.m_size = new_bits_count/GUINT_BIT_COUNT + 1; \
296 if(_oldsize<array_data.m_size)\
297 {\
298 if(array_data.m_size > array_data.m_reserve_size)\
299 {\
300 GIM_DYNARRAY_RESERVE_SIZE(GUINT,array_data,array_data.m_size+G_ARRAY_GROW_SIZE);\
301 }\
302 GUINT * _pt = GIM_DYNARRAY_POINTER(GUINT,array_data);\
303 memset(&_pt[_oldsize],0,sizeof(GUINT)*(array_data.m_size-_oldsize));\
304 }\
305}\
306
307//! Sets all bitset bit to 0.
308#define GIM_BITSET_CLEAR_ALL(array_data)\
309{\
310 memset(array_data.m_pdata,0,sizeof(GUINT)*array_data.m_size);\
311}\
312
313//! Sets all bitset bit to 1.
314#define GIM_BITSET_SET_ALL(array_data)\
315{\
316 memset(array_data.m_pdata,0xFF,sizeof(GUINT)*array_data.m_size);\
317}\
318
319///Sets the desired bit to 1
320#define GIM_BITSET_SET(array_data,bit_index)\
321{\
322 if(bit_index>=GIM_BITSET_SIZE(array_data))\
323 {\
324 GIM_BITSET_RESIZE(array_data,bit_index);\
325 }\
326 GUINT * _pt = GIM_DYNARRAY_POINTER(GUINT,array_data);\
327 _pt[bit_index >> GUINT_EXPONENT] |= (1 << (bit_index & (GUINT_BIT_COUNT-1)));\
328}\
329
330///Return 0 or 1
331#define GIM_BITSET_GET(array_data,bit_index,get_value) \
332{\
333 if(bit_index>=GIM_BITSET_SIZE(array_data))\
334 {\
335 get_value = 0;\
336 }\
337 else\
338 {\
339 GUINT * _pt = GIM_DYNARRAY_POINTER(GUINT,array_data);\
340 get_value = _pt[bit_index >> GUINT_EXPONENT] & (1 << (bit_index & (GUINT_BIT_COUNT-1)));\
341 }\
342}\
343
344///Sets the desired bit to 0
345#define GIM_BITSET_CLEAR(array_data,bit_index) \
346{\
347 if(bit_index<GIM_BITSET_SIZE(array_data))\
348 {\
349 GUINT * _pt = GIM_DYNARRAY_POINTER(GUINT,array_data);\
350 _pt[bit_index >> GUINT_EXPONENT] &= ~(1 << (bit_index & (GUINT_BIT_COUNT-1)));\
351 }\
352}\
353//! @}
354
355/*! \defgroup MEMORY_ACCESS_CONSTANTS
356\brief
357Memory Access constants.
358\sa BUFFERS
359*/
360//! @{
361#define G_MA_READ_ONLY 1
362#define G_MA_WRITE_ONLY 2
363#define G_MA_READ_WRITE 3
364//! @}
365
366/*! \defgroup MEMORY_USAGE_CONSTANTS
367\brief
368Memory usage constants.
369\sa BUFFERS
370*/
371//! @{
372/// Don't care how memory is used
373#define G_MU_EITHER 0
374/// specified once, doesn't allow read information
375#define G_MU_STATIC_WRITE 1
376/// specified once, allows to read information from a shadow buffer
377#define G_MU_STATIC_READ 2
378/// write directly on buffer, allows to read information from a shadow buffer
379#define G_MU_STATIC_READ_DYNAMIC_WRITE 3
380/// upload data to buffer from the shadow buffer, allows to read information from a shadow buffer
381#define G_MU_STATIC_READ_DYNAMIC_WRITE_COPY 4
382/// specified once, allows to read information directly from memory
383#define G_MU_STATIC_WRITE_DYNAMIC_READ 5
384/// write directly on buffer, allows to read information directly from memory
385#define G_MU_DYNAMIC_READ_WRITE 6
386//! @}
387
388/*! \defgroup BUFFER_ERRORS
389\brief
390Buffer operation errors
391\sa BUFFERS
392*/
393//! @{
394#define G_BUFFER_OP_SUCCESS 0
395#define G_BUFFER_OP_INVALID 1
396#define G_BUFFER_OP_STILLREFCOUNTED 2
397//! @}
398
399/*! \defgroup BUFFER_MANAGER_IDS
400\brief
401Buffer manager identifiers
402\sa BUFFERS, BUFFER_MANAGERS
403*/
404//! @{
405#define G_BUFFER_MANAGER_SYSTEM 0
406#define G_BUFFER_MANAGER_SHARED 1
407#define G_BUFFER_MANAGER_USER 2
408//! @}
409
410/*! \defgroup BUFFERS
411\brief
412Buffer operations and structs.
413<ul>
414<li> Before using buffers you must initializes GIMPACT buffer managers by calling \ref gimpact_init.
415<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.
416<li> For accessing to the buffer memory, you must call \ref gim_lock_buffer, and then \ref gim_unlock_buffer for finish the access.
417<li> When a buffer is no longer needed, you must free it by calling \ref gim_buffer_free.
418<li> You must call \ref gimpact_terminate when finish your application.
419<li> For a safe manipulation of buffers, use \ref BUFFER_ARRAYS
420</ul>
421\sa BUFFER_MANAGERS, BUFFER_ARRAYS
422*/
423//! @{
424
425//! Buffer handle.
426struct GBUFFER_ID
427{
428 GUINT m_buffer_id;
429 GUINT m_buffer_manager_id;
430};
431//typedef struct _GBUFFER_ID GBUFFER_ID;
432
433//! Buffer internal data
434struct GBUFFER_DATA
435{
436 GUINT m_buffer_handle;//!< if 0, buffer doesn't exists
437 GUINT m_size;
438 GUINT m_usage;
439 GINT m_access;
440 GUINT m_lock_count;
441 char * m_mapped_pointer;
442 GBUFFER_ID m_shadow_buffer;
443 GUINT m_refcount;//! Reference counting for safe garbage collection
444};
445//typedef struct _GBUFFER_DATA GBUFFER_DATA;
446//! @}
447
448/*! \defgroup BUFFERS_MANAGER_PROTOTYPES
449\brief
450Function prototypes to allocate and free memory for buffers
451\sa BUFFER_MANAGERS, BUFFERS
452*/
453//! @{
454
455//! Returns a Buffer handle
456typedef GUINT gim_buffer_alloc_function(GUINT size,int usage);
457
458//! Returns a Buffer handle, and copies the pdata to the buffer
459typedef GUINT gim_buffer_alloc_data_function(const void * pdata,GUINT size,int usage);
460
461//! Changes the size of the buffer preserving the content, and returns the new buffer id
462typedef GUINT gim_buffer_realloc_function(GUINT buffer_handle,GUINT oldsize,int old_usage,GUINT newsize,int new_usage);
463
464//! It changes the m_buffer_handle member to 0/0
465typedef void gim_buffer_free_function(GUINT buffer_handle,GUINT size);
466
467//! It maps the m_mapped_pointer. Returns a pointer
468typedef char * gim_lock_buffer_function(GUINT buffer_handle,int access);
469
470//! It sets the m_mapped_pointer to 0
471typedef void gim_unlock_buffer_function(GUINT buffer_handle);
472
473typedef void gim_download_from_buffer_function(
474 GUINT source_buffer_handle,
475 GUINT source_pos,
476 void * destdata,
477 GUINT copysize);
478
479typedef void gim_upload_to_buffer_function(
480 GUINT dest_buffer_handle,
481 GUINT dest_pos,
482 void * sourcedata,
483 GUINT copysize);
484
485typedef void gim_copy_buffers_function(
486 GUINT source_buffer_handle,
487 GUINT source_pos,
488 GUINT dest_buffer_handle,
489 GUINT dest_pos,
490 GUINT copysize);
491//! @}
492
493
494/*! \defgroup BUFFER_MANAGERS
495\brief
496Buffer Manager operations
497*/
498//! @{
499//! Buffer manager prototype
500struct GBUFFER_MANAGER_PROTOTYPE
501{
502 gim_buffer_alloc_function * alloc_fn;
503 gim_buffer_alloc_data_function *alloc_data_fn;
504 gim_buffer_realloc_function * realloc_fn;
505 gim_buffer_free_function * free_fn;
506 gim_lock_buffer_function * lock_buffer_fn;
507 gim_unlock_buffer_function * unlock_buffer_fn;
508 gim_download_from_buffer_function * download_from_buffer_fn;
509 gim_upload_to_buffer_function * upload_to_buffer_fn;
510 gim_copy_buffers_function * copy_buffers_fn;
511};
512//typedef struct _GBUFFER_MANAGER_PROTOTYPE GBUFFER_MANAGER_PROTOTYPE;
513
514//! Buffer manager
515struct GBUFFER_MANAGER_DATA
516{
517 GDYNAMIC_ARRAY m_buffer_array;//!< Array of GBUFFER_DATA objects
518 GDYNAMIC_ARRAY m_free_positions;//!< Array of GUINT elements. Free positions
519 GBUFFER_MANAGER_PROTOTYPE m_prototype;//! Prototype of functions
520 GUINT m_active; //!< 0 or 1
521};
522//typedef struct _GBUFFER_MANAGER_DATA GBUFFER_MANAGER_DATA;
523
524//! Adds a buffer Manager to the Memory Singleton
525void gim_create_buffer_manager(GBUFFER_MANAGER_PROTOTYPE * prototype,GUINT buffer_manager_id);
526//! Gets buffer manager
527GUINT gim_get_buffer_manager_count();
528//! Destroys a buffer manager
529void gim_destroy_buffer_manager(GUINT buffer_manager_id);
530void gim_get_buffer_manager_data(GUINT buffer_manager_id,GBUFFER_MANAGER_DATA ** pbm_data);
531void gim_init_buffer_managers();
532void gim_terminate_buffer_managers();
533
534//! @}
535
536
537/*! \addtogroup BUFFERS
538*/
539//! @{
540
541//!Creates a buffer on the buffer manager specified by buffer_manager_id
542/*!
543\param buffer_manager_id
544\param buffer_size
545\param usage An usage constant. Use G_MU_DYNAMIC_READ_WRITE as default.
546\param buffer_id a pointer for receive the new buffer id
547\return An error code. 0 if success.
548\post m_refcount = 0
549*/
550GUINT gim_create_buffer(
551 GUINT buffer_manager_id,
552 GUINT buffer_size,
553 int usage,
554 GBUFFER_ID * buffer_id);
555
556//!Creates a buffer on the buffer manager specified by buffer_manager_id
557/*!
558\param buffer_manager_id
559\param pdata Data for allocating
560\param buffer_size Size of the data buffer
561\param usage An usage constant. Use G_MU_DYNAMIC_READ_WRITE as default.
562\param buffer_id a pointer for receive the new buffer id
563\return An error code. 0 if success.
564\post m_refcount = 0
565*/
566GUINT gim_create_buffer_from_data(
567 GUINT buffer_manager_id,
568 const void * pdata,
569 GUINT buffer_size,
570 int usage,
571 GBUFFER_ID * buffer_id);
572
573//!Allocates on the G_BUFFER_MANAGER_SYSTEM
574GUINT gim_create_common_buffer(GUINT buffer_size, GBUFFER_ID * buffer_id);
575//!Allocates on the G_BUFFER_MANAGER_SYSTEM, and copies the data
576GUINT gim_create_common_buffer_from_data(
577 const void * pdata, GUINT buffer_size, GBUFFER_ID * buffer_id);
578//!Creates a buffer with shared data
579GUINT gim_create_shared_buffer_from_data(
580 const void * pdata, GUINT buffer_size, GBUFFER_ID * buffer_id);
581
582
583//! Add reference counting to buffer.
584GINT gim_buffer_add_ref(GBUFFER_ID * buffer_id);
585
586//! Function for resize buffer, preserving the content
587/*!
588\param buffer_id
589\param newsize
590\return An error code. 0 if success.
591\post If m_refcount>0 then it decrements it.
592*/
593GINT gim_buffer_realloc(GBUFFER_ID * buffer_id,GUINT newsize);
594
595//! Eliminates the buffer.
596/*!
597If the buffer reference counting is <= 1 and is unlocked, then it eliminates the buffer.
598*/
599GINT gim_buffer_free(GBUFFER_ID * buffer_id);
600
601//! Locks the buffer for memory access.
602/*!
603\param buffer_id Id from buffer.
604\param access Must have the following values: G_MA_READ_ONLY,G_MA_WRITE_ONLY or G_MA_READ_WRITE.
605\param map_pointer Dest Pointer of the memory address from buffer.
606\post m_lock_count increases.
607*/
608GINT gim_lock_buffer(GBUFFER_ID * buffer_id,int access,char ** map_pointer);
609
610//! Unlocks the buffer for memory access.
611GINT gim_unlock_buffer(GBUFFER_ID * buffer_id);
612
613//! Gets the buffer size in bytes
614GINT gim_get_buffer_size(GBUFFER_ID * buffer_id,GUINT * buffer_size);
615
616//! Determines if the buffer is locked
617GINT gim_get_buffer_is_locked(GBUFFER_ID * buffer_id,GUINT * lock_count);
618
619//! Copies the content of the buffer to a dest pointer
620GINT gim_download_from_buffer(
621 GBUFFER_ID * buffer_id,
622 GUINT source_pos,
623 void * destdata,
624 GUINT copysize);
625
626//! Copies the content of a memory pointer to the buffer
627GINT gim_upload_to_buffer(
628 GBUFFER_ID * buffer_id,
629 GUINT dest_pos,
630 void * sourcedata,
631 GUINT copysize);
632
633//! Copies two buffers.
634GINT gim_copy_buffers(
635 GBUFFER_ID * source_buffer_id,
636 GUINT source_pos,
637 GBUFFER_ID * dest_buffer_id,
638 GUINT dest_pos,
639 GUINT copysize);
640//! @}
641
642
643/*! \defgroup BUFFER_ARRAYS
644
645\brief
646Buffered Arrays, for manip elements on a buffer and treat it as an array.
647<ul>
648<li> Before using buffer arrays you must initializes GIMPACT buffer managers by calling gimpact_init.
649<li> Before creating buffer arrays, you must create a buffer. see \ref BUFFERS.
650<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.
651<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.
652<li> When a buffer array is no longer needed, you must free it by calling \ref GIM_BUFFER_ARRAY_DESTROY.
653</ul>
654The following example shows how Buffer arrays can be used:
655
656\code
657int main()
658{
659 //init gimpact
660 gimpact_init();
661
662 //Buffer handle to use
663 GBUFFER_ID bufferhandle;
664
665 //Create a memory buffer of 100 float numbers
666 gim_create_common_buffer(100*sizeof(float), &bufferhandle);
667
668 //Create a buffer array from the bufferhandle
669 GBUFFER_ARRAY buffer_float_array;
670 GIM_BUFFER_ARRAY_INIT_TYPE(float,buffer_float_array,bufferhandle,100);
671
672 ////Access to the buffer data, set all elements of the array
673
674 int i, count;
675 count = buffer_float_array.m_element_count;
676 //Locks the array
677 gim_buffer_array_lock(&buffer_float_array,G_MA_READ_WRITE);
678 float * pelements = GIM_BUFFER_ARRAY_POINTER(float, buffer_float_array, 0); // A pointer to the buffer memory
679
680 //fill the array with random numbers
681 for (i = 0;i < count;i++ )
682 {
683 pelements[i] = gim_unit_random();
684 }
685 //unlock buffer
686 gim_buffer_array_unlock(&buffer_float_array);
687
688 //Program code
689 ....
690 ....
691
692 //Destroy array
693 GIM_BUFFER_ARRAY_DESTROY(buffer_float_array);
694
695 //terminate gimpact
696 gimpact_terminate();
697}
698\endcode
699
700\sa BUFFERS
701*/
702//! @{
703
704//! Buffer managed array struct.
705struct GBUFFER_ARRAY
706{
707 GBUFFER_ID m_buffer_id;
708 char * m_buffer_data;
709 char m_byte_stride;
710 GUINT m_byte_offset;
711 GUINT m_element_count;
712};
713//typedef struct _GBUFFER_ARRAY GBUFFER_ARRAY;
714
715//! Sets offset for a buffered array.
716#define GIM_BUFFER_ARRAY_SET_OFFSET(_array_data,_offset) (_array_data).m_byte_offset = _offset*(_array_data).m_byte_stride;
717
718//! Sets offset for a buffered array.
719#define GIM_BUFFER_ARRAY_GET_OFFSET(_array_data,_offset) _offset = (_array_data).m_byte_offset/(_array_data).m_byte_stride;
720
721//!Return a pointer of the element at the _index
722#define GIM_BUFFER_ARRAY_POINTER(_type,_array_data,_index) (_type *)((_array_data).m_buffer_data + _index*(_array_data).m_byte_stride)
723
724//! Sets stride for a buffered array.
725#define GIM_BUFFER_ARRAY_SET_STRIDE(_type,_array_data) (_array_data).m_byte_stride = sizeof(_type);
726
727//! Is array stride equal to the size of the type ?
728#define GIM_BUFFER_ARRAY_IS_ALIGNED(_type,_array_data) ((_array_data).m_byte_stride == sizeof(_type))
729
730///Verify if two arrays have the same data
731#define GIM_BUFFER_ARRAY_ARE_SAME(_array_data1,_array_data2,aresame)\
732{\
733 aresame = 1;\
734 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)\
735 {\
736 aresame = 0;\
737 }\
738}\
739
740//! Reserve size for a buffered array.
741/*!
742\pre array_data must be unlocked, and must be the aligned (GIM_BUFFER_ARRAY_IS_ALIGNED )
743*/
744#define GIM_BUFFER_ARRAY_RESERVE_SIZE(type,array_data,reserve_size)\
745{ \
746 if(reserve_size>(array_data).m_element_count)\
747 {\
748 GUINT _buffer_size,_newarray_size;\
749 gim_get_buffer_size(&(array_data).m_buffer_id,_buffer_size);\
750 _newarray_size = reserve_size*(array_data).m_byte_stride;\
751 if(_newarray_size>_buffer_size)\
752 { \
753 _newarray_size += G_ARRAY_GROW_SIZE*(array_data).m_byte_stride;\
754 gim_buffer_realloc(&(array_data).m_buffer_id,_newarray_size);\
755 }\
756 }\
757}\
758
759//! Pushes an element at last position
760/*!
761\pre array_data must be unlocked, and must be the aligned (GIM_BUFFER_ARRAY_IS_ALIGNED )
762*/
763#define GIM_BUFFER_ARRAY_PUSH_ITEM(type,array_data,item)\
764{\
765 GIM_BUFFER_ARRAY_RESERVE_SIZE(type,array_data,(array_data).m_element_count+1);\
766 gim_buffer_array_lock(&array_data,G_MA_WRITE_ONLY);\
767 type * _pt = GIM_BUFFER_ARRAY_POINTER(type,array_data,(array_data).m_element_count);\
768 memcpy(_pt,&item,sizeof(type));\
769 gim_buffer_array_unlock(&array_data);\
770 (array_data)->m_element_count++; \
771}\
772
773//! Pushes a new element at last position
774/*!
775\pre array_data must be unlocked, and must be the aligned (GIM_BUFFER_ARRAY_IS_ALIGNED )
776*/
777#define GIM_BUFFER_ARRAY_PUSH_EMPTY(type,array_data)\
778{\
779 GIM_BUFFER_ARRAY_RESERVE_SIZE(type,array_data,(array_data).m_element_count+1);\
780 array_data->m_element_count++; \
781}\
782
783//! Inserts an element
784/*!
785\pre array_data must be unlocked, and must be the aligned (GIM_BUFFER_ARRAY_IS_ALIGNED )
786*/
787#define GIM_BUFFER_ARRAY_INSERT_ITEM(type,array_data,item,index) \
788{ \
789 GIM_BUFFER_ARRAY_RESERVE_SIZE(type,array_data,(array_data).m_element_count+1);\
790 gim_buffer_array_lock(&array_data,G_MA_WRITE_ONLY);\
791 type * _pt = GIM_BUFFER_ARRAY_POINTER(type,array_data,0);\
792 if(index<(array_data)->m_element_count-1) \
793 { \
794 memcpy(&_pt[index+1],&_pt[index],((array_data).m_element_count-index)*sizeof(type));\
795 } \
796 memcpy(&_pt[index],&item,sizeof(type));\
797 gim_buffer_array_unlock(&array_data);\
798 (array_data).m_element_count++; \
799}\
800
801//! Deletes an element
802/*!
803\pre array_data must be unlocked, and must be the aligned (GIM_BUFFER_ARRAY_IS_ALIGNED )
804*/
805#define GIM_BUFFER_ARRAY_DELETE_ITEM(type,array_data,index) \
806{ \
807 if(index<(array_data).m_element_count-1) \
808 { \
809 gim_buffer_array_lock(&array_data,G_MA_WRITE_ONLY);\
810 type * _pt = GIM_BUFFER_ARRAY_POINTER(type,array_data,0);\
811 memcpy(&_pt[index],&_pt[index+1],((array_data).m_element_count-index-1)*sizeof(type));\
812 gim_buffer_array_unlock(&array_data);\
813 } \
814 (array_data).m_element_count--; \
815}\
816
817//! Deletes an element at last position
818/*!
819\pre array_data must be unlocked, and must be the aligned (GIM_BUFFER_ARRAY_IS_ALIGNED )
820*/
821#define GIM_BUFFER_ARRAY_POP_ITEM(array_data) \
822{ \
823 if((array_data).m_element_count>0) \
824 { \
825 (array_data).m_element_count--; \
826 } \
827}\
828
829
830//! Initializes an GBUFFER_ARRAY object from a buffer ID
831/*!
832m_buffer_data will be 0, for acces to the elements, you'd need to call lock_array
833\param array_data Array structure to be filled
834\param buffer_id A GBUFFER_ID structure which this array_daya will refer to
835\param element_count Number of elements
836\param offset element offset, it isn't byte offset. 0 is recomended
837\param byte_stride size of each element. 0 is recomended.
838\post Adds reference to the buffer
839\sa gim_buffer_add_ref
840*/
841#define GIM_BUFFER_ARRAY_INIT_OFFSET_STRIDE(array_data,buffer_id,element_count,offset,byte_stride)\
842{\
843 (array_data).m_buffer_id.m_buffer_id = (buffer_id).m_buffer_id;\
844 (array_data).m_buffer_id.m_buffer_manager_id = (buffer_id).m_buffer_manager_id;\
845 (array_data).m_buffer_data = 0;\
846 (array_data).m_element_count = element_count;\
847 (array_data).m_byte_stride = byte_stride;\
848 GIM_BUFFER_ARRAY_SET_OFFSET(array_data,offset);\
849 gim_buffer_add_ref(&(buffer_id));\
850}\
851
852//! Initializes an GBUFFER_ARRAY object from a buffer ID and a Given type
853/*!
854m_buffer_data will be 0, for acces to the elements, you'd need to call lock_array
855\param type Type of the Array. It determines the stride.
856\param array_data Array structure to be filled
857\param buffer_id A GBUFFER_ID structure which this array_daya will refer to
858\param element_count Number of elements
859\param offset element offset, it isn't byte offset. 0 is recomended
860\post Adds reference to the buffer
861\sa gim_buffer_add_ref
862*/
863#define GIM_BUFFER_ARRAY_INIT_TYPE_OFFSET(type,array_data,buffer_id,element_count,offset)\
864{\
865 (array_data).m_buffer_id.m_buffer_id = (buffer_id).m_buffer_id;\
866 (array_data).m_buffer_id.m_buffer_manager_id = (buffer_id).m_buffer_manager_id;\
867 (array_data).m_buffer_data = 0;\
868 (array_data).m_element_count = element_count;\
869 GIM_BUFFER_ARRAY_SET_STRIDE(type,array_data);\
870 GIM_BUFFER_ARRAY_SET_OFFSET(array_data,offset);\
871 gim_buffer_add_ref(&(buffer_id));\
872}\
873
874//! Initializes a buffer array giving a data type and a buffer id
875/*!
876m_buffer_data will be 0, for acces to the elements, you'd need to call lock_array.
877\param type Type of the Array. It determines the stride.
878\param array_data Array structure to be filled
879\param buffer_id A GBUFFER_ID structure which this array_daya will refer to
880\param element_count Number of elements
881\post Adds reference to the buffer
882\sa gim_buffer_add_ref
883*/
884#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)
885
886//! Gain access to the array buffer through the m_buffer_data element
887/*!
888m_buffer_data pointer will be located at the m_byte_offset position of the buffer m_buffer
889Then, You'd need to call unlock_array when finish to using the array access.
890
891\pre if m_buffer_data != 0, the function returns
892\param array_data Array structure to be locked
893\param access A constant for access to the buffer. can be G_MA_READ_ONLY,G_MA_WRITE_ONLY or G_MA_READ_WRITE
894\return an Buffer error code
895*/
896GINT gim_buffer_array_lock(GBUFFER_ARRAY * array_data, int access);
897
898//! close the access to the array buffer through the m_buffer_data element
899/*!
900\param array_data Array structure to be locked
901\return an Buffer error code
902*/
903GINT gim_buffer_array_unlock(GBUFFER_ARRAY * array_data);
904
905//! Copy an array by reference
906/*!
907\post A reference to the m_buffer_id is increased.
908*/
909void gim_buffer_array_copy_ref(GBUFFER_ARRAY * source_data,GBUFFER_ARRAY * dest_data);
910
911
912//! Copy an array by value
913/*!
914\post A new buffer is created
915*/
916void gim_buffer_array_copy_value(GBUFFER_ARRAY * source_data,GBUFFER_ARRAY * dest_data, GUINT buffer_manager_id,int usage);
917
918//! Destroys an GBUFFER_ARRAY object
919/*!
920\post Attemps to destroy the buffer, decreases reference counting
921*/
922void GIM_BUFFER_ARRAY_DESTROY(GBUFFER_ARRAY & array_data);
923
924//! Copy the content of the array to a pointer
925/*!
926\pre dest_data must have the same size as the array_data
927\param type
928\param array_data A GBUFFERED_ARRAY structure
929\param dest_data A type pointer
930*/
931#define GIM_BUFFER_ARRAY_DOWNLOAD(type,array_data,dest_data)\
932{\
933 if(GIM_BUFFER_ARRAY_IS_ALIGNED(type,array_data))\
934 {\
935 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);\
936 }\
937 else\
938 {\
939 GUINT _k_, _ecount_= (array_data).m_element_count;\
940 type * _source_vert_;\
941 type * _dest_vert_ = dest_data;\
942 gim_buffer_array_lock(&(array_data),G_MA_READ_ONLY);\
943 for (_k_ = 0;_k_< _ecount_; _k_++)\
944 {\
945 _source_vert_ = GIM_BUFFER_ARRAY_POINTER(type,array_data,_k_);\
946 memcpy(_dest_vert_,_source_vert_,sizeof(type));\
947 _dest_vert_++;\
948 }\
949 gim_buffer_array_unlock(&(array_data));\
950 }\
951}\
952
953//! Upload the content of a a pointer to a buffered array
954/*!
955\pre source_data must have the same size as the array_data
956\param type
957\param array_data A GBUFFERED_ARRAY structure
958\param source_data A void pointer
959*/
960#define GIM_BUFFER_ARRAY_UPLOAD(type,array_data,source_data)\
961{\
962 if(GIM_BUFFER_ARRAY_IS_ALIGNED(type,array_data))\
963 {\
964 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);\
965 }\
966 else\
967 {\
968 GUINT _k_, _ecount_= (array_data).m_element_count;\
969 type * _source_vert_ = source_data;\
970 type * _dest_vert_;\
971 gim_buffer_array_lock(&(array_data),G_MA_WRITE_ONLY);\
972 for (_k_ = 0;_k_< _ecount_; _k_++)\
973 {\
974 _dest_vert_ = GIM_BUFFER_ARRAY_POINTER(type,array_data,_k_);\
975 memcpy(_dest_vert_,_source_vert_,sizeof(type));\
976 _source_vert_++;\
977 }\
978 gim_buffer_array_unlock(&(array_data));\
979 }\
980}\
981
982
983//!Kernel function prototype for process streams, given a buffered array as source and
984/*!
985\param 1 the uniform arguments
986\param 2 the source stream
987\param 3 the destination stream
988*/
989typedef void (* gim_kernel_func)(void *,GBUFFER_ARRAY *,GBUFFER_ARRAY *);
990
991//! Generic Stream Processingp loop
992/*!
993
994This macro executes a kernel macro or function for each element of the streams
995\pre _src_array->m_count <= _dst_array->m_count
996
997\param _uniform_data An argument to be passed to the Kernel function
998\param _src_array An GBUFFER_ARRAY structure passed as the source stream
999\param _dst_array An GBUFFER_ARRAY structure passed as the source stream
1000\param _kernel Macro or function of the kernel
1001\param _src_type Required. Type of all elements of the source stream
1002\param _dst_type Required. Type of all elements of the dest stream
1003*/
1004#define GIM_PROCESS_BUFFER_ARRAY(_uniform_data,_src_array,_dst_array,_kernel,_src_type,_dst_type) {\
1005\
1006 gim_buffer_array_lock(&_src_array,G_MA_READ_ONLY);\
1007 gim_buffer_array_lock(&_dst_array,G_MA_WRITE_ONLY);\
1008\
1009 GUINT _i_, _count_=(_src_array).m_element_count;\
1010\
1011 _src_type * _source_vert_;\
1012 _dst_type * _dest_vert_;\
1013 if(GIM_BUFFER_ARRAY_IS_ALIGNED(_src_type,_src_array) && GIM_BUFFER_ARRAY_IS_ALIGNED(_dst_type,_dst_array))\
1014 {\
1015\
1016 _source_vert_ = GIM_BUFFER_ARRAY_POINTER(_src_type,_src_array,0);\
1017 _dest_vert_ = GIM_BUFFER_ARRAY_POINTER(_dst_type,_dst_array,0);\
1018 for (_i_ = 0;_i_< _count_; _i_++)\
1019 {\
1020 _kernel(_uniform_data,(*_source_vert_),(*_dest_vert_));\
1021 _source_vert_++;\
1022 _dest_vert_++;\
1023 }\
1024 }\
1025 else\
1026 {\
1027 for (_i_ = 0;_i_< _count_; _i_++)\
1028 {\
1029 _source_vert_ = GIM_BUFFER_ARRAY_POINTER(_src_type,_src_array,_i_);\
1030 _dest_vert_ = GIM_BUFFER_ARRAY_POINTER(_dst_type,_dst_array,_i_);\
1031 _kernel(_uniform_data,(*_source_vert_),(*_dest_vert_));\
1032 }\
1033 }\
1034 gim_buffer_array_unlock(&_src_array);\
1035 gim_buffer_array_unlock(&_dst_array);\
1036}\
1037
1038//! @}
1039
1040#endif // GIM_MEMORY_H_INCLUDED
diff --git a/libraries/ode-0.9/GIMPACT/include/GIMPACT/gim_radixsort.h b/libraries/ode-0.9/GIMPACT/include/GIMPACT/gim_radixsort.h
new file mode 100644
index 0000000..a5f8e12
--- /dev/null
+++ b/libraries/ode-0.9/GIMPACT/include/GIMPACT/gim_radixsort.h
@@ -0,0 +1,258 @@
1#ifndef GIM_RADIXSORT_H_INCLUDED
2#define GIM_RADIXSORT_H_INCLUDED
3/*! \file gim_radixsort.h
4\author Francisco León.
5Based on the work of Michael Herf : "fast floating-point radix sort"
6Avaliable on http://www.stereopsis.com/radix.html
7*/
8/*
9-----------------------------------------------------------------------------
10This source file is part of GIMPACT Library.
11
12For the latest info, see http://gimpact.sourceforge.net/
13
14Copyright (c) 2006 Francisco Leon. C.C. 80087371.
15email: projectileman@yahoo.com
16
17 This library is free software; you can redistribute it and/or
18 modify it under the terms of EITHER:
19 (1) The GNU Lesser General Public License as published by the Free
20 Software Foundation; either version 2.1 of the License, or (at
21 your option) any later version. The text of the GNU Lesser
22 General Public License is included with this library in the
23 file GIMPACT-LICENSE-LGPL.TXT.
24 (2) The BSD-style license that is included with this library in
25 the file GIMPACT-LICENSE-BSD.TXT.
26
27 This library is distributed in the hope that it will be useful,
28 but WITHOUT ANY WARRANTY; without even the implied warranty of
29 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files
30 GIMPACT-LICENSE-LGPL.TXT and GIMPACT-LICENSE-BSD.TXT for more details.
31
32-----------------------------------------------------------------------------
33*/
34
35#include "GIMPACT/gim_memory.h"
36
37/*! \defgroup SORTING
38\brief
39Macros for sorting.
40*/
41//! @{
42struct GIM_RSORT_TOKEN
43{
44 GUINT m_key;
45 GUINT m_value;
46};
47//typedef struct _GIM_RSORT_TOKEN GIM_RSORT_TOKEN;
48
49//comparator for sorting
50#define RSORT_TOKEN_COMPARATOR(x, y) ((int)((x.m_key) - (y.m_key)))
51
52// ---- utils for accessing 11-bit quantities
53#define D11_0(x) (x & 0x7FF)
54#define D11_1(x) (x >> 11 & 0x7FF)
55#define D11_2(x) (x >> 22 )
56
57
58//COMMON FUNCTIONS FOR ACCESSING THE KEY OF AN ELEMENT
59
60
61//For the type of your array, you need to declare a macro for obtaining the key, like these:
62#define SIMPLE_GET_FLOAT32KEY(e,key) {key =(GREAL)(e);}
63
64#define SIMPLE_GET_INTKEY(e,key) {key =(GINT)(e);}
65
66#define SIMPLE_GET_UINTKEY(e,key) {key =(GUINT)(e);}
67
68//For the type of your array, you need to declare a macro for copy elements, like this:
69
70#define SIMPLE_COPY_ELEMENTS(dest,src) {dest = src;}
71
72#define kHist 2048
73
74///Radix sort for unsigned integer keys
75
76#define GIM_RADIX_SORT_RTOKENS(array,sorted,element_count)\
77{\
78 GUINT i;\
79 GUINT b0[kHist * 3];\
80 GUINT *b1 = b0 + kHist;\
81 GUINT *b2 = b1 + kHist;\
82 for (i = 0; i < kHist * 3; i++)\
83 {\
84 b0[i] = 0;\
85 }\
86 GUINT fi;\
87 GUINT pos;\
88 for (i = 0; i < element_count; i++)\
89 {\
90 fi = array[i].m_key;\
91 b0[D11_0(fi)] ++;\
92 b1[D11_1(fi)] ++;\
93 b2[D11_2(fi)] ++;\
94 }\
95 {\
96 GUINT sum0 = 0, sum1 = 0, sum2 = 0;\
97 GUINT tsum;\
98 for (i = 0; i < kHist; i++)\
99 {\
100 tsum = b0[i] + sum0;\
101 b0[i] = sum0 - 1;\
102 sum0 = tsum;\
103 tsum = b1[i] + sum1;\
104 b1[i] = sum1 - 1;\
105 sum1 = tsum;\
106 tsum = b2[i] + sum2;\
107 b2[i] = sum2 - 1;\
108 sum2 = tsum;\
109 }\
110 }\
111 for (i = 0; i < element_count; i++)\
112 {\
113 fi = array[i].m_key;\
114 pos = D11_0(fi);\
115 pos = ++b0[pos];\
116 sorted[pos].m_key = array[i].m_key;\
117 sorted[pos].m_value = array[i].m_value;\
118 }\
119 for (i = 0; i < element_count; i++)\
120 {\
121 fi = sorted[i].m_key;\
122 pos = D11_1(fi);\
123 pos = ++b1[pos];\
124 array[pos].m_key = sorted[i].m_key;\
125 array[pos].m_value = sorted[i].m_value;\
126 }\
127 for (i = 0; i < element_count; i++)\
128 {\
129 fi = array[i].m_key;\
130 pos = D11_2(fi);\
131 pos = ++b2[pos];\
132 sorted[pos].m_key = array[i].m_key;\
133 sorted[pos].m_value = array[i].m_value;\
134 }\
135}\
136
137/// Get the sorted tokens from an array. For generic use. Tokens are GIM_RSORT_TOKEN
138#define GIM_RADIX_SORT_ARRAY_TOKENS(array, sorted_tokens, element_count, get_uintkey_macro)\
139{\
140 GIM_RSORT_TOKEN * _unsorted = (GIM_RSORT_TOKEN *) gim_alloc(sizeof(GIM_RSORT_TOKEN )*element_count);\
141 GUINT _i;\
142 for (_i=0;_i<element_count;_i++)\
143 {\
144 get_uintkey_macro(array[_i],_unsorted[_i].m_key);\
145 _unsorted[_i].m_value = _i;\
146 }\
147 GIM_RADIX_SORT_RTOKENS(_unsorted,sorted_tokens,element_count);\
148 gim_free(_unsorted,sizeof(GIM_RSORT_TOKEN )*element_count);\
149}\
150
151/// Sorts array in place. For generic use
152#define GIM_RADIX_SORT(type,array,element_count,get_uintkey_macro,copy_elements_macro)\
153{\
154 GIM_RSORT_TOKEN * _sorted = (GIM_RSORT_TOKEN *) gim_alloc(sizeof(GIM_RSORT_TOKEN )*element_count);\
155 GIM_RADIX_SORT_ARRAY_TOKENS(array,_sorted,element_count,get_uintkey_macro);\
156 type * _original_array = (type *) gim_alloc(sizeof(type)*element_count); \
157 memcpy(_original_array,array,sizeof(type)*element_count);\
158 GUINT _i;\
159 for (_i=0;_i<element_count;_i++)\
160 {\
161 copy_elements_macro(array[_i],_original_array[_sorted[_i].m_value]);\
162 }\
163 gim_free(_original_array,sizeof(type)*element_count);\
164 gim_free(_sorted,sizeof(GIM_RSORT_TOKEN )*element_count);\
165}\
166
167/// Sorts array in place using quick sort
168#define GIM_QUICK_SORT_ARRAY(type, array, array_count, comp_macro, exchange_macro) \
169{\
170 GINT _i_, _j_, _p_, _stack_index_, _start_, _end_;\
171 GINT _start_stack_[64]; \
172 GINT _end_stack_[64];\
173 _start_stack_[0] = 0;\
174 _end_stack_[0] = (array_count);\
175 _stack_index_ = 1;\
176 while (_stack_index_ > 0)\
177 {\
178 _stack_index_ --;\
179 _start_ = _start_stack_[_stack_index_];\
180 _end_ = _end_stack_[_stack_index_];\
181 while (_end_ - _start_ > 2)\
182 {\
183 _p_ = _start_;\
184 _i_ = _start_ + 1;\
185 _j_ = _end_ - 1;\
186 while (_i_<_j_) \
187 {\
188 for(; _i_<=_j_ && comp_macro(((array)[_i_]),((array)[_p_]))<=0; _i_++) ;\
189 if (_i_ > _j_) \
190 {\
191 exchange_macro(type, array, _j_, _p_);\
192 _i_ = _j_;\
193 }\
194 else\
195 {\
196 for(; _i_<=_j_ && comp_macro(((array)[_j_]),((array)[_p_]))>=0; _j_--) ;\
197 if (_i_ > _j_) \
198 {\
199 exchange_macro(type, array, _j_, _p_);\
200 _i_ = _j_;\
201 }\
202 else if (_i_ < _j_)\
203 {\
204 exchange_macro(type, array, _i_, _j_);\
205 if (_i_+2 < _j_) {_i_++; _j_--;}\
206 else if (_i_+1 < _j_) _i_++;\
207 }\
208 }\
209 }\
210 if (_i_-_start_ > 1 && _end_-_j_ > 1) \
211 {\
212 if (_i_-_start_ < _end_-_j_-1) \
213 {\
214 _start_stack_[_stack_index_] = _j_+1;\
215 _end_stack_[_stack_index_] = _end_;\
216 _stack_index_ ++;\
217 _end_ = _i_;\
218 }\
219 else\
220 {\
221 _start_stack_[_stack_index_] = _start_;\
222 _end_stack_[_stack_index_] = _i_;\
223 _stack_index_ ++;\
224 _start_ = _j_+1;\
225 }\
226 }\
227 else\
228 {\
229 if (_i_-_start_ > 1)\
230 {\
231 _end_ = _i_;\
232 }\
233 else \
234 {\
235 _start_ = _j_+1;\
236 }\
237 }\
238 }\
239 if (_end_ - _start_ == 2) \
240 {\
241 if (comp_macro(((array)[_start_]),((array)[_end_-1])) > 0) \
242 {\
243 exchange_macro(type, array, _start_, _end_-1);\
244 }\
245 }\
246 }\
247}\
248
249#define GIM_DEF_EXCHANGE_MACRO(type, _array, _i, _j)\
250{\
251 type _e_tmp_ =(_array)[(_i)];\
252 (_array)[(_i)]=(_array)[(_j)];\
253 (_array)[(_j)]= _e_tmp_;\
254}\
255
256#define GIM_COMP_MACRO(x, y) ((GINT)((x) - (y)))
257//! @}
258#endif // GIM_RADIXSORT_H_INCLUDED
diff --git a/libraries/ode-0.9/GIMPACT/include/GIMPACT/gim_tri_capsule_collision.h b/libraries/ode-0.9/GIMPACT/include/GIMPACT/gim_tri_capsule_collision.h
new file mode 100644
index 0000000..2b31604
--- /dev/null
+++ b/libraries/ode-0.9/GIMPACT/include/GIMPACT/gim_tri_capsule_collision.h
@@ -0,0 +1,111 @@
1#ifndef GIM_TRI_CAPSULE_COLLISION_H_INCLUDED
2#define GIM_TRI_CAPSULE_COLLISION_H_INCLUDED
3
4/*! \file gim_tri_capsule_collision.h
5\author Francisco León
6*/
7/*
8-----------------------------------------------------------------------------
9This source file is part of GIMPACT Library.
10
11For the latest info, see http://gimpact.sourceforge.net/
12
13Copyright (c) 2006 Francisco Leon. C.C. 80087371.
14email: projectileman@yahoo.com
15
16 This library is free software; you can redistribute it and/or
17 modify it under the terms of EITHER:
18 (1) The GNU Lesser General Public License as published by the Free
19 Software Foundation; either version 2.1 of the License, or (at
20 your option) any later version. The text of the GNU Lesser
21 General Public License is included with this library in the
22 file GIMPACT-LICENSE-LGPL.TXT.
23 (2) The BSD-style license that is included with this library in
24 the file GIMPACT-LICENSE-BSD.TXT.
25
26 This library is distributed in the hope that it will be useful,
27 but WITHOUT ANY WARRANTY; without even the implied warranty of
28 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files
29 GIMPACT-LICENSE-LGPL.TXT and GIMPACT-LICENSE-BSD.TXT for more details.
30
31-----------------------------------------------------------------------------
32*/
33
34#include "GIMPACT/gim_memory.h"
35
36/*! \addtogroup GEOMETRIC_OPERATIONS
37*/
38//! @{
39
40//! Capsule struct
41struct GIM_CAPSULE_DATA
42{
43 GREAL m_radius;
44 vec3f m_point1;
45 vec3f m_point2;
46};
47//typedef struct _GIM_CAPSULE_DATA GIM_CAPSULE_DATA;
48
49#define CALC_CAPSULE_AABB(capsule,aabb)\
50{\
51 if(capsule.m_point1[0]<capsule.m_point2[0])\
52 {\
53 aabb.minX = capsule.m_point1[0] - capsule.m_radius;\
54 aabb.maxX = capsule.m_point2[0] + capsule.m_radius;\
55 }\
56 else\
57 {\
58 aabb.minX = capsule.m_point2[0] - capsule.m_radius;\
59 aabb.maxX = capsule.m_point1[0] + capsule.m_radius;\
60 }\
61 if(capsule.m_point1[1]<capsule.m_point2[1])\
62 {\
63 aabb.minY = capsule.m_point1[1] - capsule.m_radius;\
64 aabb.maxY = capsule.m_point2[1] + capsule.m_radius;\
65 }\
66 else\
67 {\
68 aabb.minY = capsule.m_point2[1] - capsule.m_radius;\
69 aabb.maxY = capsule.m_point1[1] + capsule.m_radius;\
70 }\
71 if(capsule.m_point1[2]<capsule.m_point2[2])\
72 {\
73 aabb.minZ = capsule.m_point1[2] - capsule.m_radius;\
74 aabb.maxZ = capsule.m_point2[2] + capsule.m_radius;\
75 }\
76 else\
77 {\
78 aabb.minZ = capsule.m_point2[2] - capsule.m_radius;\
79 aabb.maxZ = capsule.m_point1[2] + capsule.m_radius;\
80 }\
81}\
82
83//! Utility function for find the closest point between a segment and a triangle
84/*!
85
86\param triangle
87\param s1
88\param s2
89\param contacts Contains the closest points on the segment (1,2), and the normal points to segment, and m_depth contains the distance
90
91\post The contacts array is not set to 0. It adds aditional contacts
92*/
93void gim_closest_point_triangle_segment(GIM_TRIANGLE_DATA * triangle, vec3f s1,vec3f s2, GDYNAMIC_ARRAY * contacts);
94
95
96
97
98
99//! Utility function for find the closest point between a capsule and a triangle
100/*!
101
102\param triangle
103\param capsule
104\param contacts Contains the closest points on the capsule, and the normal points to triangle
105\return 1 if the triangle collides the capsule
106\post The contacts array is not set to 0. It adds aditional contacts
107*/
108int gim_triangle_capsule_collision(GIM_TRIANGLE_DATA * triangle, GIM_CAPSULE_DATA * capsule, GDYNAMIC_ARRAY * contacts);
109//! @}
110
111#endif // GIM_TRI_CAPSULE_COLLISION_H_INCLUDED
diff --git a/libraries/ode-0.9/GIMPACT/include/GIMPACT/gim_tri_collision.h b/libraries/ode-0.9/GIMPACT/include/GIMPACT/gim_tri_collision.h
new file mode 100644
index 0000000..80b34eb
--- /dev/null
+++ b/libraries/ode-0.9/GIMPACT/include/GIMPACT/gim_tri_collision.h
@@ -0,0 +1,253 @@
1#ifndef GIM_TRI_COLLISION_H_INCLUDED
2#define GIM_TRI_COLLISION_H_INCLUDED
3
4/*! \file gim_tri_collision.h
5\author Francisco León Nájera
6*/
7/*
8-----------------------------------------------------------------------------
9This source file is part of GIMPACT Library.
10
11For the latest info, see http://gimpact.sourceforge.net/
12
13Copyright (c) 2006 Francisco Leon Najera. C.C. 80087371.
14email: projectileman@yahoo.com
15
16 This library is free software; you can redistribute it and/or
17 modify it under the terms of EITHER:
18 (1) The GNU Lesser General Public License as published by the Free
19 Software Foundation; either version 2.1 of the License, or (at
20 your option) any later version. The text of the GNU Lesser
21 General Public License is included with this library in the
22 file GIMPACT-LICENSE-LGPL.TXT.
23 (2) The BSD-style license that is included with this library in
24 the file GIMPACT-LICENSE-BSD.TXT.
25
26 This library is distributed in the hope that it will be useful,
27 but WITHOUT ANY WARRANTY; without even the implied warranty of
28 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files
29 GIMPACT-LICENSE-LGPL.TXT and GIMPACT-LICENSE-BSD.TXT for more details.
30
31-----------------------------------------------------------------------------
32*/
33
34/*! \addtogroup GEOMETRIC_OPERATIONS
35*/
36//! @{
37
38
39#define MAX_TRI_CLIPPING 8
40
41//! Clips a polygon by a plane
42#define PLANE_CLIP_POLYGON(plane,polygon_points,polygon_point_count,clipped,clipped_count,max_clipped) \
43{ \
44 clipped_count = 0; \
45 GUINT _i, _vi, _prevclassif=32000, _classif; \
46 GREAL _d; \
47 for(_i=0;_i<=polygon_point_count;_i++) \
48 { \
49 _vi = _i%polygon_point_count; \
50 _d = DISTANCE_PLANE_POINT(plane,polygon_points[_vi]); \
51 _classif = _d>G_EPSILON ?1:0; \
52 if(_classif == 0) \
53 { \
54 if(_prevclassif==1) \
55 {\
56 if(clipped_count<max_clipped) \
57 {\
58 PLANE_CLIP_SEGMENT(polygon_points[_i-1],polygon_points[_vi],plane,clipped[clipped_count]); \
59 clipped_count++; \
60 } \
61 } \
62 if(clipped_count<max_clipped&&_i<polygon_point_count) \
63 { \
64 VEC_COPY(clipped[clipped_count],polygon_points[_vi]); \
65 clipped_count++; \
66 } \
67 } \
68 else \
69 { \
70 if(_prevclassif==0) \
71 { \
72 if(clipped_count<max_clipped) \
73 { \
74 PLANE_CLIP_SEGMENT(polygon_points[_i-1],polygon_points[_vi],plane,clipped[clipped_count]); \
75 clipped_count++; \
76 } \
77 } \
78 } \
79 _prevclassif = _classif; \
80 } \
81}\
82
83
84struct GIM_TRIPLANES_CACHE
85{
86 /*!
87 Planes are:
88 0 : Face normal plane (0,3)
89 1 : Edge 1 plane (4,7)
90 2 : Edge 2 plane (8,11)
91 3 : Edge 3 plane (12,15)
92 */
93 vec4f m_planes[4];
94};
95//typedef struct _GIM_TRIPLANES_CACHE GIM_TRIPLANES_CACHE;
96
97
98struct GIM_TRIANGLE_DATA
99{
100 vec3f m_vertices[3];
101 GIM_TRIPLANES_CACHE m_planes;
102};
103//typedef struct _GIM_TRIANGLE_DATA GIM_TRIANGLE_DATA;
104
105//! tri_data is a GIM_TRIANGLE_DATA
106#define GIM_CALC_TRIANGLE_DATA_PLANES(tri_data)\
107{\
108 TRIANGLE_PLANE((tri_data).m_vertices[0],(tri_data).m_vertices[1],(tri_data).m_vertices[2],(tri_data).m_planes.m_planes[0]);\
109 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]));\
110 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]));\
111 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]));\
112}\
113
114//Structure for collision
115
116struct GIM_TRIANGLE_CONTACT_DATA
117{
118 GREAL m_penetration_depth;
119 GUINT m_point_count;
120 vec3f m_separating_normal;
121 vec3f m_points[MAX_TRI_CLIPPING];
122};
123//typedef struct _GIM_TRIANGLE_CONTACT_DATA GIM_TRIANGLE_CONTACT_DATA;
124
125struct GIM_TRIANGLE_RAY_CONTACT_DATA
126{
127 GREAL u;
128 GREAL v;
129 GREAL tparam;
130 GUINT m_face_id;
131 vec3f m_point;
132 vec3f m_normal;
133};
134//typedef struct _GIM_TRIANGLE_RAY_CONTACT_DATA GIM_TRIANGLE_RAY_CONTACT_DATA;
135
136//! Fast Triangle Triangle overlapping test
137int gim_triangle_triangle_overlap(
138 GIM_TRIANGLE_DATA *tri1,
139 GIM_TRIANGLE_DATA *tri2);
140
141
142//! Fast but inacurate conservative Triangle Triangle overlapping test
143int gim_triangle_triangle_overlap_fast(
144 GIM_TRIANGLE_DATA *tri1,
145 GIM_TRIANGLE_DATA *tri2);
146
147
148//! Finds the contact points from a collision of two triangles
149/*!
150Returns the contact points, the penetration depth and the separating normal of the collision
151between two triangles. The normal is pointing toward triangle 1 from triangle 2
152*/
153int gim_triangle_triangle_collision(
154 GIM_TRIANGLE_DATA *tri1,
155 GIM_TRIANGLE_DATA *tri2,
156 GIM_TRIANGLE_CONTACT_DATA * contact_data);
157
158//Ray triangle
159
160
161/*!
162 Solve the System for u,v parameters:
163
164 u*axe1[i1] + v*axe2[i1] = vecproj[i1]
165 u*axe1[i2] + v*axe2[i2] = vecproj[i2]
166
167 sustitute:
168 v = (vecproj[i2] - u*axe1[i2])/axe2[i2]
169
170 then the first equation in terms of 'u':
171
172 --> u*axe1[i1] + ((vecproj[i2] - u*axe1[i2])/axe2[i2])*axe2[i1] = vecproj[i1]
173
174 --> u*axe1[i1] + vecproj[i2]*axe2[i1]/axe2[i2] - u*axe1[i2]*axe2[i1]/axe2[i2] = vecproj[i1]
175
176 --> u*(axe1[i1] - axe1[i2]*axe2[i1]/axe2[i2]) = vecproj[i1] - vecproj[i2]*axe2[i1]/axe2[i2]
177
178 --> u*((axe1[i1]*axe2[i2] - axe1[i2]*axe2[i1])/axe2[i2]) = (vecproj[i1]*axe2[i2] - vecproj[i2]*axe2[i1])/axe2[i2]
179
180 --> u*(axe1[i1]*axe2[i2] - axe1[i2]*axe2[i1]) = vecproj[i1]*axe2[i2] - vecproj[i2]*axe2[i1]
181
182 --> u = (vecproj[i1]*axe2[i2] - vecproj[i2]*axe2[i1]) /(axe1[i1]*axe2[i2] - axe1[i2]*axe2[i1])
183
184if 0.0<= u+v <=1.0 then they are inside of triangle
185
186 */
187#define TRIANGLE_GET_UVPARAMETERS(point,vec1,vec2,vec3,tri_plane,u,v,outside)\
188{\
189 vec3f _axe1, _axe2, _vecproj;\
190 VEC_DIFF(_axe1,vec2,vec1);\
191 VEC_DIFF(_axe2,vec3,vec1);\
192 VEC_DIFF(_vecproj,point,vec1);\
193 GUINT _i1,_i2;\
194 PLANE_MINOR_AXES(tri_plane, _i1, _i2);\
195 if(fabsf(_axe2[_i2])<G_EPSILON)\
196 {\
197 u = (_vecproj[_i2]*_axe2[_i1] - _vecproj[_i1]*_axe2[_i2]) /(_axe1[_i2]*_axe2[_i1] - _axe1[_i1]*_axe2[_i2]);\
198 v = (_vecproj[_i1] - u*_axe1[_i1])/_axe2[_i1];\
199 }\
200 else\
201 {\
202 u = (_vecproj[_i1]*_axe2[_i2] - _vecproj[_i2]*_axe2[_i1]) /(_axe1[_i1]*_axe2[_i2] - _axe1[_i2]*_axe2[_i1]);\
203 v = (_vecproj[_i2] - u*_axe1[_i2])/_axe2[_i2];\
204 }\
205 if(u<-G_EPSILON)\
206 {\
207 outside = 1;\
208 }\
209 else if(v<-G_EPSILON)\
210 {\
211 outside = 1;\
212 }\
213 else\
214 {\
215 float sumuv;\
216 sumuv = u+v;\
217 if(sumuv<-G_EPSILON)\
218 {\
219 outside = 1;\
220 }\
221 else if(sumuv-1.0f>G_EPSILON)\
222 {\
223 outside = 1;\
224 }\
225 else\
226 {\
227 outside = 0;\
228 }\
229 }\
230}\
231
232//! Finds the collision of a ray and a triangle.
233#define RAY_TRIANGLE_INTERSECTION(vOrigin,vDir,vec1,vec2,vec3,tri_plane,pout,u,v,tparam,tmax,does_intersect)\
234{\
235 RAY_PLANE_COLLISION(tri_plane,vDir,vOrigin,pout,tparam,does_intersect);\
236 if(does_intersect != 0)\
237 {\
238 if(tparam<-G_EPSILON||tparam>tmax+G_EPSILON)\
239 {\
240 does_intersect = 0;\
241 }\
242 else\
243 {\
244 TRIANGLE_GET_UVPARAMETERS(pout,vec1,vec2,vec3,tri_plane,u,v,does_intersect);\
245 does_intersect = !does_intersect;\
246 }\
247 }\
248}\
249
250
251//! @}
252
253#endif // GIM_TRI_COLLISION_H_INCLUDED
diff --git a/libraries/ode-0.9/GIMPACT/include/GIMPACT/gim_tri_sphere_collision.h b/libraries/ode-0.9/GIMPACT/include/GIMPACT/gim_tri_sphere_collision.h
new file mode 100644
index 0000000..a2a81d6
--- /dev/null
+++ b/libraries/ode-0.9/GIMPACT/include/GIMPACT/gim_tri_sphere_collision.h
@@ -0,0 +1,51 @@
1#ifndef GIM_TRI_SPHERE_COLLISION_H_INCLUDED
2#define GIM_TRI_SPHERE_COLLISION_H_INCLUDED
3
4/*! \file gim_tri_sphere_collision.h
5\author Francisco León
6*/
7/*
8-----------------------------------------------------------------------------
9This source file is part of GIMPACT Library.
10
11For the latest info, see http://gimpact.sourceforge.net/
12
13Copyright (c) 2006 Francisco Leon. C.C. 80087371.
14email: projectileman@yahoo.com
15
16 This library is free software; you can redistribute it and/or
17 modify it under the terms of EITHER:
18 (1) The GNU Lesser General Public License as published by the Free
19 Software Foundation; either version 2.1 of the License, or (at
20 your option) any later version. The text of the GNU Lesser
21 General Public License is included with this library in the
22 file GIMPACT-LICENSE-LGPL.TXT.
23 (2) The BSD-style license that is included with this library in
24 the file GIMPACT-LICENSE-BSD.TXT.
25
26 This library is distributed in the hope that it will be useful,
27 but WITHOUT ANY WARRANTY; without even the implied warranty of
28 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files
29 GIMPACT-LICENSE-LGPL.TXT and GIMPACT-LICENSE-BSD.TXT for more details.
30
31-----------------------------------------------------------------------------
32*/
33
34/*! \addtogroup GEOMETRIC_OPERATIONS
35*/
36//! @{
37
38//! Finds the contact points from a collision of a triangle and a sphere
39/*!
40\param tri
41\param center
42\param radius
43\param contact_data Contains the closest points on the Sphere, and the normal is pointing to triangle
44*/
45int gim_triangle_sphere_collision(
46 GIM_TRIANGLE_DATA *tri,
47 vec3f center, GREAL radius,
48 GIM_TRIANGLE_CONTACT_DATA * contact_data);
49
50//! @}
51#endif // GIM_TRI_SPHERE_COLLISION_H_INCLUDED
diff --git a/libraries/ode-0.9/GIMPACT/include/GIMPACT/gim_trimesh.h b/libraries/ode-0.9/GIMPACT/include/GIMPACT/gim_trimesh.h
new file mode 100644
index 0000000..b1cdf7f
--- /dev/null
+++ b/libraries/ode-0.9/GIMPACT/include/GIMPACT/gim_trimesh.h
@@ -0,0 +1,539 @@
1#ifndef GIM_TRIMESH_H_INCLUDED
2#define GIM_TRIMESH_H_INCLUDED
3/*! \file gim_trimesh.h
4\author Francisco León
5*/
6/*
7-----------------------------------------------------------------------------
8This source file is part of GIMPACT Library.
9
10For the latest info, see http://gimpact.sourceforge.net/
11
12Copyright (c) 2006 Francisco Leon. C.C. 80087371.
13email: projectileman@yahoo.com
14
15 This library is free software; you can redistribute it and/or
16 modify it under the terms of EITHER:
17 (1) The GNU Lesser General Public License as published by the Free
18 Software Foundation; either version 2.1 of the License, or (at
19 your option) any later version. The text of the GNU Lesser
20 General Public License is included with this library in the
21 file GIMPACT-LICENSE-LGPL.TXT.
22 (2) The BSD-style license that is included with this library in
23 the file GIMPACT-LICENSE-BSD.TXT.
24
25 This library is distributed in the hope that it will be useful,
26 but WITHOUT ANY WARRANTY; without even the implied warranty of
27 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files
28 GIMPACT-LICENSE-LGPL.TXT and GIMPACT-LICENSE-BSD.TXT for more details.
29
30-----------------------------------------------------------------------------
31*/
32
33#include "GIMPACT/gim_boxpruning.h"
34#include "GIMPACT/gim_contact.h"
35
36
37///MAsk defines
38#define GIM_TRIMESH_TRANSFORMED_REPLY 1
39#define GIM_TRIMESH_NEED_UPDATE 2
40
41/*! \addtogroup TRIMESH
42\brief
43A Trimesh is the basic geometric structure for representing solid objects.
44<p><strong>CREATING TRIMESHES</strong></p>
45<ul>
46<li> For creating trimeshes, you must initialize Buffer managers by calling \ref gimpact_init
47<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.
48<li> An alternative way for creaing trimesh objects is calling \ref gim_trimesh_create_from_data.
49<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.
50<li> Each time when the trimesh data is modified, you must call \ref gim_trimesh_update after.
51<li> When a trimesh is no longer needed, you must call \ref gim_trimesh_destroy.
52</ul>
53
54<p>This is an example of how to create a deformable trimesh that shares vertices with the user application:</p>
55\code
56//Declaration of vertices
57vec3f trimeshvertices[200];
58//Declaration of indices
59GUINT trimeshindices[100];
60
61... Initializing vertices and triangle indices at beginning
62
63//Then create trimesh
64GIM_TRIMESH mytrimesh;
65
66//Calling trimesh create function
67
68gim_trimesh_create_from_data(
69&mytrimesh,
70trimeshvertices,200,
710 ,//copy_vertices is 0
72trimeshindices,
73100,
740, //copy_indices is 0
750 //transformed_reply is 0
76);
77\endcode
78<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>
79<p>When the trimesh is no longer needed, destroy it safely with gim_trimesh_destroy()</p>
80<p><strong>UPDATING TRIMESHES</strong></p>
81<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>
82<ul>
83<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.
84\code
85// Access to the source vertices
86gim_buffer_array_lock(&mytrimesh.m_source_vertex_buffer, G_MA_READ_WRITE);
87
88//Get a pointer to the vertex buffer
89vec3f * vertexpointer = GIM_BUFFER_ARRAY_POINTER(vec3f,mytrimesh.m_source_vertex_buffer,0);
90
91//Get the amount of vertices
92int veccount = mytrimesh.m_source_vertex_buffer.m_element_count;
93
94//Modify vertices
95for (int i=0;i<veccount ;i++ )
96{
97 .....
98 .....
99 processing vertices
100 .....
101 .....
102}
103
104// Don't forget to unlock the source vertex array
105gim_buffer_array_unlock(&mytrimesh.m_source_vertex_buffer);
106
107// Notify that the state of the trimesh is changed
108gim_trimesh_post_update(&mytrimesh.m_source_vertex_buffer);
109
110\endcode
111For making trimeshes that allow to update their vertices, use \ref gim_trimesh_create_from_data with parameter <strong>transformed_reply</strong> = 0.
112</ul>
113<ul>
114<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.
115</ul>
116<p> After updating vertices, you must call \ref gim_trimesh_update()</p>
117<p><strong>TRIMESHES COLLISION</strong></p>
118<p>Before collide trimeshes, you need to update them first.</p>
119<p>Then you must use \ref gim_trimesh_trimesh_collision().</p>
120
121*/
122//! @{
123
124//! Prototype for updating vertices
125typedef void * gim_update_trimesh_function(struct _GIM_TRIMESH *);
126
127//! Trimesh
128struct GIM_TRIMESH
129{
130 ///Original
131 //@{
132 GBUFFER_ARRAY m_source_vertex_buffer;//!< Buffer of vec3f coordinates
133
134 //! (GUINT) Indices of triangles,groups of three elements.
135 /*!
136 Array of GUINT. Triangle indices. Each triple contains indices of the vertices for each triangle.
137 \invariant must be aligned
138 */
139 GBUFFER_ARRAY m_tri_index_buffer;
140 //@}
141 ///Allocated
142 //@{
143 char m_mask;//!< Don't use directly
144
145 //! Allocated transformed vertices vec3f
146 /*!
147 Array of vec3f.If gim_trimesh_has_tranformed_reply(this) == 1 then it refers to the m_source_vertex_buffer
148 \invariant must be aligned
149 */
150 GBUFFER_ARRAY m_transformed_vertex_buffer;
151 //@}
152 ///Auxiliary data
153 //@{
154 GIM_AABB_SET m_aabbset;
155 GDYNAMIC_ARRAY m_planes_cache_buffer;//! Allocated GIM_TRIPLANES_CACHE
156 GDYNAMIC_ARRAY m_planes_cache_bitset;
157 gim_update_trimesh_function * m_update_callback;//! If null, then m_transform is applied.
158 mat4f m_transform;
159 //@}
160};
161//typedef struct _GIM_TRIMESH GIM_TRIMESH;
162
163/// Info about mesh
164//! Return the trimesh triangle count
165GUINT gim_trimesh_get_triangle_count(GIM_TRIMESH * trimesh);
166
167//! Returns 1 if the m_transformed_vertex_buffer is a reply of m_source_vertex_buffer
168char gim_trimesh_has_tranformed_reply(GIM_TRIMESH * trimesh);
169
170//! Returns 1 if the trimesh needs to update their aabbset and the planes cache.
171char gim_trimesh_needs_update(GIM_TRIMESH * trimesh);
172
173//! Change the state of the trimesh for force it to update
174/*!
175Call it after made changes to the trimesh.
176\post gim_trimesh_need_update(trimesh) will return 1
177\sa gim_trimesh_needs_update,gim_trimesh_has_tranformed_reply
178*/
179void gim_trimesh_post_update(GIM_TRIMESH * trimesh);
180
181//! Creates the aabb set and the triangles cache
182/*!
183
184\param trimesh
185\param vertex_array
186\param triindex_array
187\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.
188\post it copies the arrays by reference, and creates the auxiliary data (m_aabbset,m_planes_cache_buffer)
189*/
190void gim_trimesh_create_from_arrays(GIM_TRIMESH * trimesh, GBUFFER_ARRAY * vertex_array, GBUFFER_ARRAY * triindex_array,char transformed_reply);
191
192
193
194//! Create a trimesh from vertex array and an index array
195/*!
196\param trimesh An uninitialized GIM_TRIMESH structure
197\param vertex_array A buffer to a vec3f array
198\param vertex_count
199\param triindex_array
200\param index_count
201\param copy_vertices If 1, it copies the source vertices in another buffer. Else (0) it constructs a reference to the data.
202\param copy_indices If 1, it copies the source vertices in another buffer. Else (0) it constructs a reference to the data.
203\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().
204*/
205void gim_trimesh_create_from_data(GIM_TRIMESH * trimesh, vec3f * vertex_array, GUINT vertex_count,char copy_vertices, GUINT * triindex_array, GUINT index_count,char copy_indices,char transformed_reply);
206
207//! Clears auxiliary data and releases buffer arrays
208void gim_trimesh_destroy(GIM_TRIMESH * trimesh);
209
210//! Copies two meshes
211/*!
212\param source_trimesh
213\param dest_trimesh
214\param copy_by_reference If 1, it attach a reference to the source vertices, else it copies the vertices
215\param transformed_reply If 1, transformed vertices are reply of source vertives. 1 Is recommended
216*/
217void gim_trimesh_copy(GIM_TRIMESH * source_trimesh,GIM_TRIMESH * dest_trimesh, char copy_by_reference, char transformed_reply);
218
219
220//! Locks the trimesh for working with it
221/*!
222\post locks m_tri_index_buffer and m_transformed_vertex_buffer.
223\param trimesh
224*/
225void gim_trimesh_locks_work_data(GIM_TRIMESH * trimesh);
226
227
228//! unlocks the trimesh
229/*!
230\post unlocks m_tri_index_buffer and m_transformed_vertex_buffer.
231\param trimesh
232*/
233void gim_trimesh_unlocks_work_data(GIM_TRIMESH * trimesh);
234
235//! Updates m_transformed_vertex_buffer
236/*!
237\pre m_transformed_vertex_buffer must be unlocked
238*/
239void gim_trimesh_update_vertices(GIM_TRIMESH * trimesh);
240
241//! Updates m_aabbset and m_planes_cache_bitset
242/*!
243\pre gim_trimesh_locks_work_data must be called before
244*/
245void gim_trimesh_update_aabbset(GIM_TRIMESH * trimesh);
246
247//! Calls before perfom collisions. Updates the trimesh if needed
248/*!
249\post If gim_trimesh_needs_update returns 1, then it calls gim_trimesh_update_vertices and gim_trimesh_update_aabbset
250*/
251void gim_trimesh_update(GIM_TRIMESH * trimesh);
252
253//! Set the transform of a trimesh
254/*!
255\post This function calls to gim_trimesh_post_update
256*/
257void gim_trimesh_set_tranform(GIM_TRIMESH * trimesh, mat4f transform);
258
259//! Fetch triangle data
260/*!
261\pre gim_trimesh_locks_work_data must be called before
262*/
263void gim_trimesh_get_triangle_data(GIM_TRIMESH * trimesh, GUINT triangle_index, GIM_TRIANGLE_DATA * tri_data);
264
265//! Fetch triangle vertices
266/*!
267\pre gim_trimesh_locks_work_data must be called before
268*/
269void gim_trimesh_get_triangle_vertices(GIM_TRIMESH * trimesh, GUINT triangle_index, vec3f v1,vec3f v2,vec3f v3);
270
271//! Trimesh Trimesh Collisions
272/*!
273Before use this function you must update each trimesh:
274\code
275gim_trimesh_update(TriMesh1);
276gim_trimesh_update(TriMesh2);
277\endcode
278Then you must use the trimesh collision in this way:
279\code
280int collide_trimeshes(GIM_TRIMESH * TriMesh1, GIM_TRIMESH * TriMesh2)
281{
282 //Create contact list
283 GDYNAMIC_ARRAY trimeshcontacts;
284 GIM_CREATE_CONTACT_LIST(trimeshcontacts);
285
286 //Collide trimeshes
287 gim_trimesh_trimesh_collision(TriMesh1,TriMesh2,&trimeshcontacts);
288
289 if(trimeshcontacts.m_size == 0) //do nothing
290 {
291 GIM_DYNARRAY_DESTROY(trimeshcontacts);//clean contact array
292 return 0;
293 }
294
295 //Getting a pointer to the contact array
296 GIM_CONTACT * ptrimeshcontacts = GIM_DYNARRAY_POINTER(GIM_CONTACT,trimeshcontacts);
297
298 int contactcount = trimeshcontacts.m_size;
299 int i;
300 //Process contacts
301 for (i=0;i<contactcount ;i++)
302 {
303 //Do something with the contact (ptrimeshcontacts)
304 ......
305 ......
306 // Like creating joints or anything else
307 ......
308 ......
309 ptrimeshcontacts++;
310 }
311 GIM_DYNARRAY_DESTROY(trimeshcontacts);
312 return contactcount;
313}
314\endcode
315In each contact
316<ul>
317<li> m_handle1 points to trimesh1.
318<li> m_handle2 points to trimesh2.
319<li> m_feature1 Is a triangle index of trimesh1.
320<li> m_feature2 Is a triangle index of trimesh2.
321</ul>
322
323\param trimesh1 Collider
324\param trimesh2 Collidee
325\param contacts A GIM_CONTACT array. Must be initialized
326*/
327void gim_trimesh_trimesh_collision(GIM_TRIMESH * trimesh1, GIM_TRIMESH * trimesh2, GDYNAMIC_ARRAY * contacts);
328
329
330//! Trimesh Sphere Collisions
331/*!
332Before use this function you must update the trimesh:
333\code
334gim_trimesh_update(trimesh);
335\endcode
336Then you must use this function in this way:
337\code
338int collide_trimesh_sphere(GIM_TRIMESH * trimesh, vec3f center,GREAL radius)
339{
340 //Create contact list
341 GDYNAMIC_ARRAY trimeshcontacts;
342 GIM_CREATE_CONTACT_LIST(trimeshcontacts);
343
344 //Collide trimeshes
345 gim_trimesh_sphere_collision(trimesh,center,radius,&trimeshcontacts);
346
347 if(trimeshcontacts.m_size == 0) //do nothing
348 {
349 GIM_DYNARRAY_DESTROY(trimeshcontacts);//clean contact array
350 return 0;
351 }
352
353 //Getting a pointer to the contact array
354 GIM_CONTACT * ptrimeshcontacts = GIM_DYNARRAY_POINTER(GIM_CONTACT,trimeshcontacts);
355
356 int contactcount = trimeshcontacts.m_size;
357 int i;
358 //Process contacts
359 for (i=0;i<contactcount ;i++)
360 {
361 //Do something with the contact (ptrimeshcontacts)
362 ......
363 ......
364 // Like creating joints or anything else
365 ......
366 ......
367 ptrimeshcontacts++;
368 }
369 GIM_DYNARRAY_DESTROY(trimeshcontacts);
370 return contactcount;
371}
372\endcode
373
374In each contact
375<ul>
376<li> m_handle1 points to trimesh.
377<li> m_handle2 points to NULL.
378<li> m_feature1 Is a triangle index of trimesh.
379</ul>
380
381\param trimesh
382\param center
383\param radius
384\param contacts A GIM_CONTACT array. Must be initialized
385*/
386void gim_trimesh_sphere_collision(GIM_TRIMESH * trimesh,vec3f center,GREAL radius, GDYNAMIC_ARRAY * contacts);
387
388
389//! Trimesh Capsule collision
390/*!
391Find the closest primitive collided by the ray.
392
393Before use this function you must update the trimesh:
394\code
395gim_trimesh_update(trimesh);
396\endcode
397Then you must use this function in this way:
398\code
399int collide_trimesh_capsule(GIM_TRIMESH * trimesh, GIM_CAPSULE_DATA * capsule)
400{
401 //Create contact list
402 GDYNAMIC_ARRAY trimeshcontacts;
403 GIM_CREATE_CONTACT_LIST(trimeshcontacts);
404
405 //Collide trimeshes
406 gim_trimesh_capsule_collision(trimesh,capsule,&trimeshcontacts);
407
408 if(trimeshcontacts.m_size == 0) //do nothing
409 {
410 GIM_DYNARRAY_DESTROY(trimeshcontacts);//clean contact array
411 return 0;
412 }
413
414 //Getting a pointer to the contact array
415 GIM_CONTACT * ptrimeshcontacts = GIM_DYNARRAY_POINTER(GIM_CONTACT,trimeshcontacts);
416
417 int contactcount = trimeshcontacts.m_size;
418 int i;
419 //Process contacts
420 for (i=0;i<contactcount ;i++)
421 {
422 //Do something with the contact (ptrimeshcontacts)
423 ......
424 ......
425 // Like creating joints or anything else
426 ......
427 ......
428 ptrimeshcontacts++;
429 }
430 GIM_DYNARRAY_DESTROY(trimeshcontacts);
431 return contactcount;
432}
433\endcode
434
435In each contact
436<ul>
437<li> m_handle1 points to trimesh.
438<li> m_handle2 points to NULL.
439<li> m_feature1 Is a triangle index of trimesh.
440</ul>
441
442\param trimesh
443\param capsule
444\param contacts A GIM_CONTACT array. Must be initialized
445*/
446void gim_trimesh_capsule_collision(GIM_TRIMESH * trimesh, GIM_CAPSULE_DATA * capsule, GDYNAMIC_ARRAY * contacts);
447
448
449///Function for create Trimesh Plane collision result
450#define GIM_CREATE_TRIMESHPLANE_CONTACTS(dynarray) GIM_DYNARRAY_CREATE(vec4f,dynarray,G_ARRAY_GROW_SIZE)
451
452//! Trimesh Plane Collisions
453/*!
454
455Before use this function you must update the trimesh:
456\code
457gim_trimesh_update(trimesh);
458\endcode
459Then you must use this function in this way:
460\code
461int collide_trimesh_plane(GIM_TRIMESH * trimesh, vec4f plane)
462{
463 //Create contact list
464 GDYNAMIC_ARRAY tri_plane_contacts;
465 GIM_CREATE_TRIMESHPLANE_CONTACTS(tri_plane_contacts);
466
467 //Collide trimeshes
468 gim_trimesh_plane_collision(trimesh,plane,&tri_plane_contacts);
469
470 if(tri_plane_contacts.m_size == 0) //do nothing
471 {
472 GIM_DYNARRAY_DESTROY(tri_plane_contacts);//clean contact array
473 return 0;
474 }
475
476 //Getting a pointer to the contact array
477 vec4f * planecontacts = GIM_DYNARRAY_POINTER(vec4f,tri_plane_contacts);
478
479 int contactcount = tri_plane_contacts.m_size;
480 int i;
481 //Process contacts
482 for (i=0;i<contactcount ;i++)
483 {
484 vec3f contactpoint;
485 GREAL contactdis;
486
487 VEC_COPY(contactpoint,planecontacts[i]); //Get contact point
488 contactdis = planecontacts[i][3]; // Get distance depth
489
490 //Do something with the contact
491 ......
492 ......
493 // Like creating joints or anything else
494 ......
495 ......
496 }
497 GIM_DYNARRAY_DESTROY(tri_plane_contacts);
498 return contactcount;
499}
500\endcode
501
502In 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.
503
504\param trimesh
505\param plane vec4f plane
506\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.
507*/
508void gim_trimesh_plane_collision(GIM_TRIMESH * trimesh,vec4f plane, GDYNAMIC_ARRAY * contacts);
509
510
511//! Trimesh Ray Collisions
512/*!
513\param trimesh
514\param origin
515\param dir
516\param tmax
517\param contact
518\return 1 if the ray collides, else 0
519*/
520int gim_trimesh_ray_collision(GIM_TRIMESH * trimesh,vec3f origin,vec3f dir, GREAL tmax, GIM_TRIANGLE_RAY_CONTACT_DATA * contact);
521
522
523//! Trimesh Ray Collisions closest
524/*!
525Find the closest primitive collided by the ray
526\param trimesh
527\param origin
528\param dir
529\param tmax
530\param contact
531\return 1 if the ray collides, else 0
532*/
533int gim_trimesh_ray_closest_collision(GIM_TRIMESH * trimesh,vec3f origin,vec3f dir, GREAL tmax, GIM_TRIANGLE_RAY_CONTACT_DATA * contact);
534
535//! @}
536
537
538
539#endif // GIM_TRIMESH_H_INCLUDED
diff --git a/libraries/ode-0.9/GIMPACT/include/GIMPACT/gimpact.h b/libraries/ode-0.9/GIMPACT/include/GIMPACT/gimpact.h
new file mode 100644
index 0000000..bcd22a1
--- /dev/null
+++ b/libraries/ode-0.9/GIMPACT/include/GIMPACT/gimpact.h
@@ -0,0 +1,45 @@
1#ifndef GIMPACT_H_INCLUDED
2#define GIMPACT_H_INCLUDED
3
4/*! \file gimpact.h
5\author Francisco León
6*/
7/*
8-----------------------------------------------------------------------------
9This source file is part of GIMPACT Library.
10
11For the latest info, see http://gimpact.sourceforge.net/
12
13Copyright (c) 2006 Francisco Leon. C.C. 80087371.
14email: projectileman@yahoo.com
15
16 This library is free software; you can redistribute it and/or
17 modify it under the terms of EITHER:
18 (1) The GNU Lesser General Public License as published by the Free
19 Software Foundation; either version 2.1 of the License, or (at
20 your option) any later version. The text of the GNU Lesser
21 General Public License is included with this library in the
22 file GIMPACT-LICENSE-LGPL.TXT.
23 (2) The BSD-style license that is included with this library in
24 the file GIMPACT-LICENSE-BSD.TXT.
25
26 This library is distributed in the hope that it will be useful,
27 but WITHOUT ANY WARRANTY; without even the implied warranty of
28 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files
29 GIMPACT-LICENSE-LGPL.TXT and GIMPACT-LICENSE-BSD.TXT for more details.
30
31-----------------------------------------------------------------------------
32*/
33
34
35#include "GIMPACT/gim_trimesh.h"
36
37/*! \defgroup GIMPACT_INIT
38*/
39//! @{
40//! Call this for initialize GIMPACT system structures.
41void gimpact_init();
42//! Call this for clean GIMPACT system structures.
43void gimpact_terminate();
44//! @}
45#endif // GIMPACT_H_INCLUDED
diff --git a/libraries/ode-0.9/GIMPACT/src/gim_boxpruning.cpp b/libraries/ode-0.9/GIMPACT/src/gim_boxpruning.cpp
new file mode 100644
index 0000000..91e1d37
--- /dev/null
+++ b/libraries/ode-0.9/GIMPACT/src/gim_boxpruning.cpp
@@ -0,0 +1,514 @@
1
2/*
3-----------------------------------------------------------------------------
4This source file is part of GIMPACT Library.
5
6For the latest info, see http://gimpact.sourceforge.net/
7
8Copyright (c) 2006 Francisco Leon. C.C. 80087371.
9email: projectileman@yahoo.com
10
11 This library is free software; you can redistribute it and/or
12 modify it under the terms of EITHER:
13 (1) The GNU Lesser General Public License as published by the Free
14 Software Foundation; either version 2.1 of the License, or (at
15 your option) any later version. The text of the GNU Lesser
16 General Public License is included with this library in the
17 file GIMPACT-LICENSE-LGPL.TXT.
18 (2) The BSD-style license that is included with this library in
19 the file GIMPACT-LICENSE-BSD.TXT.
20
21 This library is distributed in the hope that it will be useful,
22 but WITHOUT ANY WARRANTY; without even the implied warranty of
23 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files
24 GIMPACT-LICENSE-LGPL.TXT and GIMPACT-LICENSE-BSD.TXT for more details.
25
26-----------------------------------------------------------------------------
27*/
28
29
30#include "GIMPACT/gim_boxpruning.h"
31
32
33
34//! Allocate memory for all aabb set.
35void gim_aabbset_alloc(GIM_AABB_SET * aabbset, GUINT count)
36{
37 aabbset->m_count = count;
38 aabbset->m_boxes = (aabb3f *)gim_alloc(sizeof(aabb3f)*count);
39
40 if(count<GIM_MIN_SORTED_BIPARTITE_PRUNING_BOXES)
41 {
42 aabbset->m_maxcoords = 0;
43 aabbset->m_sorted_mincoords = 0;
44 }
45 else
46 {
47 aabbset->m_maxcoords = (GUINT *)gim_alloc(sizeof(GUINT)*aabbset->m_count );
48 aabbset->m_sorted_mincoords = (GIM_RSORT_TOKEN *)gim_alloc(sizeof(GIM_RSORT_TOKEN)*aabbset->m_count);
49 }
50 aabbset->m_shared = 0;
51 INVALIDATE_AABB(aabbset->m_global_bound);
52}
53
54//! Destroys the aabb set.
55void gim_aabbset_destroy(GIM_AABB_SET * aabbset)
56{
57 aabbset->m_count = 0;
58 if(aabbset->m_shared==0)
59 {
60 gim_free(aabbset->m_boxes,0);
61 gim_free(aabbset->m_maxcoords,0);
62 gim_free(aabbset->m_sorted_mincoords,0);
63 }
64 aabbset->m_boxes = 0;
65 aabbset->m_sorted_mincoords = 0;
66 aabbset->m_maxcoords = 0;
67}
68
69void gim_aabbset_calc_global_bound(GIM_AABB_SET * aabbset)
70{
71 aabb3f * paabb = aabbset->m_boxes;
72 aabb3f * globalbox = &aabbset->m_global_bound;
73 AABB_COPY((*globalbox),(*paabb));
74
75 GUINT count = aabbset->m_count-1;
76 paabb++;
77 while(count)
78 {
79 MERGEBOXES(*globalbox,*paabb)
80 paabb++;
81 count--;
82 }
83}
84
85
86//! Sorts the boxes for box prunning.
87/*!
881) find the integer representation of the aabb coords
892) Sorts the min coords
903) Calcs the global bound
91\pre aabbset must be allocated. And the boxes must be already set.
92\param aabbset
93\param calc_global_bound If 1 , calcs the global bound
94\post If aabbset->m_sorted_mincoords == 0, then it allocs the sorted coordinates
95*/
96void gim_aabbset_sort(GIM_AABB_SET * aabbset, char calc_global_bound)
97{
98 if(aabbset->m_sorted_mincoords == 0)
99 {//allocate
100 aabbset->m_maxcoords = (GUINT *)gim_alloc(sizeof(GUINT)*aabbset->m_count );
101 aabbset->m_sorted_mincoords = (GIM_RSORT_TOKEN *)gim_alloc(sizeof(GIM_RSORT_TOKEN)*aabbset->m_count);
102 }
103
104 GUINT i, count = aabbset->m_count;
105 aabb3f * paabb = aabbset->m_boxes;
106 GUINT * maxcoords = aabbset->m_maxcoords;
107 GIM_RSORT_TOKEN * sorted_tokens = aabbset->m_sorted_mincoords;
108
109 if(count<860)//Calibrated on a Pentium IV
110 {
111 //Sort by quick sort
112 //Calculate keys
113 for(i=0;i<count;i++)
114 {
115 GIM_CONVERT_VEC3F_GUINT_XZ_UPPER(paabb[i].maxX,paabb[i].maxZ,maxcoords[i]);
116 GIM_CONVERT_VEC3F_GUINT_XZ(paabb[i].minX,paabb[i].minZ,sorted_tokens[i].m_key);
117 sorted_tokens[i].m_value = i;
118 }
119 GIM_QUICK_SORT_ARRAY(GIM_RSORT_TOKEN , sorted_tokens, count, RSORT_TOKEN_COMPARATOR,GIM_DEF_EXCHANGE_MACRO);
120 }
121 else
122 {
123 //Sort by radix sort
124 GIM_RSORT_TOKEN * unsorted = (GIM_RSORT_TOKEN *)gim_alloc(sizeof(GIM_RSORT_TOKEN )*count);
125 //Calculate keys
126 for(i=0;i<count;i++)
127 {
128 GIM_CONVERT_VEC3F_GUINT_XZ_UPPER(paabb[i].maxX,paabb[i].maxZ,maxcoords[i]);
129 GIM_CONVERT_VEC3F_GUINT_XZ(paabb[i].minX,paabb[i].minZ,unsorted[i].m_key);
130 unsorted[i].m_value = i;
131 }
132 GIM_RADIX_SORT_RTOKENS(unsorted,sorted_tokens,count);
133 gim_free(unsorted,0);
134 }
135
136 if(calc_global_bound) gim_aabbset_calc_global_bound(aabbset);
137}
138
139//utility macros
140
141/*#define PUSH_PAIR(i,j,pairset)\
142{\
143 GIM_PAIR _pair={i,j};\
144 GIM_DYNARRAY_PUSH_ITEM(GIM_PAIR,pairset,_pair);\
145}*/
146
147#define PUSH_PAIR(i,j,pairset)\
148{\
149 GIM_DYNARRAY_PUSH_EMPTY(GIM_PAIR,pairset);\
150 GIM_PAIR * _pair = GIM_DYNARRAY_POINTER(GIM_PAIR,pairset) + (pairset).m_size - 1;\
151 _pair->m_index1 = i;\
152 _pair->m_index2 = j;\
153}
154
155#define PUSH_PAIR_INV(i,j,pairset)\
156{\
157 GIM_DYNARRAY_PUSH_EMPTY(GIM_PAIR,pairset);\
158 GIM_PAIR * _pair = GIM_DYNARRAY_POINTER(GIM_PAIR,pairset) + (pairset).m_size - 1;\
159 _pair->m_index1 = j;\
160 _pair->m_index2 = i;\
161}
162
163#define FIND_OVERLAPPING_FOWARD(\
164 curr_index,\
165 test_count,\
166 test_aabb,\
167 max_coord_uint,\
168 sorted_tokens,\
169 aabbarray,\
170 pairset,\
171 push_pair_macro)\
172{\
173 GUINT _i = test_count;\
174 char _intersected;\
175 GIM_RSORT_TOKEN * _psorted_tokens = sorted_tokens;\
176 while(max_coord_uint >= _psorted_tokens->m_key && _i>0)\
177 {\
178 AABBCOLLISION(_intersected,test_aabb,aabbarray[_psorted_tokens->m_value]);\
179 if(_intersected)\
180 {\
181 push_pair_macro(curr_index, _psorted_tokens->m_value,pairset);\
182 }\
183 _psorted_tokens++;\
184 _i--;\
185 }\
186}
187
188//! log(N) Complete box pruning. Returns a list of overlapping pairs of boxes, each box of the pair belongs to the same set.
189/*!
190\pre aabbset must be allocated and sorted, the boxes must be already set.
191\param aabbset Must be sorted. Global bound isn't required
192\param collision_pairs Array of GIM_PAIR elements. Must be initialized before (Reserve size ~ 100)
193*/
194void gim_aabbset_self_intersections_sorted(GIM_AABB_SET * aabbset, GDYNAMIC_ARRAY * collision_pairs)
195{
196 collision_pairs->m_size = 0;
197 GUINT count = aabbset->m_count;
198 aabb3f * paabb = aabbset->m_boxes;
199 GUINT * maxcoords = aabbset->m_maxcoords;
200 GIM_RSORT_TOKEN * sorted_tokens = aabbset->m_sorted_mincoords;
201 aabb3f test_aabb;
202 while(count>1)
203 {
204 ///current cache variables
205 GUINT curr_index = sorted_tokens->m_value;
206 GUINT max_coord_uint = maxcoords[curr_index];
207 AABB_COPY(test_aabb,paabb[curr_index]);
208
209 ///next pairs
210 sorted_tokens++;
211 count--;
212 FIND_OVERLAPPING_FOWARD( curr_index, count, test_aabb, max_coord_uint, sorted_tokens , paabb, (*collision_pairs),PUSH_PAIR);
213 }
214}
215
216//! NxN Complete box pruning. Returns a list of overlapping pairs of boxes, each box of the pair belongs to the same set.
217/*!
218\pre aabbset must be allocated, the boxes must be already set.
219\param aabbset Global bound isn't required. Doen't need to be sorted.
220\param collision_pairs Array of GIM_PAIR elements. Must be initialized before (Reserve size ~ 100)
221*/
222void gim_aabbset_self_intersections_brute_force(GIM_AABB_SET * aabbset, GDYNAMIC_ARRAY * collision_pairs)
223{
224 collision_pairs->m_size = 0;
225 GUINT i,j;
226 GUINT count = aabbset->m_count;
227 aabb3f * paabb = aabbset->m_boxes;
228 char intersected;
229 for (i=0;i< count-1 ;i++ )
230 {
231 for (j=i+1;j<count ;j++ )
232 {
233 AABBCOLLISION(intersected,paabb[i],paabb[j]);
234 if(intersected)
235 {
236 PUSH_PAIR(i,j,(*collision_pairs));
237 }
238 }
239 }
240}
241
242//! log(N) Bipartite box pruning. Returns a list of overlapping pairs of boxes, each box of the pair belongs to a different set.
243/*!
244\pre aabbset1 and aabbset2 must be allocated and sorted, the boxes must be already set.
245\param aabbset1 Must be sorted, Global bound is required.
246\param aabbset2 Must be sorted, Global bound is required.
247\param collision_pairs Array of GIM_PAIR elements. Must be initialized before (Reserve size ~ 100)
248*/
249void gim_aabbset_bipartite_intersections_sorted(GIM_AABB_SET * aabbset1, GIM_AABB_SET * aabbset2, GDYNAMIC_ARRAY * collision_pairs)
250{
251 char intersected;
252 collision_pairs->m_size = 0;
253
254 AABBCOLLISION(intersected,aabbset1->m_global_bound,aabbset2->m_global_bound);
255 if(intersected == 0) return;
256
257 GUINT count1 = aabbset1->m_count;
258 aabb3f * paabb1 = aabbset1->m_boxes;
259 GUINT * maxcoords1 = aabbset1->m_maxcoords;
260 GIM_RSORT_TOKEN * sorted_tokens1 = aabbset1->m_sorted_mincoords;
261
262 GUINT count2 = aabbset2->m_count;
263 aabb3f * paabb2 = aabbset2->m_boxes;
264 GUINT * maxcoords2 = aabbset2->m_maxcoords;
265 GIM_RSORT_TOKEN * sorted_tokens2 = aabbset2->m_sorted_mincoords;
266
267 GUINT curr_index;
268
269 GUINT max_coord_uint;
270 aabb3f test_aabb;
271
272 //Classify boxes
273 //Find Set intersection
274 aabb3f int_abbb;
275 BOXINTERSECTION(aabbset1->m_global_bound,aabbset2->m_global_bound, int_abbb);
276
277 //Clasify set 1
278 GIM_RSORT_TOKEN * classified_tokens1 = (GIM_RSORT_TOKEN *) gim_alloc(sizeof(GIM_RSORT_TOKEN)*count1);
279 GUINT i,classified_count1 = 0,classified_count2 = 0;
280
281
282 for (i=0;i<count1;i++ )
283 {
284 curr_index = sorted_tokens1[i].m_value;
285 AABBCOLLISION(intersected,paabb1[curr_index],int_abbb);
286 if(intersected)
287 {
288 classified_tokens1[classified_count1] = sorted_tokens1[i];
289 classified_count1++;
290 }
291 }
292
293 if(classified_count1==0)
294 {
295 gim_free(classified_tokens1 ,0);
296 return; // no pairs
297 }
298
299 //Clasify set 2
300 GIM_RSORT_TOKEN * classified_tokens2 = (GIM_RSORT_TOKEN *) gim_alloc(sizeof(GIM_RSORT_TOKEN)*count2);
301
302 for (i=0;i<count2;i++ )
303 {
304 curr_index = sorted_tokens2[i].m_value;
305 AABBCOLLISION(intersected,paabb2[curr_index],int_abbb);
306 if(intersected)
307 {
308 classified_tokens2[classified_count2] = sorted_tokens2[i];
309 classified_count2++;
310 }
311 }
312
313 if(classified_count2==0)
314 {
315 gim_free(classified_tokens1 ,0);
316 gim_free(classified_tokens2 ,0);
317 return; // no pairs
318 }
319
320 sorted_tokens1 = classified_tokens1;
321 sorted_tokens2 = classified_tokens2;
322
323 while(classified_count1>0&&classified_count2>0)
324 {
325 if(sorted_tokens1->m_key <= sorted_tokens2->m_key)
326 {
327 ///current cache variables
328 curr_index = sorted_tokens1->m_value;
329 max_coord_uint = maxcoords1[curr_index];
330 AABB_COPY(test_aabb,paabb1[curr_index]);
331 ///next pairs
332 sorted_tokens1++;
333 classified_count1--;
334 FIND_OVERLAPPING_FOWARD( curr_index, classified_count2, test_aabb, max_coord_uint, sorted_tokens2 , paabb2, (*collision_pairs), PUSH_PAIR);
335 }
336 else ///Switch test
337 {
338 ///current cache variables
339 curr_index = sorted_tokens2->m_value;
340 max_coord_uint = maxcoords2[curr_index];
341 AABB_COPY(test_aabb,paabb2[curr_index]);
342 ///next pairs
343 sorted_tokens2++;
344 classified_count2--;
345 FIND_OVERLAPPING_FOWARD( curr_index, classified_count1, test_aabb, max_coord_uint, sorted_tokens1 , paabb1, (*collision_pairs), PUSH_PAIR_INV );
346 }
347 }
348 gim_free(classified_tokens1 ,0);
349 gim_free(classified_tokens2 ,0);
350}
351
352//! NxM Bipartite box pruning. Returns a list of overlapping pairs of boxes, each box of the pair belongs to a different set.
353/*!
354\pre aabbset1 and aabbset2 must be allocated and sorted, the boxes must be already set.
355\param aabbset1 Must be sorted, Global bound is required.
356\param aabbset2 Must be sorted, Global bound is required.
357\param collision_pairs Array of GIM_PAIR elements. Must be initialized before (Reserve size ~ 100)
358*/
359void gim_aabbset_bipartite_intersections_brute_force(GIM_AABB_SET * aabbset1,GIM_AABB_SET * aabbset2, GDYNAMIC_ARRAY * collision_pairs)
360{
361 char intersected;
362 collision_pairs->m_size = 0;
363 AABBCOLLISION(intersected,aabbset1->m_global_bound,aabbset2->m_global_bound);
364 if(intersected == 0) return;
365
366 aabb3f int_abbb;
367 //Find Set intersection
368 BOXINTERSECTION(aabbset1->m_global_bound,aabbset2->m_global_bound, int_abbb);
369 //Clasify set 1
370 GUINT i,j;
371 GUINT classified_count = 0;
372
373 GUINT count = aabbset1->m_count;
374 aabb3f * paabb1 = aabbset1->m_boxes;
375 aabb3f * paabb2 = aabbset2->m_boxes;
376
377 GUINT * classified = (GUINT *) gim_alloc(sizeof(GUINT)*count);
378
379 for (i=0;i<count;i++ )
380 {
381 AABBCOLLISION(intersected,paabb1[i],int_abbb);
382 if(intersected)
383 {
384 classified[classified_count] = i;
385 classified_count++;
386 }
387 }
388
389 if(classified_count==0) return; // no pairs
390
391 //intesect set2
392 count = aabbset2->m_count;
393 for (i=0;i<count;i++)
394 {
395 AABBCOLLISION(intersected,paabb2[i],int_abbb);
396 if(intersected)
397 {
398 for (j=0;j<classified_count;j++)
399 {
400 AABBCOLLISION(intersected,paabb2[i],paabb1[classified[j]]);
401 if(intersected)
402 {
403 PUSH_PAIR(classified[j],i,(*collision_pairs));
404 }
405 }
406 }
407 }
408 gim_free(classified,0);
409}
410
411
412//! Initalizes the set. Sort Boxes if needed.
413/*!
414\pre aabbset must be allocated. And the boxes must be already set.
415\post If the set has less of GIM_MIN_SORTED_BIPARTITE_PRUNING_BOXES boxes, only calcs the global box,
416 else it Sorts the entire set( Only applicable for large sets)
417*/
418void gim_aabbset_update(GIM_AABB_SET * aabbset)
419{
420 if(aabbset->m_count < GIM_MIN_SORTED_BIPARTITE_PRUNING_BOXES)
421 {//Brute force approach
422 gim_aabbset_calc_global_bound(aabbset);
423 }
424 else
425 {//Sorted force approach
426 gim_aabbset_sort(aabbset,1);
427 }
428}
429
430//! Complete box pruning. Returns a list of overlapping pairs of boxes, each box of the pair belongs to the same set.
431/*!
432This function sorts the set and then it calls to gim_aabbset_self_intersections_brute_force or gim_aabbset_self_intersections_sorted.
433
434\param aabbset Set of boxes. Sorting isn't required.
435\param collision_pairs Array of GIM_PAIR elements. Must be initialized before (Reserve size ~ 100)
436\pre aabbset must be allocated and initialized.
437\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.
438*/
439void gim_aabbset_self_intersections(GIM_AABB_SET * aabbset, GDYNAMIC_ARRAY * collision_pairs)
440{
441 if(aabbset->m_count < GIM_MIN_SORTED_PRUNING_BOXES)
442 {//Brute force approach
443 gim_aabbset_self_intersections_brute_force(aabbset,collision_pairs);
444 }
445 else
446 {//Sorted force approach
447 gim_aabbset_sort(aabbset,0);
448 gim_aabbset_self_intersections_sorted(aabbset,collision_pairs);
449 }
450}
451
452//! Collides two sets. Returns a list of overlapping pairs of boxes, each box of the pair belongs to a different set.
453/*!
454\pre aabbset1 and aabbset2 must be allocated and updated. See .
455\param aabbset1 Must be sorted, Global bound is required.
456\param aabbset2 Must be sorted, Global bound is required.
457\param collision_pairs Array of GIM_PAIR elements. Must be initialized before (Reserve size ~ 100)
458*/
459void gim_aabbset_bipartite_intersections(GIM_AABB_SET * aabbset1, GIM_AABB_SET * aabbset2, GDYNAMIC_ARRAY * collision_pairs)
460{
461 if(aabbset1->m_sorted_mincoords == 0||aabbset2->m_sorted_mincoords == 0)
462 {//Brute force approach
463 gim_aabbset_bipartite_intersections_brute_force(aabbset1,aabbset2,collision_pairs);
464 }
465 else
466 {//Sorted force approach
467 gim_aabbset_bipartite_intersections_sorted(aabbset1,aabbset2,collision_pairs);
468 }
469}
470
471void gim_aabbset_box_collision(aabb3f *test_aabb, GIM_AABB_SET * aabbset, GDYNAMIC_ARRAY * collided)
472{
473 collided->m_size = 0;
474 char intersected;
475 AABBCOLLISION(intersected,aabbset->m_global_bound,(*test_aabb));
476 if(intersected == 0) return;
477
478 GUINT i;
479 GUINT count = aabbset->m_count;
480 aabb3f * paabb = aabbset->m_boxes;
481 aabb3f _testaabb;
482 AABB_COPY(_testaabb,*test_aabb);
483
484 for (i=0;i< count;i++ )
485 {
486 AABBCOLLISION(intersected,paabb[i],_testaabb);
487 if(intersected)
488 {
489 GIM_DYNARRAY_PUSH_ITEM(GUINT,(*collided),i);
490 }
491 }
492}
493
494void gim_aabbset_ray_collision(vec3f vorigin,vec3f vdir, GREAL tmax, GIM_AABB_SET * aabbset, GDYNAMIC_ARRAY * collided)
495{
496 collided->m_size = 0;
497 char intersected;
498 GREAL tparam = 0;
499 BOX_INTERSECTS_RAY(aabbset->m_global_bound, vorigin, vdir, tparam, tmax,intersected);
500 if(intersected==0) return;
501
502 GUINT i;
503 GUINT count = aabbset->m_count;
504 aabb3f * paabb = aabbset->m_boxes;
505
506 for (i=0;i< count;i++ )
507 {
508 BOX_INTERSECTS_RAY(paabb[i], vorigin, vdir, tparam, tmax,intersected);
509 if(intersected)
510 {
511 GIM_DYNARRAY_PUSH_ITEM(GUINT,(*collided),i);
512 }
513 }
514}
diff --git a/libraries/ode-0.9/GIMPACT/src/gim_contact.cpp b/libraries/ode-0.9/GIMPACT/src/gim_contact.cpp
new file mode 100644
index 0000000..762af06
--- /dev/null
+++ b/libraries/ode-0.9/GIMPACT/src/gim_contact.cpp
@@ -0,0 +1,132 @@
1
2/*
3-----------------------------------------------------------------------------
4This source file is part of GIMPACT Library.
5
6For the latest info, see http://gimpact.sourceforge.net/
7
8Copyright (c) 2006 Francisco Leon. C.C. 80087371.
9email: projectileman@yahoo.com
10
11 This library is free software; you can redistribute it and/or
12 modify it under the terms of EITHER:
13 (1) The GNU Lesser General Public License as published by the Free
14 Software Foundation; either version 2.1 of the License, or (at
15 your option) any later version. The text of the GNU Lesser
16 General Public License is included with this library in the
17 file GIMPACT-LICENSE-LGPL.TXT.
18 (2) The BSD-style license that is included with this library in
19 the file GIMPACT-LICENSE-BSD.TXT.
20
21 This library is distributed in the hope that it will be useful,
22 but WITHOUT ANY WARRANTY; without even the implied warranty of
23 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files
24 GIMPACT-LICENSE-LGPL.TXT and GIMPACT-LICENSE-BSD.TXT for more details.
25
26-----------------------------------------------------------------------------
27*/
28
29#include "GIMPACT/gim_contact.h"
30
31void gim_merge_contacts(GDYNAMIC_ARRAY * source_contacts,
32 GDYNAMIC_ARRAY * dest_contacts)
33{
34 dest_contacts->m_size = 0;
35
36 GUINT source_count = source_contacts->m_size;
37 GIM_CONTACT * psource_contacts = GIM_DYNARRAY_POINTER(GIM_CONTACT,(*source_contacts));
38 //create keys
39 GIM_RSORT_TOKEN * keycontacts = (GIM_RSORT_TOKEN * )gim_alloc(sizeof(GIM_RSORT_TOKEN)*source_count);
40
41 GUINT i;
42 for(i=0;i<source_count;i++)
43 {
44 keycontacts[i].m_value = i;
45 GIM_CALC_KEY_CONTACT(psource_contacts[i].m_point,keycontacts[i].m_key);
46 }
47
48 //sort keys
49 GIM_QUICK_SORT_ARRAY(GIM_RSORT_TOKEN , keycontacts, source_count, RSORT_TOKEN_COMPARATOR,GIM_DEF_EXCHANGE_MACRO);
50
51 // Merge contacts
52 GIM_CONTACT * pcontact = 0;
53 GIM_CONTACT * scontact = 0;
54 GUINT key,last_key=0;
55
56 for(i=0;i<source_contacts->m_size;i++)
57 {
58 key = keycontacts[i].m_key;
59 scontact = &psource_contacts[keycontacts[i].m_value];
60
61 if(i>0 && last_key == key)
62 {
63 //merge contact
64 if(pcontact->m_depth > scontact->m_depth + CONTACT_DIFF_EPSILON)
65 {
66 GIM_COPY_CONTACTS(pcontact, scontact);
67 }
68 }
69 else
70 {//add new contact
71 GIM_DYNARRAY_PUSH_EMPTY(GIM_CONTACT,(*dest_contacts));
72 pcontact = GIM_DYNARRAY_POINTER_LAST(GIM_CONTACT,(*dest_contacts));
73 GIM_COPY_CONTACTS(pcontact, scontact);
74 }
75 last_key = key;
76 }
77 gim_free(keycontacts,0);
78}
79
80void gim_merge_contacts_unique(GDYNAMIC_ARRAY * source_contacts,
81 GDYNAMIC_ARRAY * dest_contacts)
82{
83 dest_contacts->m_size = 0;
84 //Traverse the source contacts
85 GUINT source_count = source_contacts->m_size;
86 if(source_count==0) return;
87
88 GIM_CONTACT * psource_contacts = GIM_DYNARRAY_POINTER(GIM_CONTACT,(*source_contacts));
89
90 //add the unique contact
91 GIM_CONTACT * pcontact = 0;
92 GIM_DYNARRAY_PUSH_EMPTY(GIM_CONTACT,(*dest_contacts));
93 pcontact = GIM_DYNARRAY_POINTER_LAST(GIM_CONTACT,(*dest_contacts));
94 //set the first contact
95 GIM_COPY_CONTACTS(pcontact, psource_contacts);
96
97 if(source_count==1) return;
98 //scale the first contact
99 VEC_SCALE(pcontact->m_normal,pcontact->m_depth,pcontact->m_normal);
100
101 psource_contacts++;
102
103 //Average the contacts
104 GUINT i;
105 for(i=1;i<source_count;i++)
106 {
107 VEC_SUM(pcontact->m_point,pcontact->m_point,psource_contacts->m_point);
108 VEC_ACCUM(pcontact->m_normal,psource_contacts->m_depth,psource_contacts->m_normal);
109 psource_contacts++;
110 }
111
112 GREAL divide_average = 1.0f/((GREAL)source_count);
113
114 VEC_SCALE(pcontact->m_point,divide_average,pcontact->m_point);
115
116 pcontact->m_depth = VEC_DOT(pcontact->m_normal,pcontact->m_normal)*divide_average;
117 GIM_SQRT(pcontact->m_depth,pcontact->m_depth);
118
119 VEC_NORMALIZE(pcontact->m_normal);
120
121 /*GREAL normal_len;
122 VEC_INV_LENGTH(pcontact->m_normal,normal_len);
123 VEC_SCALE(pcontact->m_normal,normal_len,pcontact->m_normal);
124
125 //Deep = LEN(normal)/SQRT(source_count)
126 GIM_SQRT(divide_average,divide_average);
127 pcontact->m_depth = divide_average/normal_len;
128 */
129}
130
131
132
diff --git a/libraries/ode-0.9/GIMPACT/src/gim_math.cpp b/libraries/ode-0.9/GIMPACT/src/gim_math.cpp
new file mode 100644
index 0000000..18efb2c
--- /dev/null
+++ b/libraries/ode-0.9/GIMPACT/src/gim_math.cpp
@@ -0,0 +1,60 @@
1/*
2-----------------------------------------------------------------------------
3This source file is part of GIMPACT Library.
4
5For the latest info, see http://gimpact.sourceforge.net/
6
7Copyright (c) 2006 Francisco Leon. C.C. 80087371.
8email: projectileman@yahoo.com
9
10 This library is free software; you can redistribute it and/or
11 modify it under the terms of EITHER:
12 (1) The GNU Lesser General Public License as published by the Free
13 Software Foundation; either version 2.1 of the License, or (at
14 your option) any later version. The text of the GNU Lesser
15 General Public License is included with this library in the
16 file GIMPACT-LICENSE-LGPL.TXT.
17 (2) The BSD-style license that is included with this library in
18 the file GIMPACT-LICENSE-BSD.TXT.
19
20 This library is distributed in the hope that it will be useful,
21 but WITHOUT ANY WARRANTY; without even the implied warranty of
22 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files
23 GIMPACT-LICENSE-LGPL.TXT and GIMPACT-LICENSE-BSD.TXT for more details.
24
25-----------------------------------------------------------------------------
26*/
27
28
29#include "GIMPACT/gim_math.h"
30#include "stdlib.h"
31#include "time.h"
32
33
34GREAL gim_inv_sqrt(GREAL f)
35{
36 GREAL r;
37 GIM_INV_SQRT(f,r);
38 return r;
39}
40
41GREAL gim_sqrt(GREAL f)
42{
43 GREAL r;
44 GIM_SQRT(f,r);
45 return r;
46}
47
48//!Initializes mathematical functions
49void gim_init_math()
50{
51 srand( static_cast< unsigned int >( time( 0 ) ) );
52}
53
54//! Generates an unit random
55GREAL gim_unit_random()
56{
57 GREAL rn = static_cast< GREAL >( rand() );
58 rn/=(GREAL)RAND_MAX;
59 return rn;
60}
diff --git a/libraries/ode-0.9/GIMPACT/src/gim_memory.cpp b/libraries/ode-0.9/GIMPACT/src/gim_memory.cpp
new file mode 100644
index 0000000..247565a
--- /dev/null
+++ b/libraries/ode-0.9/GIMPACT/src/gim_memory.cpp
@@ -0,0 +1,848 @@
1
2/*
3-----------------------------------------------------------------------------
4This source file is part of GIMPACT Library.
5
6For the latest info, see http://gimpact.sourceforge.net/
7
8Copyright (c) 2006 Francisco Leon. C.C. 80087371.
9email: projectileman@yahoo.com
10
11 This library is free software; you can redistribute it and/or
12 modify it under the terms of EITHER:
13 (1) The GNU Lesser General Public License as published by the Free
14 Software Foundation; either version 2.1 of the License, or (at
15 your option) any later version. The text of the GNU Lesser
16 General Public License is included with this library in the
17 file GIMPACT-LICENSE-LGPL.TXT.
18 (2) The BSD-style license that is included with this library in
19 the file GIMPACT-LICENSE-BSD.TXT.
20
21 This library is distributed in the hope that it will be useful,
22 but WITHOUT ANY WARRANTY; without even the implied warranty of
23 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files
24 GIMPACT-LICENSE-LGPL.TXT and GIMPACT-LICENSE-BSD.TXT for more details.
25
26-----------------------------------------------------------------------------
27*/
28
29
30#include "GIMPACT/gim_memory.h"
31#include "stdlib.h"
32#include "malloc.h"
33//#include "mm_malloc.h"
34
35static gim_alloc_function *g_allocfn = 0;
36static gim_alloca_function *g_allocafn = 0;
37static gim_realloc_function *g_reallocfn = 0;
38static gim_free_function *g_freefn = 0;
39
40// buffer managers
41#define MAX_BUFFER_MANAGERS 16
42static GBUFFER_MANAGER_DATA g_buffer_managers[MAX_BUFFER_MANAGERS];
43static GUINT g_buffer_managers_count = 0;
44
45#define VALIDATE_BUFFER_MANAGER(buffer_manager_id)\
46 if(buffer_manager_id>=MAX_BUFFER_MANAGERS) return G_BUFFER_OP_INVALID;\
47 GBUFFER_MANAGER_DATA * bm_data;\
48 gim_get_buffer_manager_data(buffer_manager_id,&bm_data);\
49 if(bm_data == 0) return G_BUFFER_OP_INVALID;\
50
51#define VALIDATE_BUFFER_ID_PT(buffer_id)\
52 VALIDATE_BUFFER_MANAGER(buffer_id->m_buffer_manager_id)\
53 if(buffer_id->m_buffer_id>=bm_data->m_buffer_array.m_size) return G_BUFFER_OP_INVALID;\
54 GBUFFER_DATA * pbuffer = GIM_DYNARRAY_POINTER(GBUFFER_DATA,bm_data->m_buffer_array);\
55 pbuffer += buffer_id->m_buffer_id;\
56 if(pbuffer->m_buffer_handle==0) return G_BUFFER_OP_INVALID;\
57
58
59void GIM_BUFFER_ARRAY_DESTROY(GBUFFER_ARRAY & array_data)
60{
61 gim_buffer_array_unlock(&array_data);
62 gim_buffer_free(&(array_data).m_buffer_id);
63}
64
65void GIM_DYNARRAY_DESTROY(GDYNAMIC_ARRAY & array_data)
66{
67 if(array_data.m_pdata != 0)
68 {
69 gim_free(array_data.m_pdata,0);
70 array_data.m_reserve_size = 0;
71 array_data.m_size = 0;
72 array_data.m_pdata = 0;
73 }
74}
75
76void gim_set_alloc_handler (gim_alloc_function *fn)
77{
78 g_allocfn = fn;
79}
80
81void gim_set_alloca_handler (gim_alloca_function *fn)
82{
83 g_allocafn = fn;
84}
85
86void gim_set_realloc_handler (gim_realloc_function *fn)
87{
88 g_reallocfn = fn;
89}
90
91void gim_set_free_handler (gim_free_function *fn)
92{
93 g_freefn = fn;
94}
95
96gim_alloc_function *gim_get_alloc_handler()
97{
98 return g_allocfn;
99}
100
101gim_alloca_function *gim_get_alloca_handler()
102{
103 return g_allocafn;
104}
105
106
107gim_realloc_function *gim_get_realloc_handler ()
108{
109 return g_reallocfn;
110}
111
112
113gim_free_function *gim_get_free_handler ()
114{
115 return g_freefn;
116}
117
118
119void * gim_alloc(size_t size)
120{
121 void * ptr = 0;
122 ptr = malloc(size);
123 /*if (g_allocfn) ptr = g_allocfn(size); else ptr = malloc(size);//_mm_malloc(size,0);*/
124 if(ptr==0)
125 {
126 float * fp = 0;
127 *fp = 0.0f;
128 }
129 return ptr;
130}
131
132void * gim_alloca(size_t size)
133{
134 if (g_allocafn) return g_allocafn(size); else return alloca(size);
135}
136
137
138void * gim_realloc(void *ptr, size_t oldsize, size_t newsize)
139{
140 /*if (g_reallocfn) return g_reallocfn(ptr,oldsize,newsize);
141 else return realloc(ptr,newsize);*/
142 //return realloc(ptr,newsize);
143 void * newptr = gim_alloc(newsize);
144 size_t copysize = newsize> oldsize? oldsize: newsize;
145 memcpy(newptr,ptr,copysize);
146 gim_free(ptr,oldsize);
147 return newptr;
148}
149
150void gim_free(void *ptr, size_t size)
151{
152 if (!ptr) return;
153 if (g_freefn)
154 {
155 g_freefn(ptr,size);
156 }
157 else
158 {
159 free(ptr);//_mm_free(ptr);
160 }
161}
162
163///******************************* BUFFER MANAGERS ******************************///
164
165//!** Basic buffer prototyoe functions
166
167GUINT _system_buffer_alloc_function(GUINT size,int usage)
168{
169 void * newdata = gim_alloc(size);
170 memset(newdata,0,size);
171 return (GUINT)(newdata);
172}
173
174GUINT _system_buffer_alloc_data_function(const void * pdata,GUINT size,int usage)
175{
176 void * newdata = gim_alloc(size);
177 memcpy(newdata,pdata,size);
178 return (GUINT)(newdata);
179}
180
181GUINT _system_buffer_realloc_function(GUINT buffer_handle,GUINT oldsize,int old_usage,GUINT newsize,int new_usage)
182{
183 void * newdata = gim_realloc((void *)buffer_handle,oldsize,newsize);
184 return (GUINT)(newdata);
185}
186
187void _system_buffer_free_function(GUINT buffer_handle,GUINT size)
188{
189 gim_free((void*)buffer_handle,size);
190}
191
192char * _system_lock_buffer_function(GUINT buffer_handle,int access)
193{
194 return (char * )(buffer_handle);
195}
196
197
198void _system_unlock_buffer_function(GUINT buffer_handle)
199{
200}
201
202void _system_download_from_buffer_function(
203 GUINT source_buffer_handle,
204 GUINT source_pos,
205 void * destdata,
206 GUINT copysize)
207{
208 char * pdata;
209 pdata = (char *)source_buffer_handle;
210 memcpy(destdata,pdata+source_pos,copysize);
211}
212
213void _system_upload_to_buffer_function(
214 GUINT dest_buffer_handle,
215 GUINT dest_pos,
216 void * sourcedata,
217 GUINT copysize)
218{
219 char * pdata;
220 pdata = (char * )dest_buffer_handle;
221 memcpy(pdata+dest_pos,sourcedata,copysize);
222}
223
224void _system_copy_buffers_function(
225 GUINT source_buffer_handle,
226 GUINT source_pos,
227 GUINT dest_buffer_handle,
228 GUINT dest_pos,
229 GUINT copysize)
230{
231 char * pdata1,*pdata2;
232 pdata1 = (char *)source_buffer_handle;
233 pdata2 = (char *)dest_buffer_handle;
234 memcpy(pdata2+dest_pos,pdata1+source_pos,copysize);
235}
236
237GUINT _shared_buffer_alloc_function(GUINT size,int usage)
238{
239 return 0;
240}
241
242GUINT _shared_buffer_alloc_data_function(const void * pdata,GUINT size,int usage)
243{
244 return (GUINT)pdata;
245}
246
247GUINT _shared_buffer_realloc_function(GUINT buffer_handle,GUINT oldsize,int old_usage,GUINT newsize,int new_usage)
248{
249 return 0;
250}
251
252void _shared_buffer_free_function(GUINT buffer_handle,GUINT size)
253{
254}
255
256//!** Buffer manager operations
257void gim_create_buffer_manager(GBUFFER_MANAGER_PROTOTYPE * prototype,GUINT buffer_manager_id)
258{
259 GBUFFER_MANAGER_DATA * bm_data;
260 bm_data = &g_buffer_managers[buffer_manager_id];
261
262 if(bm_data->m_active==0)
263 {
264 if(g_buffer_managers_count<=buffer_manager_id)
265 {
266 g_buffer_managers_count = buffer_manager_id+1;
267 }
268 }
269 else
270 {
271 gim_destroy_buffer_manager(buffer_manager_id);
272 }
273 bm_data->m_active = 1;
274 //CREATE ARRAYS
275 GIM_DYNARRAY_CREATE(GBUFFER_DATA,bm_data->m_buffer_array,G_ARRAY_GROW_SIZE);
276 GIM_DYNARRAY_CREATE(GUINT,bm_data->m_free_positions,G_ARRAY_GROW_SIZE);
277 //INIT PROTOTYPE
278 bm_data->m_prototype.alloc_data_fn = prototype->alloc_data_fn;
279 bm_data->m_prototype.alloc_fn = prototype->alloc_fn;
280 bm_data->m_prototype.copy_buffers_fn = prototype->copy_buffers_fn;
281 bm_data->m_prototype.download_from_buffer_fn = prototype->download_from_buffer_fn;
282 bm_data->m_prototype.free_fn = prototype->free_fn;
283 bm_data->m_prototype.lock_buffer_fn = prototype->lock_buffer_fn;
284 bm_data->m_prototype.realloc_fn = prototype->realloc_fn;
285 bm_data->m_prototype.unlock_buffer_fn = prototype->unlock_buffer_fn;
286 bm_data->m_prototype.upload_to_buffer_fn = prototype->upload_to_buffer_fn;
287}
288
289GUINT gim_get_buffer_manager_count()
290{
291 return g_buffer_managers_count;
292}
293void gim_destroy_buffer_manager(GUINT buffer_manager_id)
294{
295 GBUFFER_MANAGER_DATA * bm_data;
296 gim_get_buffer_manager_data(buffer_manager_id,&bm_data);
297 if(bm_data == 0) return;
298 //Destroy all buffers
299
300 GBUFFER_DATA * buffers = GIM_DYNARRAY_POINTER(GBUFFER_DATA,bm_data->m_buffer_array);
301 GUINT i, buffer_count = bm_data->m_buffer_array.m_size;
302 for (i=0;i<buffer_count ;i++ )
303 {
304 if(buffers[i].m_buffer_handle!=0) //Is active
305 {
306 // free handle
307 bm_data->m_prototype.free_fn(buffers[i].m_buffer_handle,buffers[i].m_size);
308 }
309 }
310
311 //destroy buffer array
312 GIM_DYNARRAY_DESTROY(bm_data->m_buffer_array);
313 //destroy free positions
314 GIM_DYNARRAY_DESTROY(bm_data->m_free_positions);
315 //Mark as innactive
316 bm_data->m_active = 0;
317}
318void gim_get_buffer_manager_data(GUINT buffer_manager_id,GBUFFER_MANAGER_DATA ** pbm_data)
319{
320 GBUFFER_MANAGER_DATA * bm_data;
321 bm_data = &g_buffer_managers[buffer_manager_id];
322
323 if(bm_data->m_active==0)
324 {
325 *pbm_data = 0;
326 }
327 else
328 {
329 *pbm_data = bm_data;
330 }
331}
332
333void gim_init_buffer_managers()
334{
335 GUINT i;
336 for (i=0;i<MAX_BUFFER_MANAGERS;i++)
337 {
338 g_buffer_managers[i].m_active = 0;
339 g_buffer_managers[i].m_buffer_array.m_pdata = 0;
340 g_buffer_managers[i].m_buffer_array.m_reserve_size = 0;
341 g_buffer_managers[i].m_buffer_array.m_size = 0;
342 g_buffer_managers[i].m_free_positions.m_pdata = 0;
343 g_buffer_managers[i].m_free_positions.m_reserve_size = 0;
344 g_buffer_managers[i].m_free_positions.m_size = 0;
345 }
346 g_buffer_managers_count = 0;
347 // Add the two most important buffer managers
348 GBUFFER_MANAGER_PROTOTYPE prototype;
349
350 //add system buffer manager
351 prototype.alloc_data_fn = _system_buffer_alloc_data_function;
352 prototype.alloc_fn = _system_buffer_alloc_function;
353 prototype.copy_buffers_fn = _system_copy_buffers_function;
354 prototype.download_from_buffer_fn = _system_download_from_buffer_function;
355 prototype.free_fn = _system_buffer_free_function;
356 prototype.lock_buffer_fn = _system_lock_buffer_function;
357 prototype.realloc_fn = _system_buffer_realloc_function;
358 prototype.unlock_buffer_fn = _system_unlock_buffer_function;
359 prototype.upload_to_buffer_fn = _system_upload_to_buffer_function;
360
361 gim_create_buffer_manager(&prototype,G_BUFFER_MANAGER_SYSTEM );
362
363 //add zhared buffer manager
364 prototype.alloc_data_fn = _shared_buffer_alloc_data_function;
365 prototype.alloc_fn = _shared_buffer_alloc_function;
366 prototype.free_fn = _shared_buffer_free_function;
367 gim_create_buffer_manager(&prototype,G_BUFFER_MANAGER_SHARED);
368}
369
370void gim_terminate_buffer_managers()
371{
372 GUINT i;
373 for (i=0;i<g_buffer_managers_count;i++)
374 {
375 gim_destroy_buffer_manager(i);
376 }
377 g_buffer_managers_count = 0;
378}
379
380//!** Nuffer operations
381
382void GET_AVALIABLE_BUFFER_ID(GBUFFER_MANAGER_DATA * buffer_manager, GUINT & buffer_id)
383{
384 if(buffer_manager->m_free_positions.m_size>0)\
385 {
386 GUINT * _pointer = GIM_DYNARRAY_POINTER(GUINT,buffer_manager->m_free_positions);
387 buffer_id = _pointer[buffer_manager->m_free_positions.m_size-1];
388 GIM_DYNARRAY_POP_ITEM(buffer_manager->m_free_positions);
389 }
390 else
391 {
392 buffer_id = buffer_manager->m_buffer_array.m_size;
393 GIM_DYNARRAY_PUSH_EMPTY(GBUFFER_DATA,buffer_manager->m_buffer_array);
394 }
395}
396
397GINT _validate_buffer_id(GBUFFER_ID * buffer_id,GBUFFER_DATA ** ppbuffer,GBUFFER_MANAGER_DATA ** pbm_data)
398{
399 VALIDATE_BUFFER_ID_PT(buffer_id)
400 *ppbuffer = pbuffer;
401 *pbm_data = bm_data;
402 return G_BUFFER_OP_SUCCESS;
403}
404
405GUINT gim_create_buffer(
406 GUINT buffer_manager_id,
407 GUINT buffer_size,
408 int usage,
409 GBUFFER_ID * buffer_id)
410{
411 VALIDATE_BUFFER_MANAGER(buffer_manager_id)
412
413 GUINT newbufferhandle = bm_data->m_prototype.alloc_fn(buffer_size,usage);
414 if(newbufferhandle==0) return G_BUFFER_OP_INVALID;
415
416 GET_AVALIABLE_BUFFER_ID(bm_data,buffer_id->m_buffer_id);
417 buffer_id->m_buffer_manager_id = buffer_manager_id;
418
419 GBUFFER_DATA * pbuffer = GIM_DYNARRAY_POINTER(GBUFFER_DATA,bm_data->m_buffer_array);
420 pbuffer += buffer_id->m_buffer_id ;
421 pbuffer->m_buffer_handle = newbufferhandle;
422 pbuffer->m_size = buffer_size;
423 pbuffer->m_usage = usage;
424 pbuffer->m_lock_count = 0;
425 pbuffer->m_refcount = 0;
426 pbuffer->m_mapped_pointer = 0;
427
428 //set shadow buffer if needed
429
430 if(usage == G_MU_STATIC_READ ||
431 usage == G_MU_STATIC_READ_DYNAMIC_WRITE||
432 usage == G_MU_STATIC_READ_DYNAMIC_WRITE_COPY)
433 {
434 gim_create_common_buffer(buffer_size,&pbuffer->m_shadow_buffer);
435 }
436 else
437 {
438 pbuffer->m_shadow_buffer.m_buffer_id = G_UINT_INFINITY;
439 pbuffer->m_shadow_buffer.m_buffer_manager_id = G_UINT_INFINITY;
440 }
441 return G_BUFFER_OP_SUCCESS;
442}
443
444
445GUINT gim_create_buffer_from_data(
446 GUINT buffer_manager_id,
447 const void * pdata,
448 GUINT buffer_size,
449 int usage,
450 GBUFFER_ID * buffer_id)
451{
452 VALIDATE_BUFFER_MANAGER(buffer_manager_id)
453
454 GUINT newbufferhandle = bm_data->m_prototype.alloc_data_fn(pdata,buffer_size,usage);
455 if(newbufferhandle==0) return G_BUFFER_OP_INVALID;
456
457 GET_AVALIABLE_BUFFER_ID(bm_data,buffer_id->m_buffer_id);
458 buffer_id->m_buffer_manager_id = buffer_manager_id;
459
460 GBUFFER_DATA * pbuffer = GIM_DYNARRAY_POINTER(GBUFFER_DATA,bm_data->m_buffer_array);
461 pbuffer += buffer_id->m_buffer_id ;
462 pbuffer->m_buffer_handle = newbufferhandle;
463 pbuffer->m_size = buffer_size;
464 pbuffer->m_usage = usage;
465 pbuffer->m_lock_count = 0;
466 pbuffer->m_mapped_pointer = 0;
467 pbuffer->m_refcount = 0;
468
469 //set shadow buffer if needed
470
471 if(usage == G_MU_STATIC_READ ||
472 usage == G_MU_STATIC_READ_DYNAMIC_WRITE||
473 usage == G_MU_STATIC_READ_DYNAMIC_WRITE_COPY)
474 {
475 gim_create_common_buffer_from_data(pdata,buffer_size,&pbuffer->m_shadow_buffer);
476 }
477 else
478 {
479 pbuffer->m_shadow_buffer.m_buffer_id = G_UINT_INFINITY;
480 pbuffer->m_shadow_buffer.m_buffer_manager_id = G_UINT_INFINITY;
481 }
482 return G_BUFFER_OP_SUCCESS;
483}
484
485GUINT gim_create_common_buffer(GUINT buffer_size, GBUFFER_ID * buffer_id)
486{
487 return gim_create_buffer(G_BUFFER_MANAGER_SYSTEM,buffer_size,G_MU_DYNAMIC_READ_WRITE,buffer_id);
488}
489
490GUINT gim_create_common_buffer_from_data(
491 const void * pdata, GUINT buffer_size, GBUFFER_ID * buffer_id)
492{
493 return gim_create_buffer_from_data(G_BUFFER_MANAGER_SYSTEM,pdata,buffer_size,G_MU_DYNAMIC_READ_WRITE,buffer_id);
494}
495
496GUINT gim_create_shared_buffer_from_data(
497 const void * pdata, GUINT buffer_size, GBUFFER_ID * buffer_id)
498{
499 return gim_create_buffer_from_data(G_BUFFER_MANAGER_SHARED,pdata,buffer_size,G_MU_DYNAMIC_READ_WRITE,buffer_id);
500}
501
502GINT gim_buffer_realloc(GBUFFER_ID * buffer_id,GUINT newsize)
503{
504 VALIDATE_BUFFER_ID_PT(buffer_id)
505 if(pbuffer->m_lock_count>0) return G_BUFFER_OP_INVALID;
506 GUINT newhandle = bm_data->m_prototype.realloc_fn(pbuffer->m_buffer_handle,pbuffer->m_size,pbuffer->m_usage,newsize,pbuffer->m_usage);
507 if(newhandle==0) return G_BUFFER_OP_INVALID;
508 pbuffer->m_buffer_handle = newhandle;
509 //realloc shadow buffer if any
510 gim_buffer_realloc(&pbuffer->m_shadow_buffer,newsize);
511 return G_BUFFER_OP_SUCCESS;
512}
513
514GINT gim_buffer_add_ref(GBUFFER_ID * buffer_id)
515{
516 VALIDATE_BUFFER_ID_PT(buffer_id)
517 pbuffer->m_refcount++;
518 return G_BUFFER_OP_SUCCESS;
519}
520
521GINT gim_buffer_free(GBUFFER_ID * buffer_id)
522{
523 VALIDATE_BUFFER_ID_PT(buffer_id)
524 if(pbuffer->m_lock_count>0) return G_BUFFER_OP_INVALID;
525 if(pbuffer->m_refcount>0) pbuffer->m_refcount--;
526 if(pbuffer->m_refcount>0) return G_BUFFER_OP_STILLREFCOUNTED;
527
528 bm_data->m_prototype.free_fn(pbuffer->m_buffer_handle,pbuffer->m_size);
529 //destroy shadow buffer if needed
530 gim_buffer_free(&pbuffer->m_shadow_buffer);
531 // Obtain a free slot index for a new buffer
532 GIM_DYNARRAY_PUSH_ITEM(GUINT,bm_data->m_free_positions,buffer_id->m_buffer_id);
533 pbuffer->m_buffer_handle = 0;
534 pbuffer->m_size = 0;
535 pbuffer->m_shadow_buffer.m_buffer_id = G_UINT_INFINITY;
536 pbuffer->m_shadow_buffer.m_buffer_manager_id = G_UINT_INFINITY;
537 return G_BUFFER_OP_SUCCESS;
538}
539
540GINT gim_lock_buffer(GBUFFER_ID * buffer_id,int access,char ** map_pointer)
541{
542 VALIDATE_BUFFER_ID_PT(buffer_id)
543 if(pbuffer->m_lock_count>0)
544 {
545 if(pbuffer->m_access!=access) return G_BUFFER_OP_INVALID;
546 pbuffer->m_lock_count++;
547 *map_pointer = pbuffer->m_mapped_pointer;
548 return G_BUFFER_OP_SUCCESS;
549 }
550
551 pbuffer->m_access = access;
552
553 GUINT result;
554 if(pbuffer->m_usage==G_MU_STATIC_WRITE)
555 {
556 *map_pointer = 0;///no access
557 return G_BUFFER_OP_INVALID;
558 }
559 else if(pbuffer->m_usage==G_MU_STATIC_READ)
560 {
561 if(pbuffer->m_access == G_MA_READ_ONLY)
562 {
563 result = gim_lock_buffer(&pbuffer->m_shadow_buffer,access,map_pointer);
564 if(result!= G_BUFFER_OP_SUCCESS) return G_BUFFER_OP_INVALID;
565 pbuffer->m_mapped_pointer = *map_pointer;
566 pbuffer->m_lock_count++;
567 }
568 else
569 {
570 *map_pointer = 0;
571 return G_BUFFER_OP_INVALID;
572 }
573 }
574 else if(pbuffer->m_usage==G_MU_STATIC_READ_DYNAMIC_WRITE)
575 {
576 if(pbuffer->m_access == G_MA_READ_ONLY)
577 {
578 result = gim_lock_buffer(&pbuffer->m_shadow_buffer,access,map_pointer);
579 if(result!= G_BUFFER_OP_SUCCESS) return G_BUFFER_OP_INVALID;
580 pbuffer->m_mapped_pointer = *map_pointer;
581 pbuffer->m_lock_count++;
582 }
583 else if(pbuffer->m_access == G_MA_WRITE_ONLY)
584 {
585 pbuffer->m_mapped_pointer = bm_data->m_prototype.lock_buffer_fn(pbuffer->m_buffer_handle,access);
586 *map_pointer = pbuffer->m_mapped_pointer;
587 pbuffer->m_lock_count++;
588 }
589 else if(pbuffer->m_access == G_MA_READ_WRITE)
590 {
591 *map_pointer = 0;
592 return G_BUFFER_OP_INVALID;
593 }
594 }
595 else if(pbuffer->m_usage==G_MU_STATIC_READ_DYNAMIC_WRITE_COPY)
596 {
597 result = gim_lock_buffer(&pbuffer->m_shadow_buffer,access,map_pointer);
598 if(result!= G_BUFFER_OP_SUCCESS) return G_BUFFER_OP_INVALID;
599 pbuffer->m_mapped_pointer = *map_pointer;
600 pbuffer->m_lock_count++;
601 }
602 else if(pbuffer->m_usage==G_MU_STATIC_WRITE_DYNAMIC_READ)
603 {
604 if(pbuffer->m_access == G_MA_READ_ONLY)
605 {
606 pbuffer->m_mapped_pointer = bm_data->m_prototype.lock_buffer_fn(pbuffer->m_buffer_handle,access);
607 *map_pointer = pbuffer->m_mapped_pointer;
608 pbuffer->m_lock_count++;
609 }
610 else
611 {
612 *map_pointer = 0;
613 return G_BUFFER_OP_INVALID;
614 }
615 }
616 else if(pbuffer->m_usage==G_MU_DYNAMIC_READ_WRITE)
617 {
618 pbuffer->m_mapped_pointer = bm_data->m_prototype.lock_buffer_fn(pbuffer->m_buffer_handle,access);
619 *map_pointer = pbuffer->m_mapped_pointer;
620 pbuffer->m_lock_count++;
621 }
622 return G_BUFFER_OP_SUCCESS;
623}
624
625GINT gim_unlock_buffer(GBUFFER_ID * buffer_id)
626{
627 VALIDATE_BUFFER_ID_PT(buffer_id)
628 if(pbuffer->m_lock_count==0) return G_BUFFER_OP_INVALID;
629
630 if(pbuffer->m_lock_count>1)
631 {
632 pbuffer->m_lock_count--;
633 return G_BUFFER_OP_SUCCESS;
634 }
635
636
637 GUINT result;
638 if(pbuffer->m_usage==G_MU_STATIC_WRITE)
639 {
640 pbuffer->m_mapped_pointer = 0;
641 pbuffer->m_lock_count=0;
642 return G_BUFFER_OP_INVALID;
643 }
644 else if(pbuffer->m_usage==G_MU_STATIC_READ)
645 {
646 if(pbuffer->m_access == G_MA_READ_ONLY)
647 {
648 result = gim_unlock_buffer(&pbuffer->m_shadow_buffer);
649 if(result!= G_BUFFER_OP_SUCCESS) return G_BUFFER_OP_INVALID;
650 pbuffer->m_mapped_pointer = 0;
651 pbuffer->m_lock_count=0;
652 }
653 else
654 {
655 pbuffer->m_mapped_pointer = 0;
656 pbuffer->m_lock_count=0;
657 return G_BUFFER_OP_INVALID;
658 }
659 }
660 else if(pbuffer->m_usage==G_MU_STATIC_READ_DYNAMIC_WRITE)
661 {
662 if(pbuffer->m_access == G_MA_READ_ONLY)
663 {
664 result = gim_unlock_buffer(&pbuffer->m_shadow_buffer);
665 if(result!= G_BUFFER_OP_SUCCESS) return G_BUFFER_OP_INVALID;
666 pbuffer->m_mapped_pointer = 0;
667 pbuffer->m_lock_count=0;
668 }
669 else if(pbuffer->m_access == G_MA_WRITE_ONLY)
670 {
671 bm_data->m_prototype.unlock_buffer_fn(pbuffer->m_buffer_handle);
672 pbuffer->m_mapped_pointer = 0;
673 pbuffer->m_lock_count=0;
674 }
675 else if(pbuffer->m_access == G_MA_READ_WRITE)
676 {
677 pbuffer->m_mapped_pointer = 0;
678 pbuffer->m_lock_count=0;
679 return G_BUFFER_OP_INVALID;
680 }
681 }
682 else if(pbuffer->m_usage==G_MU_STATIC_READ_DYNAMIC_WRITE_COPY)
683 {
684 result = gim_unlock_buffer(&pbuffer->m_shadow_buffer);
685 if(result!= G_BUFFER_OP_SUCCESS) return G_BUFFER_OP_INVALID;
686 pbuffer->m_mapped_pointer = 0;
687 pbuffer->m_lock_count=0;
688 if(pbuffer->m_access == G_MA_WRITE_ONLY||pbuffer->m_access == G_MA_READ_WRITE)
689 {
690 gim_copy_buffers(&pbuffer->m_shadow_buffer,0,buffer_id,0,pbuffer->m_size);
691 }
692 }
693 else if(pbuffer->m_usage==G_MU_STATIC_WRITE_DYNAMIC_READ)
694 {
695 if(pbuffer->m_access == G_MA_READ_ONLY)
696 {
697 bm_data->m_prototype.unlock_buffer_fn(pbuffer->m_buffer_handle);
698 pbuffer->m_mapped_pointer = 0;
699 pbuffer->m_lock_count=0;
700 }
701 else
702 {
703 pbuffer->m_mapped_pointer = 0;
704 pbuffer->m_lock_count=0;
705 return G_BUFFER_OP_INVALID;
706 }
707 }
708 else if(pbuffer->m_usage==G_MU_DYNAMIC_READ_WRITE)
709 {
710 bm_data->m_prototype.unlock_buffer_fn(pbuffer->m_buffer_handle);
711 pbuffer->m_mapped_pointer = 0;
712 pbuffer->m_lock_count=0;
713 }
714 return G_BUFFER_OP_SUCCESS;
715}
716
717GINT gim_get_buffer_size(GBUFFER_ID * buffer_id,GUINT * buffer_size)
718{
719 VALIDATE_BUFFER_ID_PT(buffer_id)
720 *buffer_size = pbuffer->m_size;
721 return G_BUFFER_OP_SUCCESS;
722}
723
724GINT gim_get_buffer_is_locked(GBUFFER_ID * buffer_id,GUINT * lock_count)
725{
726 VALIDATE_BUFFER_ID_PT(buffer_id)
727 *lock_count = pbuffer->m_lock_count;
728 return G_BUFFER_OP_SUCCESS;
729}
730
731
732GINT gim_download_from_buffer(
733 GBUFFER_ID * buffer_id,
734 GUINT source_pos,
735 void * destdata,
736 GUINT copysize)
737{
738 VALIDATE_BUFFER_ID_PT(buffer_id)
739 bm_data->m_prototype.download_from_buffer_fn(
740 pbuffer->m_buffer_handle,source_pos,destdata,copysize);
741 return G_BUFFER_OP_SUCCESS;
742}
743
744GINT gim_upload_to_buffer(
745 GBUFFER_ID * buffer_id,
746 GUINT dest_pos,
747 void * sourcedata,
748 GUINT copysize)
749{
750 VALIDATE_BUFFER_ID_PT(buffer_id)
751 bm_data->m_prototype.upload_to_buffer_fn(
752 pbuffer->m_buffer_handle,dest_pos,sourcedata,copysize);
753 return G_BUFFER_OP_SUCCESS;
754}
755
756GINT gim_copy_buffers(
757 GBUFFER_ID * source_buffer_id,
758 GUINT source_pos,
759 GBUFFER_ID * dest_buffer_id,
760 GUINT dest_pos,
761 GUINT copysize)
762{
763 GBUFFER_MANAGER_DATA * bm_data1,* bm_data2;
764 GBUFFER_DATA * pbuffer1, * pbuffer2;
765 void * tempdata;
766 if(_validate_buffer_id(source_buffer_id,&pbuffer1,&bm_data1)!= G_BUFFER_OP_SUCCESS) return G_BUFFER_OP_INVALID;
767
768 if(_validate_buffer_id(dest_buffer_id,&pbuffer2,&bm_data2)!= G_BUFFER_OP_SUCCESS) return G_BUFFER_OP_INVALID;
769
770 if((source_buffer_id->m_buffer_manager_id == dest_buffer_id->m_buffer_manager_id)||
771 (source_buffer_id->m_buffer_manager_id == G_BUFFER_MANAGER_SYSTEM && dest_buffer_id->m_buffer_manager_id == G_BUFFER_MANAGER_SHARED)||
772 (source_buffer_id->m_buffer_manager_id == G_BUFFER_MANAGER_SHARED && dest_buffer_id->m_buffer_manager_id == G_BUFFER_MANAGER_SYSTEM)
773 )
774 {//smooth copy
775 bm_data1->m_prototype.copy_buffers_fn(pbuffer1->m_buffer_handle,source_pos,pbuffer2->m_buffer_handle,dest_pos,copysize);
776 }
777 else if(source_buffer_id->m_buffer_manager_id == G_BUFFER_MANAGER_SYSTEM || source_buffer_id->m_buffer_manager_id == G_BUFFER_MANAGER_SHARED)
778 {
779 //hard copy
780 tempdata = (void *)pbuffer1->m_buffer_handle;
781 //upload data
782 bm_data2->m_prototype.upload_to_buffer_fn(pbuffer2->m_buffer_handle,dest_pos,
783 tempdata,
784 copysize);
785 }
786 else
787 {
788 //very hard copy
789 void * tempdata = gim_alloc(copysize);
790 //download data
791 bm_data1->m_prototype.download_from_buffer_fn(pbuffer1->m_buffer_handle,source_pos,
792 tempdata,
793 copysize);
794
795 //upload data
796 bm_data2->m_prototype.upload_to_buffer_fn(pbuffer2->m_buffer_handle,dest_pos,
797 tempdata,
798 copysize);
799 //delete temp buffer
800 gim_free(tempdata,copysize);
801 }
802 return G_BUFFER_OP_SUCCESS;
803}
804
805GINT gim_buffer_array_lock(GBUFFER_ARRAY * array_data, int access)
806{
807 if(array_data->m_buffer_data != 0) return G_BUFFER_OP_SUCCESS;
808 GINT result = gim_lock_buffer(&array_data->m_buffer_id,access,&array_data->m_buffer_data);
809 if(result!= G_BUFFER_OP_SUCCESS) return result;
810 array_data->m_buffer_data += array_data->m_byte_offset;
811 return result;
812}
813
814GINT gim_buffer_array_unlock(GBUFFER_ARRAY * array_data)
815{
816 if(array_data->m_buffer_data == 0) return G_BUFFER_OP_SUCCESS;
817 GINT result = gim_unlock_buffer(&array_data->m_buffer_id);
818 if(result!= G_BUFFER_OP_SUCCESS) return result;
819 array_data->m_buffer_data = 0;
820 return result;
821}
822
823void gim_buffer_array_copy_ref(GBUFFER_ARRAY * source_data,GBUFFER_ARRAY * dest_data)
824{
825 dest_data->m_buffer_id.m_buffer_id = source_data->m_buffer_id.m_buffer_id;
826 dest_data->m_buffer_id.m_buffer_manager_id = source_data->m_buffer_id.m_buffer_manager_id;
827 dest_data->m_buffer_data = 0;
828 dest_data->m_byte_stride = source_data->m_byte_stride;
829 dest_data->m_byte_offset = source_data->m_byte_offset;
830 dest_data->m_element_count = source_data->m_element_count;
831 gim_buffer_add_ref(&dest_data->m_buffer_id);
832}
833
834void gim_buffer_array_copy_value(GBUFFER_ARRAY * source_data,GBUFFER_ARRAY * dest_data, GUINT buffer_manager_id,int usage)
835{
836 //Create new buffer
837 GUINT buffsize = source_data->m_element_count*source_data->m_byte_stride;
838 gim_create_buffer(buffer_manager_id,buffsize,usage,&dest_data->m_buffer_id);
839
840 //copy ref data
841 dest_data->m_buffer_data = 0;
842 dest_data->m_byte_stride = source_data->m_byte_stride;
843 dest_data->m_byte_offset = 0;
844 dest_data->m_element_count = source_data->m_element_count;
845 gim_buffer_add_ref(&dest_data->m_buffer_id);
846 //copy buffers
847 gim_copy_buffers(&source_data->m_buffer_id,source_data->m_byte_offset,&dest_data->m_buffer_id,0,buffsize);
848}
diff --git a/libraries/ode-0.9/GIMPACT/src/gim_tri_tri_overlap.cpp b/libraries/ode-0.9/GIMPACT/src/gim_tri_tri_overlap.cpp
new file mode 100644
index 0000000..5b4e08d
--- /dev/null
+++ b/libraries/ode-0.9/GIMPACT/src/gim_tri_tri_overlap.cpp
@@ -0,0 +1,251 @@
1
2/*
3-----------------------------------------------------------------------------
4This source file is part of GIMPACT Library.
5
6For the latest info, see http://gimpact.sourceforge.net/
7
8Copyright (c) 2006 Francisco Leon. C.C. 80087371.
9email: projectileman@yahoo.com
10
11 This library is free software; you can redistribute it and/or
12 modify it under the terms of EITHER:
13 (1) The GNU Lesser General Public License as published by the Free
14 Software Foundation; either version 2.1 of the License, or (at
15 your option) any later version. The text of the GNU Lesser
16 General Public License is included with this library in the
17 file GIMPACT-LICENSE-LGPL.TXT.
18 (2) The BSD-style license that is included with this library in
19 the file GIMPACT-LICENSE-BSD.TXT.
20
21 This library is distributed in the hope that it will be useful,
22 but WITHOUT ANY WARRANTY; without even the implied warranty of
23 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files
24 GIMPACT-LICENSE-LGPL.TXT and GIMPACT-LICENSE-BSD.TXT for more details.
25
26-----------------------------------------------------------------------------
27*/
28
29#include "GIMPACT/gim_trimesh.h"
30
31
32#define FABS(x) (float(fabs(x))) /* implement as is fastest on your machine */
33
34/* some macros */
35
36#define CLASSIFY_TRIPOINTS_BY_FACE(v1,v2,v3,faceplane,out_of_face)\
37{ \
38 _distances[0] = DISTANCE_PLANE_POINT(faceplane,v1);\
39 _distances[1] = _distances[0] * DISTANCE_PLANE_POINT(faceplane,v2);\
40 _distances[2] = _distances[0] * DISTANCE_PLANE_POINT(faceplane,v3); \
41 if(_distances[1]>0.0f && _distances[2]>0.0f)\
42 {\
43 out_of_face = 1;\
44 }\
45 else\
46 {\
47 out_of_face = 0;\
48 }\
49}\
50
51/* sort so that a<=b */
52#define SORT(a,b) \
53 if(a>b) \
54 { \
55 float c; \
56 c=a; \
57 a=b; \
58 b=c; \
59 }
60
61
62/* this edge to edge test is based on Franlin Antonio's gem:
63 "Faster Line Segment Intersection", in Graphics Gems III,
64 pp. 199-202 */
65#define EDGE_EDGE_TEST(V0,U0,U1) \
66 Bx=U0[i0]-U1[i0]; \
67 By=U0[i1]-U1[i1]; \
68 Cx=V0[i0]-U0[i0]; \
69 Cy=V0[i1]-U0[i1]; \
70 f=Ay*Bx-Ax*By; \
71 d=By*Cx-Bx*Cy; \
72 if((f>0 && d>=0 && d<=f) || (f<0 && d<=0 && d>=f)) \
73 { \
74 e=Ax*Cy-Ay*Cx; \
75 if(f>0) \
76 { \
77 if(e>=0 && e<=f) return 1; \
78 } \
79 else \
80 { \
81 if(e<=0 && e>=f) return 1; \
82 } \
83 }
84
85#define EDGE_AGAINST_TRI_EDGES(V0,V1,U0,U1,U2) \
86{ \
87 float Ax,Ay,Bx,By,Cx,Cy,e,d,f; \
88 Ax=V1[i0]-V0[i0]; \
89 Ay=V1[i1]-V0[i1]; \
90 /* test edge U0,U1 against V0,V1 */ \
91 EDGE_EDGE_TEST(V0,U0,U1); \
92 /* test edge U1,U2 against V0,V1 */ \
93 EDGE_EDGE_TEST(V0,U1,U2); \
94 /* test edge U2,U1 against V0,V1 */ \
95 EDGE_EDGE_TEST(V0,U2,U0); \
96}
97
98#define POINT_IN_TRI(V0,U0,U1,U2) \
99{ \
100 float a,b,c,d0,d1,d2; \
101 /* is T1 completly inside T2? */ \
102 /* check if V0 is inside tri(U0,U1,U2) */ \
103 a=U1[i1]-U0[i1]; \
104 b=-(U1[i0]-U0[i0]); \
105 c=-a*U0[i0]-b*U0[i1]; \
106 d0=a*V0[i0]+b*V0[i1]+c; \
107 \
108 a=U2[i1]-U1[i1]; \
109 b=-(U2[i0]-U1[i0]); \
110 c=-a*U1[i0]-b*U1[i1]; \
111 d1=a*V0[i0]+b*V0[i1]+c; \
112 \
113 a=U0[i1]-U2[i1]; \
114 b=-(U0[i0]-U2[i0]); \
115 c=-a*U2[i0]-b*U2[i1]; \
116 d2=a*V0[i0]+b*V0[i1]+c; \
117 if(d0*d1>0.0) \
118 { \
119 if(d0*d2>0.0) return 1; \
120 } \
121}
122
123int coplanar_tri_tri(GIM_TRIANGLE_DATA *tri1,
124 GIM_TRIANGLE_DATA *tri2)
125{
126 short i0,i1;
127 /* first project onto an axis-aligned plane, that maximizes the area */
128 /* of the triangles, compute indices: i0,i1. */
129 PLANE_MINOR_AXES(tri1->m_planes.m_planes[0], i0, i1);
130
131 /* test all edges of triangle 1 against the edges of triangle 2 */
132 EDGE_AGAINST_TRI_EDGES(tri1->m_vertices[0],tri1->m_vertices[1],tri2->m_vertices[0],tri2->m_vertices[1],tri2->m_vertices[2]);
133 EDGE_AGAINST_TRI_EDGES(tri1->m_vertices[1],tri1->m_vertices[2],tri2->m_vertices[0],tri2->m_vertices[1],tri2->m_vertices[2]);
134 EDGE_AGAINST_TRI_EDGES(tri1->m_vertices[2],tri1->m_vertices[0],tri2->m_vertices[0],tri2->m_vertices[1],tri2->m_vertices[2]);
135
136 /* finally, test if tri1 is totally contained in tri2 or vice versa */
137 POINT_IN_HULL(tri1->m_vertices[0],(&tri2->m_planes.m_planes[1]),3,i0);
138 if(i0==0) return 1;
139
140 POINT_IN_HULL(tri2->m_vertices[0],(&tri1->m_planes.m_planes[1]),3,i0);
141 if(i0==0) return 1;
142
143 return 0;
144}
145
146
147
148#define NEWCOMPUTE_INTERVALS(VV0,VV1,VV2,D0,D1,D2,D0D1,D0D2,A,B,C,X0,X1) \
149{ \
150 if(D0D1>0.0f) \
151 { \
152 /* here we know that D0D2<=0.0 */ \
153 /* that is D0, D1 are on the same side, D2 on the other or on the plane */ \
154 A=VV2; B=(VV0-VV2)*D2; C=(VV1-VV2)*D2; X0=D2-D0; X1=D2-D1; \
155 } \
156 else if(D0D2>0.0f)\
157 { \
158 /* here we know that d0d1<=0.0 */ \
159 A=VV1; B=(VV0-VV1)*D1; C=(VV2-VV1)*D1; X0=D1-D0; X1=D1-D2; \
160 } \
161 else if(D1*D2>0.0f || D0!=0.0f) \
162 { \
163 /* here we know that d0d1<=0.0 or that D0!=0.0 */ \
164 A=VV0; B=(VV1-VV0)*D0; C=(VV2-VV0)*D0; X0=D0-D1; X1=D0-D2; \
165 } \
166 else if(D1!=0.0f) \
167 { \
168 A=VV1; B=(VV0-VV1)*D1; C=(VV2-VV1)*D1; X0=D1-D0; X1=D1-D2; \
169 } \
170 else if(D2!=0.0f) \
171 { \
172 A=VV2; B=(VV0-VV2)*D2; C=(VV1-VV2)*D2; X0=D2-D0; X1=D2-D1; \
173 } \
174 else \
175 { \
176 /* triangles are coplanar */ \
177 return coplanar_tri_tri(tri1,tri2); \
178 } \
179}\
180
181
182
183int gim_triangle_triangle_overlap(
184 GIM_TRIANGLE_DATA *tri1,
185 GIM_TRIANGLE_DATA *tri2)
186{
187 vec3f _distances;
188 char out_of_face;
189 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);
190 if(out_of_face==1) return 0;
191
192 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);
193 if(out_of_face==1) return 0;
194
195
196 float du0=0,du1=0,du2=0,dv0=0,dv1=0,dv2=0;
197 float D[3];
198 float isect1[2], isect2[2];
199 float du0du1=0,du0du2=0,dv0dv1=0,dv0dv2=0;
200 short index;
201 float vp0,vp1,vp2;
202 float up0,up1,up2;
203 float bb,cc,max;
204
205 /* compute direction of intersection line */
206 VEC_CROSS(D,tri1->m_planes.m_planes[0],tri2->m_planes.m_planes[0]);
207
208 /* compute and index to the largest component of D */
209 max=(float)FABS(D[0]);
210 index=0;
211 bb=(float)FABS(D[1]);
212 cc=(float)FABS(D[2]);
213 if(bb>max) max=bb,index=1;
214 if(cc>max) max=cc,index=2;
215
216 /* this is the simplified projection onto L*/
217 vp0= tri1->m_vertices[0][index];
218 vp1= tri1->m_vertices[1][index];
219 vp2= tri1->m_vertices[2][index];
220
221 up0= tri2->m_vertices[0][index];
222 up1= tri2->m_vertices[1][index];
223 up2= tri2->m_vertices[2][index];
224
225 /* compute interval for triangle 1 */
226 float a,b,c,x0,x1;
227 NEWCOMPUTE_INTERVALS(vp0,vp1,vp2,dv0,dv1,dv2,dv0dv1,dv0dv2,a,b,c,x0,x1);
228
229 /* compute interval for triangle 2 */
230 float d,e,f,y0,y1;
231 NEWCOMPUTE_INTERVALS(up0,up1,up2,du0,du1,du2,du0du1,du0du2,d,e,f,y0,y1);
232
233 float xx,yy,xxyy,tmp;
234 xx=x0*x1;
235 yy=y0*y1;
236 xxyy=xx*yy;
237
238 tmp=a*xxyy;
239 isect1[0]=tmp+b*x1*yy;
240 isect1[1]=tmp+c*x0*yy;
241
242 tmp=d*xxyy;
243 isect2[0]=tmp+e*xx*y1;
244 isect2[1]=tmp+f*xx*y0;
245
246 SORT(isect1[0],isect1[1]);
247 SORT(isect2[0],isect2[1]);
248
249 if(isect1[1]<isect2[0] || isect2[1]<isect1[0]) return 0;
250 return 1;
251}
diff --git a/libraries/ode-0.9/GIMPACT/src/gim_trimesh.cpp b/libraries/ode-0.9/GIMPACT/src/gim_trimesh.cpp
new file mode 100644
index 0000000..1872592
--- /dev/null
+++ b/libraries/ode-0.9/GIMPACT/src/gim_trimesh.cpp
@@ -0,0 +1,364 @@
1
2/*
3-----------------------------------------------------------------------------
4This source file is part of GIMPACT Library.
5
6For the latest info, see http://gimpact.sourceforge.net/
7
8Copyright (c) 2006 Francisco Leon. C.C. 80087371.
9email: projectileman@yahoo.com
10
11 This library is free software; you can redistribute it and/or
12 modify it under the terms of EITHER:
13 (1) The GNU Lesser General Public License as published by the Free
14 Software Foundation; either version 2.1 of the License, or (at
15 your option) any later version. The text of the GNU Lesser
16 General Public License is included with this library in the
17 file GIMPACT-LICENSE-LGPL.TXT.
18 (2) The BSD-style license that is included with this library in
19 the file GIMPACT-LICENSE-BSD.TXT.
20
21 This library is distributed in the hope that it will be useful,
22 but WITHOUT ANY WARRANTY; without even the implied warranty of
23 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files
24 GIMPACT-LICENSE-LGPL.TXT and GIMPACT-LICENSE-BSD.TXT for more details.
25
26-----------------------------------------------------------------------------
27*/
28
29
30#include <assert.h>
31#include "GIMPACT/gim_trimesh.h"
32
33GUINT gim_trimesh_get_triangle_count(GIM_TRIMESH * trimesh)
34{
35 return trimesh->m_tri_index_buffer.m_element_count/3;
36}
37
38//! Creates the aabb set and the triangles cache
39/*!
40
41\param trimesh
42\param vertex_array
43\param triindex_array
44\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.
45\post it copies the arrays by reference, and creates the auxiliary data (m_aabbset,m_planes_cache_buffer)
46*/
47void gim_trimesh_create_from_arrays(GIM_TRIMESH * trimesh, GBUFFER_ARRAY * vertex_array, GBUFFER_ARRAY * triindex_array,char transformed_reply)
48{
49 assert(trimesh);
50 assert(vertex_array);
51 assert(triindex_array);
52 gim_buffer_array_copy_ref(vertex_array,&trimesh->m_source_vertex_buffer);
53 gim_buffer_array_copy_ref(triindex_array,&trimesh->m_tri_index_buffer);
54
55 trimesh->m_mask = GIM_TRIMESH_NEED_UPDATE;//needs update
56 //Create the transformed vertices
57 if(transformed_reply==1)
58 {
59 trimesh->m_mask |= GIM_TRIMESH_TRANSFORMED_REPLY;
60 gim_buffer_array_copy_value(vertex_array,&trimesh->m_transformed_vertex_buffer,G_BUFFER_MANAGER_SYSTEM,G_MU_DYNAMIC_READ_WRITE);
61 }
62 else
63 {
64 gim_buffer_array_copy_ref(vertex_array,&trimesh->m_transformed_vertex_buffer);
65 }
66 //create the box set
67 GUINT facecount = gim_trimesh_get_triangle_count(trimesh);
68
69 gim_aabbset_alloc(&trimesh->m_aabbset,facecount);
70 //create the planes cache
71 GIM_DYNARRAY_CREATE_SIZED(GIM_TRIPLANES_CACHE,trimesh->m_planes_cache_buffer,facecount);
72 //Create the bitset
73 GIM_BITSET_CREATE_SIZED(trimesh->m_planes_cache_bitset,facecount);
74 //Callback is 0
75 trimesh->m_update_callback = 0;
76 //set to identity
77 IDENTIFY_MATRIX_4X4(trimesh->m_transform);
78}
79
80
81
82//! Create a trimesh from vertex array and an index array
83/*!
84
85\param trimesh An uninitialized GIM_TRIMESH structure
86\param vertex_array A buffer to a vec3f array
87\param vertex_count
88\param triindex_array
89\param index_count
90\param copy_vertices If 1, it copies the source vertices in another buffer. Else (0) it constructs a reference to the data.
91\param copy_indices If 1, it copies the source vertices in another buffer. Else (0) it constructs a reference to the data.
92\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.
93*/
94void gim_trimesh_create_from_data(GIM_TRIMESH * trimesh, vec3f * vertex_array, GUINT vertex_count,char copy_vertices, GUINT * triindex_array, GUINT index_count,char copy_indices,char transformed_reply)
95{
96 GBUFFER_ARRAY buffer_vertex_array;
97 GBUFFER_ARRAY buffer_triindex_array;
98
99 //Create vertices
100 if(copy_vertices == 1)
101 {
102 gim_create_common_buffer_from_data(vertex_array, vertex_count*sizeof(vec3f), &buffer_vertex_array.m_buffer_id);
103 }
104 else//Create a shared buffer
105 {
106 gim_create_shared_buffer_from_data(vertex_array, vertex_count*sizeof(vec3f), &buffer_vertex_array.m_buffer_id);
107 }
108 GIM_BUFFER_ARRAY_INIT_TYPE(vec3f,buffer_vertex_array,buffer_vertex_array.m_buffer_id,vertex_count);
109
110
111 //Create vertices
112 if(copy_indices == 1)
113 {
114 gim_create_common_buffer_from_data(triindex_array, index_count*sizeof(GUINT), &buffer_triindex_array.m_buffer_id);
115 }
116 else//Create a shared buffer
117 {
118 gim_create_shared_buffer_from_data(triindex_array, index_count*sizeof(GUINT), &buffer_triindex_array.m_buffer_id);
119 }
120 GIM_BUFFER_ARRAY_INIT_TYPE(GUINT,buffer_triindex_array,buffer_triindex_array.m_buffer_id,index_count);
121
122 gim_trimesh_create_from_arrays(trimesh, &buffer_vertex_array, &buffer_triindex_array,transformed_reply);
123
124 ///always call this after create a buffer_array
125 GIM_BUFFER_ARRAY_DESTROY(buffer_vertex_array);
126 GIM_BUFFER_ARRAY_DESTROY(buffer_triindex_array);
127}
128
129//! Clears auxiliary data and releases buffer arrays
130void gim_trimesh_destroy(GIM_TRIMESH * trimesh)
131{
132 gim_aabbset_destroy(&trimesh->m_aabbset);
133
134 GIM_DYNARRAY_DESTROY(trimesh->m_planes_cache_buffer);
135 GIM_DYNARRAY_DESTROY(trimesh->m_planes_cache_bitset);
136
137 GIM_BUFFER_ARRAY_DESTROY(trimesh->m_transformed_vertex_buffer);
138 GIM_BUFFER_ARRAY_DESTROY(trimesh->m_source_vertex_buffer);
139 GIM_BUFFER_ARRAY_DESTROY(trimesh->m_tri_index_buffer);
140}
141
142//! Copies two meshes
143/*!
144\pre dest_trimesh shouldn't be created
145\post dest_trimesh will be created
146\param source_trimesh
147\param dest_trimesh
148\param copy_by_reference If 1, it attach a reference to the source vertices, else it copies the vertices
149\param transformed_reply IF 1, then it forces the m_trasnformed_vertices to be a reply of the source vertices
150*/
151void gim_trimesh_copy(GIM_TRIMESH * source_trimesh,GIM_TRIMESH * dest_trimesh, char copy_by_reference, char transformed_reply)
152{
153 if(copy_by_reference==1)
154 {
155 gim_trimesh_create_from_arrays(dest_trimesh, &source_trimesh->m_source_vertex_buffer, &source_trimesh->m_tri_index_buffer,transformed_reply);
156 }
157 else
158 {
159 GBUFFER_ARRAY buffer_vertex_array;
160 GBUFFER_ARRAY buffer_triindex_array;
161
162 gim_buffer_array_copy_value(&source_trimesh->m_source_vertex_buffer,&buffer_vertex_array,G_BUFFER_MANAGER_SYSTEM,G_MU_DYNAMIC_READ_WRITE);
163
164 gim_buffer_array_copy_value(&source_trimesh->m_tri_index_buffer,&buffer_triindex_array,G_BUFFER_MANAGER_SYSTEM,G_MU_DYNAMIC_READ_WRITE);
165
166 gim_trimesh_create_from_arrays(dest_trimesh, &buffer_vertex_array, &buffer_triindex_array,transformed_reply);
167
168 ///always call this after create a buffer_array
169 GIM_BUFFER_ARRAY_DESTROY(buffer_vertex_array);
170 GIM_BUFFER_ARRAY_DESTROY(buffer_triindex_array);
171 }
172}
173
174//! Locks the trimesh for working with it
175/*!
176\post locks m_tri_index_buffer and m_transformed_vertex_buffer.
177\param trimesh
178*/
179void gim_trimesh_locks_work_data(GIM_TRIMESH * trimesh)
180{
181 GINT res;
182 res=gim_buffer_array_lock(&trimesh->m_tri_index_buffer,G_MA_READ_ONLY);
183 assert(res==G_BUFFER_OP_SUCCESS);
184 res=gim_buffer_array_lock(&trimesh->m_transformed_vertex_buffer,G_MA_READ_ONLY);
185 assert(res==G_BUFFER_OP_SUCCESS);
186}
187
188//! unlocks the trimesh
189/*!
190\post unlocks m_tri_index_buffer and m_transformed_vertex_buffer.
191\param trimesh
192*/
193void gim_trimesh_unlocks_work_data(GIM_TRIMESH * trimesh)
194{
195 gim_buffer_array_unlock(&trimesh->m_tri_index_buffer);
196 gim_buffer_array_unlock(&trimesh->m_transformed_vertex_buffer);
197}
198
199
200//! Returns 1 if the m_transformed_vertex_buffer is a reply of m_source_vertex_buffer
201char gim_trimesh_has_tranformed_reply(GIM_TRIMESH * trimesh)
202{
203 if(trimesh->m_mask&GIM_TRIMESH_TRANSFORMED_REPLY) return 1;
204 return 0;
205}
206
207//! Returns 1 if the trimesh needs to update their aabbset and the planes cache.
208char gim_trimesh_needs_update(GIM_TRIMESH * trimesh)
209{
210 if(trimesh->m_mask&GIM_TRIMESH_NEED_UPDATE) return 1;
211 return 0;
212}
213
214//! Change the state of the trimesh for force it to update
215/*!
216Call it after made changes to the trimesh.
217\post gim_trimesh_need_update(trimesh) will return 1
218*/
219void gim_trimesh_post_update(GIM_TRIMESH * trimesh)
220{
221 trimesh->m_mask |= GIM_TRIMESH_NEED_UPDATE;
222}
223
224//kernel
225#define MULT_MAT_VEC4_KERNEL(_mat,_src,_dst) MAT_DOT_VEC_3X4((_dst),(_mat),(_src))
226
227//! Updates m_transformed_vertex_buffer
228/*!
229\pre m_transformed_vertex_buffer must be unlocked
230*/
231void gim_trimesh_update_vertices(GIM_TRIMESH * trimesh)
232{
233 if(gim_trimesh_has_tranformed_reply(trimesh) == 0) return; //Don't perform transformation
234
235 //Vertices
236 GBUFFER_ARRAY * psource_vertex_buffer = &trimesh->m_source_vertex_buffer;
237 GBUFFER_ARRAY * ptransformed_vertex_buffer = &trimesh->m_transformed_vertex_buffer;
238 //Temp transform
239 mat4f transform;
240 COPY_MATRIX_4X4(transform,trimesh->m_transform);
241
242 GIM_PROCESS_BUFFER_ARRAY(transform,(*psource_vertex_buffer),(*ptransformed_vertex_buffer),MULT_MAT_VEC4_KERNEL,vec3f,vec3f);
243}
244
245//! Updates m_aabbset and m_planes_cache_bitset
246/*!
247\pre gim_trimesh_locks_work_data must be called before
248*/
249void gim_trimesh_update_aabbset(GIM_TRIMESH * trimesh)
250{
251 vec3f * transformed_vertices = GIM_BUFFER_ARRAY_POINTER(vec3f,trimesh->m_transformed_vertex_buffer,0);
252 assert(transformed_vertices);
253
254 GUINT * triangle_indices = GIM_BUFFER_ARRAY_POINTER(GUINT,trimesh->m_tri_index_buffer,0);
255 assert(triangle_indices);
256 // box set
257 aabb3f * paabb = trimesh->m_aabbset.m_boxes;
258 GUINT triangle_count = gim_trimesh_get_triangle_count(trimesh);
259 float * v1,*v2,*v3;
260 GUINT i;
261 for (i=0; i<triangle_count;i++)
262 {
263 v1 = &transformed_vertices[triangle_indices[0]][0];
264 v2 = &transformed_vertices[triangle_indices[1]][0];
265 v3 = &transformed_vertices[triangle_indices[2]][0];
266 COMPUTEAABB_FOR_TRIANGLE((*paabb),v1,v2,v3);
267 triangle_indices+=3;
268 paabb++;
269 }
270 //Clear planes cache
271 GIM_BITSET_CLEAR_ALL(trimesh->m_planes_cache_bitset);
272 //Sorts set
273 gim_aabbset_update(&trimesh->m_aabbset);
274}
275
276//! Updates the trimesh if needed
277/*!
278\post If gim_trimesh_needs_update returns 1, then it calls gim_trimesh_update_vertices and gim_trimesh_update_aabbset
279*/
280void gim_trimesh_update(GIM_TRIMESH * trimesh)
281{
282 if(gim_trimesh_needs_update(trimesh)==0) return;
283 gim_trimesh_update_vertices(trimesh);
284 gim_trimesh_locks_work_data(trimesh);
285 gim_trimesh_update_aabbset(trimesh);
286 gim_trimesh_unlocks_work_data(trimesh);
287
288 //Clear update flag
289 trimesh->m_mask &= ~GIM_TRIMESH_NEED_UPDATE;
290}
291
292void gim_trimesh_set_tranform(GIM_TRIMESH * trimesh, mat4f transform)
293{
294 GREAL diff = 0.0f;
295 float * originaltrans = &trimesh->m_transform[0][0];
296 float * newtrans = &transform[0][0];
297 GUINT i;
298 for (i=0;i<16;i++)
299 {
300 diff += fabs(originaltrans[i]-newtrans[i]);
301 }
302
303// if(IS_ZERO(diff)) return ;///don't need to update
304 if(diff< 0.00001f) return ;///don't need to update
305
306 COPY_MATRIX_4X4(trimesh->m_transform,transform);
307
308 gim_trimesh_post_update(trimesh);
309}
310
311void gim_trimesh_get_triangle_data(GIM_TRIMESH * trimesh, GUINT triangle_index, GIM_TRIANGLE_DATA * tri_data)
312{
313 vec3f * transformed_vertices = GIM_BUFFER_ARRAY_POINTER(vec3f,trimesh->m_transformed_vertex_buffer,0);
314
315 GUINT * triangle_indices = GIM_BUFFER_ARRAY_POINTER(GUINT,trimesh->m_tri_index_buffer,triangle_index*3);
316
317
318 //Copy the vertices
319 VEC_COPY(tri_data->m_vertices[0],transformed_vertices[triangle_indices[0]]);
320 VEC_COPY(tri_data->m_vertices[1],transformed_vertices[triangle_indices[1]]);
321 VEC_COPY(tri_data->m_vertices[2],transformed_vertices[triangle_indices[2]]);
322
323 //Get the planes
324 GIM_TRIPLANES_CACHE * planes = GIM_DYNARRAY_POINTER(GIM_TRIPLANES_CACHE,trimesh->m_planes_cache_buffer);
325 planes += triangle_index;
326
327 //verify planes cache
328 GUINT bit_eval;
329 GIM_BITSET_GET(trimesh->m_planes_cache_bitset,triangle_index,bit_eval);
330 if(bit_eval == 0)// Needs to calc the planes
331 {
332 //Calc the face plane
333 TRIANGLE_PLANE(tri_data->m_vertices[0],tri_data->m_vertices[1],tri_data->m_vertices[2],planes->m_planes[0]);
334 //Calc the edge 1
335 EDGE_PLANE(tri_data->m_vertices[0],tri_data->m_vertices[1],(planes->m_planes[0]),(planes->m_planes[1]));
336
337 //Calc the edge 2
338 EDGE_PLANE(tri_data->m_vertices[1],tri_data->m_vertices[2],(planes->m_planes[0]),(planes->m_planes[2]));
339
340 //Calc the edge 3
341 EDGE_PLANE(tri_data->m_vertices[2],tri_data->m_vertices[0],(planes->m_planes[0]), (planes->m_planes[3]));
342
343 //mark
344 GIM_BITSET_SET(trimesh->m_planes_cache_bitset,triangle_index);
345 }
346
347
348 VEC_COPY_4((tri_data->m_planes.m_planes[0]),(planes->m_planes[0]));//face plane
349 VEC_COPY_4((tri_data->m_planes.m_planes[1]),(planes->m_planes[1]));//edge1
350 VEC_COPY_4((tri_data->m_planes.m_planes[2]),(planes->m_planes[2]));//edge2
351 VEC_COPY_4((tri_data->m_planes.m_planes[3]),(planes->m_planes[3]));//edge3
352}
353
354void gim_trimesh_get_triangle_vertices(GIM_TRIMESH * trimesh, GUINT triangle_index, vec3f v1,vec3f v2,vec3f v3)
355{
356 vec3f * transformed_vertices = GIM_BUFFER_ARRAY_POINTER(vec3f,trimesh->m_transformed_vertex_buffer,0);
357
358 GUINT * triangle_indices = GIM_BUFFER_ARRAY_POINTER(GUINT,trimesh->m_tri_index_buffer,triangle_index*3);
359
360 //Copy the vertices
361 VEC_COPY(v1,transformed_vertices[triangle_indices[0]]);
362 VEC_COPY(v2,transformed_vertices[triangle_indices[1]]);
363 VEC_COPY(v3,transformed_vertices[triangle_indices[2]]);
364}
diff --git a/libraries/ode-0.9/GIMPACT/src/gim_trimesh_capsule_collision.cpp b/libraries/ode-0.9/GIMPACT/src/gim_trimesh_capsule_collision.cpp
new file mode 100644
index 0000000..d1f7ca3
--- /dev/null
+++ b/libraries/ode-0.9/GIMPACT/src/gim_trimesh_capsule_collision.cpp
@@ -0,0 +1,279 @@
1
2/*
3-----------------------------------------------------------------------------
4This source file is part of GIMPACT Library.
5
6For the latest info, see http://gimpact.sourceforge.net/
7
8Copyright (c) 2006 Francisco Leon. C.C. 80087371.
9email: projectileman@yahoo.com
10
11 This library is free software; you can redistribute it and/or
12 modify it under the terms of EITHER:
13 (1) The GNU Lesser General Public License as published by the Free
14 Software Foundation; either version 2.1 of the License, or (at
15 your option) any later version. The text of the GNU Lesser
16 General Public License is included with this library in the
17 file GIMPACT-LICENSE-LGPL.TXT.
18 (2) The BSD-style license that is included with this library in
19 the file GIMPACT-LICENSE-BSD.TXT.
20
21 This library is distributed in the hope that it will be useful,
22 but WITHOUT ANY WARRANTY; without even the implied warranty of
23 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files
24 GIMPACT-LICENSE-LGPL.TXT and GIMPACT-LICENSE-BSD.TXT for more details.
25
26-----------------------------------------------------------------------------
27*/
28
29#include "GIMPACT/gim_trimesh.h"
30
31//! Utility function for find the closest point between a segment and a triangle
32/*!
33
34\param triangle
35\param s1
36\param s2
37\param contacts Contains the closest points on the segment (1,2), and the normal points to segment, and m_depth contains the distance
38
39\post The contacts array is not set to 0. It adds aditional contacts
40*/
41void gim_closest_point_triangle_segment(GIM_TRIANGLE_DATA * triangle, vec3f s1,vec3f s2, GDYNAMIC_ARRAY * contacts)
42{
43 vec3f segment_points[4];
44 vec3f closest_points[2];
45 GUINT intersection_type, out_edge= 10;
46 GREAL dis, dis_temp,perpend;
47 vec4f sdiff;
48
49 dis = DISTANCE_PLANE_POINT(triangle->m_planes.m_planes[0],s1);
50 dis_temp = DISTANCE_PLANE_POINT(triangle->m_planes.m_planes[0],s2);
51
52 if(dis<=0.0f && dis_temp<=0.0f) return;
53
54 VEC_DIFF(sdiff,s2,s1);
55 perpend = VEC_DOT(sdiff,triangle->m_planes.m_planes[0]);
56
57 if(!IS_ZERO(perpend)) // Not perpendicular
58 {
59 if(dis<dis_temp)
60 {
61 VEC_COPY(closest_points[0],s1);
62 }
63 else
64 {
65 dis = dis_temp;
66 VEC_COPY(closest_points[0],s2);
67 }
68
69 //Testing segment vertices over triangle
70 if(dis>=0.0f && dis_temp>=0.0f)
71 {
72 POINT_IN_HULL(closest_points[0],(&triangle->m_planes.m_planes[1]),3,out_edge);
73
74 if(out_edge==0)//Point over face
75 {
76 GIM_PUSH_CONTACT((*contacts),closest_points[0] ,triangle->m_planes.m_planes[0] ,dis,0, 0, 0,0);
77 return;
78 }
79 }
80 else
81 {
82
83 PLANE_CLIP_SEGMENT(s1,s2,triangle->m_planes.m_planes[0],closest_points[1]);
84
85 POINT_IN_HULL(closest_points[1],(&triangle->m_planes.m_planes[1]),3,out_edge);
86
87 if(out_edge==0)//Point over face
88 {
89 GIM_PUSH_CONTACT((*contacts),closest_points[0] ,triangle->m_planes.m_planes[0] ,dis,0, 0, 0,0);
90 return;
91 }
92 }
93
94 }
95 else // Perpendicular Face
96 {
97 //out_edge=10
98 //Clip segment by triangle
99 // Edge1
100 PLANE_CLIP_SEGMENT_CLOSEST(s1,s2,triangle->m_planes.m_planes[1],segment_points[0],segment_points[1],intersection_type);
101 if(intersection_type==0||intersection_type==1)
102 {
103 out_edge = 0;
104 VEC_COPY(closest_points[0],segment_points[0]);
105 }
106 else
107 {
108 //Edge2
109 PLANE_CLIP_SEGMENT_CLOSEST(segment_points[0],segment_points[1],triangle->m_planes.m_planes[2],segment_points[2],segment_points[3],intersection_type);
110 if(intersection_type==0||intersection_type==1)
111 {
112 out_edge = 1;
113 VEC_COPY(closest_points[0],segment_points[3]);
114 }
115 else
116 {
117 //Edge3
118 PLANE_CLIP_SEGMENT_CLOSEST(segment_points[2],segment_points[3],triangle->m_planes.m_planes[3],closest_points[0],closest_points[1],intersection_type);
119 if(intersection_type==0||intersection_type==1)
120 {
121 out_edge = 2;
122 }
123 }
124 }
125 //POST closest_points[0] and closest_points[1] are inside the triangle, if out_edge>2
126 if(out_edge>2) // Over triangle
127 {
128 dis = VEC_DOT(closest_points[0],triangle->m_planes.m_planes[0]);
129 GIM_PUSH_CONTACT((*contacts),closest_points[0] ,triangle->m_planes.m_planes[0] ,dis,0, 0, 0,0);
130 GIM_PUSH_CONTACT((*contacts),closest_points[1] ,triangle->m_planes.m_planes[0] ,dis,0, 0, 0,0);
131 return;
132 }
133 }
134
135 //Find closest edges
136 out_edge = 10;
137 dis = G_REAL_INFINITY;
138 GUINT i;
139 for(i=0;i<3;i++)
140 {
141 SEGMENT_COLLISION(s1,s2,triangle->m_vertices[i],triangle->m_vertices[(i+1)%3],segment_points[0],segment_points[1]);
142 VEC_DIFF(sdiff,segment_points[0],segment_points[1]);
143 dis_temp = VEC_DOT(sdiff,sdiff);
144 if(dis_temp< dis)
145 {
146 dis = dis_temp;
147 out_edge = i;
148 VEC_COPY(closest_points[0],segment_points[0]);
149 VEC_COPY(closest_points[1],sdiff);//normal
150 }
151 }
152 if(out_edge>2) return ;// ???? ASSERT this please
153
154 if(IS_ZERO(dis))
155 {
156 //Set face plane
157 GIM_PUSH_CONTACT((*contacts),closest_points[0] ,triangle->m_planes.m_planes[0] ,0.0f,0, 0, 0,0);
158
159 }
160 else
161 {
162 GIM_SQRT(dis,dis);
163 VEC_SCALE(closest_points[1],(1.0f/dis),closest_points[1]);//normal
164 GIM_PUSH_CONTACT((*contacts),closest_points[0] ,closest_points[1],dis,0, 0, 0,0);
165 }
166}
167
168
169//! Utility function for find the closest point between a capsule and a triangle
170/*!
171
172\param triangle
173\param capsule
174\param contacts Contains the closest points on the capsule, and the normal points to triangle
175
176\post The contacts array is not set to 0. It adds aditional contacts
177*/
178int gim_triangle_capsule_collision(GIM_TRIANGLE_DATA * triangle, GIM_CAPSULE_DATA * capsule, GDYNAMIC_ARRAY * contacts)
179{
180 GUINT old_contact_size = contacts->m_size;
181 gim_closest_point_triangle_segment(triangle,capsule->m_point1,capsule->m_point2,contacts);
182 GIM_CONTACT * pcontact = GIM_DYNARRAY_POINTER(GIM_CONTACT ,(*contacts));
183 pcontact+= old_contact_size;
184
185 if(pcontact->m_depth > capsule->m_radius)
186 {
187 contacts->m_size = old_contact_size;
188 return 0;
189 }
190
191 vec3f vec;
192 while(old_contact_size<contacts->m_size)
193 {
194 //Scale the normal for pointing to triangle
195 VEC_SCALE(pcontact->m_normal,-1.0f,pcontact->m_normal);
196 //Fix the contact point
197 VEC_SCALE(vec,capsule->m_radius,pcontact->m_normal);
198 VEC_SUM(pcontact->m_point,vec,pcontact->m_point);
199 //Fix the depth
200 pcontact->m_depth = capsule->m_radius - pcontact->m_depth;
201
202 pcontact++;
203 old_contact_size++;
204 }
205
206 return 1;
207}
208
209
210//! Trimesh Capsule collision
211/*!
212Find the closest primitive collided by the ray
213\param trimesh
214\param capsule
215\param contact
216\param contacts A GIM_CONTACT array. Must be initialized
217*/
218void gim_trimesh_capsule_collision(GIM_TRIMESH * trimesh, GIM_CAPSULE_DATA * capsule, GDYNAMIC_ARRAY * contacts)
219{
220 contacts->m_size = 0;
221
222 aabb3f test_aabb;
223 CALC_CAPSULE_AABB((*capsule),test_aabb);
224
225 GDYNAMIC_ARRAY collision_result;
226 GIM_CREATE_BOXQUERY_LIST(collision_result);
227
228 gim_aabbset_box_collision(&test_aabb, &trimesh->m_aabbset , &collision_result);
229
230 if(collision_result.m_size==0)
231 {
232 GIM_DYNARRAY_DESTROY(collision_result);
233 }
234
235 //collide triangles
236 //Locks trimesh
237 gim_trimesh_locks_work_data(trimesh);
238 //dummy contacts
239 GDYNAMIC_ARRAY dummycontacts;
240 GIM_CREATE_CONTACT_LIST(dummycontacts);
241
242 int cresult;
243 unsigned int i;
244 GUINT * boxesresult = GIM_DYNARRAY_POINTER(GUINT,collision_result);
245 GIM_TRIANGLE_DATA tri_data;
246 GUINT old_contact_size;
247 GIM_CONTACT * pcontact;
248
249 for(i=0;i<collision_result.m_size;i++)
250 {
251 old_contact_size = dummycontacts.m_size;
252 gim_trimesh_get_triangle_data(trimesh,boxesresult[i],&tri_data);
253 cresult = gim_triangle_capsule_collision(&tri_data, capsule, &dummycontacts);
254 if(cresult!=0)
255 {
256 pcontact = GIM_DYNARRAY_POINTER(GIM_CONTACT ,dummycontacts);
257 pcontact+= old_contact_size;
258 while(old_contact_size<dummycontacts.m_size)
259 {
260 pcontact->m_handle1 = trimesh;
261 pcontact->m_handle2 = capsule;
262 pcontact->m_feature1 = boxesresult[i];
263 pcontact->m_feature2 = 0;
264 pcontact++;
265 old_contact_size++;
266 }
267 }
268 }
269 ///unlocks
270 gim_trimesh_unlocks_work_data(trimesh);
271 ///Destroy box result
272 GIM_DYNARRAY_DESTROY(collision_result);
273
274 //merge contacts
275 gim_merge_contacts(&dummycontacts,contacts);
276
277 //Destroy dummy
278 GIM_DYNARRAY_DESTROY(dummycontacts);
279}
diff --git a/libraries/ode-0.9/GIMPACT/src/gim_trimesh_ray_collision.cpp b/libraries/ode-0.9/GIMPACT/src/gim_trimesh_ray_collision.cpp
new file mode 100644
index 0000000..0c10fe1
--- /dev/null
+++ b/libraries/ode-0.9/GIMPACT/src/gim_trimesh_ray_collision.cpp
@@ -0,0 +1,140 @@
1
2/*
3-----------------------------------------------------------------------------
4This source file is part of GIMPACT Library.
5
6For the latest info, see http://gimpact.sourceforge.net/
7
8Copyright (c) 2006 Francisco Leon. C.C. 80087371.
9email: projectileman@yahoo.com
10
11 This library is free software; you can redistribute it and/or
12 modify it under the terms of EITHER:
13 (1) The GNU Lesser General Public License as published by the Free
14 Software Foundation; either version 2.1 of the License, or (at
15 your option) any later version. The text of the GNU Lesser
16 General Public License is included with this library in the
17 file GIMPACT-LICENSE-LGPL.TXT.
18 (2) The BSD-style license that is included with this library in
19 the file GIMPACT-LICENSE-BSD.TXT.
20
21 This library is distributed in the hope that it will be useful,
22 but WITHOUT ANY WARRANTY; without even the implied warranty of
23 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files
24 GIMPACT-LICENSE-LGPL.TXT and GIMPACT-LICENSE-BSD.TXT for more details.
25
26-----------------------------------------------------------------------------
27*/
28
29#include "GIMPACT/gim_trimesh.h"
30
31
32//! Trimesh Ray Collisions
33/*!
34
35\param trimesh
36\param contact
37\return 1 if the ray collides, else 0
38*/
39int gim_trimesh_ray_collision(GIM_TRIMESH * trimesh,vec3f origin,vec3f dir, GREAL tmax, GIM_TRIANGLE_RAY_CONTACT_DATA * contact)
40{
41 GDYNAMIC_ARRAY collision_result;
42 GIM_CREATE_BOXQUERY_LIST(collision_result);
43
44 gim_aabbset_ray_collision(origin,dir,tmax,&trimesh->m_aabbset,&collision_result);
45
46 if(collision_result.m_size==0)
47 {
48 GIM_DYNARRAY_DESTROY(collision_result);
49 return 0;
50 }
51
52 //collide triangles
53
54 GUINT * boxesresult = GIM_DYNARRAY_POINTER(GUINT,collision_result);
55 GIM_TRIANGLE_DATA tridata;
56 vec3f pout;
57 GREAL tparam,u,v;
58 char does_intersect;
59
60 gim_trimesh_locks_work_data(trimesh);
61
62 for(unsigned int i=0;i<collision_result.m_size;i++)
63 {
64 gim_trimesh_get_triangle_data(trimesh,boxesresult[i],&tridata);
65
66 RAY_TRIANGLE_INTERSECTION(origin,dir,tridata.m_vertices[0],tridata.m_vertices[1],tridata.m_vertices[2],tridata.m_planes.m_planes[0],pout,u,v,tparam,tmax,does_intersect);
67 if(does_intersect)
68 {
69 contact->tparam = tparam;
70 contact->u = u;
71 contact->v = v;
72 contact->m_face_id = boxesresult[i];
73 VEC_COPY(contact->m_point,pout);
74 VEC_COPY(contact->m_normal,tridata.m_planes.m_planes[0]);
75
76 gim_trimesh_unlocks_work_data(trimesh);
77 GIM_DYNARRAY_DESTROY(collision_result);
78 return 1;
79 }
80 }
81
82 gim_trimesh_unlocks_work_data(trimesh);
83 GIM_DYNARRAY_DESTROY(collision_result);
84 return 0;//no collisiion
85}
86
87
88//! Trimesh Ray Collisions closest
89/*!
90Find the closest primitive collided by the ray
91\param trimesh
92\param contact
93\return 1 if the ray collides, else 0
94*/
95int gim_trimesh_ray_closest_collision(GIM_TRIMESH * trimesh,vec3f origin,vec3f dir, GREAL tmax, GIM_TRIANGLE_RAY_CONTACT_DATA * contact)
96{
97 GDYNAMIC_ARRAY collision_result;
98 GIM_CREATE_BOXQUERY_LIST(collision_result);
99
100 gim_aabbset_ray_collision(origin,dir,tmax,&trimesh->m_aabbset,&collision_result);
101
102 if(collision_result.m_size==0)
103 {
104 GIM_DYNARRAY_DESTROY(collision_result);
105 return 0;
106 }
107
108 //collide triangles
109
110 GUINT * boxesresult = GIM_DYNARRAY_POINTER(GUINT,collision_result);
111 GIM_TRIANGLE_DATA tridata;
112 vec3f pout;
113 GREAL tparam,u,v;
114 char does_intersect;
115 contact->tparam = tmax + 0.1f;
116
117
118 gim_trimesh_locks_work_data(trimesh);
119
120 for(unsigned int i=0;i<collision_result.m_size;i++)
121 {
122 gim_trimesh_get_triangle_data(trimesh,boxesresult[i],&tridata);
123
124 RAY_TRIANGLE_INTERSECTION(origin,dir,tridata.m_vertices[0],tridata.m_vertices[1],tridata.m_vertices[2],tridata.m_planes.m_planes[0],pout,u,v,tparam,tmax,does_intersect);
125 if(does_intersect && (tparam < contact->tparam))
126 {
127 contact->tparam = tparam;
128 contact->u = u;
129 contact->v = v;
130 contact->m_face_id = boxesresult[i];
131 VEC_COPY(contact->m_point,pout);
132 VEC_COPY(contact->m_normal,tridata.m_planes.m_planes[0]);
133 }
134 }
135
136 gim_trimesh_unlocks_work_data(trimesh);
137 GIM_DYNARRAY_DESTROY(collision_result);
138 if(contact->tparam > tmax) return 0;
139 return 1;
140}
diff --git a/libraries/ode-0.9/GIMPACT/src/gim_trimesh_sphere_collision.cpp b/libraries/ode-0.9/GIMPACT/src/gim_trimesh_sphere_collision.cpp
new file mode 100644
index 0000000..60444fb
--- /dev/null
+++ b/libraries/ode-0.9/GIMPACT/src/gim_trimesh_sphere_collision.cpp
@@ -0,0 +1,196 @@
1
2/*
3-----------------------------------------------------------------------------
4This source file is part of GIMPACT Library.
5
6For the latest info, see http://gimpact.sourceforge.net/
7
8Copyright (c) 2006 Francisco Leon. C.C. 80087371.
9email: projectileman@yahoo.com
10
11 This library is free software; you can redistribute it and/or
12 modify it under the terms of EITHER:
13 (1) The GNU Lesser General Public License as published by the Free
14 Software Foundation; either version 2.1 of the License, or (at
15 your option) any later version. The text of the GNU Lesser
16 General Public License is included with this library in the
17 file GIMPACT-LICENSE-LGPL.TXT.
18 (2) The BSD-style license that is included with this library in
19 the file GIMPACT-LICENSE-BSD.TXT.
20
21 This library is distributed in the hope that it will be useful,
22 but WITHOUT ANY WARRANTY; without even the implied warranty of
23 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files
24 GIMPACT-LICENSE-LGPL.TXT and GIMPACT-LICENSE-BSD.TXT for more details.
25
26-----------------------------------------------------------------------------
27*/
28
29#include "GIMPACT/gim_trimesh.h"
30
31int gim_triangle_sphere_collision(
32 GIM_TRIANGLE_DATA *tri,
33 vec3f center, GREAL radius,
34 GIM_TRIANGLE_CONTACT_DATA * contact_data)
35{
36 contact_data->m_point_count = 0;
37
38 //Find Face plane distance
39 GREAL dis = DISTANCE_PLANE_POINT(tri->m_planes.m_planes[0],center);
40 if(dis>radius) return 0; //out
41 if(dis<-radius) return 0;//Out of triangle
42 contact_data->m_penetration_depth = dis;
43
44 //Find the most edge
45 GUINT most_edge = 4;//no edge
46 GREAL max_dis = 0.0f;
47 dis = DISTANCE_PLANE_POINT(tri->m_planes.m_planes[1],center);
48 if(dis>radius) return 0;//Out of triangle
49 if(dis>0.0f)
50 {
51 max_dis = dis;
52 most_edge = 0;
53 }
54
55 dis = DISTANCE_PLANE_POINT(tri->m_planes.m_planes[2],center);
56 if(dis>radius) return 0;//Out of triangle
57 if(dis>max_dis)// && dis>0.0f)
58 {
59 max_dis = dis;
60 most_edge = 1;
61 }
62
63 dis = DISTANCE_PLANE_POINT(tri->m_planes.m_planes[3],center);
64 if(dis>radius) return 0;//Out of triangle
65 if(dis>max_dis)// && dis>0.0f)
66 {
67 max_dis = dis;
68 most_edge = 2;
69 }
70
71 if(most_edge == 4) //Box is into triangle
72 {
73 //contact_data->m_penetration_depth = dis is set above
74 //Find Face plane point
75 VEC_COPY(contact_data->m_separating_normal,tri->m_planes.m_planes[0]);
76 //Find point projection on plane
77 if(contact_data->m_penetration_depth>=0.0f)
78 {
79 VEC_SCALE(contact_data->m_points[0],-radius,contact_data->m_separating_normal);
80 }
81 else
82 {
83 VEC_SCALE(contact_data->m_points[0],radius,contact_data->m_separating_normal);
84 }
85 contact_data->m_penetration_depth = radius - contact_data->m_penetration_depth;
86
87 VEC_SUM(contact_data->m_points[0],contact_data->m_points[0],center);
88 //Scale normal for pointing to triangle
89 VEC_SCALE(contact_data->m_separating_normal,-1.0f,contact_data->m_separating_normal);
90 contact_data->m_point_count = 1;
91 return 1;
92 }
93 //find the edge
94 vec3f e1,e2;
95 VEC_COPY(e1,tri->m_vertices[most_edge]);
96 VEC_COPY(e2,tri->m_vertices[(most_edge+1)%3]);
97
98 CLOSEST_POINT_ON_SEGMENT(contact_data->m_points[0],center,e1,e2);
99 //find distance
100 VEC_DIFF(e1,center,contact_data->m_points[0]);
101 VEC_LENGTH(e1,dis);
102 if(dis>radius) return 0;
103
104 contact_data->m_penetration_depth = radius - dis;
105
106 if(IS_ZERO(dis))
107 {
108 VEC_COPY(contact_data->m_separating_normal,tri->m_planes.m_planes[most_edge+1]);
109 VEC_SCALE(contact_data->m_points[0],-radius,contact_data->m_separating_normal);
110 VEC_SUM(contact_data->m_points[0],contact_data->m_points[0],center);
111 }
112 else
113 {
114 VEC_SCALE(contact_data->m_separating_normal,1.0f/dis,e1);
115 VEC_SCALE(contact_data->m_points[0],-radius,contact_data->m_separating_normal);
116 VEC_SUM(contact_data->m_points[0],contact_data->m_points[0],center);
117 }
118
119 //Scale normal for pointing to triangle
120 VEC_SCALE(contact_data->m_separating_normal,-1.0f,contact_data->m_separating_normal);
121
122 contact_data->m_point_count = 1;
123 return 1;
124
125}
126
127//! Trimesh Sphere Collisions
128/*!
129In each contact
130<ul>
131<li> m_handle1 points to trimesh.
132<li> m_handle2 points to NULL.
133<li> m_feature1 Is a triangle index of trimesh.
134</ul>
135
136\param trimesh
137\param center
138\param radius
139\param contacts A GIM_CONTACT array. Must be initialized
140*/
141void gim_trimesh_sphere_collision(GIM_TRIMESH * trimesh,vec3f center,GREAL radius, GDYNAMIC_ARRAY * contacts)
142{
143 contacts->m_size = 0;
144
145 aabb3f test_aabb;
146 test_aabb.minX = center[0]-radius;
147 test_aabb.maxX = center[0]+radius;
148 test_aabb.minY = center[1]-radius;
149 test_aabb.maxY = center[1]+radius;
150 test_aabb.minZ = center[2]-radius;
151 test_aabb.maxZ = center[2]+radius;
152
153 GDYNAMIC_ARRAY collision_result;
154 GIM_CREATE_BOXQUERY_LIST(collision_result);
155
156 gim_aabbset_box_collision(&test_aabb, &trimesh->m_aabbset , &collision_result);
157
158 if(collision_result.m_size==0)
159 {
160 GIM_DYNARRAY_DESTROY(collision_result);
161 }
162
163 //collide triangles
164 //Locks trimesh
165 gim_trimesh_locks_work_data(trimesh);
166 //dummy contacts
167 GDYNAMIC_ARRAY dummycontacts;
168 GIM_CREATE_CONTACT_LIST(dummycontacts);
169
170 int cresult;
171 unsigned int i;
172 GUINT * boxesresult = GIM_DYNARRAY_POINTER(GUINT,collision_result);
173 GIM_TRIANGLE_CONTACT_DATA tri_contact_data;
174 GIM_TRIANGLE_DATA tri_data;
175
176 for(i=0;i<collision_result.m_size;i++)
177 {
178 gim_trimesh_get_triangle_data(trimesh,boxesresult[i],&tri_data);
179 cresult = gim_triangle_sphere_collision(&tri_data,center,radius,&tri_contact_data);
180 if(cresult!=0)
181 {
182 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);
183 }
184 }
185 ///unlocks
186 gim_trimesh_unlocks_work_data(trimesh);
187 ///Destroy box result
188 GIM_DYNARRAY_DESTROY(collision_result);
189
190 //merge contacts
191 gim_merge_contacts(&dummycontacts,contacts);
192
193 //Destroy dummy
194 GIM_DYNARRAY_DESTROY(dummycontacts);
195}
196
diff --git a/libraries/ode-0.9/GIMPACT/src/gim_trimesh_trimesh_collision.cpp b/libraries/ode-0.9/GIMPACT/src/gim_trimesh_trimesh_collision.cpp
new file mode 100644
index 0000000..c9c5305
--- /dev/null
+++ b/libraries/ode-0.9/GIMPACT/src/gim_trimesh_trimesh_collision.cpp
@@ -0,0 +1,348 @@
1
2/*
3-----------------------------------------------------------------------------
4This source file is part of GIMPACT Library.
5
6For the latest info, see http://gimpact.sourceforge.net/
7
8Copyright (c) 2006 Francisco Leon. C.C. 80087371.
9email: projectileman@yahoo.com
10
11 This library is free software; you can redistribute it and/or
12 modify it under the terms of EITHER:
13 (1) The GNU Lesser General Public License as published by the Free
14 Software Foundation; either version 2.1 of the License, or (at
15 your option) any later version. The text of the GNU Lesser
16 General Public License is included with this library in the
17 file GIMPACT-LICENSE-LGPL.TXT.
18 (2) The BSD-style license that is included with this library in
19 the file GIMPACT-LICENSE-BSD.TXT.
20
21 This library is distributed in the hope that it will be useful,
22 but WITHOUT ANY WARRANTY; without even the implied warranty of
23 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files
24 GIMPACT-LICENSE-LGPL.TXT and GIMPACT-LICENSE-BSD.TXT for more details.
25
26-----------------------------------------------------------------------------
27*/
28
29#include "GIMPACT/gim_trimesh.h"
30
31#define CLASSIFY_TRI_BY_FACE(v1,v2,v3,faceplane,out_of_face)\
32{ \
33 _distances[0] = DISTANCE_PLANE_POINT(faceplane,v1);\
34 _distances[1] = _distances[0] * DISTANCE_PLANE_POINT(faceplane,v2);\
35 _distances[2] = _distances[0] * DISTANCE_PLANE_POINT(faceplane,v3); \
36 if(_distances[1]>0.0f && _distances[2]>0.0f)\
37 {\
38 out_of_face = 1;\
39 }\
40 else\
41 {\
42 out_of_face = 0;\
43 }\
44}\
45
46
47//! Receives the 3 edge planes
48#define MOST_DEEP_POINTS(plane,points,point_count,deep_points,deep_points_count,maxdeep)\
49{\
50 maxdeep=-1000.0f;\
51 GUINT _k;\
52 GREAL _dist;\
53 deep_points_count = 0;\
54 for(_k=0;_k<point_count;_k++)\
55 {\
56 _dist = -DISTANCE_PLANE_POINT(plane,points[_k]);\
57 if(_dist>maxdeep)\
58 {\
59 maxdeep = _dist;\
60 _max_candidates[0] = _k;\
61 deep_points_count=1;\
62 }\
63 else if((_dist+G_EPSILON)>=maxdeep)\
64 {\
65 _max_candidates[deep_points_count] = _k;\
66 deep_points_count++;\
67 }\
68 }\
69 if(maxdeep<0.0f)\
70 {\
71 deep_points_count = 0;\
72 }\
73 else\
74 {\
75 for(_k=0;_k<deep_points_count;_k++)\
76 {\
77 VEC_COPY(deep_points[_k],points[_max_candidates[_k]]);\
78 }\
79 }\
80}\
81
82//! Receives the 3 edge planes
83#define CLIP_TRI_POINTS_BY_TRI_EDGE_PLANES(tri_points,tri_edge_planes, clipped_points, clipped_point_count)\
84{\
85 clipped_point_count = 0; \
86 _temp_clip_count = 0;\
87 PLANE_CLIP_POLYGON(tri_edge_planes[0],tri_points,3,_temp_clip,_temp_clip_count,MAX_TRI_CLIPPING);\
88 if(_temp_clip_count>0)\
89 {\
90 _temp_clip_count2 = 0;\
91 PLANE_CLIP_POLYGON(tri_edge_planes[1],_temp_clip,_temp_clip_count,_temp_clip2,_temp_clip_count2,MAX_TRI_CLIPPING);\
92 if(_temp_clip_count2>0)\
93 {\
94 PLANE_CLIP_POLYGON(tri_edge_planes[2],_temp_clip2,_temp_clip_count2,clipped_points,clipped_point_count,MAX_TRI_CLIPPING);\
95 }\
96 }\
97}\
98
99
100
101int _gim_triangle_triangle_collision(
102 GIM_TRIANGLE_DATA *tri1,
103 GIM_TRIANGLE_DATA *tri2,
104 GIM_TRIANGLE_CONTACT_DATA * contact_data)
105{
106 //Cache variables for triangle intersection
107 GUINT _max_candidates[MAX_TRI_CLIPPING];
108 vec3f _temp_clip[MAX_TRI_CLIPPING];
109 GUINT _temp_clip_count = 0;
110 vec3f _temp_clip2[MAX_TRI_CLIPPING];
111 GUINT _temp_clip_count2 = 0;
112 vec3f clipped_points2[MAX_TRI_CLIPPING];
113 vec3f deep_points2[MAX_TRI_CLIPPING];
114 vec3f clipped_points1[MAX_TRI_CLIPPING];
115 vec3f deep_points1[MAX_TRI_CLIPPING];
116
117
118
119 //State variabnles
120 GUINT mostdir=0;
121 GUINT clipped2_count=0;
122
123 //Clip tri2 by tri1 edges
124
125 CLIP_TRI_POINTS_BY_TRI_EDGE_PLANES(tri2->m_vertices,(&tri1->m_planes.m_planes[1]), clipped_points2, clipped2_count);
126
127 if(clipped2_count == 0 )
128 {
129 return 0;//Reject
130 }
131
132 //find most deep interval face1
133 GUINT deep2_count=0;
134
135 GREAL maxdeep;
136
137 MOST_DEEP_POINTS((tri1->m_planes.m_planes[0]), clipped_points2, clipped2_count, deep_points2, deep2_count, maxdeep);
138 if(deep2_count==0)
139 {
140// *perror = 0.0f;
141 return 0;//Reject
142 }
143
144 //Normal pointing to triangle1
145 VEC_SCALE(contact_data->m_separating_normal,-1.0f,(tri1->m_planes.m_planes[0]));
146
147
148 //Clip tri1 by tri2 edges
149
150 GUINT clipped1_count=0;
151
152 CLIP_TRI_POINTS_BY_TRI_EDGE_PLANES(tri1->m_vertices,(&tri2->m_planes.m_planes[1]), clipped_points1, clipped1_count);
153
154 if(clipped2_count == 0 )
155 {
156// *perror = 0.0f;
157 return 0;//Reject
158 }
159
160
161 //find interval face2
162 GUINT deep1_count=0;
163
164 GREAL dist;
165
166 MOST_DEEP_POINTS((tri2->m_planes.m_planes[0]), clipped_points1, clipped1_count, deep_points1, deep1_count, dist);
167
168 if(deep1_count==0)
169 {
170// *perror = 0.0f;
171 return 0;
172 }
173
174 if(dist<maxdeep)
175 {
176 maxdeep = dist;
177 mostdir = 1;
178 VEC_COPY(contact_data->m_separating_normal,(tri2->m_planes.m_planes[0]));
179 }
180 //set deep
181 contact_data->m_penetration_depth = maxdeep;
182
183 ////check most dir for contacts
184 if(mostdir==0)
185 {
186 contact_data->m_point_count = deep2_count;
187 for(mostdir=0;mostdir<deep2_count;mostdir++)
188 {
189 VEC_COPY(contact_data->m_points[mostdir] ,deep_points2[mostdir]);
190 }
191 }
192 else
193 {
194 contact_data->m_point_count = deep1_count;
195 for(mostdir=0;mostdir<deep1_count;mostdir++)
196 {
197 VEC_COPY(contact_data->m_points[mostdir] ,deep_points1[mostdir]);
198 }
199 }
200 return 1;
201}
202
203
204
205//! Finds the contact points from a collision of two triangles
206/*!
207Returns the contact points, the penetration depth and the separating normal of the collision
208between two triangles. The normal is pointing toward triangle 1 from triangle 2
209*/
210int gim_triangle_triangle_collision(
211 GIM_TRIANGLE_DATA *tri1,
212 GIM_TRIANGLE_DATA *tri2,
213 GIM_TRIANGLE_CONTACT_DATA * contact_data)
214{
215 vec3f _distances;
216 char out_of_face=0;
217
218 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);
219 if(out_of_face==1) return 0;
220
221 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);
222 if(out_of_face==1) return 0;
223
224 return _gim_triangle_triangle_collision(tri1,tri2,contact_data);
225}
226
227//! Trimesh Trimesh Collisions
228/*!
229
230In each contact
231<ul>
232<li> m_handle1 points to trimesh1.
233<li> m_handle2 points to trimesh2.
234<li> m_feature1 Is a triangle index of trimesh1.
235<li> m_feature2 Is a triangle index of trimesh2.
236</ul>
237
238\param trimesh1 Collider
239\param trimesh2 Collidee
240\param contacts A GIM_CONTACT array. Must be initialized
241*/
242void gim_trimesh_trimesh_collision(GIM_TRIMESH * trimesh1, GIM_TRIMESH * trimesh2, GDYNAMIC_ARRAY * contacts)
243{
244 contacts->m_size = 0;
245 GDYNAMIC_ARRAY collision_pairs;
246 GIM_CREATE_PAIR_SET(collision_pairs)
247
248 gim_aabbset_bipartite_intersections(&trimesh1->m_aabbset,&trimesh2->m_aabbset,&collision_pairs);
249
250 if(collision_pairs.m_size==0)
251 {
252 GIM_DYNARRAY_DESTROY(collision_pairs);
253 return; //no collisioin
254 }
255
256 //Locks meshes
257 gim_trimesh_locks_work_data(trimesh1);
258 gim_trimesh_locks_work_data(trimesh2);
259
260
261 //pair pointer
262 GIM_PAIR *pairs = GIM_DYNARRAY_POINTER(GIM_PAIR,collision_pairs);
263 //dummy contacts
264 GDYNAMIC_ARRAY dummycontacts;
265 GIM_CREATE_CONTACT_LIST(dummycontacts);
266
267 //Auxiliary triangle data
268 GIM_TRIANGLE_CONTACT_DATA tri_contact_data;
269 GIM_TRIANGLE_DATA tri1data,tri2data;
270
271
272 GUINT i, ti1,ti2,ci;
273 int colresult;
274 for (i=0;i<collision_pairs.m_size; i++)
275 {
276 ti1 = pairs[i].m_index1;
277 ti2 = pairs[i].m_index2;
278 //Get triangles data
279 gim_trimesh_get_triangle_data(trimesh1,ti1,&tri1data);
280 gim_trimesh_get_triangle_data(trimesh2,ti2,&tri2data);
281
282 //collide triangles
283 colresult = gim_triangle_triangle_collision(&tri1data,&tri2data,&tri_contact_data);
284 if(colresult == 1)
285 {
286 //Add contacts
287 for (ci=0;ci<tri_contact_data.m_point_count ;ci++ )
288 {
289 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);
290 }
291 }
292 }
293
294 if(dummycontacts.m_size == 0) //reject
295 {
296 GIM_DYNARRAY_DESTROY(dummycontacts);
297 GIM_DYNARRAY_DESTROY(collision_pairs);
298 return;
299 }
300 //merge contacts
301 gim_merge_contacts(&dummycontacts,contacts);
302
303 //Terminate
304 GIM_DYNARRAY_DESTROY(dummycontacts);
305 GIM_DYNARRAY_DESTROY(collision_pairs);
306
307 //Unlocks meshes
308 gim_trimesh_unlocks_work_data(trimesh1);
309 gim_trimesh_unlocks_work_data(trimesh2);
310}
311
312
313//! Trimesh Plane Collisions
314/*!
315
316\param trimesh
317\param plane vec4f plane
318\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.
319*/
320void gim_trimesh_plane_collision(GIM_TRIMESH * trimesh,vec4f plane, GDYNAMIC_ARRAY * contacts)
321{
322 contacts->m_size = 0;
323 char classify;
324 PLANE_CLASSIFY_BOX(plane,trimesh->m_aabbset.m_global_bound,classify);
325 if(classify>1) return; // in front of plane
326
327 //Locks mesh
328 gim_trimesh_locks_work_data(trimesh);
329 //Get vertices
330 GUINT i, vertcount = trimesh->m_transformed_vertex_buffer.m_element_count;
331 vec3f * vertices = GIM_BUFFER_ARRAY_POINTER(vec3f,trimesh->m_transformed_vertex_buffer,0);
332
333 GREAL dist;
334 vec4f * result_contact;
335
336 for (i=0;i<vertcount;i++)
337 {
338 dist = DISTANCE_PLANE_POINT(plane,vertices[i]);
339 if(dist<=0.0f)
340 {
341 GIM_DYNARRAY_PUSH_EMPTY(vec4f,(*contacts));
342 result_contact = GIM_DYNARRAY_POINTER_LAST(vec4f,(*contacts));
343 VEC_COPY((*result_contact),vertices[i]);
344 (*result_contact)[3] = -dist;
345 }
346 }
347 gim_trimesh_unlocks_work_data(trimesh);
348}
diff --git a/libraries/ode-0.9/GIMPACT/src/gimpact.cpp b/libraries/ode-0.9/GIMPACT/src/gimpact.cpp
new file mode 100644
index 0000000..18f1fc8
--- /dev/null
+++ b/libraries/ode-0.9/GIMPACT/src/gimpact.cpp
@@ -0,0 +1,39 @@
1
2/*
3-----------------------------------------------------------------------------
4This source file is part of GIMPACT Library.
5
6For the latest info, see http://gimpact.sourceforge.net/
7
8Copyright (c) 2006 Francisco Leon. C.C. 80087371.
9email: projectileman@yahoo.com
10
11 This library is free software; you can redistribute it and/or
12 modify it under the terms of EITHER:
13 (1) The GNU Lesser General Public License as published by the Free
14 Software Foundation; either version 2.1 of the License, or (at
15 your option) any later version. The text of the GNU Lesser
16 General Public License is included with this library in the
17 file GIMPACT-LICENSE-LGPL.TXT.
18 (2) The BSD-style license that is included with this library in
19 the file GIMPACT-LICENSE-BSD.TXT.
20
21 This library is distributed in the hope that it will be useful,
22 but WITHOUT ANY WARRANTY; without even the implied warranty of
23 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files
24 GIMPACT-LICENSE-LGPL.TXT and GIMPACT-LICENSE-BSD.TXT for more details.
25
26-----------------------------------------------------------------------------
27*/
28
29#include "GIMPACT/gimpact.h"
30
31void gimpact_init()
32{
33 gim_init_math();
34 gim_init_buffer_managers();
35}
36void gimpact_terminate()
37{
38 gim_terminate_buffer_managers();
39}