gimpact 0.2 prep

This commit is contained in:
ejcoumans 2007-06-22 16:59:13 +00:00
parent a399784077
commit 55258a8a72
36 changed files with 0 additions and 12082 deletions

View File

@ -1,19 +0,0 @@
INCLUDE_DIRECTORIES(
${BULLET_PHYSICS_SOURCE_DIR}/Extras/GIMPACT/include
)
ADD_LIBRARY(LibGIMPACT
src/gim_boxpruning.cpp
src/gim_contact.cpp
src/gim_math.cpp
src/gim_memory.cpp
src/gim_tri_tri_overlap.cpp
src/gim_trimesh.cpp
src/gim_trimesh_capsule_collision.cpp
src/gim_trimesh_data.cpp
src/gim_trimesh_ray_collision.cpp
src/gim_trimesh_sphere_collision.cpp
src/gim_trimesh_trimesh_collision.cpp
src/gim_vertex_buffer_util.cpp
src/gimpact.cpp
)

View File

@ -1,267 +0,0 @@
# Doxyfile 1.4.4
#---------------------------------------------------------------------------
# Project related configuration options
#---------------------------------------------------------------------------
PROJECT_NAME = GIMPACT
PROJECT_NUMBER = 0.0.1a
OUTPUT_DIRECTORY = docs
CREATE_SUBDIRS = YES
OUTPUT_LANGUAGE = English
USE_WINDOWS_ENCODING = YES
BRIEF_MEMBER_DESC = YES
REPEAT_BRIEF = YES
ABBREVIATE_BRIEF = "The $name class" \
"The $name widget" \
"The $name file" \
is \
provides \
specifies \
contains \
represents \
a \
an \
the
ALWAYS_DETAILED_SEC = NO
INLINE_INHERITED_MEMB = NO
FULL_PATH_NAMES = YES
STRIP_FROM_PATH = "C:/Documents and Settings/Administrador/"
STRIP_FROM_INC_PATH =
SHORT_NAMES = YES
JAVADOC_AUTOBRIEF = NO
MULTILINE_CPP_IS_BRIEF = YES
DETAILS_AT_TOP = NO
INHERIT_DOCS = YES
DISTRIBUTE_GROUP_DOC = NO
SEPARATE_MEMBER_PAGES = NO
TAB_SIZE = 8
ALIASES =
OPTIMIZE_OUTPUT_FOR_C = YES
OPTIMIZE_OUTPUT_JAVA = NO
SUBGROUPING = YES
#---------------------------------------------------------------------------
# Build related configuration options
#---------------------------------------------------------------------------
EXTRACT_ALL = NO
EXTRACT_PRIVATE = NO
EXTRACT_STATIC = NO
EXTRACT_LOCAL_CLASSES = YES
EXTRACT_LOCAL_METHODS = YES
HIDE_UNDOC_MEMBERS = YES
HIDE_UNDOC_CLASSES = YES
HIDE_FRIEND_COMPOUNDS = NO
HIDE_IN_BODY_DOCS = NO
INTERNAL_DOCS = NO
CASE_SENSE_NAMES = NO
HIDE_SCOPE_NAMES = NO
SHOW_INCLUDE_FILES = YES
INLINE_INFO = YES
SORT_MEMBER_DOCS = YES
SORT_BRIEF_DOCS = NO
SORT_BY_SCOPE_NAME = YES
GENERATE_TODOLIST = YES
GENERATE_TESTLIST = YES
GENERATE_BUGLIST = YES
GENERATE_DEPRECATEDLIST= YES
ENABLED_SECTIONS =
MAX_INITIALIZER_LINES = 30
SHOW_USED_FILES = YES
SHOW_DIRECTORIES = NO
FILE_VERSION_FILTER =
#---------------------------------------------------------------------------
# configuration options related to warning and progress messages
#---------------------------------------------------------------------------
QUIET = NO
WARNINGS = YES
WARN_IF_UNDOCUMENTED = YES
WARN_IF_DOC_ERROR = YES
WARN_NO_PARAMDOC = NO
WARN_FORMAT = "$file:$line: $text"
WARN_LOGFILE =
#---------------------------------------------------------------------------
# configuration options related to the input files
#---------------------------------------------------------------------------
INPUT = include/GIMPACT/gim_boxpruning.h \
include/GIMPACT/gim_contact.h \
include/GIMPACT/gim_geometry.h \
include/GIMPACT/gim_math.h \
include/GIMPACT/gim_memory.h \
include/GIMPACT/gim_radixsort.h \
include/GIMPACT/gim_tri_capsule_collision.h \
include/GIMPACT/gim_tri_collision.h \
include/GIMPACT/gim_tri_sphere_collision.h \
include/GIMPACT/gim_trimesh.h \
include/GIMPACT/gimpact.h
FILE_PATTERNS = *.c \
*.cc \
*.cxx \
*.cpp \
*.c++ \
*.d \
*.java \
*.ii \
*.ixx \
*.ipp \
*.i++ \
*.inl \
*.h \
*.hh \
*.hxx \
*.hpp \
*.h++ \
*.idl \
*.odl \
*.cs \
*.php \
*.php3 \
*.inc \
*.m \
*.mm \
*.dox
RECURSIVE = NO
EXCLUDE =
EXCLUDE_SYMLINKS = NO
EXCLUDE_PATTERNS =
EXAMPLE_PATH =
EXAMPLE_PATTERNS = *
EXAMPLE_RECURSIVE = NO
IMAGE_PATH =
INPUT_FILTER =
FILTER_PATTERNS =
FILTER_SOURCE_FILES = NO
#---------------------------------------------------------------------------
# configuration options related to source browsing
#---------------------------------------------------------------------------
SOURCE_BROWSER = NO
INLINE_SOURCES = NO
STRIP_CODE_COMMENTS = YES
REFERENCED_BY_RELATION = NO
REFERENCES_RELATION = NO
USE_HTAGS = NO
VERBATIM_HEADERS = NO
#---------------------------------------------------------------------------
# configuration options related to the alphabetical class index
#---------------------------------------------------------------------------
ALPHABETICAL_INDEX = YES
COLS_IN_ALPHA_INDEX = 5
IGNORE_PREFIX =
#---------------------------------------------------------------------------
# configuration options related to the HTML output
#---------------------------------------------------------------------------
GENERATE_HTML = YES
HTML_OUTPUT = html
HTML_FILE_EXTENSION = .html
HTML_HEADER =
HTML_FOOTER =
HTML_STYLESHEET =
HTML_ALIGN_MEMBERS = YES
GENERATE_HTMLHELP = NO
CHM_FILE =
HHC_LOCATION =
GENERATE_CHI = NO
BINARY_TOC = NO
TOC_EXPAND = NO
DISABLE_INDEX = NO
ENUM_VALUES_PER_LINE = 4
GENERATE_TREEVIEW = NO
TREEVIEW_WIDTH = 250
#---------------------------------------------------------------------------
# configuration options related to the LaTeX output
#---------------------------------------------------------------------------
GENERATE_LATEX = NO
LATEX_OUTPUT = latex
LATEX_CMD_NAME = latex
MAKEINDEX_CMD_NAME = makeindex
COMPACT_LATEX = NO
PAPER_TYPE = a4wide
EXTRA_PACKAGES =
LATEX_HEADER =
PDF_HYPERLINKS = NO
USE_PDFLATEX = NO
LATEX_BATCHMODE = NO
LATEX_HIDE_INDICES = NO
#---------------------------------------------------------------------------
# configuration options related to the RTF output
#---------------------------------------------------------------------------
GENERATE_RTF = NO
RTF_OUTPUT = rtf
COMPACT_RTF = NO
RTF_HYPERLINKS = NO
RTF_STYLESHEET_FILE =
RTF_EXTENSIONS_FILE =
#---------------------------------------------------------------------------
# configuration options related to the man page output
#---------------------------------------------------------------------------
GENERATE_MAN = NO
MAN_OUTPUT = man
MAN_EXTENSION = .3
MAN_LINKS = NO
#---------------------------------------------------------------------------
# configuration options related to the XML output
#---------------------------------------------------------------------------
GENERATE_XML = NO
XML_OUTPUT = xml
XML_SCHEMA =
XML_DTD =
XML_PROGRAMLISTING = YES
#---------------------------------------------------------------------------
# configuration options for the AutoGen Definitions output
#---------------------------------------------------------------------------
GENERATE_AUTOGEN_DEF = NO
#---------------------------------------------------------------------------
# configuration options related to the Perl module output
#---------------------------------------------------------------------------
GENERATE_PERLMOD = NO
PERLMOD_LATEX = NO
PERLMOD_PRETTY = YES
PERLMOD_MAKEVAR_PREFIX =
#---------------------------------------------------------------------------
# Configuration options related to the preprocessor
#---------------------------------------------------------------------------
ENABLE_PREPROCESSING = YES
MACRO_EXPANSION = YES
EXPAND_ONLY_PREDEF = NO
SEARCH_INCLUDES = YES
INCLUDE_PATH =
INCLUDE_FILE_PATTERNS =
PREDEFINED =
EXPAND_AS_DEFINED =
SKIP_FUNCTION_MACROS = YES
#---------------------------------------------------------------------------
# Configuration::additions related to external references
#---------------------------------------------------------------------------
TAGFILES =
GENERATE_TAGFILE =
ALLEXTERNALS = NO
EXTERNAL_GROUPS = YES
PERL_PATH = /usr/bin/perl
#---------------------------------------------------------------------------
# Configuration options related to the dot tool
#---------------------------------------------------------------------------
CLASS_DIAGRAMS = NO
HIDE_UNDOC_RELATIONS = YES
HAVE_DOT = NO
CLASS_GRAPH = YES
COLLABORATION_GRAPH = YES
GROUP_GRAPHS = YES
UML_LOOK = NO
TEMPLATE_RELATIONS = NO
INCLUDE_GRAPH = YES
INCLUDED_BY_GRAPH = YES
CALL_GRAPH = NO
GRAPHICAL_HIERARCHY = YES
DIRECTORY_GRAPH = YES
DOT_IMAGE_FORMAT = png
DOT_PATH =
DOTFILE_DIRS =
MAX_DOT_GRAPH_WIDTH = 1024
MAX_DOT_GRAPH_HEIGHT = 1024
MAX_DOT_GRAPH_DEPTH = 1000
DOT_TRANSPARENT = NO
DOT_MULTI_TARGETS = NO
GENERATE_LEGEND = YES
DOT_CLEANUP = YES
#---------------------------------------------------------------------------
# Configuration::additions related to the search engine
#---------------------------------------------------------------------------
SEARCHENGINE = NO

View File

@ -1,29 +0,0 @@
GIMPACT : Geometric tools for VR.
Copyright (c) 2006 , Francisco León.
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list of
conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this list
of conditions and the following disclaimer in the documentation and/or other materials
provided with the distribution.
* Neither the name of the GIMPACT nor the names of its contributors may be used
to endorse or promote products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
DAMAGE.

View File

@ -1,502 +0,0 @@
GNU LESSER GENERAL PUBLIC LICENSE
Version 2.1, February 1999
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
[This is the first released version of the Lesser GPL. It also counts
as the successor of the GNU Library Public License, version 2, hence
the version number 2.1.]
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
Licenses are intended to guarantee your freedom to share and change
free software--to make sure the software is free for all its users.
This license, the Lesser General Public License, applies to some
specially designated software packages--typically libraries--of the
Free Software Foundation and other authors who decide to use it. You
can use it too, but we suggest you first think carefully about whether
this license or the ordinary General Public License is the better
strategy to use in any particular case, based on the explanations below.
When we speak of free software, we are referring to freedom of use,
not price. Our General Public Licenses are designed to make sure that
you have the freedom to distribute copies of free software (and charge
for this service if you wish); that you receive source code or can get
it if you want it; that you can change the software and use pieces of
it in new free programs; and that you are informed that you can do
these things.
To protect your rights, we need to make restrictions that forbid
distributors to deny you these rights or to ask you to surrender these
rights. These restrictions translate to certain responsibilities for
you if you distribute copies of the library or if you modify it.
For example, if you distribute copies of the library, whether gratis
or for a fee, you must give the recipients all the rights that we gave
you. You must make sure that they, too, receive or can get the source
code. If you link other code with the library, you must provide
complete object files to the recipients, so that they can relink them
with the library after making changes to the library and recompiling
it. And you must show them these terms so they know their rights.
We protect your rights with a two-step method: (1) we copyright the
library, and (2) we offer you this license, which gives you legal
permission to copy, distribute and/or modify the library.
To protect each distributor, we want to make it very clear that
there is no warranty for the free library. Also, if the library is
modified by someone else and passed on, the recipients should know
that what they have is not the original version, so that the original
author's reputation will not be affected by problems that might be
introduced by others.
Finally, software patents pose a constant threat to the existence of
any free program. We wish to make sure that a company cannot
effectively restrict the users of a free program by obtaining a
restrictive license from a patent holder. Therefore, we insist that
any patent license obtained for a version of the library must be
consistent with the full freedom of use specified in this license.
Most GNU software, including some libraries, is covered by the
ordinary GNU General Public License. This license, the GNU Lesser
General Public License, applies to certain designated libraries, and
is quite different from the ordinary General Public License. We use
this license for certain libraries in order to permit linking those
libraries into non-free programs.
When a program is linked with a library, whether statically or using
a shared library, the combination of the two is legally speaking a
combined work, a derivative of the original library. The ordinary
General Public License therefore permits such linking only if the
entire combination fits its criteria of freedom. The Lesser General
Public License permits more lax criteria for linking other code with
the library.
We call this license the "Lesser" General Public License because it
does Less to protect the user's freedom than the ordinary General
Public License. It also provides other free software developers Less
of an advantage over competing non-free programs. These disadvantages
are the reason we use the ordinary General Public License for many
libraries. However, the Lesser license provides advantages in certain
special circumstances.
For example, on rare occasions, there may be a special need to
encourage the widest possible use of a certain library, so that it becomes
a de-facto standard. To achieve this, non-free programs must be
allowed to use the library. A more frequent case is that a free
library does the same job as widely used non-free libraries. In this
case, there is little to gain by limiting the free library to free
software only, so we use the Lesser General Public License.
In other cases, permission to use a particular library in non-free
programs enables a greater number of people to use a large body of
free software. For example, permission to use the GNU C Library in
non-free programs enables many more people to use the whole GNU
operating system, as well as its variant, the GNU/Linux operating
system.
Although the Lesser General Public License is Less protective of the
users' freedom, it does ensure that the user of a program that is
linked with the Library has the freedom and the wherewithal to run
that program using a modified version of the Library.
The precise terms and conditions for copying, distribution and
modification follow. Pay close attention to the difference between a
"work based on the library" and a "work that uses the library". The
former contains code derived from the library, whereas the latter must
be combined with the library in order to run.
GNU LESSER GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License Agreement applies to any software library or other
program which contains a notice placed by the copyright holder or
other authorized party saying it may be distributed under the terms of
this Lesser General Public License (also called "this License").
Each licensee is addressed as "you".
A "library" means a collection of software functions and/or data
prepared so as to be conveniently linked with application programs
(which use some of those functions and data) to form executables.
The "Library", below, refers to any such software library or work
which has been distributed under these terms. A "work based on the
Library" means either the Library or any derivative work under
copyright law: that is to say, a work containing the Library or a
portion of it, either verbatim or with modifications and/or translated
straightforwardly into another language. (Hereinafter, translation is
included without limitation in the term "modification".)
"Source code" for a work means the preferred form of the work for
making modifications to it. For a library, complete source code means
all the source code for all modules it contains, plus any associated
interface definition files, plus the scripts used to control compilation
and installation of the library.
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running a program using the Library is not restricted, and output from
such a program is covered only if its contents constitute a work based
on the Library (independent of the use of the Library in a tool for
writing it). Whether that is true depends on what the Library does
and what the program that uses the Library does.
1. You may copy and distribute verbatim copies of the Library's
complete source code as you receive it, in any medium, provided that
you conspicuously and appropriately publish on each copy an
appropriate copyright notice and disclaimer of warranty; keep intact
all the notices that refer to this License and to the absence of any
warranty; and distribute a copy of this License along with the
Library.
You may charge a fee for the physical act of transferring a copy,
and you may at your option offer warranty protection in exchange for a
fee.
2. You may modify your copy or copies of the Library or any portion
of it, thus forming a work based on the Library, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) The modified work must itself be a software library.
b) You must cause the files modified to carry prominent notices
stating that you changed the files and the date of any change.
c) You must cause the whole of the work to be licensed at no
charge to all third parties under the terms of this License.
d) If a facility in the modified Library refers to a function or a
table of data to be supplied by an application program that uses
the facility, other than as an argument passed when the facility
is invoked, then you must make a good faith effort to ensure that,
in the event an application does not supply such function or
table, the facility still operates, and performs whatever part of
its purpose remains meaningful.
(For example, a function in a library to compute square roots has
a purpose that is entirely well-defined independent of the
application. Therefore, Subsection 2d requires that any
application-supplied function or table used by this function must
be optional: if the application does not supply it, the square
root function must still compute square roots.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Library,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Library, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote
it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Library.
In addition, mere aggregation of another work not based on the Library
with the Library (or with a work based on the Library) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may opt to apply the terms of the ordinary GNU General Public
License instead of this License to a given copy of the Library. To do
this, you must alter all the notices that refer to this License, so
that they refer to the ordinary GNU General Public License, version 2,
instead of to this License. (If a newer version than version 2 of the
ordinary GNU General Public License has appeared, then you can specify
that version instead if you wish.) Do not make any other change in
these notices.
Once this change is made in a given copy, it is irreversible for
that copy, so the ordinary GNU General Public License applies to all
subsequent copies and derivative works made from that copy.
This option is useful when you wish to copy part of the code of
the Library into a program that is not a library.
4. You may copy and distribute the Library (or a portion or
derivative of it, under Section 2) in object code or executable form
under the terms of Sections 1 and 2 above provided that you accompany
it with the complete corresponding machine-readable source code, which
must be distributed under the terms of Sections 1 and 2 above on a
medium customarily used for software interchange.
If distribution of object code is made by offering access to copy
from a designated place, then offering equivalent access to copy the
source code from the same place satisfies the requirement to
distribute the source code, even though third parties are not
compelled to copy the source along with the object code.
5. A program that contains no derivative of any portion of the
Library, but is designed to work with the Library by being compiled or
linked with it, is called a "work that uses the Library". Such a
work, in isolation, is not a derivative work of the Library, and
therefore falls outside the scope of this License.
However, linking a "work that uses the Library" with the Library
creates an executable that is a derivative of the Library (because it
contains portions of the Library), rather than a "work that uses the
library". The executable is therefore covered by this License.
Section 6 states terms for distribution of such executables.
When a "work that uses the Library" uses material from a header file
that is part of the Library, the object code for the work may be a
derivative work of the Library even though the source code is not.
Whether this is true is especially significant if the work can be
linked without the Library, or if the work is itself a library. The
threshold for this to be true is not precisely defined by law.
If such an object file uses only numerical parameters, data
structure layouts and accessors, and small macros and small inline
functions (ten lines or less in length), then the use of the object
file is unrestricted, regardless of whether it is legally a derivative
work. (Executables containing this object code plus portions of the
Library will still fall under Section 6.)
Otherwise, if the work is a derivative of the Library, you may
distribute the object code for the work under the terms of Section 6.
Any executables containing that work also fall under Section 6,
whether or not they are linked directly with the Library itself.
6. As an exception to the Sections above, you may also combine or
link a "work that uses the Library" with the Library to produce a
work containing portions of the Library, and distribute that work
under terms of your choice, provided that the terms permit
modification of the work for the customer's own use and reverse
engineering for debugging such modifications.
You must give prominent notice with each copy of the work that the
Library is used in it and that the Library and its use are covered by
this License. You must supply a copy of this License. If the work
during execution displays copyright notices, you must include the
copyright notice for the Library among them, as well as a reference
directing the user to the copy of this License. Also, you must do one
of these things:
a) Accompany the work with the complete corresponding
machine-readable source code for the Library including whatever
changes were used in the work (which must be distributed under
Sections 1 and 2 above); and, if the work is an executable linked
with the Library, with the complete machine-readable "work that
uses the Library", as object code and/or source code, so that the
user can modify the Library and then relink to produce a modified
executable containing the modified Library. (It is understood
that the user who changes the contents of definitions files in the
Library will not necessarily be able to recompile the application
to use the modified definitions.)
b) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (1) uses at run time a
copy of the library already present on the user's computer system,
rather than copying library functions into the executable, and (2)
will operate properly with a modified version of the library, if
the user installs one, as long as the modified version is
interface-compatible with the version that the work was made with.
c) Accompany the work with a written offer, valid for at
least three years, to give the same user the materials
specified in Subsection 6a, above, for a charge no more
than the cost of performing this distribution.
d) If distribution of the work is made by offering access to copy
from a designated place, offer equivalent access to copy the above
specified materials from the same place.
e) Verify that the user has already received a copy of these
materials or that you have already sent this user a copy.
For an executable, the required form of the "work that uses the
Library" must include any data and utility programs needed for
reproducing the executable from it. However, as a special exception,
the materials to be distributed need not include anything that is
normally distributed (in either source or binary form) with the major
components (compiler, kernel, and so on) of the operating system on
which the executable runs, unless that component itself accompanies
the executable.
It may happen that this requirement contradicts the license
restrictions of other proprietary libraries that do not normally
accompany the operating system. Such a contradiction means you cannot
use both them and the Library together in an executable that you
distribute.
7. You may place library facilities that are a work based on the
Library side-by-side in a single library together with other library
facilities not covered by this License, and distribute such a combined
library, provided that the separate distribution of the work based on
the Library and of the other library facilities is otherwise
permitted, and provided that you do these two things:
a) Accompany the combined library with a copy of the same work
based on the Library, uncombined with any other library
facilities. This must be distributed under the terms of the
Sections above.
b) Give prominent notice with the combined library of the fact
that part of it is a work based on the Library, and explaining
where to find the accompanying uncombined form of the same work.
8. You may not copy, modify, sublicense, link with, or distribute
the Library except as expressly provided under this License. Any
attempt otherwise to copy, modify, sublicense, link with, or
distribute the Library is void, and will automatically terminate your
rights under this License. However, parties who have received copies,
or rights, from you under this License will not have their licenses
terminated so long as such parties remain in full compliance.
9. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Library or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Library (or any work based on the
Library), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Library or works based on it.
10. Each time you redistribute the Library (or any work based on the
Library), the recipient automatically receives a license from the
original licensor to copy, distribute, link with or modify the Library
subject to these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties with
this License.
11. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Library at all. For example, if a patent
license would not permit royalty-free redistribution of the Library by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Library.
If any portion of this section is held invalid or unenforceable under any
particular circumstance, the balance of the section is intended to apply,
and the section as a whole is intended to apply in other circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
12. If the distribution and/or use of the Library is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Library under this License may add
an explicit geographical distribution limitation excluding those countries,
so that distribution is permitted only in or among countries not thus
excluded. In such case, this License incorporates the limitation as if
written in the body of this License.
13. The Free Software Foundation may publish revised and/or new
versions of the Lesser General Public License from time to time.
Such new versions will be similar in spirit to the present version,
but may differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the Library
specifies a version number of this License which applies to it and
"any later version", you have the option of following the terms and
conditions either of that version or of any later version published by
the Free Software Foundation. If the Library does not specify a
license version number, you may choose any version ever published by
the Free Software Foundation.
14. If you wish to incorporate parts of the Library into other free
programs whose distribution conditions are incompatible with these,
write to the author to ask for permission. For software which is
copyrighted by the Free Software Foundation, write to the Free
Software Foundation; we sometimes make exceptions for this. Our
decision will be guided by the two goals of preserving the free status
of all derivatives of our free software and of promoting the sharing
and reuse of software generally.
NO WARRANTY
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Libraries
If you develop a new library, and you want it to be of the greatest
possible use to the public, we recommend making it free software that
everyone can redistribute and change. You can do so by permitting
redistribution under these terms (or, alternatively, under the terms of the
ordinary General Public License).
To apply these terms, attach the following notices to the library. It is
safest to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least the
"copyright" line and a pointer to where the full notice is found.
<one line to give the library's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Also add information on how to contact you by electronic and paper mail.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the library, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the
library `Frob' (a library for tweaking knobs) written by James Random Hacker.
<signature of Ty Coon>, 1 April 1990
Ty Coon, President of Vice
That's all there is to it!

View File

@ -1,23 +0,0 @@
GIMPACT : Geometric tools for VR.
Copyright (c) 2006 , Francisco León.
All rights reserved.
This software is provided 'as-is', without any express or implied warranty. In no
event will the authors be held liable for any damages arising from the use of this
software.
Permission is granted to anyone to use this software for any purpose, including commercial
applications, and to alter it and redistribute it freely, subject to the following
restrictions:
1. The origin of this software must not be misrepresented; you must not claim that
you wrote the original software. If you use this software in a product, an
acknowledgment in the product documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.

View File

@ -1,208 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<CodeBlocks_project_file>
<FileVersion major="1" minor="5" />
<Project>
<Option title="GIMPACT" />
<Option pch_mode="2" />
<Option default_target="" />
<Option compiler="gcc" />
<Option virtualFolders="" />
<Build>
<Target title="Release">
<Option output="lib\Release\libGIMPACT.a" />
<Option working_dir="" />
<Option object_output="obj\Release\" />
<Option type="2" />
<Option compiler="gcc" />
<Compiler>
<Add option="-O2" />
</Compiler>
<Linker>
<Add option="-s" />
</Linker>
</Target>
<Target title="Debug">
<Option output="lib\Debug\libGIMPACT.a" />
<Option working_dir="" />
<Option object_output="obj\Debug\" />
<Option type="2" />
<Option compiler="gcc" />
<Compiler>
<Add option="-g" />
</Compiler>
</Target>
</Build>
<Compiler>
<Add option="-march=pentium3" />
<Add option="-Wall" />
<Add directory="include" />
<Add directory="include\simd" />
<Add directory="include\simd\double" />
<Add directory="include\simd\single" />
</Compiler>
<Unit filename="include\GIMPACT\gim_box_collision.h">
<Option compilerVar="CPP" />
<Option compile="0" />
<Option link="0" />
<Option target="Release" />
<Option target="Debug" />
</Unit>
<Unit filename="include\GIMPACT\gim_boxpruning.h">
<Option compilerVar="CPP" />
<Option compile="0" />
<Option link="0" />
<Option target="Release" />
<Option target="Debug" />
</Unit>
<Unit filename="include\GIMPACT\gim_contact.h">
<Option compilerVar="CPP" />
<Option compile="0" />
<Option link="0" />
<Option target="Release" />
<Option target="Debug" />
</Unit>
<Unit filename="include\GIMPACT\gim_geometry.h">
<Option compilerVar="CPP" />
<Option compile="0" />
<Option link="0" />
<Option target="Release" />
<Option target="Debug" />
</Unit>
<Unit filename="include\GIMPACT\gim_math.h">
<Option compilerVar="CPP" />
<Option compile="0" />
<Option link="0" />
<Option target="Release" />
<Option target="Debug" />
</Unit>
<Unit filename="include\GIMPACT\gim_memory.h">
<Option compilerVar="CPP" />
<Option compile="0" />
<Option link="0" />
<Option target="Release" />
<Option target="Debug" />
</Unit>
<Unit filename="include\GIMPACT\gim_radixsort.h">
<Option compilerVar="CPP" />
<Option compile="0" />
<Option link="0" />
<Option target="Release" />
<Option target="Debug" />
</Unit>
<Unit filename="include\GIMPACT\gim_tri_capsule_collision.h">
<Option compilerVar="CPP" />
<Option compile="0" />
<Option link="0" />
<Option target="Release" />
<Option target="Debug" />
</Unit>
<Unit filename="include\GIMPACT\gim_tri_collision.h">
<Option compilerVar="CPP" />
<Option compile="0" />
<Option link="0" />
<Option target="Release" />
<Option target="Debug" />
</Unit>
<Unit filename="include\GIMPACT\gim_tri_sphere_collision.h">
<Option compilerVar="CPP" />
<Option compile="0" />
<Option link="0" />
<Option target="Release" />
<Option target="Debug" />
</Unit>
<Unit filename="include\GIMPACT\gim_trimesh.h">
<Option compilerVar="CPP" />
<Option compile="0" />
<Option link="0" />
<Option target="Release" />
<Option target="Debug" />
</Unit>
<Unit filename="include\GIMPACT\gim_trimesh_data.h">
<Option compilerVar="CPP" />
<Option compile="0" />
<Option link="0" />
<Option target="Release" />
<Option target="Debug" />
</Unit>
<Unit filename="include\GIMPACT\gim_vertex_buffer_util.h">
<Option compilerVar="CPP" />
<Option compile="0" />
<Option link="0" />
<Option target="Release" />
<Option target="Debug" />
</Unit>
<Unit filename="include\GIMPACT\gimpact.h">
<Option compilerVar="CPP" />
<Option compile="0" />
<Option link="0" />
<Option target="Release" />
<Option target="Debug" />
</Unit>
<Unit filename="src\gim_boxpruning.cpp">
<Option compilerVar="CPP" />
<Option target="Release" />
<Option target="Debug" />
</Unit>
<Unit filename="src\gim_contact.cpp">
<Option compilerVar="CPP" />
<Option target="Release" />
<Option target="Debug" />
</Unit>
<Unit filename="src\gim_math.cpp">
<Option compilerVar="CPP" />
<Option target="Release" />
<Option target="Debug" />
</Unit>
<Unit filename="src\gim_memory.cpp">
<Option compilerVar="CPP" />
<Option target="Release" />
<Option target="Debug" />
</Unit>
<Unit filename="src\gim_tri_tri_overlap.cpp">
<Option compilerVar="CPP" />
<Option target="Release" />
<Option target="Debug" />
</Unit>
<Unit filename="src\gim_trimesh.cpp">
<Option compilerVar="CPP" />
<Option target="Release" />
<Option target="Debug" />
</Unit>
<Unit filename="src\gim_trimesh_capsule_collision.cpp">
<Option compilerVar="CPP" />
<Option target="Release" />
<Option target="Debug" />
</Unit>
<Unit filename="src\gim_trimesh_data.cpp">
<Option compilerVar="CPP" />
<Option target="Release" />
<Option target="Debug" />
</Unit>
<Unit filename="src\gim_trimesh_ray_collision.cpp">
<Option compilerVar="CPP" />
<Option target="Release" />
<Option target="Debug" />
</Unit>
<Unit filename="src\gim_trimesh_sphere_collision.cpp">
<Option compilerVar="CPP" />
<Option target="Release" />
<Option target="Debug" />
</Unit>
<Unit filename="src\gim_trimesh_trimesh_collision.cpp">
<Option compilerVar="CPP" />
<Option target="Release" />
<Option target="Debug" />
</Unit>
<Unit filename="src\gim_vertex_buffer_util.cpp">
<Option compilerVar="CPP" />
<Option target="Release" />
<Option target="Debug" />
</Unit>
<Unit filename="src\gimpact.cpp">
<Option compilerVar="CPP" />
<Option target="Release" />
<Option target="Debug" />
</Unit>
<Extensions />
</Project>
</CodeBlocks_project_file>

View File

@ -1,307 +0,0 @@
# depslib dependency file v1.0
1159964131 source:c:\libreriaswx\oldgammaleon_reloaded\gammaleon\source\gimpact\src\gim_contact.cpp
"GIMPACT/gim_contact.h"
<sglib.h>
1159989774 c:\libreriaswx\oldgammaleon_reloaded\gammaleon\source\gimpact\include\gimpact\gim_contact.h
"GIMPACT/gim_geometry.h"
"GIMPACT/gim_radixsort.h"
1159995618 c:\libreriaswx\oldgammaleon_reloaded\gammaleon\source\gimpact\include\gimpact\gim_geometry.h
"GIMPACT/gim_math.h"
"GIMPACT/gim_tri_collision.h"
1159971186 c:\libreriaswx\oldgammaleon_reloaded\gammaleon\source\gimpact\include\gimpact\gim_math.h
<math.h>
<float.h>
1159989774 c:\libreriaswx\oldgammaleon_reloaded\gammaleon\source\gimpact\include\gimpact\gim_tri_collision.h
1159989774 c:\libreriaswx\oldgammaleon_reloaded\gammaleon\source\gimpact\include\gimpact\gim_radixsort.h
"GIMPACT/gim_memory.h"
1159989774 c:\libreriaswx\oldgammaleon_reloaded\gammaleon\source\gimpact\include\gimpact\gim_memory.h
"GIMPACT/gim_math.h"
<memory.h>
<xmmintrin.h>
1159921899 source:c:\libreriaswx\oldgammaleon_reloaded\gammaleon\source\gimpact\src\gim_math.cpp
"GIMPACT/gim_math.h"
"stdlib.h"
"time.h"
1159964559 source:c:\libreriaswx\oldgammaleon_reloaded\gammaleon\source\gimpact\src\gim_memory.cpp
"GIMPACT/gim_memory.h"
"stdlib.h"
"malloc.h"
1159992522 source:c:\libreriaswx\oldgammaleon_reloaded\gammaleon\source\gimpact\src\gim_trimesh.cpp
"GIMPACT/gim_trimesh.h"
1159994630 c:\libreriaswx\oldgammaleon_reloaded\gammaleon\source\gimpact\include\gimpact\gim_trimesh.h
"GIMPACT/gim_boxpruning.h"
"GIMPACT/gim_contact.h"
1159989774 c:\libreriaswx\oldgammaleon_reloaded\gammaleon\source\gimpact\include\gimpact\gim_boxpruning.h
"GIMPACT/gim_radixsort.h"
"GIMPACT/gim_geometry.h"
1159928249 source:c:\libreriaswx\oldgammaleon_reloaded\gammaleon\source\gimpact\src\gim_trimesh_trimesh_collision.cpp
"GIMPACT/gim_trimesh.h"
1159992207 source:c:\libreriaswx\oldgammaleon_reloaded\gammaleon\source\gimpact\src\gim_boxpruning.cpp
"GIMPACT/gim_boxpruning.h"
"sglib.h"
1160663612 source:c:\libreriaswx\physics\ode-0.7\gimpact\src\gim_trimesh_capsule_collision.cpp
"GIMPACT/gim_trimesh.h"
1160668423 c:\libreriaswx\physics\ode-0.7\gimpact\include\gimpact\gim_trimesh.h
"GIMPACT/gim_boxpruning.h"
"GIMPACT/gim_contact.h"
1160665573 c:\libreriaswx\physics\ode-0.7\gimpact\include\gimpact\gim_boxpruning.h
"GIMPACT/gim_radixsort.h"
"GIMPACT/gim_geometry.h"
1159989774 c:\libreriaswx\physics\ode-0.7\gimpact\include\gimpact\gim_radixsort.h
"GIMPACT/gim_memory.h"
1160666133 c:\libreriaswx\physics\ode-0.7\gimpact\include\gimpact\gim_memory.h
"GIMPACT/gim_math.h"
<memory.h>
<xmmintrin.h>
1160664080 c:\libreriaswx\physics\ode-0.7\gimpact\include\gimpact\gim_math.h
<math.h>
<float.h>
1160665531 c:\libreriaswx\physics\ode-0.7\gimpact\include\gimpact\gim_geometry.h
"GIMPACT/gim_math.h"
"GIMPACT/gim_tri_collision.h"
"GIMPACT/gim_tri_sphere_collision.h"
"GIMPACT/gim_tri_capsule_collision.h"
1160666237 c:\libreriaswx\physics\ode-0.7\gimpact\include\gimpact\gim_tri_collision.h
1160666277 c:\libreriaswx\physics\ode-0.7\gimpact\include\gimpact\gim_tri_sphere_collision.h
1160663800 c:\libreriaswx\physics\ode-0.7\gimpact\include\gimpact\gim_tri_capsule_collision.h
"GIMPACT/gim_memory.h"
1160663800 c:\libreriaswx\physics\ode-0.7\gimpact\include\gimpact\gim_contact.h
"GIMPACT/gim_geometry.h"
"GIMPACT/gim_radixsort.h"
1160663612 source:c:\libreriaswx\physics\ode-0.7\gimpact\src\gim_contact.cpp
"GIMPACT/gim_contact.h"
<sglib.h>
1136910978 c:\libreriaswx\physics\ode-0.7\gimpact\include\sglib.h
<assert.h>
1160663502 source:c:\libreriaswx\physics\ode-0.7\gimpact\src\gim_math.cpp
"GIMPACT/gim_math.h"
"stdlib.h"
"time.h"
1160663502 source:c:\libreriaswx\physics\ode-0.7\gimpact\src\gim_memory.cpp
"GIMPACT/gim_memory.h"
"stdlib.h"
"malloc.h"
1160663502 source:c:\libreriaswx\physics\ode-0.7\gimpact\src\gim_trimesh.cpp
"GIMPACT/gim_trimesh.h"
1160663502 source:c:\libreriaswx\physics\ode-0.7\gimpact\src\gim_boxpruning.cpp
"GIMPACT/gim_boxpruning.h"
"sglib.h"
1160663502 source:c:\libreriaswx\physics\ode-0.7\gimpact\src\gim_trimesh_ray_collision.cpp
"GIMPACT/gim_trimesh.h"
1160663612 source:c:\libreriaswx\physics\ode-0.7\gimpact\src\gim_trimesh_sphere_collision.cpp
"GIMPACT/gim_trimesh.h"
1160663503 source:c:\libreriaswx\physics\ode-0.7\gimpact\src\gim_trimesh_trimesh_collision.cpp
"GIMPACT/gim_trimesh.h"
1160663612 source:c:\libreriaswx\physics\ode-0.7\gimpact\src\gimpact.cpp
"GIMPACT/gimpact.h"
1160663925 c:\libreriaswx\physics\ode-0.7\gimpact\include\gimpact\gimpact.h
"GIMPACT/gim_trimesh.h"
1161470699 source:c:\desarrollo\gimpact\src\gim_boxpruning.cpp
"GIMPACT/gim_boxpruning.h"
1161561167 c:\desarrollo\gimpact\include\gimpact\gim_boxpruning.h
"GIMPACT/gim_radixsort.h"
"GIMPACT/gim_geometry.h"
1161493754 c:\desarrollo\gimpact\include\gimpact\gim_radixsort.h
"GIMPACT/gim_memory.h"
1161546016 c:\desarrollo\gimpact\include\gimpact\gim_memory.h
"GIMPACT/gim_math.h"
<memory.h>
<xmmintrin.h>
1161407413 c:\desarrollo\gimpact\include\gimpact\gim_math.h
<math.h>
<float.h>
1161493719 c:\desarrollo\gimpact\include\gimpact\gim_geometry.h
"GIMPACT/gim_math.h"
"GIMPACT/gim_tri_collision.h"
"GIMPACT/gim_tri_sphere_collision.h"
"GIMPACT/gim_tri_capsule_collision.h"
1161535917 c:\desarrollo\gimpact\include\gimpact\gim_tri_collision.h
1161407944 c:\desarrollo\gimpact\include\gimpact\gim_tri_sphere_collision.h
1161407945 c:\desarrollo\gimpact\include\gimpact\gim_tri_capsule_collision.h
"GIMPACT/gim_memory.h"
1161470699 source:c:\desarrollo\gimpact\src\gim_contact.cpp
"GIMPACT/gim_contact.h"
1161493737 c:\desarrollo\gimpact\include\gimpact\gim_contact.h
"GIMPACT/gim_geometry.h"
"GIMPACT/gim_radixsort.h"
1160663502 source:c:\desarrollo\gimpact\src\gim_math.cpp
"GIMPACT/gim_math.h"
"stdlib.h"
"time.h"
1160663502 source:c:\desarrollo\gimpact\src\gim_memory.cpp
"GIMPACT/gim_memory.h"
"stdlib.h"
"malloc.h"
1161546129 source:c:\desarrollo\gimpact\src\gim_tri_tri_overlap.cpp
"GIMPACT/gim_trimesh.h"
1161493760 c:\desarrollo\gimpact\include\gimpact\gim_trimesh.h
"GIMPACT/gim_boxpruning.h"
"GIMPACT/gim_contact.h"
1161543680 source:c:\desarrollo\gimpact\src\gim_trimesh.cpp
"GIMPACT/gim_trimesh.h"
1160663612 source:c:\desarrollo\gimpact\src\gim_trimesh_capsule_collision.cpp
"GIMPACT/gim_trimesh.h"
1160663502 source:c:\desarrollo\gimpact\src\gim_trimesh_ray_collision.cpp
"GIMPACT/gim_trimesh.h"
1160663612 source:c:\desarrollo\gimpact\src\gim_trimesh_sphere_collision.cpp
"GIMPACT/gim_trimesh.h"
1161545852 source:c:\desarrollo\gimpact\src\gim_trimesh_trimesh_collision.cpp
"GIMPACT/gim_trimesh.h"
1160663612 source:c:\desarrollo\gimpact\src\gimpact.cpp
"GIMPACT/gimpact.h"
1161488518 c:\desarrollo\gimpact\include\gimpact\gimpact.h
"GIMPACT/gim_trimesh.h"
1163169405 source:c:\libreriaswx\gammaleon_reloaded\gammaleon\source\gimpact\src\gim_trimesh_capsule_collision.cpp
"GIMPACT/gim_trimesh.h"
1163156330 c:\libreriaswx\gammaleon_reloaded\gammaleon\source\gimpact\include\gimpact\gim_trimesh.h
"GIMPACT/gim_trimesh_data.h"
"GIMPACT/gim_vertex_buffer_util.h"
"GIMPACT/gim_contact.h"
1163156330 c:\libreriaswx\gammaleon_reloaded\gammaleon\source\gimpact\include\gimpact\gim_trimesh_data.h
"GIMPACT/gim_boxpruning.h"
1163169530 c:\libreriaswx\gammaleon_reloaded\gammaleon\source\gimpact\include\gimpact\gim_boxpruning.h
"GIMPACT/gim_radixsort.h"
"GIMPACT/gim_geometry.h"
1163156180 c:\libreriaswx\gammaleon_reloaded\gammaleon\source\gimpact\include\gimpact\gim_radixsort.h
"GIMPACT/gim_memory.h"
1163156168 c:\libreriaswx\gammaleon_reloaded\gammaleon\source\gimpact\include\gimpact\gim_memory.h
"GIMPACT/gim_math.h"
<memory.h>
<xmmintrin.h>
1163169574 c:\libreriaswx\gammaleon_reloaded\gammaleon\source\gimpact\include\gimpact\gim_math.h
<math.h>
<float.h>
1163169881 c:\libreriaswx\gammaleon_reloaded\gammaleon\source\gimpact\include\gimpact\gim_geometry.h
"GIMPACT/gim_math.h"
"GIMPACT/gim_box_collision.h"
"GIMPACT/gim_tri_collision.h"
"GIMPACT/gim_tri_sphere_collision.h"
"GIMPACT/gim_tri_capsule_collision.h"
1163169574 c:\libreriaswx\gammaleon_reloaded\gammaleon\source\gimpact\include\gimpact\gim_box_collision.h
1163156329 c:\libreriaswx\gammaleon_reloaded\gammaleon\source\gimpact\include\gimpact\gim_tri_collision.h
1163156330 c:\libreriaswx\gammaleon_reloaded\gammaleon\source\gimpact\include\gimpact\gim_tri_sphere_collision.h
1163156199 c:\libreriaswx\gammaleon_reloaded\gammaleon\source\gimpact\include\gimpact\gim_tri_capsule_collision.h
"GIMPACT/gim_memory.h"
1163156330 c:\libreriaswx\gammaleon_reloaded\gammaleon\source\gimpact\include\gimpact\gim_vertex_buffer_util.h
"GIMPACT/gim_geometry.h"
"GIMPACT/gim_memory.h"
1163168527 c:\libreriaswx\gammaleon_reloaded\gammaleon\source\gimpact\include\gimpact\gim_contact.h
"GIMPACT/gim_geometry.h"
"GIMPACT/gim_radixsort.h"
1163156330 source:c:\libreriaswx\gammaleon_reloaded\gammaleon\source\gimpact\src\gim_math.cpp
"GIMPACT/gim_math.h"
"stdlib.h"
"time.h"
1163156330 source:c:\libreriaswx\gammaleon_reloaded\gammaleon\source\gimpact\src\gim_memory.cpp
"GIMPACT/gim_memory.h"
"stdlib.h"
"malloc.h"
1163156330 source:c:\libreriaswx\gammaleon_reloaded\gammaleon\source\gimpact\src\gim_tri_tri_overlap.cpp
"GIMPACT/gim_trimesh.h"
1163169405 source:c:\libreriaswx\gammaleon_reloaded\gammaleon\source\gimpact\src\gim_trimesh.cpp
"GIMPACT/gim_trimesh.h"
"assert.h"
1163156330 source:c:\libreriaswx\gammaleon_reloaded\gammaleon\source\gimpact\src\gim_trimesh_data.cpp
"GIMPACT/gim_trimesh_data.h"
1163156330 source:c:\libreriaswx\gammaleon_reloaded\gammaleon\source\gimpact\src\gim_trimesh_ray_collision.cpp
"GIMPACT/gim_trimesh.h"
1163169405 source:c:\libreriaswx\gammaleon_reloaded\gammaleon\source\gimpact\src\gim_trimesh_sphere_collision.cpp
"GIMPACT/gim_trimesh.h"
1163156330 source:c:\libreriaswx\gammaleon_reloaded\gammaleon\source\gimpact\src\gim_trimesh_trimesh_collision.cpp
"GIMPACT/gim_trimesh.h"
1163156330 source:c:\libreriaswx\gammaleon_reloaded\gammaleon\source\gimpact\src\gim_vertex_buffer_util.cpp
"GIMPACT/gim_vertex_buffer_util.h"
1163156328 source:c:\libreriaswx\gammaleon_reloaded\gammaleon\source\gimpact\src\gimpact.cpp
"GIMPACT/gimpact.h"
1163156330 c:\libreriaswx\gammaleon_reloaded\gammaleon\source\gimpact\include\gimpact\gimpact.h
"GIMPACT/gim_trimesh.h"
1163169629 source:c:\libreriaswx\gammaleon_reloaded\gammaleon\source\gimpact\src\gim_contact.cpp
"GIMPACT/gim_contact.h"
1163169723 source:c:\libreriaswx\gammaleon_reloaded\gammaleon\source\gimpact\src\gim_boxpruning.cpp
"GIMPACT/gim_boxpruning.h"
<assert.h>

View File

@ -1,31 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<CodeBlocks_layout_file>
<ActiveTarget name="Release" />
<File name="include\GIMPACT\gim_box_collision.h" open="1" top="0" tabpos="4">
<Cursor position="6591" topLine="178" />
</File>
<File name="include\GIMPACT\gim_boxpruning.h" open="1" top="0" tabpos="2">
<Cursor position="12980" topLine="339" />
</File>
<File name="include\GIMPACT\gim_geometry.h" open="1" top="1" tabpos="3">
<Cursor position="28755" topLine="1219" />
</File>
<File name="include\GIMPACT\gim_math.h" open="1" top="0" tabpos="1">
<Cursor position="3572" topLine="0" />
</File>
<File name="src\gim_boxpruning.cpp" open="1" top="0" tabpos="7">
<Cursor position="5952" topLine="184" />
</File>
<File name="src\gim_contact.cpp" open="1" top="0" tabpos="5">
<Cursor position="1555" topLine="34" />
</File>
<File name="src\gim_trimesh.cpp" open="1" top="0" tabpos="6">
<Cursor position="16351" topLine="525" />
</File>
<File name="src\gim_trimesh_capsule_collision.cpp" open="0" top="0" tabpos="0">
<Cursor position="5705" topLine="155" />
</File>
<File name="src\gim_trimesh_sphere_collision.cpp" open="0" top="0" tabpos="0">
<Cursor position="3677" topLine="91" />
</File>
</CodeBlocks_layout_file>

View File

@ -1,12 +0,0 @@
SubDir TOP Extras GIMPACT ;
#IncludeDir Extras/GIMPACT/include ;
Library GIMPACT : [ Wildcard src : */.h *.cpp ] : noinstall ;
CFlags GIMPACT : [ FIncludes $(TOP)/Extras/GIMPACT/include ] ;
LibDepends GIMPACT : ;
MsvcIncDirs GIMPACT :
"../../Extras/GIMPACT/include" ;
InstallHeader [ Wildcard *.h ] : GIMPACT ;

View File

@ -1,400 +0,0 @@
#ifndef GIM_BOX_COLLISION_H_INCLUDED
#define GIM_BOX_COLLISION_H_INCLUDED
/*! \file gim_box_collision.h
\author Francisco León Nájera
*/
/*
-----------------------------------------------------------------------------
This source file is part of GIMPACT Library.
For the latest info, see http://gimpact.sourceforge.net/
Copyright (c) 2006 Francisco Leon Najera. C.C. 80087371.
email: projectileman@yahoo.com
This library is free software; you can redistribute it and/or
modify it under the terms of EITHER:
(1) The GNU Lesser General Public License as published by the Free
Software Foundation; either version 2.1 of the License, or (at
your option) any later version. The text of the GNU Lesser
General Public License is included with this library in the
file GIMPACT-LICENSE-LGPL.TXT.
(2) The BSD-style license that is included with this library in
the file GIMPACT-LICENSE-BSD.TXT.
(3) The zlib/libpng license that is included with this library in
the file GIMPACT-LICENSE-ZLIB.TXT.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files
GIMPACT-LICENSE-LGPL.TXT, GIMPACT-LICENSE-ZLIB.TXT and GIMPACT-LICENSE-BSD.TXT for more details.
-----------------------------------------------------------------------------
*/
/*! \defgroup BOUND_AABB_OPERATIONS
*/
//! @{
//!Initializes an AABB
#define INVALIDATE_AABB(aabb) {\
(aabb).minX = G_REAL_INFINITY;\
(aabb).maxX = -G_REAL_INFINITY;\
(aabb).minY = G_REAL_INFINITY;\
(aabb).maxY = -G_REAL_INFINITY;\
(aabb).minZ = G_REAL_INFINITY;\
(aabb).maxZ = -G_REAL_INFINITY;\
}\
#define AABB_GET_MIN(aabb,vmin) {\
vmin[0] = (aabb).minX;\
vmin[1] = (aabb).minY;\
vmin[2] = (aabb).minZ;\
}\
#define AABB_GET_MAX(aabb,vmax) {\
vmax[0] = (aabb).maxX;\
vmax[1] = (aabb).maxY;\
vmax[2] = (aabb).maxZ;\
}\
//!Copy boxes
#define AABB_COPY(dest_aabb,src_aabb)\
{\
(dest_aabb).minX = (src_aabb).minX;\
(dest_aabb).maxX = (src_aabb).maxX;\
(dest_aabb).minY = (src_aabb).minY;\
(dest_aabb).maxY = (src_aabb).maxY;\
(dest_aabb).minZ = (src_aabb).minZ;\
(dest_aabb).maxZ = (src_aabb).maxZ;\
}\
//! Computes an Axis aligned box from a triangle
#define COMPUTEAABB_FOR_TRIANGLE(aabb,V1,V2,V3) {\
(aabb).minX = GIM_MIN3(V1[0],V2[0],V3[0]);\
(aabb).maxX = GIM_MAX3(V1[0],V2[0],V3[0]);\
(aabb).minY = GIM_MIN3(V1[1],V2[1],V3[1]);\
(aabb).maxY = GIM_MAX3(V1[1],V2[1],V3[1]);\
(aabb).minZ = GIM_MIN3(V1[2],V2[2],V3[2]);\
(aabb).maxZ = GIM_MAX3(V1[2],V2[2],V3[2]);\
}\
//! Apply a transform to an AABB
#define AABB_TRANSFORM(dest_box,source_box,mat4trans)\
{\
vec3f _vx,_vy,_vz;\
float _vtemp[] = {(source_box.maxX-source_box.minX),(source_box.maxY-source_box.minY),(source_box.maxZ-source_box.minZ)};\
MAT_GET_COL(mat4trans,_vx,0);\
VEC_SCALE(_vx,_vtemp[0],_vx); \
MAT_GET_COL(mat4trans,_vy,1);\
VEC_SCALE(_vy,_vtemp[1],_vy); \
MAT_GET_COL(mat4trans,_vz,2);\
VEC_SCALE(_vz,_vtemp[2],_vz);\
float _vtrans[] = {source_box.minX,source_box.minY,source_box.minZ}; \
MAT_DOT_VEC_3X4(_vtemp,mat4trans,_vtrans);\
dest_box.minX = dest_box.maxX = _vtemp[0];\
dest_box.minY = dest_box.maxY = _vtemp[1];\
dest_box.minZ = dest_box.maxZ = _vtemp[2]; \
if(_vx[0]<0.0f) dest_box.minX += _vx[0]; else dest_box.maxX += _vx[0];\
if(_vx[1]<0.0f) dest_box.minY += _vx[1]; else dest_box.maxY += _vx[1];\
if(_vx[2]<0.0f) dest_box.minZ += _vx[2]; else dest_box.maxZ += _vx[2];\
if(_vy[0]<0.0f) dest_box.minX += _vy[0]; else dest_box.maxX += _vy[0];\
if(_vy[1]<0.0f) dest_box.minY += _vy[1]; else dest_box.maxY += _vy[1];\
if(_vy[2]<0.0f) dest_box.minZ += _vy[2]; else dest_box.maxZ += _vy[2];\
if(_vz[0]<0.0f) dest_box.minX += _vz[0]; else dest_box.maxX += _vz[0];\
if(_vz[1]<0.0f) dest_box.minY += _vz[1]; else dest_box.maxY += _vz[1];\
if(_vz[2]<0.0f) dest_box.minZ += _vz[2]; else dest_box.maxZ += _vz[2];\
}\
//! Merge two boxes to destaabb
#define MERGEBOXES(destaabb,aabb) {\
(destaabb).minX = GIM_MIN((aabb).minX,(destaabb).minX);\
(destaabb).minY = GIM_MIN((aabb).minY,(destaabb).minY);\
(destaabb).minZ = GIM_MIN((aabb).minZ,(destaabb).minZ);\
(destaabb).maxX = GIM_MAX((aabb).maxX,(destaabb).maxX);\
(destaabb).maxY = GIM_MAX((aabb).maxY,(destaabb).maxY);\
(destaabb).maxZ = GIM_MAX((aabb).maxZ,(destaabb).maxZ);\
}\
//! Extends the box
#define AABB_POINT_EXTEND(destaabb,p) {\
(destaabb).minX = GIM_MIN(p[0],(destaabb).minX);\
(destaabb).maxX = GIM_MAX(p[0],(destaabb).maxX);\
(destaabb).minY = GIM_MIN(p[1],(destaabb).minY);\
(destaabb).maxY = GIM_MAX(p[1],(destaabb).maxY);\
(destaabb).minZ = GIM_MIN(p[2],(destaabb).minZ);\
(destaabb).maxZ = GIM_MAX(p[2],(destaabb).maxZ);\
}\
//! Gets the center and the dimension of the AABB
#define AABB_GET_CENTER_EXTEND(aabb,center,extend)\
{\
extend[0] = (aabb.maxX - aabb.minX)*0.5f;\
extend[1] = (aabb.maxY - aabb.minY)*0.5f;\
extend[2] = (aabb.maxZ - aabb.minZ)*0.5f;\
center[0] = aabb.minX + extend[0];\
center[1] = aabb.minY + extend[1];\
center[2] = aabb.minZ + extend[2];\
}\
//! Finds the intersection box of two boxes
#define BOXINTERSECTION(aabb1, aabb2, iaabb) {\
(iaabb).minX = GIM_MAX((aabb1).minX,(aabb2).minX);\
(iaabb).minY = GIM_MAX((aabb1).minY,(aabb2).minY);\
(iaabb).minZ = GIM_MAX((aabb1).minZ,(aabb2).minZ);\
(iaabb).maxX = GIM_MIN((aabb1).maxX,(aabb2).maxX);\
(iaabb).maxY = GIM_MIN((aabb1).maxY,(aabb2).maxY);\
(iaabb).maxZ = GIM_MIN((aabb1).maxZ,(aabb2).maxZ);\
}\
//! Determines if two aligned boxes do intersect
#define AABBCOLLISION(intersected,aabb1,aabb2) {\
intersected = 1;\
if ((aabb1).minX > (aabb2).maxX ||\
(aabb1).maxX < (aabb2).minX ||\
(aabb1).minY > (aabb2).maxY ||\
(aabb1).maxY < (aabb2).minY ||\
(aabb1).minZ > (aabb2).maxZ ||\
(aabb1).maxZ < (aabb2).minZ )\
{\
intersected = 0;\
}\
}\
#define AXIS_INTERSECT(min,max, a, d,tfirst, tlast,is_intersected) {\
if(GIM_IS_ZERO(d))\
{\
is_intersected = !(a < min || a > max);\
}\
else\
{\
GREAL a0, a1;\
a0 = (min - a) / (d);\
a1 = (max - a) / (d);\
if(a0 > a1) GIM_SWAP_NUMBERS(a0, a1);\
tfirst = GIM_MAX(a0, tfirst);\
tlast = GIM_MIN(a1, tlast);\
if (tlast < tfirst)\
{\
is_intersected = 0;\
}\
else\
{\
is_intersected = 1;\
}\
}\
}\
/*! \brief Finds the Ray intersection parameter.
\param aabb Aligned box
\param vorigin A vec3f with the origin of the ray
\param vdir A vec3f with the direction of the ray
\param tparam Output parameter
\param tmax Max lenght of the ray
\param is_intersected 1 if the ray collides the box, else false
*/
#define BOX_INTERSECTS_RAY(aabb, vorigin, vdir, tparam, tmax,is_intersected) { \
GREAL _tfirst = 0.0f, _tlast = tmax;\
AXIS_INTERSECT(aabb.minX,aabb.maxX,vorigin[0], vdir[0], _tfirst, _tlast,is_intersected);\
if(is_intersected)\
{\
AXIS_INTERSECT(aabb.minY,aabb.maxY,vorigin[1], vdir[1], _tfirst, _tlast,is_intersected);\
}\
if(is_intersected)\
{\
AXIS_INTERSECT(aabb.minZ,aabb.maxZ,vorigin[2], vdir[2], _tfirst, _tlast,is_intersected);\
}\
tparam = _tfirst;\
}\
/*! \brief Finds the Ray intersection parameter.
\param aabb Aligned box
\param vorigin A vec3f with the origin of the ray
\param vdir A vec3f with the direction of the ray
*/
inline int BOX_INTERSECTS_RAY_FAST(aabb3f & aabb, vec3f vorigin,vec3f vdir)
{
vec3f extents,center;
AABB_GET_CENTER_EXTEND(aabb,center,extents);
GREAL Dx = vorigin[0] - center[0];
if(GIM_GREATER(Dx, extents[0]) && Dx*vdir[0]>=0.0f) return 0;
GREAL Dy = vorigin[1] - center[1];
if(GIM_GREATER(Dy, extents[1]) && Dy*vdir[1]>=0.0f) return 0;
GREAL Dz = vorigin[2] - center[2];
if(GIM_GREATER(Dz, extents[2]) && Dz*vdir[2]>=0.0f) return 0;
GREAL f;
f = vdir[1] * Dz - vdir[2] * Dy;
if(fabsf(f) > extents[1]*fabsf(vdir[2]) + extents[2]*fabsf(vdir[1])) return 0;
f = vdir[2] * Dx - vdir[0] * Dz;
if(fabsf(f) > extents[0]*fabsf(vdir[2]) + extents[2]*fabsf(vdir[0]))return 0;
f = vdir[0] * Dy - vdir[1] * Dx;
if(fabsf(f) > extents[0]*fabsf(vdir[1]) + extents[1]*fabsf(vdir[0]))return 0;
return 1;
}
#define AABB_PROJECTION_INTERVAL(aabb,direction, vmin, vmax)\
{\
GREAL _center[] = {(aabb.minX + aabb.maxX)*0.5f, (aabb.minY + aabb.maxY)*0.5f, (aabb.minZ + aabb.maxZ)*0.5f};\
\
GREAL _extend[] = {aabb.maxX-_center[0],aabb.maxY-_center[1],aabb.maxZ-_center[2]};\
GREAL _fOrigin = VEC_DOT(direction,_center);\
GREAL _fMaximumExtent = _extend[0]*fabsf(direction[0]) + \
_extend[1]*fabsf(direction[1]) + \
_extend[2]*fabsf(direction[2]); \
\
vmin = _fOrigin - _fMaximumExtent; \
vmax = _fOrigin + _fMaximumExtent; \
}\
#define BOX_PLANE_EPSILON 0.000001f
/*!
classify values:
<ol>
<li> 0 : In back of plane
<li> 1 : Spanning
<li> 2 : In front of
</ol>
*/
#define PLANE_CLASSIFY_BOX(plane,aabb,classify)\
{\
GREAL _fmin,_fmax; \
AABB_PROJECTION_INTERVAL(aabb,plane, _fmin, _fmax); \
if(plane[3] > _fmax + BOX_PLANE_EPSILON ) \
{ \
classify = 0;/*In back of*/ \
} \
else \
{ \
if(plane[3]+BOX_PLANE_EPSILON >=_fmin) \
{ \
classify = 1;/*Spanning*/ \
} \
else \
{ \
classify = 2;/*In front of*/ \
} \
} \
}\
//! Class for transforming a model1 to the space of model0
class GIM_BOX_BOX_TRANSFORM_CACHE
{
public:
vec3f m_T1to0;//!< Transforms translation of model1 to model 0
mat3f m_R1to0;//!< Transforms Rotation of model1 to model 0, equal to R0' * R1
mat3f m_AR;//!< Absolute value of m_R1to0
GIM_BOX_BOX_TRANSFORM_CACHE(mat4f trans1_to_0)
{
COPY_MATRIX_3X3(m_R1to0,trans1_to_0)
MAT_GET_TRANSLATION(trans1_to_0,m_T1to0)
int i,j;
for(i=0;i<3;i++)
{
for(j=0;j<3;j++ )
{
m_AR[i][j] = 1e-6f + fabsf(m_R1to0[i][j]);
}
}
}
};
inline int gim_box_box_overlap_trans_conservative(aabb3f * box0,aabb3f * box1,mat4f trans1_to_0)
{
aabb3f pbox1;
AABB_TRANSFORM(pbox1,(*box1),trans1_to_0);
int intersected;
AABBCOLLISION(intersected,pbox1,(*box0));
return intersected;
}
inline int gim_box_box_overlap_cache(aabb3f * box0,aabb3f * box1,GIM_BOX_BOX_TRANSFORM_CACHE * boxcache, bool fulltest)
{
//Taken from OPCODE
vec3f ea,eb;//extends
vec3f ca,cb;//extends
AABB_GET_CENTER_EXTEND((*box0),ca,ea);
AABB_GET_CENTER_EXTEND((*box1),cb,eb);
vec3f T;
GREAL t,t2;
int i;
// Class I : A's basis vectors
for(i=0;i<3;i++)
{
T[i] = MAT_DOT_ROW(boxcache->m_R1to0,cb,i) + boxcache->m_T1to0[i] - ca[i];
t = MAT_DOT_ROW(boxcache->m_AR,eb,i) + ea[i];
if(GIM_GREATER(T[i], t)) return 0;
}
// Class II : B's basis vectors
for(i=0;i<3;i++)
{
t = MAT_DOT_COL(boxcache->m_R1to0,T,i);
t2 = MAT_DOT_COL(boxcache->m_AR,ea,i) + eb[i];
if(GIM_GREATER(t,t2)) return 0;
}
// Class III : 9 cross products
if(fulltest)
{
int j,m,n,o,p,q,r;
for(i=0;i<3;i++)
{
m = (i+1)%3;
n = (i+2)%3;
o = i==0?1:0;
p = i==2?1:2;
for(j=0;j<3;j++)
{
q = j==2?1:2;
r = j==0?1:0;
t = T[n]*boxcache->m_R1to0[m][j] - T[m]*boxcache->m_R1to0[n][j];
t2 = ea[o]*boxcache->m_AR[p][j] + ea[p]*boxcache->m_AR[o][j] +
eb[r]*boxcache->m_AR[i][q] + eb[q]*boxcache->m_AR[i][r];
if(GIM_GREATER(t,t2)) return 0;
}
}
}
return 1;
}
/// conservative test for overlap between triangle and aabb
inline int gim_box_collide_triangle(vec3f p1, vec3f p2, vec3f p3,aabb3f & box)
{
if(GIM_MIN3(p1[0],p2[0],p3[0])> box.maxX) return 0;
if(GIM_MAX3(p1[0],p2[0],p3[0])< box.minX) return 0;
if(GIM_MIN3(p1[2],p2[2],p3[2])> box.maxZ) return 0;
if(GIM_MAX3(p1[2],p2[2],p3[2])< box.minZ) return 0;
if(GIM_MIN3(p1[1],p2[1],p3[1])> box.maxY) return 0;
if(GIM_MAX3(p1[1],p2[1],p3[1])< box.minY) return 0;
vec4f plane;
TRIANGLE_PLANE_FAST(p1,p2,p3,plane);
char classify;
PLANE_CLASSIFY_BOX(plane,box,classify);
if(classify != 1) return 0;
return 1;
}
//! @}
#endif // GIM_BOX_COLLISION_H_INCLUDED

View File

@ -1,484 +0,0 @@
#ifndef GIM_BOXPRUNING_H_INCLUDED
#define GIM_BOXPRUNING_H_INCLUDED
/*! \file gim_boxpruning.h
\author Francisco León Nájera
*/
/*
-----------------------------------------------------------------------------
This source file is part of GIMPACT Library.
For the latest info, see http://gimpact.sourceforge.net/
Copyright (c) 2006 Francisco Leon Najera. C.C. 80087371.
email: projectileman@yahoo.com
This library is free software; you can redistribute it and/or
modify it under the terms of EITHER:
(1) The GNU Lesser General Public License as published by the Free
Software Foundation; either version 2.1 of the License, or (at
your option) any later version. The text of the GNU Lesser
General Public License is included with this library in the
file GIMPACT-LICENSE-LGPL.TXT.
(2) The BSD-style license that is included with this library in
the file GIMPACT-LICENSE-BSD.TXT.
(3) The zlib/libpng license that is included with this library in
the file GIMPACT-LICENSE-ZLIB.TXT.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files
GIMPACT-LICENSE-LGPL.TXT, GIMPACT-LICENSE-ZLIB.TXT and GIMPACT-LICENSE-BSD.TXT for more details.
-----------------------------------------------------------------------------
*/
#include "GIMPACT/gim_radixsort.h"
#include "GIMPACT/gim_geometry.h"
/*! \defgroup BOX_PRUNNING
\brief
Tools for find overlapping objects on a scenary. These functions sort boxes for faster collisioin queries, using radix sort or quick sort as convenience. See \ref SORTING .
<ul>
<li> For using these collision routines, you must create a \ref GIM_AABB_SET by using this function : \ref gim_aabbset_alloc.
<li> The GIM_AABB_SET objects must be updated on their boxes on each query, and they must be update by calling \ref gim_aabbset_update
<li> Before calling collision functions, you must create a pair set with \ref GIM_CREATE_PAIR_SET
<li> For finding collision pairs on a scene (common space for objects), call \ref gim_aabbset_self_intersections
<li> For finding collision pairs between two box sets , call \ref gim_aabbset_box_collision
<li> After using collision routines, you must destroy the pairset with \ref GIM_DESTROY_PAIR_SET
<li> When the box set is no longer used, you must destroy it by calling \ref gim_aabbset_destroy
</ul>
*/
//! @{
//! Overlapping pair
struct GIM_PAIR
{
GUINT m_index1;
GUINT m_index2;
};
//typedef struct _GIM_PAIR GIM_PAIR;
//! Box container
struct GIM_AABB_SET
{
GUINT m_count;
aabb3f m_global_bound;//!< Global calculated bound of all boxes
aabb3f * m_boxes;
GUINT * m_maxcoords;//!<Upper corners of the boxes, in integer representation
GIM_RSORT_TOKEN * m_sorted_mincoords;//!< sorted min coords (lower corners), with their coord value as the m_key and m_value as the box index
char m_shared;//!< if m_shared == 0 then the memory is allocated and the set must be destroyed, else the pointers are shared and the set should't be destroyed
};
//typedef struct _GIM_AABB_SET GIM_AABB_SET;
//! Function for creating an overlapping pair set
#define GIM_CREATE_PAIR_SET(dynarray) GIM_DYNARRAY_CREATE(GIM_PAIR,dynarray,G_ARRAY_GROW_SIZE)
//! Function for destroying an overlapping pair set
#define GIM_DESTROY_PAIR_SET(dynarray) GIM_DYNARRAY_DESTROY(dynarray)
//! Allocate memory for all aabb set.
void gim_aabbset_alloc(GIM_AABB_SET * aabbset, GUINT count);
//! Destroys the aabb set.
void gim_aabbset_destroy(GIM_AABB_SET * aabbset);
//! Calcs the global bound only
/*!
\pre aabbset must be allocated. And the boxes must be already set.
*/
void gim_aabbset_calc_global_bound(GIM_AABB_SET * aabbset);
//! Sorts the boxes for box prunning.
/*!
1) find the integer representation of the aabb coords
2) Sorts the min coords
3) Calcs the global bound
\pre aabbset must be allocated. And the boxes must be already set.
\param aabbset
\param calc_global_bound If 1 , calcs the global bound
\post If aabbset->m_sorted_mincoords == 0, then it allocs the sorted coordinates
*/
void gim_aabbset_sort(GIM_AABB_SET * aabbset, char calc_global_bound);
//! log(N) Complete box pruning. Returns a list of overlapping pairs of boxes, each box of the pair belongs to the same set.
/*!
\pre aabbset must be allocated and sorted, the boxes must be already set.
\param aabbset Must be sorted. Global bound isn't required
\param collision_pairs Array of GIM_PAIR elements. Must be initialized before (Reserve size ~ 100)
*/
void gim_aabbset_self_intersections_sorted(GIM_AABB_SET * aabbset, GDYNAMIC_ARRAY * collision_pairs);
//! NxN Complete box pruning. Returns a list of overlapping pairs of boxes, each box of the pair belongs to the same set.
/*!
\pre aabbset must be allocated, the boxes must be already set.
\param aabbset Global bound isn't required. Doen't need to be sorted.
\param collision_pairs Array of GIM_PAIR elements. Must be initialized before (Reserve size ~ 100)
*/
void gim_aabbset_self_intersections_brute_force(GIM_AABB_SET * aabbset, GDYNAMIC_ARRAY * collision_pairs);
//! log(N) Bipartite box pruning. Returns a list of overlapping pairs of boxes, each box of the pair belongs to a different set.
/*!
\pre aabbset1 and aabbset2 must be allocated and sorted, the boxes must be already set.
\param aabbset1 Must be sorted, Global bound is required.
\param aabbset2 Must be sorted, Global bound is required.
\param collision_pairs Array of GIM_PAIR elements. Must be initialized before (Reserve size ~ 100)
*/
void gim_aabbset_bipartite_intersections_sorted(GIM_AABB_SET * aabbset1, GIM_AABB_SET * aabbset2, GDYNAMIC_ARRAY * collision_pairs);
//! NxM Bipartite box pruning. Returns a list of overlapping pairs of boxes, each box of the pair belongs to a different set.
/*!
\pre aabbset1 and aabbset2 must be allocated and sorted, the boxes must be already set.
\param aabbset1 Must be sorted, Global bound is required.
\param aabbset2 Must be sorted, Global bound is required.
\param collision_pairs Array of GIM_PAIR elements. Must be initialized before (Reserve size ~ 100)
*/
void gim_aabbset_bipartite_intersections_brute_force(GIM_AABB_SET * aabbset1,GIM_AABB_SET * aabbset2, GDYNAMIC_ARRAY * collision_pairs);
/*
Brute-Force Vs Sorted pruning
Different approaches must be applied when colliding sets with different number of
elements. When sets have less of 100 boxes, is often better to apply force brute
approach instead of sorted methods, because at lowlevel bruteforce routines gives
better perormance and consumes less resources, due of their simplicity.
But when sets are larger, the complexiity of bruteforce increases exponencially.
In the case of large sets, sorted approach is applied. So GIMPACT has the following
strategies:
On Sorting sets:
!) When sets have more of 140 boxes, the boxes are sorted by its coded min coord
and the global box is calculated. But when sets are smaller (less of 140 boxes),
Is convenient to apply brute force approach.
*******************************************************************************/
//! Constant for apply approaches between brute force and sorted pruning on bipartite queries
#define GIM_MIN_SORTED_BIPARTITE_PRUNING_BOXES 600
//! Constant for apply approaches between brute force and sorted pruning for box collision
#define GIM_MIN_SORTED_PRUNING_BOXES 140
//Use these functions for general initialization
//! Initalizes the set. Sort Boxes if needed.
/*!
\pre aabbset must be allocated. And the boxes must be already set.
\post If the set has less of GIM_MIN_SORTED_BIPARTITE_PRUNING_BOXES boxes, only calcs the global box,
else it Sorts the entire set( Only applicable for large sets)
*/
void gim_aabbset_update(GIM_AABB_SET * aabbset);
///Use these functions for general collision
//! Complete box pruning. Returns a list of overlapping pairs of boxes, each box of the pair belongs to the same set.
/*!
This function sorts the set and then it calls to gim_aabbset_self_intersections_brute_force or gim_aabbset_self_intersections_sorted. This is an example of how to use this function:
\code
//Create contact list
GDYNAMIC_ARRAY collision_pairs;
GIM_CREATE_PAIR_SET(collision_pairs);
//Do collision
gim_aabbset_self_intersections(&aabbset,&collision_pairs);
if(collision_pairs.m_size==0)
{
GIM_DYNARRAY_DESTROY(collision_pairs);//
return; //no collisioin
}
//pair pointer
GIM_PAIR *pairs = GIM_DYNARRAY_POINTER(GIM_PAIR,collision_pairs);
GUINT i, ti1,ti2;
for (i=0;i<collision_pairs.m_size; i++)
{
ti1 = pairs[i].m_index1;
ti2 = pairs[i].m_index2;
//Do something with the pairs
....
....
...
}
//Terminate
GIM_DYNARRAY_DESTROY(dummycontacts);
GIM_DYNARRAY_DESTROY(collision_pairs);
\endcode
\param aabbset Set of boxes. Sorting isn't required.
\param collision_pairs Array of GIM_PAIR elements. Must be initialized before (Reserve size ~ 100)
\pre aabbset must be allocated and initialized.
\post If aabbset->m_count >= GIM_MIN_SORTED_PRUNING_BOXES, then it calls to gim_aabbset_sort and then to gim_aabbset_self_intersections_sorted. Global box won't be calculated.
*/
void gim_aabbset_self_intersections(GIM_AABB_SET * aabbset, GDYNAMIC_ARRAY * collision_pairs);
//! Collides two sets. Returns a list of overlapping pairs of boxes, each box of the pair belongs to a different set.
/*!
\pre aabbset1 and aabbset2 must be allocated and updated. See gim_aabbset_update.
\param aabbset1 Must be updated.
\param aabbset2 Must be updated.
\param collision_pairs Array of GIM_PAIR elements. Must be initialized before (Reserve size ~ 100)
*/
void gim_aabbset_bipartite_intersections(GIM_AABB_SET * aabbset1, GIM_AABB_SET * aabbset2, GDYNAMIC_ARRAY * collision_pairs);
///Function for create Box collision result set
#define GIM_CREATE_BOXQUERY_LIST(dynarray) GIM_DYNARRAY_CREATE(GUINT,dynarray,G_ARRAY_GROW_SIZE)
//! Finds intersections between a box and a set. Return the colliding boxes of the set
/*!
\pre aabbset must be allocated and initialized.
\param test_aabb Box for collision query
\param aabbset Set of boxes .Global bound is required.
\param collided Array of GUINT elements, indices of boxes. Must be initialized before (Reserve size ~ 100)
*/
void gim_aabbset_box_collision(aabb3f *test_aabb, GIM_AABB_SET * aabbset, GDYNAMIC_ARRAY * collided);
//! Finds intersections between a box and a set. Return the colliding boxes of the set
/*!
\pre aabbset must be allocated and initialized.
\param vorigin Origin point of ray.
\param vdir Direction vector of ray.
\param tmax Max distance param for ray.
\param aabbset Set of boxes .Global bound is required.
\param collided Array of GUINT elements, indices of boxes. Must be initialized before (Reserve size ~ 100)
*/
void gim_aabbset_ray_collision(vec3f vorigin,vec3f vdir, GREAL tmax, GIM_AABB_SET * aabbset, GDYNAMIC_ARRAY * collided);
/*
For sorting, each box corner must be discretized to a 32 bit integer.
For this, we take the x and z coordinates from the box corner (a vector vec3f)
Then convert the (x,z) pair to an integer. For convenience, we choose an error
constant for converting the coordinates (0.05).
*******************************************************************************/
/**
For fitting the coordinate to an integer, we need to constraint the range of its values. So each coord component (x, z) must lie between 0 and 65536.
20 give us a 0.05 floating point error
*/
#define ERROR_AABB 20.0f
/**
An error of 0.05 allows to make coordinates up to 1638.0f and no less of -1638.0f.
So the maximum size of a room should be about 3276x3276 . Its dimensions must lie between [-1638,1638.0f]
*/
#define MAX_AABB_SIZE 1638.0f
/**
If 1, then the system manages objects that are far away beyond the limits of the world [-1638,1638.0f]
*/
#define CLAMP_FURTHER_OBJECTS 0
//! Converts a vector coordinate to an integer for box sorting. Secure clamped
/*!
\param vx X component
\param vz Z component
\param uint_key a GUINT
*/
#define GIM_CONVERT_VEC3F_GUINT_XZ_CLAMPED(vx,vz,uint_key)\
{\
GREAL _cx = GIM_CLAMP(vx,-MAX_AABB_SIZE,MAX_AABB_SIZE);\
GREAL _cz = GIM_CLAMP(vz,-MAX_AABB_SIZE,MAX_AABB_SIZE);\
GUINT _z = ((GUINT)(_cz*ERROR_AABB))+32768;\
uint_key = ((GUINT)(_cx*ERROR_AABB))+32768;\
uint_key = (uint_key<<16) + _z;\
}\
//! Converts a vector coordinate to an integer for box sorting. Secure clamped, rounded
/*!
\param vx X component
\param vz Z component
\param uint_key a GUINT
*/
#define GIM_CONVERT_VEC3F_GUINT_XZ_UPPER_CLAMPED(vx,vz,uint_key)\
{\
GREAL _cx = GIM_CLAMP(vx,-MAX_AABB_SIZE,MAX_AABB_SIZE);\
GREAL _cz = GIM_CLAMP(vz,-MAX_AABB_SIZE,MAX_AABB_SIZE);\
GUINT _z = ((GUINT)ceilf(_cz*ERROR_AABB))+32768;\
uint_key = ((GUINT)ceilf(_cx*ERROR_AABB))+32768;\
uint_key = (uint_key<<16) + _z;\
}\
#if (CLAMP_FURTHER_OBJECTS == 1)
#define GIM_CONVERT_VEC3F_GUINT_XZ(vx,vz,uint_key) GIM_CONVERT_VEC3F_GUINT_XZ_CLAMPED(vx,vz,uint_key)
#define GIM_CONVERT_VEC3F_GUINT_XZ_UPPER(vx,vz,uint_key) GIM_CONVERT_VEC3F_GUINT_XZ_UPPER_CLAMPED(vx,vz,uint_key)
#else
//! Converts a vector coordinate to an integer for box sorting
/*!
\param vx X component
\param vz Z component
\param uint_key a GUINT
*/
#define GIM_CONVERT_VEC3F_GUINT_XZ(vx,vz,uint_key)\
{\
GUINT _z = ((GUINT)(vz*ERROR_AABB))+32768;\
uint_key = ((GUINT)(vx*ERROR_AABB))+32768;\
uint_key = (uint_key<<16) + _z;\
}\
//! Converts a vector coordinate to an integer for box sorting,rounding to the upper int
/*!
\param vx X component
\param vz Z component
\param uint_key a GUINT
*/
#define GIM_CONVERT_VEC3F_GUINT_XZ_UPPER(vx,vz,uint_key)\
{\
GUINT _z = ((GUINT)ceilf(vz*ERROR_AABB))+32768;\
uint_key = ((GUINT)ceilf(vx*ERROR_AABB))+32768;\
uint_key = (uint_key<<16) + _z;\
}\
#endif
//! @}
/*! \defgroup HIERARCHY_BOX_PRUNNING
\brief
Tools for find overlapping objects on a scenary, by using Bounding Volume Trees.
*/
//! @{
struct GIM_AABB_DATA
{
aabb3f m_aabb;//!< Bounding volume
GUINT m_data;
};
#define AABB_DATA_COPY(dest_data,src_data)\
{\
AABB_COPY(dest_data.m_aabb,src_data.m_aabb);\
dest_data.m_data = src_data.m_data;\
}\
//! Node Structure for trees
struct GIM_AABB_TREE_NODE
{
GIM_AABB_TREE_NODE * m_left;//!< Left subtree
GIM_AABB_TREE_NODE * m_right;//!< Right subtree
GUINT m_escapeIndex;//!< Scape index for traversing
GIM_AABB_DATA m_data;
GIM_AABB_TREE_NODE()
{
m_left = 0;
m_right = 0;
m_escapeIndex = 0;
}
bool is_leaf_node()
{
return (!m_left && !m_right);
}
};
//! AABB tree
struct GIM_AABB_TREE
{
GIM_AABB_TREE_NODE * m_node_array;
GUINT m_num_nodes;
GUINT m_nodes_array_size;
GIM_AABB_TREE_NODE * m_root_node;
void clear_nodes()
{
if(m_node_array != 0) gim_free(m_node_array,0);
m_num_nodes = 0;
m_root_node = 0;
m_nodes_array_size = 0;
}
GIM_AABB_TREE()
{
m_node_array = 0;
m_num_nodes = 0;
m_root_node = 0;
m_nodes_array_size = 0;
}
~GIM_AABB_TREE()
{
clear_nodes();
}
};
//! Creates and intializes a GIM_AABB_TREE from an array of boxes
/*!
\param newtree Tree for be build
\param boxarray A GIM_AABB_DATA array for sorting, must be allocated by user.
\param boxcount box count.
*/
void gim_aabbtree_create(GIM_AABB_TREE * newtree, GIM_AABB_DATA * boxarray, GUINT boxcount);
//! Destroy an GIM_AABB_TREE.
void gim_aabbtree_destroy(GIM_AABB_TREE * tree);
//! Finds intersections between a box and a tree. Return the indices from the colliding nodes of the tree
/*!
\pre aabbtree must be initialized.
\param test_aabb Box for collision query
\param aabbtree Tree of boxes.
\param collided Array of GUINT elements which corresponds to the index of the collided node in the m_nodes_array menber. Must be initialized before (Reserve size ~ 100)
*/
void gim_aabbtree_box_collision_get_nodes(aabb3f *test_aabb, GIM_AABB_TREE * aabbtree, GDYNAMIC_ARRAY * collided);
//! Finds intersections between a box and a tree. Return the data index from the colliding leaf boxes of the tree
/*!
\pre aabbtree must be initialized.
\param test_aabb Box for collision query
\param aabbtree Tree of boxes.
\param collided Array of GUINT elements which corresponds to the data index in the leafs. Must be initialized before (Reserve size ~ 100)
*/
void gim_aabbtree_box_collision(aabb3f *test_aabb, GIM_AABB_TREE * aabbtree, GDYNAMIC_ARRAY * collided);
//! Finds intersections between a box and a tree. Return the colliding boxes of the set
/*!
\param vorigin Origin point of ray.
\param vdir Direction vector of ray.
\param tmax Max distance param for ray.
\param aabbtree Set of boxes.
\param collided Array of GUINT elements, indices of boxes. Must be initialized before (Reserve size ~ 100)
*/
void gim_aabbtree_ray_collision(vec3f vorigin,vec3f vdir, GREAL tmax, GIM_AABB_TREE * aabbtree, GDYNAMIC_ARRAY * collided);
//! Collides two transformed box trees. Returns a list of the data (m_data) from the overlapping pairs of box leafs, each leaf data belongs to a different tree.
/*!
\param aabbtree1 Must be updated.
\param aabbtree2 Must be updated.
\param trans1inverse Inverse Transformation of aabbtree1.
\param trans2 Transformation of aabbtree2.
\param collision_pairs Array of GIM_PAIR elements. Must be initialized before (Reserve size ~ 100)
*/
void gim_aabbtree_bipartite_intersections_trans(GIM_AABB_TREE * aabbtree1, GIM_AABB_TREE * aabbtree2,
mat4f trans1,mat4f trans1inverse,
mat4f trans2,mat4f trans2inverse,
GDYNAMIC_ARRAY * collision_pairs);
//! Collides an aabbset and aabbtree. Returns a pair list of overlapping pairs. The first element of the pair belongs to aabbset and the second belongs to aabbtree.
/*!
\param aabbset Must be updated.
\param aabbtree Must be initialized.
\param trans_aabbtree Transformation of the aabbtree.
\param inv_trans_aabbtree Inverse Transformation of the aabbtree.
\param collision_pairs Array of GIM_PAIR elements. The first element of the pair belongs to aabbset and the second belongs to aabbtree having the m_data value from leaf. Must be initialized before (Reserve size ~ 100)
*/
void gim_aabbset_aabbtree_intersections_trans(GIM_AABB_SET * aabbset, GIM_AABB_TREE * aabbtree, mat4f trans_aabbtree, mat4f inv_trans_aabbtree, GDYNAMIC_ARRAY * collision_pairs);
//! @}
#endif // GIM_BOXPRUNING_H_INCLUDED

View File

@ -1,121 +0,0 @@
#ifndef GIM_CONTACT_H_INCLUDED
#define GIM_CONTACT_H_INCLUDED
/*! \file gim_contact.h
\author Francisco León Nájera
*/
/*
-----------------------------------------------------------------------------
This source file is part of GIMPACT Library.
For the latest info, see http://gimpact.sourceforge.net/
Copyright (c) 2006 Francisco Leon Najera. C.C. 80087371.
email: projectileman@yahoo.com
This library is free software; you can redistribute it and/or
modify it under the terms of EITHER:
(1) The GNU Lesser General Public License as published by the Free
Software Foundation; either version 2.1 of the License, or (at
your option) any later version. The text of the GNU Lesser
General Public License is included with this library in the
file GIMPACT-LICENSE-LGPL.TXT.
(2) The BSD-style license that is included with this library in
the file GIMPACT-LICENSE-BSD.TXT.
(3) The zlib/libpng license that is included with this library in
the file GIMPACT-LICENSE-ZLIB.TXT.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files
GIMPACT-LICENSE-LGPL.TXT, GIMPACT-LICENSE-ZLIB.TXT and GIMPACT-LICENSE-BSD.TXT for more details.
-----------------------------------------------------------------------------
*/
#include "GIMPACT/gim_geometry.h"
#include "GIMPACT/gim_radixsort.h"
/*! \defgroup CONTACTS
\brief
Functions for managing and sorting contacts resulting from a collision query.
<ul>
<li> Contact lists must be create by calling \ref GIM_CREATE_CONTACT_LIST
<li> After querys, contact lists must be destroy by calling \ref GIM_DYNARRAY_DESTROY
<li> Contacts can be merge for avoid duplicate results by calling \ref gim_merge_contacts
</ul>
*/
//! @{
/**
Configuration var for applying interpolation of contact normals
*/
#define NORMAL_CONTACT_AVERAGE 1
/// Structure for collision results
struct GIM_CONTACT
{
vec3f m_point;
vec3f m_normal;
GREAL m_depth;//Positive value indicates interpenetration
void * m_handle1;
void * m_handle2;
GUINT m_feature1;//Face number
GUINT m_feature2;//Face number
};
//typedef struct _GIM_CONTACT GIM_CONTACT;
#define CONTACT_DIFF_EPSILON 0.00001f
#define GIM_CALC_KEY_CONTACT(pos,hash)\
{\
GINT _coords[] = {(GINT)(pos[0]*1000.0f+1.0f),(GINT)(pos[1]*1333.0f),(GINT)(pos[2]*2133.0f+3.0f)};\
GUINT _hash=0;\
GUINT *_uitmp = (GUINT *)(&_coords[0]);\
_hash = *_uitmp;\
_uitmp++;\
_hash += (*_uitmp)<<4;\
_uitmp++;\
_hash += (*_uitmp)<<8;\
hash = _hash;\
}\
///Creates a contact list for queries
#define GIM_CREATE_CONTACT_LIST(contact_array) GIM_DYNARRAY_CREATE(GIM_CONTACT,contact_array,64)
#define GIM_PUSH_CONTACT(contact_array, point, normal, deep,handle1, handle2, feat1, feat2)\
{\
GIM_DYNARRAY_PUSH_EMPTY(GIM_CONTACT,contact_array);\
GIM_CONTACT * _last = GIM_DYNARRAY_POINTER_LAST(GIM_CONTACT,contact_array);\
VEC_COPY(_last->m_point,point);\
VEC_COPY(_last->m_normal,normal);\
_last->m_depth = deep;\
_last->m_handle1 = handle1;\
_last->m_handle2 = handle2;\
_last->m_feature1 = feat1;\
_last->m_feature2 = feat2;\
}\
///Receive pointer to contacts
#define GIM_COPY_CONTACTS(dest_contact, source_contact)\
{\
VEC_COPY(dest_contact->m_point,source_contact->m_point);\
VEC_COPY(dest_contact->m_normal,source_contact->m_normal);\
dest_contact->m_depth = source_contact->m_depth;\
dest_contact->m_handle1 = source_contact->m_handle1;\
dest_contact->m_handle2 = source_contact->m_handle2;\
dest_contact->m_feature1 = source_contact->m_feature1;\
dest_contact->m_feature2 = source_contact->m_feature2;\
}\
//! Merges duplicate contacts with minimum depth criterion
void gim_merge_contacts(GDYNAMIC_ARRAY * source_contacts,
GDYNAMIC_ARRAY * dest_contacts);
//! Merges to an unique contact
void gim_merge_contacts_unique(GDYNAMIC_ARRAY * source_contacts,
GDYNAMIC_ARRAY * dest_contacts);
//! @}
#endif // GIM_CONTACT_H_INCLUDED

File diff suppressed because it is too large Load Diff

View File

@ -1,168 +0,0 @@
#ifndef GIM_MATH_H_INCLUDED
#define GIM_MATH_H_INCLUDED
/*! \file gim_math.h
\author Francisco León Nájera
*/
/*
-----------------------------------------------------------------------------
This source file is part of GIMPACT Library.
For the latest info, see http://gimpact.sourceforge.net/
Copyright (c) 2006 Francisco Leon Najera. C.C. 80087371.
email: projectileman@yahoo.com
This library is free software; you can redistribute it and/or
modify it under the terms of EITHER:
(1) The GNU Lesser General Public License as published by the Free
Software Foundation; either version 2.1 of the License, or (at
your option) any later version. The text of the GNU Lesser
General Public License is included with this library in the
file GIMPACT-LICENSE-LGPL.TXT.
(2) The BSD-style license that is included with this library in
the file GIMPACT-LICENSE-BSD.TXT.
(3) The zlib/libpng license that is included with this library in
the file GIMPACT-LICENSE-ZLIB.TXT.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files
GIMPACT-LICENSE-LGPL.TXT, GIMPACT-LICENSE-ZLIB.TXT and GIMPACT-LICENSE-BSD.TXT for more details.
-----------------------------------------------------------------------------
*/
#include <math.h>
#include <float.h>
/*! \defgroup BASIC_TYPES
Basic types and constants
Conventions:
Types starting with G
Constants starting with G_
*/
//! @{
/*! Types */
#define GREAL float
#define GREAL2 double
#define GINT long
#define GUINT unsigned long
#define GSHORT short
#define GUSHORT unsigned short
/*! Constants for integers*/
#define GUINT_BIT_COUNT 32
#define GUINT_EXPONENT 5
#define G_FASTMATH 1
#define G_PI 3.14159265358979f
#define G_HALF_PI 1.5707963f
//267948966
#define G_TWO_PI 6.28318530f
//71795864
#define G_ROOT3 1.73205f
#define G_ROOT2 1.41421f
#define G_UINT_INFINITY 65534
#define G_REAL_INFINITY FLT_MAX
#define G_SIGN_BITMASK 0x80000000
#define G_USE_EPSILON_TEST
#define G_EPSILON 0.0000001f
//! @}
/*! \defgroup SCALAR_TYPES
\brief
Precision type constants
*/
//! @{
#define G_STYPE_REAL 0
#define G_STYPE_REAL2 1
#define G_STYPE_SHORT 2
#define G_STYPE_USHORT 3
#define G_STYPE_INT 4
#define G_STYPE_UINT 5
//! @}
/*! \defgroup MATH_FUNCTIONS
mathematical functions
*/
//! @{
#define G_DEGTORAD(X) ((X)*3.1415926f/180.0f)
#define G_RADTODEG(X) ((X)*180.0f/3.1415926f)
//! Integer representation of a floating-point value.
#define GIM_IR(x) ((GUINT&)(x))
//! Signed integer representation of a floating-point value.
#define GIM_SIR(x) ((GINT&)(x))
//! Absolute integer representation of a floating-point value
#define GIM_AIR(x) (GIM_IR(x)&0x7fffffff)
//! Floating-point representation of an integer value.
#define GIM_FR(x) ((GREAL&)(x))
#define GIM_MAX(a,b) (a<b?b:a)
#define GIM_MIN(a,b) (a>b?b:a)
#define GIM_MAX3(a,b,c) GIM_MAX(a,GIM_MAX(b,c))
#define GIM_MIN3(a,b,c) GIM_MIN(a,GIM_MIN(b,c))
#define GIM_IS_ZERO(value) (value < G_EPSILON && value > -G_EPSILON)
#define GIM_IS_NEGATIVE(value) (value <= -G_EPSILON)
#define GIM_IS_POSISITVE(value) (value >= G_EPSILON)
///returns a clamped number
#define GIM_CLAMP(number,minval,maxval) (number<minval?minval:(number>maxval?maxval:number))
#define GIM_GREATER(x, y) fabsf(x) > (y)
///Swap numbers
#define GIM_SWAP_NUMBERS(a,b){ \
a = a+b; \
b = a-b; \
a = a-b; \
}\
#define GIM_INV_SQRT(va,isva)\
{\
if(va<=0.0000001f)\
{\
isva = G_REAL_INFINITY;\
}\
else\
{\
GREAL _x = va * 0.5f;\
GUINT _y = 0x5f3759df - ( GIM_IR(va) >> 1);\
isva = GIM_FR(_y);\
isva = isva * ( 1.5f - ( _x * isva * isva ) );\
}\
}\
#define GIM_SQRT(va,sva)\
{\
GIM_INV_SQRT(va,sva);\
sva = 1.0f/sva;\
}\
//! Computes 1.0f / sqrtf(x). Comes from Quake3. See http://www.magic-software.com/3DGEDInvSqrt.html
GREAL gim_inv_sqrt(GREAL f);
//! Computes sqrtf(x) faster.
/*!
\sa gim_inv_sqrt
*/
GREAL gim_sqrt(GREAL f);
//!Initializes mathematical functions
void gim_init_math();
//! Generates an unit random
GREAL gim_unit_random();
//! @}
#endif // GIM_MATH_H_INCLUDED

File diff suppressed because it is too large Load Diff

View File

@ -1,302 +0,0 @@
#ifndef GIM_RADIXSORT_H_INCLUDED
#define GIM_RADIXSORT_H_INCLUDED
/*! \file gim_radixsort.h
\author Francisco León Nájera.
Based on the work of Michael Herf : "fast floating-point radix sort"
Avaliable on http://www.stereopsis.com/radix.html
*/
/*
-----------------------------------------------------------------------------
This source file is part of GIMPACT Library.
For the latest info, see http://gimpact.sourceforge.net/
Copyright (c) 2006 Francisco Leon Najera. C.C. 80087371.
email: projectileman@yahoo.com
This library is free software; you can redistribute it and/or
modify it under the terms of EITHER:
(1) The GNU Lesser General Public License as published by the Free
Software Foundation; either version 2.1 of the License, or (at
your option) any later version. The text of the GNU Lesser
General Public License is included with this library in the
file GIMPACT-LICENSE-LGPL.TXT.
(2) The BSD-style license that is included with this library in
the file GIMPACT-LICENSE-BSD.TXT.
(3) The zlib/libpng license that is included with this library in
the file GIMPACT-LICENSE-ZLIB.TXT.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files
GIMPACT-LICENSE-LGPL.TXT, GIMPACT-LICENSE-ZLIB.TXT and GIMPACT-LICENSE-BSD.TXT for more details.
-----------------------------------------------------------------------------
*/
#include "GIMPACT/gim_memory.h"
/*! \defgroup SORTING
\brief
Macros for sorting.
*/
//! @{
struct GIM_RSORT_TOKEN
{
GUINT m_key;
GUINT m_value;
};
//typedef struct _GIM_RSORT_TOKEN GIM_RSORT_TOKEN;
//comparator for sorting
#define RSORT_TOKEN_COMPARATOR(x, y) ((int)((x.m_key) - (y.m_key)))
// ---- utils for accessing 11-bit quantities
#define D11_0(x) (x & 0x7FF)
#define D11_1(x) (x >> 11 & 0x7FF)
#define D11_2(x) (x >> 22 )
//COMMON FUNCTIONS FOR ACCESSING THE KEY OF AN ELEMENT
//For the type of your array, you need to declare a macro for obtaining the key, like these:
#define SIMPLE_GET_FLOAT32KEY(e,key) {key =(GREAL)(e);}
#define SIMPLE_GET_INTKEY(e,key) {key =(GINT)(e);}
#define SIMPLE_GET_UINTKEY(e,key) {key =(GUINT)(e);}
//For the type of your array, you need to declare a macro for copy elements, like this:
#define SIMPLE_COPY_ELEMENTS(dest,src) {dest = src;}
#define kHist 2048
///Radix sort for unsigned integer keys
#define GIM_RADIX_SORT_RTOKENS(array,sorted,element_count)\
{\
GUINT i;\
GUINT b0[kHist * 3];\
GUINT *b1 = b0 + kHist;\
GUINT *b2 = b1 + kHist;\
for (i = 0; i < kHist * 3; i++)\
{\
b0[i] = 0;\
}\
GUINT fi;\
GUINT pos;\
for (i = 0; i < element_count; i++)\
{\
fi = array[i].m_key;\
b0[D11_0(fi)] ++;\
b1[D11_1(fi)] ++;\
b2[D11_2(fi)] ++;\
}\
{\
GUINT sum0 = 0, sum1 = 0, sum2 = 0;\
GUINT tsum;\
for (i = 0; i < kHist; i++)\
{\
tsum = b0[i] + sum0;\
b0[i] = sum0 - 1;\
sum0 = tsum;\
tsum = b1[i] + sum1;\
b1[i] = sum1 - 1;\
sum1 = tsum;\
tsum = b2[i] + sum2;\
b2[i] = sum2 - 1;\
sum2 = tsum;\
}\
}\
for (i = 0; i < element_count; i++)\
{\
fi = array[i].m_key;\
pos = D11_0(fi);\
pos = ++b0[pos];\
sorted[pos].m_key = array[i].m_key;\
sorted[pos].m_value = array[i].m_value;\
}\
for (i = 0; i < element_count; i++)\
{\
fi = sorted[i].m_key;\
pos = D11_1(fi);\
pos = ++b1[pos];\
array[pos].m_key = sorted[i].m_key;\
array[pos].m_value = sorted[i].m_value;\
}\
for (i = 0; i < element_count; i++)\
{\
fi = array[i].m_key;\
pos = D11_2(fi);\
pos = ++b2[pos];\
sorted[pos].m_key = array[i].m_key;\
sorted[pos].m_value = array[i].m_value;\
}\
}\
/// Get the sorted tokens from an array. For generic use. Tokens are GIM_RSORT_TOKEN
#define GIM_RADIX_SORT_ARRAY_TOKENS(array, sorted_tokens, element_count, get_uintkey_macro)\
{\
GIM_RSORT_TOKEN * _unsorted = (GIM_RSORT_TOKEN *) gim_alloc(sizeof(GIM_RSORT_TOKEN )*element_count);\
GUINT _i;\
for (_i=0;_i<element_count;_i++)\
{\
get_uintkey_macro(array[_i],_unsorted[_i].m_key);\
_unsorted[_i].m_value = _i;\
}\
GIM_RADIX_SORT_RTOKENS(_unsorted,sorted_tokens,element_count);\
gim_free(_unsorted,sizeof(GIM_RSORT_TOKEN )*element_count);\
}\
/// Sorts array in place. For generic use
#define GIM_RADIX_SORT(type,array,element_count,get_uintkey_macro,copy_elements_macro)\
{\
GIM_RSORT_TOKEN * _sorted = (GIM_RSORT_TOKEN *) gim_alloc(sizeof(GIM_RSORT_TOKEN )*element_count);\
GIM_RADIX_SORT_ARRAY_TOKENS(array,_sorted,element_count,get_uintkey_macro);\
type * _original_array = (type *) gim_alloc(sizeof(type)*element_count); \
memcpy(_original_array,array,sizeof(type)*element_count);\
GUINT _i;\
for (_i=0;_i<element_count;_i++)\
{\
copy_elements_macro(array[_i],_original_array[_sorted[_i].m_value]);\
}\
gim_free(_original_array,sizeof(type)*element_count);\
gim_free(_sorted,sizeof(GIM_RSORT_TOKEN )*element_count);\
}\
/// Sorts array in place using quick sort
#define GIM_QUICK_SORT_ARRAY(type, array, array_count, comp_macro, exchange_macro) \
{\
GINT _i_, _j_, _p_, _stack_index_, _start_, _end_;\
GINT _start_stack_[64]; \
GINT _end_stack_[64];\
_start_stack_[0] = 0;\
_end_stack_[0] = (array_count);\
_stack_index_ = 1;\
while (_stack_index_ > 0)\
{\
_stack_index_ --;\
_start_ = _start_stack_[_stack_index_];\
_end_ = _end_stack_[_stack_index_];\
while (_end_ - _start_ > 2)\
{\
_p_ = _start_;\
_i_ = _start_ + 1;\
_j_ = _end_ - 1;\
while (_i_<_j_) \
{\
for(; _i_<=_j_ && comp_macro(((array)[_i_]),((array)[_p_]))<=0; _i_++) ;\
if (_i_ > _j_) \
{\
exchange_macro(type, array, _j_, _p_);\
_i_ = _j_;\
}\
else\
{\
for(; _i_<=_j_ && comp_macro(((array)[_j_]),((array)[_p_]))>=0; _j_--) ;\
if (_i_ > _j_) \
{\
exchange_macro(type, array, _j_, _p_);\
_i_ = _j_;\
}\
else if (_i_ < _j_)\
{\
exchange_macro(type, array, _i_, _j_);\
if (_i_+2 < _j_) {_i_++; _j_--;}\
else if (_i_+1 < _j_) _i_++;\
}\
}\
}\
if (_i_-_start_ > 1 && _end_-_j_ > 1) \
{\
if (_i_-_start_ < _end_-_j_-1) \
{\
_start_stack_[_stack_index_] = _j_+1;\
_end_stack_[_stack_index_] = _end_;\
_stack_index_ ++;\
_end_ = _i_;\
}\
else\
{\
_start_stack_[_stack_index_] = _start_;\
_end_stack_[_stack_index_] = _i_;\
_stack_index_ ++;\
_start_ = _j_+1;\
}\
}\
else\
{\
if (_i_-_start_ > 1)\
{\
_end_ = _i_;\
}\
else \
{\
_start_ = _j_+1;\
}\
}\
}\
if (_end_ - _start_ == 2) \
{\
if (comp_macro(((array)[_start_]),((array)[_end_-1])) > 0) \
{\
exchange_macro(type, array, _start_, _end_-1);\
}\
}\
}\
}\
#define GIM_DEF_EXCHANGE_MACRO(type, _array, _i, _j)\
{\
type _e_tmp_ =(_array)[(_i)];\
(_array)[(_i)]=(_array)[(_j)];\
(_array)[(_j)]= _e_tmp_;\
}\
#define GIM_COMP_MACRO(x, y) ((GINT)((x) - (y)))
//! Iterative binary search
/*!
\param _array
\param _start_i the beginning of the array
\param _end_i the ending index of the array
\param _search_key Value to find
\param _comp_macro macro for comparing elements
\param _found If 1 the value has found
\param _result_index the index of the found element, or if not found then it will get the index of the closest bigger value
*/
#define GIM_BINARY_SEARCH(_array, _start_i, _end_i, _search_key, _comp_macro, _found, _result_index)\
{\
GUINT _k, _comp_result, _i, _j;\
_i = _start_i; \
_j = _end_i+1;\
_found = 0;\
while ((_i < _j) &&( _found==0)) \
{\
_k = (_j+_i-1)/2;\
_comp_result = _comp_macro(_array[_k], _search_key);\
if (_comp_result == 0) \
{\
_result_index = _k; \
_found = 1;\
}\
else if (_comp_result < 0) \
{\
_i = _k+1;\
} \
else\
{\
_j = _k;\
}\
}\
if (_found == 0) \
{\
_result_index = _j;\
}\
}\
//! @}
#endif // GIM_RADIXSORT_H_INCLUDED

View File

@ -1,113 +0,0 @@
#ifndef GIM_TRI_CAPSULE_COLLISION_H_INCLUDED
#define GIM_TRI_CAPSULE_COLLISION_H_INCLUDED
/*! \file gim_tri_capsule_collision.h
\author Francisco León Nájera
*/
/*
-----------------------------------------------------------------------------
This source file is part of GIMPACT Library.
For the latest info, see http://gimpact.sourceforge.net/
Copyright (c) 2006 Francisco Leon Najera. C.C. 80087371.
email: projectileman@yahoo.com
This library is free software; you can redistribute it and/or
modify it under the terms of EITHER:
(1) The GNU Lesser General Public License as published by the Free
Software Foundation; either version 2.1 of the License, or (at
your option) any later version. The text of the GNU Lesser
General Public License is included with this library in the
file GIMPACT-LICENSE-LGPL.TXT.
(2) The BSD-style license that is included with this library in
the file GIMPACT-LICENSE-BSD.TXT.
(3) The zlib/libpng license that is included with this library in
the file GIMPACT-LICENSE-ZLIB.TXT.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files
GIMPACT-LICENSE-LGPL.TXT, GIMPACT-LICENSE-ZLIB.TXT and GIMPACT-LICENSE-BSD.TXT for more details.
-----------------------------------------------------------------------------
*/
#include "GIMPACT/gim_memory.h"
/*! \addtogroup GEOMETRIC_OPERATIONS
*/
//! @{
//! Capsule struct
struct GIM_CAPSULE_DATA
{
GREAL m_radius;
vec3f m_point1;
vec3f m_point2;
};
//typedef struct _GIM_CAPSULE_DATA GIM_CAPSULE_DATA;
#define CALC_CAPSULE_AABB(capsule,aabb)\
{\
if(capsule.m_point1[0]<capsule.m_point2[0])\
{\
aabb.minX = capsule.m_point1[0] - capsule.m_radius;\
aabb.maxX = capsule.m_point2[0] + capsule.m_radius;\
}\
else\
{\
aabb.minX = capsule.m_point2[0] - capsule.m_radius;\
aabb.maxX = capsule.m_point1[0] + capsule.m_radius;\
}\
if(capsule.m_point1[1]<capsule.m_point2[1])\
{\
aabb.minY = capsule.m_point1[1] - capsule.m_radius;\
aabb.maxY = capsule.m_point2[1] + capsule.m_radius;\
}\
else\
{\
aabb.minY = capsule.m_point2[1] - capsule.m_radius;\
aabb.maxY = capsule.m_point1[1] + capsule.m_radius;\
}\
if(capsule.m_point1[2]<capsule.m_point2[2])\
{\
aabb.minZ = capsule.m_point1[2] - capsule.m_radius;\
aabb.maxZ = capsule.m_point2[2] + capsule.m_radius;\
}\
else\
{\
aabb.minZ = capsule.m_point2[2] - capsule.m_radius;\
aabb.maxZ = capsule.m_point1[2] + capsule.m_radius;\
}\
}\
//! Utility function for find the closest point between a segment and a triangle
/*!
\param triangle
\param s1
\param s2
\param contacts Contains the closest points on the segment (1,2), and the normal points to segment, and m_depth contains the distance
\post The contacts array is not set to 0. It adds aditional contacts
*/
void gim_closest_point_triangle_segment(GIM_TRIANGLE_DATA * triangle, vec3f s1,vec3f s2, GDYNAMIC_ARRAY * contacts);
//! Utility function for find the closest point between a capsule and a triangle
/*!
\param triangle
\param capsule
\param contacts Contains the closest points on the capsule, and the normal points to triangle
\return 1 if the triangle collides the capsule
\post The contacts array is not set to 0. It adds aditional contacts
*/
int gim_triangle_capsule_collision(GIM_TRIANGLE_DATA * triangle, GIM_CAPSULE_DATA * capsule, GDYNAMIC_ARRAY * contacts);
//! @}
#endif // GIM_TRI_CAPSULE_COLLISION_H_INCLUDED

View File

@ -1,256 +0,0 @@
#ifndef GIM_TRI_COLLISION_H_INCLUDED
#define GIM_TRI_COLLISION_H_INCLUDED
/*! \file gim_tri_collision.h
\author Francisco León Nájera
*/
/*
-----------------------------------------------------------------------------
This source file is part of GIMPACT Library.
For the latest info, see http://gimpact.sourceforge.net/
Copyright (c) 2006 Francisco Leon Najera. C.C. 80087371.
email: projectileman@yahoo.com
This library is free software; you can redistribute it and/or
modify it under the terms of EITHER:
(1) The GNU Lesser General Public License as published by the Free
Software Foundation; either version 2.1 of the License, or (at
your option) any later version. The text of the GNU Lesser
General Public License is included with this library in the
file GIMPACT-LICENSE-LGPL.TXT.
(2) The BSD-style license that is included with this library in
the file GIMPACT-LICENSE-BSD.TXT.
(3) The zlib/libpng license that is included with this library in
the file GIMPACT-LICENSE-ZLIB.TXT.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files
GIMPACT-LICENSE-LGPL.TXT, GIMPACT-LICENSE-ZLIB.TXT and GIMPACT-LICENSE-BSD.TXT for more details.
-----------------------------------------------------------------------------
*/
/*! \addtogroup GEOMETRIC_OPERATIONS
*/
//! @{
#define MAX_TRI_CLIPPING 8
//! Clips a polygon by a plane
#define PLANE_CLIP_POLYGON(plane,polygon_points,polygon_point_count,clipped,clipped_count,max_clipped) \
{ \
clipped_count = 0; \
GUINT _i, _vi, _prevclassif=32000, _classif; \
GREAL _d; \
for(_i=0;_i<=polygon_point_count;_i++) \
{ \
_vi = _i%polygon_point_count; \
_d = DISTANCE_PLANE_POINT(plane,polygon_points[_vi]); \
_classif = _d>G_EPSILON ?1:0; \
if(_classif == 0) \
{ \
if(_prevclassif==1) \
{\
if(clipped_count<max_clipped) \
{\
PLANE_CLIP_SEGMENT(polygon_points[_i-1],polygon_points[_vi],plane,clipped[clipped_count]); \
clipped_count++; \
} \
} \
if(clipped_count<max_clipped&&_i<polygon_point_count) \
{ \
VEC_COPY(clipped[clipped_count],polygon_points[_vi]); \
clipped_count++; \
} \
} \
else \
{ \
if(_prevclassif==0) \
{ \
if(clipped_count<max_clipped) \
{ \
PLANE_CLIP_SEGMENT(polygon_points[_i-1],polygon_points[_vi],plane,clipped[clipped_count]); \
clipped_count++; \
} \
} \
} \
_prevclassif = _classif; \
} \
}\
struct GIM_TRIPLANES_CACHE
{
/*!
Planes are:
0 : Face normal plane (0,3)
1 : Edge 1 plane (4,7)
2 : Edge 2 plane (8,11)
3 : Edge 3 plane (12,15)
*/
vec4f m_planes[4];
};
//typedef struct _GIM_TRIPLANES_CACHE GIM_TRIPLANES_CACHE;
struct GIM_TRIANGLE_DATA
{
vec3f m_vertices[3];
GIM_TRIPLANES_CACHE m_planes;
int m_has_planes;
};
//typedef struct _GIM_TRIANGLE_DATA GIM_TRIANGLE_DATA;
//! tri_data is a GIM_TRIANGLE_DATA
#define GIM_CALC_TRIANGLE_DATA_PLANES(tri_data)\
{\
TRIANGLE_PLANE((tri_data).m_vertices[0],(tri_data).m_vertices[1],(tri_data).m_vertices[2],(tri_data).m_planes.m_planes[0]);\
EDGE_PLANE((tri_data).m_vertices[0],(tri_data).m_vertices[1],((tri_data).m_planes.m_planes[0]),((tri_data).m_planes.m_planes[1]));\
EDGE_PLANE((tri_data).m_vertices[1],(tri_data).m_vertices[2],((tri_data).m_planes.m_planes[0]),((tri_data).m_planes.m_planes[2]));\
EDGE_PLANE((tri_data).m_vertices[2],(tri_data).m_vertices[0],((tri_data).m_planes.m_planes[0]), ((tri_data).m_planes.m_planes[3]));\
}\
//Structure for collision
struct GIM_TRIANGLE_CONTACT_DATA
{
GREAL m_penetration_depth;
GUINT m_point_count;
vec3f m_separating_normal;
vec3f m_points[MAX_TRI_CLIPPING];
};
//typedef struct _GIM_TRIANGLE_CONTACT_DATA GIM_TRIANGLE_CONTACT_DATA;
struct GIM_TRIANGLE_RAY_CONTACT_DATA
{
GREAL u;
GREAL v;
GREAL tparam;
GUINT m_face_id;
vec3f m_point;
vec3f m_normal;
};
//typedef struct _GIM_TRIANGLE_RAY_CONTACT_DATA GIM_TRIANGLE_RAY_CONTACT_DATA;
//! Fast Triangle Triangle overlapping test
int gim_triangle_triangle_overlap(
GIM_TRIANGLE_DATA *tri1,
GIM_TRIANGLE_DATA *tri2);
//! Fast but inacurate conservative Triangle Triangle overlapping test
int gim_triangle_triangle_overlap_fast(
GIM_TRIANGLE_DATA *tri1,
GIM_TRIANGLE_DATA *tri2);
//! Finds the contact points from a collision of two triangles
/*!
Returns the contact points, the penetration depth and the separating normal of the collision
between two triangles. The normal is pointing toward triangle 1 from triangle 2
*/
int gim_triangle_triangle_collision(
GIM_TRIANGLE_DATA *tri1,
GIM_TRIANGLE_DATA *tri2,
GIM_TRIANGLE_CONTACT_DATA * contact_data);
//Ray triangle
/*!
Solve the System for u,v parameters:
u*axe1[i1] + v*axe2[i1] = vecproj[i1]
u*axe1[i2] + v*axe2[i2] = vecproj[i2]
sustitute:
v = (vecproj[i2] - u*axe1[i2])/axe2[i2]
then the first equation in terms of 'u':
--> u*axe1[i1] + ((vecproj[i2] - u*axe1[i2])/axe2[i2])*axe2[i1] = vecproj[i1]
--> u*axe1[i1] + vecproj[i2]*axe2[i1]/axe2[i2] - u*axe1[i2]*axe2[i1]/axe2[i2] = vecproj[i1]
--> u*(axe1[i1] - axe1[i2]*axe2[i1]/axe2[i2]) = vecproj[i1] - vecproj[i2]*axe2[i1]/axe2[i2]
--> u*((axe1[i1]*axe2[i2] - axe1[i2]*axe2[i1])/axe2[i2]) = (vecproj[i1]*axe2[i2] - vecproj[i2]*axe2[i1])/axe2[i2]
--> u*(axe1[i1]*axe2[i2] - axe1[i2]*axe2[i1]) = vecproj[i1]*axe2[i2] - vecproj[i2]*axe2[i1]
--> u = (vecproj[i1]*axe2[i2] - vecproj[i2]*axe2[i1]) /(axe1[i1]*axe2[i2] - axe1[i2]*axe2[i1])
if 0.0<= u+v <=1.0 then they are inside of triangle
*/
#define TRIANGLE_GET_UVPARAMETERS(point,vec1,vec2,vec3,tri_plane,u,v,outside)\
{\
vec3f _axe1, _axe2, _vecproj;\
VEC_DIFF(_axe1,vec2,vec1);\
VEC_DIFF(_axe2,vec3,vec1);\
VEC_DIFF(_vecproj,point,vec1);\
GUINT _i1,_i2;\
PLANE_MINOR_AXES(tri_plane, _i1, _i2);\
if(fabsf(_axe2[_i2])<G_EPSILON)\
{\
u = (_vecproj[_i2]*_axe2[_i1] - _vecproj[_i1]*_axe2[_i2]) /(_axe1[_i2]*_axe2[_i1] - _axe1[_i1]*_axe2[_i2]);\
v = (_vecproj[_i1] - u*_axe1[_i1])/_axe2[_i1];\
}\
else\
{\
u = (_vecproj[_i1]*_axe2[_i2] - _vecproj[_i2]*_axe2[_i1]) /(_axe1[_i1]*_axe2[_i2] - _axe1[_i2]*_axe2[_i1]);\
v = (_vecproj[_i2] - u*_axe1[_i2])/_axe2[_i2];\
}\
if(u<-G_EPSILON)\
{\
outside = 1;\
}\
else if(v<-G_EPSILON)\
{\
outside = 1;\
}\
else\
{\
float sumuv;\
sumuv = u+v;\
if(sumuv<-G_EPSILON)\
{\
outside = 1;\
}\
else if(sumuv-1.0f>G_EPSILON)\
{\
outside = 1;\
}\
else\
{\
outside = 0;\
}\
}\
}\
//! Finds the collision of a ray and a triangle.
#define RAY_TRIANGLE_INTERSECTION(vOrigin,vDir,vec1,vec2,vec3,tri_plane,pout,u,v,tparam,tmax,does_intersect)\
{\
RAY_PLANE_COLLISION(tri_plane,vDir,vOrigin,pout,tparam,does_intersect);\
if(does_intersect != 0)\
{\
if(tparam<-G_EPSILON||tparam>tmax+G_EPSILON)\
{\
does_intersect = 0;\
}\
else\
{\
TRIANGLE_GET_UVPARAMETERS(pout,vec1,vec2,vec3,tri_plane,u,v,does_intersect);\
does_intersect = !does_intersect;\
}\
}\
}\
//! @}
#endif // GIM_TRI_COLLISION_H_INCLUDED

View File

@ -1,53 +0,0 @@
#ifndef GIM_TRI_SPHERE_COLLISION_H_INCLUDED
#define GIM_TRI_SPHERE_COLLISION_H_INCLUDED
/*! \file gim_tri_sphere_collision.h
\author Francisco León Nájera
*/
/*
-----------------------------------------------------------------------------
This source file is part of GIMPACT Library.
For the latest info, see http://gimpact.sourceforge.net/
Copyright (c) 2006 Francisco Leon Najera. C.C. 80087371.
email: projectileman@yahoo.com
This library is free software; you can redistribute it and/or
modify it under the terms of EITHER:
(1) The GNU Lesser General Public License as published by the Free
Software Foundation; either version 2.1 of the License, or (at
your option) any later version. The text of the GNU Lesser
General Public License is included with this library in the
file GIMPACT-LICENSE-LGPL.TXT.
(2) The BSD-style license that is included with this library in
the file GIMPACT-LICENSE-BSD.TXT.
(3) The zlib/libpng license that is included with this library in
the file GIMPACT-LICENSE-ZLIB.TXT.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files
GIMPACT-LICENSE-LGPL.TXT, GIMPACT-LICENSE-ZLIB.TXT and GIMPACT-LICENSE-BSD.TXT for more details.
-----------------------------------------------------------------------------
*/
/*! \addtogroup GEOMETRIC_OPERATIONS
*/
//! @{
//! Finds the contact points from a collision of a triangle and a sphere
/*!
\param tri
\param center
\param radius
\param contact_data Contains the closest points on the Sphere, and the normal is pointing to triangle
*/
int gim_triangle_sphere_collision(
GIM_TRIANGLE_DATA *tri,
vec3f center, GREAL radius,
GIM_TRIANGLE_CONTACT_DATA * contact_data);
//! @}
#endif // GIM_TRI_SPHERE_COLLISION_H_INCLUDED

View File

@ -1,657 +0,0 @@
#ifndef GIM_TRIMESH_H_INCLUDED
#define GIM_TRIMESH_H_INCLUDED
/*! \file gim_trimesh.h
\author Francisco León Nájera
*/
/*
-----------------------------------------------------------------------------
This source file is part of GIMPACT Library.
For the latest info, see http://gimpact.sourceforge.net/
Copyright (c) 2006 Francisco Leon Najera. C.C. 80087371.
email: projectileman@yahoo.com
This library is free software; you can redistribute it and/or
modify it under the terms of EITHER:
(1) The GNU Lesser General Public License as published by the Free
Software Foundation; either version 2.1 of the License, or (at
your option) any later version. The text of the GNU Lesser
General Public License is included with this library in the
file GIMPACT-LICENSE-LGPL.TXT.
(2) The BSD-style license that is included with this library in
the file GIMPACT-LICENSE-BSD.TXT.
(3) The zlib/libpng license that is included with this library in
the file GIMPACT-LICENSE-ZLIB.TXT.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files
GIMPACT-LICENSE-LGPL.TXT, GIMPACT-LICENSE-ZLIB.TXT and GIMPACT-LICENSE-BSD.TXT for more details.
-----------------------------------------------------------------------------
*/
#include "GIMPACT/gim_trimesh_data.h"
#include "GIMPACT/gim_vertex_buffer_util.h"
#include "GIMPACT/gim_contact.h"
/*! \addtogroup TRIMESH
\brief
A Trimesh is the basic geometric structure for representing solid objects.
<p><strong>CREATING TRIMESHES</strong></p>
<ul>
<li> For creating trimeshes, you must initialize Buffer managers by calling \ref gimpact_init
<li> Then you must define the vertex and index sources by creating them with \ref BUFFER_ARRAYS routines, and then call \ref gim_trimesh_create_from_arrays.
<li> An alternative way for creaing trimesh objects is calling \ref gim_trimesh_create_from_data.
<li> For access to the trimesh data (vertices, triangle indices), you must call \ref gim_trimesh_locks_work_data , and \ref gim_trimesh_unlocks_work_data for finish the access.
<li> Each time when the trimesh data is modified, you must call \ref gim_trimesh_update after.
<li> When a trimesh is no longer needed, you must call \ref gim_trimesh_destroy.
</ul>
<p>This is an example of how to create a deformable trimesh that shares vertices with the user application:</p>
\code
//Declaration of vertices
vec3f trimeshvertices[200];
//Declaration of indices
GUINT trimeshindices[100];
... Initializing vertices and triangle indices at beginning
//Then create trimesh
GIM_TRIMESH mytrimesh;
//Calling trimesh create function
gim_trimesh_create_from_data(
&mytrimesh,
trimeshvertices,200,
0 ,//copy_vertices is 0
trimeshindices,
100,
0, //copy_indices is 0
0 //transformed_reply is 0
);
\endcode
<p>Note that parameter transformed_reply is 0, that means that m_transformed_vertex_buffer is a reference to m_source_vertex on the trimesh, and transformations are not avaliable. Use that configuration if you have to simulate a deformable trimesh like cloth or elastic bodies.</p>
<p>When the trimesh is no longer needed, destroy it safely with gim_trimesh_destroy()</p>
<p><strong>UPDATING TRIMESHES</strong></p>
<p>On simulation loops, is needed to update trimeshes every time for update vertices althought updating triangle boxes and planes cache. There is two ways for update trimeshes: </p>
<ul>
<li> Updating vertices directly. You need to access to the \ref GIM_TRIMESH.m_source_vertex_buffer member; a vertex buffer which has access to the source vertices.
\code
// Access to the source vertices
gim_buffer_array_lock(&mytrimesh.m_source_vertex_buffer, G_MA_READ_WRITE);
//Get a pointer to the vertex buffer
vec3f * vertexpointer = GIM_BUFFER_ARRAY_POINTER(vec3f,mytrimesh.m_source_vertex_buffer,0);
//Get the amount of vertices
int veccount = mytrimesh.m_source_vertex_buffer.m_element_count;
//Modify vertices
for (int i=0;i<veccount ;i++ )
{
.....
.....
processing vertices
.....
.....
}
// Don't forget to unlock the source vertex array
gim_buffer_array_unlock(&mytrimesh.m_source_vertex_buffer);
// Notify that the state of the trimesh is changed
gim_trimesh_post_update(&mytrimesh.m_source_vertex_buffer);
\endcode
For making trimeshes that allow to update their vertices, use \ref gim_trimesh_create_from_data with parameter <strong>transformed_reply</strong> = 0.
</ul>
<ul>
<li> Aplying a transformation. Simply use \ref gim_trimesh_set_tranform . Remember that with this method trimeshes must be created with \ref gim_trimesh_create_from_data with parameter <strong>transformed_reply</strong> = 1.
</ul>
<p> After updating vertices, you must call \ref gim_trimesh_update()</p>
<p><strong>TRIMESHES COLLISION</strong></p>
<p>Before collide trimeshes, you need to update them first.</p>
<p>Then you must use \ref gim_trimesh_trimesh_collision().</p>
*/
//! @{
//! Prototype for updating vertices
typedef void * gim_update_trimesh_function(struct GIM_TRIMESH *);
struct GIM_TRIMESH_CACHE
{
GDYNAMIC_ARRAY m_planes_cache_buffer;//! Allocated GIM_TRIPLANES_CACHE
GDYNAMIC_ARRAY m_planes_cache_bitset;
//! Allocated transformed vertices vec3f
/*!
\invariant must be aligned
*/
GBUFFER_ARRAY m_transformed_vertex_buffer;
GDYNAMIC_ARRAY m_transformed_vertices_cache_bitset;
GUINT m_tranformed_scalar_type;
};
//! Constant which defines the Bounding volume method
#define G_TRIMESH_BOUND_NONE 0
//! Constant which defines the Bounding volume method
#define G_TRIMESH_BOUND_AABB_TREE 1
//! Constant which defines the Bounding volume method
#define G_TRIMESH_BOUND_AABB_SET 2
///MAsk defines
#define GIM_TRIMESH_APPLY_TRANSFORMATION 1
#define GIM_TRIMESH_NEED_UPDATE 2
//! Trimesh
struct GIM_TRIMESH
{
GUINT m_trimesh_data_handle;//!< Handle to a trimesh data object
GIM_TRIMESH_DATA * m_unlocked_trimesh_data; //!< temporal pointer
char m_mask;//!< Don't use directly
GIM_AABB_SET * m_aabbset;
GIM_TRIMESH_CACHE * m_cache;
gim_update_trimesh_function * m_update_callback;//! If null, then m_transform is applied.
mat4f m_transform;
mat4f m_inv_transform;
};
//typedef struct _GIM_TRIMESH GIM_TRIMESH;
//! Return the bound method
/*!
\ return G_TRIMESH_BOUND_AABB_TREE or G_TRIMESH_BOUND_AABB_SET
*/
GUINT gim_trimesh_get_bound_method(GIM_TRIMESH * trimesh);
/// Info about mesh
//! Return the trimesh triangle count
GUINT gim_trimesh_get_triangle_count(GIM_TRIMESH * trimesh);
GUINT gim_trimesh_get_vertex_count(GIM_TRIMESH * trimesh);
//! Returns 1 if the m_transformed_vertex_buffer is a reply of m_source_vertex_buffer
char gim_trimesh_has_tranform(GIM_TRIMESH * trimesh);
//! Get the global bounding box
void gim_trimesh_get_aabb(GIM_TRIMESH * trimesh,aabb3f * bound);
//! Returns 1 if the trimesh needs to update their aabbset and the planes cache.
char gim_trimesh_needs_update(GIM_TRIMESH * trimesh);
//! Change the state of the trimesh for force it to update
/*!
Call it after made changes to the trimesh.
\post gim_trimesh_need_update(trimesh) will return 1
\sa gim_trimesh_needs_update
*/
void gim_trimesh_post_update(GIM_TRIMESH * trimesh);
//! Creates cache information for this mesh
/*!
*/
void gim_trimesh_initialize_cache(GIM_TRIMESH * trimesh);
//! Destroys the cache
/*!
*/
void gim_trimesh_destroy_cache(GIM_TRIMESH * trimesh);
//! Creates an AABB set for triangles.
/*!
*/
void gim_trimesh_initialize_bound(GIM_TRIMESH * trimesh);
//! Destroys the AABB set
/*!
*/
void gim_trimesh_destroy_bound(GIM_TRIMESH * trimesh);
//! Creates a trimesh
/*!
\param trimesh for be created
\param trimesh_data_handle Handle to a trimesh data
\param apply_transform If 1, then it transforms the source vertices.
\param create_Cache If 1, then it allocates a cache for transformed vertices and planes.
\post Adds a reference to the trimesh_data_handle, and creates the auxiliary data (m_aabbset,m_planes_cache_buffer)
*/
void gim_trimesh_create(GIM_TRIMESH * trimesh, GUINT trimesh_data_handle,char apply_transform,char create_cache);
//! Creates the aabb set and the triangles cache
/*!
\param trimesh
\param vertex_array
\param triindex_array
\param apply_transform If 1, then it transforms the source vertices.
\param create_Cache If 1, then it allocates a cache for transformed vertices and planes.
\param vertex_scalar_type G_STYPE_REAL or G_STYPE_REAL2
\param index_scalar_type G_STYPE_SHORT,G_STYPE_USHORT,G_STYPE_INT or G_STYPE_UINT
\post it copies the arrays by reference, and creates the auxiliary data (m_aabbset,m_planes_cache_buffer)
*/
void gim_trimesh_create_from_arrays(GIM_TRIMESH * trimesh, GBUFFER_ARRAY * vertex_array,GUINT vertex_scalar_type, GBUFFER_ARRAY * triindex_array,GUINT index_scalar_type,
char apply_transform,char create_cache);
//! Create a trimesh from vertex array and an index array
/*!
\param trimesh An uninitialized GIM_TRIMESH structure
\param vertex_array A buffer to a vec3f array
\param vertex_count
\param triindex_array
\param triangle_count
\param copy_vertices If 1, it copies the source vertices in another buffer. Else (0) it constructs a reference to the data.
\param copy_indices If 1, it copies the source vertices in another buffer. Else (0) it constructs a reference to the data.
\param apply_transform If 1, then it transforms the source vertices.
\param create_Cache If 1, then it allocates a cache for transformed vertices and planes.
*/
void gim_trimesh_create_from_data(GIM_TRIMESH * trimesh, vec3f * vertex_array, GUINT vertex_count,char copy_vertices, GUINT * triindex_array, GUINT triangle_count,char copy_indices,
char apply_transform,char create_cache);
//! Clears auxiliary data and releases buffer arrays
void gim_trimesh_destroy(GIM_TRIMESH * trimesh);
//! Copies two meshes
/*!
\param source_trimesh
\param dest_trimesh
\param copy_by_reference If 1, it attach a reference to the source vertices, else it copies the vertices
\param apply_transform If 1, then it transforms the source vertices.
\param create_Cache If 1, then it allocates a cache for transformed vertices and planes.
*/
void gim_trimesh_copy(GIM_TRIMESH * source_trimesh,GIM_TRIMESH * dest_trimesh, char copy_by_reference,
char apply_transform,char create_cache);
//! Locks the trimesh for working with it
/*!
\post locks m_trimesh_data_handle in G_MA_READ_ONLY and m_transformed_vertex_buffer in G_MA_READ_WRITE.
\param trimesh
*/
void gim_trimesh_locks_work_data(GIM_TRIMESH * trimesh);
//! unlocks the trimesh
/*!
\post unlocks m_tri_index_buffer and m_transformed_vertex_buffer.
\param trimesh
*/
void gim_trimesh_unlocks_work_data(GIM_TRIMESH * trimesh);
//! Updates m_transformed_vertex_buffer
/*!
\pre m_transformed_vertex_buffer must be unlocked
*/
void gim_trimesh_update_vertices(GIM_TRIMESH * trimesh);
//! Updates the cache variables
void gim_trimesh_update_cache(GIM_TRIMESH * trimesh);
//! Updates m_aabbset and m_planes_cache_bitset
/*!
\pre gim_trimesh_locks_work_data must be called before
*/
void gim_trimesh_update_aabbset(GIM_TRIMESH * trimesh);
//! Calls before perfom collisions. Updates the trimesh if needed
/*!
\post If gim_trimesh_needs_update returns 1, then it calls gim_trimesh_update_vertices and gim_trimesh_update_aabbset
*/
void gim_trimesh_update(GIM_TRIMESH * trimesh);
//! Set the transform of a trimesh
/*!
\post This function calls to gim_trimesh_post_update
*/
void gim_trimesh_set_tranform(GIM_TRIMESH * trimesh, mat4f transform);
//! Fetch triangle data
/*!
\pre gim_trimesh_locks_work_data must be called before
*/
void gim_trimesh_get_triangle_data(GIM_TRIMESH * trimesh, GUINT triangle_index, GIM_TRIANGLE_DATA * tri_data);
//! Fetch triangle data
/*!
\pre gim_trimesh_locks_work_data must be called before
If Planes cache is not avaliable, it doesn't calc the planes
*/
void gim_trimesh_get_triangle_data_lazy(GIM_TRIMESH * trimesh, GUINT triangle_index, GIM_TRIANGLE_DATA * tri_data);
//! Fetch triangle vertices, transformed to global space
/*!
\pre gim_trimesh_locks_work_data must be called before
*/
void gim_trimesh_get_triangle_vertices(GIM_TRIMESH * trimesh, GUINT triangle_index, vec3f v1,vec3f v2,vec3f v3);
//! Fetch a single transformed vertex
/*!
\pre gim_trimesh_locks_work_data must be called before
*/
void gim_trimesh_get_vertex(GIM_TRIMESH * trimesh, GUINT vertex_index, vec3f vec);
//! Fetch triangle vertices, transformed to global space
/*!
\pre gim_trimesh_locks_work_data must be called before
*/
void gim_trimesh_get_triangle_vertices_local(GIM_TRIMESH * trimesh, GUINT triangle_index, vec3f v1,vec3f v2,vec3f v3);
//! Fetch a single transformed vertex
/*!
\pre gim_trimesh_locks_work_data must be called before
*/
void gim_trimesh_get_vertex_local(GIM_TRIMESH * trimesh, GUINT vertex_index, vec3f vec);
//! Finds Intersected boxes
/*!
\param trimesh
\param test_aabb Box for collision query, in global space
\param collided Array of GUINT elements, indices of trinagles. Must be initialized before (Reserve size ~ 100)
*/
void gim_trimesh_midphase_box_collision(GIM_TRIMESH * trimesh,aabb3f *test_aabb, GDYNAMIC_ARRAY * collided);
//! Finds Intersected boxes in local space
/*!
\param trimesh
\param test_aabb Box for collision query, in global space
\param collided Array of GUINT elements, indices of trinagles. Must be initialized before (Reserve size ~ 100)
*/
void gim_trimesh_midphase_box_collision_local(GIM_TRIMESH * trimesh,aabb3f *test_aabb, GDYNAMIC_ARRAY * collided);
//! Finds overlapping boxes between sets
/*!
\param trimesh1
\param trimesh2
\param collision_pairs Array of GIM_PAIR elements. Must be initialized before (Reserve size ~ 100)
\param swaped If 1, result pairs are swaped and that would means that element 1 belongs to trimesh2 and element 2 belongs to trimesh1. 0 is normal.
*/
void gim_trimesh_midphase_trimesh_collision(GIM_TRIMESH * trimesh1,
GIM_TRIMESH * trimesh2, GDYNAMIC_ARRAY * collision_pairs, char * swaped);
//! Trimesh Trimesh Collisions
/*!
Before use this function you must update each trimesh:
\code
gim_trimesh_update(TriMesh1);
gim_trimesh_update(TriMesh2);
\endcode
Then you must use the trimesh collision in this way:
\code
int collide_trimeshes(GIM_TRIMESH * TriMesh1, GIM_TRIMESH * TriMesh2)
{
//Create contact list
GDYNAMIC_ARRAY trimeshcontacts;
GIM_CREATE_CONTACT_LIST(trimeshcontacts);
//Collide trimeshes
gim_trimesh_trimesh_collision(TriMesh1,TriMesh2,&trimeshcontacts);
if(trimeshcontacts.m_size == 0) //do nothing
{
GIM_DYNARRAY_DESTROY(trimeshcontacts);//clean contact array
return 0;
}
//Getting a pointer to the contact array
GIM_CONTACT * ptrimeshcontacts = GIM_DYNARRAY_POINTER(GIM_CONTACT,trimeshcontacts);
int contactcount = trimeshcontacts.m_size;
int i;
//Process contacts
for (i=0;i<contactcount ;i++)
{
//Do something with the contact (ptrimeshcontacts)
......
......
// Like creating joints or anything else
......
......
ptrimeshcontacts++;
}
GIM_DYNARRAY_DESTROY(trimeshcontacts);
return contactcount;
}
\endcode
In each contact
<ul>
<li> m_handle1 points to trimesh1.
<li> m_handle2 points to trimesh2.
<li> m_feature1 Is a triangle index of trimesh1.
<li> m_feature2 Is a triangle index of trimesh2.
</ul>
\param trimesh1 Collider
\param trimesh2 Collidee
\param contacts A GIM_CONTACT array. Must be initialized
*/
void gim_trimesh_trimesh_collision(GIM_TRIMESH * trimesh1, GIM_TRIMESH * trimesh2, GDYNAMIC_ARRAY * contacts);
//! Trimesh Sphere Collisions
/*!
Before use this function you must update the trimesh:
\code
gim_trimesh_update(trimesh);
\endcode
Then you must use this function in this way:
\code
int collide_trimesh_sphere(GIM_TRIMESH * trimesh, vec3f center,GREAL radius)
{
//Create contact list
GDYNAMIC_ARRAY trimeshcontacts;
GIM_CREATE_CONTACT_LIST(trimeshcontacts);
//Collide trimeshes
gim_trimesh_sphere_collision(trimesh,center,radius,&trimeshcontacts);
if(trimeshcontacts.m_size == 0) //do nothing
{
GIM_DYNARRAY_DESTROY(trimeshcontacts);//clean contact array
return 0;
}
//Getting a pointer to the contact array
GIM_CONTACT * ptrimeshcontacts = GIM_DYNARRAY_POINTER(GIM_CONTACT,trimeshcontacts);
int contactcount = trimeshcontacts.m_size;
int i;
//Process contacts
for (i=0;i<contactcount ;i++)
{
//Do something with the contact (ptrimeshcontacts)
......
......
// Like creating joints or anything else
......
......
ptrimeshcontacts++;
}
GIM_DYNARRAY_DESTROY(trimeshcontacts);
return contactcount;
}
\endcode
In each contact
<ul>
<li> m_handle1 points to trimesh.
<li> m_handle2 points to NULL.
<li> m_feature1 Is a triangle index of trimesh.
</ul>
\param trimesh
\param center
\param radius
\param contacts A GIM_CONTACT array. Must be initialized
*/
void gim_trimesh_sphere_collision(GIM_TRIMESH * trimesh,vec3f center,GREAL radius, GDYNAMIC_ARRAY * contacts);
//! Trimesh Capsule collision
/*!
Find the closest primitive collided by the ray.
Before use this function you must update the trimesh:
\code
gim_trimesh_update(trimesh);
\endcode
Then you must use this function in this way:
\code
int collide_trimesh_capsule(GIM_TRIMESH * trimesh, GIM_CAPSULE_DATA * capsule)
{
//Create contact list
GDYNAMIC_ARRAY trimeshcontacts;
GIM_CREATE_CONTACT_LIST(trimeshcontacts);
//Collide trimeshes
gim_trimesh_capsule_collision(trimesh,capsule,&trimeshcontacts);
if(trimeshcontacts.m_size == 0) //do nothing
{
GIM_DYNARRAY_DESTROY(trimeshcontacts);//clean contact array
return 0;
}
//Getting a pointer to the contact array
GIM_CONTACT * ptrimeshcontacts = GIM_DYNARRAY_POINTER(GIM_CONTACT,trimeshcontacts);
int contactcount = trimeshcontacts.m_size;
int i;
//Process contacts
for (i=0;i<contactcount ;i++)
{
//Do something with the contact (ptrimeshcontacts)
......
......
// Like creating joints or anything else
......
......
ptrimeshcontacts++;
}
GIM_DYNARRAY_DESTROY(trimeshcontacts);
return contactcount;
}
\endcode
In each contact
<ul>
<li> m_handle1 points to trimesh.
<li> m_handle2 points to NULL.
<li> m_feature1 Is a triangle index of trimesh.
</ul>
\param trimesh
\param capsule
\param contacts A GIM_CONTACT array. Must be initialized
*/
void gim_trimesh_capsule_collision(GIM_TRIMESH * trimesh, GIM_CAPSULE_DATA * capsule, GDYNAMIC_ARRAY * contacts);
///Function for create Trimesh Plane collision result
#define GIM_CREATE_TRIMESHPLANE_CONTACTS(dynarray) GIM_DYNARRAY_CREATE(vec4f,dynarray,G_ARRAY_GROW_SIZE)
//! Trimesh Plane Collisions
/*!
Before use this function you must update the trimesh:
\code
gim_trimesh_update(trimesh);
\endcode
Then you must use this function in this way:
\code
int collide_trimesh_plane(GIM_TRIMESH * trimesh, vec4f plane)
{
//Create contact list
GDYNAMIC_ARRAY tri_plane_contacts;
GIM_CREATE_TRIMESHPLANE_CONTACTS(tri_plane_contacts);
//Collide trimeshes
gim_trimesh_plane_collision(trimesh,plane,&tri_plane_contacts);
if(tri_plane_contacts.m_size == 0) //do nothing
{
GIM_DYNARRAY_DESTROY(tri_plane_contacts);//clean contact array
return 0;
}
//Getting a pointer to the contact array
vec4f * planecontacts = GIM_DYNARRAY_POINTER(vec4f,tri_plane_contacts);
int contactcount = tri_plane_contacts.m_size;
int i;
//Process contacts
for (i=0;i<contactcount ;i++)
{
vec3f contactpoint;
GREAL contactdis;
VEC_COPY(contactpoint,planecontacts[i]); //Get contact point
contactdis = planecontacts[i][3]; // Get distance depth
//Do something with the contact
......
......
// Like creating joints or anything else
......
......
}
GIM_DYNARRAY_DESTROY(tri_plane_contacts);
return contactcount;
}
\endcode
In each contact the 3 first coordinates refers to the contact point, the fourth refers to the distance depth and the normal is the normal of the plane.
\param trimesh
\param plane vec4f plane
\param contacts A vec4f array. Must be initialized (~100). Each element have the coordinate point in the first 3 elements, and vec4f[3] has the penetration depth.
*/
void gim_trimesh_plane_collision(GIM_TRIMESH * trimesh,vec4f plane, GDYNAMIC_ARRAY * contacts);
//! Trimesh Ray Collisions
/*!
\param trimesh
\param origin
\param dir
\param tmax
\param contact
\return 1 if the ray collides, else 0
*/
int gim_trimesh_ray_collision(GIM_TRIMESH * trimesh,vec3f origin,vec3f dir, GREAL tmax, GIM_TRIANGLE_RAY_CONTACT_DATA * contact);
//! Trimesh Ray Collisions closest
/*!
Find the closest primitive collided by the ray
\param trimesh
\param origin
\param dir
\param tmax
\param contact
\return 1 if the ray collides, else 0
*/
int gim_trimesh_ray_closest_collision(GIM_TRIMESH * trimesh,vec3f origin,vec3f dir, GREAL tmax, GIM_TRIANGLE_RAY_CONTACT_DATA * contact);
//! @}
#endif // GIM_TRIMESH_H_INCLUDED

View File

@ -1,182 +0,0 @@
#ifndef GIM_TRIMESH_DATA_H_INCLUDED
#define GIM_TRIMESH_DATA_H_INCLUDED
/*! \file gim_trimesh_data.h
\author Francisco León Nájera
*/
/*
-----------------------------------------------------------------------------
This source file is part of GIMPACT Library.
For the latest info, see http://gimpact.sourceforge.net/
Copyright (c) 2006 Francisco Leon Najera. C.C. 80087371.
email: projectileman@yahoo.com
This library is free software; you can redistribute it and/or
modify it under the terms of EITHER:
(1) The GNU Lesser General Public License as published by the Free
Software Foundation; either version 2.1 of the License, or (at
your option) any later version. The text of the GNU Lesser
General Public License is included with this library in the
file GIMPACT-LICENSE-LGPL.TXT.
(2) The BSD-style license that is included with this library in
the file GIMPACT-LICENSE-BSD.TXT.
(3) The zlib/libpng license that is included with this library in
the file GIMPACT-LICENSE-ZLIB.TXT.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files
GIMPACT-LICENSE-LGPL.TXT, GIMPACT-LICENSE-ZLIB.TXT and GIMPACT-LICENSE-BSD.TXT for more details.
-----------------------------------------------------------------------------
*/
#include "GIMPACT/gim_boxpruning.h"
/*! \addtogroup TRIMESH_DATA
\brief
*/
//! @{
//! Class for managing Mesh data
struct GIM_TRIMESH_DATA
{
GUINT m_vertex_scalar_type;//!< G_STYPE_REAL or G_STYPE_REAL2
GUINT m_index_scalar_type;//!< G_STYPE_INT,G_STYPE_UINT, G_STYPE_SHORT or G_STYPE_USHORT
GBUFFER_ARRAY m_source_vertex_buffer;//!< Buffer of vec3f coordinates
//! vec3ui,vec3i,vec3s or vec3us Indices of triangles,groups of three elements.
/*!
Array of Triangle indices. Each triple contains indices of the vertices for each triangle.
Array size = Triangle count
*/
GBUFFER_ARRAY m_tri_index_buffer;
GIM_AABB_TREE m_bv_tree;
GUINT m_ref_count;//!< Refvertex_scalar_typeerence counting
GUINT m_handle;
};
//Functions for trimesh data
//Trimesh data manager
void gim_trimesh_data_manager_init();
void gim_trimesh_data_manager_end();
int gim_trimesh_data_is_valid_manager();
//! Test if the trimesh data has bounding volume tree
int gim_trimesh_data_has_bv_tree(GUINT trimesh_data_handle);
/*!
\param trimesh_data_handle Must be superior to 0
*/
void gim_trimesh_data_get(GUINT trimesh_data_handle,GIM_TRIMESH_DATA ** trimesh_data);
//! Creates an empty trimesh
void gim_trimesh_data_create_empty(GUINT * trimesh_data_handle);
//! Create a trimesh from vertex array and an index array
/*!
\param trimesh_data_handle A pointer to receive the trimesh handle
\param vertex_array A buffer to a vec3f array
\param vertex_count
\param triindex_array
\param index_count
\param copy_vertices If 1, it copies the source vertices in another buffer. Else (0) it constructs a reference to the data.
\param copy_indices If 1, it copies the source vertices in another buffer. Else (0) it constructs a reference to the data.
*/
void gim_trimesh_data_create_from_arrays(GUINT * trimesh_data_handle, GBUFFER_ARRAY * vertex_array,GUINT vertex_scalar_type, GBUFFER_ARRAY * triindex_array,GUINT index_scalar_type);
//! Create a trimesh from vertex array and an index array
/*!
\param trimesh_data_handle A pointer to receive the trimesh handle
\param vertex_array A buffer to a vec3f array
\param vertex_count
\param triindex_array
\param index_count
\param copy_vertices If 1, it copies the source vertices in another buffer. Else (0) it constructs a reference to the data.
\param copy_indices If 1, it copies the source vertices in another buffer. Else (0) it constructs a reference to the data.
*/
void gim_trimesh_data_create_from_array_data(GUINT * trimesh_data_handle, vec3f * vertex_array, GUINT vertex_count,char copy_vertices, GUINT * triindex_array, GUINT triangle_count,char copy_indices);
//! Increase the reference to a GIM_TRIMESH_DATA object
/*!
Use this function for prevents destroying the trimesh data when it stills
is being used. If you have a singleton scene manager, increase the references to all trimesh data resources.
*/
void gim_trimesh_data_inc_ref(GUINT trimesh_data_handle);
//! Decrease the reference to a GIM_TRIMESH_DATA object, and attempts to destroy it
/*!
Use this function for safe destruction of the trimesh data. If the reference of the trimesh is bigger than 1, then
it doen't destroy the trimesh data.
*/
void gim_trimesh_data_dec_ref(GUINT trimesh_data_handle);
void gim_trimesh_data_destroy(GUINT trimesh_data_handle);
/*!
Locks m_source_vertex_buffer and m_tri_index_buffer
*/
void gim_trimesh_data_lock(GUINT trimesh_data_handle, int access,GIM_TRIMESH_DATA ** trimesh_data);
/*!
Unlocks m_source_vertex_buffer and m_tri_index_buffer
*/
void gim_trimesh_data_unlock(GUINT trimesh_data_handle);
GUINT gim_trimesh_data_get_vertex_count(GUINT trimesh_data_handle);
GUINT gim_trimesh_data_get_triangle_count(GUINT trimesh_data_handle);
//! Get triangle indices
/*!
\pre trimesh_data must be locked
*/
void gim_trimesh_data_get_triangle_indices(GIM_TRIMESH_DATA * trimesh_data, GUINT tri_index, GUINT * indices);
//! Get trimesh vertex
/*!
\pre trimesh_data must be locked
*/
void gim_trimesh_data_get_vertex(GIM_TRIMESH_DATA * trimesh_data, GUINT vertex_index, vec3f vec);
//! Get triangle vertices
/*!
\pre trimesh_data must be locked
*/
void gim_trimesh_data_get_triangle_vertices(GIM_TRIMESH_DATA * trimesh_data, GUINT tri_index, vec3f v1, vec3f v2, vec3f v3);
//! Builds a Bounding Volume tree from the Trimesh data
void gim_trimesh_data_build_aabbtree(GUINT trimesh_data_handle);
//! Copies two meshes
/*!
\param source_trimesh_data
\param dest_trimesh_data
\param copy_by_reference If 1, it attach a reference to the source vertices, else it copies the vertices
\param transformed_reply If 1, transformed vertices are reply of source vertives. 1 Is recommended
*/
void gim_trimesh_data_copy(GUINT source_trimesh_data,GUINT dest_trimesh_data, char copy_by_reference);
//! Copies two meshes
/*!
\param source_trimesh_data
\param dest_trimesh_data
\param copy_by_reference If 1, it attach a reference to the source vertices, else it copies the vertices
\param transformed_reply If 1, transformed vertices are reply of source vertives. 1 Is recommended
*/
void gim_trimesh_data_create_copy(GUINT source_trimesh_data,GUINT * dest_trimesh_data, char copy_by_reference);
//! @}
#endif // GIM_TRIMESH_DATA_H_INCLUDED

View File

@ -1,106 +0,0 @@
#ifndef GIM_VERTEX_BUFFER_UTIL_H_INCLUDED
#define GIM_VERTEX_BUFFER_UTIL_H_INCLUDED
/*! \file gim_trimesh_data.h
\author Francisco León Nájera
*/
/*
-----------------------------------------------------------------------------
This source file is part of GIMPACT Library.
For the latest info, see http://gimpact.sourceforge.net/
Copyright (c) 2006 Francisco Leon Najera. C.C. 80087371.
email: projectileman@yahoo.com
This library is free software; you can redistribute it and/or
modify it under the terms of EITHER:
(1) The GNU Lesser General Public License as published by the Free
Software Foundation; either version 2.1 of the License, or (at
your option) any later version. The text of the GNU Lesser
General Public License is included with this library in the
file GIMPACT-LICENSE-LGPL.TXT.
(2) The BSD-style license that is included with this library in
the file GIMPACT-LICENSE-BSD.TXT.
(3) The zlib/libpng license that is included with this library in
the file GIMPACT-LICENSE-ZLIB.TXT.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files
GIMPACT-LICENSE-LGPL.TXT, GIMPACT-LICENSE-ZLIB.TXT and GIMPACT-LICENSE-BSD.TXT for more details.
-----------------------------------------------------------------------------
*/
#include "GIMPACT/gim_geometry.h"
#include "GIMPACT/gim_memory.h"
/*! \addtogroup VERTEX_BUFFER_UTIL
\brief
Functions for processing vertex buffers
*/
//! @{
//Macro for processing vertex buffers
#define GIM_PROCESS_VERTEX_BUFFER_ARRAY(_uniform_data,_src_array,_dst_array,_kernel,_src_scalar_type,_dst_scalar_type)\
{\
if(_src_scalar_type == G_STYPE_REAL)\
{\
if(_dst_scalar_type == G_STYPE_REAL)\
{\
GIM_PROCESS_BUFFER_ARRAY(_uniform_data,_src_array,_dst_array,_kernel,vec3f,vec3f);\
}\
else if(_dst_scalar_type == G_STYPE_REAL2)\
{\
GIM_PROCESS_BUFFER_ARRAY(_uniform_data,_src_array,_dst_array,_kernel,vec3f,vec3d);\
}\
}\
else if(_src_scalar_type == G_STYPE_REAL2)\
{\
if(_dst_scalar_type == G_STYPE_REAL)\
{\
GIM_PROCESS_BUFFER_ARRAY(_uniform_data,_src_array,_dst_array,_kernel,vec3d,vec3f);\
}\
else if(_dst_scalar_type == G_STYPE_REAL2)\
{\
GIM_PROCESS_BUFFER_ARRAY(_uniform_data,_src_array,_dst_array,_kernel,vec3d,vec3f);\
}\
}\
}\
//******Common kernels*******//
#define MULT_MAT_VEC4_KERNEL(_mat,_src,_dst) MAT_DOT_VEC_3X4((_dst),(_mat),(_src))
#define COPY_VEC3_KERNEL(_uni,_src,_dst) VEC_COPY((_dst),(_src))
//******+++++++++++*******//
//! Creates a packed vertex buffer with vec3f
void gim_create_common_vertex_buffer(GBUFFER_ARRAY * vertex_buffer,GUINT vertex_count);
//! Copies vertex buffer arrays
/*!
They must have the same size
*/
void gim_copy_vertex_buffers(GBUFFER_ARRAY * source_vertex_buffer,GUINT source_scalar_type,GBUFFER_ARRAY * dest_vertex_buffer,GUINT dest_scalar_type);
//! Applies a linear transformation to vertices
/*!
They must have the same size
*/
void gim_transform_vertex_buffers(GBUFFER_ARRAY * source_vertex_buffer,GUINT source_scalar_type,GBUFFER_ARRAY * dest_vertex_buffer,GUINT dest_scalar_type, mat4f transform);
//! General processing for vertex arrays
/*!
It's an alternative to GIM_PROCESS_VERTEX_BUFFER_ARRAY
*/
void gim_process_vertex_buffers(GBUFFER_ARRAY * source_vertex_buffer,GUINT source_scalar_type,GBUFFER_ARRAY * dest_vertex_buffer,GUINT dest_scalar_type, void *uniform_data,gim_kernel_func kernel_func);
//! @}
#endif // GIM_VERTEX_BUFFER_UTIL_H_INCLUDED

View File

@ -1,47 +0,0 @@
#ifndef GIMPACT_H_INCLUDED
#define GIMPACT_H_INCLUDED
/*! \file gimpact.h
\author Francisco León Nájera
*/
/*
-----------------------------------------------------------------------------
This source file is part of GIMPACT Library.
For the latest info, see http://gimpact.sourceforge.net/
Copyright (c) 2006 Francisco Leon Najera. C.C. 80087371.
email: projectileman@yahoo.com
This library is free software; you can redistribute it and/or
modify it under the terms of EITHER:
(1) The GNU Lesser General Public License as published by the Free
Software Foundation; either version 2.1 of the License, or (at
your option) any later version. The text of the GNU Lesser
General Public License is included with this library in the
file GIMPACT-LICENSE-LGPL.TXT.
(2) The BSD-style license that is included with this library in
the file GIMPACT-LICENSE-BSD.TXT.
(3) The zlib/libpng license that is included with this library in
the file GIMPACT-LICENSE-ZLIB.TXT.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files
GIMPACT-LICENSE-LGPL.TXT, GIMPACT-LICENSE-ZLIB.TXT and GIMPACT-LICENSE-BSD.TXT for more details.
-----------------------------------------------------------------------------
*/
#include "GIMPACT/gim_trimesh.h"
/*! \defgroup GIMPACT_INIT
*/
//! @{
//! Call this for initialize GIMPACT system structures.
void gimpact_init();
//! Call this for clean GIMPACT system structures.
void gimpact_terminate();
//! @}
#endif // GIMPACT_H_INCLUDED

File diff suppressed because it is too large Load Diff

View File

@ -1,185 +0,0 @@
/*
-----------------------------------------------------------------------------
This source file is part of GIMPACT Library.
For the latest info, see http://gimpact.sourceforge.net/
Copyright (c) 2006 Francisco Leon Najera. C.C. 80087371.
email: projectileman@yahoo.com
This library is free software; you can redistribute it and/or
modify it under the terms of EITHER:
(1) The GNU Lesser General Public License as published by the Free
Software Foundation; either version 2.1 of the License, or (at
your option) any later version. The text of the GNU Lesser
General Public License is included with this library in the
file GIMPACT-LICENSE-LGPL.TXT.
(2) The BSD-style license that is included with this library in
the file GIMPACT-LICENSE-BSD.TXT.
(3) The zlib/libpng license that is included with this library in
the file GIMPACT-LICENSE-ZLIB.TXT.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files
GIMPACT-LICENSE-LGPL.TXT, GIMPACT-LICENSE-ZLIB.TXT and GIMPACT-LICENSE-BSD.TXT for more details.
-----------------------------------------------------------------------------
*/
#include "GIMPACT/gim_contact.h"
#define MAX_COINCIDENT 8
void gim_interpolate_contact_normals(GIM_CONTACT * destcontact,vec3f * normals,GUINT normal_count)
{
GREAL vec_sum[]={0.0f,0.0f,0.0f};
vec3f test_vec;
for(GUINT i=0;i<normal_count;i++)
{
VEC_SCALE(test_vec,destcontact->m_depth,normals[i]);
VEC_SUM(vec_sum,vec_sum,test_vec);
}
if(VEC_DOT(vec_sum,vec_sum)<CONTACT_DIFF_EPSILON) return;
test_vec[0] = 1.0f/((GREAL)normal_count);
VEC_SCALE(vec_sum,test_vec[0],vec_sum);
VEC_LENGTH(vec_sum,destcontact->m_depth);
test_vec[0] = 1.0f/destcontact->m_depth;
VEC_SCALE(destcontact->m_normal,test_vec[0],vec_sum);
}
void gim_merge_contacts(GDYNAMIC_ARRAY * source_contacts,
GDYNAMIC_ARRAY * dest_contacts)
{
dest_contacts->m_size = 0;
GUINT source_count = source_contacts->m_size;
GIM_CONTACT * psource_contacts = GIM_DYNARRAY_POINTER(GIM_CONTACT,(*source_contacts));
//create keys
GIM_RSORT_TOKEN * keycontacts = (GIM_RSORT_TOKEN * )gim_alloc(sizeof(GIM_RSORT_TOKEN)*source_count);
GUINT i;
for(i=0;i<source_count;i++)
{
keycontacts[i].m_value = i;
GIM_CALC_KEY_CONTACT(psource_contacts[i].m_point,keycontacts[i].m_key);
}
//sort keys
GIM_QUICK_SORT_ARRAY(GIM_RSORT_TOKEN , keycontacts, source_count, RSORT_TOKEN_COMPARATOR,GIM_DEF_EXCHANGE_MACRO);
// Merge contacts
GIM_CONTACT * pcontact = 0;
GIM_CONTACT * scontact = 0;
GUINT key,last_key=0;
GUINT coincident_count=0;
vec3f coincident_normals[MAX_COINCIDENT];
for(i=0;i<source_contacts->m_size;i++)
{
key = keycontacts[i].m_key;
scontact = &psource_contacts[keycontacts[i].m_value];
if(i>0 && last_key == key)
{
//merge contact
if(pcontact->m_depth - CONTACT_DIFF_EPSILON > scontact->m_depth)//)
{
GIM_COPY_CONTACTS(pcontact, scontact);
coincident_count = 0;
}
else
{
#if (NORMAL_CONTACT_AVERAGE == 1)
if(fabsf(pcontact->m_depth - scontact->m_depth)<CONTACT_DIFF_EPSILON)
{
if(coincident_count<MAX_COINCIDENT)
{
VEC_COPY(coincident_normals[coincident_count],scontact->m_normal);
coincident_count++;
}
}
#endif
}
}
else
{//add new contact
#if (NORMAL_CONTACT_AVERAGE == 1)
if(pcontact&&coincident_count>0)
{
gim_interpolate_contact_normals(pcontact,coincident_normals,coincident_count);
coincident_count = 0;
}
#endif
GIM_DYNARRAY_PUSH_EMPTY(GIM_CONTACT,(*dest_contacts));
pcontact = GIM_DYNARRAY_POINTER_LAST(GIM_CONTACT,(*dest_contacts));
GIM_COPY_CONTACTS(pcontact, scontact);
coincident_count=0;
}
last_key = key;
}
gim_free(keycontacts,0);
}
void gim_merge_contacts_unique(GDYNAMIC_ARRAY * source_contacts,
GDYNAMIC_ARRAY * dest_contacts)
{
dest_contacts->m_size = 0;
//Traverse the source contacts
GUINT source_count = source_contacts->m_size;
if(source_count==0) return;
GIM_CONTACT * psource_contacts = GIM_DYNARRAY_POINTER(GIM_CONTACT,(*source_contacts));
//add the unique contact
GIM_CONTACT * pcontact = 0;
GIM_DYNARRAY_PUSH_EMPTY(GIM_CONTACT,(*dest_contacts));
pcontact = GIM_DYNARRAY_POINTER_LAST(GIM_CONTACT,(*dest_contacts));
//set the first contact
GIM_COPY_CONTACTS(pcontact, psource_contacts);
if(source_count==1) return;
//scale the first contact
VEC_SCALE(pcontact->m_normal,pcontact->m_depth,pcontact->m_normal);
psource_contacts++;
//Average the contacts
GUINT i;
for(i=1;i<source_count;i++)
{
VEC_SUM(pcontact->m_point,pcontact->m_point,psource_contacts->m_point);
VEC_ACCUM(pcontact->m_normal,psource_contacts->m_depth,psource_contacts->m_normal);
psource_contacts++;
}
GREAL divide_average = 1.0f/((GREAL)source_count);
VEC_SCALE(pcontact->m_point,divide_average,pcontact->m_point);
pcontact->m_depth = VEC_DOT(pcontact->m_normal,pcontact->m_normal)*divide_average;
GIM_SQRT(pcontact->m_depth,pcontact->m_depth);
VEC_NORMALIZE(pcontact->m_normal);
/*GREAL normal_len;
VEC_INV_LENGTH(pcontact->m_normal,normal_len);
VEC_SCALE(pcontact->m_normal,normal_len,pcontact->m_normal);
//Deep = LEN(normal)/SQRT(source_count)
GIM_SQRT(divide_average,divide_average);
pcontact->m_depth = divide_average/normal_len;
*/
}

View File

@ -1,62 +0,0 @@
/*
-----------------------------------------------------------------------------
This source file is part of GIMPACT Library.
For the latest info, see http://gimpact.sourceforge.net/
Copyright (c) 2006 Francisco Leon Najera. C.C. 80087371.
email: projectileman@yahoo.com
This library is free software; you can redistribute it and/or
modify it under the terms of EITHER:
(1) The GNU Lesser General Public License as published by the Free
Software Foundation; either version 2.1 of the License, or (at
your option) any later version. The text of the GNU Lesser
General Public License is included with this library in the
file GIMPACT-LICENSE-LGPL.TXT.
(2) The BSD-style license that is included with this library in
the file GIMPACT-LICENSE-BSD.TXT.
(3) The zlib/libpng license that is included with this library in
the file GIMPACT-LICENSE-ZLIB.TXT.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files
GIMPACT-LICENSE-LGPL.TXT, GIMPACT-LICENSE-ZLIB.TXT and GIMPACT-LICENSE-BSD.TXT for more details.
-----------------------------------------------------------------------------
*/
#include "GIMPACT/gim_math.h"
#include "stdlib.h"
#include "time.h"
GREAL gim_inv_sqrt(GREAL f)
{
GREAL r;
GIM_INV_SQRT(f,r);
return r;
}
GREAL gim_sqrt(GREAL f)
{
GREAL r;
GIM_SQRT(f,r);
return r;
}
//!Initializes mathematical functions
void gim_init_math()
{
srand(time(0));
}
//! Generates an unit random
GREAL gim_unit_random()
{
GREAL rn = rand();
rn/=(GREAL)RAND_MAX;
return rn;
}

View File

@ -1,857 +0,0 @@
/*
-----------------------------------------------------------------------------
This source file is part of GIMPACT Library.
For the latest info, see http://gimpact.sourceforge.net/
Copyright (c) 2006 Francisco Leon Najera. C.C. 80087371.
email: projectileman@yahoo.com
This library is free software; you can redistribute it and/or
modify it under the terms of EITHER:
(1) The GNU Lesser General Public License as published by the Free
Software Foundation; either version 2.1 of the License, or (at
your option) any later version. The text of the GNU Lesser
General Public License is included with this library in the
file GIMPACT-LICENSE-LGPL.TXT.
(2) The BSD-style license that is included with this library in
the file GIMPACT-LICENSE-BSD.TXT.
(3) The zlib/libpng license that is included with this library in
the file GIMPACT-LICENSE-ZLIB.TXT.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files
GIMPACT-LICENSE-LGPL.TXT, GIMPACT-LICENSE-ZLIB.TXT and GIMPACT-LICENSE-BSD.TXT for more details.
-----------------------------------------------------------------------------
*/
#include "GIMPACT/gim_memory.h"
#include "stdlib.h"
//#include "malloc.h"
//#include "mm_malloc.h"
static gim_alloc_function *g_allocfn = 0;
static gim_alloca_function *g_allocafn = 0;
static gim_realloc_function *g_reallocfn = 0;
static gim_free_function *g_freefn = 0;
// buffer managers
#define MAX_BUFFER_MANAGERS 16
static GBUFFER_MANAGER_DATA g_buffer_managers[MAX_BUFFER_MANAGERS];
static GUINT g_buffer_managers_count = 0;
#define VALIDATE_BUFFER_MANAGER(buffer_manager_id)\
if(buffer_manager_id>=MAX_BUFFER_MANAGERS) return G_BUFFER_OP_INVALID;\
GBUFFER_MANAGER_DATA * bm_data;\
gim_get_buffer_manager_data(buffer_manager_id,&bm_data);\
if(bm_data == 0) return G_BUFFER_OP_INVALID;\
#define VALIDATE_BUFFER_ID_PT(buffer_id)\
VALIDATE_BUFFER_MANAGER(buffer_id->m_buffer_manager_id)\
if(buffer_id->m_buffer_id>=bm_data->m_buffer_array.m_size) return G_BUFFER_OP_INVALID;\
GBUFFER_DATA * pbuffer = GIM_DYNARRAY_POINTER(GBUFFER_DATA,bm_data->m_buffer_array);\
pbuffer += buffer_id->m_buffer_id;\
if(pbuffer->m_buffer_handle==0) return G_BUFFER_OP_INVALID;\
void GIM_BUFFER_ARRAY_DESTROY(GBUFFER_ARRAY & array_data)
{
gim_buffer_array_unlock(&array_data);
gim_buffer_free(&(array_data).m_buffer_id);
array_data.m_buffer_id.m_buffer_id = G_UINT_INFINITY;
array_data.m_element_count = 0;
}
void GIM_DYNARRAY_DESTROY(GDYNAMIC_ARRAY & array_data)
{
if(array_data.m_pdata != 0)
{
gim_free(array_data.m_pdata,0);
array_data.m_reserve_size = 0;
array_data.m_size = 0;
array_data.m_pdata = 0;
}
}
void gim_set_alloc_handler (gim_alloc_function *fn)
{
g_allocfn = fn;
}
void gim_set_alloca_handler (gim_alloca_function *fn)
{
g_allocafn = fn;
}
void gim_set_realloc_handler (gim_realloc_function *fn)
{
g_reallocfn = fn;
}
void gim_set_free_handler (gim_free_function *fn)
{
g_freefn = fn;
}
gim_alloc_function *gim_get_alloc_handler()
{
return g_allocfn;
}
gim_alloca_function *gim_get_alloca_handler()
{
return g_allocafn;
}
gim_realloc_function *gim_get_realloc_handler ()
{
return g_reallocfn;
}
gim_free_function *gim_get_free_handler ()
{
return g_freefn;
}
void * gim_alloc(size_t size)
{
char * ptr = 0;
ptr = new char[size]; //malloc(size);
/*if (g_allocfn) ptr = g_allocfn(size); else ptr = malloc(size);//_mm_malloc(size,0);*/
if(ptr==0)
{
float * fp = 0;
*fp = 0.0f;
}
return ptr;
}
#ifdef ALLOCA_GIMPACT
void * gim_alloca(size_t size)
{
if (g_allocafn) return g_allocafn(size); else
return alloca(size);
}
#endif
void * gim_realloc(void *ptr, size_t oldsize, size_t newsize)
{
/*if (g_reallocfn) return g_reallocfn(ptr,oldsize,newsize);
else return realloc(ptr,newsize);*/
//return realloc(ptr,newsize);
void * newptr = gim_alloc(newsize);
size_t copysize = newsize> oldsize? oldsize: newsize;
memcpy(newptr,ptr,copysize);
gim_free(ptr,oldsize);
return newptr;
}
void gim_free(void *ptr, size_t size)
{
if (!ptr) return;
if (g_freefn)
{
g_freefn(ptr,size);
}
else
{
char * cptr = (char *)ptr;
delete [] cptr;
//free(ptr);//_mm_free(ptr);
}
}
///******************************* BUFFER MANAGERS ******************************///
//!** Basic buffer prototyoe functions
GUINT _system_buffer_alloc_function(GUINT size,int usage)
{
void * newdata = gim_alloc(size);
memset(newdata,0,size);
return (GUINT)(newdata);
}
GUINT _system_buffer_alloc_data_function(const void * pdata,GUINT size,int usage)
{
void * newdata = gim_alloc(size);
memcpy(newdata,pdata,size);
return (GUINT)(newdata);
}
GUINT _system_buffer_realloc_function(GUINT buffer_handle,GUINT oldsize,int old_usage,GUINT newsize,int new_usage)
{
void * newdata = gim_realloc((void *)buffer_handle,oldsize,newsize);
return (GUINT)(newdata);
}
void _system_buffer_free_function(GUINT buffer_handle,GUINT size)
{
gim_free((void*)buffer_handle,size);
}
char * _system_lock_buffer_function(GUINT buffer_handle,int access)
{
return (char * )(buffer_handle);
}
void _system_unlock_buffer_function(GUINT buffer_handle)
{
}
void _system_download_from_buffer_function(
GUINT source_buffer_handle,
GUINT source_pos,
void * destdata,
GUINT copysize)
{
char * pdata;
pdata = (char *)source_buffer_handle;
memcpy(destdata,pdata+source_pos,copysize);
}
void _system_upload_to_buffer_function(
GUINT dest_buffer_handle,
GUINT dest_pos,
void * sourcedata,
GUINT copysize)
{
char * pdata;
pdata = (char * )dest_buffer_handle;
memcpy(pdata+dest_pos,sourcedata,copysize);
}
void _system_copy_buffers_function(
GUINT source_buffer_handle,
GUINT source_pos,
GUINT dest_buffer_handle,
GUINT dest_pos,
GUINT copysize)
{
char * pdata1,*pdata2;
pdata1 = (char *)source_buffer_handle;
pdata2 = (char *)dest_buffer_handle;
memcpy(pdata2+dest_pos,pdata1+source_pos,copysize);
}
GUINT _shared_buffer_alloc_function(GUINT size,int usage)
{
return 0;
}
GUINT _shared_buffer_alloc_data_function(const void * pdata,GUINT size,int usage)
{
return (GUINT)pdata;
}
GUINT _shared_buffer_realloc_function(GUINT buffer_handle,GUINT oldsize,int old_usage,GUINT newsize,int new_usage)
{
return 0;
}
void _shared_buffer_free_function(GUINT buffer_handle,GUINT size)
{
}
//!** Buffer manager operations
void gim_create_buffer_manager(GBUFFER_MANAGER_PROTOTYPE * prototype,GUINT buffer_manager_id)
{
GBUFFER_MANAGER_DATA * bm_data;
bm_data = &g_buffer_managers[buffer_manager_id];
if(bm_data->m_active==0)
{
if(g_buffer_managers_count<=buffer_manager_id)
{
g_buffer_managers_count = buffer_manager_id+1;
}
}
else
{
gim_destroy_buffer_manager(buffer_manager_id);
}
bm_data->m_active = 1;
//CREATE ARRAYS
GIM_DYNARRAY_CREATE(GBUFFER_DATA,bm_data->m_buffer_array,G_ARRAY_GROW_SIZE);
GIM_DYNARRAY_CREATE(GUINT,bm_data->m_free_positions,G_ARRAY_GROW_SIZE);
//INIT PROTOTYPE
bm_data->m_prototype.alloc_data_fn = prototype->alloc_data_fn;
bm_data->m_prototype.alloc_fn = prototype->alloc_fn;
bm_data->m_prototype.copy_buffers_fn = prototype->copy_buffers_fn;
bm_data->m_prototype.download_from_buffer_fn = prototype->download_from_buffer_fn;
bm_data->m_prototype.free_fn = prototype->free_fn;
bm_data->m_prototype.lock_buffer_fn = prototype->lock_buffer_fn;
bm_data->m_prototype.realloc_fn = prototype->realloc_fn;
bm_data->m_prototype.unlock_buffer_fn = prototype->unlock_buffer_fn;
bm_data->m_prototype.upload_to_buffer_fn = prototype->upload_to_buffer_fn;
}
GUINT gim_get_buffer_manager_count()
{
return g_buffer_managers_count;
}
void gim_destroy_buffer_manager(GUINT buffer_manager_id)
{
GBUFFER_MANAGER_DATA * bm_data;
gim_get_buffer_manager_data(buffer_manager_id,&bm_data);
if(bm_data == 0) return;
//Destroy all buffers
GBUFFER_DATA * buffers = GIM_DYNARRAY_POINTER(GBUFFER_DATA,bm_data->m_buffer_array);
GUINT i, buffer_count = bm_data->m_buffer_array.m_size;
for (i=0;i<buffer_count ;i++ )
{
if(buffers[i].m_buffer_handle!=0) //Is active
{
// free handle
bm_data->m_prototype.free_fn(buffers[i].m_buffer_handle,buffers[i].m_size);
}
}
//destroy buffer array
GIM_DYNARRAY_DESTROY(bm_data->m_buffer_array);
//destroy free positions
GIM_DYNARRAY_DESTROY(bm_data->m_free_positions);
//Mark as innactive
bm_data->m_active = 0;
}
void gim_get_buffer_manager_data(GUINT buffer_manager_id,GBUFFER_MANAGER_DATA ** pbm_data)
{
GBUFFER_MANAGER_DATA * bm_data;
bm_data = &g_buffer_managers[buffer_manager_id];
if(bm_data->m_active==0)
{
*pbm_data = 0;
}
else
{
*pbm_data = bm_data;
}
}
void gim_init_buffer_managers()
{
GUINT i;
for (i=0;i<MAX_BUFFER_MANAGERS;i++)
{
g_buffer_managers[i].m_active = 0;
g_buffer_managers[i].m_buffer_array.m_pdata = 0;
g_buffer_managers[i].m_buffer_array.m_reserve_size = 0;
g_buffer_managers[i].m_buffer_array.m_size = 0;
g_buffer_managers[i].m_free_positions.m_pdata = 0;
g_buffer_managers[i].m_free_positions.m_reserve_size = 0;
g_buffer_managers[i].m_free_positions.m_size = 0;
}
g_buffer_managers_count = 0;
// Add the two most important buffer managers
GBUFFER_MANAGER_PROTOTYPE prototype;
//add system buffer manager
prototype.alloc_data_fn = _system_buffer_alloc_data_function;
prototype.alloc_fn = _system_buffer_alloc_function;
prototype.copy_buffers_fn = _system_copy_buffers_function;
prototype.download_from_buffer_fn = _system_download_from_buffer_function;
prototype.free_fn = _system_buffer_free_function;
prototype.lock_buffer_fn = _system_lock_buffer_function;
prototype.realloc_fn = _system_buffer_realloc_function;
prototype.unlock_buffer_fn = _system_unlock_buffer_function;
prototype.upload_to_buffer_fn = _system_upload_to_buffer_function;
gim_create_buffer_manager(&prototype,G_BUFFER_MANAGER_SYSTEM );
//add zhared buffer manager
prototype.alloc_data_fn = _shared_buffer_alloc_data_function;
prototype.alloc_fn = _shared_buffer_alloc_function;
prototype.free_fn = _shared_buffer_free_function;
gim_create_buffer_manager(&prototype,G_BUFFER_MANAGER_SHARED);
}
void gim_terminate_buffer_managers()
{
GUINT i;
for (i=0;i<g_buffer_managers_count;i++)
{
gim_destroy_buffer_manager(i);
}
g_buffer_managers_count = 0;
}
//!** Nuffer operations
void GET_AVALIABLE_BUFFER_ID(GBUFFER_MANAGER_DATA * buffer_manager, GUINT & buffer_id)
{
if(buffer_manager->m_free_positions.m_size>0)\
{
GUINT * _pointer = GIM_DYNARRAY_POINTER(GUINT,buffer_manager->m_free_positions);
buffer_id = _pointer[buffer_manager->m_free_positions.m_size-1];
GIM_DYNARRAY_POP_ITEM(buffer_manager->m_free_positions);
}
else
{
buffer_id = buffer_manager->m_buffer_array.m_size;
GIM_DYNARRAY_PUSH_EMPTY(GBUFFER_DATA,buffer_manager->m_buffer_array);
}
}
GINT _validate_buffer_id(GBUFFER_ID * buffer_id,GBUFFER_DATA ** ppbuffer,GBUFFER_MANAGER_DATA ** pbm_data)
{
VALIDATE_BUFFER_ID_PT(buffer_id)
*ppbuffer = pbuffer;
*pbm_data = bm_data;
return G_BUFFER_OP_SUCCESS;
}
GUINT gim_create_buffer(
GUINT buffer_manager_id,
GUINT buffer_size,
int usage,
GBUFFER_ID * buffer_id)
{
VALIDATE_BUFFER_MANAGER(buffer_manager_id)
GUINT newbufferhandle = bm_data->m_prototype.alloc_fn(buffer_size,usage);
if(newbufferhandle==0) return G_BUFFER_OP_INVALID;
GET_AVALIABLE_BUFFER_ID(bm_data,buffer_id->m_buffer_id);
buffer_id->m_buffer_manager_id = buffer_manager_id;
GBUFFER_DATA * pbuffer = GIM_DYNARRAY_POINTER(GBUFFER_DATA,bm_data->m_buffer_array);
pbuffer += buffer_id->m_buffer_id ;
pbuffer->m_buffer_handle = newbufferhandle;
pbuffer->m_size = buffer_size;
pbuffer->m_usage = usage;
pbuffer->m_lock_count = 0;
pbuffer->m_refcount = 0;
pbuffer->m_mapped_pointer = 0;
//set shadow buffer if needed
if(usage == G_MU_STATIC_READ ||
usage == G_MU_STATIC_READ_DYNAMIC_WRITE||
usage == G_MU_STATIC_READ_DYNAMIC_WRITE_COPY)
{
gim_create_common_buffer(buffer_size,&pbuffer->m_shadow_buffer);
}
else
{
pbuffer->m_shadow_buffer.m_buffer_id = G_UINT_INFINITY;
pbuffer->m_shadow_buffer.m_buffer_manager_id = G_UINT_INFINITY;
}
return G_BUFFER_OP_SUCCESS;
}
GUINT gim_create_buffer_from_data(
GUINT buffer_manager_id,
const void * pdata,
GUINT buffer_size,
int usage,
GBUFFER_ID * buffer_id)
{
VALIDATE_BUFFER_MANAGER(buffer_manager_id)
GUINT newbufferhandle = bm_data->m_prototype.alloc_data_fn(pdata,buffer_size,usage);
if(newbufferhandle==0) return G_BUFFER_OP_INVALID;
GET_AVALIABLE_BUFFER_ID(bm_data,buffer_id->m_buffer_id);
buffer_id->m_buffer_manager_id = buffer_manager_id;
GBUFFER_DATA * pbuffer = GIM_DYNARRAY_POINTER(GBUFFER_DATA,bm_data->m_buffer_array);
pbuffer += buffer_id->m_buffer_id ;
pbuffer->m_buffer_handle = newbufferhandle;
pbuffer->m_size = buffer_size;
pbuffer->m_usage = usage;
pbuffer->m_lock_count = 0;
pbuffer->m_mapped_pointer = 0;
pbuffer->m_refcount = 0;
//set shadow buffer if needed
if(usage == G_MU_STATIC_READ ||
usage == G_MU_STATIC_READ_DYNAMIC_WRITE||
usage == G_MU_STATIC_READ_DYNAMIC_WRITE_COPY)
{
gim_create_common_buffer_from_data(pdata,buffer_size,&pbuffer->m_shadow_buffer);
}
else
{
pbuffer->m_shadow_buffer.m_buffer_id = G_UINT_INFINITY;
pbuffer->m_shadow_buffer.m_buffer_manager_id = G_UINT_INFINITY;
}
return G_BUFFER_OP_SUCCESS;
}
GUINT gim_create_common_buffer(GUINT buffer_size, GBUFFER_ID * buffer_id)
{
return gim_create_buffer(G_BUFFER_MANAGER_SYSTEM,buffer_size,G_MU_DYNAMIC_READ_WRITE,buffer_id);
}
GUINT gim_create_common_buffer_from_data(
const void * pdata, GUINT buffer_size, GBUFFER_ID * buffer_id)
{
return gim_create_buffer_from_data(G_BUFFER_MANAGER_SYSTEM,pdata,buffer_size,G_MU_DYNAMIC_READ_WRITE,buffer_id);
}
GUINT gim_create_shared_buffer_from_data(
const void * pdata, GUINT buffer_size, GBUFFER_ID * buffer_id)
{
return gim_create_buffer_from_data(G_BUFFER_MANAGER_SHARED,pdata,buffer_size,G_MU_DYNAMIC_READ_WRITE,buffer_id);
}
GINT gim_buffer_realloc(GBUFFER_ID * buffer_id,GUINT newsize)
{
VALIDATE_BUFFER_ID_PT(buffer_id)
if(pbuffer->m_lock_count>0) return G_BUFFER_OP_INVALID;
GUINT newhandle = bm_data->m_prototype.realloc_fn(pbuffer->m_buffer_handle,pbuffer->m_size,pbuffer->m_usage,newsize,pbuffer->m_usage);
if(newhandle==0) return G_BUFFER_OP_INVALID;
pbuffer->m_buffer_handle = newhandle;
//realloc shadow buffer if any
gim_buffer_realloc(&pbuffer->m_shadow_buffer,newsize);
return G_BUFFER_OP_SUCCESS;
}
GINT gim_buffer_add_ref(GBUFFER_ID * buffer_id)
{
VALIDATE_BUFFER_ID_PT(buffer_id)
pbuffer->m_refcount++;
return G_BUFFER_OP_SUCCESS;
}
GINT gim_buffer_free(GBUFFER_ID * buffer_id)
{
VALIDATE_BUFFER_ID_PT(buffer_id)
if(pbuffer->m_lock_count>0) return G_BUFFER_OP_INVALID;
if(pbuffer->m_refcount>0) pbuffer->m_refcount--;
if(pbuffer->m_refcount>0) return G_BUFFER_OP_STILLREFCOUNTED;
bm_data->m_prototype.free_fn(pbuffer->m_buffer_handle,pbuffer->m_size);
//destroy shadow buffer if needed
gim_buffer_free(&pbuffer->m_shadow_buffer);
// Obtain a free slot index for a new buffer
GIM_DYNARRAY_PUSH_ITEM(GUINT,bm_data->m_free_positions,buffer_id->m_buffer_id);
pbuffer->m_buffer_handle = 0;
pbuffer->m_size = 0;
pbuffer->m_shadow_buffer.m_buffer_id = G_UINT_INFINITY;
pbuffer->m_shadow_buffer.m_buffer_manager_id = G_UINT_INFINITY;
return G_BUFFER_OP_SUCCESS;
}
GINT gim_lock_buffer(GBUFFER_ID * buffer_id,int access,char ** map_pointer)
{
VALIDATE_BUFFER_ID_PT(buffer_id)
if(pbuffer->m_lock_count>0)
{
if(pbuffer->m_access!=access) return G_BUFFER_OP_INVALID;
pbuffer->m_lock_count++;
*map_pointer = pbuffer->m_mapped_pointer;
return G_BUFFER_OP_SUCCESS;
}
pbuffer->m_access = access;
GUINT result;
if(pbuffer->m_usage==G_MU_STATIC_WRITE)
{
*map_pointer = 0;///no access
return G_BUFFER_OP_INVALID;
}
else if(pbuffer->m_usage==G_MU_STATIC_READ)
{
if(pbuffer->m_access == G_MA_READ_ONLY)
{
result = gim_lock_buffer(&pbuffer->m_shadow_buffer,access,map_pointer);
if(result!= G_BUFFER_OP_SUCCESS) return G_BUFFER_OP_INVALID;
pbuffer->m_mapped_pointer = *map_pointer;
pbuffer->m_lock_count++;
}
else
{
*map_pointer = 0;
return G_BUFFER_OP_INVALID;
}
}
else if(pbuffer->m_usage==G_MU_STATIC_READ_DYNAMIC_WRITE)
{
if(pbuffer->m_access == G_MA_READ_ONLY)
{
result = gim_lock_buffer(&pbuffer->m_shadow_buffer,access,map_pointer);
if(result!= G_BUFFER_OP_SUCCESS) return G_BUFFER_OP_INVALID;
pbuffer->m_mapped_pointer = *map_pointer;
pbuffer->m_lock_count++;
}
else if(pbuffer->m_access == G_MA_WRITE_ONLY)
{
pbuffer->m_mapped_pointer = bm_data->m_prototype.lock_buffer_fn(pbuffer->m_buffer_handle,access);
*map_pointer = pbuffer->m_mapped_pointer;
pbuffer->m_lock_count++;
}
else if(pbuffer->m_access == G_MA_READ_WRITE)
{
*map_pointer = 0;
return G_BUFFER_OP_INVALID;
}
}
else if(pbuffer->m_usage==G_MU_STATIC_READ_DYNAMIC_WRITE_COPY)
{
result = gim_lock_buffer(&pbuffer->m_shadow_buffer,access,map_pointer);
if(result!= G_BUFFER_OP_SUCCESS) return G_BUFFER_OP_INVALID;
pbuffer->m_mapped_pointer = *map_pointer;
pbuffer->m_lock_count++;
}
else if(pbuffer->m_usage==G_MU_STATIC_WRITE_DYNAMIC_READ)
{
if(pbuffer->m_access == G_MA_READ_ONLY)
{
pbuffer->m_mapped_pointer = bm_data->m_prototype.lock_buffer_fn(pbuffer->m_buffer_handle,access);
*map_pointer = pbuffer->m_mapped_pointer;
pbuffer->m_lock_count++;
}
else
{
*map_pointer = 0;
return G_BUFFER_OP_INVALID;
}
}
else if(pbuffer->m_usage==G_MU_DYNAMIC_READ_WRITE)
{
pbuffer->m_mapped_pointer = bm_data->m_prototype.lock_buffer_fn(pbuffer->m_buffer_handle,access);
*map_pointer = pbuffer->m_mapped_pointer;
pbuffer->m_lock_count++;
}
return G_BUFFER_OP_SUCCESS;
}
GINT gim_unlock_buffer(GBUFFER_ID * buffer_id)
{
VALIDATE_BUFFER_ID_PT(buffer_id)
if(pbuffer->m_lock_count==0) return G_BUFFER_OP_INVALID;
if(pbuffer->m_lock_count>1)
{
pbuffer->m_lock_count--;
return G_BUFFER_OP_SUCCESS;
}
GUINT result;
if(pbuffer->m_usage==G_MU_STATIC_WRITE)
{
pbuffer->m_mapped_pointer = 0;
pbuffer->m_lock_count=0;
return G_BUFFER_OP_INVALID;
}
else if(pbuffer->m_usage==G_MU_STATIC_READ)
{
if(pbuffer->m_access == G_MA_READ_ONLY)
{
result = gim_unlock_buffer(&pbuffer->m_shadow_buffer);
if(result!= G_BUFFER_OP_SUCCESS) return G_BUFFER_OP_INVALID;
pbuffer->m_mapped_pointer = 0;
pbuffer->m_lock_count=0;
}
else
{
pbuffer->m_mapped_pointer = 0;
pbuffer->m_lock_count=0;
return G_BUFFER_OP_INVALID;
}
}
else if(pbuffer->m_usage==G_MU_STATIC_READ_DYNAMIC_WRITE)
{
if(pbuffer->m_access == G_MA_READ_ONLY)
{
result = gim_unlock_buffer(&pbuffer->m_shadow_buffer);
if(result!= G_BUFFER_OP_SUCCESS) return G_BUFFER_OP_INVALID;
pbuffer->m_mapped_pointer = 0;
pbuffer->m_lock_count=0;
}
else if(pbuffer->m_access == G_MA_WRITE_ONLY)
{
bm_data->m_prototype.unlock_buffer_fn(pbuffer->m_buffer_handle);
pbuffer->m_mapped_pointer = 0;
pbuffer->m_lock_count=0;
}
else if(pbuffer->m_access == G_MA_READ_WRITE)
{
pbuffer->m_mapped_pointer = 0;
pbuffer->m_lock_count=0;
return G_BUFFER_OP_INVALID;
}
}
else if(pbuffer->m_usage==G_MU_STATIC_READ_DYNAMIC_WRITE_COPY)
{
result = gim_unlock_buffer(&pbuffer->m_shadow_buffer);
if(result!= G_BUFFER_OP_SUCCESS) return G_BUFFER_OP_INVALID;
pbuffer->m_mapped_pointer = 0;
pbuffer->m_lock_count=0;
if(pbuffer->m_access == G_MA_WRITE_ONLY||pbuffer->m_access == G_MA_READ_WRITE)
{
gim_copy_buffers(&pbuffer->m_shadow_buffer,0,buffer_id,0,pbuffer->m_size);
}
}
else if(pbuffer->m_usage==G_MU_STATIC_WRITE_DYNAMIC_READ)
{
if(pbuffer->m_access == G_MA_READ_ONLY)
{
bm_data->m_prototype.unlock_buffer_fn(pbuffer->m_buffer_handle);
pbuffer->m_mapped_pointer = 0;
pbuffer->m_lock_count=0;
}
else
{
pbuffer->m_mapped_pointer = 0;
pbuffer->m_lock_count=0;
return G_BUFFER_OP_INVALID;
}
}
else if(pbuffer->m_usage==G_MU_DYNAMIC_READ_WRITE)
{
bm_data->m_prototype.unlock_buffer_fn(pbuffer->m_buffer_handle);
pbuffer->m_mapped_pointer = 0;
pbuffer->m_lock_count=0;
}
return G_BUFFER_OP_SUCCESS;
}
GINT gim_get_buffer_size(GBUFFER_ID * buffer_id,GUINT * buffer_size)
{
VALIDATE_BUFFER_ID_PT(buffer_id)
*buffer_size = pbuffer->m_size;
return G_BUFFER_OP_SUCCESS;
}
GINT gim_get_buffer_is_locked(GBUFFER_ID * buffer_id,GUINT * lock_count)
{
VALIDATE_BUFFER_ID_PT(buffer_id)
*lock_count = pbuffer->m_lock_count;
return G_BUFFER_OP_SUCCESS;
}
GINT gim_download_from_buffer(
GBUFFER_ID * buffer_id,
GUINT source_pos,
void * destdata,
GUINT copysize)
{
VALIDATE_BUFFER_ID_PT(buffer_id)
bm_data->m_prototype.download_from_buffer_fn(
pbuffer->m_buffer_handle,source_pos,destdata,copysize);
return G_BUFFER_OP_SUCCESS;
}
GINT gim_upload_to_buffer(
GBUFFER_ID * buffer_id,
GUINT dest_pos,
void * sourcedata,
GUINT copysize)
{
VALIDATE_BUFFER_ID_PT(buffer_id)
bm_data->m_prototype.upload_to_buffer_fn(
pbuffer->m_buffer_handle,dest_pos,sourcedata,copysize);
return G_BUFFER_OP_SUCCESS;
}
GINT gim_copy_buffers(
GBUFFER_ID * source_buffer_id,
GUINT source_pos,
GBUFFER_ID * dest_buffer_id,
GUINT dest_pos,
GUINT copysize)
{
GBUFFER_MANAGER_DATA * bm_data1,* bm_data2;
GBUFFER_DATA * pbuffer1, * pbuffer2;
void * tempdata;
if(_validate_buffer_id(source_buffer_id,&pbuffer1,&bm_data1)!= G_BUFFER_OP_SUCCESS) return G_BUFFER_OP_INVALID;
if(_validate_buffer_id(dest_buffer_id,&pbuffer2,&bm_data2)!= G_BUFFER_OP_SUCCESS) return G_BUFFER_OP_INVALID;
if((source_buffer_id->m_buffer_manager_id == dest_buffer_id->m_buffer_manager_id)||
(source_buffer_id->m_buffer_manager_id == G_BUFFER_MANAGER_SYSTEM && dest_buffer_id->m_buffer_manager_id == G_BUFFER_MANAGER_SHARED)||
(source_buffer_id->m_buffer_manager_id == G_BUFFER_MANAGER_SHARED && dest_buffer_id->m_buffer_manager_id == G_BUFFER_MANAGER_SYSTEM)
)
{//smooth copy
bm_data1->m_prototype.copy_buffers_fn(pbuffer1->m_buffer_handle,source_pos,pbuffer2->m_buffer_handle,dest_pos,copysize);
}
else if(source_buffer_id->m_buffer_manager_id == G_BUFFER_MANAGER_SYSTEM || source_buffer_id->m_buffer_manager_id == G_BUFFER_MANAGER_SHARED)
{
//hard copy
tempdata = (void *)pbuffer1->m_buffer_handle;
//upload data
bm_data2->m_prototype.upload_to_buffer_fn(pbuffer2->m_buffer_handle,dest_pos,
tempdata,
copysize);
}
else
{
//very hard copy
void * tempdata = gim_alloc(copysize);
//download data
bm_data1->m_prototype.download_from_buffer_fn(pbuffer1->m_buffer_handle,source_pos,
tempdata,
copysize);
//upload data
bm_data2->m_prototype.upload_to_buffer_fn(pbuffer2->m_buffer_handle,dest_pos,
tempdata,
copysize);
//delete temp buffer
gim_free(tempdata,copysize);
}
return G_BUFFER_OP_SUCCESS;
}
GINT gim_buffer_array_lock(GBUFFER_ARRAY * array_data, int access)
{
if(array_data->m_buffer_data != 0) return G_BUFFER_OP_SUCCESS;
GINT result = gim_lock_buffer(&array_data->m_buffer_id,access,&array_data->m_buffer_data);
if(result!= G_BUFFER_OP_SUCCESS) return result;
array_data->m_buffer_data += array_data->m_byte_offset;
return result;
}
GINT gim_buffer_array_unlock(GBUFFER_ARRAY * array_data)
{
if(array_data->m_buffer_data == 0) return G_BUFFER_OP_SUCCESS;
GINT result = gim_unlock_buffer(&array_data->m_buffer_id);
if(result!= G_BUFFER_OP_SUCCESS) return result;
array_data->m_buffer_data = 0;
return result;
}
void gim_buffer_array_copy_ref(GBUFFER_ARRAY * source_data,GBUFFER_ARRAY * dest_data)
{
dest_data->m_buffer_id.m_buffer_id = source_data->m_buffer_id.m_buffer_id;
dest_data->m_buffer_id.m_buffer_manager_id = source_data->m_buffer_id.m_buffer_manager_id;
dest_data->m_buffer_data = 0;
dest_data->m_byte_stride = source_data->m_byte_stride;
dest_data->m_byte_offset = source_data->m_byte_offset;
dest_data->m_element_count = source_data->m_element_count;
gim_buffer_add_ref(&dest_data->m_buffer_id);
}
void gim_buffer_array_copy_value(GBUFFER_ARRAY * source_data,GBUFFER_ARRAY * dest_data, GUINT buffer_manager_id,int usage)
{
//Create new buffer
GUINT buffsize = source_data->m_element_count*source_data->m_byte_stride;
gim_create_buffer(buffer_manager_id,buffsize,usage,&dest_data->m_buffer_id);
//copy ref data
dest_data->m_buffer_data = 0;
dest_data->m_byte_stride = source_data->m_byte_stride;
dest_data->m_byte_offset = 0;
dest_data->m_element_count = source_data->m_element_count;
gim_buffer_add_ref(&dest_data->m_buffer_id);
//copy buffers
gim_copy_buffers(&source_data->m_buffer_id,source_data->m_byte_offset,&dest_data->m_buffer_id,0,buffsize);
}

View File

@ -1,329 +0,0 @@
/*
-----------------------------------------------------------------------------
This source file is part of GIMPACT Library.
For the latest info, see http://gimpact.sourceforge.net/
Copyright (c) 2006 Francisco Leon Najera. C.C. 80087371.
email: projectileman@yahoo.com
This library is free software; you can redistribute it and/or
modify it under the terms of EITHER:
(1) The GNU Lesser General Public License as published by the Free
Software Foundation; either version 2.1 of the License, or (at
your option) any later version. The text of the GNU Lesser
General Public License is included with this library in the
file GIMPACT-LICENSE-LGPL.TXT.
(2) The BSD-style license that is included with this library in
the file GIMPACT-LICENSE-BSD.TXT.
(3) The zlib/libpng license that is included with this library in
the file GIMPACT-LICENSE-ZLIB.TXT.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files
GIMPACT-LICENSE-LGPL.TXT, GIMPACT-LICENSE-ZLIB.TXT and GIMPACT-LICENSE-BSD.TXT for more details.
-----------------------------------------------------------------------------
*/
#include "GIMPACT/gim_trimesh.h"
#define FABS(x) (float(fabs(x))) /* implement as is fastest on your machine */
/* some macros */
#define CLASSIFY_TRIPOINTS_BY_FACE(v1,v2,v3,faceplane,out_of_face)\
{ \
_distances[0] = DISTANCE_PLANE_POINT(faceplane,v1);\
_distances[1] = _distances[0] * DISTANCE_PLANE_POINT(faceplane,v2);\
_distances[2] = _distances[0] * DISTANCE_PLANE_POINT(faceplane,v3); \
if(_distances[1]>0.0f && _distances[2]>0.0f)\
{\
out_of_face = 1;\
}\
else\
{\
out_of_face = 0;\
}\
}\
#define CLASSIFY_TRIPOINTS_BY_PLANE(v1,v2,v3,faceplane,out_of_face)\
{ \
_distances[0] = DISTANCE_PLANE_POINT(faceplane,v1);\
_distances[1] = DISTANCE_PLANE_POINT(faceplane,v2);\
_distances[2] = DISTANCE_PLANE_POINT(faceplane,v3); \
if(_distances[0]<=0.0f || _distances[1]<=0.0f || _distances[2]<=0.0f)\
{\
out_of_face = 0;\
}\
else\
{\
out_of_face = 1;\
}\
}\
/* sort so that a<=b */
#define SORT(a,b) \
if(a>b) \
{ \
float c; \
c=a; \
a=b; \
b=c; \
}
/* this edge to edge test is based on Franlin Antonio's gem:
"Faster Line Segment Intersection", in Graphics Gems III,
pp. 199-202 */
#define EDGE_EDGE_TEST(V0,U0,U1) \
Bx=U0[i0]-U1[i0]; \
By=U0[i1]-U1[i1]; \
Cx=V0[i0]-U0[i0]; \
Cy=V0[i1]-U0[i1]; \
f=Ay*Bx-Ax*By; \
d=By*Cx-Bx*Cy; \
if((f>0 && d>=0 && d<=f) || (f<0 && d<=0 && d>=f)) \
{ \
e=Ax*Cy-Ay*Cx; \
if(f>0) \
{ \
if(e>=0 && e<=f) return 1; \
} \
else \
{ \
if(e<=0 && e>=f) return 1; \
} \
}
#define EDGE_AGAINST_TRI_EDGES(V0,V1,U0,U1,U2) \
{ \
float Ax,Ay,Bx,By,Cx,Cy,e,d,f; \
Ax=V1[i0]-V0[i0]; \
Ay=V1[i1]-V0[i1]; \
/* test edge U0,U1 against V0,V1 */ \
EDGE_EDGE_TEST(V0,U0,U1); \
/* test edge U1,U2 against V0,V1 */ \
EDGE_EDGE_TEST(V0,U1,U2); \
/* test edge U2,U1 against V0,V1 */ \
EDGE_EDGE_TEST(V0,U2,U0); \
}
#define POINT_IN_TRI(V0,U0,U1,U2) \
{ \
float a,b,c,d0,d1,d2; \
/* is T1 completly inside T2? */ \
/* check if V0 is inside tri(U0,U1,U2) */ \
a=U1[i1]-U0[i1]; \
b=-(U1[i0]-U0[i0]); \
c=-a*U0[i0]-b*U0[i1]; \
d0=a*V0[i0]+b*V0[i1]+c; \
\
a=U2[i1]-U1[i1]; \
b=-(U2[i0]-U1[i0]); \
c=-a*U1[i0]-b*U1[i1]; \
d1=a*V0[i0]+b*V0[i1]+c; \
\
a=U0[i1]-U2[i1]; \
b=-(U0[i0]-U2[i0]); \
c=-a*U2[i0]-b*U2[i1]; \
d2=a*V0[i0]+b*V0[i1]+c; \
if(d0*d1>0.0) \
{ \
if(d0*d2>0.0) return 1; \
} \
}
int coplanar_tri_tri(GIM_TRIANGLE_DATA *tri1,
GIM_TRIANGLE_DATA *tri2)
{
short i0,i1;
/* first project onto an axis-aligned plane, that maximizes the area */
/* of the triangles, compute indices: i0,i1. */
PLANE_MINOR_AXES(tri1->m_planes.m_planes[0], i0, i1);
/* test all edges of triangle 1 against the edges of triangle 2 */
EDGE_AGAINST_TRI_EDGES(tri1->m_vertices[0],tri1->m_vertices[1],tri2->m_vertices[0],tri2->m_vertices[1],tri2->m_vertices[2]);
EDGE_AGAINST_TRI_EDGES(tri1->m_vertices[1],tri1->m_vertices[2],tri2->m_vertices[0],tri2->m_vertices[1],tri2->m_vertices[2]);
EDGE_AGAINST_TRI_EDGES(tri1->m_vertices[2],tri1->m_vertices[0],tri2->m_vertices[0],tri2->m_vertices[1],tri2->m_vertices[2]);
/* finally, test if tri1 is totally contained in tri2 or vice versa */
/*POINT_IN_HULL(tri1->m_vertices[0],(&tri2->m_planes.m_planes[1]),3,i0);
if(i0==0) return 1;
POINT_IN_HULL(tri2->m_vertices[0],(&tri1->m_planes.m_planes[1]),3,i0);
if(i0==0) return 1;*/
POINT_IN_TRI(tri1->m_vertices[0],tri2->m_vertices[0],tri2->m_vertices[1],tri2->m_vertices[2])
POINT_IN_TRI(tri2->m_vertices[0],tri1->m_vertices[0],tri1->m_vertices[1],tri1->m_vertices[2])
return 0;
}
#define NEWCOMPUTE_INTERVALS(VV0,VV1,VV2,D0,D1,D2,D0D1,D0D2,A,B,C,X0,X1) \
{ \
if(D0D1>0.0f) \
{ \
/* here we know that D0D2<=0.0 */ \
/* that is D0, D1 are on the same side, D2 on the other or on the plane */ \
A=VV2; B=(VV0-VV2)*D2; C=(VV1-VV2)*D2; X0=D2-D0; X1=D2-D1; \
} \
else if(D0D2>0.0f)\
{ \
/* here we know that d0d1<=0.0 */ \
A=VV1; B=(VV0-VV1)*D1; C=(VV2-VV1)*D1; X0=D1-D0; X1=D1-D2; \
} \
else if(D1*D2>0.0f || D0!=0.0f) \
{ \
/* here we know that d0d1<=0.0 or that D0!=0.0 */ \
A=VV0; B=(VV1-VV0)*D0; C=(VV2-VV0)*D0; X0=D0-D1; X1=D0-D2; \
} \
else if(D1!=0.0f) \
{ \
A=VV1; B=(VV0-VV1)*D1; C=(VV2-VV1)*D1; X0=D1-D0; X1=D1-D2; \
} \
else if(D2!=0.0f) \
{ \
A=VV2; B=(VV0-VV2)*D2; C=(VV1-VV2)*D2; X0=D2-D0; X1=D2-D1; \
} \
else \
{ \
/* triangles are coplanar */ \
return coplanar_tri_tri(tri1,tri2); \
} \
}\
int gim_triangle_triangle_overlap_fast(
GIM_TRIANGLE_DATA *tri1,
GIM_TRIANGLE_DATA *tri2)
{
vec3f _distances;
char out_of_face;
CLASSIFY_TRIPOINTS_BY_FACE(tri1->m_vertices[0],tri1->m_vertices[1],tri1->m_vertices[2],tri2->m_planes.m_planes[0],out_of_face);
if(out_of_face==1) return 0;
CLASSIFY_TRIPOINTS_BY_PLANE(tri2->m_vertices[0],tri2->m_vertices[1],
tri2->m_vertices[2],tri1->m_planes.m_planes[0],out_of_face);
if(out_of_face==1) return 0;
/*vec3f _points[3];
VEC_COPY(_points[0],tri2->m_vertices[0]);
VEC_COPY(_points[1],tri2->m_vertices[1]);
VEC_COPY(_points[2],tri2->m_vertices[2]);
CLASSIFY_TRIPOINTS_BY_FACE(_points[0],_points[1],_points[2],tri1->m_planes.m_planes[0],out_of_face);
if(out_of_face==1) return 0;
CLASSIFY_TRIPOINTS_BY_PLANE(_points[0],_points[1],_points[2],tri1->m_planes.m_planes[1],out_of_face);
if(out_of_face==1) return 0;
CLASSIFY_TRIPOINTS_BY_PLANE(_points[0],_points[1],_points[2],tri1->m_planes.m_planes[2],out_of_face);
if(out_of_face==1) return 0;
CLASSIFY_TRIPOINTS_BY_PLANE(_points[0],_points[1],_points[2],tri1->m_planes.m_planes[3],out_of_face);
if(out_of_face==1) return 0;
return 1;*/
short i0,i1;
/* first project onto an axis-aligned plane, that maximizes the area */
/* of the triangles, compute indices: i0,i1. */
PLANE_MINOR_AXES(tri2->m_planes.m_planes[0], i0, i1);
/* test all edges of triangle 1 against the edges of triangle 2 */
EDGE_AGAINST_TRI_EDGES(tri1->m_vertices[0],tri1->m_vertices[1],tri2->m_vertices[0],tri2->m_vertices[1],tri2->m_vertices[2]);
EDGE_AGAINST_TRI_EDGES(tri1->m_vertices[1],tri1->m_vertices[2],tri2->m_vertices[0],tri2->m_vertices[1],tri2->m_vertices[2]);
EDGE_AGAINST_TRI_EDGES(tri1->m_vertices[2],tri1->m_vertices[0],tri2->m_vertices[0],tri2->m_vertices[1],tri2->m_vertices[2]);
/* finally, test if tri1 is totally contained in tri2 or vice versa */
/*POINT_IN_HULL(tri1->m_vertices[0],(&tri2->m_planes.m_planes[1]),3,i0);
if(i0==0) return 1;
POINT_IN_HULL(tri2->m_vertices[0],(&tri1->m_planes.m_planes[1]),3,i0);
if(i0==0) return 1;*/
POINT_IN_TRI(tri1->m_vertices[0],tri2->m_vertices[0],tri2->m_vertices[1],tri2->m_vertices[2])
POINT_IN_TRI(tri2->m_vertices[0],tri1->m_vertices[0],tri1->m_vertices[1],tri1->m_vertices[2])
return 0;
}
int gim_triangle_triangle_overlap(
GIM_TRIANGLE_DATA *tri1,
GIM_TRIANGLE_DATA *tri2)
{
vec3f _distances;
char out_of_face;
CLASSIFY_TRIPOINTS_BY_FACE(tri1->m_vertices[0],tri1->m_vertices[1],tri1->m_vertices[2],tri2->m_planes.m_planes[0],out_of_face);
if(out_of_face==1) return 0;
CLASSIFY_TRIPOINTS_BY_FACE(tri2->m_vertices[0],tri2->m_vertices[1],tri2->m_vertices[2],tri1->m_planes.m_planes[0],out_of_face);
if(out_of_face==1) return 0;
float du0=0,du1=0,du2=0,dv0=0,dv1=0,dv2=0;
float D[3];
float isect1[2], isect2[2];
float du0du1=0,du0du2=0,dv0dv1=0,dv0dv2=0;
short index;
float vp0,vp1,vp2;
float up0,up1,up2;
float bb,cc,max;
/* compute direction of intersection line */
VEC_CROSS(D,tri1->m_planes.m_planes[0],tri2->m_planes.m_planes[0]);
/* compute and index to the largest component of D */
max=(float)FABS(D[0]);
index=0;
bb=(float)FABS(D[1]);
cc=(float)FABS(D[2]);
if(bb>max) max=bb,index=1;
if(cc>max) max=cc,index=2;
/* this is the simplified projection onto L*/
vp0= tri1->m_vertices[0][index];
vp1= tri1->m_vertices[1][index];
vp2= tri1->m_vertices[2][index];
up0= tri2->m_vertices[0][index];
up1= tri2->m_vertices[1][index];
up2= tri2->m_vertices[2][index];
/* compute interval for triangle 1 */
float a,b,c,x0,x1;
NEWCOMPUTE_INTERVALS(vp0,vp1,vp2,dv0,dv1,dv2,dv0dv1,dv0dv2,a,b,c,x0,x1);
/* compute interval for triangle 2 */
float d,e,f,y0,y1;
NEWCOMPUTE_INTERVALS(up0,up1,up2,du0,du1,du2,du0du1,du0du2,d,e,f,y0,y1);
float xx,yy,xxyy,tmp;
xx=x0*x1;
yy=y0*y1;
xxyy=xx*yy;
tmp=a*xxyy;
isect1[0]=tmp+b*x1*yy;
isect1[1]=tmp+c*x0*yy;
tmp=d*xxyy;
isect2[0]=tmp+e*xx*y1;
isect2[1]=tmp+f*xx*y0;
SORT(isect1[0],isect1[1]);
SORT(isect2[0],isect2[1]);
if(isect1[1]<isect2[0] || isect2[1]<isect1[0]) return 0;
return 1;
}

View File

@ -1,707 +0,0 @@
/*
-----------------------------------------------------------------------------
This source file is part of GIMPACT Library.
For the latest info, see http://gimpact.sourceforge.net/
Copyright (c) 2006 Francisco Leon Najera. C.C. 80087371.
email: projectileman@yahoo.com
This library is free software; you can redistribute it and/or
modify it under the terms of EITHER:
(1) The GNU Lesser General Public License as published by the Free
Software Foundation; either version 2.1 of the License, or (at
your option) any later version. The text of the GNU Lesser
General Public License is included with this library in the
file GIMPACT-LICENSE-LGPL.TXT.
(2) The BSD-style license that is included with this library in
the file GIMPACT-LICENSE-BSD.TXT.
(3) The zlib/libpng license that is included with this library in
the file GIMPACT-LICENSE-ZLIB.TXT.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files
GIMPACT-LICENSE-LGPL.TXT, GIMPACT-LICENSE-ZLIB.TXT and GIMPACT-LICENSE-BSD.TXT for more details.
-----------------------------------------------------------------------------
*/
#include "GIMPACT/gim_trimesh.h"
#include "assert.h"
GUINT gim_trimesh_get_triangle_count(GIM_TRIMESH * trimesh)
{
return gim_trimesh_data_get_triangle_count(trimesh->m_trimesh_data_handle);
}
GUINT gim_trimesh_get_vertex_count(GIM_TRIMESH * trimesh)
{
return gim_trimesh_data_get_vertex_count(trimesh->m_trimesh_data_handle);
}
GUINT gim_trimesh_get_bound_method(GIM_TRIMESH * trimesh)
{
if(gim_trimesh_data_has_bv_tree(trimesh->m_trimesh_data_handle) != 0) return G_TRIMESH_BOUND_AABB_TREE;
else if(trimesh->m_aabbset != 0) return G_TRIMESH_BOUND_AABB_SET;
return G_TRIMESH_BOUND_NONE;
}
#define LAZY_TRANSFORM_VERTEX(bitset,vec_index,transform,source_trimesh_data,dest_vert,temp_vert)\
{\
GUINT bit_eval;\
if(GIM_DYNARRAY_IS_VALID(bitset))\
{\
GIM_BITSET_GET(bitset,vec_index,bit_eval);\
if(bit_eval == 0)\
{\
gim_trimesh_data_get_vertex(source_trimesh_data,vec_index,vec);\
MAT_DOT_VEC_3X4(dest_vert,transform,temp_vert);\
}\
}\
}\
//! Fetch a single transformed vertex
/*!
\pre gim_trimesh_locks_work_data must be called before
*/
void gim_trimesh_get_vertex(GIM_TRIMESH * trimesh, GUINT vertex_index, vec3f vec)
{
if(trimesh->m_cache)
{
if(GIM_BUFFER_ARRAY_IS_VALID(trimesh->m_cache->m_transformed_vertex_buffer))
{
GREAL * transvecf = GIM_BUFFER_ARRAY_POINTER(GREAL,trimesh->m_cache->m_transformed_vertex_buffer,vertex_index);
LAZY_TRANSFORM_VERTEX(trimesh->m_cache->m_transformed_vertices_cache_bitset,vertex_index,trimesh->m_transform,trimesh->m_unlocked_trimesh_data,transvecf,vec);
VEC_COPY(vec,transvecf);
return;
}
}
if(gim_trimesh_has_tranform(trimesh))
{
vec3f vectemp;
gim_trimesh_data_get_vertex(trimesh->m_unlocked_trimesh_data,vertex_index,vectemp);
MAT_DOT_VEC_3X4(vec,trimesh->m_transform,vectemp);
return;
}
gim_trimesh_data_get_vertex(trimesh->m_unlocked_trimesh_data,vertex_index,vec);
}
void gim_trimesh_get_triangle_vertices_local(GIM_TRIMESH * trimesh, GUINT triangle_index,
vec3f v1,vec3f v2,vec3f v3)
{
vec3ui triangle_indices;
gim_trimesh_data_get_triangle_indices(
trimesh->m_unlocked_trimesh_data,triangle_index,triangle_indices);
gim_trimesh_data_get_vertex(trimesh->m_unlocked_trimesh_data,triangle_indices[0],v1);
gim_trimesh_data_get_vertex(trimesh->m_unlocked_trimesh_data,triangle_indices[1],v2);
gim_trimesh_data_get_vertex(trimesh->m_unlocked_trimesh_data,triangle_indices[2],v3);
}
void gim_trimesh_get_vertex_local(GIM_TRIMESH * trimesh, GUINT vertex_index, vec3f vec)
{
gim_trimesh_data_get_vertex(trimesh->m_unlocked_trimesh_data,vertex_index,vec);
}
void gim_trimesh_get_triangle_vertices(GIM_TRIMESH * trimesh, GUINT triangle_index, vec3f v1,vec3f v2,vec3f v3)
{
if(gim_trimesh_has_tranform(trimesh)==0)
{
gim_trimesh_get_triangle_vertices_local(trimesh,triangle_index,v1,v2,v3);
return;
}
vec3ui triangle_indices;
gim_trimesh_data_get_triangle_indices(
trimesh->m_unlocked_trimesh_data,triangle_index,triangle_indices);
if(trimesh->m_aabbset)
{
vec3f * vertices = GIM_BUFFER_ARRAY_POINTER(vec3f,trimesh->m_cache->m_transformed_vertex_buffer,0);
VEC_COPY(v1,vertices[triangle_indices[0]]);
VEC_COPY(v2,vertices[triangle_indices[1]]);
VEC_COPY(v3,vertices[triangle_indices[2]]);
return;
}
gim_trimesh_get_vertex(trimesh, triangle_indices[0], v1);
gim_trimesh_get_vertex(trimesh, triangle_indices[1], v2);
gim_trimesh_get_vertex(trimesh, triangle_indices[2], v3);
}
void gim_trimesh_initialize_cache(GIM_TRIMESH * trimesh)
{
trimesh->m_cache = (GIM_TRIMESH_CACHE *)gim_alloc(sizeof(GIM_TRIMESH_CACHE));
//Initializes the transformed vertices
if(gim_trimesh_has_tranform(trimesh))
{
gim_trimesh_data_get(trimesh->m_trimesh_data_handle,&trimesh->m_unlocked_trimesh_data );
//Create vertex buffer
gim_create_common_vertex_buffer(&trimesh->m_cache->m_transformed_vertex_buffer,
trimesh->m_unlocked_trimesh_data->m_source_vertex_buffer.m_element_count);
//Copy the vertex buffer
gim_copy_vertex_buffers(&trimesh->m_unlocked_trimesh_data->m_source_vertex_buffer,
trimesh->m_unlocked_trimesh_data->m_vertex_scalar_type,
&trimesh->m_cache->m_transformed_vertex_buffer,G_STYPE_REAL);
trimesh->m_cache->m_tranformed_scalar_type = G_STYPE_REAL;
trimesh->m_unlocked_trimesh_data = 0;
//Create vertices bitset
if(gim_trimesh_get_bound_method(trimesh)==G_TRIMESH_BOUND_AABB_TREE)
{
//Create the bitset
GIM_BITSET_CREATE_SIZED(trimesh->m_cache->m_transformed_vertices_cache_bitset,
trimesh->m_cache->m_transformed_vertex_buffer.m_element_count);
}
else
{
GIM_DYNARRAY_INVALIDATE(trimesh->m_cache->m_transformed_vertices_cache_bitset);
}
}
else
{
GIM_BUFFER_ARRAY_INVALIDATE(trimesh->m_cache->m_transformed_vertex_buffer);
GIM_DYNARRAY_INVALIDATE(trimesh->m_cache->m_transformed_vertices_cache_bitset);
}
GUINT facecount = gim_trimesh_get_triangle_count(trimesh);
//create the planes cache
GIM_DYNARRAY_CREATE_SIZED(GIM_TRIPLANES_CACHE,trimesh->m_cache->m_planes_cache_buffer,facecount);
//Create the bitset
GIM_BITSET_CREATE_SIZED(trimesh->m_cache->m_planes_cache_bitset,facecount);
}
void gim_trimesh_destroy_cache(GIM_TRIMESH * trimesh)
{
if(trimesh->m_cache==0) return;
if(trimesh->m_unlocked_trimesh_data != 0)
{
gim_trimesh_unlocks_work_data(trimesh);
}
GIM_DYNARRAY_DESTROY(trimesh->m_cache->m_planes_cache_buffer);
GIM_DYNARRAY_DESTROY(trimesh->m_cache->m_planes_cache_bitset);
if(GIM_BUFFER_ARRAY_IS_VALID(trimesh->m_cache->m_transformed_vertex_buffer))
{
GIM_BUFFER_ARRAY_DESTROY(trimesh->m_cache->m_transformed_vertex_buffer);
if(GIM_DYNARRAY_IS_VALID(trimesh->m_cache->m_transformed_vertices_cache_bitset))
{
GIM_DYNARRAY_DESTROY(trimesh->m_cache->m_transformed_vertices_cache_bitset);
}
}
gim_free(trimesh->m_cache,0);
trimesh->m_cache = 0;
}
void gim_trimesh_initialize_bound(GIM_TRIMESH * trimesh)
{
if(gim_trimesh_get_bound_method(trimesh)==G_TRIMESH_BOUND_NONE)
{
GUINT facecount = gim_trimesh_get_triangle_count(trimesh);
trimesh->m_aabbset = (GIM_AABB_SET *)gim_alloc(sizeof(GIM_AABB_SET));
gim_aabbset_alloc(trimesh->m_aabbset,facecount);
}
}
void gim_trimesh_destroy_bound(GIM_TRIMESH * trimesh)
{
if(trimesh->m_aabbset != 0)
{
gim_aabbset_destroy(trimesh->m_aabbset);
gim_free(trimesh->m_aabbset,0);
}
trimesh->m_aabbset = 0;
}
void gim_trimesh_create(GIM_TRIMESH * trimesh, GUINT trimesh_data_handle,
char apply_transform,char create_cache)
{
trimesh->m_mask = GIM_TRIMESH_NEED_UPDATE;//needs update
trimesh->m_trimesh_data_handle = trimesh_data_handle;
trimesh->m_unlocked_trimesh_data = 0;
gim_trimesh_data_inc_ref(trimesh->m_trimesh_data_handle);
trimesh->m_aabbset = 0;
trimesh->m_cache = 0;
if(apply_transform==1) trimesh->m_mask |= GIM_TRIMESH_APPLY_TRANSFORMATION;
gim_trimesh_initialize_bound(trimesh);
if(create_cache == 1 || gim_trimesh_get_bound_method(trimesh)==G_TRIMESH_BOUND_AABB_SET )
{
gim_trimesh_initialize_cache(trimesh);
}
//Callback is 0
trimesh->m_update_callback = 0;
//set to identity
IDENTIFY_MATRIX_4X4(trimesh->m_transform);
IDENTIFY_MATRIX_4X4(trimesh->m_inv_transform);
}
void gim_trimesh_create_from_arrays(GIM_TRIMESH * trimesh, GBUFFER_ARRAY * vertex_array,GUINT vertex_scalar_type, GBUFFER_ARRAY * triindex_array,GUINT index_scalar_type,
char apply_transform,char create_cache)
{
//Create mesh data
gim_trimesh_data_create_from_arrays(
&trimesh->m_trimesh_data_handle,vertex_array,vertex_scalar_type,triindex_array,index_scalar_type);
//Create
gim_trimesh_create(trimesh,trimesh->m_trimesh_data_handle,apply_transform,create_cache);
}
//! Create a trimesh from vertex array and an index array
/*!
\param trimesh An uninitialized GIM_TRIMESH structure
\param vertex_array A buffer to a vec3f array
\param vertex_count
\param triindex_array
\param index_count
\param copy_vertices If 1, it copies the source vertices in another buffer. Else (0) it constructs a reference to the data.
\param copy_indices If 1, it copies the source vertices in another buffer. Else (0) it constructs a reference to the data.
\param transformed_reply If , then the m_transformed_vertices is a reply of the source vertices. Else it just be a reference to the original array.
*/
void gim_trimesh_create_from_data(GIM_TRIMESH * trimesh, vec3f * vertex_array, GUINT vertex_count,char copy_vertices, GUINT * triindex_array, GUINT triangle_count,char copy_indices,
char apply_transform,char create_cache)
{
//Create mesh data
gim_trimesh_data_create_from_array_data(
&trimesh->m_trimesh_data_handle,vertex_array,vertex_count,copy_vertices,
triindex_array, triangle_count,copy_indices);
//Create
gim_trimesh_create(trimesh,trimesh->m_trimesh_data_handle,
apply_transform,create_cache);
}
//! Clears auxiliary data and releases buffer arrays
void gim_trimesh_destroy(GIM_TRIMESH * trimesh)
{
gim_trimesh_destroy_cache(trimesh);
gim_trimesh_destroy_bound(trimesh);
//Release trimesh data
gim_trimesh_data_dec_ref(trimesh->m_trimesh_data_handle);
trimesh->m_trimesh_data_handle = 0;
}
//! Copies two meshes
/*!
\pre dest_trimesh shouldn't be created
\post dest_trimesh will be created
\param source_trimesh
\param dest_trimesh
\param copy_by_reference If 1, it attach a reference to the source vertices, else it copies the vertices
\param transformed_reply IF 1, then it forces the m_trasnformed_vertices to be a reply of the source vertices
*/
void gim_trimesh_copy(GIM_TRIMESH * source_trimesh,GIM_TRIMESH * dest_trimesh, char copy_by_reference,
char apply_transform,char create_cache)
{
if(copy_by_reference==1)
{
gim_trimesh_create(dest_trimesh,source_trimesh->m_trimesh_data_handle,
apply_transform,create_cache);
}
else
{
gim_trimesh_data_create_copy(source_trimesh->m_trimesh_data_handle,&dest_trimesh->m_trimesh_data_handle,0);
gim_trimesh_create(dest_trimesh,dest_trimesh->m_trimesh_data_handle,
apply_transform,create_cache);
}
}
void gim_trimesh_locks_work_data(GIM_TRIMESH * trimesh)
{
gim_trimesh_data_lock(trimesh->m_trimesh_data_handle,G_MA_READ_ONLY,&trimesh->m_unlocked_trimesh_data);
if(trimesh->m_cache)
{
if(GIM_BUFFER_ARRAY_IS_VALID(trimesh->m_cache->m_transformed_vertex_buffer))
{
gim_buffer_array_lock(&trimesh->m_cache->m_transformed_vertex_buffer,G_MA_READ_ONLY);
}
}
}
//! unlocks the trimesh
/*!
\post unlocks m_tri_index_buffer and m_transformed_vertex_buffer.
\param trimesh
*/
void gim_trimesh_unlocks_work_data(GIM_TRIMESH * trimesh)
{
trimesh->m_unlocked_trimesh_data = 0;
gim_trimesh_data_unlock(trimesh->m_trimesh_data_handle);
if(trimesh->m_cache)
{
if(GIM_BUFFER_ARRAY_IS_VALID(trimesh->m_cache->m_transformed_vertex_buffer))
{
gim_buffer_array_unlock(&trimesh->m_cache->m_transformed_vertex_buffer);
}
}
}
//! Returns 1 if the m_transformed_vertex_buffer is a reply of m_source_vertex_buffer
char gim_trimesh_has_tranform(GIM_TRIMESH * trimesh)
{
if(trimesh->m_mask&GIM_TRIMESH_APPLY_TRANSFORMATION) return 1;
return 0;
}
//! Returns 1 if the trimesh needs to update their aabbset and the planes cache.
char gim_trimesh_needs_update(GIM_TRIMESH * trimesh)
{
if(trimesh->m_mask&GIM_TRIMESH_NEED_UPDATE) return 1;
return 0;
}
//! Change the state of the trimesh for force it to update
/*!
Call it after made changes to the trimesh.
\post gim_trimesh_need_update(trimesh) will return 1
*/
void gim_trimesh_post_update(GIM_TRIMESH * trimesh)
{
trimesh->m_mask |= GIM_TRIMESH_NEED_UPDATE;
}
//! Updates m_transformed_vertex_buffer
/*!
\pre m_transformed_vertex_buffer must be unlocked
*/
void gim_trimesh_update_vertices(GIM_TRIMESH * trimesh)
{
if(trimesh->m_cache == 0) return;
if(gim_trimesh_has_tranform(trimesh) == 0) return; //Don't perform transformation
if(GIM_DYNARRAY_IS_VALID( trimesh->m_cache->m_transformed_vertices_cache_bitset))
{
GIM_BITSET_CLEAR_ALL(trimesh->m_cache->m_transformed_vertices_cache_bitset);
return;
}
//transform vertices
mat4f transform;
COPY_MATRIX_4X4(transform,trimesh->m_transform);
gim_trimesh_data_get(trimesh->m_trimesh_data_handle,&trimesh->m_unlocked_trimesh_data );
gim_transform_vertex_buffers(
&trimesh->m_unlocked_trimesh_data->m_source_vertex_buffer,
trimesh->m_unlocked_trimesh_data->m_vertex_scalar_type,
&trimesh->m_cache->m_transformed_vertex_buffer,trimesh->m_cache->m_tranformed_scalar_type,transform);
trimesh->m_unlocked_trimesh_data = 0;
}
void gim_trimesh_update_cache(GIM_TRIMESH * trimesh)
{
if(trimesh->m_cache == 0) return;
//Clear planes cache
GIM_BITSET_CLEAR_ALL(trimesh->m_cache->m_planes_cache_bitset);
gim_trimesh_update_vertices(trimesh);
}
//! Updates m_aabbset and m_planes_cache_bitset
/*!
\pre gim_trimesh_locks_work_data must be called before
*/
void gim_trimesh_update_aabbset(GIM_TRIMESH * trimesh)
{
if(trimesh->m_aabbset == 0) return;
assert(trimesh->m_cache);
assert(GIM_BUFFER_ARRAY_IS_VALID(trimesh->m_cache->m_transformed_vertex_buffer));
vec3f * vertices = GIM_BUFFER_ARRAY_POINTER(vec3f,trimesh->m_cache->m_transformed_vertex_buffer,0);
// box set
aabb3f * paabb = trimesh->m_aabbset->m_boxes;
GUINT triangle_count = gim_trimesh_get_triangle_count(trimesh);
vec3ui triangle_indices;
GUINT i;
for (i=0; i<triangle_count;i++)
{
gim_trimesh_data_get_triangle_indices(
trimesh->m_unlocked_trimesh_data,i,triangle_indices);
COMPUTEAABB_FOR_TRIANGLE((*paabb),
vertices[triangle_indices[0]],
vertices[triangle_indices[1]],vertices[triangle_indices[2]]);
paabb++;
}
//Sorts set
gim_aabbset_update(trimesh->m_aabbset);
}
//! Updates the trimesh if needed
/*!
\post If gim_trimesh_needs_update returns 1, then it calls gim_trimesh_update_vertices and gim_trimesh_update_aabbset
*/
void gim_trimesh_update(GIM_TRIMESH * trimesh)
{
if(gim_trimesh_needs_update(trimesh)==0) return;
gim_trimesh_update_cache(trimesh);
if(trimesh->m_aabbset!=0)
{
gim_trimesh_locks_work_data(trimesh);
gim_trimesh_update_aabbset(trimesh);
gim_trimesh_unlocks_work_data(trimesh);
}
//Clear update flag
trimesh->m_mask &= ~GIM_TRIMESH_NEED_UPDATE;
}
void gim_trimesh_set_tranform(GIM_TRIMESH * trimesh, mat4f transform)
{
GREAL diff = 0.0f;
float * originaltrans = &trimesh->m_transform[0][0];
float * newtrans = &transform[0][0];
GUINT i;
for (i=0;i<16;i++)
{
diff += fabs(originaltrans[i]-newtrans[i]);
}
if(GIM_IS_ZERO(diff)) return ;///don't need to update
//if(diff< 0.0006f) return ;///don't need to update
COPY_MATRIX_4X4(trimesh->m_transform,transform);
GREAL det;
INVERT_4X4(trimesh->m_inv_transform,det,transform);
gim_trimesh_post_update(trimesh);
}
void gim_trimesh_get_triangle_data(GIM_TRIMESH * trimesh, GUINT triangle_index, GIM_TRIANGLE_DATA * tri_data)
{
gim_trimesh_get_triangle_vertices(trimesh,triangle_index,
tri_data->m_vertices[0],
tri_data->m_vertices[1],
tri_data->m_vertices[2]);
if(trimesh->m_cache)
{
//Get the planes
GIM_TRIPLANES_CACHE * planes = GIM_DYNARRAY_POINTER(GIM_TRIPLANES_CACHE,trimesh->m_cache->m_planes_cache_buffer);
planes += triangle_index;
//verify planes cache
char bit_eval;
GIM_BITSET_GET(trimesh->m_cache->m_planes_cache_bitset,triangle_index,bit_eval);
if(bit_eval == 0)// Needs to calc the planes
{
//Calc the face plane
TRIANGLE_PLANE(tri_data->m_vertices[0],tri_data->m_vertices[1],tri_data->m_vertices[2],planes->m_planes[0]);
//Calc the edge 1
EDGE_PLANE(tri_data->m_vertices[0],tri_data->m_vertices[1],(planes->m_planes[0]),(planes->m_planes[1]));
//Calc the edge 2
EDGE_PLANE(tri_data->m_vertices[1],tri_data->m_vertices[2],(planes->m_planes[0]),(planes->m_planes[2]));
//Calc the edge 3
EDGE_PLANE(tri_data->m_vertices[2],tri_data->m_vertices[0],(planes->m_planes[0]), (planes->m_planes[3]));
//mark
GIM_BITSET_SET(trimesh->m_cache->m_planes_cache_bitset,triangle_index);
}
VEC_COPY_4((tri_data->m_planes.m_planes[0]),(planes->m_planes[0]));//face plane
VEC_COPY_4((tri_data->m_planes.m_planes[1]),(planes->m_planes[1]));//edge1
VEC_COPY_4((tri_data->m_planes.m_planes[2]),(planes->m_planes[2]));//edge2
VEC_COPY_4((tri_data->m_planes.m_planes[3]),(planes->m_planes[3]));//edge3
tri_data->m_has_planes = 1;
return;
}
GIM_CALC_TRIANGLE_DATA_PLANES((*tri_data));
tri_data->m_has_planes = 1;
}
void gim_trimesh_get_triangle_data_lazy(GIM_TRIMESH * trimesh, GUINT triangle_index, GIM_TRIANGLE_DATA * tri_data)
{
gim_trimesh_get_triangle_vertices(trimesh,triangle_index,
tri_data->m_vertices[0],
tri_data->m_vertices[1],
tri_data->m_vertices[2]);
if(trimesh->m_cache)
{
//Get the planes
GIM_TRIPLANES_CACHE * planes = GIM_DYNARRAY_POINTER(GIM_TRIPLANES_CACHE,trimesh->m_cache->m_planes_cache_buffer);
planes += triangle_index;
//verify planes cache
char bit_eval;
GIM_BITSET_GET(trimesh->m_cache->m_planes_cache_bitset,triangle_index,bit_eval);
if(bit_eval == 0)// Needs to calc the planes
{
//Calc the face plane
TRIANGLE_PLANE(tri_data->m_vertices[0],tri_data->m_vertices[1],tri_data->m_vertices[2],planes->m_planes[0]);
//Calc the edge 1
EDGE_PLANE(tri_data->m_vertices[0],tri_data->m_vertices[1],(planes->m_planes[0]),(planes->m_planes[1]));
//Calc the edge 2
EDGE_PLANE(tri_data->m_vertices[1],tri_data->m_vertices[2],(planes->m_planes[0]),(planes->m_planes[2]));
//Calc the edge 3
EDGE_PLANE(tri_data->m_vertices[2],tri_data->m_vertices[0],(planes->m_planes[0]), (planes->m_planes[3]));
//mark
GIM_BITSET_SET(trimesh->m_cache->m_planes_cache_bitset,triangle_index);
}
VEC_COPY_4((tri_data->m_planes.m_planes[0]),(planes->m_planes[0]));//face plane
VEC_COPY_4((tri_data->m_planes.m_planes[1]),(planes->m_planes[1]));//edge1
VEC_COPY_4((tri_data->m_planes.m_planes[2]),(planes->m_planes[2]));//edge2
VEC_COPY_4((tri_data->m_planes.m_planes[3]),(planes->m_planes[3]));//edge3
tri_data->m_has_planes = 1;
return;
}
tri_data->m_has_planes = 0;
}
void gim_trimesh_get_aabb(GIM_TRIMESH * trimesh,aabb3f * bound)
{
if(trimesh->m_aabbset)
{
AABB_COPY((*bound),trimesh->m_aabbset->m_global_bound);
return;
}
if(gim_trimesh_data_has_bv_tree(trimesh->m_trimesh_data_handle))
{
gim_trimesh_data_get(trimesh->m_trimesh_data_handle,&trimesh->m_unlocked_trimesh_data);
if(gim_trimesh_has_tranform(trimesh))
{
AABB_TRANSFORM((*bound),
trimesh->m_unlocked_trimesh_data->m_bv_tree.m_root_node->m_data.m_aabb,
trimesh->m_transform);
}
else
{
AABB_COPY((*bound),trimesh->m_unlocked_trimesh_data->m_bv_tree.m_root_node->m_data.m_aabb);
}
trimesh->m_unlocked_trimesh_data = 0;
return;
}
}
void gim_trimesh_midphase_box_collision(GIM_TRIMESH * trimesh,aabb3f *test_aabb, GDYNAMIC_ARRAY * collided)
{
collided->m_size = 0;
if(gim_trimesh_get_bound_method(trimesh)==G_TRIMESH_BOUND_AABB_TREE)
{
GIM_TRIMESH_DATA * tridata;
gim_trimesh_data_get(trimesh->m_trimesh_data_handle,&tridata);
aabb3f transbound;
AABB_TRANSFORM(transbound,(*test_aabb),trimesh->m_inv_transform);
gim_aabbtree_box_collision(&transbound,&tridata->m_bv_tree,collided);
}
else if(gim_trimesh_get_bound_method(trimesh)==G_TRIMESH_BOUND_AABB_SET)
{
gim_aabbset_box_collision(test_aabb,trimesh->m_aabbset,collided);
}
}
void gim_trimesh_midphase_box_collision_local(GIM_TRIMESH * trimesh,aabb3f *test_aabb, GDYNAMIC_ARRAY * collided)
{
collided->m_size = 0;
if(gim_trimesh_get_bound_method(trimesh)==G_TRIMESH_BOUND_AABB_TREE)
{
GIM_TRIMESH_DATA * tridata;
gim_trimesh_data_get(trimesh->m_trimesh_data_handle,&tridata);
gim_aabbtree_box_collision(test_aabb,&tridata->m_bv_tree,collided);
}
else if(gim_trimesh_get_bound_method(trimesh)==G_TRIMESH_BOUND_AABB_SET)
{
gim_aabbset_box_collision(test_aabb,trimesh->m_aabbset,collided);
}
}
void gim_trimesh_midphase_trimesh_collision(GIM_TRIMESH * trimesh1,
GIM_TRIMESH * trimesh2, GDYNAMIC_ARRAY * collision_pairs, char * swaped)
{
collision_pairs->m_size = 0;
GIM_TRIMESH_DATA * tridata1;
GIM_TRIMESH_DATA * tridata2;
if(gim_trimesh_get_bound_method(trimesh1)==G_TRIMESH_BOUND_AABB_TREE)
{
gim_trimesh_data_get(trimesh1->m_trimesh_data_handle,&tridata1);
if(gim_trimesh_get_bound_method(trimesh2)==G_TRIMESH_BOUND_AABB_TREE)
{
*swaped = 0;
gim_trimesh_data_get(trimesh2->m_trimesh_data_handle,&tridata2);
gim_aabbtree_bipartite_intersections_trans(
&tridata1->m_bv_tree,
&tridata2->m_bv_tree,
trimesh1->m_transform,
trimesh1->m_inv_transform,
trimesh2->m_transform,
trimesh2->m_inv_transform,
collision_pairs);
}
else if(gim_trimesh_get_bound_method(trimesh2)==G_TRIMESH_BOUND_AABB_SET)
{
*swaped = 1;
gim_aabbset_aabbtree_intersections_trans(
trimesh2->m_aabbset,
&tridata1->m_bv_tree,
trimesh1->m_transform,
trimesh1->m_inv_transform,
collision_pairs);
}
}
else if(gim_trimesh_get_bound_method(trimesh1)==G_TRIMESH_BOUND_AABB_SET)
{
*swaped = 0;
if(gim_trimesh_get_bound_method(trimesh2)==G_TRIMESH_BOUND_AABB_TREE)
{
gim_trimesh_data_get(trimesh2->m_trimesh_data_handle,&tridata2);
gim_aabbset_aabbtree_intersections_trans(
trimesh1->m_aabbset,
&tridata2->m_bv_tree,
trimesh2->m_transform,
trimesh2->m_inv_transform,
collision_pairs);
}
else if(gim_trimesh_get_bound_method(trimesh2)==G_TRIMESH_BOUND_AABB_SET)
{
gim_aabbset_bipartite_intersections(
trimesh1->m_aabbset,
trimesh2->m_aabbset,
collision_pairs);
}
}
}

View File

@ -1,281 +0,0 @@
/*
-----------------------------------------------------------------------------
This source file is part of GIMPACT Library.
For the latest info, see http://gimpact.sourceforge.net/
Copyright (c) 2006 Francisco Leon Najera. C.C. 80087371.
email: projectileman@yahoo.com
This library is free software; you can redistribute it and/or
modify it under the terms of EITHER:
(1) The GNU Lesser General Public License as published by the Free
Software Foundation; either version 2.1 of the License, or (at
your option) any later version. The text of the GNU Lesser
General Public License is included with this library in the
file GIMPACT-LICENSE-LGPL.TXT.
(2) The BSD-style license that is included with this library in
the file GIMPACT-LICENSE-BSD.TXT.
(3) The zlib/libpng license that is included with this library in
the file GIMPACT-LICENSE-ZLIB.TXT.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files
GIMPACT-LICENSE-LGPL.TXT, GIMPACT-LICENSE-ZLIB.TXT and GIMPACT-LICENSE-BSD.TXT for more details.
-----------------------------------------------------------------------------
*/
#include "GIMPACT/gim_trimesh.h"
//! Utility function for find the closest point between a segment and a triangle
/*!
\param triangle
\param s1
\param s2
\param contacts Contains the closest points on the segment (1,2), and the normal points to segment, and m_depth contains the distance
\post The contacts array is not set to 0. It adds aditional contacts
*/
void gim_closest_point_triangle_segment(GIM_TRIANGLE_DATA * triangle, vec3f s1,vec3f s2, GDYNAMIC_ARRAY * contacts)
{
vec3f segment_points[4];
vec3f closest_points[2];
GUINT intersection_type, out_edge= 10;
GREAL dis, dis_temp,perpend;
vec4f sdiff;
dis = DISTANCE_PLANE_POINT(triangle->m_planes.m_planes[0],s1);
dis_temp = DISTANCE_PLANE_POINT(triangle->m_planes.m_planes[0],s2);
if(dis<=0.0f && dis_temp<=0.0f) return;
VEC_DIFF(sdiff,s2,s1);
perpend = VEC_DOT(sdiff,triangle->m_planes.m_planes[0]);
if(!GIM_IS_ZERO(perpend)) // Not perpendicular
{
if(dis<dis_temp)
{
VEC_COPY(closest_points[0],s1);
}
else
{
dis = dis_temp;
VEC_COPY(closest_points[0],s2);
}
//Testing segment vertices over triangle
if(dis>=0.0f && dis_temp>=0.0f)
{
POINT_IN_HULL(closest_points[0],(&triangle->m_planes.m_planes[1]),3,out_edge);
if(out_edge==0)//Point over face
{
GIM_PUSH_CONTACT((*contacts),closest_points[0] ,triangle->m_planes.m_planes[0] ,dis,0, 0, 0,0);
return;
}
}
else
{
PLANE_CLIP_SEGMENT(s1,s2,triangle->m_planes.m_planes[0],closest_points[1]);
POINT_IN_HULL(closest_points[1],(&triangle->m_planes.m_planes[1]),3,out_edge);
if(out_edge==0)//Point over face
{
GIM_PUSH_CONTACT((*contacts),closest_points[0] ,triangle->m_planes.m_planes[0] ,dis,0, 0, 0,0);
return;
}
}
}
else // Perpendicular Face
{
//out_edge=10
//Clip segment by triangle
// Edge1
PLANE_CLIP_SEGMENT_CLOSEST(s1,s2,triangle->m_planes.m_planes[1],segment_points[0],segment_points[1],intersection_type);
if(intersection_type==0||intersection_type==1)
{
out_edge = 0;
VEC_COPY(closest_points[0],segment_points[0]);
}
else
{
//Edge2
PLANE_CLIP_SEGMENT_CLOSEST(segment_points[0],segment_points[1],triangle->m_planes.m_planes[2],segment_points[2],segment_points[3],intersection_type);
if(intersection_type==0||intersection_type==1)
{
out_edge = 1;
VEC_COPY(closest_points[0],segment_points[3]);
}
else
{
//Edge3
PLANE_CLIP_SEGMENT_CLOSEST(segment_points[2],segment_points[3],triangle->m_planes.m_planes[3],closest_points[0],closest_points[1],intersection_type);
if(intersection_type==0||intersection_type==1)
{
out_edge = 2;
}
}
}
//POST closest_points[0] and closest_points[1] are inside the triangle, if out_edge>2
if(out_edge>2) // Over triangle
{
dis = VEC_DOT(closest_points[0],triangle->m_planes.m_planes[0]);
GIM_PUSH_CONTACT((*contacts),closest_points[0] ,triangle->m_planes.m_planes[0] ,dis,0, 0, 0,0);
GIM_PUSH_CONTACT((*contacts),closest_points[1] ,triangle->m_planes.m_planes[0] ,dis,0, 0, 0,0);
return;
}
}
//Find closest edges
out_edge = 10;
dis = G_REAL_INFINITY;
GUINT i;
for(i=0;i<3;i++)
{
SEGMENT_COLLISION(s1,s2,triangle->m_vertices[i],triangle->m_vertices[(i+1)%3],segment_points[0],segment_points[1]);
VEC_DIFF(sdiff,segment_points[0],segment_points[1]);
dis_temp = VEC_DOT(sdiff,sdiff);
if(dis_temp< dis)
{
dis = dis_temp;
out_edge = i;
VEC_COPY(closest_points[0],segment_points[0]);
VEC_COPY(closest_points[1],sdiff);//normal
}
}
if(out_edge>2) return ;// ???? btAssert this please
if(GIM_IS_ZERO(dis))
{
//Set face plane
GIM_PUSH_CONTACT((*contacts),closest_points[0] ,triangle->m_planes.m_planes[0] ,0.0f,0, 0, 0,0);
}
else
{
GIM_SQRT(dis,dis);
VEC_SCALE(closest_points[1],(1.0f/dis),closest_points[1]);//normal
GIM_PUSH_CONTACT((*contacts),closest_points[0] ,closest_points[1],dis,0, 0, 0,0);
}
}
//! Utility function for find the closest point between a capsule and a triangle
/*!
\param triangle
\param capsule
\param contacts Contains the closest points on the capsule, and the normal points to triangle
\post The contacts array is not set to 0. It adds aditional contacts
*/
int gim_triangle_capsule_collision(GIM_TRIANGLE_DATA * triangle, GIM_CAPSULE_DATA * capsule, GDYNAMIC_ARRAY * contacts)
{
GUINT old_contact_size = contacts->m_size;
gim_closest_point_triangle_segment(triangle,capsule->m_point1,capsule->m_point2,contacts);
GIM_CONTACT * pcontact = GIM_DYNARRAY_POINTER(GIM_CONTACT ,(*contacts));
pcontact+= old_contact_size;
if(pcontact->m_depth > capsule->m_radius)
{
contacts->m_size = old_contact_size;
return 0;
}
vec3f vec;
while(old_contact_size<contacts->m_size)
{
//Scale the normal for pointing to triangle
VEC_SCALE(pcontact->m_normal,-1.0f,pcontact->m_normal);
//Fix the contact point
VEC_SCALE(vec,capsule->m_radius,pcontact->m_normal);
VEC_SUM(pcontact->m_point,vec,pcontact->m_point);
//Fix the depth
pcontact->m_depth = capsule->m_radius - pcontact->m_depth;
pcontact++;
old_contact_size++;
}
return 1;
}
//! Trimesh Capsule collision
/*!
Find the closest primitive collided by the ray
\param trimesh
\param capsule
\param contact
\param contacts A GIM_CONTACT array. Must be initialized
*/
void gim_trimesh_capsule_collision(GIM_TRIMESH * trimesh, GIM_CAPSULE_DATA * capsule, GDYNAMIC_ARRAY * contacts)
{
contacts->m_size = 0;
aabb3f test_aabb;
CALC_CAPSULE_AABB((*capsule),test_aabb);
GDYNAMIC_ARRAY collision_result;
GIM_CREATE_BOXQUERY_LIST(collision_result);
gim_trimesh_midphase_box_collision(trimesh,&test_aabb,&collision_result);
if(collision_result.m_size==0)
{
GIM_DYNARRAY_DESTROY(collision_result);
}
//collide triangles
//Locks trimesh
gim_trimesh_locks_work_data(trimesh);
//dummy contacts
GDYNAMIC_ARRAY dummycontacts;
GIM_CREATE_CONTACT_LIST(dummycontacts);
int cresult;
unsigned int i;
GUINT * boxesresult = GIM_DYNARRAY_POINTER(GUINT,collision_result);
GIM_TRIANGLE_DATA tri_data;
GUINT old_contact_size;
GIM_CONTACT * pcontact;
for(i=0;i<collision_result.m_size;i++)
{
old_contact_size = dummycontacts.m_size;
gim_trimesh_get_triangle_data(trimesh,boxesresult[i],&tri_data);
cresult = gim_triangle_capsule_collision(&tri_data, capsule, &dummycontacts);
if(cresult!=0)
{
pcontact = GIM_DYNARRAY_POINTER(GIM_CONTACT ,dummycontacts);
pcontact+= old_contact_size;
while(old_contact_size<dummycontacts.m_size)
{
pcontact->m_handle1 = trimesh;
pcontact->m_handle2 = capsule;
pcontact->m_feature1 = boxesresult[i];
pcontact->m_feature2 = 0;
pcontact++;
old_contact_size++;
}
}
}
///unlocks
gim_trimesh_unlocks_work_data(trimesh);
///Destroy box result
GIM_DYNARRAY_DESTROY(collision_result);
//merge contacts
gim_merge_contacts(&dummycontacts,contacts);
//Destroy dummy
GIM_DYNARRAY_DESTROY(dummycontacts);
}

View File

@ -1,454 +0,0 @@
/*
-----------------------------------------------------------------------------
This source file is part of GIMPACT Library.
For the latest info, see http://gimpact.sourceforge.net/
Copyright (c) 2006 Francisco Leon Najera. C.C. 80087371.
email: projectileman@yahoo.com
This library is free software; you can redistribute it and/or
modify it under the terms of EITHER:
(1) The GNU Lesser General Public License as published by the Free
Software Foundation; either version 2.1 of the License, or (at
your option) any later version. The text of the GNU Lesser
General Public License is included with this library in the
file GIMPACT-LICENSE-LGPL.TXT.
(2) The BSD-style license that is included with this library in
the file GIMPACT-LICENSE-BSD.TXT.
(3) The zlib/libpng license that is included with this library in
the file GIMPACT-LICENSE-ZLIB.TXT.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files
GIMPACT-LICENSE-LGPL.TXT, GIMPACT-LICENSE-ZLIB.TXT and GIMPACT-LICENSE-BSD.TXT for more details.
-----------------------------------------------------------------------------
*/
#include "GIMPACT/gim_trimesh_data.h"
GDYNAMIC_ARRAY g_trimesh_data_array;
GDYNAMIC_ARRAY g_trimesh_data_free_positions;
void gim_trimesh_data_manager_init()
{
GIM_DYNARRAY_CREATE(GIM_TRIMESH_DATA,g_trimesh_data_array,G_ARRAY_GROW_SIZE);
GIM_DYNARRAY_CREATE(GUINT,g_trimesh_data_free_positions,G_ARRAY_GROW_SIZE);
}
void gim_trimesh_data_manager_end()
{
//Destroy all trimeshes
GUINT i,tricount;
GIM_TRIMESH_DATA * trimeshes = GIM_DYNARRAY_POINTER(GIM_TRIMESH_DATA,g_trimesh_data_array);
tricount = g_trimesh_data_array.m_size;
for (i=0;i<tricount;i++)
{
if(GIM_IS_VALID_BUFFER_ID(trimeshes[i].m_source_vertex_buffer.m_buffer_id))
{
trimeshes[i].m_ref_count = 0;
gim_trimesh_data_destroy(i);
}
}
GIM_DYNARRAY_DESTROY(g_trimesh_data_array);
GIM_DYNARRAY_DESTROY(g_trimesh_data_free_positions);
}
int gim_trimesh_data_is_valid_manager()
{
if(g_trimesh_data_array.m_pdata == 0 ) return 0;
return 1;
}
//! Returns the free position (1 based) on the g_trimesh_data_array
GUINT _gim_trimesh_data_get_avaliable_pos()
{
if(gim_trimesh_data_is_valid_manager()==0) return 0;
if(g_trimesh_data_free_positions.m_size>0)
{
GUINT freeposition = *GIM_DYNARRAY_POINTER_LAST(GUINT,g_trimesh_data_free_positions);
GIM_DYNARRAY_POP_ITEM(g_trimesh_data_free_positions);
return freeposition+1;
}
GIM_DYNARRAY_PUSH_EMPTY(GIM_TRIMESH_DATA,g_trimesh_data_array);
return g_trimesh_data_array.m_size;
}
void _gim_trimesh_data_free_handle(GUINT handle)
{
if(gim_trimesh_data_is_valid_manager()==0) return;
GUINT freeposition = handle-1;
GIM_DYNARRAY_PUSH_ITEM(GUINT,g_trimesh_data_free_positions,freeposition);
}
void gim_trimesh_data_get(GUINT trimesh_data_handle,GIM_TRIMESH_DATA ** trimesh_data)
{
if(gim_trimesh_data_is_valid_manager()==0)
{
*trimesh_data = 0;
return;
}
GIM_TRIMESH_DATA * trimeshes = GIM_DYNARRAY_POINTER(GIM_TRIMESH_DATA,g_trimesh_data_array);
*trimesh_data = trimeshes+(trimesh_data_handle-1);
}
void _gim_gim_trimesh_data_create_empty(GIM_TRIMESH_DATA * tridata)
{
tridata->m_vertex_scalar_type = G_STYPE_REAL;
tridata->m_index_scalar_type = G_STYPE_UINT;
tridata->m_ref_count = 0;
//Init bvh
tridata->m_bv_tree.m_node_array = 0;
tridata->m_bv_tree.m_num_nodes = 0;
tridata->m_bv_tree.m_root_node = 0;
tridata->m_bv_tree.m_nodes_array_size = 0;
//Reference buffer arrays
tridata->m_source_vertex_buffer.m_buffer_data = 0;
tridata->m_source_vertex_buffer.m_buffer_id.m_buffer_id = G_UINT_INFINITY;
tridata->m_source_vertex_buffer.m_element_count = 0;
tridata->m_tri_index_buffer.m_buffer_data = 0;
tridata->m_tri_index_buffer.m_buffer_id.m_buffer_id = G_UINT_INFINITY;
tridata->m_tri_index_buffer.m_element_count = 0;
}
void _gim_gim_trimesh_data_build_from_arrays(GIM_TRIMESH_DATA * tridata,GBUFFER_ARRAY * vertex_array,GUINT vertex_scalar_type, GBUFFER_ARRAY * triindex_array,GUINT index_scalar_type)
{
tridata->m_vertex_scalar_type = vertex_scalar_type;
tridata->m_index_scalar_type = index_scalar_type;
tridata->m_ref_count = 0;
//Init bvh
tridata->m_bv_tree.m_node_array = 0;
tridata->m_bv_tree.m_num_nodes = 0;
tridata->m_bv_tree.m_root_node = 0;
tridata->m_bv_tree.m_nodes_array_size = 0;
//Reference buffer arrays
gim_buffer_array_copy_ref(vertex_array,&tridata->m_source_vertex_buffer);
gim_buffer_array_copy_ref(triindex_array,&tridata->m_tri_index_buffer);
}
void _gim_gim_trimesh_data_destroy_data(GIM_TRIMESH_DATA * tridata)
{
GIM_BUFFER_ARRAY_DESTROY(tridata->m_source_vertex_buffer);
GIM_BUFFER_ARRAY_DESTROY(tridata->m_tri_index_buffer);
gim_aabbtree_destroy(&tridata->m_bv_tree);
}
void gim_trimesh_data_create_empty(GUINT * trimesh_data_handle)
{
*trimesh_data_handle = _gim_trimesh_data_get_avaliable_pos();
if(*trimesh_data_handle == 0) return ; //an error ocurred
GIM_TRIMESH_DATA * tridata;
gim_trimesh_data_get(*trimesh_data_handle,&tridata);
//init trimesh
tridata->m_handle = *trimesh_data_handle;
_gim_gim_trimesh_data_create_empty(tridata);
}
void gim_trimesh_data_create_from_arrays(GUINT * trimesh_data_handle, GBUFFER_ARRAY * vertex_array,GUINT vertex_scalar_type, GBUFFER_ARRAY * triindex_array,GUINT index_scalar_type)
{
*trimesh_data_handle = _gim_trimesh_data_get_avaliable_pos();
if(*trimesh_data_handle == 0) return ; //an error ocurred
GIM_TRIMESH_DATA * tridata;
gim_trimesh_data_get(*trimesh_data_handle,&tridata);
//init trimesh
tridata->m_handle = *trimesh_data_handle;
//construct
_gim_gim_trimesh_data_build_from_arrays(tridata,vertex_array,vertex_scalar_type,triindex_array,index_scalar_type);
}
void gim_trimesh_data_create_from_array_data(GUINT * trimesh_data_handle, vec3f * vertex_array, GUINT vertex_count,char copy_vertices, GUINT * triindex_array, GUINT triangle_count,char copy_indices)
{
if(gim_trimesh_data_is_valid_manager()==0)
{
*trimesh_data_handle = 0;
return;
}
GBUFFER_ARRAY buffer_vertex_array;
GBUFFER_ARRAY buffer_triindex_array;
//Create vertices
if(copy_vertices == 1)
{
gim_create_common_buffer_from_data(vertex_array, vertex_count*sizeof(vec3f), &buffer_vertex_array.m_buffer_id);
}
else//Create a shared buffer
{
gim_create_shared_buffer_from_data(vertex_array, vertex_count*sizeof(vec3f), &buffer_vertex_array.m_buffer_id);
}
GIM_BUFFER_ARRAY_INIT_TYPE(vec3f,buffer_vertex_array,buffer_vertex_array.m_buffer_id,vertex_count);
//Create vertices
if(copy_indices == 1)
{
gim_create_common_buffer_from_data(triindex_array, triangle_count*sizeof(vec3ui), &buffer_triindex_array.m_buffer_id);
}
else//Create a shared buffer
{
gim_create_shared_buffer_from_data(triindex_array, triangle_count*sizeof(vec3ui), &buffer_triindex_array.m_buffer_id);
}
GIM_BUFFER_ARRAY_INIT_TYPE(vec3ui,buffer_triindex_array,buffer_triindex_array.m_buffer_id,triangle_count);
gim_trimesh_data_create_from_arrays(trimesh_data_handle, &buffer_vertex_array,G_STYPE_REAL, &buffer_triindex_array,G_STYPE_UINT);
///always call this after create a buffer_array
GIM_BUFFER_ARRAY_DESTROY(buffer_vertex_array);
GIM_BUFFER_ARRAY_DESTROY(buffer_triindex_array);
}
void gim_trimesh_data_inc_ref(GUINT trimesh_data_handle)
{
if(gim_trimesh_data_is_valid_manager()==0) return;
GIM_TRIMESH_DATA * tridata;
gim_trimesh_data_get(trimesh_data_handle,&tridata);
tridata->m_ref_count++;
}
void gim_trimesh_data_dec_ref(GUINT trimesh_data_handle)
{
if(gim_trimesh_data_is_valid_manager()==0) return;
GIM_TRIMESH_DATA * tridata;
gim_trimesh_data_get(trimesh_data_handle,&tridata);
if(tridata->m_ref_count==0)
{
//Attemps to destroy the trimesh
gim_trimesh_data_destroy(trimesh_data_handle);
return;
}
tridata->m_ref_count--;
if(tridata->m_ref_count==0)
{
//Attemps to destroy the trimesh
gim_trimesh_data_destroy(trimesh_data_handle);
}
}
void gim_trimesh_data_destroy(GUINT trimesh_data_handle)
{
if(gim_trimesh_data_is_valid_manager()==0) return;
GIM_TRIMESH_DATA * tridata;
gim_trimesh_data_get(trimesh_data_handle,&tridata);
if(tridata->m_ref_count>0) return; //Can't destroy it now
_gim_gim_trimesh_data_destroy_data(tridata);
//Get a free position
_gim_trimesh_data_free_handle(trimesh_data_handle);
}
void gim_trimesh_data_lock(GUINT trimesh_data_handle, int access,GIM_TRIMESH_DATA ** trimesh_data)
{
if(gim_trimesh_data_is_valid_manager()==0) return;
gim_trimesh_data_get(trimesh_data_handle,trimesh_data);
gim_buffer_array_lock(&(*trimesh_data)->m_source_vertex_buffer,access);
gim_buffer_array_lock(&(*trimesh_data)->m_tri_index_buffer,access);
}
void gim_trimesh_data_unlock(GUINT trimesh_data_handle)
{
if(gim_trimesh_data_is_valid_manager()==0) return;
GIM_TRIMESH_DATA * tridata;
gim_trimesh_data_get(trimesh_data_handle,&tridata);
gim_buffer_array_unlock(&tridata->m_source_vertex_buffer);
gim_buffer_array_unlock(&tridata->m_tri_index_buffer);
}
GUINT gim_trimesh_data_get_vertex_count(GUINT trimesh_data_handle)
{
GIM_TRIMESH_DATA * tridata;
gim_trimesh_data_get(trimesh_data_handle,&tridata);
return tridata->m_source_vertex_buffer.m_element_count;
}
GUINT gim_trimesh_data_get_triangle_count(GUINT trimesh_data_handle)
{
GIM_TRIMESH_DATA * tridata;
gim_trimesh_data_get(trimesh_data_handle,&tridata);
return tridata->m_tri_index_buffer.m_element_count;
}
void gim_trimesh_data_get_triangle_indices(GIM_TRIMESH_DATA * trimesh_data, GUINT tri_index, GUINT * indices)
{
if(trimesh_data->m_index_scalar_type == G_STYPE_UINT)
{
GUINT * uipindices = GIM_BUFFER_ARRAY_POINTER(GUINT,trimesh_data->m_tri_index_buffer,tri_index);
indices[0] = uipindices[0];
indices[1] = uipindices[1];
indices[2] = uipindices[2];
}
else if(trimesh_data->m_index_scalar_type == G_STYPE_INT)
{
GINT * ipindices = GIM_BUFFER_ARRAY_POINTER(GINT,trimesh_data->m_tri_index_buffer,tri_index);
indices[0] = ipindices[0];
indices[1] = ipindices[1];
indices[2] = ipindices[2];
}
else if(trimesh_data->m_index_scalar_type == G_STYPE_USHORT)
{
GUSHORT * uspindices = GIM_BUFFER_ARRAY_POINTER(GUSHORT,trimesh_data->m_tri_index_buffer,tri_index);
indices[0] = uspindices[0];
indices[1] = uspindices[1];
indices[2] = uspindices[2];
}
else if(trimesh_data->m_index_scalar_type == G_STYPE_SHORT)
{
GSHORT * spindices = GIM_BUFFER_ARRAY_POINTER(GSHORT,trimesh_data->m_tri_index_buffer,tri_index);
indices[0] = spindices[0];
indices[1] = spindices[1];
indices[2] = spindices[2];
}
}
void gim_trimesh_data_get_vertex(GIM_TRIMESH_DATA * trimesh_data, GUINT vertex_index, vec3f vec)
{
if(trimesh_data->m_vertex_scalar_type == G_STYPE_REAL)
{
GREAL * rvalues = GIM_BUFFER_ARRAY_POINTER(GREAL,trimesh_data->m_source_vertex_buffer,vertex_index);
vec[0] = rvalues[0];
vec[1] = rvalues[1];
vec[2] = rvalues[2];
}
else if(trimesh_data->m_vertex_scalar_type == G_STYPE_REAL2)
{
GREAL2 * r2values = GIM_BUFFER_ARRAY_POINTER(GREAL2,trimesh_data->m_source_vertex_buffer,vertex_index);
vec[0] = r2values[0];
vec[1] = r2values[1];
vec[2] = r2values[2];
}
}
void gim_trimesh_data_get_triangle_vertices(GIM_TRIMESH_DATA * trimesh_data, GUINT tri_index, vec3f v1, vec3f v2, vec3f v3)
{
GUINT tri_indices[3];
gim_trimesh_data_get_triangle_indices(trimesh_data,tri_index,tri_indices);
if(trimesh_data->m_vertex_scalar_type == G_STYPE_REAL)
{
GREAL * rvalues = GIM_BUFFER_ARRAY_POINTER(GREAL,trimesh_data->m_source_vertex_buffer,tri_indices[0]);
VEC_COPY(v1,rvalues);
rvalues = GIM_BUFFER_ARRAY_POINTER(GREAL,trimesh_data->m_source_vertex_buffer,tri_indices[1]);
VEC_COPY(v2,rvalues);
rvalues = GIM_BUFFER_ARRAY_POINTER(GREAL,trimesh_data->m_source_vertex_buffer,tri_indices[2]);
VEC_COPY(v3,rvalues);
}
else if(trimesh_data->m_vertex_scalar_type == G_STYPE_REAL2)
{
GREAL2 * r2values = GIM_BUFFER_ARRAY_POINTER(GREAL2,trimesh_data->m_source_vertex_buffer,tri_indices[0]);
VEC_COPY(v1,r2values);
r2values = GIM_BUFFER_ARRAY_POINTER(GREAL2,trimesh_data->m_source_vertex_buffer,tri_indices[1]);
VEC_COPY(v2,r2values);
r2values = GIM_BUFFER_ARRAY_POINTER(GREAL2,trimesh_data->m_source_vertex_buffer,tri_indices[2]);
VEC_COPY(v3,r2values);
}
}
void gim_trimesh_data_build_aabbtree(GUINT trimesh_data_handle)
{
if(gim_trimesh_data_is_valid_manager()==0) return;
GIM_TRIMESH_DATA * tridata;
gim_trimesh_data_lock(trimesh_data_handle, G_MA_READ_ONLY,&tridata);
GUINT i,tricount;
tricount = gim_trimesh_data_get_triangle_count(trimesh_data_handle);
GIM_AABB_DATA * boxarray = (GIM_AABB_DATA *)gim_alloc(tricount*sizeof(GIM_AABB_DATA));
vec3f trivertices[3];
for (i=0;i<tricount ;i++ )
{
gim_trimesh_data_get_triangle_vertices(tridata,i,trivertices[0],trivertices[1],trivertices[2]);
COMPUTEAABB_FOR_TRIANGLE(boxarray[i].m_aabb,trivertices[0],trivertices[1],trivertices[2]);
boxarray[i].m_data = i;
}
gim_trimesh_data_unlock(trimesh_data_handle);
gim_aabbtree_create(&tridata->m_bv_tree,boxarray,tricount);
gim_free(boxarray,0);
}
int gim_trimesh_data_has_bv_tree(GUINT trimesh_data_handle)
{
GIM_TRIMESH_DATA * tridata;
gim_trimesh_data_get(trimesh_data_handle,&tridata);
if(tridata->m_bv_tree.m_node_array == 0) return 0;
return 1;
}
void gim_trimesh_data_copy(GUINT source_trimesh_data,GUINT dest_trimesh_data, char copy_by_reference)
{
if(gim_trimesh_data_is_valid_manager()==0) return;
GIM_TRIMESH_DATA * sourcetridata;
gim_trimesh_data_get(source_trimesh_data,&sourcetridata);
GIM_TRIMESH_DATA * desttridata;
gim_trimesh_data_get(dest_trimesh_data,&desttridata);
_gim_gim_trimesh_data_destroy_data(desttridata);//Clear previus data
if(copy_by_reference==1)
{
_gim_gim_trimesh_data_build_from_arrays(desttridata, &sourcetridata->m_source_vertex_buffer,
sourcetridata->m_vertex_scalar_type, &sourcetridata->m_tri_index_buffer,
sourcetridata->m_index_scalar_type);
}
else
{
GBUFFER_ARRAY buffer_vertex_array;
GBUFFER_ARRAY buffer_triindex_array;
gim_buffer_array_copy_value(&sourcetridata->m_source_vertex_buffer,&buffer_vertex_array,G_BUFFER_MANAGER_SYSTEM,G_MU_DYNAMIC_READ_WRITE);
gim_buffer_array_copy_value(&sourcetridata->m_tri_index_buffer,&buffer_triindex_array,G_BUFFER_MANAGER_SYSTEM,G_MU_DYNAMIC_READ_WRITE);
_gim_gim_trimesh_data_build_from_arrays(desttridata, &buffer_vertex_array,
sourcetridata->m_vertex_scalar_type, &buffer_triindex_array,
sourcetridata->m_index_scalar_type);
///always call this after create a buffer_array
GIM_BUFFER_ARRAY_DESTROY(buffer_vertex_array);
GIM_BUFFER_ARRAY_DESTROY(buffer_triindex_array);
}
//If it has a Bounding volume tree, construct it
if(gim_trimesh_data_has_bv_tree(source_trimesh_data))
{
gim_trimesh_data_build_aabbtree(dest_trimesh_data);
}
}
void gim_trimesh_data_create_copy(GUINT source_trimesh_data,GUINT * dest_trimesh_data, char copy_by_reference)
{
if(gim_trimesh_data_is_valid_manager()==0) return;
gim_trimesh_data_create_empty(dest_trimesh_data);
gim_trimesh_data_copy(source_trimesh_data,*dest_trimesh_data, copy_by_reference);
}

View File

@ -1,180 +0,0 @@
/*
-----------------------------------------------------------------------------
This source file is part of GIMPACT Library.
For the latest info, see http://gimpact.sourceforge.net/
Copyright (c) 2006 Francisco Leon Najera. C.C. 80087371.
email: projectileman@yahoo.com
This library is free software; you can redistribute it and/or
modify it under the terms of EITHER:
(1) The GNU Lesser General Public License as published by the Free
Software Foundation; either version 2.1 of the License, or (at
your option) any later version. The text of the GNU Lesser
General Public License is included with this library in the
file GIMPACT-LICENSE-LGPL.TXT.
(2) The BSD-style license that is included with this library in
the file GIMPACT-LICENSE-BSD.TXT.
(3) The zlib/libpng license that is included with this library in
the file GIMPACT-LICENSE-ZLIB.TXT.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files
GIMPACT-LICENSE-LGPL.TXT, GIMPACT-LICENSE-ZLIB.TXT and GIMPACT-LICENSE-BSD.TXT for more details.
-----------------------------------------------------------------------------
*/
#include "GIMPACT/gim_trimesh.h"
//! Trimesh Ray Collisions
/*!
\param trimesh
\param contact
\return 1 if the ray collides, else 0
*/
int gim_trimesh_ray_collision(GIM_TRIMESH * trimesh,vec3f origin,vec3f dir, GREAL tmax, GIM_TRIANGLE_RAY_CONTACT_DATA * contact)
{
GDYNAMIC_ARRAY collision_result;
GIM_CREATE_BOXQUERY_LIST(collision_result);
if(trimesh->m_aabbset)
{
gim_aabbset_ray_collision(origin,dir,tmax,trimesh->m_aabbset,
&collision_result);
}
else if(gim_trimesh_get_bound_method(trimesh)==G_TRIMESH_BOUND_AABB_TREE)
{
vec3f torigin, tdir;
gim_trimesh_data_get(trimesh->m_trimesh_data_handle,
&trimesh->m_unlocked_trimesh_data);
MAT_DOT_VEC_3X4(torigin,trimesh->m_inv_transform,dir);
MAT_DOT_VEC_3X3(tdir,trimesh->m_inv_transform,dir);
gim_aabbtree_ray_collision(
torigin,tdir, tmax,
&trimesh->m_unlocked_trimesh_data->m_bv_tree, &collision_result);
trimesh->m_unlocked_trimesh_data = 0;
}
if(collision_result.m_size==0)
{
GIM_DYNARRAY_DESTROY(collision_result);
return 0;
}
//collide triangles
GUINT * boxesresult = GIM_DYNARRAY_POINTER(GUINT,collision_result);
GIM_TRIANGLE_DATA tridata;
vec3f pout;
GREAL tparam,u,v;
char does_intersect;
gim_trimesh_locks_work_data(trimesh);
for(unsigned int i=0;i<collision_result.m_size;i++)
{
gim_trimesh_get_triangle_data(trimesh,boxesresult[i],&tridata);
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);
if(does_intersect)
{
contact->tparam = tparam;
contact->u = u;
contact->v = v;
contact->m_face_id = boxesresult[i];
VEC_COPY(contact->m_point,pout);
VEC_COPY(contact->m_normal,tridata.m_planes.m_planes[0]);
gim_trimesh_unlocks_work_data(trimesh);
GIM_DYNARRAY_DESTROY(collision_result);
return 1;
}
}
gim_trimesh_unlocks_work_data(trimesh);
GIM_DYNARRAY_DESTROY(collision_result);
return 0;//no collisiion
}
//! Trimesh Ray Collisions closest
/*!
Find the closest primitive collided by the ray
\param trimesh
\param contact
\return 1 if the ray collides, else 0
*/
int gim_trimesh_ray_closest_collision(GIM_TRIMESH * trimesh,vec3f origin,vec3f dir, GREAL tmax, GIM_TRIANGLE_RAY_CONTACT_DATA * contact)
{
GDYNAMIC_ARRAY collision_result;
GIM_CREATE_BOXQUERY_LIST(collision_result);
if(trimesh->m_aabbset)
{
gim_aabbset_ray_collision(origin,dir,tmax,trimesh->m_aabbset,
&collision_result);
}
else if(gim_trimesh_get_bound_method(trimesh)==G_TRIMESH_BOUND_AABB_TREE)
{
vec3f torigin, tdir;
gim_trimesh_data_get(trimesh->m_trimesh_data_handle,
&trimesh->m_unlocked_trimesh_data);
MAT_DOT_VEC_3X4(torigin,trimesh->m_inv_transform,dir);
MAT_DOT_VEC_3X3(tdir,trimesh->m_inv_transform,dir);
gim_aabbtree_ray_collision(
torigin,tdir, tmax,
&trimesh->m_unlocked_trimesh_data->m_bv_tree, &collision_result);
trimesh->m_unlocked_trimesh_data = 0;
}
if(collision_result.m_size==0)
{
GIM_DYNARRAY_DESTROY(collision_result);
return 0;
}
//collide triangles
GUINT * boxesresult = GIM_DYNARRAY_POINTER(GUINT,collision_result);
GIM_TRIANGLE_DATA tridata;
vec3f pout;
GREAL tparam,u,v;
char does_intersect;
contact->tparam = tmax + 0.1f;
gim_trimesh_locks_work_data(trimesh);
for(unsigned int i=0;i<collision_result.m_size;i++)
{
gim_trimesh_get_triangle_data(trimesh,boxesresult[i],&tridata);
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);
if(does_intersect && (tparam < contact->tparam))
{
contact->tparam = tparam;
contact->u = u;
contact->v = v;
contact->m_face_id = boxesresult[i];
VEC_COPY(contact->m_point,pout);
VEC_COPY(contact->m_normal,tridata.m_planes.m_planes[0]);
}
}
gim_trimesh_unlocks_work_data(trimesh);
GIM_DYNARRAY_DESTROY(collision_result);
if(contact->tparam > tmax) return 0;
return 1;
}

View File

@ -1,198 +0,0 @@
/*
-----------------------------------------------------------------------------
This source file is part of GIMPACT Library.
For the latest info, see http://gimpact.sourceforge.net/
Copyright (c) 2006 Francisco Leon Najera. C.C. 80087371.
email: projectileman@yahoo.com
This library is free software; you can redistribute it and/or
modify it under the terms of EITHER:
(1) The GNU Lesser General Public License as published by the Free
Software Foundation; either version 2.1 of the License, or (at
your option) any later version. The text of the GNU Lesser
General Public License is included with this library in the
file GIMPACT-LICENSE-LGPL.TXT.
(2) The BSD-style license that is included with this library in
the file GIMPACT-LICENSE-BSD.TXT.
(3) The zlib/libpng license that is included with this library in
the file GIMPACT-LICENSE-ZLIB.TXT.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files
GIMPACT-LICENSE-LGPL.TXT, GIMPACT-LICENSE-ZLIB.TXT and GIMPACT-LICENSE-BSD.TXT for more details.
-----------------------------------------------------------------------------
*/
#include "GIMPACT/gim_trimesh.h"
int gim_triangle_sphere_collision(
GIM_TRIANGLE_DATA *tri,
vec3f center, GREAL radius,
GIM_TRIANGLE_CONTACT_DATA * contact_data)
{
contact_data->m_point_count = 0;
//Find Face plane distance
GREAL dis = DISTANCE_PLANE_POINT(tri->m_planes.m_planes[0],center);
if(dis>radius) return 0; //out
if(dis<-radius) return 0;//Out of triangle
contact_data->m_penetration_depth = dis;
//Find the most edge
GUINT most_edge = 4;//no edge
GREAL max_dis = 0.0f;
dis = DISTANCE_PLANE_POINT(tri->m_planes.m_planes[1],center);
if(dis>radius) return 0;//Out of triangle
if(dis>0.0f)
{
max_dis = dis;
most_edge = 0;
}
dis = DISTANCE_PLANE_POINT(tri->m_planes.m_planes[2],center);
if(dis>radius) return 0;//Out of triangle
if(dis>max_dis)// && dis>0.0f)
{
max_dis = dis;
most_edge = 1;
}
dis = DISTANCE_PLANE_POINT(tri->m_planes.m_planes[3],center);
if(dis>radius) return 0;//Out of triangle
if(dis>max_dis)// && dis>0.0f)
{
max_dis = dis;
most_edge = 2;
}
if(most_edge == 4) //Box is into triangle
{
//contact_data->m_penetration_depth = dis is set above
//Find Face plane point
VEC_COPY(contact_data->m_separating_normal,tri->m_planes.m_planes[0]);
//Find point projection on plane
if(contact_data->m_penetration_depth>=0.0f)
{
VEC_SCALE(contact_data->m_points[0],-radius,contact_data->m_separating_normal);
}
else
{
VEC_SCALE(contact_data->m_points[0],radius,contact_data->m_separating_normal);
}
contact_data->m_penetration_depth = radius - contact_data->m_penetration_depth;
VEC_SUM(contact_data->m_points[0],contact_data->m_points[0],center);
//Scale normal for pointing to triangle
VEC_SCALE(contact_data->m_separating_normal,-1.0f,contact_data->m_separating_normal);
contact_data->m_point_count = 1;
return 1;
}
//find the edge
vec3f e1,e2;
VEC_COPY(e1,tri->m_vertices[most_edge]);
VEC_COPY(e2,tri->m_vertices[(most_edge+1)%3]);
CLOSEST_POINT_ON_SEGMENT(contact_data->m_points[0],center,e1,e2);
//find distance
VEC_DIFF(e1,center,contact_data->m_points[0]);
VEC_LENGTH(e1,dis);
if(dis>radius) return 0;
contact_data->m_penetration_depth = radius - dis;
if(GIM_IS_ZERO(dis))
{
VEC_COPY(contact_data->m_separating_normal,tri->m_planes.m_planes[most_edge+1]);
VEC_SCALE(contact_data->m_points[0],-radius,contact_data->m_separating_normal);
VEC_SUM(contact_data->m_points[0],contact_data->m_points[0],center);
}
else
{
VEC_SCALE(contact_data->m_separating_normal,1.0f/dis,e1);
VEC_SCALE(contact_data->m_points[0],-radius,contact_data->m_separating_normal);
VEC_SUM(contact_data->m_points[0],contact_data->m_points[0],center);
}
//Scale normal for pointing to triangle
VEC_SCALE(contact_data->m_separating_normal,-1.0f,contact_data->m_separating_normal);
contact_data->m_point_count = 1;
return 1;
}
//! Trimesh Sphere Collisions
/*!
In each contact
<ul>
<li> m_handle1 points to trimesh.
<li> m_handle2 points to NULL.
<li> m_feature1 Is a triangle index of trimesh.
</ul>
\param trimesh
\param center
\param radius
\param contacts A GIM_CONTACT array. Must be initialized
*/
void gim_trimesh_sphere_collision(GIM_TRIMESH * trimesh,vec3f center,GREAL radius, GDYNAMIC_ARRAY * contacts)
{
contacts->m_size = 0;
aabb3f test_aabb;
test_aabb.minX = center[0]-radius;
test_aabb.maxX = center[0]+radius;
test_aabb.minY = center[1]-radius;
test_aabb.maxY = center[1]+radius;
test_aabb.minZ = center[2]-radius;
test_aabb.maxZ = center[2]+radius;
GDYNAMIC_ARRAY collision_result;
GIM_CREATE_BOXQUERY_LIST(collision_result);
gim_trimesh_midphase_box_collision(trimesh,&test_aabb,&collision_result);
if(collision_result.m_size==0)
{
GIM_DYNARRAY_DESTROY(collision_result);
}
//collide triangles
//Locks trimesh
gim_trimesh_locks_work_data(trimesh);
//dummy contacts
GDYNAMIC_ARRAY dummycontacts;
GIM_CREATE_CONTACT_LIST(dummycontacts);
int cresult;
unsigned int i;
GUINT * boxesresult = GIM_DYNARRAY_POINTER(GUINT,collision_result);
GIM_TRIANGLE_CONTACT_DATA tri_contact_data;
GIM_TRIANGLE_DATA tri_data;
for(i=0;i<collision_result.m_size;i++)
{
gim_trimesh_get_triangle_data(trimesh,boxesresult[i],&tri_data);
cresult = gim_triangle_sphere_collision(&tri_data,center,radius,&tri_contact_data);
if(cresult!=0)
{
GIM_PUSH_CONTACT(dummycontacts, tri_contact_data.m_points[0],tri_contact_data.m_separating_normal ,tri_contact_data.m_penetration_depth,trimesh, 0, boxesresult[i],0);
}
}
///unlocks
gim_trimesh_unlocks_work_data(trimesh);
///Destroy box result
GIM_DYNARRAY_DESTROY(collision_result);
//merge contacts
gim_merge_contacts(&dummycontacts,contacts);
//Destroy dummy
GIM_DYNARRAY_DESTROY(dummycontacts);
}

View File

@ -1,457 +0,0 @@
/*
-----------------------------------------------------------------------------
This source file is part of GIMPACT Library.
For the latest info, see http://gimpact.sourceforge.net/
Copyright (c) 2006 Francisco Leon Najera. C.C. 80087371.
email: projectileman@yahoo.com
This library is free software; you can redistribute it and/or
modify it under the terms of EITHER:
(1) The GNU Lesser General Public License as published by the Free
Software Foundation; either version 2.1 of the License, or (at
your option) any later version. The text of the GNU Lesser
General Public License is included with this library in the
file GIMPACT-LICENSE-LGPL.TXT.
(2) The BSD-style license that is included with this library in
the file GIMPACT-LICENSE-BSD.TXT.
(3) The zlib/libpng license that is included with this library in
the file GIMPACT-LICENSE-ZLIB.TXT.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files
GIMPACT-LICENSE-LGPL.TXT, GIMPACT-LICENSE-ZLIB.TXT and GIMPACT-LICENSE-BSD.TXT for more details.
-----------------------------------------------------------------------------
*/
#include "GIMPACT/gim_trimesh.h"
#define CLASSIFY_TRI_BY_FACE(v1,v2,v3,faceplane,out_of_face)\
{ \
_distances[0] = DISTANCE_PLANE_POINT(faceplane,v1);\
_distances[1] = _distances[0] * DISTANCE_PLANE_POINT(faceplane,v2);\
_distances[2] = _distances[0] * DISTANCE_PLANE_POINT(faceplane,v3); \
if(_distances[1]<=0.0f || _distances[2]<=0.0f)\
{\
out_of_face = 0;\
}\
else\
{\
out_of_face = 1;\
}\
}\
#define CLASSIFY_TRI_BY_PLANE(v1,v2,v3,faceplane,out_of_face)\
{ \
if(DISTANCE_PLANE_POINT(faceplane,v1)<=0.0f)\
{\
out_of_face = 0;\
}\
else if(DISTANCE_PLANE_POINT(faceplane,v2)<=0.0f)\
{\
out_of_face = 0;\
}\
else if(DISTANCE_PLANE_POINT(faceplane,v3)<=0.0f)\
{\
out_of_face = 0;\
}\
else\
{\
out_of_face = 1;\
}\
}\
//! Receives the 3 edge planes
#define MOST_DEEP_POINTS(plane,points,point_count,deep_points,deep_points_count,maxdeep)\
{\
maxdeep=-1000.0f;\
GUINT _k;\
GREAL _dist;\
deep_points_count = 0;\
for(_k=0;_k<point_count;_k++)\
{\
_dist = -DISTANCE_PLANE_POINT(plane,points[_k]);\
if(_dist>maxdeep)\
{\
maxdeep = _dist;\
_max_candidates[0] = _k;\
deep_points_count=1;\
}\
else if((_dist+G_EPSILON)>=maxdeep)\
{\
_max_candidates[deep_points_count] = _k;\
deep_points_count++;\
}\
}\
if(maxdeep<0.0f)\
{\
deep_points_count = 0;\
}\
else\
{\
for(_k=0;_k<deep_points_count;_k++)\
{\
VEC_COPY(deep_points[_k],points[_max_candidates[_k]]);\
}\
}\
}\
//! Receives the 3 edge planes
#define CLIP_TRI_POINTS_BY_TRI_EDGE_PLANES(tri_points,tri_edge_planes, clipped_points, clipped_point_count)\
{\
clipped_point_count = 0; \
_temp_clip_count = 0;\
PLANE_CLIP_POLYGON(tri_edge_planes[0],tri_points,3,_temp_clip,_temp_clip_count,MAX_TRI_CLIPPING);\
if(_temp_clip_count>0)\
{\
_temp_clip_count2 = 0;\
PLANE_CLIP_POLYGON(tri_edge_planes[1],_temp_clip,_temp_clip_count,_temp_clip2,_temp_clip_count2,MAX_TRI_CLIPPING);\
if(_temp_clip_count2>0)\
{\
PLANE_CLIP_POLYGON(tri_edge_planes[2],_temp_clip2,_temp_clip_count2,clipped_points,clipped_point_count,MAX_TRI_CLIPPING);\
}\
}\
}\
static int _gim_triangle_triangle_collision(
GIM_TRIANGLE_DATA *tri1,
GIM_TRIANGLE_DATA *tri2,
GIM_TRIANGLE_CONTACT_DATA * contact_data)
{
//Cache variables for triangle intersection
GUINT _max_candidates[MAX_TRI_CLIPPING];
vec3f _temp_clip[MAX_TRI_CLIPPING];
GUINT _temp_clip_count = 0;
vec3f _temp_clip2[MAX_TRI_CLIPPING];
GUINT _temp_clip_count2 = 0;
vec3f clipped_points2[MAX_TRI_CLIPPING];
vec3f deep_points2[MAX_TRI_CLIPPING];
vec3f clipped_points1[MAX_TRI_CLIPPING];
vec3f deep_points1[MAX_TRI_CLIPPING];
//State variabnles
GUINT mostdir=0;
GUINT clipped2_count=0;
//Clip tri2 by tri1 edges
CLIP_TRI_POINTS_BY_TRI_EDGE_PLANES(tri2->m_vertices,(&tri1->m_planes.m_planes[1]), clipped_points2, clipped2_count);
if(clipped2_count == 0 )
{
return 0;//Reject
}
//find most deep interval face1
GUINT deep2_count=0;
GREAL maxdeep;
MOST_DEEP_POINTS((tri1->m_planes.m_planes[0]), clipped_points2, clipped2_count, deep_points2, deep2_count, maxdeep);
if(deep2_count==0)
{
// *perror = 0.0f;
return 0;//Reject
}
//Normal pointing to triangle1
VEC_SCALE(contact_data->m_separating_normal,-1.0f,(tri1->m_planes.m_planes[0]));
//Clip tri1 by tri2 edges
GUINT clipped1_count=0;
CLIP_TRI_POINTS_BY_TRI_EDGE_PLANES(tri1->m_vertices,(&tri2->m_planes.m_planes[1]), clipped_points1, clipped1_count);
if(clipped2_count == 0 )
{
// *perror = 0.0f;
return 0;//Reject
}
//find interval face2
GUINT deep1_count=0;
GREAL dist;
MOST_DEEP_POINTS((tri2->m_planes.m_planes[0]), clipped_points1, clipped1_count, deep_points1, deep1_count, dist);
if(deep1_count==0)
{
// *perror = 0.0f;
return 0;
}
if(dist<maxdeep)
{
maxdeep = dist;
mostdir = 1;
VEC_COPY(contact_data->m_separating_normal,(tri2->m_planes.m_planes[0]));
}
//set deep
contact_data->m_penetration_depth = maxdeep;
////check most dir for contacts
if(mostdir==0)
{
contact_data->m_point_count = deep2_count;
for(mostdir=0;mostdir<deep2_count;mostdir++)
{
VEC_COPY(contact_data->m_points[mostdir] ,deep_points2[mostdir]);
}
}
else
{
contact_data->m_point_count = deep1_count;
for(mostdir=0;mostdir<deep1_count;mostdir++)
{
VEC_COPY(contact_data->m_points[mostdir] ,deep_points1[mostdir]);
}
}
return 1;
}
//! Finds the contact points from a collision of two triangles
/*!
Returns the contact points, the penetration depth and the separating normal of the collision
between two triangles. The normal is pointing toward triangle 1 from triangle 2
*/
int gim_triangle_triangle_collision(
GIM_TRIANGLE_DATA *tri1,
GIM_TRIANGLE_DATA *tri2,
GIM_TRIANGLE_CONTACT_DATA * contact_data)
{
vec3f _distances;
char out_of_face=0;
if(tri2->m_has_planes==0)
{
TRIANGLE_PLANE(tri2->m_vertices[0],
tri2->m_vertices[1],tri2->m_vertices[2],tri2->m_planes.m_planes[0]);
}
//Fast overlapp
CLASSIFY_TRI_BY_FACE(tri1->m_vertices[0],tri1->m_vertices[1],tri1->m_vertices[2],tri2->m_planes.m_planes[0],out_of_face);
if(out_of_face==1) return 0;
if(tri1->m_has_planes==0)
{
TRIANGLE_PLANE(tri1->m_vertices[0],tri1->m_vertices[1],
tri1->m_vertices[2],tri1->m_planes.m_planes[0]);
}
//Fast overlapp
CLASSIFY_TRI_BY_FACE(tri2->m_vertices[0],tri2->m_vertices[1],tri2->m_vertices[2],tri1->m_planes.m_planes[0],out_of_face);
if(out_of_face==1) return 0;
/*
if(tri1->m_has_planes==0)
{
EDGE_PLANE(tri1->m_vertices[0],tri1->m_vertices[1],
(tri1->m_planes.m_planes[0]),(tri1->m_planes.m_planes[1]));
}
//Fast overlapp
CLASSIFY_TRI_BY_PLANE(tri2->m_vertices[0],tri2->m_vertices[1],tri2->m_vertices[2],tri1->m_planes.m_planes[1],out_of_face);
if(out_of_face==1) return 0;
if(tri1->m_has_planes==0)
{
EDGE_PLANE(tri1->m_vertices[1],tri1->m_vertices[2],
(tri1->m_planes.m_planes[0]),(tri1->m_planes.m_planes[2]));
}
//Fast overlapp
CLASSIFY_TRI_BY_PLANE(tri2->m_vertices[0],tri2->m_vertices[1],tri2->m_vertices[2],tri1->m_planes.m_planes[2],out_of_face);
if(out_of_face==1) return 0;
if(tri1->m_has_planes==0)
{
EDGE_PLANE(tri1->m_vertices[2],tri1->m_vertices[0],
(tri1->m_planes.m_planes[0]),(tri1->m_planes.m_planes[3]));
}
//Fast overlapp
CLASSIFY_TRI_BY_PLANE(tri2->m_vertices[0],tri2->m_vertices[1],tri2->m_vertices[2],tri1->m_planes.m_planes[3],out_of_face);
if(out_of_face==1) return 0;
if(tri2->m_has_planes==0)
{
EDGE_PLANE(tri2->m_vertices[0],tri2->m_vertices[1],
(tri2->m_planes.m_planes[0]),(tri2->m_planes.m_planes[1]));
EDGE_PLANE(tri2->m_vertices[1],tri2->m_vertices[2],
(tri2->m_planes.m_planes[0]),(tri2->m_planes.m_planes[2]));
EDGE_PLANE(tri2->m_vertices[2],tri2->m_vertices[0],
(tri2->m_planes.m_planes[0]),(tri2->m_planes.m_planes[3]));
}*/
if(tri1->m_has_planes==0)
{
EDGE_PLANE(tri1->m_vertices[0],tri1->m_vertices[1],
(tri1->m_planes.m_planes[0]),(tri1->m_planes.m_planes[1]));
EDGE_PLANE(tri1->m_vertices[1],tri1->m_vertices[2],
(tri1->m_planes.m_planes[0]),(tri1->m_planes.m_planes[2]));
EDGE_PLANE(tri1->m_vertices[2],tri1->m_vertices[0],
(tri1->m_planes.m_planes[0]),(tri1->m_planes.m_planes[3]));
}
if(tri2->m_has_planes==0)
{
EDGE_PLANE(tri2->m_vertices[0],tri2->m_vertices[1],
(tri2->m_planes.m_planes[0]),(tri2->m_planes.m_planes[1]));
EDGE_PLANE(tri2->m_vertices[1],tri2->m_vertices[2],
(tri2->m_planes.m_planes[0]),(tri2->m_planes.m_planes[2]));
EDGE_PLANE(tri2->m_vertices[2],tri2->m_vertices[0],
(tri2->m_planes.m_planes[0]),(tri2->m_planes.m_planes[3]));
}
return _gim_triangle_triangle_collision(tri1,tri2,contact_data);
}
//! Trimesh Trimesh Collisions
/*!
In each contact
<ul>
<li> m_handle1 points to trimesh1.
<li> m_handle2 points to trimesh2.
<li> m_feature1 Is a triangle index of trimesh1.
<li> m_feature2 Is a triangle index of trimesh2.
</ul>
\param trimesh1 Collider
\param trimesh2 Collidee
\param contacts A GIM_CONTACT array. Must be initialized
*/
void gim_trimesh_trimesh_collision(GIM_TRIMESH * trimesh1, GIM_TRIMESH * trimesh2, GDYNAMIC_ARRAY * contacts)
{
contacts->m_size = 0;
GDYNAMIC_ARRAY collision_pairs;
GIM_CREATE_PAIR_SET(collision_pairs);
char swaped;
gim_trimesh_midphase_trimesh_collision(trimesh1,trimesh2,&collision_pairs,&swaped);
if(collision_pairs.m_size==0)
{
GIM_DYNARRAY_DESTROY(collision_pairs);
return; //no collisioin
}
//Locks meshes
gim_trimesh_locks_work_data(trimesh1);
gim_trimesh_locks_work_data(trimesh2);
//pair pointer
GUINT *pairs = GIM_DYNARRAY_POINTER(GUINT,collision_pairs);
//dummy contacts
GDYNAMIC_ARRAY dummycontacts;
GIM_CREATE_CONTACT_LIST(dummycontacts);
//Auxiliary triangle data
GIM_TRIANGLE_CONTACT_DATA tri_contact_data;
GIM_TRIANGLE_DATA tri1data,tri2data;
GUINT i, ti1,ti2,ci;
int colresult;
for (i=0;i<collision_pairs.m_size; i++)
{
ti1 = pairs[i*2 + swaped]; // m_index1
ti2 = pairs[i*2 + (!swaped) ]; // m_index2
//Get triangles data
gim_trimesh_get_triangle_data_lazy(trimesh1,ti1,&tri1data);
gim_trimesh_get_triangle_data_lazy(trimesh2,ti2,&tri2data);
//collide triangles
colresult = gim_triangle_triangle_collision(&tri1data,&tri2data,&tri_contact_data);
if(colresult == 1)
{
//Add contacts
for (ci=0;ci<tri_contact_data.m_point_count ;ci++ )
{
GIM_PUSH_CONTACT(dummycontacts, tri_contact_data.m_points[ci],tri_contact_data.m_separating_normal ,tri_contact_data.m_penetration_depth,trimesh1, trimesh2, ti1, ti2);
}
}
}
if(dummycontacts.m_size == 0) //reject
{
//Unlocks meshes
gim_trimesh_unlocks_work_data(trimesh1);
gim_trimesh_unlocks_work_data(trimesh2);
GIM_DYNARRAY_DESTROY(dummycontacts);
GIM_DYNARRAY_DESTROY(collision_pairs);
return;
}
//merge contacts
gim_merge_contacts(&dummycontacts,contacts);
//Terminate
GIM_DYNARRAY_DESTROY(dummycontacts);
GIM_DYNARRAY_DESTROY(collision_pairs);
//Unlocks meshes
gim_trimesh_unlocks_work_data(trimesh1);
gim_trimesh_unlocks_work_data(trimesh2);
}
//! Trimesh Plane Collisions
/*!
\param trimesh
\param plane vec4f plane
\param contacts A vec4f array. Must be initialized (~100). Each element have the coordinate point in the first 3 elements, and vec4f[3] has the penetration depth.
*/
void gim_trimesh_plane_collision(GIM_TRIMESH * trimesh,vec4f plane, GDYNAMIC_ARRAY * contacts)
{
contacts->m_size = 0;
char classify;
aabb3f bound;
gim_trimesh_get_aabb(trimesh,&bound);
PLANE_CLASSIFY_BOX(plane,bound,classify);
if(classify>1) return; // in front of plane
//Locks mesh
gim_trimesh_locks_work_data(trimesh);
//Get vertices
GUINT i, vertcount = gim_trimesh_get_vertex_count(trimesh);
vec3f vec;
GREAL dist;
vec4f * result_contact;
for (i=0;i<vertcount;i++)
{
gim_trimesh_get_vertex(trimesh,i,vec);
dist = DISTANCE_PLANE_POINT(plane,vec);
if(dist<=0.0f)
{
GIM_DYNARRAY_PUSH_EMPTY(vec4f,(*contacts));
result_contact = GIM_DYNARRAY_POINTER_LAST(vec4f,(*contacts));
VEC_COPY((*result_contact),vec);
(*result_contact)[3] = -dist;
}
}
gim_trimesh_unlocks_work_data(trimesh);
}

View File

@ -1,56 +0,0 @@
/*
-----------------------------------------------------------------------------
This source file is part of GIMPACT Library.
For the latest info, see http://gimpact.sourceforge.net/
Copyright (c) 2006 Francisco Leon Najera. C.C. 80087371.
email: projectileman@yahoo.com
This library is free software; you can redistribute it and/or
modify it under the terms of EITHER:
(1) The GNU Lesser General Public License as published by the Free
Software Foundation; either version 2.1 of the License, or (at
your option) any later version. The text of the GNU Lesser
General Public License is included with this library in the
file GIMPACT-LICENSE-LGPL.TXT.
(2) The BSD-style license that is included with this library in
the file GIMPACT-LICENSE-BSD.TXT.
(3) The zlib/libpng license that is included with this library in
the file GIMPACT-LICENSE-ZLIB.TXT.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files
GIMPACT-LICENSE-LGPL.TXT, GIMPACT-LICENSE-ZLIB.TXT and GIMPACT-LICENSE-BSD.TXT for more details.
-----------------------------------------------------------------------------
*/
#include "GIMPACT/gim_vertex_buffer_util.h"
void gim_create_common_vertex_buffer(GBUFFER_ARRAY * vertex_buffer,GUINT vertex_count)
{
gim_create_common_buffer(vertex_count*sizeof(vec3f), &vertex_buffer->m_buffer_id);
GIM_BUFFER_ARRAY_INIT_TYPE(vec3f,(*vertex_buffer),vertex_buffer->m_buffer_id,vertex_count);
}
void gim_copy_vertex_buffers(GBUFFER_ARRAY * source_vertex_buffer,GUINT source_scalar_type,GBUFFER_ARRAY * dest_vertex_buffer,GUINT dest_scalar_type)
{
GIM_PROCESS_VERTEX_BUFFER_ARRAY(0,(*source_vertex_buffer),(*dest_vertex_buffer),COPY_VEC3_KERNEL,source_scalar_type,dest_scalar_type);
}
void gim_transform_vertex_buffers(GBUFFER_ARRAY * source_vertex_buffer,GUINT source_scalar_type,GBUFFER_ARRAY * dest_vertex_buffer,GUINT dest_scalar_type, mat4f transform)
{
GIM_PROCESS_VERTEX_BUFFER_ARRAY(transform,(*source_vertex_buffer),(*dest_vertex_buffer),MULT_MAT_VEC4_KERNEL,source_scalar_type,dest_scalar_type);
}
void gim_process_vertex_buffers(GBUFFER_ARRAY * source_vertex_buffer,GUINT source_scalar_type,GBUFFER_ARRAY * dest_vertex_buffer,GUINT dest_scalar_type, void *uniform_data,gim_kernel_func kernel_func)
{
GIM_PROCESS_VERTEX_BUFFER_ARRAY(uniform_data,(*source_vertex_buffer),(*dest_vertex_buffer),kernel_func,source_scalar_type,dest_scalar_type);
}

View File

@ -1,43 +0,0 @@
/*
-----------------------------------------------------------------------------
This source file is part of GIMPACT Library.
For the latest info, see http://gimpact.sourceforge.net/
Copyright (c) 2006 Francisco Leon Najera. C.C. 80087371.
email: projectileman@yahoo.com
This library is free software; you can redistribute it and/or
modify it under the terms of EITHER:
(1) The GNU Lesser General Public License as published by the Free
Software Foundation; either version 2.1 of the License, or (at
your option) any later version. The text of the GNU Lesser
General Public License is included with this library in the
file GIMPACT-LICENSE-LGPL.TXT.
(2) The BSD-style license that is included with this library in
the file GIMPACT-LICENSE-BSD.TXT.
(3) The zlib/libpng license that is included with this library in
the file GIMPACT-LICENSE-ZLIB.TXT.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files
GIMPACT-LICENSE-LGPL.TXT, GIMPACT-LICENSE-ZLIB.TXT and GIMPACT-LICENSE-BSD.TXT for more details.
-----------------------------------------------------------------------------
*/
#include "GIMPACT/gimpact.h"
void gimpact_init()
{
gim_init_math();
gim_init_buffer_managers();
gim_trimesh_data_manager_init();
}
void gimpact_terminate()
{
gim_terminate_buffer_managers();
gim_trimesh_data_manager_end();
}