diff --git a/Demos/MovingConcaveDemo/CMakeLists.txt b/Demos/MovingConcaveDemo/CMakeLists.txt
index 3c264fdd8..7c85b6d6c 100644
--- a/Demos/MovingConcaveDemo/CMakeLists.txt
+++ b/Demos/MovingConcaveDemo/CMakeLists.txt
@@ -48,11 +48,11 @@ ELSE (WIN32)
ENDIF (WIN32)
INCLUDE_DIRECTORIES(
-${BULLET_PHYSICS_SOURCE_DIR}/src ${BULLET_PHYSICS_SOURCE_DIR}/Demos/OpenGL }
+${BULLET_PHYSICS_SOURCE_DIR}/Extras/GIMPACT/include ${BULLET_PHYSICS_SOURCE_DIR}/src ${BULLET_PHYSICS_SOURCE_DIR}/Demos/OpenGL }
)
LINK_LIBRARIES(
-LibGIMPACTBullet LibGIMPACT LibOpenGLSupport LibBulletDynamics LibBulletCollision LibLinearMath ${GLUT_glut_LIBRARY} ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY}
+LibGIMPACT LibOpenGLSupport LibBulletDynamics LibBulletCollision LibLinearMath ${GLUT_glut_LIBRARY} ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY}
)
ADD_EXECUTABLE(MovingConcaveDemo
diff --git a/Demos/MovingConcaveDemo/ConcaveDemo.h b/Demos/MovingConcaveDemo/ConcaveDemo.h
index f6f736ba7..d16e54d30 100644
--- a/Demos/MovingConcaveDemo/ConcaveDemo.h
+++ b/Demos/MovingConcaveDemo/ConcaveDemo.h
@@ -24,10 +24,11 @@ struct btCollisionAlgorithmCreateFunc;
class ConcaveDemo : public DemoApplication
{
- btCollisionAlgorithmCreateFunc* m_gimpactCollisionCreateFunc;
+ btCollisionShape * m_trimeshShape;
public:
+ void initGImpactCollision();
void initPhysics();
virtual void clientMoveAndDisplay();
diff --git a/Demos/MovingConcaveDemo/ConcavePhysicsDemo.cpp b/Demos/MovingConcaveDemo/ConcavePhysicsDemo.cpp
index e3b0247c2..0c335854b 100644
--- a/Demos/MovingConcaveDemo/ConcavePhysicsDemo.cpp
+++ b/Demos/MovingConcaveDemo/ConcavePhysicsDemo.cpp
@@ -20,13 +20,8 @@ subject to the following restrictions:
#include "LinearMath/btIDebugDraw.h"
#include "LinearMath/btQuickprof.h"
#include "LinearMath/btDefaultMotionState.h"
-#include "../Extras/GIMPACTBullet/btGIMPACTMeshShape.h"
-#include "../Extras/GIMPACTBullet/btConcaveConcaveCollisionAlgorithm.h"
-
-//#define USE_PARALLEL_DISPATCHER 1
-#ifdef USE_PARALLEL_DISPATCHER
-#include "../../Extras/BulletMultiThreaded/SpuGatheringCollisionDispatcher.h"
-#endif//USE_PARALLEL_DISPATCHER
+#include "GIMPACT/Bullet/btGImpactShape.h"
+#include "GIMPACT/Bullet/btGImpactCollisionAlgorithm.h"
@@ -1409,11 +1404,12 @@ int gIndices[NUM_TRIANGLES][3] = {
{452,450,449}
};
-//TRIMESH GLOBAL
-btGIMPACTMeshData * g_trimeshData;
//***************************THE END OF FAMOUS BUNNY TRIMESH********************************************//
+//****GLOBALS
+
+//****GLOBALS
///User can override this material combiner by implementing gContactAddedCallback and setting body0->m_collisionFlags |= btCollisionObject::customMaterialCallback;
inline btScalar calculateCombinedFriction(float friction0,float friction1)
@@ -1615,7 +1611,7 @@ void ConcaveDemo::renderme()
sprintf(buf,"+- shooting speed = %10.2f",m_ShootBoxInitialSpeed);
BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),buf);
yStart += yIncr;
-
+
resetPerspectiveProjection();
@@ -1624,26 +1620,33 @@ void ConcaveDemo::renderme()
}
-void ConcaveDemo::initPhysics()
-{
+void ConcaveDemo::initGImpactCollision()
+{
+ // create trimesh
btTriangleIndexVertexArray* indexVertexArrays = new btTriangleIndexVertexArray(NUM_TRIANGLES,
&gIndices[0][0],
3*sizeof(int),
- NUM_VERTICES,(REAL*) &gVertices[0],sizeof(REAL)*3);
+ NUM_VERTICES,(REAL*) &gVertices[0],sizeof(REAL)*3);
+
+ btGImpactMeshShape * trimesh = new btGImpactMeshShape(indexVertexArrays);
+ trimesh->setLocalScaling(btVector3(4.f,4.f,4.f));
+ trimesh->updateBound();
+ m_trimeshShape = trimesh;
+
+ //register algorithm
+
+ btCollisionDispatcher * dispatcher = static_cast(m_dynamicsWorld ->getDispatcher());
+ btGImpactCollisionAlgorithm::registerAlgorithm(dispatcher);
+
+}
+
+void ConcaveDemo::initPhysics()
+{
- g_trimeshData = new btGIMPACTMeshData(indexVertexArrays);
//btConstraintSolver* solver = new btSequentialImpulseConstraintSolver;
-
-#ifdef USE_PARALLEL_DISPATCHER
- btCollisionDispatcher* dispatcher = new SpuGatheringCollisionDispatcher();
-#else
- btCollisionDispatcher* dispatcher = new btCollisionDispatcher();
-#endif//USE_PARALLEL_DISPATCHER
-
-
-
+ btCollisionDispatcher* dispatcher = new btCollisionDispatcher();
//btOverlappingPairCache* broadphase = new btSimpleBroadphase();
btOverlappingPairCache* broadphase = new btSimpleBroadphase();
@@ -1651,12 +1654,10 @@ void ConcaveDemo::initPhysics()
m_dynamicsWorld = new btDiscreteDynamicsWorld(dispatcher,broadphase,constraintSolver);
- m_gimpactCollisionCreateFunc = new btConcaveConcaveCollisionAlgorithm::CreateFunc;
- dispatcher->registerCollisionCreateFunc(GIMPACT_SHAPE_PROXYTYPE,GIMPACT_SHAPE_PROXYTYPE,m_gimpactCollisionCreateFunc);
- dispatcher->registerCollisionCreateFunc(TRIANGLE_MESH_SHAPE_PROXYTYPE,GIMPACT_SHAPE_PROXYTYPE,m_gimpactCollisionCreateFunc);
- dispatcher->registerCollisionCreateFunc(GIMPACT_SHAPE_PROXYTYPE,TRIANGLE_MESH_SHAPE_PROXYTYPE,m_gimpactCollisionCreateFunc);
- dispatcher->registerCollisionCreateFunc(STATIC_PLANE_PROXYTYPE,GIMPACT_SHAPE_PROXYTYPE,m_gimpactCollisionCreateFunc);
- dispatcher->registerCollisionCreateFunc(GIMPACT_SHAPE_PROXYTYPE,STATIC_PLANE_PROXYTYPE,m_gimpactCollisionCreateFunc);
+ //create trimesh model and shape
+ initGImpactCollision();
+
+
float mass = 0.f;
btTransform startTransform;
@@ -1685,19 +1686,33 @@ void ConcaveDemo::initPhysics()
btRigidBody* staticBody = localCreateRigidBody(mass, startTransform,staticScenario);
+ staticBody->setCollisionFlags(staticBody->getCollisionFlags()|btCollisionObject::CF_STATIC_OBJECT);
+
//enable custom material callback
- staticBody->setCollisionFlags(staticBody->getCollisionFlags() | btCollisionObject::CF_STATIC_OBJECT | btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK);
+ staticBody->setCollisionFlags(staticBody->getCollisionFlags()|btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK);
+
+
+ //static plane
+ btVector3 normal(0.4,1.5,-0.4);
+ normal.normalize();
+ btCollisionShape* staticplaneShape6 = new btStaticPlaneShape(normal,0.0);// A plane
+
+ startTransform.setOrigin(btVector3(0,0,0));
+
+ btRigidBody* staticBody2 = localCreateRigidBody(mass, startTransform,staticplaneShape6 );
+
+ staticBody2->setCollisionFlags(staticBody2->getCollisionFlags()|btCollisionObject::CF_STATIC_OBJECT);
{
- for (int i=0;i<10;i++)
+ for (int i=0;i<9;i++)
{
btCollisionShape* boxShape = new btBoxShape(btVector3(1,1,1));
- startTransform.setOrigin(btVector3(2*i,2,1));
+ startTransform.setOrigin(btVector3(2*i-5,2,-3));
localCreateRigidBody(1, startTransform,boxShape);
}
}
- m_debugMode |= btIDebugDraw::DBG_DrawWireframe;
+ //m_debugMode |= btIDebugDraw::DBG_DrawWireframe;
}
@@ -1842,17 +1857,9 @@ void ConcaveDemo::keyboardCallback(unsigned char key, int x, int y)
}
-btGIMPACTMeshShape * createMesh()
-{
- btGIMPACTMeshShape * newtrimeshShape = new btGIMPACTMeshShape(g_trimeshData );
- newtrimeshShape->setLocalScaling(btVector3(4.f,4.f,4.f));
-// OGL_displaylist_register_shape(newtrimeshShape);
- return newtrimeshShape;
-}
-
void ConcaveDemo::shootTrimesh(const btVector3& destination)
{
-
+
if (m_dynamicsWorld)
{
float mass = 4.f;
@@ -1861,9 +1868,7 @@ void ConcaveDemo::shootTrimesh(const btVector3& destination)
btVector3 camPos = getCameraPosition();
startTransform.setOrigin(camPos);
- btGIMPACTMeshShape * newtrimeshShape = createMesh();
-
- btRigidBody* body = this->localCreateRigidBody(mass, startTransform,newtrimeshShape);
+ btRigidBody* body = this->localCreateRigidBody(mass, startTransform,m_trimeshShape);
btVector3 linVel(destination[0]-camPos[0],destination[1]-camPos[1],destination[2]-camPos[2]);
linVel.normalize();
diff --git a/Demos/MovingConcaveDemo/Jamfile b/Demos/MovingConcaveDemo/Jamfile
index 1eba954c7..5757da7a7 100644
--- a/Demos/MovingConcaveDemo/Jamfile
+++ b/Demos/MovingConcaveDemo/Jamfile
@@ -6,18 +6,16 @@ SubDir TOP Demos MovingConcaveDemo ;
{
Application $(<) : $(>) : noinstall console nomanifest ;
- LinkWith $(<) : GIMPACTBullet GIMPACT bulletopenglsupport bulletdynamics bulletcollision bulletmath ;
+ LinkWith $(<) : GIMPACT bulletopenglsupport bulletdynamics bulletcollision bulletmath ;
CFlags $(<) :
[ FIncludes $(TOP)/Demos/OpenGL ]
[ FIncludes $(TOP)/Extras/GIMPACT/include ]
- [ FIncludes $(TOP)/Extras/GIMPACTBullet ]
;
MsvcIncDirs $(<) :
"../../Demos/OpenGL"
- "../../Extras/GIMPACT/include"
- "../../Extras/GIMPACTBullet" ;
+ "../../Extras/GIMPACT/include" ;
}
ExtraDemo1 MovingConcaveDemo : [ Wildcard *.h *.cpp ] ;
diff --git a/Extras/CMakeLists.txt b/Extras/CMakeLists.txt
index a4570883d..b118f73b5 100644
--- a/Extras/CMakeLists.txt
+++ b/Extras/CMakeLists.txt
@@ -1 +1 @@
-SUBDIRS( LibXML COLLADA_DOM GIMPACT GIMPACTBullet )
+SUBDIRS( LibXML COLLADA_DOM GIMPACT )
diff --git a/Extras/GIMPACT/BULLET_PHYSICS.build/Debug/libLibGIMPACT.a.build/Objects-normal/i386/LibGIMPACT.LinkFileList b/Extras/GIMPACT/BULLET_PHYSICS.build/Debug/libLibGIMPACT.a.build/Objects-normal/i386/LibGIMPACT.LinkFileList
new file mode 100644
index 000000000..1662bab32
--- /dev/null
+++ b/Extras/GIMPACT/BULLET_PHYSICS.build/Debug/libLibGIMPACT.a.build/Objects-normal/i386/LibGIMPACT.LinkFileList
@@ -0,0 +1,6 @@
+/Users/erwincoumans/develop/sf/bullet-2.54/Extras/GIMPACT/BULLET_PHYSICS.build/Debug/libLibGIMPACT.a.build/Objects-normal/i386/btGImpactCollisionAlgorithm.o
+/Users/erwincoumans/develop/sf/bullet-2.54/Extras/GIMPACT/BULLET_PHYSICS.build/Debug/libLibGIMPACT.a.build/Objects-normal/i386/btGImpactShape.o
+/Users/erwincoumans/develop/sf/bullet-2.54/Extras/GIMPACT/BULLET_PHYSICS.build/Debug/libLibGIMPACT.a.build/Objects-normal/i386/gim_box_set.o
+/Users/erwincoumans/develop/sf/bullet-2.54/Extras/GIMPACT/BULLET_PHYSICS.build/Debug/libLibGIMPACT.a.build/Objects-normal/i386/gim_contact.o
+/Users/erwincoumans/develop/sf/bullet-2.54/Extras/GIMPACT/BULLET_PHYSICS.build/Debug/libLibGIMPACT.a.build/Objects-normal/i386/gim_memory.o
+/Users/erwincoumans/develop/sf/bullet-2.54/Extras/GIMPACT/BULLET_PHYSICS.build/Debug/libLibGIMPACT.a.build/Objects-normal/i386/gim_tri_collision.o
diff --git a/Extras/GIMPACT/BULLET_PHYSICS.build/Debug/libLibGIMPACT.a.build/Script-13302F013302F013302F0000.sh b/Extras/GIMPACT/BULLET_PHYSICS.build/Debug/libLibGIMPACT.a.build/Script-13302F013302F013302F0000.sh
new file mode 100755
index 000000000..bb791c2b6
--- /dev/null
+++ b/Extras/GIMPACT/BULLET_PHYSICS.build/Debug/libLibGIMPACT.a.build/Script-13302F013302F013302F0000.sh
@@ -0,0 +1,2 @@
+#!/bin/sh
+make -C /Users/erwincoumans/develop/sf/bullet-2.54 -f /Users/erwincoumans/develop/sf/bullet-2.54/CMakeScripts/ReRunCMake.make
diff --git a/Extras/GIMPACT/BULLET_PHYSICS.build/Debug/libLibGIMPACT.a.build/Script-1330B401330B401330B40000.sh b/Extras/GIMPACT/BULLET_PHYSICS.build/Debug/libLibGIMPACT.a.build/Script-1330B401330B401330B40000.sh
new file mode 100755
index 000000000..bb791c2b6
--- /dev/null
+++ b/Extras/GIMPACT/BULLET_PHYSICS.build/Debug/libLibGIMPACT.a.build/Script-1330B401330B401330B40000.sh
@@ -0,0 +1,2 @@
+#!/bin/sh
+make -C /Users/erwincoumans/develop/sf/bullet-2.54 -f /Users/erwincoumans/develop/sf/bullet-2.54/CMakeScripts/ReRunCMake.make
diff --git a/Extras/GIMPACT/BULLET_PHYSICS.build/Debug/libLibGIMPACT.a.build/Script-133CA50133CA50133CA50000.sh b/Extras/GIMPACT/BULLET_PHYSICS.build/Debug/libLibGIMPACT.a.build/Script-133CA50133CA50133CA50000.sh
new file mode 100755
index 000000000..bb791c2b6
--- /dev/null
+++ b/Extras/GIMPACT/BULLET_PHYSICS.build/Debug/libLibGIMPACT.a.build/Script-133CA50133CA50133CA50000.sh
@@ -0,0 +1,2 @@
+#!/bin/sh
+make -C /Users/erwincoumans/develop/sf/bullet-2.54 -f /Users/erwincoumans/develop/sf/bullet-2.54/CMakeScripts/ReRunCMake.make
diff --git a/Extras/GIMPACT/BULLET_PHYSICS.build/Debug/libLibGIMPACT.a.build/libLibGIMPACT.a.dep b/Extras/GIMPACT/BULLET_PHYSICS.build/Debug/libLibGIMPACT.a.build/libLibGIMPACT.a.dep
new file mode 100644
index 000000000..8d690e35d
--- /dev/null
+++ b/Extras/GIMPACT/BULLET_PHYSICS.build/Debug/libLibGIMPACT.a.build/libLibGIMPACT.a.dep
@@ -0,0 +1,7 @@
+00000000002a1016000000000000944b 582e883c151ba574c0f5b6085732499b ffffffffffffffffffffffffffffffff 61676 /Users/erwincoumans/develop/sf/bullet-2.54/Extras/GIMPACT/BULLET_PHYSICS.build/Debug/libLibGIMPACT.a.build/Objects-normal/i386/gim_tri_collision.o
+0000000044427ffb000000000000cc2e fadb4c71fc3b509301f1b79175fc75b7 ffffffffffffffffffffffffffffffff 6748 /Users/erwincoumans/develop/sf/bullet-2.54/Extras/GIMPACT/BULLET_PHYSICS.build/Debug/libLibGIMPACT.a.build/Objects-normal/i386/gim_memory.o
+00000000464e4b6e000000000000af12 54d6f4ff7c506f1e8f42a617b21b1f30 ffffffffffffffffffffffffffffffff 48500 /Users/erwincoumans/develop/sf/bullet-2.54/Extras/GIMPACT/BULLET_PHYSICS.build/Debug/libLibGIMPACT.a.build/Objects-normal/i386/gim_contact.o
+00000000001ce1140000000000005087 8abd5fd65e40fdff4b616094d8f3a471 ffffffffffffffffffffffffffffffff 54688 /Users/erwincoumans/develop/sf/bullet-2.54/Extras/GIMPACT/BULLET_PHYSICS.build/Debug/libLibGIMPACT.a.build/Objects-normal/i386/gim_box_set.o
+00000000467d375200000000000039ed d7bf46a0db97844dd677c02246b8f3a8 ffffffffffffffffffffffffffffffff 235632 /Users/erwincoumans/develop/sf/bullet-2.54/Extras/GIMPACT/BULLET_PHYSICS.build/Debug/libLibGIMPACT.a.build/Objects-normal/i386/btGImpactShape.o
+0000000000200129000000000000dc1f 70e1b343c97824104bf5cf6ce036c670 ffffffffffffffffffffffffffffffff 385580 /Users/erwincoumans/develop/sf/bullet-2.54/Extras/GIMPACT/BULLET_PHYSICS.build/Debug/libLibGIMPACT.a.build/Objects-normal/i386/btGImpactCollisionAlgorithm.o
+dbc09a87dbc430ff98a5c854eea8f3d1 32e74142d5c8ece00339d5418a5668e7 ffffffffffffffffffffffffffffffff 834284 /Users/erwincoumans/develop/sf/bullet-2.54/Extras/GIMPACT/Debug/libLibGIMPACT.a
diff --git a/Extras/GIMPACT/BULLET_PHYSICS.build/Debug/libLibGIMPACT.a.build/libLibGIMPACT.a~.dep b/Extras/GIMPACT/BULLET_PHYSICS.build/Debug/libLibGIMPACT.a.build/libLibGIMPACT.a~.dep
new file mode 100644
index 000000000..bea22095a
--- /dev/null
+++ b/Extras/GIMPACT/BULLET_PHYSICS.build/Debug/libLibGIMPACT.a.build/libLibGIMPACT.a~.dep
@@ -0,0 +1,7 @@
+000000000006c8220000000000000a61 c31f0b6300cb69efef1695286a9967cf ffffffffffffffffffffffffffffffff 0 /Users/erwincoumans/develop/sf/bullet-2.54/Extras/GIMPACT/BULLET_PHYSICS.build/Debug/libLibGIMPACT.a.build/Objects-normal/i386/btGImpactShape.o
+0000000000200136000000000000fb47 ae54f1915d207c2d451efd532699d45f ffffffffffffffffffffffffffffffff 0 /Users/erwincoumans/develop/sf/bullet-2.54/Extras/GIMPACT/BULLET_PHYSICS.build/Debug/libLibGIMPACT.a.build/Objects-normal/i386/btGImpactCollisionAlgorithm.o
+ffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffff 0 /Users/erwincoumans/develop/sf/bullet-2.54/Extras/GIMPACT/Debug/libLibGIMPACT.a
+ffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffff 0 /Users/erwincoumans/develop/sf/bullet-2.54/Extras/GIMPACT/BULLET_PHYSICS.build/Debug/libLibGIMPACT.a.build/Objects-normal/i386/gim_tri_collision.o
+ffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffff 0 /Users/erwincoumans/develop/sf/bullet-2.54/Extras/GIMPACT/BULLET_PHYSICS.build/Debug/libLibGIMPACT.a.build/Objects-normal/i386/gim_memory.o
+ffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffff 0 /Users/erwincoumans/develop/sf/bullet-2.54/Extras/GIMPACT/BULLET_PHYSICS.build/Debug/libLibGIMPACT.a.build/Objects-normal/i386/gim_contact.o
+ffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffff 0 /Users/erwincoumans/develop/sf/bullet-2.54/Extras/GIMPACT/BULLET_PHYSICS.build/Debug/libLibGIMPACT.a.build/Objects-normal/i386/gim_box_set.o
diff --git a/Extras/GIMPACT/CMakeLists.txt b/Extras/GIMPACT/CMakeLists.txt
new file mode 100644
index 000000000..be295fe9c
--- /dev/null
+++ b/Extras/GIMPACT/CMakeLists.txt
@@ -0,0 +1,13 @@
+INCLUDE_DIRECTORIES(
+${BULLET_PHYSICS_SOURCE_DIR}/Extras/GIMPACT/include
+${BULLET_PHYSICS_SOURCE_DIR}/src
+)
+
+ADD_LIBRARY(LibGIMPACT
+ src/Bullet/btGImpactCollisionAlgorithm.cpp
+ src/Bullet/btGImpactShape.cpp
+ src/core/gim_box_set.cpp
+ src/core/gim_contact.cpp
+ src/core/gim_memory.cpp
+ src/core/gim_tri_collision.cpp
+)
diff --git a/Extras/GIMPACT/Debug/libLibGIMPACT.a b/Extras/GIMPACT/Debug/libLibGIMPACT.a
new file mode 100644
index 000000000..cda36bf70
Binary files /dev/null and b/Extras/GIMPACT/Debug/libLibGIMPACT.a differ
diff --git a/Extras/GIMPACT/Doxyfile b/Extras/GIMPACT/Doxyfile
new file mode 100755
index 000000000..e37623ac0
--- /dev/null
+++ b/Extras/GIMPACT/Doxyfile
@@ -0,0 +1,263 @@
+# Doxyfile 1.5.2
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+DOXYFILE_ENCODING = UTF-8
+PROJECT_NAME = GIMPACT
+PROJECT_NUMBER = 0.2
+OUTPUT_DIRECTORY = docs
+CREATE_SUBDIRS = NO
+OUTPUT_LANGUAGE = English
+BRIEF_MEMBER_DESC = YES
+REPEAT_BRIEF = YES
+ABBREVIATE_BRIEF = "The $name class" \
+ "The $name widget" \
+ "The $name file" \
+ is \
+ provides \
+ specifies \
+ contains \
+ represents \
+ a \
+ an \
+ the
+ALWAYS_DETAILED_SEC = NO
+INLINE_INHERITED_MEMB = NO
+FULL_PATH_NAMES = YES
+STRIP_FROM_PATH = "C:/Documents and Settings/Administrador/"
+STRIP_FROM_INC_PATH =
+SHORT_NAMES = NO
+JAVADOC_AUTOBRIEF = NO
+MULTILINE_CPP_IS_BRIEF = NO
+DETAILS_AT_TOP = NO
+INHERIT_DOCS = YES
+SEPARATE_MEMBER_PAGES = NO
+TAB_SIZE = 8
+ALIASES =
+OPTIMIZE_OUTPUT_FOR_C = NO
+OPTIMIZE_OUTPUT_JAVA = NO
+BUILTIN_STL_SUPPORT = NO
+CPP_CLI_SUPPORT = NO
+DISTRIBUTE_GROUP_DOC = NO
+SUBGROUPING = YES
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+EXTRACT_ALL = YES
+EXTRACT_PRIVATE = YES
+EXTRACT_STATIC = YES
+EXTRACT_LOCAL_CLASSES = YES
+EXTRACT_LOCAL_METHODS = NO
+HIDE_UNDOC_MEMBERS = NO
+HIDE_UNDOC_CLASSES = NO
+HIDE_FRIEND_COMPOUNDS = NO
+HIDE_IN_BODY_DOCS = NO
+INTERNAL_DOCS = NO
+CASE_SENSE_NAMES = NO
+HIDE_SCOPE_NAMES = NO
+SHOW_INCLUDE_FILES = YES
+INLINE_INFO = YES
+SORT_MEMBER_DOCS = YES
+SORT_BRIEF_DOCS = NO
+SORT_BY_SCOPE_NAME = NO
+GENERATE_TODOLIST = YES
+GENERATE_TESTLIST = YES
+GENERATE_BUGLIST = YES
+GENERATE_DEPRECATEDLIST= YES
+ENABLED_SECTIONS =
+MAX_INITIALIZER_LINES = 30
+SHOW_USED_FILES = YES
+SHOW_DIRECTORIES = NO
+FILE_VERSION_FILTER =
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+QUIET = NO
+WARNINGS = YES
+WARN_IF_UNDOCUMENTED = YES
+WARN_IF_DOC_ERROR = YES
+WARN_NO_PARAMDOC = NO
+WARN_FORMAT = "$file:$line: $text"
+WARN_LOGFILE =
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+INPUT = include
+INPUT_ENCODING = UTF-8
+FILE_PATTERNS = *.c \
+ *.cc \
+ *.cxx \
+ *.cpp \
+ *.c++ \
+ *.d \
+ *.java \
+ *.ii \
+ *.ixx \
+ *.ipp \
+ *.i++ \
+ *.inl \
+ *.h \
+ *.hh \
+ *.hxx \
+ *.hpp \
+ *.h++ \
+ *.idl \
+ *.odl \
+ *.cs \
+ *.php \
+ *.php3 \
+ *.inc \
+ *.m \
+ *.mm \
+ *.dox \
+ *.py
+RECURSIVE = YES
+EXCLUDE =
+EXCLUDE_SYMLINKS = NO
+EXCLUDE_PATTERNS =
+EXCLUDE_SYMBOLS =
+EXAMPLE_PATH =
+EXAMPLE_PATTERNS = *
+EXAMPLE_RECURSIVE = NO
+IMAGE_PATH =
+INPUT_FILTER =
+FILTER_PATTERNS =
+FILTER_SOURCE_FILES = NO
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+SOURCE_BROWSER = NO
+INLINE_SOURCES = NO
+STRIP_CODE_COMMENTS = YES
+REFERENCED_BY_RELATION = NO
+REFERENCES_RELATION = NO
+REFERENCES_LINK_SOURCE = YES
+USE_HTAGS = NO
+VERBATIM_HEADERS = NO
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+ALPHABETICAL_INDEX = NO
+COLS_IN_ALPHA_INDEX = 5
+IGNORE_PREFIX =
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+GENERATE_HTML = YES
+HTML_OUTPUT = html
+HTML_FILE_EXTENSION = .html
+HTML_HEADER =
+HTML_FOOTER =
+HTML_STYLESHEET =
+HTML_ALIGN_MEMBERS = YES
+GENERATE_HTMLHELP = NO
+CHM_FILE =
+HHC_LOCATION =
+GENERATE_CHI = NO
+BINARY_TOC = NO
+TOC_EXPAND = NO
+DISABLE_INDEX = NO
+ENUM_VALUES_PER_LINE = 4
+GENERATE_TREEVIEW = NO
+TREEVIEW_WIDTH = 250
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+GENERATE_LATEX = YES
+LATEX_OUTPUT = latex
+LATEX_CMD_NAME = latex
+MAKEINDEX_CMD_NAME = makeindex
+COMPACT_LATEX = NO
+PAPER_TYPE = a4wide
+EXTRA_PACKAGES =
+LATEX_HEADER =
+PDF_HYPERLINKS = NO
+USE_PDFLATEX = NO
+LATEX_BATCHMODE = NO
+LATEX_HIDE_INDICES = NO
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+GENERATE_RTF = NO
+RTF_OUTPUT = rtf
+COMPACT_RTF = NO
+RTF_HYPERLINKS = NO
+RTF_STYLESHEET_FILE =
+RTF_EXTENSIONS_FILE =
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+GENERATE_MAN = NO
+MAN_OUTPUT = man
+MAN_EXTENSION = .3
+MAN_LINKS = NO
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+GENERATE_XML = NO
+XML_OUTPUT = xml
+XML_SCHEMA =
+XML_DTD =
+XML_PROGRAMLISTING = YES
+#---------------------------------------------------------------------------
+# configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+GENERATE_AUTOGEN_DEF = NO
+#---------------------------------------------------------------------------
+# configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+GENERATE_PERLMOD = NO
+PERLMOD_LATEX = NO
+PERLMOD_PRETTY = YES
+PERLMOD_MAKEVAR_PREFIX =
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor
+#---------------------------------------------------------------------------
+ENABLE_PREPROCESSING = YES
+MACRO_EXPANSION = NO
+EXPAND_ONLY_PREDEF = NO
+SEARCH_INCLUDES = YES
+INCLUDE_PATH =
+INCLUDE_FILE_PATTERNS =
+PREDEFINED =
+EXPAND_AS_DEFINED =
+SKIP_FUNCTION_MACROS = YES
+#---------------------------------------------------------------------------
+# Configuration::additions related to external references
+#---------------------------------------------------------------------------
+TAGFILES =
+GENERATE_TAGFILE =
+ALLEXTERNALS = NO
+EXTERNAL_GROUPS = YES
+PERL_PATH = /usr/bin/perl
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool
+#---------------------------------------------------------------------------
+CLASS_DIAGRAMS = YES
+MSCGEN_PATH =
+HIDE_UNDOC_RELATIONS = YES
+HAVE_DOT = NO
+CLASS_GRAPH = YES
+COLLABORATION_GRAPH = YES
+GROUP_GRAPHS = YES
+UML_LOOK = NO
+TEMPLATE_RELATIONS = NO
+INCLUDE_GRAPH = YES
+INCLUDED_BY_GRAPH = YES
+CALL_GRAPH = NO
+CALLER_GRAPH = NO
+GRAPHICAL_HIERARCHY = YES
+DIRECTORY_GRAPH = YES
+DOT_IMAGE_FORMAT = png
+DOT_PATH =
+DOTFILE_DIRS =
+DOT_GRAPH_MAX_NODES = 50
+DOT_TRANSPARENT = NO
+DOT_MULTI_TARGETS = NO
+GENERATE_LEGEND = YES
+DOT_CLEANUP = YES
+#---------------------------------------------------------------------------
+# Configuration::additions related to the search engine
+#---------------------------------------------------------------------------
+SEARCHENGINE = NO
diff --git a/Extras/GIMPACT/GIMPACT-LICENSE-BSD.TXT b/Extras/GIMPACT/GIMPACT-LICENSE-BSD.TXT
new file mode 100755
index 000000000..95545aac2
--- /dev/null
+++ b/Extras/GIMPACT/GIMPACT-LICENSE-BSD.TXT
@@ -0,0 +1,29 @@
+GIMPACT : Geometric tools for VR.
+
+Copyright (c) 2006 , Francisco León.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+ are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice, this list of
+ conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice, this list
+ of conditions and the following disclaimer in the documentation and/or other materials
+ provided with the distribution.
+
+ * Neither the name of the GIMPACT nor the names of its contributors may be used
+ to endorse or promote products derived from this software without specific prior
+ written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
+OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ DAMAGE.
\ No newline at end of file
diff --git a/Extras/GIMPACT/GIMPACT-LICENSE-LGPL.TXT b/Extras/GIMPACT/GIMPACT-LICENSE-LGPL.TXT
new file mode 100755
index 000000000..60b81560d
--- /dev/null
+++ b/Extras/GIMPACT/GIMPACT-LICENSE-LGPL.TXT
@@ -0,0 +1,502 @@
+ GNU LESSER GENERAL PUBLIC LICENSE
+ Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+ 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL. It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+ This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it. You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+ When we speak of free software, we are referring to freedom of use,
+not price. Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+ To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights. These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+ For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you. You must make sure that they, too, receive or can get the source
+code. If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it. And you must show them these terms so they know their rights.
+
+ We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+ To protect each distributor, we want to make it very clear that
+there is no warranty for the free library. Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+
+ Finally, software patents pose a constant threat to the existence of
+any free program. We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder. Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+ Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License. This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License. We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+ When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library. The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom. The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+ We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License. It also provides other free software developers Less
+of an advantage over competing non-free programs. These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries. However, the Lesser license provides advantages in certain
+special circumstances.
+
+ For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard. To achieve this, non-free programs must be
+allowed to use the library. A more frequent case is that a free
+library does the same job as widely used non-free libraries. In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+ In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software. For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+ Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+ The precise terms and conditions for copying, distribution and
+modification follow. Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library". The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+
+ GNU LESSER GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+ A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+ The "Library", below, refers to any such software library or work
+which has been distributed under these terms. A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language. (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+ "Source code" for a work means the preferred form of the work for
+making modifications to it. For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+ Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it). Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+ 1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+ You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+
+ 2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) The modified work must itself be a software library.
+
+ b) You must cause the files modified to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ c) You must cause the whole of the work to be licensed at no
+ charge to all third parties under the terms of this License.
+
+ d) If a facility in the modified Library refers to a function or a
+ table of data to be supplied by an application program that uses
+ the facility, other than as an argument passed when the facility
+ is invoked, then you must make a good faith effort to ensure that,
+ in the event an application does not supply such function or
+ table, the facility still operates, and performs whatever part of
+ its purpose remains meaningful.
+
+ (For example, a function in a library to compute square roots has
+ a purpose that is entirely well-defined independent of the
+ application. Therefore, Subsection 2d requires that any
+ application-supplied function or table used by this function must
+ be optional: if the application does not supply it, the square
+ root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library. To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License. (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.) Do not make any other change in
+these notices.
+
+ Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+ This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+ 4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+ If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library". Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+ However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library". The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+ When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library. The
+threshold for this to be true is not precisely defined by law.
+
+ If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work. (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+ Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+
+ 6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+ You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License. You must supply a copy of this License. If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License. Also, you must do one
+of these things:
+
+ a) Accompany the work with the complete corresponding
+ machine-readable source code for the Library including whatever
+ changes were used in the work (which must be distributed under
+ Sections 1 and 2 above); and, if the work is an executable linked
+ with the Library, with the complete machine-readable "work that
+ uses the Library", as object code and/or source code, so that the
+ user can modify the Library and then relink to produce a modified
+ executable containing the modified Library. (It is understood
+ that the user who changes the contents of definitions files in the
+ Library will not necessarily be able to recompile the application
+ to use the modified definitions.)
+
+ b) Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (1) uses at run time a
+ copy of the library already present on the user's computer system,
+ rather than copying library functions into the executable, and (2)
+ will operate properly with a modified version of the library, if
+ the user installs one, as long as the modified version is
+ interface-compatible with the version that the work was made with.
+
+ c) Accompany the work with a written offer, valid for at
+ least three years, to give the same user the materials
+ specified in Subsection 6a, above, for a charge no more
+ than the cost of performing this distribution.
+
+ d) If distribution of the work is made by offering access to copy
+ from a designated place, offer equivalent access to copy the above
+ specified materials from the same place.
+
+ e) Verify that the user has already received a copy of these
+ materials or that you have already sent this user a copy.
+
+ For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it. However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+ It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system. Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+
+ 7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+ a) Accompany the combined library with a copy of the same work
+ based on the Library, uncombined with any other library
+ facilities. This must be distributed under the terms of the
+ Sections above.
+
+ b) Give prominent notice with the combined library of the fact
+ that part of it is a work based on the Library, and explaining
+ where to find the accompanying uncombined form of the same work.
+
+ 8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License. Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License. However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+ 9. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Library or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+ 10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+
+ 11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all. For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded. In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+ 13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation. If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+
+ 14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission. For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this. Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+ NO WARRANTY
+
+ 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Libraries
+
+ If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change. You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+ To apply these terms, attach the following notices to the library. It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+
+ Copyright (C)
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the
+ library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+ , 1 April 1990
+ Ty Coon, President of Vice
+
+That's all there is to it!
diff --git a/Extras/GIMPACT/GIMPACT-LICENSE-ZLIB.TXT b/Extras/GIMPACT/GIMPACT-LICENSE-ZLIB.TXT
new file mode 100755
index 000000000..616f33f7c
--- /dev/null
+++ b/Extras/GIMPACT/GIMPACT-LICENSE-ZLIB.TXT
@@ -0,0 +1,23 @@
+GIMPACT : Geometric tools for VR.
+
+Copyright (c) 2006 , Francisco León.
+All rights reserved.
+
+
+This software is provided 'as-is', without any express or implied warranty. In no
+event will the authors be held liable for any damages arising from the use of this
+software.
+
+Permission is granted to anyone to use this software for any purpose, including commercial
+applications, and to alter it and redistribute it freely, subject to the following
+restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not claim that
+ you wrote the original software. If you use this software in a product, an
+ acknowledgment in the product documentation would be appreciated but is not required.
+
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+
+ 3. This notice may not be removed or altered from any source distribution.
+
diff --git a/Extras/GIMPACT/Jamfile b/Extras/GIMPACT/Jamfile
new file mode 100644
index 000000000..4a6ac654b
--- /dev/null
+++ b/Extras/GIMPACT/Jamfile
@@ -0,0 +1,12 @@
+SubDir TOP Extras GIMPACT ;
+
+#IncludeDir Extras/GIMPACT/include ;
+
+Library GIMPACT : [ Wildcard src/Bullet : */.h *.cpp ] [ Wildcard src/core : *.cpp ] : noinstall ;
+CFlags GIMPACT : [ FIncludes $(TOP)/Extras/GIMPACT/include ] ;
+LibDepends GIMPACT : ;
+
+ MsvcIncDirs GIMPACT :
+ "../../Extras/GIMPACT/include" ;
+
+InstallHeader [ Wildcard *.h ] : GIMPACT ;
diff --git a/Extras/GIMPACT/cmake_install.cmake b/Extras/GIMPACT/cmake_install.cmake
new file mode 100644
index 000000000..609da2a62
--- /dev/null
+++ b/Extras/GIMPACT/cmake_install.cmake
@@ -0,0 +1,29 @@
+# Install script for directory: /Users/erwincoumans/develop/sf/bullet-2.54/Extras/GIMPACT
+
+# Set the install prefix
+IF(NOT DEFINED CMAKE_INSTALL_PREFIX)
+ SET(CMAKE_INSTALL_PREFIX "/usr/local")
+ENDIF(NOT DEFINED CMAKE_INSTALL_PREFIX)
+STRING(REGEX REPLACE "/$" "" CMAKE_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}")
+
+# Set the install configuration name.
+IF(NOT CMAKE_INSTALL_CONFIG_NAME)
+ IF(BUILD_TYPE)
+ STRING(REGEX REPLACE "^[^A-Za-z0-9_]+" ""
+ CMAKE_INSTALL_CONFIG_NAME "${BUILD_TYPE}")
+ ELSE(BUILD_TYPE)
+ SET(CMAKE_INSTALL_CONFIG_NAME "Release")
+ ENDIF(BUILD_TYPE)
+ MESSAGE(STATUS "Install configuration: \"${CMAKE_INSTALL_CONFIG_NAME}\"")
+ENDIF(NOT CMAKE_INSTALL_CONFIG_NAME)
+
+# Set the component getting installed.
+IF(NOT CMAKE_INSTALL_COMPONENT)
+ IF(COMPONENT)
+ MESSAGE(STATUS "Install component: \"${COMPONENT}\"")
+ SET(CMAKE_INSTALL_COMPONENT "${COMPONENT}")
+ ELSE(COMPONENT)
+ SET(CMAKE_INSTALL_COMPONENT)
+ ENDIF(COMPONENT)
+ENDIF(NOT CMAKE_INSTALL_COMPONENT)
+
diff --git a/Extras/GIMPACT/docs/html/annotated.html b/Extras/GIMPACT/docs/html/annotated.html
new file mode 100755
index 000000000..06df1ba70
--- /dev/null
+++ b/Extras/GIMPACT/docs/html/annotated.html
@@ -0,0 +1,70 @@
+
+
+GIMPACT: Class List
+
+
+
+
+
template<typename _GIM_PRIMITIVE_MANAGER_PROTOTYPE, typename _GIM_BOX_TREE_PROTOTYPE>
+ class GIM_BOX_TREE_TEMPLATE_SET< _GIM_PRIMITIVE_MANAGER_PROTOTYPE, _GIM_BOX_TREE_PROTOTYPE >
+
+Generic Box Tree Template.
+
+This class offers an structure for managing a box tree of primitives. Requires a Primitive prototype (like GIM_PRIMITIVE_MANAGER_PROTOTYPE ) and a Box tree structure ( like GIM_BOX_TREE).
+
+Prototype Base class for primitive classification.
+
+This class is a wrapper for primitive collections. This tells relevant info for the Bounding Box set classes, which take care of space classification. This class can manage Compound shapes and trimeshes, and if it is managing trimesh then the Hierarchy Bounding Box classes will take advantage of primitive Vs Box overlapping tests for getting optimal results and less Per Box compairisons.
+
Simply create this shape by passing the btStridingMeshInterface to the constructor btGImpactMeshShape, then you must call updateBound() after creating the mesh
+
+
+
You can handle deformable meshes with this shape, by calling postUpdate() every time when changing the mesh vertices.
+
+
+
Constructor & Destructor Documentation
+
+
+
+
+
+
btGImpactMeshShape::btGImpactMeshShape
+
(
+
btStridingMeshInterface *
+
meshInterface
+
)
+
[inline]
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
virtual btGImpactMeshShape::~btGImpactMeshShape
+
(
+
+
)
+
[inline, virtual]
+
+
+
+
+
+
+
+
+
+
Member Function Documentation
+
+
+
+
+
+
void btGImpactMeshShape::buildMeshParts
+
(
+
btStridingMeshInterface *
+
meshInterface
+
)
+
[inline, protected]
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
virtual void btGImpactMeshShape::calcLocalAABB
+
(
+
+
)
+
[inline, protected, virtual]
+
+
+
+
+
+
+use this function for perfofm refit in bounding boxes
+
+This class manages a sub part of a mesh supplied by the btStridingMeshInterface interface.
+
+
+
Simply create this shape by passing the btStridingMeshInterface to the constructor btGImpactMeshShapePart, then you must call updateBound() after creating the mesh
When making operations with this shape, you must call lock before accessing to the trimesh primitives, and then call unlock
You can handle deformable meshes with this shape, by calling postUpdate() every time when changing the mesh vertices.
+A memory aligned compact hash table that coud be treated as an array. It could be a simple sorted array without the overhead of the hash key bucked, or could be a formely hash table with an array of keys. You can use switch_to_hashtable() and switch_to_sorted_array for saving space or increase speed.
+
+
+if node_size = 0, then this container becomes a simple sorted array allocator. reserve_size is used for reserve memory in m_nodes. When the array size reaches the size equivalent to 'min_hash_table_size', then it becomes a hash table by calling check_for_switching_to_hashtable.
+
+If node_size != 0, then this container becomes a hash table for ever
+if node_size = 0, then this container becomes a simple sorted array allocator. reserve_size is used for reserve memory in m_nodes. When the array size reaches the size equivalent to 'min_hash_table_size', then it becomes a hash table by calling check_for_switching_to_hashtable. If node_size != 0, then this container becomes a hash table for ever
+
the index in the array of the existing element,or GIM_INVALID_HASH if the element has been inserted If so, the element has been inserted at the last position of the array.
Collision detection algorithm for concave shapes in the Bullet Physics Engine. See btGImpactCollisionAlgorithm.
Efficient Dynamic Hierarcht Bounding Box tree structures for handle collisions with composed shapes whose have large sets of primitives (triangles or convex shapes) See the GIM_BOX_TREE_SET class.
Collision detection for trimeshes with the btGImpactMeshShape class. Now GIMPACT works fine with the btStridingInterface class for getting the data from trimesh models.
Support for deformable trimeshes.
Collision detection for compound shapes through the btGImpactCompoundShape class. This class takes advantage from the Hierarcht Bounding Box structure (GIM_BOX_TREE_SET class).
Collision Shapes (Both btGImpactCompoundSape and btGImpactTrimeshShape ) can be shared by two or more Rigid Bodies in Bullet.
+Generated on Wed Jun 13 16:58:21 2007 for GIMPACT by
+
+ 1.5.2
+
+
diff --git a/Extras/GIMPACT/docs/html/files.html b/Extras/GIMPACT/docs/html/files.html
new file mode 100755
index 000000000..7e005e40d
--- /dev/null
+++ b/Extras/GIMPACT/docs/html/files.html
@@ -0,0 +1,47 @@
+
+
+GIMPACT: File Index
+
+
+
+
+
This page explains how to interpret the graphs that are generated by doxygen.
+Consider the following example:
/*! Invisible class because of truncation */
+class Invisible { };
+
+/*! Truncated class, inheritance relation is hidden */
+class Truncated : public Invisible { };
+
+/* Class not documented with doxygen comments */
+class Undocumented { };
+
+/*! Class that is inherited using public inheritance */
+class PublicBase : public Truncated { };
+
+/*! A template class */
+template<class T> class Templ { };
+
+/*! Class that is inherited using protected inheritance */
+class ProtectedBase { };
+
+/*! Class that is inherited using private inheritance */
+class PrivateBase { };
+
+/*! Class that is used by the Inherited class */
+class Used { };
+
+/*! Super class that inherits a number of other classes */
+class Inherited : public PublicBase,
+ protected ProtectedBase,
+ private PrivateBase,
+ public Undocumented,
+ public Templ<int>
+{
+ private:
+ Used *m_usedClass;
+};
+
If the MAX_DOT_GRAPH_HEIGHT tag in the configuration file is set to 240 this will result in the following graph:
+
+
+
+
+The boxes in the above graph have the following meaning:
+
+A filled gray box represents the struct or class for which the graph is generated.
+
+A box with a black border denotes a documented struct or class.
+
+A box with a grey border denotes an undocumented struct or class.
+
+A box with a red border denotes a documented struct or class forwhich not all inheritance/containment relations are shown. A graph is truncated if it does not fit within the specified boundaries.
+
+The arrows have the following meaning:
+
+A dark blue arrow is used to visualize a public inheritance relation between two classes.
+
+A dark green arrow is used for protected inheritance.
+
+A dark red arrow is used for private inheritance.
+
+A purple dashed arrow is used if a class is contained or used by another class. The arrow is labeled with the variable(s) through which the pointed class or struct is accessible.
+
+A yellow dashed arrow denotes a relation between a template instance and the template class it was instantiated from. The arrow is labeled with the template parameters of the instance.
+
+Generated on Wed Jun 13 15:30:52 2007 for GIMPACT by
+
+ 1.5.2
+
+
diff --git a/Extras/GIMPACT/docs/html/group___a_r_r_a_y___u_t_i_l_i_t_i_e_s.html b/Extras/GIMPACT/docs/html/group___a_r_r_a_y___u_t_i_l_i_t_i_e_s.html
new file mode 100755
index 000000000..8853f504d
--- /dev/null
+++ b/Extras/GIMPACT/docs/html/group___a_r_r_a_y___u_t_i_l_i_t_i_e_s.html
@@ -0,0 +1,165 @@
+
+
+GIMPACT: ARRAY_UTILITIES
+
+
+
+
+
+If the element exists, this won't insert the element
Returns:
the index in the array of the existing element,or GIM_INVALID_HASH if the element has been inserted If so, the element has been inserted at the last position of the array.
+If the element exists, this replaces the element.
Returns:
the index in the array of the existing element,or GIM_INVALID_HASH if the element has been inserted If so, the element has been inserted at the last position of the array.
+GIMPACT is a software library with tools for geometry processing and collision detection, focused on solving most common problems on Virtual Reality development.
+Since Version 0.2, GIMPACT will work integrated with the Bullet Engine for general collision detection and physics. For more details, please visit http://www.continuousphysics.com/Bullet/
+For creating trimeshes you must provide an interface for your model data. You could use btTriangleIndexVertexArray class for providing the indices and the vertices from your triangle models.
+For example, you could create a trimesh from memory as following:
At end, you must call btGImpactMeshShape.updateBound for ensure that the shape will build its internal Box set structure:
trimesh->updateBound();// Call this method once before doing collisions
+
Also you must call btGImpactMeshShape.postUpdate() each time when changing the trimesh data ( For deformable meshes), this will enable a flag to the trimesh shape which tells that the trimesh data has been changed and btGImpactMeshShape.updateBound will be called in collision routines. <
At end, you must call btGImpactCompoundShape.updateBound for ensure that the shape will build its internal Box set structure: Generated on Wed Jun 13 16:58:21 2007 for GIMPACT by
+
+ 1.5.2
+
+
diff --git a/Extras/GIMPACT/docs/html/requirements.html b/Extras/GIMPACT/docs/html/requirements.html
new file mode 100755
index 000000000..c77971c15
--- /dev/null
+++ b/Extras/GIMPACT/docs/html/requirements.html
@@ -0,0 +1,24 @@
+
+
+GIMPACT:
+
+
+
+
+
if node_size = 0, then this container becomes a simple sorted array allocator. reserve_size is used for reserve memory in m_nodes.
+When the array size reaches the size equivalent to 'min_hash_table_size', then it becomes a hash table by calling check_for_switching_to_hashtable.
+
If node_size != 0, then this container becomes a hash table for ever
+
+
+*/
+template
+class gim_hash_table
+{
+protected:
+ typedef GIM_HASH_TABLE_NODE _node_type;
+
+ //!The nodes
+ //array< _node_type, SuperAllocator<_node_type> > m_nodes;
+ gim_array< _node_type > m_nodes;
+ //SuperBufferedArray< _node_type > m_nodes;
+ bool m_sorted;
+
+ /*! \defgroup HASH_TABLE_STRUCTURES
+ \brief
+ Hash table data management. The hash table has the indices to the corresponding m_nodes array
+ */
+ //! @{
+
+ GUINT * m_hash_table;//!<
+ GUINT m_table_size;//!<
+ GUINT m_node_size;//!<
+ GUINT m_min_hash_table_size;
+
+
+
+ //! Returns the cell index
+ inline GUINT _find_cell(GUINT hashkey)
+ {
+ _node_type * nodesptr = m_nodes.pointer();
+ GUINT start_index = (hashkey%m_table_size)*m_node_size;
+ GUINT end_index = start_index + m_node_size;
+
+ while(start_index= m_nodes.size()) return false;
+ if(m_nodes[index].m_key != GIM_INVALID_HASH)
+ {
+ //Search for the avaliable cell in buffer
+ GUINT cell_index = _find_cell(m_nodes[index].m_key);
+
+ btAssert(cell_index!=GIM_INVALID_HASH);
+ btAssert(m_hash_table[cell_index]==index);
+
+ m_hash_table[cell_index] = GIM_INVALID_HASH;
+ }
+
+ return this->_erase_unsorted(index);
+ }
+
+ //! erase by key in hash table
+ inline bool _erase_hash_table(GUINT hashkey)
+ {
+ if(hashkey == GIM_INVALID_HASH) return false;
+
+ //Search for the avaliable cell in buffer
+ GUINT cell_index = _find_cell(hashkey);
+ if(cell_index ==GIM_INVALID_HASH) return false;
+
+ GUINT index = m_hash_table[cell_index];
+ m_hash_table[cell_index] = GIM_INVALID_HASH;
+
+ return this->_erase_unsorted(index);
+ }
+
+
+
+ //! insert an element in hash table
+ /*!
+ If the element exists, this won't insert the element
+ \return the index in the array of the existing element,or GIM_INVALID_HASH if the element has been inserted
+ If so, the element has been inserted at the last position of the array.
+ */
+ inline GUINT _insert_hash_table(GUINT hashkey, const T & value)
+ {
+ if(hashkey==GIM_INVALID_HASH)
+ {
+ //Insert anyway
+ _insert_unsorted(hashkey,value);
+ return GIM_INVALID_HASH;
+ }
+
+ GUINT cell_index = _assign_hash_table_cell(hashkey);
+
+ GUINT value_key = m_hash_table[cell_index];
+
+ if(value_key!= GIM_INVALID_HASH) return value_key;// Not overrited
+
+ m_hash_table[cell_index] = m_nodes.size();
+
+ _insert_unsorted(hashkey,value);
+ return GIM_INVALID_HASH;
+ }
+
+ //! insert an element in hash table.
+ /*!
+ If the element exists, this replaces the element.
+ \return the index in the array of the existing element,or GIM_INVALID_HASH if the element has been inserted
+ If so, the element has been inserted at the last position of the array.
+ */
+ inline GUINT _insert_hash_table_replace(GUINT hashkey, const T & value)
+ {
+ if(hashkey==GIM_INVALID_HASH)
+ {
+ //Insert anyway
+ _insert_unsorted(hashkey,value);
+ return GIM_INVALID_HASH;
+ }
+
+ GUINT cell_index = _assign_hash_table_cell(hashkey);
+
+ GUINT value_key = m_hash_table[cell_index];
+
+ if(value_key!= GIM_INVALID_HASH)
+ {//replaces the existing
+ m_nodes[value_key] = _node_type(hashkey,value);
+ return value_key;// index of the replaced element
+ }
+
+ m_hash_table[cell_index] = m_nodes.size();
+
+ _insert_unsorted(hashkey,value);
+ return GIM_INVALID_HASH;
+
+ }
+
+ //! @}
+
+ /*! \defgroup SORTED_ARRAY_STRUCTURES
+ \brief
+ Sorted array data management. The hash table has the indices to the corresponding m_nodes array
+ */
+ //! @{
+ inline bool _erase_sorted(GUINT index)
+ {
+ if(index>=(GUINT)m_nodes.size()) return false;
+ m_nodes.erase_sorted(index);
+ if(m_nodes.size()<2) m_sorted = false;
+ return true;
+ }
+
+ //! faster, but unsorted
+ inline bool _erase_unsorted(GUINT index)
+ {
+ if(index>=m_nodes.size()) return false;
+
+ GUINT lastindex = m_nodes.size()-1;
+ if(indexcheck_for_switching_to_hashtable();
+ }
+
+ //! Insert an element in an ordered array
+ inline GUINT _insert_sorted(GUINT hashkey, const T & value)
+ {
+ if(hashkey==GIM_INVALID_HASH || size()==0)
+ {
+ m_nodes.push_back(_node_type(hashkey,value));
+ return GIM_INVALID_HASH;
+ }
+ //Insert at last position
+ //Sort element
+
+
+ GUINT result_ind=0;
+ GUINT last_index = m_nodes.size()-1;
+ _node_type * ptr = m_nodes.pointer();
+
+ bool found = gim_binary_search_ex(
+ ptr,0,last_index,result_ind,hashkey,GIM_HASH_NODE_CMP_KEY_MACRO());
+
+
+ //Insert before found index
+ if(found)
+ {
+ return result_ind;
+ }
+ else
+ {
+ _insert_in_pos(hashkey, value, result_ind);
+ }
+ return GIM_INVALID_HASH;
+ }
+
+ inline GUINT _insert_sorted_replace(GUINT hashkey, const T & value)
+ {
+ if(hashkey==GIM_INVALID_HASH || size()==0)
+ {
+ m_nodes.push_back(_node_type(hashkey,value));
+ return GIM_INVALID_HASH;
+ }
+ //Insert at last position
+ //Sort element
+ GUINT result_ind;
+ GUINT last_index = m_nodes.size()-1;
+ _node_type * ptr = m_nodes.pointer();
+
+ bool found = gim_binary_search_ex(
+ ptr,0,last_index,result_ind,hashkey,GIM_HASH_NODE_CMP_KEY_MACRO());
+
+ //Insert before found index
+ if(found)
+ {
+ m_nodes[result_ind] = _node_type(hashkey,value);
+ }
+ else
+ {
+ _insert_in_pos(hashkey, value, result_ind);
+ }
+ return result_ind;
+ }
+
+ //! Fast insertion in m_nodes array
+ inline GUINT _insert_unsorted(GUINT hashkey, const T & value)
+ {
+ m_nodes.push_back(_node_type(hashkey,value));
+ m_sorted = false;
+ return GIM_INVALID_HASH;
+ }
+
+ //! @}
+
+
+public:
+
+ /*!
+
if node_size = 0, then this container becomes a simple sorted array allocator. reserve_size is used for reserve memory in m_nodes.
+ When the array size reaches the size equivalent to 'min_hash_table_size', then it becomes a hash table by calling check_for_switching_to_hashtable.
+
If node_size != 0, then this container becomes a hash table for ever
+
+ */
+ gim_hash_table(GUINT reserve_size = GIM_DEFAULT_HASH_TABLE_SIZE,
+ GUINT node_size = GIM_DEFAULT_HASH_TABLE_NODE_SIZE,
+ GUINT min_hash_table_size = GIM_INVALID_HASH)
+ {
+ m_hash_table = NULL;
+ m_table_size = 0;
+ m_sorted = false;
+ m_node_size = node_size;
+ m_min_hash_table_size = min_hash_table_size;
+
+ if(m_node_size!=0)
+ {
+ if(reserve_size!=0)
+ {
+ m_nodes.reserve(reserve_size);
+ _reserve_table_memory(reserve_size);
+ _invalidate_keys();
+ }
+ else
+ {
+ m_nodes.reserve(GIM_DEFAULT_HASH_TABLE_SIZE);
+ _reserve_table_memory(GIM_DEFAULT_HASH_TABLE_SIZE);
+ _invalidate_keys();
+ }
+ }
+ else if(reserve_size!=0)
+ {
+ m_nodes.reserve(reserve_size);
+ }
+
+ }
+
+ ~gim_hash_table()
+ {
+ _destroy();
+ }
+
+ inline bool is_hash_table()
+ {
+ if(m_hash_table) return true;
+ return false;
+ }
+
+ inline bool is_sorted()
+ {
+ if(size()<2) return true;
+ return m_sorted;
+ }
+
+ bool sort()
+ {
+ if(is_sorted()) return true;
+ if(m_nodes.size()<2) return false;
+
+
+ _node_type * ptr = m_nodes.pointer();
+ GUINT siz = m_nodes.size();
+ gim_sort_hash_node_array(ptr,siz);
+ m_sorted=true;
+
+
+
+ if(m_hash_table)
+ {
+ _rehash();
+ }
+ return true;
+ }
+
+ bool switch_to_hashtable()
+ {
+ if(m_hash_table) return false;
+ if(m_node_size==0) m_node_size = GIM_DEFAULT_HASH_TABLE_NODE_SIZE;
+ if(m_nodes.size()m_hash_table) return true;
+
+ if(!(m_nodes.size()< m_min_hash_table_size))
+ {
+ if(m_node_size == 0)
+ {
+ m_node_size = GIM_DEFAULT_HASH_TABLE_NODE_SIZE;
+ }
+
+ _resize_table(m_nodes.size()+1);
+ return true;
+ }
+ return false;
+ }
+
+ inline void set_sorted(bool value)
+ {
+ m_sorted = value;
+ }
+
+ //! Retrieves the amount of keys.
+ inline GUINT size() const
+ {
+ return m_nodes.size();
+ }
+
+ //! Retrieves the hash key.
+ inline GUINT get_key(GUINT index) const
+ {
+ return m_nodes[index].m_key;
+ }
+
+ //! Retrieves the value by index
+ /*!
+ */
+ inline T * get_value_by_index(GUINT index)
+ {
+ return &m_nodes[index].m_data;
+ }
+
+ inline const T& operator[](GUINT index) const
+ {
+ return m_nodes[index].m_data;
+ }
+
+ inline T& operator[](GUINT index)
+ {
+ return m_nodes[index].m_data;
+ }
+
+ //! Finds the index of the element with the key
+ /*!
+ \return the index in the array of the existing element,or GIM_INVALID_HASH if the element has been inserted
+ If so, the element has been inserted at the last position of the array.
+ */
+ inline GUINT find(GUINT hashkey)
+ {
+ if(m_hash_table)
+ {
+ GUINT cell_index = _find_cell(hashkey);
+ if(cell_index==GIM_INVALID_HASH) return GIM_INVALID_HASH;
+ return m_hash_table[cell_index];
+ }
+ GUINT last_index = m_nodes.size();
+ if(last_index<2)
+ {
+ if(last_index==0) return GIM_INVALID_HASH;
+ if(m_nodes[0].m_key == hashkey) return 0;
+ return GIM_INVALID_HASH;
+ }
+ else if(m_sorted)
+ {
+ //Binary search
+ GUINT result_ind = 0;
+ last_index--;
+ _node_type * ptr = m_nodes.pointer();
+
+ bool found = gim_binary_search_ex(ptr,0,last_index,result_ind,hashkey,GIM_HASH_NODE_CMP_KEY_MACRO());
+
+
+ if(found) return result_ind;
+ }
+ return GIM_INVALID_HASH;
+ }
+
+ //! Retrieves the value associated with the index
+ /*!
+ \return the found element, or null
+ */
+ inline T * get_value(GUINT hashkey)
+ {
+ GUINT index = find(hashkey);
+ if(index == GIM_INVALID_HASH) return NULL;
+ return &m_nodes[index].m_data;
+ }
+
+
+ /*!
+ */
+ inline bool erase_by_index(GUINT index)
+ {
+ if(index > m_nodes.size()) return false;
+
+ if(m_hash_table == NULL)
+ {
+ if(is_sorted())
+ {
+ return this->_erase_sorted(index);
+ }
+ else
+ {
+ return this->_erase_unsorted(index);
+ }
+ }
+ else
+ {
+ return this->_erase_by_index_hash_table(index);
+ }
+ return false;
+ }
+
+
+
+ inline bool erase_by_index_unsorted(GUINT index)
+ {
+ if(index > m_nodes.size()) return false;
+
+ if(m_hash_table == NULL)
+ {
+ return this->_erase_unsorted(index);
+ }
+ else
+ {
+ return this->_erase_by_index_hash_table(index);
+ }
+ return false;
+ }
+
+
+
+ /*!
+
+ */
+ inline bool erase_by_key(GUINT hashkey)
+ {
+ if(size()==0) return false;
+
+ if(m_hash_table)
+ {
+ return this->_erase_hash_table(hashkey);
+ }
+ //Binary search
+
+ if(is_sorted()==false) return false;
+
+ GUINT result_ind = find(hashkey);
+ if(result_ind!= GIM_INVALID_HASH)
+ {
+ return this->_erase_sorted(result_ind);
+ }
+ return false;
+ }
+
+ void clear()
+ {
+ m_nodes.clear();
+
+ if(m_hash_table==NULL) return;
+ GUINT datasize = m_table_size*m_node_size;
+ //Initialize the hashkeys.
+ GUINT i;
+ for(i=0;i_insert_hash_table(hashkey,element);
+ }
+ if(this->is_sorted())
+ {
+ return this->_insert_sorted(hashkey,element);
+ }
+ return this->_insert_unsorted(hashkey,element);
+ }
+
+ //! Insert an element into the hash, and could overrite an existing object with the same hash.
+ /*!
+ \return If GIM_INVALID_HASH, the object has been inserted succesfully. Else it returns the position
+ of the replaced element.
+ */
+ inline GUINT insert_override(GUINT hashkey, const T & element)
+ {
+ if(m_hash_table)
+ {
+ return this->_insert_hash_table_replace(hashkey,element);
+ }
+ if(this->is_sorted())
+ {
+ return this->_insert_sorted_replace(hashkey,element);
+ }
+ this->_insert_unsorted(hashkey,element);
+ return m_nodes.size();
+ }
+
+
+
+ //! Insert an element into the hash,But if this container is a sorted array, this inserts it unsorted
+ /*!
+ */
+ inline GUINT insert_unsorted(GUINT hashkey,const T & element)
+ {
+ if(m_hash_table)
+ {
+ return this->_insert_hash_table(hashkey,element);
+ }
+ return this->_insert_unsorted(hashkey,element);
+ }
+
+
+};
+
+//! @}
+
+
+
+#endif // GIM_CONTAINERS_H_INCLUDED
diff --git a/Extras/GIMPACT/include/GIMPACT/core/gim_linear_math.h b/Extras/GIMPACT/include/GIMPACT/core/gim_linear_math.h
new file mode 100755
index 000000000..26613ca98
--- /dev/null
+++ b/Extras/GIMPACT/include/GIMPACT/core/gim_linear_math.h
@@ -0,0 +1,1584 @@
+#ifndef GIM_LINEAR_H_INCLUDED
+#define GIM_LINEAR_H_INCLUDED
+
+/*! \file gim_linear_math.h
+*\author Francisco León Nájera
+Type Independant Vector and matrix operations.
+*/
+/*
+-----------------------------------------------------------------------------
+This source file is part of GIMPACT Library.
+
+For the latest info, see http://gimpact.sourceforge.net/
+
+Copyright (c) 2006 Francisco Leon Najera. C.C. 80087371.
+email: projectileman@yahoo.com
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of EITHER:
+ (1) The GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 2.1 of the License, or (at
+ your option) any later version. The text of the GNU Lesser
+ General Public License is included with this library in the
+ file GIMPACT-LICENSE-LGPL.TXT.
+ (2) The BSD-style license that is included with this library in
+ the file GIMPACT-LICENSE-BSD.TXT.
+ (3) The zlib/libpng license that is included with this library in
+ the file GIMPACT-LICENSE-ZLIB.TXT.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files
+ GIMPACT-LICENSE-LGPL.TXT, GIMPACT-LICENSE-ZLIB.TXT and GIMPACT-LICENSE-BSD.TXT for more details.
+
+-----------------------------------------------------------------------------
+*/
+
+
+#include "GIMPACT/core/gim_math.h"
+#include "GIMPACT/core/gim_geom_types.h"
+
+
+
+/*! \defgroup VECTOR_OPERATIONS
+T
+Operations for vectors : vec2f,vec3f and vec4f
+*/
+//! @{
+
+//! Zero out a 2D vector
+#define VEC_ZERO_2(a) \
+{ \
+ (a)[0] = (a)[1] = 0.0f; \
+}\
+
+
+//! Zero out a 3D vector
+#define VEC_ZERO(a) \
+{ \
+ (a)[0] = (a)[1] = (a)[2] = 0.0f; \
+}\
+
+
+/// Zero out a 4D vector
+#define VEC_ZERO_4(a) \
+{ \
+ (a)[0] = (a)[1] = (a)[2] = (a)[3] = 0.0f; \
+}\
+
+
+/// Vector copy
+#define VEC_COPY_2(b,a) \
+{ \
+ (b)[0] = (a)[0]; \
+ (b)[1] = (a)[1]; \
+}\
+
+
+/// Copy 3D vector
+#define VEC_COPY(b,a) \
+{ \
+ (b)[0] = (a)[0]; \
+ (b)[1] = (a)[1]; \
+ (b)[2] = (a)[2]; \
+}\
+
+
+/// Copy 4D vector
+#define VEC_COPY_4(b,a) \
+{ \
+ (b)[0] = (a)[0]; \
+ (b)[1] = (a)[1]; \
+ (b)[2] = (a)[2]; \
+ (b)[3] = (a)[3]; \
+}\
+
+/// VECTOR SWAP
+#define VEC_SWAP(b,a) \
+{ \
+ GIM_SWAP_NUMBERS((b)[0],(a)[0]);\
+ GIM_SWAP_NUMBERS((b)[1],(a)[1]);\
+ GIM_SWAP_NUMBERS((b)[2],(a)[2]);\
+}\
+
+/// Vector difference
+#define VEC_DIFF_2(v21,v2,v1) \
+{ \
+ (v21)[0] = (v2)[0] - (v1)[0]; \
+ (v21)[1] = (v2)[1] - (v1)[1]; \
+}\
+
+
+/// Vector difference
+#define VEC_DIFF(v21,v2,v1) \
+{ \
+ (v21)[0] = (v2)[0] - (v1)[0]; \
+ (v21)[1] = (v2)[1] - (v1)[1]; \
+ (v21)[2] = (v2)[2] - (v1)[2]; \
+}\
+
+
+/// Vector difference
+#define VEC_DIFF_4(v21,v2,v1) \
+{ \
+ (v21)[0] = (v2)[0] - (v1)[0]; \
+ (v21)[1] = (v2)[1] - (v1)[1]; \
+ (v21)[2] = (v2)[2] - (v1)[2]; \
+ (v21)[3] = (v2)[3] - (v1)[3]; \
+}\
+
+
+/// Vector sum
+#define VEC_SUM_2(v21,v2,v1) \
+{ \
+ (v21)[0] = (v2)[0] + (v1)[0]; \
+ (v21)[1] = (v2)[1] + (v1)[1]; \
+}\
+
+
+/// Vector sum
+#define VEC_SUM(v21,v2,v1) \
+{ \
+ (v21)[0] = (v2)[0] + (v1)[0]; \
+ (v21)[1] = (v2)[1] + (v1)[1]; \
+ (v21)[2] = (v2)[2] + (v1)[2]; \
+}\
+
+
+/// Vector sum
+#define VEC_SUM_4(v21,v2,v1) \
+{ \
+ (v21)[0] = (v2)[0] + (v1)[0]; \
+ (v21)[1] = (v2)[1] + (v1)[1]; \
+ (v21)[2] = (v2)[2] + (v1)[2]; \
+ (v21)[3] = (v2)[3] + (v1)[3]; \
+}\
+
+
+/// scalar times vector
+#define VEC_SCALE_2(c,a,b) \
+{ \
+ (c)[0] = (a)*(b)[0]; \
+ (c)[1] = (a)*(b)[1]; \
+}\
+
+
+/// scalar times vector
+#define VEC_SCALE(c,a,b) \
+{ \
+ (c)[0] = (a)*(b)[0]; \
+ (c)[1] = (a)*(b)[1]; \
+ (c)[2] = (a)*(b)[2]; \
+}\
+
+
+/// scalar times vector
+#define VEC_SCALE_4(c,a,b) \
+{ \
+ (c)[0] = (a)*(b)[0]; \
+ (c)[1] = (a)*(b)[1]; \
+ (c)[2] = (a)*(b)[2]; \
+ (c)[3] = (a)*(b)[3]; \
+}\
+
+
+/// accumulate scaled vector
+#define VEC_ACCUM_2(c,a,b) \
+{ \
+ (c)[0] += (a)*(b)[0]; \
+ (c)[1] += (a)*(b)[1]; \
+}\
+
+
+/// accumulate scaled vector
+#define VEC_ACCUM(c,a,b) \
+{ \
+ (c)[0] += (a)*(b)[0]; \
+ (c)[1] += (a)*(b)[1]; \
+ (c)[2] += (a)*(b)[2]; \
+}\
+
+
+/// accumulate scaled vector
+#define VEC_ACCUM_4(c,a,b) \
+{ \
+ (c)[0] += (a)*(b)[0]; \
+ (c)[1] += (a)*(b)[1]; \
+ (c)[2] += (a)*(b)[2]; \
+ (c)[3] += (a)*(b)[3]; \
+}\
+
+
+/// Vector dot product
+#define VEC_DOT_2(a,b) ((a)[0]*(b)[0] + (a)[1]*(b)[1])
+
+
+/// Vector dot product
+#define VEC_DOT(a,b) ((a)[0]*(b)[0] + (a)[1]*(b)[1] + (a)[2]*(b)[2])
+
+/// Vector dot product
+#define VEC_DOT_4(a,b) ((a)[0]*(b)[0] + (a)[1]*(b)[1] + (a)[2]*(b)[2] + (a)[3]*(b)[3])
+
+/// vector impact parameter (squared)
+#define VEC_IMPACT_SQ(bsq,direction,position) {\
+ GREAL _llel_ = VEC_DOT(direction, position);\
+ bsq = VEC_DOT(position, position) - _llel_*_llel_;\
+}\
+
+
+/// vector impact parameter
+#define VEC_IMPACT(bsq,direction,position) {\
+ VEC_IMPACT_SQ(bsq,direction,position); \
+ GIM_SQRT(bsq,bsq); \
+}\
+
+/// Vector length
+#define VEC_LENGTH_2(a,l)\
+{\
+ GREAL _pp = VEC_DOT_2(a,a);\
+ GIM_SQRT(_pp,l);\
+}\
+
+
+/// Vector length
+#define VEC_LENGTH(a,l)\
+{\
+ GREAL _pp = VEC_DOT(a,a);\
+ GIM_SQRT(_pp,l);\
+}\
+
+
+/// Vector length
+#define VEC_LENGTH_4(a,l)\
+{\
+ GREAL _pp = VEC_DOT_4(a,a);\
+ GIM_SQRT(_pp,l);\
+}\
+
+/// Vector inv length
+#define VEC_INV_LENGTH_2(a,l)\
+{\
+ GREAL _pp = VEC_DOT_2(a,a);\
+ GIM_INV_SQRT(_pp,l);\
+}\
+
+
+/// Vector inv length
+#define VEC_INV_LENGTH(a,l)\
+{\
+ GREAL _pp = VEC_DOT(a,a);\
+ GIM_INV_SQRT(_pp,l);\
+}\
+
+
+/// Vector inv length
+#define VEC_INV_LENGTH_4(a,l)\
+{\
+ GREAL _pp = VEC_DOT_4(a,a);\
+ GIM_INV_SQRT(_pp,l);\
+}\
+
+
+
+/// distance between two points
+#define VEC_DISTANCE(_len,_va,_vb) {\
+ vec3f _tmp_; \
+ VEC_DIFF(_tmp_, _vb, _va); \
+ VEC_LENGTH(_tmp_,_len); \
+}\
+
+
+/// Vector length
+#define VEC_CONJUGATE_LENGTH(a,l)\
+{\
+ GREAL _pp = 1.0 - a[0]*a[0] - a[1]*a[1] - a[2]*a[2];\
+ GIM_SQRT(_pp,l);\
+}\
+
+
+/// Vector length
+#define VEC_NORMALIZE(a) { \
+ GREAL len;\
+ VEC_INV_LENGTH(a,len); \
+ if(lenA[1]?(A[0]>A[2]?0:2):(A[1]>A[2]?1:2);\
+}\
+
+//! Finds the 2 smallest cartesian coordinates from a vector
+#define VEC_MINOR_AXES(vec, i0, i1)\
+{\
+ VEC_MAYOR_COORD(vec,i0);\
+ i0 = (i0+1)%3;\
+ i1 = (i0+1)%3;\
+}\
+
+
+
+
+#define VEC_EQUAL(v1,v2) (v1[0]==v2[0]&&v1[1]==v2[1]&&v1[2]==v2[2])
+
+#define VEC_NEAR_EQUAL(v1,v2) (GIM_NEAR_EQUAL(v1[0],v2[0])&&GIM_NEAR_EQUAL(v1[1],v2[1])&&GIM_NEAR_EQUAL(v1[2],v2[2]))
+
+
+/// Vector cross
+#define X_AXIS_CROSS_VEC(dst,src)\
+{ \
+ dst[0] = 0.0f; \
+ dst[1] = -src[2]; \
+ dst[2] = src[1]; \
+}\
+
+#define Y_AXIS_CROSS_VEC(dst,src)\
+{ \
+ dst[0] = src[2]; \
+ dst[1] = 0.0f; \
+ dst[2] = -src[0]; \
+}\
+
+#define Z_AXIS_CROSS_VEC(dst,src)\
+{ \
+ dst[0] = -src[1]; \
+ dst[1] = src[0]; \
+ dst[2] = 0.0f; \
+}\
+
+
+
+//! @}
+
+
+/*! \defgroup MATRIX_OPERATIONS
+Operations for matrices : mat2f, mat3f and mat4f
+*/
+//! @{
+
+/// initialize matrix
+#define IDENTIFY_MATRIX_3X3(m) \
+{ \
+ m[0][0] = 1.0; \
+ m[0][1] = 0.0; \
+ m[0][2] = 0.0; \
+ \
+ m[1][0] = 0.0; \
+ m[1][1] = 1.0; \
+ m[1][2] = 0.0; \
+ \
+ m[2][0] = 0.0; \
+ m[2][1] = 0.0; \
+ m[2][2] = 1.0; \
+}\
+
+/*! initialize matrix */
+#define IDENTIFY_MATRIX_4X4(m) \
+{ \
+ m[0][0] = 1.0; \
+ m[0][1] = 0.0; \
+ m[0][2] = 0.0; \
+ m[0][3] = 0.0; \
+ \
+ m[1][0] = 0.0; \
+ m[1][1] = 1.0; \
+ m[1][2] = 0.0; \
+ m[1][3] = 0.0; \
+ \
+ m[2][0] = 0.0; \
+ m[2][1] = 0.0; \
+ m[2][2] = 1.0; \
+ m[2][3] = 0.0; \
+ \
+ m[3][0] = 0.0; \
+ m[3][1] = 0.0; \
+ m[3][2] = 0.0; \
+ m[3][3] = 1.0; \
+}\
+
+/*! initialize matrix */
+#define ZERO_MATRIX_4X4(m) \
+{ \
+ m[0][0] = 0.0; \
+ m[0][1] = 0.0; \
+ m[0][2] = 0.0; \
+ m[0][3] = 0.0; \
+ \
+ m[1][0] = 0.0; \
+ m[1][1] = 0.0; \
+ m[1][2] = 0.0; \
+ m[1][3] = 0.0; \
+ \
+ m[2][0] = 0.0; \
+ m[2][1] = 0.0; \
+ m[2][2] = 0.0; \
+ m[2][3] = 0.0; \
+ \
+ m[3][0] = 0.0; \
+ m[3][1] = 0.0; \
+ m[3][2] = 0.0; \
+ m[3][3] = 0.0; \
+}\
+
+/*! matrix rotation X */
+#define ROTX_CS(m,cosine,sine) \
+{ \
+ /* rotation about the x-axis */ \
+ \
+ m[0][0] = 1.0; \
+ m[0][1] = 0.0; \
+ m[0][2] = 0.0; \
+ m[0][3] = 0.0; \
+ \
+ m[1][0] = 0.0; \
+ m[1][1] = (cosine); \
+ m[1][2] = (sine); \
+ m[1][3] = 0.0; \
+ \
+ m[2][0] = 0.0; \
+ m[2][1] = -(sine); \
+ m[2][2] = (cosine); \
+ m[2][3] = 0.0; \
+ \
+ m[3][0] = 0.0; \
+ m[3][1] = 0.0; \
+ m[3][2] = 0.0; \
+ m[3][3] = 1.0; \
+}\
+
+/*! matrix rotation Y */
+#define ROTY_CS(m,cosine,sine) \
+{ \
+ /* rotation about the y-axis */ \
+ \
+ m[0][0] = (cosine); \
+ m[0][1] = 0.0; \
+ m[0][2] = -(sine); \
+ m[0][3] = 0.0; \
+ \
+ m[1][0] = 0.0; \
+ m[1][1] = 1.0; \
+ m[1][2] = 0.0; \
+ m[1][3] = 0.0; \
+ \
+ m[2][0] = (sine); \
+ m[2][1] = 0.0; \
+ m[2][2] = (cosine); \
+ m[2][3] = 0.0; \
+ \
+ m[3][0] = 0.0; \
+ m[3][1] = 0.0; \
+ m[3][2] = 0.0; \
+ m[3][3] = 1.0; \
+}\
+
+/*! matrix rotation Z */
+#define ROTZ_CS(m,cosine,sine) \
+{ \
+ /* rotation about the z-axis */ \
+ \
+ m[0][0] = (cosine); \
+ m[0][1] = (sine); \
+ m[0][2] = 0.0; \
+ m[0][3] = 0.0; \
+ \
+ m[1][0] = -(sine); \
+ m[1][1] = (cosine); \
+ m[1][2] = 0.0; \
+ m[1][3] = 0.0; \
+ \
+ m[2][0] = 0.0; \
+ m[2][1] = 0.0; \
+ m[2][2] = 1.0; \
+ m[2][3] = 0.0; \
+ \
+ m[3][0] = 0.0; \
+ m[3][1] = 0.0; \
+ m[3][2] = 0.0; \
+ m[3][3] = 1.0; \
+}\
+
+/*! matrix copy */
+#define COPY_MATRIX_2X2(b,a) \
+{ \
+ b[0][0] = a[0][0]; \
+ b[0][1] = a[0][1]; \
+ \
+ b[1][0] = a[1][0]; \
+ b[1][1] = a[1][1]; \
+ \
+}\
+
+
+/*! matrix copy */
+#define COPY_MATRIX_2X3(b,a) \
+{ \
+ b[0][0] = a[0][0]; \
+ b[0][1] = a[0][1]; \
+ b[0][2] = a[0][2]; \
+ \
+ b[1][0] = a[1][0]; \
+ b[1][1] = a[1][1]; \
+ b[1][2] = a[1][2]; \
+}\
+
+
+/*! matrix copy */
+#define COPY_MATRIX_3X3(b,a) \
+{ \
+ b[0][0] = a[0][0]; \
+ b[0][1] = a[0][1]; \
+ b[0][2] = a[0][2]; \
+ \
+ b[1][0] = a[1][0]; \
+ b[1][1] = a[1][1]; \
+ b[1][2] = a[1][2]; \
+ \
+ b[2][0] = a[2][0]; \
+ b[2][1] = a[2][1]; \
+ b[2][2] = a[2][2]; \
+}\
+
+
+/*! matrix copy */
+#define COPY_MATRIX_4X4(b,a) \
+{ \
+ b[0][0] = a[0][0]; \
+ b[0][1] = a[0][1]; \
+ b[0][2] = a[0][2]; \
+ b[0][3] = a[0][3]; \
+ \
+ b[1][0] = a[1][0]; \
+ b[1][1] = a[1][1]; \
+ b[1][2] = a[1][2]; \
+ b[1][3] = a[1][3]; \
+ \
+ b[2][0] = a[2][0]; \
+ b[2][1] = a[2][1]; \
+ b[2][2] = a[2][2]; \
+ b[2][3] = a[2][3]; \
+ \
+ b[3][0] = a[3][0]; \
+ b[3][1] = a[3][1]; \
+ b[3][2] = a[3][2]; \
+ b[3][3] = a[3][3]; \
+}\
+
+
+/*! matrix transpose */
+#define TRANSPOSE_MATRIX_2X2(b,a) \
+{ \
+ b[0][0] = a[0][0]; \
+ b[0][1] = a[1][0]; \
+ \
+ b[1][0] = a[0][1]; \
+ b[1][1] = a[1][1]; \
+}\
+
+
+/*! matrix transpose */
+#define TRANSPOSE_MATRIX_3X3(b,a) \
+{ \
+ b[0][0] = a[0][0]; \
+ b[0][1] = a[1][0]; \
+ b[0][2] = a[2][0]; \
+ \
+ b[1][0] = a[0][1]; \
+ b[1][1] = a[1][1]; \
+ b[1][2] = a[2][1]; \
+ \
+ b[2][0] = a[0][2]; \
+ b[2][1] = a[1][2]; \
+ b[2][2] = a[2][2]; \
+}\
+
+
+/*! matrix transpose */
+#define TRANSPOSE_MATRIX_4X4(b,a) \
+{ \
+ b[0][0] = a[0][0]; \
+ b[0][1] = a[1][0]; \
+ b[0][2] = a[2][0]; \
+ b[0][3] = a[3][0]; \
+ \
+ b[1][0] = a[0][1]; \
+ b[1][1] = a[1][1]; \
+ b[1][2] = a[2][1]; \
+ b[1][3] = a[3][1]; \
+ \
+ b[2][0] = a[0][2]; \
+ b[2][1] = a[1][2]; \
+ b[2][2] = a[2][2]; \
+ b[2][3] = a[3][2]; \
+ \
+ b[3][0] = a[0][3]; \
+ b[3][1] = a[1][3]; \
+ b[3][2] = a[2][3]; \
+ b[3][3] = a[3][3]; \
+}\
+
+
+/*! multiply matrix by scalar */
+#define SCALE_MATRIX_2X2(b,s,a) \
+{ \
+ b[0][0] = (s) * a[0][0]; \
+ b[0][1] = (s) * a[0][1]; \
+ \
+ b[1][0] = (s) * a[1][0]; \
+ b[1][1] = (s) * a[1][1]; \
+}\
+
+
+/*! multiply matrix by scalar */
+#define SCALE_MATRIX_3X3(b,s,a) \
+{ \
+ b[0][0] = (s) * a[0][0]; \
+ b[0][1] = (s) * a[0][1]; \
+ b[0][2] = (s) * a[0][2]; \
+ \
+ b[1][0] = (s) * a[1][0]; \
+ b[1][1] = (s) * a[1][1]; \
+ b[1][2] = (s) * a[1][2]; \
+ \
+ b[2][0] = (s) * a[2][0]; \
+ b[2][1] = (s) * a[2][1]; \
+ b[2][2] = (s) * a[2][2]; \
+}\
+
+
+/*! multiply matrix by scalar */
+#define SCALE_MATRIX_4X4(b,s,a) \
+{ \
+ b[0][0] = (s) * a[0][0]; \
+ b[0][1] = (s) * a[0][1]; \
+ b[0][2] = (s) * a[0][2]; \
+ b[0][3] = (s) * a[0][3]; \
+ \
+ b[1][0] = (s) * a[1][0]; \
+ b[1][1] = (s) * a[1][1]; \
+ b[1][2] = (s) * a[1][2]; \
+ b[1][3] = (s) * a[1][3]; \
+ \
+ b[2][0] = (s) * a[2][0]; \
+ b[2][1] = (s) * a[2][1]; \
+ b[2][2] = (s) * a[2][2]; \
+ b[2][3] = (s) * a[2][3]; \
+ \
+ b[3][0] = s * a[3][0]; \
+ b[3][1] = s * a[3][1]; \
+ b[3][2] = s * a[3][2]; \
+ b[3][3] = s * a[3][3]; \
+}\
+
+
+/*! multiply matrix by scalar */
+#define SCALE_VEC_MATRIX_2X2(b,svec,a) \
+{ \
+ b[0][0] = svec[0] * a[0][0]; \
+ b[1][0] = svec[0] * a[1][0]; \
+ \
+ b[0][1] = svec[1] * a[0][1]; \
+ b[1][1] = svec[1] * a[1][1]; \
+}\
+
+
+/*! multiply matrix by scalar. Each columns is scaled by each scalar vector component */
+#define SCALE_VEC_MATRIX_3X3(b,svec,a) \
+{ \
+ b[0][0] = svec[0] * a[0][0]; \
+ b[1][0] = svec[0] * a[1][0]; \
+ b[2][0] = svec[0] * a[2][0]; \
+ \
+ b[0][1] = svec[1] * a[0][1]; \
+ b[1][1] = svec[1] * a[1][1]; \
+ b[2][1] = svec[1] * a[2][1]; \
+ \
+ b[0][2] = svec[2] * a[0][2]; \
+ b[1][2] = svec[2] * a[1][2]; \
+ b[2][2] = svec[2] * a[2][2]; \
+}\
+
+
+/*! multiply matrix by scalar */
+#define SCALE_VEC_MATRIX_4X4(b,svec,a) \
+{ \
+ b[0][0] = svec[0] * a[0][0]; \
+ b[1][0] = svec[0] * a[1][0]; \
+ b[2][0] = svec[0] * a[2][0]; \
+ b[3][0] = svec[0] * a[3][0]; \
+ \
+ b[0][1] = svec[1] * a[0][1]; \
+ b[1][1] = svec[1] * a[1][1]; \
+ b[2][1] = svec[1] * a[2][1]; \
+ b[3][1] = svec[1] * a[3][1]; \
+ \
+ b[0][2] = svec[2] * a[0][2]; \
+ b[1][2] = svec[2] * a[1][2]; \
+ b[2][2] = svec[2] * a[2][2]; \
+ b[3][2] = svec[2] * a[3][2]; \
+ \
+ b[0][3] = svec[3] * a[0][3]; \
+ b[1][3] = svec[3] * a[1][3]; \
+ b[2][3] = svec[3] * a[2][3]; \
+ b[3][3] = svec[3] * a[3][3]; \
+}\
+
+
+/*! multiply matrix by scalar */
+#define ACCUM_SCALE_MATRIX_2X2(b,s,a) \
+{ \
+ b[0][0] += (s) * a[0][0]; \
+ b[0][1] += (s) * a[0][1]; \
+ \
+ b[1][0] += (s) * a[1][0]; \
+ b[1][1] += (s) * a[1][1]; \
+}\
+
+
+/*! multiply matrix by scalar */
+#define ACCUM_SCALE_MATRIX_3X3(b,s,a) \
+{ \
+ b[0][0] += (s) * a[0][0]; \
+ b[0][1] += (s) * a[0][1]; \
+ b[0][2] += (s) * a[0][2]; \
+ \
+ b[1][0] += (s) * a[1][0]; \
+ b[1][1] += (s) * a[1][1]; \
+ b[1][2] += (s) * a[1][2]; \
+ \
+ b[2][0] += (s) * a[2][0]; \
+ b[2][1] += (s) * a[2][1]; \
+ b[2][2] += (s) * a[2][2]; \
+}\
+
+
+/*! multiply matrix by scalar */
+#define ACCUM_SCALE_MATRIX_4X4(b,s,a) \
+{ \
+ b[0][0] += (s) * a[0][0]; \
+ b[0][1] += (s) * a[0][1]; \
+ b[0][2] += (s) * a[0][2]; \
+ b[0][3] += (s) * a[0][3]; \
+ \
+ b[1][0] += (s) * a[1][0]; \
+ b[1][1] += (s) * a[1][1]; \
+ b[1][2] += (s) * a[1][2]; \
+ b[1][3] += (s) * a[1][3]; \
+ \
+ b[2][0] += (s) * a[2][0]; \
+ b[2][1] += (s) * a[2][1]; \
+ b[2][2] += (s) * a[2][2]; \
+ b[2][3] += (s) * a[2][3]; \
+ \
+ b[3][0] += (s) * a[3][0]; \
+ b[3][1] += (s) * a[3][1]; \
+ b[3][2] += (s) * a[3][2]; \
+ b[3][3] += (s) * a[3][3]; \
+}\
+
+/*! matrix product */
+/*! c[x][y] = a[x][0]*b[0][y]+a[x][1]*b[1][y]+a[x][2]*b[2][y]+a[x][3]*b[3][y];*/
+#define MATRIX_PRODUCT_2X2(c,a,b) \
+{ \
+ c[0][0] = a[0][0]*b[0][0]+a[0][1]*b[1][0]; \
+ c[0][1] = a[0][0]*b[0][1]+a[0][1]*b[1][1]; \
+ \
+ c[1][0] = a[1][0]*b[0][0]+a[1][1]*b[1][0]; \
+ c[1][1] = a[1][0]*b[0][1]+a[1][1]*b[1][1]; \
+ \
+}\
+
+/*! matrix product */
+/*! c[x][y] = a[x][0]*b[0][y]+a[x][1]*b[1][y]+a[x][2]*b[2][y]+a[x][3]*b[3][y];*/
+#define MATRIX_PRODUCT_3X3(c,a,b) \
+{ \
+ c[0][0] = a[0][0]*b[0][0]+a[0][1]*b[1][0]+a[0][2]*b[2][0]; \
+ c[0][1] = a[0][0]*b[0][1]+a[0][1]*b[1][1]+a[0][2]*b[2][1]; \
+ c[0][2] = a[0][0]*b[0][2]+a[0][1]*b[1][2]+a[0][2]*b[2][2]; \
+ \
+ c[1][0] = a[1][0]*b[0][0]+a[1][1]*b[1][0]+a[1][2]*b[2][0]; \
+ c[1][1] = a[1][0]*b[0][1]+a[1][1]*b[1][1]+a[1][2]*b[2][1]; \
+ c[1][2] = a[1][0]*b[0][2]+a[1][1]*b[1][2]+a[1][2]*b[2][2]; \
+ \
+ c[2][0] = a[2][0]*b[0][0]+a[2][1]*b[1][0]+a[2][2]*b[2][0]; \
+ c[2][1] = a[2][0]*b[0][1]+a[2][1]*b[1][1]+a[2][2]*b[2][1]; \
+ c[2][2] = a[2][0]*b[0][2]+a[2][1]*b[1][2]+a[2][2]*b[2][2]; \
+}\
+
+
+/*! matrix product */
+/*! c[x][y] = a[x][0]*b[0][y]+a[x][1]*b[1][y]+a[x][2]*b[2][y]+a[x][3]*b[3][y];*/
+#define MATRIX_PRODUCT_4X4(c,a,b) \
+{ \
+ c[0][0] = a[0][0]*b[0][0]+a[0][1]*b[1][0]+a[0][2]*b[2][0]+a[0][3]*b[3][0];\
+ c[0][1] = a[0][0]*b[0][1]+a[0][1]*b[1][1]+a[0][2]*b[2][1]+a[0][3]*b[3][1];\
+ c[0][2] = a[0][0]*b[0][2]+a[0][1]*b[1][2]+a[0][2]*b[2][2]+a[0][3]*b[3][2];\
+ c[0][3] = a[0][0]*b[0][3]+a[0][1]*b[1][3]+a[0][2]*b[2][3]+a[0][3]*b[3][3];\
+ \
+ c[1][0] = a[1][0]*b[0][0]+a[1][1]*b[1][0]+a[1][2]*b[2][0]+a[1][3]*b[3][0];\
+ c[1][1] = a[1][0]*b[0][1]+a[1][1]*b[1][1]+a[1][2]*b[2][1]+a[1][3]*b[3][1];\
+ c[1][2] = a[1][0]*b[0][2]+a[1][1]*b[1][2]+a[1][2]*b[2][2]+a[1][3]*b[3][2];\
+ c[1][3] = a[1][0]*b[0][3]+a[1][1]*b[1][3]+a[1][2]*b[2][3]+a[1][3]*b[3][3];\
+ \
+ c[2][0] = a[2][0]*b[0][0]+a[2][1]*b[1][0]+a[2][2]*b[2][0]+a[2][3]*b[3][0];\
+ c[2][1] = a[2][0]*b[0][1]+a[2][1]*b[1][1]+a[2][2]*b[2][1]+a[2][3]*b[3][1];\
+ c[2][2] = a[2][0]*b[0][2]+a[2][1]*b[1][2]+a[2][2]*b[2][2]+a[2][3]*b[3][2];\
+ c[2][3] = a[2][0]*b[0][3]+a[2][1]*b[1][3]+a[2][2]*b[2][3]+a[2][3]*b[3][3];\
+ \
+ c[3][0] = a[3][0]*b[0][0]+a[3][1]*b[1][0]+a[3][2]*b[2][0]+a[3][3]*b[3][0];\
+ c[3][1] = a[3][0]*b[0][1]+a[3][1]*b[1][1]+a[3][2]*b[2][1]+a[3][3]*b[3][1];\
+ c[3][2] = a[3][0]*b[0][2]+a[3][1]*b[1][2]+a[3][2]*b[2][2]+a[3][3]*b[3][2];\
+ c[3][3] = a[3][0]*b[0][3]+a[3][1]*b[1][3]+a[3][2]*b[2][3]+a[3][3]*b[3][3];\
+}\
+
+
+/*! matrix times vector */
+#define MAT_DOT_VEC_2X2(p,m,v) \
+{ \
+ p[0] = m[0][0]*v[0] + m[0][1]*v[1]; \
+ p[1] = m[1][0]*v[0] + m[1][1]*v[1]; \
+}\
+
+
+/*! matrix times vector */
+#define MAT_DOT_VEC_3X3(p,m,v) \
+{ \
+ p[0] = m[0][0]*v[0] + m[0][1]*v[1] + m[0][2]*v[2]; \
+ p[1] = m[1][0]*v[0] + m[1][1]*v[1] + m[1][2]*v[2]; \
+ p[2] = m[2][0]*v[0] + m[2][1]*v[1] + m[2][2]*v[2]; \
+}\
+
+
+/*! matrix times vector
+v is a vec4f
+*/
+#define MAT_DOT_VEC_4X4(p,m,v) \
+{ \
+ p[0] = m[0][0]*v[0] + m[0][1]*v[1] + m[0][2]*v[2] + m[0][3]*v[3]; \
+ p[1] = m[1][0]*v[0] + m[1][1]*v[1] + m[1][2]*v[2] + m[1][3]*v[3]; \
+ p[2] = m[2][0]*v[0] + m[2][1]*v[1] + m[2][2]*v[2] + m[2][3]*v[3]; \
+ p[3] = m[3][0]*v[0] + m[3][1]*v[1] + m[3][2]*v[2] + m[3][3]*v[3]; \
+}\
+
+/*! matrix times vector
+v is a vec3f
+and m is a mat4f
+Last column is added as the position
+*/
+#define MAT_DOT_VEC_3X4(p,m,v) \
+{ \
+ p[0] = m[0][0]*v[0] + m[0][1]*v[1] + m[0][2]*v[2] + m[0][3]; \
+ p[1] = m[1][0]*v[0] + m[1][1]*v[1] + m[1][2]*v[2] + m[1][3]; \
+ p[2] = m[2][0]*v[0] + m[2][1]*v[1] + m[2][2]*v[2] + m[2][3]; \
+}\
+
+
+/*! vector transpose times matrix */
+/*! p[j] = v[0]*m[0][j] + v[1]*m[1][j] + v[2]*m[2][j]; */
+#define VEC_DOT_MAT_3X3(p,v,m) \
+{ \
+ p[0] = v[0]*m[0][0] + v[1]*m[1][0] + v[2]*m[2][0]; \
+ p[1] = v[0]*m[0][1] + v[1]*m[1][1] + v[2]*m[2][1]; \
+ p[2] = v[0]*m[0][2] + v[1]*m[1][2] + v[2]*m[2][2]; \
+}\
+
+
+/*! affine matrix times vector */
+/** The matrix is assumed to be an affine matrix, with last two
+ * entries representing a translation */
+#define MAT_DOT_VEC_2X3(p,m,v) \
+{ \
+ p[0] = m[0][0]*v[0] + m[0][1]*v[1] + m[0][2]; \
+ p[1] = m[1][0]*v[0] + m[1][1]*v[1] + m[1][2]; \
+}\
+
+//! Transform a plane
+#define MAT_TRANSFORM_PLANE_4X4(pout,m,plane)\
+{ \
+ pout[0] = m[0][0]*plane[0] + m[0][1]*plane[1] + m[0][2]*plane[2];\
+ pout[1] = m[1][0]*plane[0] + m[1][1]*plane[1] + m[1][2]*plane[2];\
+ pout[2] = m[2][0]*plane[0] + m[2][1]*plane[1] + m[2][2]*plane[2];\
+ pout[3] = m[0][3]*pout[0] + m[1][3]*pout[1] + m[2][3]*pout[2] + plane[3];\
+}\
+
+
+
+/** inverse transpose of matrix times vector
+ *
+ * This macro computes inverse transpose of matrix m,
+ * and multiplies vector v into it, to yeild vector p
+ *
+ * DANGER !!! Do Not use this on normal vectors!!!
+ * It will leave normals the wrong length !!!
+ * See macro below for use on normals.
+ */
+#define INV_TRANSP_MAT_DOT_VEC_2X2(p,m,v) \
+{ \
+ GREAL det; \
+ \
+ det = m[0][0]*m[1][1] - m[0][1]*m[1][0]; \
+ p[0] = m[1][1]*v[0] - m[1][0]*v[1]; \
+ p[1] = - m[0][1]*v[0] + m[0][0]*v[1]; \
+ \
+ /* if matrix not singular, and not orthonormal, then renormalize */ \
+ if ((det!=1.0f) && (det != 0.0f)) { \
+ det = 1.0f / det; \
+ p[0] *= det; \
+ p[1] *= det; \
+ } \
+}\
+
+
+/** transform normal vector by inverse transpose of matrix
+ * and then renormalize the vector
+ *
+ * This macro computes inverse transpose of matrix m,
+ * and multiplies vector v into it, to yeild vector p
+ * Vector p is then normalized.
+ */
+#define NORM_XFORM_2X2(p,m,v) \
+{ \
+ GREAL len; \
+ \
+ /* do nothing if off-diagonals are zero and diagonals are \
+ * equal */ \
+ if ((m[0][1] != 0.0) || (m[1][0] != 0.0) || (m[0][0] != m[1][1])) { \
+ p[0] = m[1][1]*v[0] - m[1][0]*v[1]; \
+ p[1] = - m[0][1]*v[0] + m[0][0]*v[1]; \
+ \
+ len = p[0]*p[0] + p[1]*p[1]; \
+ GIM_INV_SQRT(len,len); \
+ p[0] *= len; \
+ p[1] *= len; \
+ } else { \
+ VEC_COPY_2 (p, v); \
+ } \
+}\
+
+
+/** outer product of vector times vector transpose
+ *
+ * The outer product of vector v and vector transpose t yeilds
+ * dyadic matrix m.
+ */
+#define OUTER_PRODUCT_2X2(m,v,t) \
+{ \
+ m[0][0] = v[0] * t[0]; \
+ m[0][1] = v[0] * t[1]; \
+ \
+ m[1][0] = v[1] * t[0]; \
+ m[1][1] = v[1] * t[1]; \
+}\
+
+
+/** outer product of vector times vector transpose
+ *
+ * The outer product of vector v and vector transpose t yeilds
+ * dyadic matrix m.
+ */
+#define OUTER_PRODUCT_3X3(m,v,t) \
+{ \
+ m[0][0] = v[0] * t[0]; \
+ m[0][1] = v[0] * t[1]; \
+ m[0][2] = v[0] * t[2]; \
+ \
+ m[1][0] = v[1] * t[0]; \
+ m[1][1] = v[1] * t[1]; \
+ m[1][2] = v[1] * t[2]; \
+ \
+ m[2][0] = v[2] * t[0]; \
+ m[2][1] = v[2] * t[1]; \
+ m[2][2] = v[2] * t[2]; \
+}\
+
+
+/** outer product of vector times vector transpose
+ *
+ * The outer product of vector v and vector transpose t yeilds
+ * dyadic matrix m.
+ */
+#define OUTER_PRODUCT_4X4(m,v,t) \
+{ \
+ m[0][0] = v[0] * t[0]; \
+ m[0][1] = v[0] * t[1]; \
+ m[0][2] = v[0] * t[2]; \
+ m[0][3] = v[0] * t[3]; \
+ \
+ m[1][0] = v[1] * t[0]; \
+ m[1][1] = v[1] * t[1]; \
+ m[1][2] = v[1] * t[2]; \
+ m[1][3] = v[1] * t[3]; \
+ \
+ m[2][0] = v[2] * t[0]; \
+ m[2][1] = v[2] * t[1]; \
+ m[2][2] = v[2] * t[2]; \
+ m[2][3] = v[2] * t[3]; \
+ \
+ m[3][0] = v[3] * t[0]; \
+ m[3][1] = v[3] * t[1]; \
+ m[3][2] = v[3] * t[2]; \
+ m[3][3] = v[3] * t[3]; \
+}\
+
+
+/** outer product of vector times vector transpose
+ *
+ * The outer product of vector v and vector transpose t yeilds
+ * dyadic matrix m.
+ */
+#define ACCUM_OUTER_PRODUCT_2X2(m,v,t) \
+{ \
+ m[0][0] += v[0] * t[0]; \
+ m[0][1] += v[0] * t[1]; \
+ \
+ m[1][0] += v[1] * t[0]; \
+ m[1][1] += v[1] * t[1]; \
+}\
+
+
+/** outer product of vector times vector transpose
+ *
+ * The outer product of vector v and vector transpose t yeilds
+ * dyadic matrix m.
+ */
+#define ACCUM_OUTER_PRODUCT_3X3(m,v,t) \
+{ \
+ m[0][0] += v[0] * t[0]; \
+ m[0][1] += v[0] * t[1]; \
+ m[0][2] += v[0] * t[2]; \
+ \
+ m[1][0] += v[1] * t[0]; \
+ m[1][1] += v[1] * t[1]; \
+ m[1][2] += v[1] * t[2]; \
+ \
+ m[2][0] += v[2] * t[0]; \
+ m[2][1] += v[2] * t[1]; \
+ m[2][2] += v[2] * t[2]; \
+}\
+
+
+/** outer product of vector times vector transpose
+ *
+ * The outer product of vector v and vector transpose t yeilds
+ * dyadic matrix m.
+ */
+#define ACCUM_OUTER_PRODUCT_4X4(m,v,t) \
+{ \
+ m[0][0] += v[0] * t[0]; \
+ m[0][1] += v[0] * t[1]; \
+ m[0][2] += v[0] * t[2]; \
+ m[0][3] += v[0] * t[3]; \
+ \
+ m[1][0] += v[1] * t[0]; \
+ m[1][1] += v[1] * t[1]; \
+ m[1][2] += v[1] * t[2]; \
+ m[1][3] += v[1] * t[3]; \
+ \
+ m[2][0] += v[2] * t[0]; \
+ m[2][1] += v[2] * t[1]; \
+ m[2][2] += v[2] * t[2]; \
+ m[2][3] += v[2] * t[3]; \
+ \
+ m[3][0] += v[3] * t[0]; \
+ m[3][1] += v[3] * t[1]; \
+ m[3][2] += v[3] * t[2]; \
+ m[3][3] += v[3] * t[3]; \
+}\
+
+
+/** determinant of matrix
+ *
+ * Computes determinant of matrix m, returning d
+ */
+#define DETERMINANT_2X2(d,m) \
+{ \
+ d = m[0][0] * m[1][1] - m[0][1] * m[1][0]; \
+}\
+
+
+/** determinant of matrix
+ *
+ * Computes determinant of matrix m, returning d
+ */
+#define DETERMINANT_3X3(d,m) \
+{ \
+ d = m[0][0] * (m[1][1]*m[2][2] - m[1][2] * m[2][1]); \
+ d -= m[0][1] * (m[1][0]*m[2][2] - m[1][2] * m[2][0]); \
+ d += m[0][2] * (m[1][0]*m[2][1] - m[1][1] * m[2][0]); \
+}\
+
+
+/** i,j,th cofactor of a 4x4 matrix
+ *
+ */
+#define COFACTOR_4X4_IJ(fac,m,i,j) \
+{ \
+ GUINT __ii[4], __jj[4], __k; \
+ \
+ for (__k=0; __k
+*/
+#define INV_MAT_DOT_VEC_3X3(p,m,v) \
+{ \
+ p[0] = MAT_DOT_COL(m,v,0); \
+ p[1] = MAT_DOT_COL(m,v,1); \
+ p[2] = MAT_DOT_COL(m,v,2); \
+}\
+
+
+//! @}
+
+#endif // GIM_VECTOR_H_INCLUDED
diff --git a/Extras/GIMPACT/include/GIMPACT/core/gim_math.h b/Extras/GIMPACT/include/GIMPACT/core/gim_math.h
new file mode 100755
index 000000000..18e55aded
--- /dev/null
+++ b/Extras/GIMPACT/include/GIMPACT/core/gim_math.h
@@ -0,0 +1,181 @@
+#ifndef GIM_MATH_H_INCLUDED
+#define GIM_MATH_H_INCLUDED
+/*! \file gim_math.h
+\author Francisco León Nájera
+*/
+/*
+-----------------------------------------------------------------------------
+This source file is part of GIMPACT Library.
+
+For the latest info, see http://gimpact.sourceforge.net/
+
+Copyright (c) 2006 Francisco Leon Najera. C.C. 80087371.
+email: projectileman@yahoo.com
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of EITHER:
+ (1) The GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 2.1 of the License, or (at
+ your option) any later version. The text of the GNU Lesser
+ General Public License is included with this library in the
+ file GIMPACT-LICENSE-LGPL.TXT.
+ (2) The BSD-style license that is included with this library in
+ the file GIMPACT-LICENSE-BSD.TXT.
+ (3) The zlib/libpng license that is included with this library in
+ the file GIMPACT-LICENSE-ZLIB.TXT.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files
+ GIMPACT-LICENSE-LGPL.TXT, GIMPACT-LICENSE-ZLIB.TXT and GIMPACT-LICENSE-BSD.TXT for more details.
+
+-----------------------------------------------------------------------------
+*/
+
+#include "LinearMath/btScalar.h"
+
+
+/*! \defgroup BASIC_TYPES
+Basic types and constants
+Conventions:
+Types starting with G
+Constants starting with G_
+*/
+//! @{
+
+#define GREAL btScalar
+#define GREAL2 double
+#define GINT int
+#define GUINT unsigned int
+#define GSHORT short
+#define GUSHORT unsigned short
+#define GINT64 long long
+#define GUINT64 unsigned long long
+
+//! @}
+
+/*! \defgroup BASIC_CONSTANTS
+Basic constants
+Conventions:
+Types starting with G
+Constants starting with G_
+*/
+//! @{
+
+#define G_PI 3.14159265358979f
+#define G_HALF_PI 1.5707963f
+//267948966
+#define G_TWO_PI 6.28318530f
+//71795864
+#define G_ROOT3 1.73205f
+#define G_ROOT2 1.41421f
+#define G_UINT_INFINITY 0xffffffff //!< A very very high value
+#define G_REAL_INFINITY FLT_MAX
+#define G_SIGN_BITMASK 0x80000000
+#define G_EPSILON SIMD_EPSILON
+//! @}
+
+
+/*! \defgroup SCALAR_TYPES
+\brief
+Precision type constants
+*/
+//! @{
+enum GIM_SCALAR_TYPES
+{
+ G_STYPE_REAL =0,
+ G_STYPE_REAL2,
+ G_STYPE_SHORT,
+ G_STYPE_USHORT,
+ G_STYPE_INT,
+ G_STYPE_UINT,
+ G_STYPE_INT64,
+ G_STYPE_UINT64
+};
+//! @}
+
+/*! \defgroup MATH_FUNCTIONS
+mathematical functions
+*/
+//! @{
+
+#define G_DEGTORAD(X) ((X)*3.1415926f/180.0f)
+#define G_RADTODEG(X) ((X)*180.0f/3.1415926f)
+
+//! Integer representation of a floating-point value.
+#define GIM_IR(x) ((GUINT&)(x))
+
+//! Signed integer representation of a floating-point value.
+#define GIM_SIR(x) ((GINT&)(x))
+
+//! Absolute integer representation of a floating-point value
+#define GIM_AIR(x) (GIM_IR(x)&0x7fffffff)
+
+//! Floating-point representation of an integer value.
+#define GIM_FR(x) ((GREAL&)(x))
+
+#define GIM_MAX(a,b) (ab?b:a)
+
+#define GIM_MAX3(a,b,c) GIM_MAX(a,GIM_MAX(b,c))
+#define GIM_MIN3(a,b,c) GIM_MIN(a,GIM_MIN(b,c))
+
+#define GIM_IS_ZERO(value) (value < G_EPSILON && value > -G_EPSILON)
+
+#define GIM_IS_NEGATIVE(value) (value <= -G_EPSILON)
+
+#define GIM_IS_POSISITVE(value) (value >= G_EPSILON)
+
+#define GIM_NEAR_EQUAL(v1,v2) GIM_IS_ZERO((v1-v2))
+
+///returns a clamped number
+#define GIM_CLAMP(number,minval,maxval) (numbermaxval?maxval:number))
+
+#define GIM_GREATER(x, y) fabsf(x) > (y)
+
+///Swap numbers
+#define GIM_SWAP_NUMBERS(a,b){ \
+ a = a+b; \
+ b = a-b; \
+ a = a-b; \
+}\
+
+#define GIM_INV_SQRT(va,isva)\
+{\
+ if(va<=0.0000001f)\
+ {\
+ isva = G_REAL_INFINITY;\
+ }\
+ else\
+ {\
+ GREAL _x = va * 0.5f;\
+ GUINT _y = 0x5f3759df - ( GIM_IR(va) >> 1);\
+ isva = GIM_FR(_y);\
+ isva = isva * ( 1.5f - ( _x * isva * isva ) );\
+ }\
+}\
+
+#define GIM_SQRT(va,sva)\
+{\
+ GIM_INV_SQRT(va,sva);\
+ sva = 1.0f/sva;\
+}\
+
+//! Computes 1.0f / sqrtf(x). Comes from Quake3. See http://www.magic-software.com/3DGEDInvSqrt.html
+inline GREAL gim_inv_sqrt(GREAL f)
+{
+ GREAL r;
+ GIM_INV_SQRT(f,r);
+ return r;
+}
+
+inline GREAL gim_sqrt(GREAL f)
+{
+ GREAL r;
+ GIM_SQRT(f,r);
+ return r;
+}
+
+//! @}
+
+#endif // GIM_MATH_H_INCLUDED
diff --git a/Extras/GIMPACT/include/GIMPACT/core/gim_memory.h b/Extras/GIMPACT/include/GIMPACT/core/gim_memory.h
new file mode 100755
index 000000000..8e654bdcf
--- /dev/null
+++ b/Extras/GIMPACT/include/GIMPACT/core/gim_memory.h
@@ -0,0 +1,208 @@
+#ifndef GIM_MEMORY_H_INCLUDED
+#define GIM_MEMORY_H_INCLUDED
+/*! \file gim_memory.h
+\author Francisco León Nájera
+*/
+/*
+-----------------------------------------------------------------------------
+This source file is part of GIMPACT Library.
+
+For the latest info, see http://gimpact.sourceforge.net/
+
+Copyright (c) 2006 Francisco Leon Najera. C.C. 80087371.
+email: projectileman@yahoo.com
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of EITHER:
+ (1) The GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 2.1 of the License, or (at
+ your option) any later version. The text of the GNU Lesser
+ General Public License is included with this library in the
+ file GIMPACT-LICENSE-LGPL.TXT.
+ (2) The BSD-style license that is included with this library in
+ the file GIMPACT-LICENSE-BSD.TXT.
+ (3) The zlib/libpng license that is included with this library in
+ the file GIMPACT-LICENSE-ZLIB.TXT.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files
+ GIMPACT-LICENSE-LGPL.TXT, GIMPACT-LICENSE-ZLIB.TXT and GIMPACT-LICENSE-BSD.TXT for more details.
+
+-----------------------------------------------------------------------------
+*/
+
+
+#include "GIMPACT/core/gim_math.h"
+#include
+
+//#define PREFETCH 1
+//! \defgroup PREFETCH
+//! @{
+#ifdef PREFETCH
+#include // for prefetch
+#define pfval 64
+#define pfval2 128
+//! Prefetch 64
+#define pf(_x,_i) _mm_prefetch((void *)(_x + _i + pfval), 0)
+//! Prefetch 128
+#define pf2(_x,_i) _mm_prefetch((void *)(_x + _i + pfval2), 0)
+#else
+//! Prefetch 64
+#define pf(_x,_i)
+//! Prefetch 128
+#define pf2(_x,_i)
+#endif
+//! @}
+
+/*! \defgroup ARRAY_UTILITIES
+\brief
+Functions for manip packed arrays of numbers
+*/
+//! @{
+#define GIM_COPY_ARRAYS(dest_array,source_array,element_count)\
+{\
+ for (GUINT _i_=0;_i_=SIMD_T_SIZE)
+ {
+ *(ui_dst_ptr++) = *(ui_src_ptr++);
+ copysize-=SIMD_T_SIZE;
+ }
+ if(copysize==0) return;
+
+ char * c_src_ptr = (char *)ui_src_ptr;
+ char * c_dst_ptr = (char *)ui_dst_ptr;
+ while(copysize>0)
+ {
+ *(c_dst_ptr++) = *(c_src_ptr++);
+ copysize--;
+ }
+ return;
+#else
+ memcpy(dst,src,copysize);
+#endif
+}
+
+
+
+template
+inline void gim_swap_elements(T* _array,size_t _i,size_t _j)
+{
+ T _e_tmp_ = _array[_i];
+ _array[_i] = _array[_j];
+ _array[_j] = _e_tmp_;
+}
+
+
+template
+inline void gim_swap_elements_memcpy(T* _array,size_t _i,size_t _j)
+{
+ char _e_tmp_[sizeof(T)];
+ gim_simd_memcpy(_e_tmp_,&_array[_i],sizeof(T));
+ gim_simd_memcpy(&_array[_i],&_array[_j],sizeof(T));
+ gim_simd_memcpy(&_array[_j],_e_tmp_,sizeof(T));
+}
+
+template
+inline void gim_swap_elements_ptr(char * _array,size_t _i,size_t _j)
+{
+ char _e_tmp_[SIZE];
+ _i*=SIZE;
+ _j*=SIZE;
+ gim_simd_memcpy(_e_tmp_,_array+_i,SIZE);
+ gim_simd_memcpy(_array+_i,_array+_j,SIZE);
+ gim_simd_memcpy(_array+_j,_e_tmp_,SIZE);
+}
+
+#endif // GIM_MEMORY_H_INCLUDED
diff --git a/Extras/GIMPACT/include/GIMPACT/core/gim_radixsort.h b/Extras/GIMPACT/include/GIMPACT/core/gim_radixsort.h
new file mode 100755
index 000000000..cf2a6bacd
--- /dev/null
+++ b/Extras/GIMPACT/include/GIMPACT/core/gim_radixsort.h
@@ -0,0 +1,410 @@
+#ifndef GIM_RADIXSORT_H_INCLUDED
+#define GIM_RADIXSORT_H_INCLUDED
+/*! \file gim_radixsort.h
+\author Francisco León Nájera.
+Based on the work of Michael Herf : "fast floating-point radix sort"
+Avaliable on http://www.stereopsis.com/radix.html
+*/
+/*
+-----------------------------------------------------------------------------
+This source file is part of GIMPACT Library.
+
+For the latest info, see http://gimpact.sourceforge.net/
+
+Copyright (c) 2006 Francisco Leon Najera. C.C. 80087371.
+email: projectileman@yahoo.com
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of EITHER:
+ (1) The GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 2.1 of the License, or (at
+ your option) any later version. The text of the GNU Lesser
+ General Public License is included with this library in the
+ file GIMPACT-LICENSE-LGPL.TXT.
+ (2) The BSD-style license that is included with this library in
+ the file GIMPACT-LICENSE-BSD.TXT.
+ (3) The zlib/libpng license that is included with this library in
+ the file GIMPACT-LICENSE-ZLIB.TXT.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files
+ GIMPACT-LICENSE-LGPL.TXT, GIMPACT-LICENSE-ZLIB.TXT and GIMPACT-LICENSE-BSD.TXT for more details.
+
+-----------------------------------------------------------------------------
+*/
+
+#include "GIMPACT/core/gim_memory.h"
+
+/*! \defgroup SORTING
+\brief
+Macros for sorting.
+*/
+
+//! Prototype for comparators
+class less_comparator
+{
+ public:
+
+ template
+ inline int operator() ( const T& a, const Z& b )
+ {
+ return ( ab?1:0));
+ }
+};
+
+//! Prototype for comparators
+class integer_comparator
+{
+ public:
+
+ template
+ inline int operator() ( const T& a, const T& b )
+ {
+ return (int)(a-b);
+ }
+};
+
+//!Prototype for getting the integer representation of an object
+class uint_key_func
+{
+public:
+ template
+ inline GUINT operator()( const T& a)
+ {
+ return (GUINT)a;
+ }
+};
+
+
+//!Prototype for copying elements
+class copy_elements_func
+{
+public:
+ template
+ inline void operator()(T& a,T& b)
+ {
+ a = b;
+ }
+};
+
+//!Prototype for copying elements
+class memcopy_elements_func
+{
+public:
+ template
+ inline void operator()(T& a,T& b)
+ {
+ gim_simd_memcpy(&a,&b,sizeof(T));
+ }
+};
+
+
+//! @{
+struct GIM_RSORT_TOKEN
+{
+ GUINT m_key;
+ GUINT m_value;
+ GIM_RSORT_TOKEN()
+ {
+ }
+ GIM_RSORT_TOKEN(const GIM_RSORT_TOKEN& rtoken)
+ {
+ m_key = rtoken.m_key;
+ m_value = rtoken.m_value;
+ }
+
+ inline bool operator <(const GIM_RSORT_TOKEN& other) const
+ {
+ return (m_key < other.m_key);
+ }
+
+ inline bool operator >(const GIM_RSORT_TOKEN& other) const
+ {
+ return (m_key > other.m_key);
+ }
+};
+
+//! Prototype for comparators
+class GIM_RSORT_TOKEN_COMPARATOR
+{
+ public:
+
+ inline int operator()( const GIM_RSORT_TOKEN& a, const GIM_RSORT_TOKEN& b )
+ {
+ return (int)((a.m_key) - (b.m_key));
+ }
+};
+
+
+
+#define kHist 2048
+// ---- utils for accessing 11-bit quantities
+#define D11_0(x) (x & 0x7FF)
+#define D11_1(x) (x >> 11 & 0x7FF)
+#define D11_2(x) (x >> 22 )
+
+
+
+///Radix sort for unsigned integer keys
+inline void gim_radix_sort_rtokens(
+ GIM_RSORT_TOKEN * array,
+ GIM_RSORT_TOKEN * sorted, GUINT element_count)
+{
+ GUINT i;
+ GUINT b0[kHist * 3];
+ GUINT *b1 = b0 + kHist;
+ GUINT *b2 = b1 + kHist;
+ for (i = 0; i < kHist * 3; ++i)
+ {
+ b0[i] = 0;
+ }
+ GUINT fi;
+ GUINT pos;
+ for (i = 0; i < element_count; ++i)
+ {
+ fi = array[i].m_key;
+ b0[D11_0(fi)] ++;
+ b1[D11_1(fi)] ++;
+ b2[D11_2(fi)] ++;
+ }
+ {
+ GUINT sum0 = 0, sum1 = 0, sum2 = 0;
+ GUINT tsum;
+ for (i = 0; i < kHist; ++i)
+ {
+ tsum = b0[i] + sum0;
+ b0[i] = sum0 - 1;
+ sum0 = tsum;
+ tsum = b1[i] + sum1;
+ b1[i] = sum1 - 1;
+ sum1 = tsum;
+ tsum = b2[i] + sum2;
+ b2[i] = sum2 - 1;
+ sum2 = tsum;
+ }
+ }
+ for (i = 0; i < element_count; ++i)
+ {
+ fi = array[i].m_key;
+ pos = D11_0(fi);
+ pos = ++b0[pos];
+ sorted[pos].m_key = array[i].m_key;
+ sorted[pos].m_value = array[i].m_value;
+ }
+ for (i = 0; i < element_count; ++i)
+ {
+ fi = sorted[i].m_key;
+ pos = D11_1(fi);
+ pos = ++b1[pos];
+ array[pos].m_key = sorted[i].m_key;
+ array[pos].m_value = sorted[i].m_value;
+ }
+ for (i = 0; i < element_count; ++i)
+ {
+ fi = array[i].m_key;
+ pos = D11_2(fi);
+ pos = ++b2[pos];
+ sorted[pos].m_key = array[i].m_key;
+ sorted[pos].m_value = array[i].m_value;
+ }
+}
+
+
+
+
+/// Get the sorted tokens from an array. For generic use. Tokens are IRR_RSORT_TOKEN
+/*!
+*\param array Array of elements to sort
+*\param sorted_tokens Tokens of sorted elements
+*\param element_count element count
+*\param uintkey_macro Functor which retrieves the integer representation of an array element
+*/
+template
+void gim_radix_sort_array_tokens(
+ T* array ,
+ GIM_RSORT_TOKEN * sorted_tokens,
+ GUINT element_count,GETKEY_CLASS uintkey_macro)
+{
+ GIM_RSORT_TOKEN * _unsorted = (GIM_RSORT_TOKEN *) gim_alloc(sizeof(GIM_RSORT_TOKEN)*element_count);
+ for (GUINT _i=0;_i
+void gim_radix_sort(
+ T * array, GUINT element_count,
+ GETKEY_CLASS get_uintkey_macro, COPY_CLASS copy_elements_macro)
+{
+ GIM_RSORT_TOKEN * _sorted = (GIM_RSORT_TOKEN *) gim_alloc(sizeof(GIM_RSORT_TOKEN)*element_count);
+ gim_radix_sort_array_tokens(array,_sorted,element_count,get_uintkey_macro);
+ T * _original_array = (T *) gim_alloc(sizeof(T)*element_count);
+ gim_simd_memcpy(_original_array,array,sizeof(T)*element_count);
+ for (GUINT _i=0;_i
+bool gim_binary_search_ex(
+ const T* _array, GUINT _start_i,
+ GUINT _end_i,GUINT & _result_index,
+ const KEYCLASS & _search_key,
+ COMP_CLASS _comp_macro)
+{
+ GUINT _k;
+ int _comp_result;
+ GUINT _i = _start_i;
+ GUINT _j = _end_i+1;
+ while (_i < _j)
+ {
+ _k = (_j+_i-1)/2;
+ _comp_result = _comp_macro(_array[_k], _search_key);
+ if (_comp_result == 0)
+ {
+ _result_index = _k;
+ return true;
+ }
+ else if (_comp_result < 0)
+ {
+ _i = _k+1;
+ }
+ else
+ {
+ _j = _k;
+ }
+ }
+ _result_index = _i;
+ return false;
+}
+
+
+
+//! Failsafe Iterative binary search,Template version
+/*!
+If the element is not found, it returns the nearest upper element position, may be the further position after the last element.
+\param _array
+\param _start_i the beginning of the array
+\param _end_i the ending index of the array
+\param _search_key Value to find
+\param _result_index the index of the found element, or if not found then it will get the index of the closest bigger value
+\return true if found, else false
+*/
+template
+bool gim_binary_search(
+ const T*_array,GUINT _start_i,
+ GUINT _end_i,const T & _search_key,
+ GUINT & _result_index)
+{
+ GUINT _i = _start_i;
+ GUINT _j = _end_i+1;
+ GUINT _k;
+ while(_i < _j)
+ {
+ _k = (_j+_i-1)/2;
+ if(_array[_k]==_search_key)
+ {
+ _result_index = _k;
+ return true;
+ }
+ else if (_array[_k]<_search_key)
+ {
+ _i = _k+1;
+ }
+ else
+ {
+ _j = _k;
+ }
+ }
+ _result_index = _i;
+ return false;
+}
+
+
+
+///heap sort from http://www.csse.monash.edu.au/~lloyd/tildeAlgDS/Sort/Heap/
+template
+void gim_down_heap(T *pArr, GUINT k, GUINT n,COMP_CLASS CompareFunc)
+{
+ /* PRE: a[k+1..N] is a heap */
+ /* POST: a[k..N] is a heap */
+
+ T temp = pArr[k - 1];
+ /* k has child(s) */
+ while (k <= n/2)
+ {
+ int child = 2*k;
+
+ if ((child < (int)n) && CompareFunc(pArr[child - 1] , pArr[child])<0)
+ {
+ child++;
+ }
+ /* pick larger child */
+ if (CompareFunc(temp , pArr[child - 1])<0)
+ {
+ /* move child up */
+ pArr[k - 1] = pArr[child - 1];
+ k = child;
+ }
+ else
+ {
+ break;
+ }
+ }
+ pArr[k - 1] = temp;
+} /*downHeap*/
+
+
+template
+void gim_heap_sort(T *pArr, GUINT element_count, COMP_CLASS CompareFunc)
+{
+ /* sort a[0..N-1], N.B. 0 to N-1 */
+ GUINT k;
+ GUINT n = element_count;
+ for (k = n/2; k > 0; k--)
+ {
+ gim_down_heap(pArr, k, n, CompareFunc);
+ }
+
+ /* a[1..N] is now a heap */
+ while ( n>=2 )
+ {
+ gim_swap_elements(pArr,0,n-1); /* largest of a[0..n-1] */
+ --n;
+ /* restore a[1..i-1] heap */
+ gim_down_heap(pArr, 1, n, CompareFunc);
+ }
+}
+
+
+
+//! @}
+#endif // GIM_RADIXSORT_H_INCLUDED
diff --git a/Extras/GIMPACT/include/GIMPACT/core/gim_tri_collision.h b/Extras/GIMPACT/include/GIMPACT/core/gim_tri_collision.h
new file mode 100755
index 000000000..31725ab68
--- /dev/null
+++ b/Extras/GIMPACT/include/GIMPACT/core/gim_tri_collision.h
@@ -0,0 +1,381 @@
+#ifndef GIM_TRI_COLLISION_H_INCLUDED
+#define GIM_TRI_COLLISION_H_INCLUDED
+
+/*! \file gim_tri_collision.h
+\author Francisco León Nájera
+*/
+/*
+-----------------------------------------------------------------------------
+This source file is part of GIMPACT Library.
+
+For the latest info, see http://gimpact.sourceforge.net/
+
+Copyright (c) 2006 Francisco Leon Najera. C.C. 80087371.
+email: projectileman@yahoo.com
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of EITHER:
+ (1) The GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 2.1 of the License, or (at
+ your option) any later version. The text of the GNU Lesser
+ General Public License is included with this library in the
+ file GIMPACT-LICENSE-LGPL.TXT.
+ (2) The BSD-style license that is included with this library in
+ the file GIMPACT-LICENSE-BSD.TXT.
+ (3) The zlib/libpng license that is included with this library in
+ the file GIMPACT-LICENSE-ZLIB.TXT.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files
+ GIMPACT-LICENSE-LGPL.TXT, GIMPACT-LICENSE-ZLIB.TXT and GIMPACT-LICENSE-BSD.TXT for more details.
+
+-----------------------------------------------------------------------------
+*/
+
+#include "GIMPACT/core/gim_box_collision.h"
+#include "GIMPACT/core/gim_clip_polygon.h"
+
+/*! \addtogroup GEOMETRIC_OPERATIONS
+*/
+//! @{
+
+
+
+#define MAX_TRI_CLIPPING 16
+
+//! Structure for collision
+struct GIM_TRIANGLE_CONTACT_DATA
+{
+ GREAL m_penetration_depth;
+ GUINT m_point_count;
+ btVector4 m_separating_normal;
+ btVector3 m_points[MAX_TRI_CLIPPING];
+
+ SIMD_FORCE_INLINE void copy_from(const GIM_TRIANGLE_CONTACT_DATA& other)
+ {
+ m_penetration_depth = other.m_penetration_depth;
+ m_separating_normal = other.m_separating_normal;
+ m_point_count = other.m_point_count;
+ GUINT i = m_point_count;
+ while(i--)
+ {
+ m_points[i] = other.m_points[i];
+ }
+ }
+
+ GIM_TRIANGLE_CONTACT_DATA()
+ {
+ }
+
+ GIM_TRIANGLE_CONTACT_DATA(const GIM_TRIANGLE_CONTACT_DATA& other)
+ {
+ copy_from(other);
+ }
+
+
+
+
+ //! classify points that are closer
+ template
+ SIMD_FORCE_INLINE void mergepoints_generic(const CLASS_PLANE & plane,
+ GREAL margin, const btVector3 * points, GUINT point_count, DISTANCE_FUNC distance_func)
+ {
+ m_point_count = 0;
+ m_penetration_depth= -1000.0f;
+
+ GUINT point_indices[MAX_TRI_CLIPPING];
+
+ for(GUINT _k=0;_k=0.0f)
+ {
+ if(_dist>m_penetration_depth)
+ {
+ m_penetration_depth = _dist;
+ point_indices[0] = _k;
+ m_point_count=1;
+ }
+ else if((_dist+G_EPSILON)>=m_penetration_depth)
+ {
+ point_indices[m_point_count] = _k;
+ m_point_count++;
+ }
+ }
+ }
+
+ for(GUINT _k=0;_k u*axe1[i1] + ((vecproj[i2] - u*axe1[i2])/axe2[i2])*axe2[i1] = vecproj[i1]
+
+ --> u*axe1[i1] + vecproj[i2]*axe2[i1]/axe2[i2] - u*axe1[i2]*axe2[i1]/axe2[i2] = vecproj[i1]
+
+ --> u*(axe1[i1] - axe1[i2]*axe2[i1]/axe2[i2]) = vecproj[i1] - vecproj[i2]*axe2[i1]/axe2[i2]
+
+ --> u*((axe1[i1]*axe2[i2] - axe1[i2]*axe2[i1])/axe2[i2]) = (vecproj[i1]*axe2[i2] - vecproj[i2]*axe2[i1])/axe2[i2]
+
+ --> u*(axe1[i1]*axe2[i2] - axe1[i2]*axe2[i1]) = vecproj[i1]*axe2[i2] - vecproj[i2]*axe2[i1]
+
+ --> u = (vecproj[i1]*axe2[i2] - vecproj[i2]*axe2[i1]) /(axe1[i1]*axe2[i2] - axe1[i2]*axe2[i1])
+
+if 0.0<= u+v <=1.0 then they are inside of triangle
+
+ \return false if the point is outside of triangle.This function doesn't take the margin
+ */
+ SIMD_FORCE_INLINE bool get_uv_parameters(
+ const btVector3 & point,
+ const btVector3 & tri_plane,
+ GREAL & u, GREAL & v) const
+ {
+ btVector3 _axe1 = m_vertices[1]-m_vertices[0];
+ btVector3 _axe2 = m_vertices[2]-m_vertices[0];
+ btVector3 _vecproj = point - m_vertices[0];
+ GUINT _i1 = (tri_plane.closestAxis()+1)%3;
+ GUINT _i2 = (_i1+1)%3;
+ if(btFabs(_axe2[_i2])G_EPSILON)
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ //! is point in triangle beam?
+ /*!
+ Test if point is in triangle, with m_margin tolerance
+ */
+ SIMD_FORCE_INLINE bool is_point_inside(const btVector3 & point, const btVector3 & tri_normal) const
+ {
+ //Test with edge 0
+ btVector4 edge_plane;
+ this->get_edge_plane(0,tri_normal,edge_plane);
+ GREAL dist = DISTANCE_PLANE_POINT(edge_plane,point);
+ if(dist-m_margin>0.0f) return false; // outside plane
+
+ this->get_edge_plane(1,tri_normal,edge_plane);
+ dist = DISTANCE_PLANE_POINT(edge_plane,point);
+ if(dist-m_margin>0.0f) return false; // outside plane
+
+ this->get_edge_plane(2,tri_normal,edge_plane);
+ dist = DISTANCE_PLANE_POINT(edge_plane,point);
+ if(dist-m_margin>0.0f) return false; // outside plane
+ return true;
+ }
+
+
+ //! Bidireccional ray collision
+ SIMD_FORCE_INLINE bool ray_collision(
+ const btVector3 & vPoint,
+ const btVector3 & vDir, btVector3 & pout, btVector3 & triangle_normal,
+ GREAL & tparam, GREAL tmax = G_REAL_INFINITY)
+ {
+ btVector4 faceplane;
+ {
+ btVector3 dif1 = m_vertices[1] - m_vertices[0];
+ btVector3 dif2 = m_vertices[2] - m_vertices[0];
+ VEC_CROSS(faceplane,dif1,dif2);
+ faceplane[3] = m_vertices[0].dot(faceplane);
+ }
+
+ GUINT res = LINE_PLANE_COLLISION(faceplane,vDir,vPoint,pout,tparam,0.0f, tmax);
+ if(res == 0) return false;
+ if(! is_point_inside(pout,faceplane)) return false;
+
+ if(res==2) //invert normal
+ {
+ triangle_normal.setValue(-faceplane[0],-faceplane[1],-faceplane[2]);
+ }
+ else
+ {
+ triangle_normal.setValue(faceplane[0],faceplane[1],faceplane[2]);
+ }
+
+ VEC_NORMALIZE(triangle_normal);
+
+ return true;
+ }
+
+
+ //! one direccion ray collision
+ SIMD_FORCE_INLINE bool ray_collision_front_side(
+ const btVector3 & vPoint,
+ const btVector3 & vDir, btVector3 & pout, btVector3 & triangle_normal,
+ GREAL & tparam, GREAL tmax = G_REAL_INFINITY)
+ {
+ btVector4 faceplane;
+ {
+ btVector3 dif1 = m_vertices[1] - m_vertices[0];
+ btVector3 dif2 = m_vertices[2] - m_vertices[0];
+ VEC_CROSS(faceplane,dif1,dif2);
+ faceplane[3] = m_vertices[0].dot(faceplane);
+ }
+
+ GUINT res = LINE_PLANE_COLLISION(faceplane,vDir,vPoint,pout,tparam,0.0f, tmax);
+ if(res != 1) return false;
+
+ if(!is_point_inside(pout,faceplane)) return false;
+
+ triangle_normal.setValue(faceplane[0],faceplane[1],faceplane[2]);
+
+ VEC_NORMALIZE(triangle_normal);
+
+ return true;
+ }
+
+};
+
+
+
+//! @}
+
+#endif // GIM_TRI_COLLISION_H_INCLUDED
diff --git a/Extras/GIMPACT/include/GIMPACT/gim_manual.h b/Extras/GIMPACT/include/GIMPACT/gim_manual.h
new file mode 100755
index 000000000..09cf77495
--- /dev/null
+++ b/Extras/GIMPACT/include/GIMPACT/gim_manual.h
@@ -0,0 +1,146 @@
+#ifndef GIM_MANUAL_H_INCLUDED
+#define GIM_MANUAL_H_INCLUDED
+
+/*! \file gim_manual.h
+*\author Francisco León Nájera
+GIMPACT documentation
+
+*/
+/*
+-----------------------------------------------------------------------------
+This source file is part of GIMPACT Library.
+
+For the latest info, see http://gimpact.sourceforge.net/
+
+Copyright (c) 2006 Francisco Leon Najera. C.C. 80087371.
+email: projectileman@yahoo.com
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of EITHER:
+ (1) The GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 2.1 of the License, or (at
+ your option) any later version. The text of the GNU Lesser
+ General Public License is included with this library in the
+ file GIMPACT-LICENSE-LGPL.TXT.
+ (2) The BSD-style license that is included with this library in
+ the file GIMPACT-LICENSE-BSD.TXT.
+ (3) The zlib/libpng license that is included with this library in
+ the file GIMPACT-LICENSE-ZLIB.TXT.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files
+ GIMPACT-LICENSE-LGPL.TXT, GIMPACT-LICENSE-ZLIB.TXT and GIMPACT-LICENSE-BSD.TXT for more details.
+
+-----------------------------------------------------------------------------
+*/
+
+/*! \mainpage GIMPACT
+*\section INTRO INTRODUCTION
+
+GIMPACT is a software library with tools for geometry processing and collision detection, focused on solving most common problems on Virtual Reality development.
+
+
+Since Version 0.2, GIMPACT will work integrated with the Bullet Engine for general collision detection and physics. For more details, please visit http://www.continuousphysics.com/Bullet/
+
+
For updates, please visit http://sourceforge.net/projects/gimpact/
+
+*\section CONTENT
+- \subpage FEATURES
+- \subpage REQUIREMENTS
+- \subpage PROGRAMMERS_GUIDE "PROGRAMMERS GUIDE"
+- \subpage TODO
+*/
+/*! \page FEATURES
+- C++ oriented.
+- Extensible design.
+- Collision detection algorithm for concave shapes in the Bullet Physics Engine. See btGImpactCollisionAlgorithm.
+- Efficient Dynamic Hierarcht Bounding Box tree structures for handle collisions with composed shapes whose have large sets of primitives (triangles or convex shapes) See the GIM_BOX_TREE_SET class.
+- Collision detection for trimeshes with the btGImpactMeshShape class. Now GIMPACT works fine with the btStridingInterface class for getting the data from trimesh models.
+- Support for deformable trimeshes.
+- Collision detection for compound shapes through the btGImpactCompoundShape class. This class takes advantage from the Hierarcht Bounding Box structure (GIM_BOX_TREE_SET class).
+- Collision Shapes (Both btGImpactCompoundSape and btGImpactTrimeshShape ) can be shared by two or more Rigid Bodies in Bullet.
+
+*/
+/*! \page REQUIREMENTS
+- GIMPACT has dependencies to the Bullet Physics Engine.
+- Ansi C++ compiler,
+*/
+/*! \page PROGRAMMERS_GUIDE PROGRAMMERS GUIDE
+This guide will show how to incorpore the GIMPACt functionality on the Bullet Engine:
+*\section REG Registering the Algorithm
+For register this algorithm in Bullet, proceed as following:
+ \code
+btCollisionDispatcher * dispatcher = static_cast(m_dynamicsWorld ->getDispatcher());
+btGImpactCollisionAlgorithm::registerAlgorithm(dispatcher);
+ \endcode
+
+With the instructon above, btGImpactCollisionAlgorithm will handle:
+- Convex shapes vs GImpact shapes.
+- Concave shapes vs GImpact shapes.
+- Compoind shapes vs GImpact shapes.
+
+*\section CREATING_SHAPES Creating Shapes.
+*\subsection TRIMESH Creating trimeshes.
+
For creating trimeshes you must provide an interface for your model data. You could use btTriangleIndexVertexArray class for providing the indices and the vertices from your triangle models.
+
+For example, you could create a trimesh from memory as following:
+\code
+btTriangleIndexVertexArray* indexVertexArrays = new btTriangleIndexVertexArray(NUM_TRIANGLES,
+ &gIndices[0][0],
+ 3*sizeof(int),
+ NUM_VERTICES,(REAL*) &gVertices[0],sizeof(REAL)*3);
+\endcode
+
+
+Where gIndices is an array of integers and gVertices is an array of float with 3 components.
+
+Then you must create the Trimesh shape as following:
+\code
+btGImpactMeshShape * trimesh = new btGImpactMeshShape(indexVertexArrays);
+\endcode
+The next step is configuring the trimesh, for example changing the scale:
+\code
+trimesh->setLocalScaling(btVector3(4.f,4.f,4.f));
+\endcode
+At end, you must call btGImpactMeshShape.updateBound for ensure that the shape will build its internal Box set structure:
+\code
+trimesh->updateBound();// Call this method once before doing collisions
+\endcode
+Also you must call btGImpactMeshShape.postUpdate() each time when changing the trimesh data ( For deformable meshes), this will enable a flag to the trimesh shape which tells that the trimesh data has been changed and btGImpactMeshShape.updateBound will be called in collision routines.
+<
+
+*\subsection COMPOUND Compound Shapes.
+For compound shapes, you must create btGImpactCompoundShape objects. Then you could add
+sub shapes as following;
+\code
+btGImpactCompoundShape * mycompound = new btGImpactCompoundShape();
+
+btTransform localtransform;
+ .... Setting transformation
+
+//add shapes with transformation
+btCollisionShape * subshape = creatingShape(0);
+mycompound->addChildShape(localtransform,subshape);
+.... Setting transformation
+btCollisionShape * subshape2 = creatingShape(1);
+mycompound->addChildShape(localtransform,subshape);
+.... add more shapes
+\endcode
+At end, you must call btGImpactCompoundShape.updateBound for ensure that the shape will build its internal Box set structure:
+*/
+
+/*! \page TODO
+*\section FEATURE FEATURE REQUESTS
+- Tetrahedrization for solid trimeshes.
+- Examples for implement deformable collisions, like cloth simulations and finite elements dynamics.
+- Generic Ray collision functionality.
+- Implement Low level SAT algorithms for speed up convex collisions.
+*\section MISCELANEOUS
+- Improve the documentation.
+- Benchmarking.
+- Bug reports and Bug Fixes.
+*/
+
+
+#endif
diff --git a/Extras/GIMPACT/index.html b/Extras/GIMPACT/index.html
new file mode 100755
index 000000000..4289abd13
--- /dev/null
+++ b/Extras/GIMPACT/index.html
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/Extras/GIMPACT/src/Bullet/btGImpactCollisionAlgorithm.cpp b/Extras/GIMPACT/src/Bullet/btGImpactCollisionAlgorithm.cpp
new file mode 100755
index 000000000..59fb1fe92
--- /dev/null
+++ b/Extras/GIMPACT/src/Bullet/btGImpactCollisionAlgorithm.cpp
@@ -0,0 +1,924 @@
+/*
+Bullet Continuous Collision Detection and Physics Library
+Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
+
+This software is provided 'as-is', without any express or implied warranty.
+In no event will the authors be held liable for any damages arising from the use of this software.
+Permission is granted to anyone to use this software for any purpose,
+including commercial applications, and to alter it and redistribute it freely,
+subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
+2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
+3. This notice may not be removed or altered from any source distribution.
+*/
+
+/*
+Author: Francisco León Nájera
+Concave-Concave Collision
+
+*/
+
+#include "BulletCollision/CollisionDispatch/btManifoldResult.h"
+#include "LinearMath/btIDebugDraw.h"
+#include "BulletCollision/CollisionDispatch/btCollisionObject.h"
+#include "GIMPACT/Bullet/btGImpactCollisionAlgorithm.h"
+#include "GIMPACT/core/gim_contact.h"
+#include "BulletCollision/CollisionShapes/btBoxShape.h"
+
+#define BULLET_TRIANGLE_COLLISION 1
+#define TREE_PRIMITIVE_VS_BOX true
+#define GIMPACT_VS_PLANE_COLLISION 1
+
+
+//! Class for accessing the plane equation
+class btPlaneShape : public btStaticPlaneShape
+{
+public:
+
+ btPlaneShape(const btVector3& v, float f)
+ :btStaticPlaneShape(v,f)
+ {
+ }
+
+ void get_plane_equation(btVector4 &equation)
+ {
+ equation[0] = m_planeNormal[0];
+ equation[1] = m_planeNormal[1];
+ equation[2] = m_planeNormal[2];
+ equation[3] = m_planeConstant;
+ }
+
+
+ void get_plane_equation_transformed(const btTransform & trans,btVector4 &equation)
+ {
+ equation[0] = trans.getBasis().getRow(0).dot(m_planeNormal);
+ equation[1] = trans.getBasis().getRow(1).dot(m_planeNormal);
+ equation[2] = trans.getBasis().getRow(2).dot(m_planeNormal);
+ equation[3] = trans.getOrigin().dot(m_planeNormal) + m_planeConstant;
+ }
+};
+
+btGImpactCollisionAlgorithm::btGImpactCollisionAlgorithm( const btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* body0,btCollisionObject* body1)
+: btCollisionAlgorithm(ci)
+{
+ m_manifoldPtr = NULL;
+ m_convex_algorithm = NULL;
+}
+
+btGImpactCollisionAlgorithm::~btGImpactCollisionAlgorithm()
+{
+ clearCache();
+}
+
+
+
+//////////////////////////////////////////////////////////////////////////////////////////////
+
+
+void btGImpactCollisionAlgorithm::gimpactcompound_vs_gimpactcompound_find_pairs(
+ const btTransform & trans0,
+ const btTransform & trans1,
+ btGImpactCompoundShape * shape0,
+ btGImpactCompoundShape * shape1,gim_pair_set & pairset) const
+{
+ GIM_TREE_TREE_COLLIDER collider;
+ collider.find_collision(shape0->getBoxSet(),trans0,shape1->getBoxSet(),trans1,pairset,TREE_PRIMITIVE_VS_BOX);
+
+}
+
+void btGImpactCollisionAlgorithm::gimpacttrimeshpart_vs_gimpacttrimeshpart_find_pairs(
+ const btTransform & trans0,
+ const btTransform & trans1,
+ btGImpactMeshShapePart * shape0,
+ btGImpactMeshShapePart * shape1,gim_pair_set & pairset) const
+{
+ GIM_TREE_TREE_COLLIDER collider;
+
+ collider.find_collision(shape0->getBoxSet(),trans0,shape1->getBoxSet(),trans1,pairset,TREE_PRIMITIVE_VS_BOX);
+
+}
+
+void btGImpactCollisionAlgorithm::gimpactcompound_vs_gimpacttrimeshpart_find_pairs(
+ const btTransform & trans0,
+ const btTransform & trans1,
+ btGImpactCompoundShape * shape0,
+ btGImpactMeshShapePart * shape1,gim_pair_set & pairset) const
+{
+ GIM_TREE_TREE_COLLIDER collider;
+ collider.find_collision(shape0->getBoxSet(),trans0,shape1->getBoxSet(),trans1,pairset,TREE_PRIMITIVE_VS_BOX);
+}
+
+
+
+
+void btGImpactCollisionAlgorithm::shape_vs_shape_collision(
+ btCollisionObject * body0,
+ btCollisionObject * body1,
+ btCollisionShape * shape0,
+ btCollisionShape * shape1,bool swapped)
+{
+
+ btCollisionShape * orgshape0 = body0->getCollisionShape();
+ btCollisionShape * orgshape1 = body1->getCollisionShape();
+
+ body0->setCollisionShape(shape0);
+ body1->setCollisionShape(shape1);
+
+
+ if(swapped)
+ {
+ btCollisionAlgorithm* algorswapped = newAlgorithm(body1,body0);
+
+ m_resultOut->setPersistentManifold(m_manifoldPtr);
+ m_resultOut->setShapeIdentifiers(m_part1,m_triface1,m_part0,m_triface0);
+
+ algorswapped->processCollision(body1,body0,*m_dispatchInfo,m_resultOut);
+
+ delete algorswapped;
+ }
+ else
+ {
+ btCollisionAlgorithm* algor = newAlgorithm(body0,body1);
+
+ m_resultOut->setPersistentManifold(m_manifoldPtr);
+ m_resultOut->setShapeIdentifiers(m_part0,m_triface0,m_part1,m_triface1);
+
+ algor->processCollision(body0,body1,*m_dispatchInfo,m_resultOut);
+
+ delete algor;
+ }
+
+ body0->setCollisionShape(orgshape0);
+ body1->setCollisionShape(orgshape1);
+}
+
+void btGImpactCollisionAlgorithm::convex_vs_convex_collision(
+ btCollisionObject * body0,
+ btCollisionObject * body1,
+ btCollisionShape * shape0,
+ btCollisionShape * shape1)
+{
+ //shape_vs_shape_collision(body0,body1,shape0,shape1,false);
+ //return;
+
+ btCollisionShape * orgshape0 = body0->getCollisionShape();
+ btCollisionShape * orgshape1 = body1->getCollisionShape();
+
+ body0->setCollisionShape(shape0);
+ body1->setCollisionShape(shape1);
+
+
+ m_resultOut->setShapeIdentifiers(m_part0,m_triface0,m_part1,m_triface1);
+
+ checkConvexAlgorithm(body0,body1);
+ m_convex_algorithm->processCollision(body0,body1,*m_dispatchInfo,m_resultOut);
+
+ body0->setCollisionShape(orgshape0);
+ body1->setCollisionShape(orgshape1);
+
+}
+
+
+
+void btGImpactCollisionAlgorithm::gimpacttrimesh_vs_shape_collision(
+ btCollisionObject * body0,
+ btCollisionObject * body1,
+ btGImpactMeshShape * shape0,
+ btCollisionShape * shape1,bool swapped)
+{
+ GUINT i = shape0->getMeshPartCount();
+ while(i--)
+ {
+ btGImpactMeshShapePart * part = shape0->getMeshPart(i);
+ gimpacttrimeshpart_vs_shape_collision(body0,body1,part,shape1,swapped);
+ }
+}
+
+void btGImpactCollisionAlgorithm::gimpacttrimesh_vs_gimpacttrimesh(
+ btCollisionObject * body0,
+ btCollisionObject * body1,
+ btGImpactMeshShape * shape0,
+ btGImpactMeshShape * shape1)
+{
+ GUINT i = shape0->getMeshPartCount();
+ while(i--)
+ {
+ btGImpactMeshShapePart * part0 = shape0->getMeshPart(i);
+
+ GUINT j = shape1->getMeshPartCount();
+ while(j--)
+ {
+ btGImpactMeshShapePart * part1 = shape1->getMeshPart(j);
+ gimpacttrimeshpart_vs_gimpacttrimeshpart_collision(body0,body1,part0,part1,false);
+ }
+ }
+}
+
+void btGImpactCollisionAlgorithm::gimpacttrimesh_vs_gimpactcompound(
+ btCollisionObject * body0,
+ btCollisionObject * body1,
+ btGImpactMeshShape * shape0,
+ btGImpactCompoundShape * shape1,bool swapped)
+{
+ GUINT i = shape0->getMeshPartCount();
+ while(i--)
+ {
+ btGImpactMeshShapePart * part = shape0->getMeshPart(i);
+ gimpactcompound_vs_gimpacttrimeshpart_collision(body1,body0,shape1,part,!swapped);
+ }
+}
+
+
+
+void btGImpactCollisionAlgorithm::gimpacttrimesh_vs_trimeshpart(
+ btCollisionObject * body0,
+ btCollisionObject * body1,
+ btGImpactMeshShape * shape0,
+ btGImpactMeshShapePart * shape1,bool swapped)
+{
+ GUINT i = shape0->getMeshPartCount();
+ while(i--)
+ {
+ btGImpactMeshShapePart * part = shape0->getMeshPart(i);
+ gimpacttrimeshpart_vs_gimpacttrimeshpart_collision(body0,body1,part,shape1,swapped);
+ }
+}
+
+
+void btGImpactCollisionAlgorithm::gimpactcompound_vs_gimpactcompound_collision(
+ btCollisionObject * body0,
+ btCollisionObject * body1,
+ btGImpactCompoundShape * shape0,
+ btGImpactCompoundShape * shape1)
+{
+ btTransform orgtrans0 = body0->getWorldTransform();
+ btTransform orgtrans1 = body1->getWorldTransform();
+
+ gim_pair_set pairset;
+
+ gimpactcompound_vs_gimpactcompound_find_pairs(orgtrans0,orgtrans1,shape0,shape1,pairset);
+
+ if(pairset.size()== 0) return;
+
+// btCollisionShape * orgshape0 = body0->getCollisionShape();
+// btCollisionShape * orgshape1 = body1->getCollisionShape();
+
+ GUINT i = pairset.size();
+ while(i--)
+ {
+ const GIM_PAIR & pair = pairset[i];
+ btCollisionShape * colshape0 = shape0->getChildShape(pair.m_index1);
+ btCollisionShape * colshape1 = shape1->getChildShape(pair.m_index2);
+
+ btTransform childtrans0 = orgtrans0*shape0->getChildTransform(pair.m_index1);
+ btTransform childtrans1 = orgtrans1*shape1->getChildTransform(pair.m_index2);
+
+ body0->setWorldTransform(childtrans0);
+ body1->setWorldTransform(childtrans1);
+
+
+ //collide two shapes
+ shape_vs_shape_collision(body0,body1,colshape0,colshape1,false);
+
+ //restore transforms
+// body0->setCollisionShape(orgshape0);
+// body1->setCollisionShape(orgshape1);
+
+ body0->setWorldTransform(orgtrans0);
+ body1->setWorldTransform(orgtrans1);
+ }
+}
+
+
+void btGImpactCollisionAlgorithm::gimpactcompound_vs_gimpacttrimeshpart_collision(
+ btCollisionObject * body0,
+ btCollisionObject * body1,
+ btGImpactCompoundShape * shape0,
+ btGImpactMeshShapePart * shape1,bool swapped)
+{
+ //lock trimesh
+ shape1->lock();
+
+ btTransform orgtrans0 = body0->getWorldTransform();
+ btTransform orgtrans1 = body1->getWorldTransform();
+
+ gim_pair_set pairset;
+
+ gimpactcompound_vs_gimpacttrimeshpart_find_pairs(orgtrans0,orgtrans1,shape0,shape1,pairset);
+
+ if(pairset.size()== 0)
+ {
+ //unlock trimesh
+ shape1->unlock();
+ return;
+ }
+
+// btCollisionShape * orgshape0 = body0->getCollisionShape();
+// btCollisionShape * orgshape1 = body1->getCollisionShape();
+
+
+ m_part1 = shape1->getPart();
+ m_part0 = -1;
+ m_triface0 = -1;
+
+ btTriangleShapeEx bullet_triangle(btVector3(0.f,0.f,0.f),btVector3(0.f,0.f,0.f),btVector3(0.f,0.f,0.f));
+
+
+ GUINT i = pairset.size();
+
+ while(i--)
+ {
+ const GIM_PAIR & pair = pairset[i];
+ btCollisionShape * colshape0 = shape0->getChildShape(pair.m_index1);
+ btTransform childtrans0 = orgtrans0*shape0->getChildTransform(pair.m_index1);
+ body0->setWorldTransform(childtrans0);
+
+ shape1->getBulletTriangle(pair.m_index2,bullet_triangle);
+ m_triface1 = pair.m_index2;
+
+ //collide two shapes
+ shape_vs_shape_collision(body0,body1,colshape0,&bullet_triangle,swapped);
+
+ //restore transforms
+// body0->setCollisionShape(orgshape0);
+// body1->setCollisionShape(orgshape1);
+ body1->setWorldTransform(orgtrans1);
+ }
+
+ //unlock trimesh
+ shape1->unlock();
+}
+
+
+
+void btGImpactCollisionAlgorithm::gimpactcompound_vs_shape_collision(
+ btCollisionObject * body0,
+ btCollisionObject * body1,
+ btGImpactCompoundShape * shape0,
+ btCollisionShape * shape1,bool swapped)
+{
+ btTransform orgtrans0 = body0->getWorldTransform();
+
+ btTransform trans1to0 = orgtrans0.inverse();
+ trans1to0 *= body1->getWorldTransform();
+
+ GIM_AABB boxshape;
+ shape1->getAabb(trans1to0,boxshape.m_min,boxshape.m_max);
+ gim_array collided_results;
+ shape0->getBoxSet()->boxQuery(boxshape, collided_results);
+
+ if(collided_results.size() == 0) return;
+
+
+
+ GUINT i = collided_results.size();
+
+ while(i--)
+ {
+ btCollisionShape * colshape0 = shape0->getChildShape(collided_results[i]);
+ btTransform childtrans0 = orgtrans0*shape0->getChildTransform(collided_results[i]);
+
+ body0->setWorldTransform(childtrans0);
+
+ //collide two shapes
+ shape_vs_shape_collision(body0,body1,colshape0,shape1,swapped);
+
+ //restore transforms
+// body0->setCollisionShape(orgshape0);
+ body0->setWorldTransform(orgtrans0);
+ }
+
+}
+
+
+
+
+void btGImpactCollisionAlgorithm::gimpacttrimeshpart_vs_gimpacttrimeshpart_collision(
+ btCollisionObject * body0,
+ btCollisionObject * body1,
+ btGImpactMeshShapePart * shape0,
+ btGImpactMeshShapePart * shape1,bool swapped)
+{
+ shape0->lock();
+ shape1->lock();
+
+ btGImpactMeshShapePart * trishape0;
+ btGImpactMeshShapePart * trishape1;
+ btCollisionObject * tribody0;
+ btCollisionObject * tribody1;
+
+ if(swapped)
+ {
+ trishape0 = shape1;
+ trishape1 = shape0;
+ tribody0 = body1;
+ tribody1 = body0;
+ }
+ else
+ {
+ trishape0 = shape0;
+ trishape1 = shape1;
+ tribody0 = body0;
+ tribody1 = body1;
+ }
+
+ btTransform orgtrans0 = tribody0->getWorldTransform();
+ btTransform orgtrans1 = tribody1->getWorldTransform();
+
+ gim_pair_set pairset;
+
+ gimpacttrimeshpart_vs_gimpacttrimeshpart_find_pairs(orgtrans0,orgtrans1,trishape0,trishape1,pairset);
+
+ if(pairset.size()== 0)
+ {
+ shape0->unlock();
+ shape1->unlock();
+ return;
+ }
+
+ m_part0 = trishape0->getPart();
+ m_part1 = trishape1->getPart();
+
+#ifdef BULLET_TRIANGLE_COLLISION
+
+ btTriangleShapeEx tri0(btVector3(0.f,0.f,0.f),btVector3(0.f,0.f,0.f),btVector3(0.f,0.f,0.f));
+ btTriangleShapeEx tri1(btVector3(0.f,0.f,0.f),btVector3(0.f,0.f,0.f),btVector3(0.f,0.f,0.f));
+ GUINT i = pairset.size();
+ while(i--)
+ {
+ const GIM_PAIR & pair = pairset[i];
+ m_triface0 = pair.m_index1;
+ m_triface1 = pair.m_index2;
+
+ trishape0->getBulletTriangle(pair.m_index1,tri0);
+ trishape1->getBulletTriangle(pair.m_index2,tri1);
+
+
+ convex_vs_convex_collision(
+ tribody0,
+ tribody1,
+ &tri0,
+ &tri1);
+
+ }
+ //unlock
+ shape0->unlock();
+ shape1->unlock();
+
+#else
+ gim_contact_array tempcontacts;
+ GIM_TRIANGLE tri0;
+ GIM_TRIANGLE tri1;
+ GIM_TRIANGLE_CONTACT_DATA contact_data;
+ GUINT i = pairset.size();
+ while(i--)
+ {
+ const GIM_PAIR & pair = pairset[i];
+
+ trishape0->getTriangle(pair.m_index1,tri0);
+ trishape1->getTriangle(pair.m_index2,tri1);
+
+ tri0.apply_transform(orgtrans0);
+ tri1.apply_transform(orgtrans1);
+
+ if(tri0.collide_triangle(tri1,contact_data))
+ {
+ tempcontacts.push_triangle_contacts(contact_data,pair.m_index1,pair.m_index2);
+ }
+ }
+ //unlock
+ shape0->unlock();
+ shape1->unlock();
+
+ if(tempcontacts.size()==0) return;
+
+ //sort contacts
+ gim_contact_array contacts;
+ contacts.merge_contacts(tempcontacts,true);
+ // put contacts
+ m_part0 = trishape0->getPart();
+ m_part1 = trishape1->getPart();
+ i = contacts.size();
+ while(i--)
+ {
+ GIM_CONTACT * pcontact = &contacts[i];
+
+ m_triface0 = pcontact->m_feature1;
+ m_triface1 = pcontact->m_feature2;
+
+ addContactPoint(tribody0, tribody1,
+ pcontact->m_point,
+ pcontact->m_normal,
+ -pcontact->m_depth);
+ }
+#endif
+}
+
+void btGImpactCollisionAlgorithm::gimpacttrimeshpart_vs_plane_collision(
+ btCollisionObject * body0,
+ btCollisionObject * body1,
+ btGImpactMeshShapePart * shape0,
+ btStaticPlaneShape * shape1,bool swapped)
+{
+
+
+ btTransform orgtrans0 = body0->getWorldTransform();
+ btTransform orgtrans1 = body1->getWorldTransform();
+
+ btPlaneShape * planeshape = static_cast(shape1);
+ btVector4 plane;
+ planeshape->get_plane_equation_transformed(orgtrans1,plane);
+
+ //test box against plane
+
+ GIM_AABB tribox;
+ shape0->getAabb(orgtrans0,tribox.m_min,tribox.m_max);
+ tribox.increment_margin(planeshape->getMargin());
+
+ if( tribox.plane_classify(plane)!= G_COLLIDE_PLANE) return;
+
+ shape0->lock();
+
+ GREAL margin = shape0->getMargin() + planeshape->getMargin();
+
+ btVector3 vertex;
+ GUINT vi = shape0->getVertexCount();
+ while(vi--)
+ {
+ shape0->getVertex(vi,vertex);
+ vertex = orgtrans0(vertex);
+
+ GREAL distance = vertex.dot(plane) - plane[3] - margin;
+
+ if(distance<0.0)//add contact
+ {
+ if(swapped)
+ {
+ addContactPoint(body1, body0,
+ vertex,
+ -plane,
+ distance);
+ }
+ else
+ {
+ addContactPoint(body0, body1,
+ vertex,
+ plane,
+ distance);
+ }
+ }
+ }
+
+ shape0->unlock();
+}
+
+
+class btGImpactTriangleCallback: public btTriangleCallback
+{
+public:
+ btGImpactCollisionAlgorithm * algorithm;
+ btCollisionObject * body0;
+ btCollisionObject * body1;
+ btGImpactMeshShapePart * gimpactshape0;
+ bool swapped;
+ btScalar margin;
+
+
+ virtual void processTriangle(btVector3* triangle, int partId, int triangleIndex)
+ {
+ btTriangleShapeEx tri1(triangle[0],triangle[1],triangle[2]);
+ tri1.setMargin(margin);
+ algorithm->gimpacttrimeshpart_vs_shape_collision(
+ body0,body1,gimpactshape0,&tri1,swapped);
+ }
+};
+
+
+
+void btGImpactCollisionAlgorithm::gimpacttrimeshpart_vs_concave_collision(
+ btCollisionObject * body0,
+ btCollisionObject * body1,
+ btGImpactMeshShapePart * shape0,
+ btConcaveShape * shape1,bool swapped)
+{
+
+ //create the callback
+ btGImpactTriangleCallback tricallback;
+ tricallback.algorithm = this;
+ tricallback.body0 = body0;
+ tricallback.body1 = body1;
+ tricallback.gimpactshape0 = shape0;
+ tricallback.swapped = swapped;
+ tricallback.margin = shape1->getMargin();
+
+
+
+ //getting the trimesh AABB
+ btTransform gimpactInConcaveSpace;
+ gimpactInConcaveSpace = body1->getWorldTransform().inverse() * body0->getWorldTransform();
+ btVector3 minAABB,maxAABB;
+ shape0->getAabb(gimpactInConcaveSpace,minAABB,maxAABB);
+
+ shape1->processAllTriangles(&tricallback,minAABB,maxAABB);
+
+
+
+}
+
+
+void btGImpactCollisionAlgorithm::gimpacttrimeshpart_vs_shape_collision(
+ btCollisionObject * body0,
+ btCollisionObject * body1,
+ btGImpactMeshShapePart * shape0,
+ btCollisionShape * shape1,bool swapped)
+{
+#ifdef GIMPACT_VS_PLANE_COLLISION
+ if(shape1->getShapeType() == STATIC_PLANE_PROXYTYPE)
+ {
+ btStaticPlaneShape * plane1 = static_cast(shape1);
+ gimpacttrimeshpart_vs_plane_collision(body0,body1,shape0,plane1,swapped);
+ return;
+ }
+#endif
+ if(shape1->isConcave())
+ {
+ btConcaveShape * concave1 = static_cast(shape1);
+ gimpacttrimeshpart_vs_concave_collision(body0,body1,shape0,concave1,swapped);
+ return;
+ }
+
+ btTransform trans1to0 = body0->getWorldTransform().inverse();
+ trans1to0 *= body1->getWorldTransform();
+
+ //lock
+ shape0->lock();
+
+ GIM_AABB boxshape;
+ shape1->getAabb(trans1to0,boxshape.m_min,boxshape.m_max);
+ gim_array collided_results(32);
+ shape0->getBoxSet()->boxQuery(boxshape, collided_results);
+
+ if(collided_results.size() == 0)
+ {
+ shape0->unlock();
+ return;
+ }
+
+ btTriangleShapeEx bullet_triangle(btVector3(0.f,0.f,0.f),btVector3(0.f,0.f,0.f),btVector3(0.f,0.f,0.f));
+
+
+ m_part0 = shape0->getPart();
+ m_part1 = -1;
+ m_triface1 = -1;
+
+ GUINT i = collided_results.size();
+
+ if(shape1->isConvex())
+ {
+ if(swapped)
+ {
+ while(i--)
+ {
+ m_triface0 = collided_results[i];
+ shape0->getBulletTriangle(collided_results[i],bullet_triangle);
+ //collide two shapes
+ convex_vs_convex_collision(body1,body0,shape1,&bullet_triangle);
+ }
+ }
+ else
+ {
+ while(i--)
+ {
+ m_triface0 = collided_results[i];
+ shape0->getBulletTriangle(collided_results[i],bullet_triangle);
+ //collide two shapes
+ convex_vs_convex_collision(body0,body1,&bullet_triangle,shape1);
+ }
+ }
+ }
+ else
+ {
+ while(i--)
+ {
+ m_triface0 = collided_results[i];
+ shape0->getBulletTriangle(collided_results[i],bullet_triangle);
+ //collide two shapes
+ shape_vs_shape_collision(body0,body1,&bullet_triangle,shape1,swapped);
+ }
+ }
+
+
+
+ shape0->unlock();
+}
+
+
+void btGImpactCollisionAlgorithm::gimpact_vs_compoundshape(btCollisionObject * body0,
+ btCollisionObject * body1,
+ btGImpactShapeInterface * shape0,
+ btCompoundShape * shape1,bool swapped)
+{
+ btTransform orgtrans1 = body1->getWorldTransform();
+
+ int i = shape1->getNumChildShapes();
+ while(i--)
+ {
+
+ btCollisionShape * colshape1 = shape1->getChildShape(i);
+ btTransform childtrans1 = orgtrans1*shape1->getChildTransform(i);
+
+ body1->setWorldTransform(childtrans1);
+
+ //collide child shape
+ gimpact_vs_shape(body0, body1,
+ shape0,colshape1,swapped);
+
+
+ //restore transforms
+ body1->setWorldTransform(orgtrans1);
+ }
+}
+
+
+void btGImpactCollisionAlgorithm::gimpact_vs_shape(btCollisionObject * body0,
+ btCollisionObject * body1,
+ btGImpactShapeInterface * shape0,
+ btCollisionShape * shape1,bool swapped)
+{
+ if(shape1->getShapeType() == COMPOUND_SHAPE_PROXYTYPE)
+ {
+ btCompoundShape * compoundshape = static_cast(shape1);
+ gimpact_vs_compoundshape(body0,body1,shape0,compoundshape,swapped);
+ return;
+ }
+
+ eGIMPACT_SHAPE_TYPE shapetype0 = shape0->getGImpactShapeType();
+ if(shapetype0 == CONST_GIMPACT_TRIMESH_SHAPE)
+ {
+ btGImpactMeshShape * trimesh0 = static_cast(shape0);
+ gimpacttrimesh_vs_shape_collision(body0,body1,trimesh0,shape1,swapped);
+ }
+ else if(shapetype0 == CONST_GIMPACT_TRIMESH_SHAPE_PART)
+ {
+ btGImpactMeshShapePart * trimeshpart0 = static_cast(shape0);
+ gimpacttrimeshpart_vs_shape_collision(body0,body1,trimeshpart0,shape1,swapped);
+ }
+ else// compound
+ {
+ btGImpactCompoundShape * compound0 = static_cast(shape0);
+ gimpactcompound_vs_shape_collision(body0,body1,compound0,shape1,swapped);
+ }
+}
+
+void btGImpactCollisionAlgorithm::gimpact_vs_gimpact(btCollisionObject * body0,
+ btCollisionObject * body1,
+ btGImpactShapeInterface * shape0,
+ btGImpactShapeInterface * shape1)
+{
+
+ eGIMPACT_SHAPE_TYPE shapetype0 = shape0->getGImpactShapeType();
+ eGIMPACT_SHAPE_TYPE shapetype1 = shape1->getGImpactShapeType();
+
+ btGImpactMeshShape * trimesh0;
+ btGImpactMeshShape * trimesh1;
+ btGImpactMeshShapePart * trimeshpart0;
+ btGImpactMeshShapePart * trimeshpart1;
+ btGImpactCompoundShape * compound0;
+ btGImpactCompoundShape * compound1;
+
+
+ if(shapetype0 == CONST_GIMPACT_TRIMESH_SHAPE)
+ {
+ if(shapetype1 == CONST_GIMPACT_TRIMESH_SHAPE) // trimesh vs trimesh
+ {
+ trimesh0 = static_cast(shape0);
+ trimesh1 = static_cast(shape1);
+ gimpacttrimesh_vs_gimpacttrimesh(body0,body1,trimesh0,trimesh1);
+ }
+ else
+ {
+ if(shapetype1 == CONST_GIMPACT_COMPOUND_SHAPE) // trimesh vs compound
+ {
+ trimesh0 = static_cast(shape0);
+ compound1 = static_cast(shape1);
+ gimpacttrimesh_vs_gimpactcompound(body0,body1,trimesh0,compound1,false);
+ }
+ else // trimesh vs trimesh part
+ {
+ trimesh0 = static_cast(shape0);
+ trimeshpart1 = static_cast(shape1);
+ gimpacttrimesh_vs_trimeshpart(body0,body1,trimesh0,trimeshpart1,false);
+ }
+ }
+ }
+ else if(shapetype1 == CONST_GIMPACT_TRIMESH_SHAPE)
+ {
+ if(shapetype0 == CONST_GIMPACT_COMPOUND_SHAPE) // compound vs trimesh
+ {
+ compound0 = static_cast(shape0);
+ trimesh1 = static_cast(shape1);
+ gimpacttrimesh_vs_gimpactcompound(body1,body0,trimesh1,compound0,true);
+ }
+ else // trimesh part vs trimesh
+ {
+ trimeshpart0 = static_cast(shape0);
+ trimesh1 = static_cast(shape1);
+ gimpacttrimesh_vs_trimeshpart(body1,body0,trimesh1,trimeshpart0,true);
+ }
+ }
+ else
+ {
+ if(shapetype0 == CONST_GIMPACT_COMPOUND_SHAPE)
+ {
+ if(shapetype1 == CONST_GIMPACT_COMPOUND_SHAPE) // compound vs compound
+ {
+ compound0 = static_cast(shape0);
+ compound1 = static_cast(shape1);
+ gimpactcompound_vs_gimpactcompound_collision(body0,body1,compound0,compound1);
+ }
+ else // compound vs trimesh part
+ {
+ compound0 = static_cast(shape0);
+ trimeshpart1 = static_cast(shape1);
+ gimpactcompound_vs_gimpacttrimeshpart_collision(body0,body1,compound0,trimeshpart1,false);
+ }
+ }
+ else if(shapetype1 == CONST_GIMPACT_COMPOUND_SHAPE) // trimesh part vs compound
+ {
+ compound1 = static_cast(shape1);
+ trimeshpart0 = static_cast(shape0);
+ gimpactcompound_vs_gimpacttrimeshpart_collision(body1,body0,compound1,trimeshpart0,true);
+ }
+ else // trimesh part vs trimesh part
+ {
+ trimeshpart0 = static_cast(shape0);
+ trimeshpart1 = static_cast(shape1);
+
+ gimpacttrimeshpart_vs_gimpacttrimeshpart_collision(body0,body1,trimeshpart0,trimeshpart1,false);
+ }
+ }
+}
+
+void btGImpactCollisionAlgorithm::processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
+{
+ clearCache();
+
+ m_resultOut = resultOut;
+ m_dispatchInfo = &dispatchInfo;
+
+
+ btGImpactShapeInterface * gimpactshape0;
+ btGImpactShapeInterface * gimpactshape1;
+ if (body0->getCollisionShape()->getShapeType()==GIMPACT_SHAPE_PROXYTYPE)
+ {
+ if( body1->getCollisionShape()->getShapeType()==GIMPACT_SHAPE_PROXYTYPE )
+ {
+ gimpactshape0 = static_cast(body0->getCollisionShape());
+ gimpactshape1 = static_cast(body1->getCollisionShape());
+ gimpact_vs_gimpact(body0,body1,gimpactshape0,gimpactshape1);
+ }
+ else
+ {
+ gimpactshape0 = static_cast(body0->getCollisionShape());
+ gimpact_vs_shape(body0,body1,gimpactshape0,body1->getCollisionShape(),false);
+ }
+ }
+ else if (body1->getCollisionShape()->getShapeType()==GIMPACT_SHAPE_PROXYTYPE )
+ {
+ gimpactshape1 = static_cast(body1->getCollisionShape());
+ gimpact_vs_shape(body1,body0,gimpactshape1,body0->getCollisionShape(),true);
+ }
+}
+
+
+btScalar btGImpactCollisionAlgorithm::calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
+{
+ return 1.f;
+
+}
+
+///////////////////////////////////// REGISTERING ALGORITHM //////////////////////////////////////////////
+
+
+//! Use this function for register the algorithm externally
+void btGImpactCollisionAlgorithm::registerAlgorithm(btCollisionDispatcher * dispatcher)
+{
+
+ for (GUINT i = 0;i < MAX_BROADPHASE_COLLISION_TYPES ;i++ )
+ {
+ dispatcher->registerCollisionCreateFunc(GIMPACT_SHAPE_PROXYTYPE,i ,new btGImpactCollisionAlgorithm::CreateFunc);
+ }
+
+ for (GUINT i = 0;i < MAX_BROADPHASE_COLLISION_TYPES ;i++ )
+ {
+ dispatcher->registerCollisionCreateFunc(i,GIMPACT_SHAPE_PROXYTYPE ,new btGImpactCollisionAlgorithm::CreateFunc);
+ }
+
+ /*
+ dispatcher->registerCollisionCreateFunc(GIMPACT_SHAPE_PROXYTYPE,GIMPACT_SHAPE_PROXYTYPE,new btGImpactCollisionAlgorithm::CreateFunc);
+ dispatcher->registerCollisionCreateFunc(STATIC_PLANE_PROXYTYPE ,GIMPACT_SHAPE_PROXYTYPE,new btGImpactCollisionAlgorithm::CreateFunc);
+ dispatcher->registerCollisionCreateFunc(GIMPACT_SHAPE_PROXYTYPE,STATIC_PLANE_PROXYTYPE ,new btGImpactCollisionAlgorithm::CreateFunc);*/
+
+
+}
diff --git a/Extras/GIMPACT/src/Bullet/btGImpactShape.cpp b/Extras/GIMPACT/src/Bullet/btGImpactShape.cpp
new file mode 100755
index 000000000..18fccce24
--- /dev/null
+++ b/Extras/GIMPACT/src/Bullet/btGImpactShape.cpp
@@ -0,0 +1,194 @@
+/*
+-----------------------------------------------------------------------------
+This source file is part of GIMPACT Library.
+
+For the latest info, see http://gimpact.sourceforge.net/
+
+Copyright (c) 2006 Francisco Leon Najera. C.C. 80087371.
+email: projectileman@yahoo.com
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of EITHER:
+ (1) The GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 2.1 of the License, or (at
+ your option) any later version. The text of the GNU Lesser
+ General Public License is included with this library in the
+ file GIMPACT-LICENSE-LGPL.TXT.
+ (2) The BSD-style license that is included with this library in
+ the file GIMPACT-LICENSE-BSD.TXT.
+ (3) The zlib/libpng license that is included with this library in
+ the file GIMPACT-LICENSE-ZLIB.TXT.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files
+ GIMPACT-LICENSE-LGPL.TXT, GIMPACT-LICENSE-ZLIB.TXT and GIMPACT-LICENSE-BSD.TXT for more details.
+
+-----------------------------------------------------------------------------
+*/
+
+
+#include "GIMPACT/Bullet/btGImpactShape.h"
+#include "GIMPACT/Bullet/btGImpactMassUtil.h"
+
+
+#define CALC_EXACT_INERTIA 1
+
+void btGImpactCompoundShape::calculateLocalInertia(btScalar mass,btVector3& inertia)
+{
+
+#ifdef CALC_EXACT_INERTIA
+ inertia.setValue(0.f,0.f,0.f);
+
+ GUINT i = this->getNumChildShapes();
+ GREAL shapemass = mass/btScalar(i);
+
+ while(i--)
+ {
+ btVector3 temp_inertia;
+ m_childShapes[i]->calculateLocalInertia(shapemass,temp_inertia);
+ inertia = gim_inertia_add_transformed( inertia,temp_inertia,m_childTransforms[i]);
+ }
+
+#else
+
+ // Calc box inertia
+
+ btScalar lx= m_localAABB.m_max[0] - m_localAABB.m_min[0];
+ btScalar ly= m_localAABB.m_max[1] - m_localAABB.m_min[1];
+ btScalar lz= m_localAABB.m_max[2] - m_localAABB.m_min[2];
+ const btScalar x2 = lx*lx;
+ const btScalar y2 = ly*ly;
+ const btScalar z2 = lz*lz;
+ const btScalar scaledmass = mass * btScalar(0.08333333);
+
+ inertia = scaledmass * (btVector3(y2+z2,x2+z2,x2+y2));
+
+#endif
+}
+
+
+
+void btGImpactMeshShapePart::calculateLocalInertia(btScalar mass,btVector3& inertia)
+{
+ lock();
+
+
+#ifdef CALC_EXACT_INERTIA
+ inertia.setValue(0.f,0.f,0.f);
+
+ GUINT i = this->getVertexCount();
+ GREAL pointmass = mass/btScalar(i);
+
+ while(i--)
+ {
+ btVector3 pointintertia;
+ this->getVertex(i,pointintertia);
+ pointintertia = gim_get_point_inertia(pointintertia,pointmass);
+ inertia+=pointintertia;
+ }
+
+#else
+
+ // Calc box inertia
+
+ btScalar lx= m_localAABB.m_max[0] - m_localAABB.m_min[0];
+ btScalar ly= m_localAABB.m_max[1] - m_localAABB.m_min[1];
+ btScalar lz= m_localAABB.m_max[2] - m_localAABB.m_min[2];
+ const btScalar x2 = lx*lx;
+ const btScalar y2 = ly*ly;
+ const btScalar z2 = lz*lz;
+ const btScalar scaledmass = mass * btScalar(0.08333333);
+
+ inertia = scaledmass * (btVector3(y2+z2,x2+z2,x2+y2));
+
+#endif
+
+ unlock();
+}
+
+void btGImpactMeshShape::calculateLocalInertia(btScalar mass,btVector3& inertia)
+{
+
+#ifdef CALC_EXACT_INERTIA
+ inertia.setValue(0.f,0.f,0.f);
+
+ GUINT i = this->getMeshPartCount();
+ GREAL partmass = mass/btScalar(i);
+
+ while(i--)
+ {
+ btVector3 partinertia;
+ getMeshPart(i)->calculateLocalInertia(partmass,partinertia);
+ inertia+=partinertia;
+ }
+
+#else
+
+ // Calc box inertia
+
+ btScalar lx= m_localAABB.m_max[0] - m_localAABB.m_min[0];
+ btScalar ly= m_localAABB.m_max[1] - m_localAABB.m_min[1];
+ btScalar lz= m_localAABB.m_max[2] - m_localAABB.m_min[2];
+ const btScalar x2 = lx*lx;
+ const btScalar y2 = ly*ly;
+ const btScalar z2 = lz*lz;
+ const btScalar scaledmass = mass * btScalar(0.08333333);
+
+ inertia = scaledmass * (btVector3(y2+z2,x2+z2,x2+y2));
+
+#endif
+}
+
+
+
+void btGImpactCompoundShape::rayTest(const btVector3& rayFrom, const btVector3& rayTo, btCollisionWorld::RayResultCallback& resultCallback) const
+{
+
+}
+
+void btGImpactMeshShape::rayTest(const btVector3& rayFrom, const btVector3& rayTo, btCollisionWorld::RayResultCallback& resultCallback) const
+{
+}
+
+void btGImpactMeshShapePart::rayTest(const btVector3& rayFrom, const btVector3& rayTo, btCollisionWorld::RayResultCallback& resultCallback) const
+{
+}
+
+
+void btGImpactMeshShapePart::processAllTriangles(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const
+{
+ lock();
+ GIM_AABB box;
+ box.m_min = aabbMin;
+ box.m_max = aabbMax;
+
+ gim_array collided;
+ m_box_set.boxQuery(box,collided);
+
+ if(collided.size()==0)
+ {
+ unlock();
+ return;
+ }
+
+ int part = (int)getPart();
+ GIM_TRIANGLE triangle;
+ GUINT i = collided.size();
+ while(i--)
+ {
+ this->getTriangle(collided[i],triangle);
+ callback->processTriangle(triangle.m_vertices,part,collided[i]);
+ }
+ unlock();
+
+}
+
+void btGImpactMeshShape::processAllTriangles(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const
+{
+ GUINT i = m_mesh_parts.size();
+ while(i--)
+ {
+ m_mesh_parts[i]->processAllTriangles(callback,aabbMin,aabbMax);
+ }
+}
diff --git a/Extras/GIMPACT/src/core/gim_box_set.cpp b/Extras/GIMPACT/src/core/gim_box_set.cpp
new file mode 100755
index 000000000..b9b6be991
--- /dev/null
+++ b/Extras/GIMPACT/src/core/gim_box_set.cpp
@@ -0,0 +1,182 @@
+
+/*
+-----------------------------------------------------------------------------
+This source file is part of GIMPACT Library.
+
+For the latest info, see http://gimpact.sourceforge.net/
+
+Copyright (c) 2006 Francisco Leon Najera. C.C. 80087371.
+email: projectileman@yahoo.com
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of EITHER:
+ (1) The GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 2.1 of the License, or (at
+ your option) any later version. The text of the GNU Lesser
+ General Public License is included with this library in the
+ file GIMPACT-LICENSE-LGPL.TXT.
+ (2) The BSD-style license that is included with this library in
+ the file GIMPACT-LICENSE-BSD.TXT.
+ (3) The zlib/libpng license that is included with this library in
+ the file GIMPACT-LICENSE-ZLIB.TXT.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files
+ GIMPACT-LICENSE-LGPL.TXT, GIMPACT-LICENSE-ZLIB.TXT and GIMPACT-LICENSE-BSD.TXT for more details.
+
+-----------------------------------------------------------------------------
+*/
+
+
+#include "GIMPACT/core/gim_box_set.h"
+
+
+GUINT GIM_BOX_TREE::_calc_splitting_axis(
+ gim_array & primitive_boxes, GUINT startIndex, GUINT endIndex)
+{
+ GUINT i;
+
+ btVector3 means(btScalar(0.),btScalar(0.),btScalar(0.));
+ btVector3 variance(btScalar(0.),btScalar(0.),btScalar(0.));
+ GUINT numIndices = endIndex-startIndex;
+
+ for (i=startIndex;i & primitive_boxes, GUINT startIndex,
+ GUINT endIndex, GUINT splitAxis)
+{
+ GUINT i;
+ GUINT splitIndex =startIndex;
+ GUINT numIndices = endIndex - startIndex;
+
+ // average of centers
+ btScalar splitValue = 0.0f;
+ for (i=startIndex;i splitValue)
+ {
+ //swap
+ primitive_boxes.swap(i,splitIndex);
+ splitIndex++;
+ }
+ }
+
+ //if the splitIndex causes unbalanced trees, fix this by using the center in between startIndex and endIndex
+ //otherwise the tree-building might fail due to stack-overflows in certain cases.
+ //unbalanced1 is unsafe: it can cause stack overflows
+ //bool unbalanced1 = ((splitIndex==startIndex) || (splitIndex == (endIndex-1)));
+
+ //unbalanced2 should work too: always use center (perfect balanced trees)
+ //bool unbalanced2 = true;
+
+ //this should be safe too:
+ GUINT rangeBalancedIndices = numIndices/3;
+ bool unbalanced = ((splitIndex<=(startIndex+rangeBalancedIndices)) || (splitIndex >=(endIndex-1-rangeBalancedIndices)));
+
+ if (unbalanced)
+ {
+ splitIndex = startIndex+ (numIndices>>1);
+ }
+
+ bool unbal = (splitIndex==startIndex) || (splitIndex == (endIndex));
+ btAssert(!unbal);
+
+ return splitIndex;
+}
+
+
+void GIM_BOX_TREE::_build_sub_tree(gim_array & primitive_boxes, GUINT startIndex, GUINT endIndex)
+{
+ GUINT current_index = m_num_nodes++;
+
+ btAssert((endIndex-startIndex)>0);
+
+ if((endIndex-startIndex) == 1) //we got a leaf
+ {
+ m_node_array[current_index].m_left = 0;
+ m_node_array[current_index].m_right = 0;
+ m_node_array[current_index].m_escapeIndex = 0;
+
+ m_node_array[current_index].m_bound = primitive_boxes[startIndex].m_bound;
+ m_node_array[current_index].m_data = primitive_boxes[startIndex].m_data;
+ return;
+ }
+
+ //configure inner node
+
+ GUINT splitIndex;
+
+ //calc this node bounding box
+ m_node_array[current_index].m_bound.invalidate();
+ for (splitIndex=startIndex;splitIndex & primitive_boxes)
+{
+ // initialize node count to 0
+ m_num_nodes = 0;
+ // allocate nodes
+ m_node_array.resize(primitive_boxes.size()*2);
+
+ _build_sub_tree(primitive_boxes, 0, primitive_boxes.size());
+}
+
diff --git a/Extras/GIMPACT/src/core/gim_contact.cpp b/Extras/GIMPACT/src/core/gim_contact.cpp
new file mode 100755
index 000000000..6f8e0751e
--- /dev/null
+++ b/Extras/GIMPACT/src/core/gim_contact.cpp
@@ -0,0 +1,142 @@
+
+/*
+-----------------------------------------------------------------------------
+This source file is part of GIMPACT Library.
+
+For the latest info, see http://gimpact.sourceforge.net/
+
+Copyright (c) 2006 Francisco Leon Najera. C.C. 80087371.
+email: projectileman@yahoo.com
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of EITHER:
+ (1) The GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 2.1 of the License, or (at
+ your option) any later version. The text of the GNU Lesser
+ General Public License is included with this library in the
+ file GIMPACT-LICENSE-LGPL.TXT.
+ (2) The BSD-style license that is included with this library in
+ the file GIMPACT-LICENSE-BSD.TXT.
+ (3) The zlib/libpng license that is included with this library in
+ the file GIMPACT-LICENSE-ZLIB.TXT.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files
+ GIMPACT-LICENSE-LGPL.TXT, GIMPACT-LICENSE-ZLIB.TXT and GIMPACT-LICENSE-BSD.TXT for more details.
+
+-----------------------------------------------------------------------------
+*/
+
+#include "GIMPACT/core/gim_contact.h"
+
+#define MAX_COINCIDENT 8
+
+void gim_contact_array::merge_contacts(
+ const gim_contact_array & contacts, bool normal_contact_average)
+{
+ clear();
+
+ if(contacts.size()==1)
+ {
+ push_back(contacts.back());
+ return;
+ }
+
+ gim_array keycontacts(contacts.size());
+ keycontacts.resize(contacts.size(),false);
+
+ //fill key contacts
+
+ for (GUINT i = 0;im_depth - CONTACT_DIFF_EPSILON > scontact->m_depth)//)
+ {
+ *pcontact = *scontact;
+ coincident_count = 0;
+ }
+ else if(normal_contact_average)
+ {
+ if(btFabs(pcontact->m_depth - scontact->m_depth)m_normal;
+ coincident_count++;
+ }
+ }
+ }
+ }
+ else
+ {//add new contact
+
+ if(normal_contact_average && coincident_count>0)
+ {
+ pcontact->interpolate_normals(coincident_normals,coincident_count);
+ coincident_count = 0;
+ }
+
+ push_back(*scontact);
+ pcontact = &back();
+ }
+ last_key = key;
+ }
+}
+
+void gim_contact_array::merge_contacts_unique(const gim_contact_array & contacts)
+{
+ clear();
+
+ if(contacts.size()==1)
+ {
+ push_back(contacts.back());
+ return;
+ }
+
+ GIM_CONTACT average_contact = contacts.back();
+
+ for (GUINT i=1;i0.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 */
+ scale_edge0 = -D2/(D0-D2);
+ scale_edge1 = -D1/(D2-D1);
+ edge_index0 = 2;edge_index1 = 1;
+ }
+ else if(D0D2>0.0f)
+ {
+ /* here we know that d0d1<=0.0 */
+ scale_edge0 = -D0/(D1-D0);
+ scale_edge1 = -D1/(D2-D1);
+ edge_index0 = 0;edge_index1 = 1;
+ }
+ else if(D1*D2>0.0f || D0!=0.0f)
+ {
+ /* here we know that d0d1<=0.0 or that D0!=0.0 */
+ scale_edge0 = -D0/(D1-D0);
+ scale_edge1 = -D2/(D0-D2);
+ edge_index0 = 0 ;edge_index1 = 2;
+ }
+ else
+ {
+ return false;
+ }
+ return true;
+ }
+
+
+ //! clip triangle
+ /*!
+ */
+ SIMD_FORCE_INLINE GUINT clip_triangle(
+ const btVector4 & tri_plane,
+ const btVector3 * tripoints,
+ const btVector3 * srcpoints,
+ btVector3 * clip_points)
+ {
+ // edge 0
+
+ btVector4 edgeplane;
+
+ EDGE_PLANE(tripoints[0],tripoints[1],tri_plane,edgeplane);
+
+ GUINT clipped_count = PLANE_CLIP_TRIANGLE3D(
+ edgeplane,srcpoints[0],srcpoints[1],srcpoints[2],temp_points);
+
+ if(clipped_count == 0) return 0;
+
+ // edge 1
+
+ EDGE_PLANE(tripoints[1],tripoints[2],tri_plane,edgeplane);
+
+ clipped_count = PLANE_CLIP_POLYGON3D(
+ edgeplane,temp_points,clipped_count,temp_points1);
+
+ if(clipped_count == 0) return 0;
+
+ // edge 2
+
+ EDGE_PLANE(tripoints[2],tripoints[0],tri_plane,edgeplane);
+
+ clipped_count = PLANE_CLIP_POLYGON3D(
+ edgeplane,temp_points1,clipped_count,clip_points);
+
+ return clipped_count;
+
+
+ /*GUINT i0 = (tri_plane.closestAxis()+1)%3;
+ GUINT i1 = (i0+1)%3;
+ // edge 0
+ btVector3 temp_points[MAX_TRI_CLIPPING];
+ btVector3 temp_points1[MAX_TRI_CLIPPING];
+
+ GUINT clipped_count= PLANE_CLIP_TRIANGLE_GENERIC(
+ 0,srcpoints[0],srcpoints[1],srcpoints[2],temp_points,
+ DISTANCE_EDGE(tripoints[0],tripoints[1],i0,i1));
+
+
+ if(clipped_count == 0) return 0;
+
+ // edge 1
+ clipped_count = PLANE_CLIP_POLYGON_GENERIC(
+ 0,temp_points,clipped_count,temp_points1,
+ DISTANCE_EDGE(tripoints[1],tripoints[2],i0,i1));
+
+ if(clipped_count == 0) return 0;
+
+ // edge 2
+ clipped_count = PLANE_CLIP_POLYGON_GENERIC(
+ 0,temp_points1,clipped_count,clipped_points,
+ DISTANCE_EDGE(tripoints[2],tripoints[0],i0,i1));
+
+ return clipped_count;*/
+ }
+
+ SIMD_FORCE_INLINE void sort_isect(
+ GREAL & isect0,GREAL & isect1,GUINT &e0,GUINT &e1,btVector3 & vec0,btVector3 & vec1)
+ {
+ if(isect1=isect_v[1]) // face U casts face V
+ {
+ return 1;
+ }
+ else if(isect_v[0]<=isect_u[0]) // face V casts face U
+ {
+ return 2;
+ }
+ // closest points
+ closest_point_u = up_e1;
+ closest_point_v = vp_e0;
+ // calc edges and separation
+
+ if(isect_u[1]+ MIN_EDGE_EDGE_DIS=isect_u[1]) // face V casts face U
+ {
+ return 2;
+ }
+ else if(isect_u[0]<=isect_v[0]) // face U casts face V
+ {
+ return 1;
+ }
+ // closest points
+ closest_point_u = up_e0;
+ closest_point_v = vp_e1;
+ // calc edges and separation
+
+ if(isect_v[1]+MIN_EDGE_EDGE_DIS0.0f && du0du2>0.0f) // same sign on all of them + not equal 0 ?
+ {
+ if(du[0]<0) //we need test behind the triangle plane
+ {
+ distances[0] = GIM_MAX3(du[0],du[1],du[2]);
+ distances[0] = -distances[0];
+ if(distances[0]>margin) return false; //never intersect
+
+ //reorder triangle v
+ VEC_SWAP(tv_vertices[0],tv_vertices[1]);
+ VEC_SCALE_4(tv_plane,-1.0f,tv_plane);
+ }
+ else
+ {
+ distances[0] = GIM_MIN3(du[0],du[1],du[2]);
+ if(distances[0]>margin) return false; //never intersect
+ }
+ }
+ else
+ {
+ //Look if we need to invert the triangle
+ distances[0] = (du[0]+du[1]+du[2])/3.0f; //centroid
+
+ if(distances[0]<0.0f)
+ {
+ //reorder triangle v
+ VEC_SWAP(tv_vertices[0],tv_vertices[1]);
+ VEC_SCALE_4(tv_plane,-1.0f,tv_plane);
+
+ distances[0] = GIM_MAX3(du[0],du[1],du[2]);
+ distances[0] = -distances[0];
+ }
+ else
+ {
+ distances[0] = GIM_MIN3(du[0],du[1],du[2]);
+ }
+ }
+
+
+ // plane U vs V points
+
+ TRIANGLE_PLANE(tu_vertices[0],tu_vertices[1],tu_vertices[2],tu_plane);
+
+ dv[0] = DISTANCE_PLANE_POINT(tu_plane,tv_vertices[0]);
+ dv[1] = DISTANCE_PLANE_POINT(tu_plane,tv_vertices[1]);
+ dv[2] = DISTANCE_PLANE_POINT(tu_plane,tv_vertices[2]);
+
+ dv0dv1 = dv[0] * dv[1];
+ dv0dv2 = dv[0] * dv[2];
+
+
+ if(dv0dv1>0.0f && dv0dv2>0.0f) // same sign on all of them + not equal 0 ?
+ {
+ if(dv[0]<0) //we need test behind the triangle plane
+ {
+ distances[1] = GIM_MAX3(dv[0],dv[1],dv[2]);
+ distances[1] = -distances[1];
+ if(distances[1]>margin) return false; //never intersect
+
+ //reorder triangle u
+ VEC_SWAP(tu_vertices[0],tu_vertices[1]);
+ VEC_SCALE_4(tu_plane,-1.0f,tu_plane);
+ }
+ else
+ {
+ distances[1] = GIM_MIN3(dv[0],dv[1],dv[2]);
+ if(distances[1]>margin) return false; //never intersect
+ }
+ }
+ else
+ {
+ //Look if we need to invert the triangle
+ distances[1] = (dv[0]+dv[1]+dv[2])/3.0f; //centroid
+
+ if(distances[1]<0.0f)
+ {
+ //reorder triangle v
+ VEC_SWAP(tu_vertices[0],tu_vertices[1]);
+ VEC_SCALE_4(tu_plane,-1.0f,tu_plane);
+
+ distances[1] = GIM_MAX3(dv[0],dv[1],dv[2]);
+ distances[1] = -distances[1];
+ }
+ else
+ {
+ distances[1] = GIM_MIN3(dv[0],dv[1],dv[2]);
+ }
+ }
+
+ GUINT bl;
+ /* bl = cross_line_intersection_test();
+ if(bl==3)
+ {
+ //take edge direction too
+ bl = distances.maxAxis();
+ }
+ else
+ {*/
+ bl = 0;
+ if(distances[0]margin) return false;
+
+ contacts.m_penetration_depth = -distances[2] + margin;
+ contacts.m_points[0] = closest_point_v;
+ contacts.m_point_count = 1;
+ VEC_COPY(contacts.m_separating_normal,edge_edge_dir);
+
+ return true;
+ }
+
+ //clip face against other
+
+
+ GUINT point_count;
+ //TODO
+ if(bl == 0) //clip U points against V
+ {
+ point_count = clip_triangle(tv_plane,tv_vertices,tu_vertices,contact_points);
+ if(point_count == 0) return false;
+ contacts.merge_points(tv_plane,margin,contact_points,point_count);
+ }
+ else //clip V points against U
+ {
+ point_count = clip_triangle(tu_plane,tu_vertices,tv_vertices,contact_points);
+ if(point_count == 0) return false;
+ contacts.merge_points(tu_plane,margin,contact_points,point_count);
+ contacts.m_separating_normal *= -1.f;
+ }
+ if(contacts.m_point_count == 0) return false;
+ return true;
+ }
+
+};
+
+
+/*class _GIM_TRIANGLE_CALCULATION_CACHE
+{
+public:
+ GREAL margin;
+ GUINT clipped_count;
+ btVector3 tu_vertices[3];
+ btVector3 tv_vertices[3];
+ btVector3 temp_points[MAX_TRI_CLIPPING];
+ btVector3 temp_points1[MAX_TRI_CLIPPING];
+ btVector3 clipped_points[MAX_TRI_CLIPPING];
+ GIM_TRIANGLE_CONTACT_DATA contacts1;
+ GIM_TRIANGLE_CONTACT_DATA contacts2;
+
+
+ //! clip triangle
+ GUINT clip_triangle(
+ const btVector4 & tri_plane,
+ const btVector3 * tripoints,
+ const btVector3 * srcpoints,
+ btVector3 * clipped_points)
+ {
+ // edge 0
+
+ btVector4 edgeplane;
+
+ EDGE_PLANE(tripoints[0],tripoints[1],tri_plane,edgeplane);
+
+ GUINT clipped_count = PLANE_CLIP_TRIANGLE3D(
+ edgeplane,srcpoints[0],srcpoints[1],srcpoints[2],temp_points);
+
+ if(clipped_count == 0) return 0;
+
+ // edge 1
+
+ EDGE_PLANE(tripoints[1],tripoints[2],tri_plane,edgeplane);
+
+ clipped_count = PLANE_CLIP_POLYGON3D(
+ edgeplane,temp_points,clipped_count,temp_points1);
+
+ if(clipped_count == 0) return 0;
+
+ // edge 2
+
+ EDGE_PLANE(tripoints[2],tripoints[0],tri_plane,edgeplane);
+
+ clipped_count = PLANE_CLIP_POLYGON3D(
+ edgeplane,temp_points1,clipped_count,clipped_points);
+
+ return clipped_count;
+ }
+
+
+
+
+ //! collides only on one side
+ bool triangle_collision(
+ const btVector3 & u0,
+ const btVector3 & u1,
+ const btVector3 & u2,
+ GREAL margin_u,
+ const btVector3 & v0,
+ const btVector3 & v1,
+ const btVector3 & v2,
+ GREAL margin_v,
+ GIM_TRIANGLE_CONTACT_DATA & contacts)
+ {
+
+ margin = margin_u + margin_v;
+
+
+ tu_vertices[0] = u0;
+ tu_vertices[1] = u1;
+ tu_vertices[2] = u2;
+
+ tv_vertices[0] = v0;
+ tv_vertices[1] = v1;
+ tv_vertices[2] = v2;
+
+ //create planes
+ // plane v vs U points
+
+
+ TRIANGLE_PLANE(tv_vertices[0],tv_vertices[1],tv_vertices[2],contacts1.m_separating_normal);
+
+ clipped_count = clip_triangle(
+ contacts1.m_separating_normal,tv_vertices,tu_vertices,clipped_points);
+
+ if(clipped_count == 0 )
+ {
+ return false;//Reject
+ }
+
+ //find most deep interval face1
+ contacts1.merge_points(contacts1.m_separating_normal,margin,clipped_points,clipped_count);
+ if(contacts1.m_point_count == 0) return false; // too far
+
+ //Normal pointing to triangle1
+ //contacts1.m_separating_normal *= -1.f;
+
+ //Clip tri1 by tri2 edges
+
+ TRIANGLE_PLANE(tu_vertices[0],tu_vertices[1],tu_vertices[2],contacts2.m_separating_normal);
+
+ clipped_count = clip_triangle(
+ contacts2.m_separating_normal,tu_vertices,tv_vertices,clipped_points);
+
+ if(clipped_count == 0 )
+ {
+ return false;//Reject
+ }
+
+ //find most deep interval face1
+ contacts2.merge_points(contacts2.m_separating_normal,margin,clipped_points,clipped_count);
+ if(contacts2.m_point_count == 0) return false; // too far
+
+ contacts2.m_separating_normal *= -1.f;
+
+ ////check most dir for contacts
+ if(contacts2.m_penetration_depth