first commit

This commit is contained in:
2024-06-10 12:48:14 +03:00
commit d54c9805b3
1398 changed files with 739400 additions and 0 deletions

View File

@@ -0,0 +1,19 @@
noinst_LTLIBRARIES = libGIMPACT.la
AM_CPPFLAGS = -fno-strict-aliasing \
-I$(top_srcdir)/include \
-I$(top_builddir)/include \
-I$(top_srcdir)/ode/src \
-I$(top_srcdir)/GIMPACT/include
libGIMPACT_la_SOURCES = gim_boxpruning.cpp \
gim_contact.cpp \
gim_math.cpp \
gim_memory.cpp \
gim_tri_tri_overlap.cpp \
gim_trimesh.cpp \
gim_trimesh_capsule_collision.cpp \
gim_trimesh_ray_collision.cpp \
gim_trimesh_sphere_collision.cpp \
gim_trimesh_trimesh_collision.cpp \
gimpact.cpp

View File

@@ -0,0 +1,638 @@
# Makefile.in generated by automake 1.15 from Makefile.am.
# @configure_input@
# Copyright (C) 1994-2014 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
@SET_MAKE@
VPATH = @srcdir@
am__is_gnu_make = { \
if test -z '$(MAKELEVEL)'; then \
false; \
elif test -n '$(MAKE_HOST)'; then \
true; \
elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
true; \
else \
false; \
fi; \
}
am__make_running_with_option = \
case $${target_option-} in \
?) ;; \
*) echo "am__make_running_with_option: internal error: invalid" \
"target option '$${target_option-}' specified" >&2; \
exit 1;; \
esac; \
has_opt=no; \
sane_makeflags=$$MAKEFLAGS; \
if $(am__is_gnu_make); then \
sane_makeflags=$$MFLAGS; \
else \
case $$MAKEFLAGS in \
*\\[\ \ ]*) \
bs=\\; \
sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
| sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
esac; \
fi; \
skip_next=no; \
strip_trailopt () \
{ \
flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
}; \
for flg in $$sane_makeflags; do \
test $$skip_next = yes && { skip_next=no; continue; }; \
case $$flg in \
*=*|--*) continue;; \
-*I) strip_trailopt 'I'; skip_next=yes;; \
-*I?*) strip_trailopt 'I';; \
-*O) strip_trailopt 'O'; skip_next=yes;; \
-*O?*) strip_trailopt 'O';; \
-*l) strip_trailopt 'l'; skip_next=yes;; \
-*l?*) strip_trailopt 'l';; \
-[dEDm]) skip_next=yes;; \
-[JT]) skip_next=yes;; \
esac; \
case $$flg in \
*$$target_option*) has_opt=yes; break;; \
esac; \
done; \
test $$has_opt = yes
am__make_dryrun = (target_option=n; $(am__make_running_with_option))
am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
pkgdatadir = $(datadir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkglibexecdir = $(libexecdir)/@PACKAGE@
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
subdir = GIMPACT/src
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \
$(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
$(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
$(top_srcdir)/m4/pkg.m4 $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = $(top_builddir)/ode/src/config.h
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
LTLIBRARIES = $(noinst_LTLIBRARIES)
libGIMPACT_la_LIBADD =
am_libGIMPACT_la_OBJECTS = gim_boxpruning.lo gim_contact.lo \
gim_math.lo gim_memory.lo gim_tri_tri_overlap.lo \
gim_trimesh.lo gim_trimesh_capsule_collision.lo \
gim_trimesh_ray_collision.lo gim_trimesh_sphere_collision.lo \
gim_trimesh_trimesh_collision.lo gimpact.lo
libGIMPACT_la_OBJECTS = $(am_libGIMPACT_la_OBJECTS)
AM_V_lt = $(am__v_lt_@AM_V@)
am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
am__v_lt_0 = --silent
am__v_lt_1 =
AM_V_P = $(am__v_P_@AM_V@)
am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
am__v_P_0 = false
am__v_P_1 = :
AM_V_GEN = $(am__v_GEN_@AM_V@)
am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
am__v_GEN_0 = @echo " GEN " $@;
am__v_GEN_1 =
AM_V_at = $(am__v_at_@AM_V@)
am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
am__v_at_0 = @
am__v_at_1 =
DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/ode/src
depcomp = $(SHELL) $(top_srcdir)/depcomp
am__depfiles_maybe = depfiles
am__mv = mv -f
CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \
$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
$(AM_CXXFLAGS) $(CXXFLAGS)
AM_V_CXX = $(am__v_CXX_@AM_V@)
am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@)
am__v_CXX_0 = @echo " CXX " $@;
am__v_CXX_1 =
CXXLD = $(CXX)
CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
$(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
AM_V_CXXLD = $(am__v_CXXLD_@AM_V@)
am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@)
am__v_CXXLD_0 = @echo " CXXLD " $@;
am__v_CXXLD_1 =
SOURCES = $(libGIMPACT_la_SOURCES)
DIST_SOURCES = $(libGIMPACT_la_SOURCES)
am__can_run_installinfo = \
case $$AM_UPDATE_INFO_DIR in \
n|no|NO) false;; \
*) (install-info --version) >/dev/null 2>&1;; \
esac
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
# Read a list of newline-separated strings from the standard input,
# and print each of them once, without duplicates. Input order is
# *not* preserved.
am__uniquify_input = $(AWK) '\
BEGIN { nonempty = 0; } \
{ items[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in items) print i; }; } \
'
# Make sure the list of sources is unique. This is necessary because,
# e.g., the same source file might be shared among _SOURCES variables
# for different programs/libraries.
am__define_uniq_tagged_files = \
list='$(am__tagged_files)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | $(am__uniquify_input)`
ETAGS = etags
CTAGS = ctags
am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
ALLOCA = @ALLOCA@
AMTAR = @AMTAR@
AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
AR = @AR@
AS = @AS@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CCD_CFLAGS = @CCD_CFLAGS@
CCD_LIBS = @CCD_LIBS@
CFLAGS = @CFLAGS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CXX = @CXX@
CXXCPP = @CXXCPP@
CXXDEPMODE = @CXXDEPMODE@
CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
DLLTOOL = @DLLTOOL@
DOXYGEN = @DOXYGEN@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
EXTRA_LIBTOOL_LDFLAGS = @EXTRA_LIBTOOL_LDFLAGS@
FGREP = @FGREP@
GL_LIBS = @GL_LIBS@
GREP = @GREP@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LD = @LD@
LDFLAGS = @LDFLAGS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBSTDCXX = @LIBSTDCXX@
LIBTOOL = @LIBTOOL@
LIPO = @LIPO@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
MAKEINFO = @MAKEINFO@
MANIFEST_TOOL = @MANIFEST_TOOL@
MKDIR_P = @MKDIR_P@
NM = @NM@
NMEDIT = @NMEDIT@
OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
ODE_PRECISION = @ODE_PRECISION@
ODE_VERSION = @ODE_VERSION@
ODE_VERSION_INFO = @ODE_VERSION_INFO@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_URL = @PACKAGE_URL@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
PKG_CONFIG = @PKG_CONFIG@
PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
RANLIB = @RANLIB@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
VERSION = @VERSION@
WINDRES = @WINDRES@
X11_CFLAGS = @X11_CFLAGS@
X11_LIBS = @X11_LIBS@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
ac_ct_AR = @ac_ct_AR@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
ac_ct_WINDRES = @ac_ct_WINDRES@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
runstatedir = @runstatedir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
subdirs = @subdirs@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
noinst_LTLIBRARIES = libGIMPACT.la
AM_CPPFLAGS = -fno-strict-aliasing \
-I$(top_srcdir)/include \
-I$(top_builddir)/include \
-I$(top_srcdir)/ode/src \
-I$(top_srcdir)/GIMPACT/include
libGIMPACT_la_SOURCES = gim_boxpruning.cpp \
gim_contact.cpp \
gim_math.cpp \
gim_memory.cpp \
gim_tri_tri_overlap.cpp \
gim_trimesh.cpp \
gim_trimesh_capsule_collision.cpp \
gim_trimesh_ray_collision.cpp \
gim_trimesh_sphere_collision.cpp \
gim_trimesh_trimesh_collision.cpp \
gimpact.cpp
all: all-am
.SUFFIXES:
.SUFFIXES: .cpp .lo .o .obj
$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
&& { if test -f $@; then exit 0; else break; fi; }; \
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign GIMPACT/src/Makefile'; \
$(am__cd) $(top_srcdir) && \
$(AUTOMAKE) --foreign GIMPACT/src/Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
*) \
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
esac;
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(top_srcdir)/configure: $(am__configure_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(ACLOCAL_M4): $(am__aclocal_m4_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(am__aclocal_m4_deps):
clean-noinstLTLIBRARIES:
-test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
@list='$(noinst_LTLIBRARIES)'; \
locs=`for p in $$list; do echo $$p; done | \
sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
sort -u`; \
test -z "$$locs" || { \
echo rm -f $${locs}; \
rm -f $${locs}; \
}
libGIMPACT.la: $(libGIMPACT_la_OBJECTS) $(libGIMPACT_la_DEPENDENCIES) $(EXTRA_libGIMPACT_la_DEPENDENCIES)
$(AM_V_CXXLD)$(CXXLINK) $(libGIMPACT_la_OBJECTS) $(libGIMPACT_la_LIBADD) $(LIBS)
mostlyclean-compile:
-rm -f *.$(OBJEXT)
distclean-compile:
-rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gim_boxpruning.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gim_contact.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gim_math.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gim_memory.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gim_tri_tri_overlap.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gim_trimesh.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gim_trimesh_capsule_collision.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gim_trimesh_ray_collision.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gim_trimesh_sphere_collision.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gim_trimesh_trimesh_collision.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gimpact.Plo@am__quote@
.cpp.o:
@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $<
.cpp.obj:
@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
.cpp.lo:
@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LTCXXCOMPILE) -c -o $@ $<
mostlyclean-libtool:
-rm -f *.lo
clean-libtool:
-rm -rf .libs _libs
ID: $(am__tagged_files)
$(am__define_uniq_tagged_files); mkid -fID $$unique
tags: tags-am
TAGS: tags
tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
set x; \
here=`pwd`; \
$(am__define_uniq_tagged_files); \
shift; \
if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
test -n "$$unique" || unique=$$empty_fix; \
if test $$# -gt 0; then \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
"$$@" $$unique; \
else \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$unique; \
fi; \
fi
ctags: ctags-am
CTAGS: ctags
ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
$(am__define_uniq_tagged_files); \
test -z "$(CTAGS_ARGS)$$unique" \
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
$$unique
GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& $(am__cd) $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) "$$here"
cscopelist: cscopelist-am
cscopelist-am: $(am__tagged_files)
list='$(am__tagged_files)'; \
case "$(srcdir)" in \
[\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
*) sdir=$(subdir)/$(srcdir) ;; \
esac; \
for i in $$list; do \
if test -f "$$i"; then \
echo "$(subdir)/$$i"; \
else \
echo "$$sdir/$$i"; \
fi; \
done >> $(top_builddir)/cscope.files
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
distdir: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
list='$(DISTFILES)'; \
dist_files=`for file in $$list; do echo $$file; done | \
sed -e "s|^$$srcdirstrip/||;t" \
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
case $$dist_files in \
*/*) $(MKDIR_P) `echo "$$dist_files" | \
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
sort -u` ;; \
esac; \
for file in $$dist_files; do \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
if test -d $$d/$$file; then \
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
if test -d "$(distdir)/$$file"; then \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
else \
test -f "$(distdir)/$$file" \
|| cp -p $$d/$$file "$(distdir)/$$file" \
|| exit 1; \
fi; \
done
check-am: all-am
check: check-am
all-am: Makefile $(LTLIBRARIES)
installdirs:
install: install-am
install-exec: install-exec-am
install-data: install-data-am
uninstall: uninstall-am
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-am
install-strip:
if test -z '$(STRIP)'; then \
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
install; \
else \
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
"INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
fi
mostlyclean-generic:
clean-generic:
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
clean: clean-am
clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \
mostlyclean-am
distclean: distclean-am
-rm -rf ./$(DEPDIR)
-rm -f Makefile
distclean-am: clean-am distclean-compile distclean-generic \
distclean-tags
dvi: dvi-am
dvi-am:
html: html-am
html-am:
info: info-am
info-am:
install-data-am:
install-dvi: install-dvi-am
install-dvi-am:
install-exec-am:
install-html: install-html-am
install-html-am:
install-info: install-info-am
install-info-am:
install-man:
install-pdf: install-pdf-am
install-pdf-am:
install-ps: install-ps-am
install-ps-am:
installcheck-am:
maintainer-clean: maintainer-clean-am
-rm -rf ./$(DEPDIR)
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-am
mostlyclean-am: mostlyclean-compile mostlyclean-generic \
mostlyclean-libtool
pdf: pdf-am
pdf-am:
ps: ps-am
ps-am:
uninstall-am:
.MAKE: install-am install-strip
.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \
clean-libtool clean-noinstLTLIBRARIES cscopelist-am ctags \
ctags-am distclean distclean-compile distclean-generic \
distclean-libtool distclean-tags distdir dvi dvi-am html \
html-am info info-am install install-am install-data \
install-data-am install-dvi install-dvi-am install-exec \
install-exec-am install-html install-html-am install-info \
install-info-am install-man install-pdf install-pdf-am \
install-ps install-ps-am install-strip installcheck \
installcheck-am installdirs maintainer-clean \
maintainer-clean-generic mostlyclean mostlyclean-compile \
mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
tags tags-am uninstall uninstall-am
.PRECIOUS: Makefile
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:

View File

@@ -0,0 +1,519 @@
/*
-----------------------------------------------------------------------------
This source file is part of GIMPACT Library.
For the latest info, see http://gimpact.sourceforge.net/
Copyright (c) 2006 Francisco Leon. C.C. 80087371.
email: projectileman@yahoo.com
This library is free software; you can redistribute it and/or
modify it under the terms of EITHER:
(1) The GNU Lesser General Public License as published by the Free
Software Foundation; either version 2.1 of the License, or (at
your option) any later version. The text of the GNU Lesser
General Public License is included with this library in the
file GIMPACT-LICENSE-LGPL.TXT.
(2) The BSD-style license that is included with this library in
the file GIMPACT-LICENSE-BSD.TXT.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files
GIMPACT-LICENSE-LGPL.TXT and GIMPACT-LICENSE-BSD.TXT for more details.
-----------------------------------------------------------------------------
*/
#include "GIMPACT/gim_boxpruning.h"
//! Allocate memory for all aabb set.
void gim_aabbset_alloc(GIM_AABB_SET * aabbset, GUINT32 count)
{
aabbset->m_count = count;
aabbset->m_boxes = (aabb3f *)gim_alloc(sizeof(aabb3f)*count);
if(count<GIM_MIN_SORTED_BIPARTITE_PRUNING_BOXES)
{
aabbset->m_maxcoords = 0;
aabbset->m_sorted_mincoords = 0;
}
else
{
aabbset->m_maxcoords = (GUINT32 *)gim_alloc(sizeof(GUINT32)*aabbset->m_count );
aabbset->m_sorted_mincoords = (GIM_RSORT_TOKEN *)gim_alloc(sizeof(GIM_RSORT_TOKEN)*aabbset->m_count);
}
aabbset->m_shared = 0;
INVALIDATE_AABB(aabbset->m_global_bound);
}
//! Destroys the aabb set.
void gim_aabbset_destroy(GIM_AABB_SET * aabbset)
{
aabbset->m_count = 0;
if(aabbset->m_shared==0)
{
gim_free(aabbset->m_boxes,0);
gim_free(aabbset->m_maxcoords,0);
gim_free(aabbset->m_sorted_mincoords,0);
}
aabbset->m_boxes = 0;
aabbset->m_sorted_mincoords = 0;
aabbset->m_maxcoords = 0;
}
void gim_aabbset_calc_global_bound(GIM_AABB_SET * aabbset)
{
aabb3f * paabb = aabbset->m_boxes;
aabb3f * globalbox = &aabbset->m_global_bound;
AABB_COPY((*globalbox),(*paabb));
GUINT32 count = aabbset->m_count-1;
paabb++;
while(count)
{
MERGEBOXES(*globalbox,*paabb)
paabb++;
count--;
}
}
//! Sorts the boxes for box prunning.
/*!
1) find the integer representation of the aabb coords
2) Sorts the min coords
3) Calcs the global bound
\pre aabbset must be allocated. And the boxes must be already set.
\param aabbset
\param calc_global_bound If 1 , calcs the global bound
\post If aabbset->m_sorted_mincoords == 0, then it allocs the sorted coordinates
*/
void gim_aabbset_sort(GIM_AABB_SET * aabbset, char calc_global_bound)
{
if(aabbset->m_sorted_mincoords == 0)
{//allocate
aabbset->m_maxcoords = (GUINT32 *)gim_alloc(sizeof(GUINT32)*aabbset->m_count );
aabbset->m_sorted_mincoords = (GIM_RSORT_TOKEN *)gim_alloc(sizeof(GIM_RSORT_TOKEN)*aabbset->m_count);
}
GUINT32 i, count = aabbset->m_count;
aabb3f * paabb = aabbset->m_boxes;
GUINT32 * maxcoords = aabbset->m_maxcoords;
GIM_RSORT_TOKEN * sorted_tokens = aabbset->m_sorted_mincoords;
if(count<860)//Calibrated on a Pentium IV
{
//Sort by quick sort
//Calculate keys
for(i=0;i<count;i++)
{
GIM_CONVERT_VEC3F_GUINT_XZ_UPPER(paabb[i].maxX,paabb[i].maxZ,maxcoords[i]);
GIM_CONVERT_VEC3F_GUINT_XZ(paabb[i].minX,paabb[i].minZ,sorted_tokens[i].m_key);
sorted_tokens[i].m_value = i;
}
GIM_QUICK_SORT_ARRAY(GIM_RSORT_TOKEN , sorted_tokens, count, RSORT_TOKEN_COMPARATOR,GIM_DEF_EXCHANGE_MACRO);
}
else
{
//Sort by radix sort
GIM_RSORT_TOKEN * unsorted = (GIM_RSORT_TOKEN *)gim_alloc(sizeof(GIM_RSORT_TOKEN )*count);
//Calculate keys
for(i=0;i<count;i++)
{
GIM_CONVERT_VEC3F_GUINT_XZ_UPPER(paabb[i].maxX,paabb[i].maxZ,maxcoords[i]);
GIM_CONVERT_VEC3F_GUINT_XZ(paabb[i].minX,paabb[i].minZ,unsorted[i].m_key);
unsorted[i].m_value = i;
}
GIM_RADIX_SORT_RTOKENS(unsorted,sorted_tokens,count);
gim_free(unsorted,0);
}
if(calc_global_bound) gim_aabbset_calc_global_bound(aabbset);
}
//utility macros
/*#define PUSH_PAIR(i,j,pairset)\
{\
GIM_PAIR _pair={i,j};\
GIM_DYNARRAY_PUSH_ITEM(GIM_PAIR,pairset,_pair);\
}*/
#define PUSH_PAIR(i,j,pairset)\
{\
GIM_DYNARRAY_PUSH_EMPTY(GIM_PAIR,pairset);\
GIM_PAIR * _pair = GIM_DYNARRAY_POINTER(GIM_PAIR,pairset) + (pairset).m_size - 1;\
_pair->m_index1 = i;\
_pair->m_index2 = j;\
}
#define PUSH_PAIR_INV(i,j,pairset)\
{\
GIM_DYNARRAY_PUSH_EMPTY(GIM_PAIR,pairset);\
GIM_PAIR * _pair = GIM_DYNARRAY_POINTER(GIM_PAIR,pairset) + (pairset).m_size - 1;\
_pair->m_index1 = j;\
_pair->m_index2 = i;\
}
#define FIND_OVERLAPPING_FOWARD(\
curr_index,\
test_count,\
test_aabb,\
max_coord_uint,\
sorted_tokens,\
aabbarray,\
pairset,\
push_pair_macro)\
{\
GUINT32 _i = test_count;\
char _intersected;\
GIM_RSORT_TOKEN * _psorted_tokens = sorted_tokens;\
while(_i>0 && max_coord_uint >= _psorted_tokens->m_key)\
{\
AABBCOLLISION(_intersected,test_aabb,aabbarray[_psorted_tokens->m_value]);\
if(_intersected)\
{\
push_pair_macro(curr_index, _psorted_tokens->m_value,pairset);\
}\
_psorted_tokens++;\
_i--;\
}\
}
//! log(N) Complete box pruning. Returns a list of overlapping pairs of boxes, each box of the pair belongs to the same set.
/*!
\pre aabbset must be allocated and sorted, the boxes must be already set.
\param aabbset Must be sorted. Global bound isn't required
\param collision_pairs Array of GIM_PAIR elements. Must be initialized before (Reserve size ~ 100)
*/
void gim_aabbset_self_intersections_sorted(GIM_AABB_SET * aabbset, GDYNAMIC_ARRAY * collision_pairs)
{
collision_pairs->m_size = 0;
GUINT32 count = aabbset->m_count;
aabb3f * paabb = aabbset->m_boxes;
GUINT32 * maxcoords = aabbset->m_maxcoords;
GIM_RSORT_TOKEN * sorted_tokens = aabbset->m_sorted_mincoords;
aabb3f test_aabb;
while(count>1)
{
///current cache variables
GUINT32 curr_index = sorted_tokens->m_value;
GUINT32 max_coord_uint = maxcoords[curr_index];
AABB_COPY(test_aabb,paabb[curr_index]);
///next pairs
sorted_tokens++;
count--;
FIND_OVERLAPPING_FOWARD( curr_index, count, test_aabb, max_coord_uint, sorted_tokens , paabb, (*collision_pairs),PUSH_PAIR);
}
}
//! NxN Complete box pruning. Returns a list of overlapping pairs of boxes, each box of the pair belongs to the same set.
/*!
\pre aabbset must be allocated, the boxes must be already set.
\param aabbset Global bound isn't required. Doen't need to be sorted.
\param collision_pairs Array of GIM_PAIR elements. Must be initialized before (Reserve size ~ 100)
*/
void gim_aabbset_self_intersections_brute_force(GIM_AABB_SET * aabbset, GDYNAMIC_ARRAY * collision_pairs)
{
collision_pairs->m_size = 0;
GUINT32 i,j;
GUINT32 count = aabbset->m_count;
aabb3f * paabb = aabbset->m_boxes;
char intersected;
for (i=0;i< count-1 ;i++ )
{
for (j=i+1;j<count ;j++ )
{
AABBCOLLISION(intersected,paabb[i],paabb[j]);
if(intersected)
{
PUSH_PAIR(i,j,(*collision_pairs));
}
}
}
}
//! log(N) Bipartite box pruning. Returns a list of overlapping pairs of boxes, each box of the pair belongs to a different set.
/*!
\pre aabbset1 and aabbset2 must be allocated and sorted, the boxes must be already set.
\param aabbset1 Must be sorted, Global bound is required.
\param aabbset2 Must be sorted, Global bound is required.
\param collision_pairs Array of GIM_PAIR elements. Must be initialized before (Reserve size ~ 100)
*/
void gim_aabbset_bipartite_intersections_sorted(GIM_AABB_SET * aabbset1, GIM_AABB_SET * aabbset2, GDYNAMIC_ARRAY * collision_pairs)
{
char intersected;
collision_pairs->m_size = 0;
AABBCOLLISION(intersected,aabbset1->m_global_bound,aabbset2->m_global_bound);
if(intersected == 0) return;
GUINT32 count1 = aabbset1->m_count;
aabb3f * paabb1 = aabbset1->m_boxes;
GUINT32 * maxcoords1 = aabbset1->m_maxcoords;
GIM_RSORT_TOKEN * sorted_tokens1 = aabbset1->m_sorted_mincoords;
GUINT32 count2 = aabbset2->m_count;
aabb3f * paabb2 = aabbset2->m_boxes;
GUINT32 * maxcoords2 = aabbset2->m_maxcoords;
GIM_RSORT_TOKEN * sorted_tokens2 = aabbset2->m_sorted_mincoords;
GUINT32 curr_index;
GUINT32 max_coord_uint;
aabb3f test_aabb;
//Classify boxes
//Find Set intersection
aabb3f int_abbb;
BOXINTERSECTION(aabbset1->m_global_bound,aabbset2->m_global_bound, int_abbb);
//Clasify set 1
GIM_RSORT_TOKEN * classified_tokens1 = (GIM_RSORT_TOKEN *) gim_alloc(sizeof(GIM_RSORT_TOKEN)*count1);
GUINT32 i,classified_count1 = 0,classified_count2 = 0;
for (i=0;i<count1;i++ )
{
curr_index = sorted_tokens1[i].m_value;
AABBCOLLISION(intersected,paabb1[curr_index],int_abbb);
if(intersected)
{
classified_tokens1[classified_count1] = sorted_tokens1[i];
classified_count1++;
}
}
if(classified_count1==0)
{
gim_free(classified_tokens1 ,0);
return; // no pairs
}
//Clasify set 2
GIM_RSORT_TOKEN * classified_tokens2 = (GIM_RSORT_TOKEN *) gim_alloc(sizeof(GIM_RSORT_TOKEN)*count2);
for (i=0;i<count2;i++ )
{
curr_index = sorted_tokens2[i].m_value;
AABBCOLLISION(intersected,paabb2[curr_index],int_abbb);
if(intersected)
{
classified_tokens2[classified_count2] = sorted_tokens2[i];
classified_count2++;
}
}
if(classified_count2==0)
{
gim_free(classified_tokens1 ,0);
gim_free(classified_tokens2 ,0);
return; // no pairs
}
sorted_tokens1 = classified_tokens1;
sorted_tokens2 = classified_tokens2;
while(classified_count1>0&&classified_count2>0)
{
if(sorted_tokens1->m_key <= sorted_tokens2->m_key)
{
///current cache variables
curr_index = sorted_tokens1->m_value;
max_coord_uint = maxcoords1[curr_index];
AABB_COPY(test_aabb,paabb1[curr_index]);
///next pairs
sorted_tokens1++;
classified_count1--;
FIND_OVERLAPPING_FOWARD( curr_index, classified_count2, test_aabb, max_coord_uint, sorted_tokens2 , paabb2, (*collision_pairs), PUSH_PAIR);
}
else ///Switch test
{
///current cache variables
curr_index = sorted_tokens2->m_value;
max_coord_uint = maxcoords2[curr_index];
AABB_COPY(test_aabb,paabb2[curr_index]);
///next pairs
sorted_tokens2++;
classified_count2--;
FIND_OVERLAPPING_FOWARD( curr_index, classified_count1, test_aabb, max_coord_uint, sorted_tokens1 , paabb1, (*collision_pairs), PUSH_PAIR_INV );
}
}
gim_free(classified_tokens1 ,0);
gim_free(classified_tokens2 ,0);
}
//! NxM Bipartite box pruning. Returns a list of overlapping pairs of boxes, each box of the pair belongs to a different set.
/*!
\pre aabbset1 and aabbset2 must be allocated and sorted, the boxes must be already set.
\param aabbset1 Must be sorted, Global bound is required.
\param aabbset2 Must be sorted, Global bound is required.
\param collision_pairs Array of GIM_PAIR elements. Must be initialized before (Reserve size ~ 100)
*/
void gim_aabbset_bipartite_intersections_brute_force(GIM_AABB_SET * aabbset1,GIM_AABB_SET * aabbset2, GDYNAMIC_ARRAY * collision_pairs)
{
char intersected;
collision_pairs->m_size = 0;
AABBCOLLISION(intersected,aabbset1->m_global_bound,aabbset2->m_global_bound);
if(intersected == 0) return;
aabb3f int_abbb;
//Find Set intersection
BOXINTERSECTION(aabbset1->m_global_bound,aabbset2->m_global_bound, int_abbb);
//Clasify set 1
GUINT32 i,j;
GUINT32 classified_count = 0;
GUINT32 count = aabbset1->m_count;
aabb3f * paabb1 = aabbset1->m_boxes;
aabb3f * paabb2 = aabbset2->m_boxes;
GUINT32 * classified = (GUINT32 *) gim_alloc(sizeof(GUINT32)*count);
for (i=0;i<count;i++ )
{
AABBCOLLISION(intersected,paabb1[i],int_abbb);
if(intersected)
{
classified[classified_count] = i;
classified_count++;
}
}
if(classified_count==0)
{
gim_free(classified,0);
return; // no pairs
}
//intesect set2
count = aabbset2->m_count;
for (i=0;i<count;i++)
{
AABBCOLLISION(intersected,paabb2[i],int_abbb);
if(intersected)
{
for (j=0;j<classified_count;j++)
{
AABBCOLLISION(intersected,paabb2[i],paabb1[classified[j]]);
if(intersected)
{
PUSH_PAIR(classified[j],i,(*collision_pairs));
}
}
}
}
gim_free(classified,0);
}
//! Initalizes the set. Sort Boxes if needed.
/*!
\pre aabbset must be allocated. And the boxes must be already set.
\post If the set has less of GIM_MIN_SORTED_BIPARTITE_PRUNING_BOXES boxes, only calcs the global box,
else it Sorts the entire set( Only applicable for large sets)
*/
void gim_aabbset_update(GIM_AABB_SET * aabbset)
{
if(aabbset->m_count < GIM_MIN_SORTED_BIPARTITE_PRUNING_BOXES)
{//Brute force approach
gim_aabbset_calc_global_bound(aabbset);
}
else
{//Sorted force approach
gim_aabbset_sort(aabbset,1);
}
}
//! Complete box pruning. Returns a list of overlapping pairs of boxes, each box of the pair belongs to the same set.
/*!
This function sorts the set and then it calls to gim_aabbset_self_intersections_brute_force or gim_aabbset_self_intersections_sorted.
\param aabbset Set of boxes. Sorting isn't required.
\param collision_pairs Array of GIM_PAIR elements. Must be initialized before (Reserve size ~ 100)
\pre aabbset must be allocated and initialized.
\post If aabbset->m_count >= GIM_MIN_SORTED_PRUNING_BOXES, then it calls to gim_aabbset_sort and then to gim_aabbset_self_intersections_sorted.
*/
void gim_aabbset_self_intersections(GIM_AABB_SET * aabbset, GDYNAMIC_ARRAY * collision_pairs)
{
if(aabbset->m_count < GIM_MIN_SORTED_PRUNING_BOXES)
{//Brute force approach
gim_aabbset_self_intersections_brute_force(aabbset,collision_pairs);
}
else
{//Sorted force approach
gim_aabbset_sort(aabbset,0);
gim_aabbset_self_intersections_sorted(aabbset,collision_pairs);
}
}
//! Collides two sets. Returns a list of overlapping pairs of boxes, each box of the pair belongs to a different set.
/*!
\pre aabbset1 and aabbset2 must be allocated and updated. See .
\param aabbset1 Must be sorted, Global bound is required.
\param aabbset2 Must be sorted, Global bound is required.
\param collision_pairs Array of GIM_PAIR elements. Must be initialized before (Reserve size ~ 100)
*/
void gim_aabbset_bipartite_intersections(GIM_AABB_SET * aabbset1, GIM_AABB_SET * aabbset2, GDYNAMIC_ARRAY * collision_pairs)
{
if(aabbset1->m_sorted_mincoords == 0||aabbset2->m_sorted_mincoords == 0)
{//Brute force approach
gim_aabbset_bipartite_intersections_brute_force(aabbset1,aabbset2,collision_pairs);
}
else
{//Sorted force approach
gim_aabbset_bipartite_intersections_sorted(aabbset1,aabbset2,collision_pairs);
}
}
void gim_aabbset_box_collision(aabb3f *test_aabb, GIM_AABB_SET * aabbset, GDYNAMIC_ARRAY * collided)
{
collided->m_size = 0;
char intersected;
AABBCOLLISION(intersected,aabbset->m_global_bound,(*test_aabb));
if(intersected == 0) return;
GUINT32 i;
GUINT32 count = aabbset->m_count;
aabb3f * paabb = aabbset->m_boxes;
aabb3f _testaabb;
AABB_COPY(_testaabb,*test_aabb);
for (i=0;i< count;i++ )
{
AABBCOLLISION(intersected,paabb[i],_testaabb);
if(intersected)
{
GIM_DYNARRAY_PUSH_ITEM(GUINT32,(*collided),i);
}
}
}
void gim_aabbset_ray_collision(vec3f vorigin,vec3f vdir, GREAL tmax, GIM_AABB_SET * aabbset, GDYNAMIC_ARRAY * collided)
{
collided->m_size = 0;
char intersected;
GREAL tparam = 0;
BOX_INTERSECTS_RAY(aabbset->m_global_bound, vorigin, vdir, tparam, tmax,intersected);
if(intersected==0) return;
GUINT32 i;
GUINT32 count = aabbset->m_count;
aabb3f * paabb = aabbset->m_boxes;
for (i=0;i< count;i++ )
{
BOX_INTERSECTS_RAY(paabb[i], vorigin, vdir, tparam, tmax,intersected);
if(intersected)
{
GIM_DYNARRAY_PUSH_ITEM(GUINT32,(*collided),i);
}
}
(void)tparam;
}

View File

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

View File

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

View File

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

View File

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

View File

@@ -0,0 +1,391 @@
/*
-----------------------------------------------------------------------------
This source file is part of GIMPACT Library.
For the latest info, see http://gimpact.sourceforge.net/
Copyright (c) 2006 Francisco Leon. C.C. 80087371.
email: projectileman@yahoo.com
This library is free software; you can redistribute it and/or
modify it under the terms of EITHER:
(1) The GNU Lesser General Public License as published by the Free
Software Foundation; either version 2.1 of the License, or (at
your option) any later version. The text of the GNU Lesser
General Public License is included with this library in the
file GIMPACT-LICENSE-LGPL.TXT.
(2) The BSD-style license that is included with this library in
the file GIMPACT-LICENSE-BSD.TXT.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files
GIMPACT-LICENSE-LGPL.TXT and GIMPACT-LICENSE-BSD.TXT for more details.
-----------------------------------------------------------------------------
*/
#include <assert.h>
#include "GIMPACT/gim_trimesh.h"
GUINT32 gim_trimesh_get_triangle_count(GIM_TRIMESH * trimesh)
{
return trimesh->m_tri_index_buffer.m_element_count/3;
}
//! Creates the aabb set and the triangles cache
/*!
\param trimesh
\param vertex_array
\param triindex_array
\param transformed_reply If 1, then the m_transformed_vertices is a reply of the source vertices. Else it just is a reference to the original array.
\post it copies the arrays by reference, and creates the auxiliary data (m_aabbset,m_planes_cache_buffer)
*/
void gim_trimesh_create_from_arrays(GBUFFER_MANAGER_DATA buffer_managers[],
GIM_TRIMESH * trimesh, GBUFFER_ARRAY * vertex_array, GBUFFER_ARRAY * triindex_array,char transformed_reply)
{
assert(trimesh);
assert(vertex_array);
assert(triindex_array);
gim_buffer_array_copy_ref(vertex_array,&trimesh->m_source_vertex_buffer);
gim_buffer_array_copy_ref(triindex_array,&trimesh->m_tri_index_buffer);
trimesh->m_mask = GIM_TRIMESH_NEED_UPDATE;//needs update
//Create the transformed vertices
if(transformed_reply==1)
{
trimesh->m_mask |= GIM_TRIMESH_TRANSFORMED_REPLY;
gim_buffer_array_copy_value(vertex_array,
buffer_managers,&trimesh->m_transformed_vertex_buffer,G_BUFFER_MANAGER_SYSTEM,G_MU_DYNAMIC_READ_WRITE);
}
else
{
gim_buffer_array_copy_ref(vertex_array,&trimesh->m_transformed_vertex_buffer);
}
//create the box set
GUINT32 facecount = gim_trimesh_get_triangle_count(trimesh);
gim_aabbset_alloc(&trimesh->m_aabbset,facecount);
//create the planes cache
GIM_DYNARRAY_CREATE_SIZED(GIM_TRIPLANES_CACHE,trimesh->m_planes_cache_buffer,facecount);
//Create the bitset
GIM_BITSET_CREATE_SIZED(trimesh->m_planes_cache_bitset,facecount);
//Callback is 0
trimesh->m_update_callback = 0;
//set to identity
IDENTIFY_MATRIX_4X4(trimesh->m_transform);
}
//! Create a trimesh from vertex array and an index array
/*!
\param trimesh An uninitialized GIM_TRIMESH structure
\param vertex_array A buffer to a vec3f array
\param vertex_count
\param triindex_array
\param index_count
\param copy_vertices If 1, it copies the source vertices to another buffer. Else (0) it constructs a reference to the data.
\param copy_indices If 1, it copies the source vertices to another buffer. Else (0) it constructs a reference to the data.
\param transformed_reply If 1, then the m_transformed_vertices is a reply of the source vertices. Else (0) it just is a reference to the original array.
*/
void gim_trimesh_create_from_data(GBUFFER_MANAGER_DATA buffer_managers[],
GIM_TRIMESH * trimesh, vec3f * vertex_array, GUINT32 vertex_count,char copy_vertices,
GUINT32 * triindex_array, GUINT32 index_count,char copy_indices,char transformed_reply)
{
GBUFFER_ARRAY buffer_vertex_array;
GBUFFER_ARRAY buffer_triindex_array;
//Create vertices
if(copy_vertices == 1)
{
gim_create_common_buffer_from_data(buffer_managers,
vertex_array, vertex_count*sizeof(vec3f), &buffer_vertex_array.m_buffer_id);
}
else//Create a shared buffer
{
gim_create_shared_buffer_from_data(buffer_managers,
vertex_array, vertex_count*sizeof(vec3f), &buffer_vertex_array.m_buffer_id);
}
GIM_BUFFER_ARRAY_INIT_TYPE(vec3f,buffer_vertex_array,buffer_vertex_array.m_buffer_id,vertex_count);
//Create vertices
if(copy_indices == 1)
{
gim_create_common_buffer_from_data(buffer_managers,
triindex_array, index_count*sizeof(GUINT32), &buffer_triindex_array.m_buffer_id);
}
else//Create a shared buffer
{
gim_create_shared_buffer_from_data(buffer_managers,
triindex_array, index_count*sizeof(GUINT32), &buffer_triindex_array.m_buffer_id);
}
GIM_BUFFER_ARRAY_INIT_TYPE(GUINT32,buffer_triindex_array,buffer_triindex_array.m_buffer_id,index_count);
gim_trimesh_create_from_arrays(buffer_managers, trimesh,
&buffer_vertex_array, &buffer_triindex_array,transformed_reply);
///always call this after create a buffer_array
GIM_BUFFER_ARRAY_DESTROY(buffer_vertex_array);
GIM_BUFFER_ARRAY_DESTROY(buffer_triindex_array);
}
//! Clears auxiliary data and releases buffer arrays
void gim_trimesh_destroy(GIM_TRIMESH * trimesh)
{
gim_aabbset_destroy(&trimesh->m_aabbset);
GIM_DYNARRAY_DESTROY(trimesh->m_planes_cache_buffer);
GIM_DYNARRAY_DESTROY(trimesh->m_planes_cache_bitset);
GIM_BUFFER_ARRAY_DESTROY(trimesh->m_transformed_vertex_buffer);
GIM_BUFFER_ARRAY_DESTROY(trimesh->m_source_vertex_buffer);
GIM_BUFFER_ARRAY_DESTROY(trimesh->m_tri_index_buffer);
}
//! Copies two meshes
/*!
\pre dest_trimesh shouldn't be created
\post dest_trimesh will be created
\param source_trimesh
\param dest_trimesh
\param copy_by_reference If 1, it attaches a reference to the source vertices, else it copies the vertices
\param transformed_reply IF 1, then it forces the m_trasnformed_vertices to be a reply of the source vertices
*/
void gim_trimesh_copy(GIM_TRIMESH * source_trimesh,
GBUFFER_MANAGER_DATA dest_buffer_managers[], GIM_TRIMESH * dest_trimesh,
char copy_by_reference, char transformed_reply)
{
/* -- trimesh can not be copied by reference until GBUFFER_MANAGER_DATA is rewritten
to be thread safe and until it is moved back to global variables.
if(copy_by_reference==1)
{
gim_trimesh_create_from_arrays(dest_trimesh, &source_trimesh->m_source_vertex_buffer, &source_trimesh->m_tri_index_buffer,transformed_reply);
}
else
*/
{
GBUFFER_ARRAY buffer_vertex_array;
GBUFFER_ARRAY buffer_triindex_array;
gim_buffer_array_copy_value(&source_trimesh->m_source_vertex_buffer,
dest_buffer_managers,&buffer_vertex_array,G_BUFFER_MANAGER_SYSTEM,G_MU_DYNAMIC_READ_WRITE);
gim_buffer_array_copy_value(&source_trimesh->m_tri_index_buffer,
dest_buffer_managers,&buffer_triindex_array,G_BUFFER_MANAGER_SYSTEM,G_MU_DYNAMIC_READ_WRITE);
gim_trimesh_create_from_arrays(dest_buffer_managers, dest_trimesh,
&buffer_vertex_array, &buffer_triindex_array,transformed_reply);
///always call this after create a buffer_array
GIM_BUFFER_ARRAY_DESTROY(buffer_vertex_array);
GIM_BUFFER_ARRAY_DESTROY(buffer_triindex_array);
}
}
//! Locks the trimesh for working with it
/*!
\post locks m_tri_index_buffer and m_transformed_vertex_buffer.
\param trimesh
*/
void gim_trimesh_locks_work_data(GIM_TRIMESH * trimesh)
{
GINT32 res;
res=gim_buffer_array_lock(&trimesh->m_tri_index_buffer,G_MA_READ_ONLY);
assert(res==G_BUFFER_OP_SUCCESS);
res=gim_buffer_array_lock(&trimesh->m_transformed_vertex_buffer,G_MA_READ_ONLY);
assert(res==G_BUFFER_OP_SUCCESS);
}
//! unlocks the trimesh
/*!
\post unlocks m_tri_index_buffer and m_transformed_vertex_buffer.
\param trimesh
*/
void gim_trimesh_unlocks_work_data(GIM_TRIMESH * trimesh)
{
gim_buffer_array_unlock(&trimesh->m_tri_index_buffer);
gim_buffer_array_unlock(&trimesh->m_transformed_vertex_buffer);
}
//! Returns 1 if the m_transformed_vertex_buffer is a reply of m_source_vertex_buffer
char gim_trimesh_has_tranformed_reply(GIM_TRIMESH * trimesh)
{
if(trimesh->m_mask&GIM_TRIMESH_TRANSFORMED_REPLY) return 1;
return 0;
}
//! Returns 1 if the trimesh needs to update their aabbset and the planes cache.
char gim_trimesh_needs_update(GIM_TRIMESH * trimesh)
{
if(trimesh->m_mask&GIM_TRIMESH_NEED_UPDATE) return 1;
return 0;
}
//! Change the state of the trimesh for force it to update
/*!
Call it after having made changes to the trimesh.
\post gim_trimesh_need_update(trimesh) will return 1
*/
void gim_trimesh_post_update(GIM_TRIMESH * trimesh)
{
trimesh->m_mask |= GIM_TRIMESH_NEED_UPDATE;
}
//kernel
#define MULT_MAT_VEC4_KERNEL(_mat,_src,_dst) MAT_DOT_VEC_3X4((_dst),(_mat),(_src))
//! Updates m_transformed_vertex_buffer
/*!
\pre m_transformed_vertex_buffer must be unlocked
*/
void gim_trimesh_update_vertices(GIM_TRIMESH * trimesh)
{
if(gim_trimesh_has_tranformed_reply(trimesh) == 0) return; //Don't perform transformation
//Vertices
GBUFFER_ARRAY * psource_vertex_buffer = &trimesh->m_source_vertex_buffer;
GBUFFER_ARRAY * ptransformed_vertex_buffer = &trimesh->m_transformed_vertex_buffer;
//Temp transform
mat4f transform;
COPY_MATRIX_4X4(transform,trimesh->m_transform);
GIM_PROCESS_BUFFER_ARRAY(transform,(*psource_vertex_buffer),(*ptransformed_vertex_buffer),MULT_MAT_VEC4_KERNEL,vec3f,vec3f);
}
//! Updates m_aabbset and m_planes_cache_bitset
/*!
\pre gim_trimesh_locks_work_data must be called before
*/
void gim_trimesh_update_aabbset(GIM_TRIMESH * trimesh)
{
vec3f * transformed_vertices = GIM_BUFFER_ARRAY_POINTER(vec3f,trimesh->m_transformed_vertex_buffer,0);
assert(transformed_vertices);
GUINT32 * triangle_indices = GIM_BUFFER_ARRAY_POINTER(GUINT32,trimesh->m_tri_index_buffer,0);
assert(triangle_indices);
// box set
aabb3f * paabb = trimesh->m_aabbset.m_boxes;
GUINT32 triangle_count = gim_trimesh_get_triangle_count(trimesh);
float * v1,*v2,*v3;
GUINT32 i;
for (i=0; i<triangle_count;i++)
{
v1 = &transformed_vertices[triangle_indices[0]][0];
v2 = &transformed_vertices[triangle_indices[1]][0];
v3 = &transformed_vertices[triangle_indices[2]][0];
COMPUTEAABB_FOR_TRIANGLE((*paabb),v1,v2,v3);
triangle_indices+=3;
paabb++;
}
//Clear planes cache
GIM_BITSET_CLEAR_ALL(trimesh->m_planes_cache_bitset);
//Sorts set
gim_aabbset_update(&trimesh->m_aabbset);
}
//! Updates the trimesh if needed
/*!
\post If gim_trimesh_needs_update returns 1, then it calls gim_trimesh_update_vertices and gim_trimesh_update_aabbset
*/
void gim_trimesh_update(GIM_TRIMESH * trimesh)
{
if(gim_trimesh_needs_update(trimesh)==0) return;
gim_trimesh_update_vertices(trimesh);
gim_trimesh_locks_work_data(trimesh);
gim_trimesh_update_aabbset(trimesh);
gim_trimesh_unlocks_work_data(trimesh);
//Clear update flag
trimesh->m_mask &= ~GIM_TRIMESH_NEED_UPDATE;
}
void gim_trimesh_set_tranform(GIM_TRIMESH * trimesh, mat4f transform)
{
GREAL diff = 0.0f;
float * originaltrans = &trimesh->m_transform[0][0];
float * newtrans = &transform[0][0];
GUINT32 i;
for (i=0;i<16;i++)
{
diff += fabs(originaltrans[i]-newtrans[i]);
}
// if(IS_ZERO(diff)) return ;///don't need to update
if(diff< 0.00001f) return ;///don't need to update
COPY_MATRIX_4X4(trimesh->m_transform,transform);
gim_trimesh_post_update(trimesh);
}
void gim_trimesh_get_triangle_data(GIM_TRIMESH * trimesh, GUINT32 triangle_index, GIM_TRIANGLE_DATA * tri_data)
{
vec3f * transformed_vertices = GIM_BUFFER_ARRAY_POINTER(vec3f,trimesh->m_transformed_vertex_buffer,0);
GUINT32 * triangle_indices = GIM_BUFFER_ARRAY_POINTER(GUINT32,trimesh->m_tri_index_buffer,triangle_index*3);
//Copy the vertices
VEC_COPY(tri_data->m_vertices[0],transformed_vertices[triangle_indices[0]]);
VEC_COPY(tri_data->m_vertices[1],transformed_vertices[triangle_indices[1]]);
VEC_COPY(tri_data->m_vertices[2],transformed_vertices[triangle_indices[2]]);
//Get the planes
GIM_TRIPLANES_CACHE * planes = GIM_DYNARRAY_POINTER(GIM_TRIPLANES_CACHE,trimesh->m_planes_cache_buffer);
planes += triangle_index;
//verify planes cache
GUINT32 bit_eval;
GIM_BITSET_GET(trimesh->m_planes_cache_bitset,triangle_index,bit_eval);
if(bit_eval == 0)// Needs to calc the planes
{
//Calc the face plane
TRIANGLE_PLANE(tri_data->m_vertices[0],tri_data->m_vertices[1],tri_data->m_vertices[2],planes->m_planes[0]);
//Calc the edge 1
EDGE_PLANE(tri_data->m_vertices[0],tri_data->m_vertices[1],(planes->m_planes[0]),(planes->m_planes[1]));
//Calc the edge 2
EDGE_PLANE(tri_data->m_vertices[1],tri_data->m_vertices[2],(planes->m_planes[0]),(planes->m_planes[2]));
//Calc the edge 3
EDGE_PLANE(tri_data->m_vertices[2],tri_data->m_vertices[0],(planes->m_planes[0]), (planes->m_planes[3]));
//mark
GIM_BITSET_SET(trimesh->m_planes_cache_bitset,triangle_index);
}
VEC_COPY_4((tri_data->m_planes.m_planes[0]),(planes->m_planes[0]));//face plane
VEC_COPY_4((tri_data->m_planes.m_planes[1]),(planes->m_planes[1]));//edge1
VEC_COPY_4((tri_data->m_planes.m_planes[2]),(planes->m_planes[2]));//edge2
VEC_COPY_4((tri_data->m_planes.m_planes[3]),(planes->m_planes[3]));//edge3
}
void gim_trimesh_get_triangle_vertices(GIM_TRIMESH * trimesh, GUINT32 triangle_index, vec3f v1, vec3f v2, vec3f v3)
{
vec3f * transformed_vertices = GIM_BUFFER_ARRAY_POINTER(vec3f,trimesh->m_transformed_vertex_buffer,0);
GUINT32 * triangle_indices = GIM_BUFFER_ARRAY_POINTER(GUINT32,trimesh->m_tri_index_buffer,triangle_index*3);
//Copy the vertices
if (v1 != NULL)
{
VEC_COPY(v1,transformed_vertices[triangle_indices[0]]);
}
if (v2 != NULL)
{
VEC_COPY(v2,transformed_vertices[triangle_indices[1]]);
}
if (v3 != NULL)
{
VEC_COPY(v3,transformed_vertices[triangle_indices[2]]);
}
}

View File

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

View File

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

View File

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

View File

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

View File

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