Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/extern
diff options
context:
space:
mode:
authorErwin Coumans <blender@erwincoumans.com>2005-07-16 13:58:01 +0400
committerErwin Coumans <blender@erwincoumans.com>2005-07-16 13:58:01 +0400
commitfeb4f51103a7d6d22f564510deeb53ba83eaa931 (patch)
tree3facb14b2cd84faab73db921a45865d12fa8e461 /extern
parent1921a356be5999f4eab6d13adbf80d16526c988e (diff)
Added Bullet library.
Only windows projectfiles for now. Will ask Hans to get unix makefiles done.
Diffstat (limited to 'extern')
-rw-r--r--extern/bullet/Bullet/BroadphaseCollision/BroadphaseInterface.h32
-rw-r--r--extern/bullet/Bullet/BroadphaseCollision/BroadphaseProxy.cpp12
-rw-r--r--extern/bullet/Bullet/BroadphaseCollision/BroadphaseProxy.h125
-rw-r--r--extern/bullet/Bullet/BroadphaseCollision/CollisionAlgorithm.cpp18
-rw-r--r--extern/bullet/Bullet/BroadphaseCollision/CollisionAlgorithm.h62
-rw-r--r--extern/bullet/Bullet/BroadphaseCollision/CollisionDispatcher.cpp17
-rw-r--r--extern/bullet/Bullet/BroadphaseCollision/CollisionDispatcher.h71
-rw-r--r--extern/bullet/Bullet/BroadphaseCollision/SimpleBroadphase.cpp273
-rw-r--r--extern/bullet/Bullet/BroadphaseCollision/SimpleBroadphase.h78
-rw-r--r--extern/bullet/Bullet/Bullet3.dsp412
-rw-r--r--extern/bullet/Bullet/Bullet3_vc7.vcproj427
-rw-r--r--extern/bullet/Bullet/Bullet3_vc8.sln20
-rw-r--r--extern/bullet/Bullet/Bullet3_vc8.vcproj552
-rw-r--r--extern/bullet/Bullet/CollisionShapes/BoxShape.cpp34
-rw-r--r--extern/bullet/Bullet/CollisionShapes/BoxShape.h274
-rw-r--r--extern/bullet/Bullet/CollisionShapes/CollisionShape.cpp70
-rw-r--r--extern/bullet/Bullet/CollisionShapes/CollisionShape.h76
-rw-r--r--extern/bullet/Bullet/CollisionShapes/ConeShape.cpp85
-rw-r--r--extern/bullet/Bullet/CollisionShapes/ConeShape.h73
-rw-r--r--extern/bullet/Bullet/CollisionShapes/ConvexHullShape.cpp146
-rw-r--r--extern/bullet/Bullet/CollisionShapes/ConvexHullShape.h59
-rw-r--r--extern/bullet/Bullet/CollisionShapes/ConvexShape.cpp67
-rw-r--r--extern/bullet/Bullet/CollisionShapes/ConvexShape.h74
-rw-r--r--extern/bullet/Bullet/CollisionShapes/CylinderShape.cpp169
-rw-r--r--extern/bullet/Bullet/CollisionShapes/CylinderShape.h63
-rw-r--r--extern/bullet/Bullet/CollisionShapes/MinkowskiSumShape.cpp39
-rw-r--r--extern/bullet/Bullet/CollisionShapes/MinkowskiSumShape.h54
-rw-r--r--extern/bullet/Bullet/CollisionShapes/MultiSphereShape.cpp115
-rw-r--r--extern/bullet/Bullet/CollisionShapes/MultiSphereShape.h55
-rw-r--r--extern/bullet/Bullet/CollisionShapes/PolyhedralConvexShape.cpp52
-rw-r--r--extern/bullet/Bullet/CollisionShapes/PolyhedralConvexShape.h43
-rw-r--r--extern/bullet/Bullet/CollisionShapes/Simplex1to4Shape.cpp188
-rw-r--r--extern/bullet/Bullet/CollisionShapes/Simplex1to4Shape.h74
-rw-r--r--extern/bullet/Bullet/CollisionShapes/SphereShape.cpp58
-rw-r--r--extern/bullet/Bullet/CollisionShapes/SphereShape.h46
-rw-r--r--extern/bullet/Bullet/CollisionShapes/StridingMeshInterface.cpp16
-rw-r--r--extern/bullet/Bullet/CollisionShapes/StridingMeshInterface.h69
-rw-r--r--extern/bullet/Bullet/CollisionShapes/TriangleCallback.h25
-rw-r--r--extern/bullet/Bullet/CollisionShapes/TriangleMesh.cpp39
-rw-r--r--extern/bullet/Bullet/CollisionShapes/TriangleMesh.h63
-rw-r--r--extern/bullet/Bullet/CollisionShapes/TriangleMeshShape.cpp182
-rw-r--r--extern/bullet/Bullet/CollisionShapes/TriangleMeshShape.h63
-rw-r--r--extern/bullet/Bullet/CollisionShapes/TriangleShape.h146
-rw-r--r--extern/bullet/Bullet/Doxyfile746
-rw-r--r--extern/bullet/Bullet/NarrowPhaseCollision/BU_AlgebraicPolynomialSolver.cpp355
-rw-r--r--extern/bullet/Bullet/NarrowPhaseCollision/BU_AlgebraicPolynomialSolver.h40
-rw-r--r--extern/bullet/Bullet/NarrowPhaseCollision/BU_Collidable.cpp20
-rw-r--r--extern/bullet/Bullet/NarrowPhaseCollision/BU_Collidable.h52
-rw-r--r--extern/bullet/Bullet/NarrowPhaseCollision/BU_CollisionPair.cpp576
-rw-r--r--extern/bullet/Bullet/NarrowPhaseCollision/BU_CollisionPair.h49
-rw-r--r--extern/bullet/Bullet/NarrowPhaseCollision/BU_EdgeEdge.cpp573
-rw-r--r--extern/bullet/Bullet/NarrowPhaseCollision/BU_EdgeEdge.h71
-rw-r--r--extern/bullet/Bullet/NarrowPhaseCollision/BU_MotionStateInterface.h45
-rw-r--r--extern/bullet/Bullet/NarrowPhaseCollision/BU_PolynomialSolverInterface.h26
-rw-r--r--extern/bullet/Bullet/NarrowPhaseCollision/BU_Screwing.cpp197
-rw-r--r--extern/bullet/Bullet/NarrowPhaseCollision/BU_Screwing.h72
-rw-r--r--extern/bullet/Bullet/NarrowPhaseCollision/BU_StaticMotionState.h86
-rw-r--r--extern/bullet/Bullet/NarrowPhaseCollision/BU_VertexPoly.cpp154
-rw-r--r--extern/bullet/Bullet/NarrowPhaseCollision/BU_VertexPoly.h38
-rw-r--r--extern/bullet/Bullet/NarrowPhaseCollision/CollisionMargin.h11
-rw-r--r--extern/bullet/Bullet/NarrowPhaseCollision/ContinuousConvexCollision.cpp186
-rw-r--r--extern/bullet/Bullet/NarrowPhaseCollision/ContinuousConvexCollision.h46
-rw-r--r--extern/bullet/Bullet/NarrowPhaseCollision/ConvexCast.cpp5
-rw-r--r--extern/bullet/Bullet/NarrowPhaseCollision/ConvexCast.h57
-rw-r--r--extern/bullet/Bullet/NarrowPhaseCollision/ConvexPenetrationDepthSolver.h33
-rw-r--r--extern/bullet/Bullet/NarrowPhaseCollision/DiscreteCollisionDetectorInterface.h79
-rw-r--r--extern/bullet/Bullet/NarrowPhaseCollision/GjkConvexCast.cpp157
-rw-r--r--extern/bullet/Bullet/NarrowPhaseCollision/GjkConvexCast.h44
-rw-r--r--extern/bullet/Bullet/NarrowPhaseCollision/GjkPairDetector.cpp186
-rw-r--r--extern/bullet/Bullet/NarrowPhaseCollision/GjkPairDetector.h60
-rw-r--r--extern/bullet/Bullet/NarrowPhaseCollision/ManifoldPoint.h59
-rw-r--r--extern/bullet/Bullet/NarrowPhaseCollision/MinkowskiPenetrationDepthSolver.cpp132
-rw-r--r--extern/bullet/Bullet/NarrowPhaseCollision/MinkowskiPenetrationDepthSolver.h20
-rw-r--r--extern/bullet/Bullet/NarrowPhaseCollision/PersistentManifold.cpp182
-rw-r--r--extern/bullet/Bullet/NarrowPhaseCollision/PersistentManifold.h116
-rw-r--r--extern/bullet/Bullet/NarrowPhaseCollision/PointCollector.h36
-rw-r--r--extern/bullet/Bullet/NarrowPhaseCollision/RaycastCallback.cpp94
-rw-r--r--extern/bullet/Bullet/NarrowPhaseCollision/RaycastCallback.h40
-rw-r--r--extern/bullet/Bullet/NarrowPhaseCollision/SimplexSolverInterface.h58
-rw-r--r--extern/bullet/Bullet/NarrowPhaseCollision/SubSimplexConvexCast.cpp124
-rw-r--r--extern/bullet/Bullet/NarrowPhaseCollision/SubSimplexConvexCast.h42
-rw-r--r--extern/bullet/Bullet/NarrowPhaseCollision/VoronoiSimplexSolver.cpp582
-rw-r--r--extern/bullet/Bullet/NarrowPhaseCollision/VoronoiSimplexSolver.h152
-rw-r--r--extern/bullet/BulletDynamics/BulletDynamics.dsp236
-rw-r--r--extern/bullet/BulletDynamics/BulletDynamics_vc7.vcproj231
-rw-r--r--extern/bullet/BulletDynamics/BulletDynamics_vc8.vcproj301
-rw-r--r--extern/bullet/BulletDynamics/CollisionDispatch/ConvexConcaveCollisionAlgorithm.cpp212
-rw-r--r--extern/bullet/BulletDynamics/CollisionDispatch/ConvexConcaveCollisionAlgorithm.h90
-rw-r--r--extern/bullet/BulletDynamics/CollisionDispatch/ConvexConvexAlgorithm.cpp250
-rw-r--r--extern/bullet/BulletDynamics/CollisionDispatch/ConvexConvexAlgorithm.h62
-rw-r--r--extern/bullet/BulletDynamics/CollisionDispatch/EmptyCollisionAlgorithm.cpp30
-rw-r--r--extern/bullet/BulletDynamics/CollisionDispatch/EmptyCollisionAlgorithm.h35
-rw-r--r--extern/bullet/BulletDynamics/CollisionDispatch/ManifoldResult.cpp46
-rw-r--r--extern/bullet/BulletDynamics/CollisionDispatch/ManifoldResult.h35
-rw-r--r--extern/bullet/BulletDynamics/CollisionDispatch/ToiContactDispatcher.cpp221
-rw-r--r--extern/bullet/BulletDynamics/CollisionDispatch/ToiContactDispatcher.h105
-rw-r--r--extern/bullet/BulletDynamics/CollisionDispatch/UnionFind.cpp54
-rw-r--r--extern/bullet/BulletDynamics/CollisionDispatch/UnionFind.h21
-rw-r--r--extern/bullet/BulletDynamics/ConstraintSolver/ConstraintSolver.h35
-rw-r--r--extern/bullet/BulletDynamics/ConstraintSolver/ContactConstraint.cpp324
-rw-r--r--extern/bullet/BulletDynamics/ConstraintSolver/ContactConstraint.h48
-rw-r--r--extern/bullet/BulletDynamics/ConstraintSolver/ContactSolverInfo.h39
-rw-r--r--extern/bullet/BulletDynamics/ConstraintSolver/JacobianEntry.h129
-rw-r--r--extern/bullet/BulletDynamics/ConstraintSolver/OdeConstraintSolver.cpp256
-rw-r--r--extern/bullet/BulletDynamics/ConstraintSolver/OdeConstraintSolver.h31
-rw-r--r--extern/bullet/BulletDynamics/ConstraintSolver/OdeConstraintSolver2.cpp246
-rw-r--r--extern/bullet/BulletDynamics/ConstraintSolver/OdeConstraintSolver2.h31
-rw-r--r--extern/bullet/BulletDynamics/ConstraintSolver/Point2PointConstraint.cpp111
-rw-r--r--extern/bullet/BulletDynamics/ConstraintSolver/Point2PointConstraint.h56
-rw-r--r--extern/bullet/BulletDynamics/ConstraintSolver/SimpleConstraintSolver.cpp127
-rw-r--r--extern/bullet/BulletDynamics/ConstraintSolver/SimpleConstraintSolver.h32
-rw-r--r--extern/bullet/BulletDynamics/ConstraintSolver/Solve2LinearConstraint.cpp234
-rw-r--r--extern/bullet/BulletDynamics/ConstraintSolver/Solve2LinearConstraint.h101
-rw-r--r--extern/bullet/BulletDynamics/ConstraintSolver/SorLcp.cpp821
-rw-r--r--extern/bullet/BulletDynamics/ConstraintSolver/SorLcp.h32
-rw-r--r--extern/bullet/BulletDynamics/Dynamics/BU_Joint.cpp10
-rw-r--r--extern/bullet/BulletDynamics/Dynamics/BU_Joint.h78
-rw-r--r--extern/bullet/BulletDynamics/Dynamics/ContactJoint.cpp233
-rw-r--r--extern/bullet/BulletDynamics/Dynamics/ContactJoint.h33
-rw-r--r--extern/bullet/BulletDynamics/Dynamics/MassProps.h18
-rw-r--r--extern/bullet/BulletDynamics/Dynamics/RigidBody.cpp157
-rw-r--r--extern/bullet/BulletDynamics/Dynamics/RigidBody.h165
-rw-r--r--extern/bullet/BulletLicense.txt14
-rw-r--r--extern/bullet/Extras/PhysicsInterface/CcdPhysics/CcdPhysics.dsp112
-rw-r--r--extern/bullet/Extras/PhysicsInterface/CcdPhysics/CcdPhysicsController.cpp230
-rw-r--r--extern/bullet/Extras/PhysicsInterface/CcdPhysics/CcdPhysicsController.h133
-rw-r--r--extern/bullet/Extras/PhysicsInterface/CcdPhysics/CcdPhysicsEnvironment.h121
-rw-r--r--extern/bullet/Extras/PhysicsInterface/CcdPhysics/CcdPhysics_vc7.vcproj131
-rw-r--r--extern/bullet/Extras/PhysicsInterface/CcdPhysics/CcdPhysics_vc8.vcproj185
-rw-r--r--extern/bullet/Extras/PhysicsInterface/Common/PHY_DynamicTypes.h87
-rw-r--r--extern/bullet/Extras/PhysicsInterface/Common/PHY_IMotionState.cpp23
-rw-r--r--extern/bullet/Extras/PhysicsInterface/Common/PHY_IMotionState.h39
-rw-r--r--extern/bullet/Extras/PhysicsInterface/Common/PHY_IPhysicsController.cpp24
-rw-r--r--extern/bullet/Extras/PhysicsInterface/Common/PHY_IPhysicsController.h85
-rw-r--r--extern/bullet/Extras/PhysicsInterface/Common/PHY_IPhysicsEnvironment.cpp30
-rw-r--r--extern/bullet/Extras/PhysicsInterface/Common/PHY_IPhysicsEnvironment.h54
-rw-r--r--extern/bullet/Extras/PhysicsInterface/Common/PHY_Pro.h45
-rw-r--r--extern/bullet/Extras/PhysicsInterface/Common/PhysicsInterface.dsp128
-rw-r--r--extern/bullet/Extras/PhysicsInterface/Common/PhysicsInterfaceCommon/PhysicsInterfaceCommon_vc7.vcproj143
-rw-r--r--extern/bullet/Extras/PhysicsInterface/Common/PhysicsInterfaceCommon/PhysicsInterfaceCommon_vc8.vcproj201
-rw-r--r--extern/bullet/LinearMath/AabbUtil2.h67
-rw-r--r--extern/bullet/LinearMath/GEN_List.h85
-rw-r--r--extern/bullet/LinearMath/GEN_MinMax.h81
-rw-r--r--extern/bullet/LinearMath/GEN_random.h54
-rw-r--r--extern/bullet/LinearMath/SimdMatrix3x3.h407
-rw-r--r--extern/bullet/LinearMath/SimdMinMax.h52
-rw-r--r--extern/bullet/LinearMath/SimdPoint3.h36
-rw-r--r--extern/bullet/LinearMath/SimdQuadWord.h113
-rw-r--r--extern/bullet/LinearMath/SimdQuaternion.h302
-rw-r--r--extern/bullet/LinearMath/SimdScalar.h95
-rw-r--r--extern/bullet/LinearMath/SimdTransform.h248
-rw-r--r--extern/bullet/LinearMath/SimdTransformUtil.h94
-rw-r--r--extern/bullet/LinearMath/SimdVector3.h396
-rw-r--r--extern/bullet/continuous.dsw239
-rw-r--r--extern/bullet/continuous_vc7.sln140
-rw-r--r--extern/bullet/continuous_vc8.sln129
156 files changed, 19816 insertions, 0 deletions
diff --git a/extern/bullet/Bullet/BroadphaseCollision/BroadphaseInterface.h b/extern/bullet/Bullet/BroadphaseCollision/BroadphaseInterface.h
new file mode 100644
index 00000000000..29c6a64eedc
--- /dev/null
+++ b/extern/bullet/Bullet/BroadphaseCollision/BroadphaseInterface.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies.
+ * Erwin Coumans makes no representations about the suitability
+ * of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+*/
+#ifndef BROADPHASE_INTERFACE_H
+#define BROADPHASE_INTERFACE_H
+
+
+struct DispatcherInfo;
+class Dispatcher;
+struct BroadphaseProxy;
+#include "SimdVector3.h"
+
+///BroadphaseInterface for aabb-overlapping object pairs
+class BroadphaseInterface
+{
+public:
+ virtual BroadphaseProxy* CreateProxy( void *object,int type, const SimdVector3& min, const SimdVector3& max) =0;
+ virtual void DestroyProxy(BroadphaseProxy* proxy)=0;
+ virtual void SetAabb(BroadphaseProxy* proxy,const SimdVector3& aabbMin,const SimdVector3& aabbMax)=0;
+ virtual void CleanProxyFromPairs(BroadphaseProxy* proxy)=0;
+ virtual void DispatchAllCollisionPairs(Dispatcher& dispatcher,DispatcherInfo& dispatchInfo)=0;
+
+};
+
+#endif //BROADPHASE_INTERFACE_H
diff --git a/extern/bullet/Bullet/BroadphaseCollision/BroadphaseProxy.cpp b/extern/bullet/Bullet/BroadphaseCollision/BroadphaseProxy.cpp
new file mode 100644
index 00000000000..b7c6c72c8be
--- /dev/null
+++ b/extern/bullet/Bullet/BroadphaseCollision/BroadphaseProxy.cpp
@@ -0,0 +1,12 @@
+/*
+ * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies.
+ * Erwin Coumans makes no representations about the suitability
+ * of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+*/
+#include "BroadphaseProxy.h"
+
diff --git a/extern/bullet/Bullet/BroadphaseCollision/BroadphaseProxy.h b/extern/bullet/Bullet/BroadphaseCollision/BroadphaseProxy.h
new file mode 100644
index 00000000000..9dfeb370347
--- /dev/null
+++ b/extern/bullet/Bullet/BroadphaseCollision/BroadphaseProxy.h
@@ -0,0 +1,125 @@
+/*
+ * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies.
+ * Erwin Coumans makes no representations about the suitability
+ * of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+*/
+#ifndef BROADPHASE_PROXY_H
+#define BROADPHASE_PROXY_H
+
+
+
+/// Dispatcher uses these types
+/// IMPORTANT NOTE:The types are ordered polyhedral, implicit convex and concave
+/// to facilitate type checking
+enum BroadphaseNativeTypes
+{
+// polyhedral convex shapes
+ BOX_SHAPE_PROXYTYPE,
+ TRIANGLE_SHAPE_PROXYTYPE,
+ TETRAHEDRAL_SHAPE_PROXYTYPE,
+ CONVEX_HULL_SHAPE_PROXYTYPE,
+//implicit convex shapes
+IMPLICIT_CONVEX_SHAPES_START_HERE,
+ SPHERE_SHAPE_PROXYTYPE,
+ MULTI_SPHERE_SHAPE_PROXYTYPE,
+ CONE_SHAPE_PROXYTYPE,
+ CONVEX_SHAPE_PROXYTYPE,
+ CYLINDER_SHAPE_PROXYTYPE,
+ MINKOWSKI_SUM_SHAPE_PROXYTYPE,
+ MINKOWSKI_DIFFERENCE_SHAPE_PROXYTYPE,
+//concave shapes
+CONCAVE_SHAPES_START_HERE,
+ //keep all the convex shapetype below here, for the check IsConvexShape in broadphase proxy!
+ TRIANGLE_MESH_SHAPE_PROXYTYPE,
+
+ MAX_BROADPHASE_COLLISION_TYPES
+};
+
+
+///BroadphaseProxy
+struct BroadphaseProxy
+{
+ BroadphaseProxy() :m_clientObject(0),m_clientObjectType(-1){}
+ BroadphaseProxy(void* object,int type)
+ :m_clientObject(object),
+ m_clientObjectType(type)
+ {
+ }
+
+ void *m_clientObject;
+
+ int GetClientObjectType ( ) const { return m_clientObjectType;}
+
+
+ void SetClientObjectType( int type ) {
+ m_clientObjectType = type;
+ }
+
+ bool IsConvexShape()
+ {
+ return (GetClientObjectType () < TRIANGLE_MESH_SHAPE_PROXYTYPE);
+ }
+ bool IsConcaveShape()
+ {
+ return (GetClientObjectType() > CONCAVE_SHAPES_START_HERE);
+ }
+
+protected:
+ int m_clientObjectType;
+};
+
+class CollisionAlgorithm;
+
+struct BroadphaseProxy;
+
+#define SIMPLE_MAX_ALGORITHMS 2
+
+/// contains a pair of aabb-overlapping objects
+struct BroadphasePair
+{
+ BroadphasePair ()
+ :
+ m_pProxy0(0),
+ m_pProxy1(0)
+ {
+ for (int i=0;i<SIMPLE_MAX_ALGORITHMS;i++)
+ {
+ m_algorithms[i] = 0;
+ }
+ }
+
+ BroadphasePair(const BroadphasePair& other)
+ : m_pProxy0(other.m_pProxy0),
+ m_pProxy1(other.m_pProxy1)
+ {
+ for (int i=0;i<SIMPLE_MAX_ALGORITHMS;i++)
+ {
+ m_algorithms[i] = other.m_algorithms[i];
+ }
+ }
+ BroadphasePair(BroadphaseProxy& proxy0,BroadphaseProxy& proxy1)
+ :
+ m_pProxy0(&proxy0),
+ m_pProxy1(&proxy1)
+ {
+ for (int i=0;i<SIMPLE_MAX_ALGORITHMS;i++)
+ {
+ m_algorithms[i] = 0;
+ }
+
+ }
+
+
+ BroadphaseProxy* m_pProxy0;
+ BroadphaseProxy* m_pProxy1;
+
+ mutable CollisionAlgorithm* m_algorithms[SIMPLE_MAX_ALGORITHMS];
+};
+
+#endif //BROADPHASE_PROXY_H
+
diff --git a/extern/bullet/Bullet/BroadphaseCollision/CollisionAlgorithm.cpp b/extern/bullet/Bullet/BroadphaseCollision/CollisionAlgorithm.cpp
new file mode 100644
index 00000000000..a4e20359aea
--- /dev/null
+++ b/extern/bullet/Bullet/BroadphaseCollision/CollisionAlgorithm.cpp
@@ -0,0 +1,18 @@
+/*
+ * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies.
+ * Erwin Coumans makes no representations about the suitability
+ * of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+*/
+#include "CollisionAlgorithm.h"
+#include "CollisionDispatcher.h"
+
+CollisionAlgorithm::CollisionAlgorithm(const CollisionAlgorithmConstructionInfo& ci)
+{
+ m_dispatcher = ci.m_dispatcher;
+}
+
diff --git a/extern/bullet/Bullet/BroadphaseCollision/CollisionAlgorithm.h b/extern/bullet/Bullet/BroadphaseCollision/CollisionAlgorithm.h
new file mode 100644
index 00000000000..5699f1019df
--- /dev/null
+++ b/extern/bullet/Bullet/BroadphaseCollision/CollisionAlgorithm.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies.
+ * Erwin Coumans makes no representations about the suitability
+ * of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+*/
+#ifndef COLLISION_ALGORITHM_H
+#define COLLISION_ALGORITHM_H
+
+struct BroadphaseProxy;
+class Dispatcher;
+
+struct CollisionAlgorithmConstructionInfo
+{
+ CollisionAlgorithmConstructionInfo()
+ :m_dispatcher(0)
+ {
+ }
+ CollisionAlgorithmConstructionInfo(Dispatcher* dispatcher,int temp)
+ :m_dispatcher(dispatcher)
+ {
+ }
+
+ Dispatcher* m_dispatcher;
+
+ int GetDispatcherId();
+
+};
+
+
+///CollisionAlgorithm is an collision interface that is compatible with the Broadphase and Dispatcher.
+///It is persistent over frames
+class CollisionAlgorithm
+{
+
+protected:
+
+ Dispatcher* m_dispatcher;
+
+protected:
+ int GetDispatcherId();
+
+public:
+
+ CollisionAlgorithm() {};
+
+ CollisionAlgorithm(const CollisionAlgorithmConstructionInfo& ci);
+
+ virtual ~CollisionAlgorithm() {};
+
+ virtual void ProcessCollision (BroadphaseProxy* proxy0,BroadphaseProxy* proxy1,float timeStep,int stepCount, bool useContinuous) = 0;
+
+ virtual float CalculateTimeOfImpact(BroadphaseProxy* proxy0,BroadphaseProxy* proxy1,float timeStep,int stepCount) = 0;
+
+};
+
+
+#endif //COLLISION_ALGORITHM_H
diff --git a/extern/bullet/Bullet/BroadphaseCollision/CollisionDispatcher.cpp b/extern/bullet/Bullet/BroadphaseCollision/CollisionDispatcher.cpp
new file mode 100644
index 00000000000..65a7b616fb2
--- /dev/null
+++ b/extern/bullet/Bullet/BroadphaseCollision/CollisionDispatcher.cpp
@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies.
+ * Erwin Coumans makes no representations about the suitability
+ * of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+*/
+#include "CollisionDispatcher.h"
+
+Dispatcher::~Dispatcher()
+{
+
+}
+
diff --git a/extern/bullet/Bullet/BroadphaseCollision/CollisionDispatcher.h b/extern/bullet/Bullet/BroadphaseCollision/CollisionDispatcher.h
new file mode 100644
index 00000000000..7787ed417c5
--- /dev/null
+++ b/extern/bullet/Bullet/BroadphaseCollision/CollisionDispatcher.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies.
+ * Erwin Coumans makes no representations about the suitability
+ * of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+*/
+#ifndef COLLISION_DISPATCHER_H
+#define COLLISION_DISPATCHER_H
+
+class CollisionAlgorithm;
+struct BroadphaseProxy;
+class RigidBody;
+
+enum CollisionDispatcherId
+{
+ RIGIDBODY_DISPATCHER = 0,
+ RAGDOLL_DISPATCHER
+};
+
+class PersistentManifold;
+
+struct DispatcherInfo
+{
+ enum DispatchFunc
+ {
+ DISPATCH_DISCRETE = 1,
+ DISPATCH_CONTINUOUS
+ };
+ DispatcherInfo()
+ :m_dispatchFunc(DISPATCH_DISCRETE),
+ m_timeOfImpact(1.f),
+ m_useContinuous(false)
+ {
+
+ }
+ float m_timeStep;
+ int m_stepCount;
+ int m_dispatchFunc;
+ float m_timeOfImpact;
+ bool m_useContinuous;
+
+};
+
+/// Collision Dispatcher can be used in combination with broadphase and collision algorithms.
+class Dispatcher
+{
+
+
+public:
+ virtual ~Dispatcher() ;
+
+ virtual CollisionAlgorithm* FindAlgorithm(BroadphaseProxy& proxy0,BroadphaseProxy& proxy1) = 0;
+
+ //
+ // asume dispatchers to have unique id's in the range [0..max dispacher]
+ //
+ virtual int GetUniqueId() = 0;
+
+ virtual PersistentManifold* GetNewManifold(void* body0,void* body1)=0;
+
+ virtual void ReleaseManifold(PersistentManifold* manifold)=0;
+
+
+};
+
+
+#endif //COLLISION_DISPATCHER_H
diff --git a/extern/bullet/Bullet/BroadphaseCollision/SimpleBroadphase.cpp b/extern/bullet/Bullet/BroadphaseCollision/SimpleBroadphase.cpp
new file mode 100644
index 00000000000..5d72376825d
--- /dev/null
+++ b/extern/bullet/Bullet/BroadphaseCollision/SimpleBroadphase.cpp
@@ -0,0 +1,273 @@
+/*
+ * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies.
+ * Erwin Coumans makes no representations about the suitability
+ * of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+*/
+#include "SimpleBroadphase.h"
+#include "BroadphaseCollision/CollisionDispatcher.h"
+#include "BroadphaseCollision/CollisionAlgorithm.h"
+
+#include "SimdVector3.h"
+#include "SimdTransform.h"
+#include "SimdMatrix3x3.h"
+#include <vector>
+#include "NarrowPhaseCollision/CollisionMargin.h"
+
+SimpleBroadphase::SimpleBroadphase()
+: m_firstFreeProxy(0),
+ m_numProxies(0),
+ m_blockedForChanges(false),
+ m_NumOverlapBroadphasePair(0)
+{
+ int i;
+ for (i=0;i<SIMPLE_MAX_PROXIES;i++)
+ {
+ m_freeProxies[i] = i;
+ }
+}
+
+SimpleBroadphase::~SimpleBroadphase()
+{
+ /*int i;
+ for (i=m_numProxies-1;i>=0;i--)
+ {
+ BP_Proxy* proxy = m_pProxies[i];
+ destroyProxy(proxy);
+ }
+ */
+}
+
+
+BroadphaseProxy* SimpleBroadphase::CreateProxy( void *object, int type, const SimdVector3& min, const SimdVector3& max)
+{
+ if (m_numProxies >= SIMPLE_MAX_PROXIES)
+ {
+ assert(0);
+ return 0; //should never happen, but don't let the game crash ;-)
+ }
+ assert(min[0]<= max[0] && min[1]<= max[1] && min[2]<= max[2]);
+
+ int freeIndex= m_freeProxies[m_firstFreeProxy];
+ BroadphaseProxy* proxy = new (&m_proxies[freeIndex])SimpleBroadphaseProxy(object,type,min,max);
+ m_firstFreeProxy++;
+
+ m_pProxies[m_numProxies] = proxy;
+ m_numProxies++;
+
+ return proxy;
+}
+void SimpleBroadphase::DestroyProxy(BroadphaseProxy* proxy)
+{
+ m_numProxies--;
+ BroadphaseProxy* proxy1 = &m_proxies[0];
+
+ int index = proxy - proxy1;
+ m_freeProxies[--m_firstFreeProxy] = index;
+
+}
+
+SimpleBroadphaseProxy* SimpleBroadphase::GetSimpleProxyFromProxy(BroadphaseProxy* proxy)
+{
+ SimpleBroadphaseProxy* proxy0 = static_cast<SimpleBroadphaseProxy*>(proxy);
+
+ int index = proxy0 - &m_proxies[0];
+ assert(index < m_numProxies);
+
+ SimpleBroadphaseProxy* sbp = &m_proxies[index];
+ return sbp;
+}
+void SimpleBroadphase::SetAabb(BroadphaseProxy* proxy,const SimdVector3& aabbMin,const SimdVector3& aabbMax)
+{
+ SimpleBroadphaseProxy* sbp = GetSimpleProxyFromProxy(proxy);
+ sbp->m_min = aabbMin;
+ sbp->m_max = aabbMax;
+}
+
+void SimpleBroadphase::CleanOverlappingPair(BroadphasePair& pair)
+{
+ for (int dispatcherId=0;dispatcherId<SIMPLE_MAX_ALGORITHMS;dispatcherId++)
+ {
+ if (pair.m_algorithms[dispatcherId])
+ {
+ {
+ delete pair.m_algorithms[dispatcherId];
+ pair.m_algorithms[dispatcherId]=0;
+ }
+ }
+ }
+}
+
+
+void SimpleBroadphase::CleanProxyFromPairs(BroadphaseProxy* proxy)
+{
+ for (int i=0;i<m_NumOverlapBroadphasePair;i++)
+ {
+ BroadphasePair& pair = m_OverlappingPairs[i];
+ if (pair.m_pProxy0 == proxy ||
+ pair.m_pProxy1 == proxy)
+ {
+ CleanOverlappingPair(pair);
+ }
+ }
+}
+
+void SimpleBroadphase::AddOverlappingPair(BroadphaseProxy* proxy0,BroadphaseProxy* proxy1)
+{
+ BroadphasePair pair(*proxy0,*proxy1);
+ m_OverlappingPairs[m_NumOverlapBroadphasePair] = pair;
+
+ int i;
+ for (i=0;i<SIMPLE_MAX_ALGORITHMS;i++)
+ {
+ assert(!m_OverlappingPairs[m_NumOverlapBroadphasePair].m_algorithms[i]);
+ m_OverlappingPairs[m_NumOverlapBroadphasePair].m_algorithms[i] = 0;
+ }
+ m_NumOverlapBroadphasePair++;
+}
+
+bool SimpleBroadphase::FindPair(BroadphaseProxy* proxy0,BroadphaseProxy* proxy1)
+{
+ bool found = false;
+ int i;
+ for (i=m_NumOverlapBroadphasePair-1;i>=0;i--)
+ {
+ BroadphasePair& pair = m_OverlappingPairs[i];
+ if (((pair.m_pProxy0 == proxy0) && (pair.m_pProxy1 == proxy1)) ||
+ ((pair.m_pProxy0 == proxy1) && (pair.m_pProxy1 == proxy0)))
+ {
+ found = true;
+ break;
+ }
+ }
+
+ return found;
+}
+void SimpleBroadphase::RemoveOverlappingPair(BroadphasePair& pair)
+{
+ CleanOverlappingPair(pair);
+ int index = &pair - &m_OverlappingPairs[0];
+ //remove efficiently, swap with the last
+ m_OverlappingPairs[index] = m_OverlappingPairs[m_NumOverlapBroadphasePair-1];
+ m_NumOverlapBroadphasePair--;
+}
+
+bool SimpleBroadphase::AabbOverlap(SimpleBroadphaseProxy* proxy0,SimpleBroadphaseProxy* proxy1)
+{
+ return proxy0->m_min[0] <= proxy1->m_max[0] && proxy1->m_min[0] <= proxy0->m_max[0] &&
+ proxy0->m_min[1] <= proxy1->m_max[1] && proxy1->m_min[1] <= proxy0->m_max[1] &&
+ proxy0->m_min[2] <= proxy1->m_max[2] && proxy1->m_min[2] <= proxy0->m_max[2];
+
+}
+void SimpleBroadphase::RefreshOverlappingPairs()
+{
+ //first check for new overlapping pairs
+ int i,j;
+
+ for (i=0;i<m_numProxies;i++)
+ {
+ BroadphaseProxy* proxy0 = m_pProxies[i];
+ for (j=i+1;j<m_numProxies;j++)
+ {
+ BroadphaseProxy* proxy1 = m_pProxies[j];
+ SimpleBroadphaseProxy* p0 = GetSimpleProxyFromProxy(proxy0);
+ SimpleBroadphaseProxy* p1 = GetSimpleProxyFromProxy(proxy1);
+
+ if (AabbOverlap(p0,p1))
+ {
+ if ( !FindPair(proxy0,proxy1))
+ {
+ AddOverlappingPair(proxy0,proxy1);
+ }
+ }
+
+ }
+ }
+
+ //then remove non-overlapping ones
+ for (i=0;i<m_NumOverlapBroadphasePair;i++)
+ {
+ BroadphasePair& pair = m_OverlappingPairs[i];
+ SimpleBroadphaseProxy* proxy0 = GetSimpleProxyFromProxy(pair.m_pProxy0);
+ SimpleBroadphaseProxy* proxy1 = GetSimpleProxyFromProxy(pair.m_pProxy1);
+ if (!AabbOverlap(proxy0,proxy1))
+ {
+ RemoveOverlappingPair(pair);
+ }
+ }
+
+ //BroadphasePair m_OverlappingPairs[SIMPLE_MAX_OVERLAP];
+ //int m_NumOverlapBroadphasePair;
+
+}
+
+void SimpleBroadphase::DispatchAllCollisionPairs(Dispatcher& dispatcher,DispatcherInfo& dispatchInfo)
+{
+ m_blockedForChanges = true;
+
+ int i;
+
+ int dispatcherId = dispatcher.GetUniqueId();
+
+ RefreshOverlappingPairs();
+
+ for (i=0;i<m_NumOverlapBroadphasePair;i++)
+ {
+
+ BroadphasePair& pair = m_OverlappingPairs[i];
+
+ if (dispatcherId>= 0)
+ {
+ //dispatcher will keep algorithms persistent in the collision pair
+ if (!pair.m_algorithms[dispatcherId])
+ {
+ pair.m_algorithms[dispatcherId] = dispatcher.FindAlgorithm(
+ *pair.m_pProxy0,
+ *pair.m_pProxy1);
+ }
+
+ if (pair.m_algorithms[dispatcherId])
+ {
+ if (dispatchInfo.m_dispatchFunc == DispatcherInfo::DISPATCH_DISCRETE)
+ {
+ pair.m_algorithms[dispatcherId]->ProcessCollision(pair.m_pProxy0,pair.m_pProxy1,dispatchInfo.m_timeStep,dispatchInfo.m_stepCount,dispatchInfo.m_useContinuous);
+ } else
+ {
+ float toi = pair.m_algorithms[dispatcherId]->CalculateTimeOfImpact(pair.m_pProxy0,pair.m_pProxy1,dispatchInfo.m_timeStep,dispatchInfo.m_stepCount);
+ if (dispatchInfo.m_timeOfImpact > toi)
+ dispatchInfo.m_timeOfImpact = toi;
+
+ }
+ }
+ } else
+ {
+ //non-persistent algorithm dispatcher
+ CollisionAlgorithm* algo = dispatcher.FindAlgorithm(
+ *pair.m_pProxy0,
+ *pair.m_pProxy1);
+
+ if (algo)
+ {
+ if (dispatchInfo.m_dispatchFunc == DispatcherInfo::DISPATCH_DISCRETE)
+ {
+ algo->ProcessCollision(pair.m_pProxy0,pair.m_pProxy1,dispatchInfo.m_timeStep,dispatchInfo.m_stepCount,dispatchInfo.m_useContinuous);
+ } else
+ {
+ float toi = algo->CalculateTimeOfImpact(pair.m_pProxy0,pair.m_pProxy1,dispatchInfo.m_timeStep,dispatchInfo.m_stepCount);
+ if (dispatchInfo.m_timeOfImpact > toi)
+ dispatchInfo.m_timeOfImpact = toi;
+ }
+ }
+ }
+
+ }
+
+ m_blockedForChanges = false;
+
+}
+
+
diff --git a/extern/bullet/Bullet/BroadphaseCollision/SimpleBroadphase.h b/extern/bullet/Bullet/BroadphaseCollision/SimpleBroadphase.h
new file mode 100644
index 00000000000..754d004d111
--- /dev/null
+++ b/extern/bullet/Bullet/BroadphaseCollision/SimpleBroadphase.h
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies.
+ * Erwin Coumans makes no representations about the suitability
+ * of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+*/
+#ifndef SIMPLE_BROADPHASE_H
+#define SIMPLE_BROADPHASE_H
+
+#define SIMPLE_MAX_PROXIES 8192
+#define SIMPLE_MAX_OVERLAP 4096
+
+#include "BroadphaseInterface.h"
+#include "BroadphaseProxy.h"
+#include "SimdPoint3.h"
+
+struct SimpleBroadphaseProxy : public BroadphaseProxy
+{
+ SimdVector3 m_min;
+ SimdVector3 m_max;
+
+ SimpleBroadphaseProxy() {};
+
+ SimpleBroadphaseProxy(void* object,int type,const SimdPoint3& minpt,const SimdPoint3& maxpt)
+ :BroadphaseProxy(object,type),
+ m_min(minpt),m_max(maxpt)
+ {
+ }
+
+
+};
+
+///SimpleBroadphase is a brute force aabb culling broadphase based on O(n^2) aabb checks
+class SimpleBroadphase : public BroadphaseInterface
+{
+
+ SimpleBroadphaseProxy m_proxies[SIMPLE_MAX_PROXIES];
+ int m_freeProxies[SIMPLE_MAX_PROXIES];
+ int m_firstFreeProxy;
+
+ BroadphaseProxy* m_pProxies[SIMPLE_MAX_PROXIES];
+ int m_numProxies;
+
+ //during the dispatch, check that user doesn't destroy/create proxy
+ bool m_blockedForChanges;
+
+ BroadphasePair m_OverlappingPairs[SIMPLE_MAX_OVERLAP];
+ int m_NumOverlapBroadphasePair;
+
+
+ SimpleBroadphaseProxy* GetSimpleProxyFromProxy(BroadphaseProxy* proxy);
+
+ bool AabbOverlap(SimpleBroadphaseProxy* proxy0,SimpleBroadphaseProxy* proxy1);
+ void RemoveOverlappingPair(BroadphasePair& pair);
+ void CleanOverlappingPair(BroadphasePair& pair);
+ void AddOverlappingPair(BroadphaseProxy* proxy0,BroadphaseProxy* proxy1);
+ bool FindPair(BroadphaseProxy* proxy0,BroadphaseProxy* proxy1);
+ void RefreshOverlappingPairs();
+public:
+ SimpleBroadphase();
+ virtual ~SimpleBroadphase();
+
+ virtual BroadphaseProxy* CreateProxy( void *object,int type, const SimdVector3& min, const SimdVector3& max) ;
+ virtual void DestroyProxy(BroadphaseProxy* proxy);
+ virtual void SetAabb(BroadphaseProxy* proxy,const SimdVector3& aabbMin,const SimdVector3& aabbMax);
+ virtual void CleanProxyFromPairs(BroadphaseProxy* proxy);
+ virtual void DispatchAllCollisionPairs(Dispatcher& dispatcher,DispatcherInfo& dispatchInfo);
+
+};
+
+
+
+#endif //SIMPLE_BROADPHASE_H
+
diff --git a/extern/bullet/Bullet/Bullet3.dsp b/extern/bullet/Bullet/Bullet3.dsp
new file mode 100644
index 00000000000..2e4ffaf6738
--- /dev/null
+++ b/extern/bullet/Bullet/Bullet3.dsp
@@ -0,0 +1,412 @@
+# Microsoft Developer Studio Project File - Name="Bullet" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Static Library" 0x0104
+
+CFG=Bullet - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "Bullet3.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "Bullet3.mak" CFG="Bullet - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "Bullet - Win32 Release" (based on "Win32 (x86) Static Library")
+!MESSAGE "Bullet - Win32 Debug" (based on "Win32 (x86) Static Library")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "Bullet - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Target_Dir ""
+MTL=midl.exe
+LINK32=link.exe -lib
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
+# ADD CPP /nologo /MT /W3 /GX /Zd /O2 /I "../LinearMath" /I "." /D "NDEBUG" /D "_LIB" /D "WIN32" /D "_MBCS" /D "BUM_INLINED" /D "USE_ALGEBRAIC" /YX /FD /c
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LIB32=link.exe -lib
+# ADD BASE LIB32 /nologo
+# ADD LIB32 /nologo
+
+!ELSEIF "$(CFG)" == "Bullet - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Target_Dir ""
+MTL=midl.exe
+LINK32=link.exe -lib
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
+# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "../LinearMath" /I "." /D "_DEBUG" /D "_LIB" /D "WIN32" /D "_MBCS" /D "BUM_INLINED" /D "USE_ALGEBRAIC" /YX /FD /GZ /c
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LIB32=link.exe -lib
+# ADD BASE LIB32 /nologo
+# ADD LIB32 /nologo
+
+!ENDIF
+
+# Begin Target
+
+# Name "Bullet - Win32 Release"
+# Name "Bullet - Win32 Debug"
+# Begin Group "NarrowPhaseCollision"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=.\NarrowPhaseCollision\BU_AlgebraicPolynomialSolver.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\NarrowPhaseCollision\BU_AlgebraicPolynomialSolver.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\NarrowPhaseCollision\BU_Collidable.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\NarrowPhaseCollision\BU_Collidable.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\NarrowPhaseCollision\BU_CollisionPair.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\NarrowPhaseCollision\BU_CollisionPair.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\NarrowPhaseCollision\BU_EdgeEdge.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\NarrowPhaseCollision\BU_EdgeEdge.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\NarrowPhaseCollision\BU_MotionStateInterface.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\NarrowPhaseCollision\BU_PolynomialSolverInterface.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\NarrowPhaseCollision\BU_Screwing.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\NarrowPhaseCollision\BU_Screwing.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\NarrowPhaseCollision\BU_StaticMotionState.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\NarrowPhaseCollision\BU_VertexPoly.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\NarrowPhaseCollision\BU_VertexPoly.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\NarrowPhaseCollision\CollisionMargin.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\NarrowPhaseCollision\ContinuousConvexCollision.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\NarrowPhaseCollision\ContinuousConvexCollision.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\NarrowPhaseCollision\ConvexCast.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\NarrowPhaseCollision\ConvexCast.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\NarrowPhaseCollision\ConvexPenetrationDepthSolver.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\NarrowPhaseCollision\DiscreteCollisionDetectorInterface.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\NarrowPhaseCollision\GjkConvexCast.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\NarrowPhaseCollision\GjkConvexCast.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\NarrowPhaseCollision\GjkPairDetector.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\NarrowPhaseCollision\GjkPairDetector.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\NarrowPhaseCollision\ManifoldPoint.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\NarrowPhaseCollision\MinkowskiPenetrationDepthSolver.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\NarrowPhaseCollision\MinkowskiPenetrationDepthSolver.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\NarrowPhaseCollision\PersistentManifold.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\NarrowPhaseCollision\PersistentManifold.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\NarrowPhaseCollision\PointCollector.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\NarrowPhaseCollision\RaycastCallback.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\NarrowPhaseCollision\RaycastCallback.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\NarrowPhaseCollision\SimplexSolverInterface.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\NarrowPhaseCollision\SubSimplexConvexCast.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\NarrowPhaseCollision\SubSimplexConvexCast.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\NarrowPhaseCollision\VoronoiSimplexSolver.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\NarrowPhaseCollision\VoronoiSimplexSolver.h
+# End Source File
+# End Group
+# Begin Group "BroadphaseCollision"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=.\BroadphaseCollision\BroadPhaseInterface.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\BroadphaseCollision\BroadphaseProxy.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\BroadphaseCollision\BroadphaseProxy.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\BroadphaseCollision\CollisionAlgorithm.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\BroadphaseCollision\CollisionAlgorithm.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\BroadphaseCollision\CollisionDispatcher.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\BroadphaseCollision\CollisionDispatcher.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\BroadphaseCollision\SimpleBroadphase.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\BroadphaseCollision\SimpleBroadphase.h
+# End Source File
+# End Group
+# Begin Group "CollisionShapes"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=.\CollisionShapes\BoxShape.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\CollisionShapes\BoxShape.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\CollisionShapes\CollisionShape.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\CollisionShapes\CollisionShape.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\CollisionShapes\ConeShape.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\CollisionShapes\ConeShape.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\CollisionShapes\ConvexHullShape.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\CollisionShapes\ConvexHullShape.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\CollisionShapes\ConvexShape.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\CollisionShapes\ConvexShape.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\CollisionShapes\CylinderShape.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\CollisionShapes\CylinderShape.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\CollisionShapes\MinkowskiSumShape.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\CollisionShapes\MinkowskiSumShape.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\CollisionShapes\MultiSphereShape.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\CollisionShapes\MultiSphereShape.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\CollisionShapes\PolyhedralConvexShape.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\CollisionShapes\PolyhedralConvexShape.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\CollisionShapes\Simplex1to4Shape.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\CollisionShapes\Simplex1to4Shape.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\CollisionShapes\SphereShape.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\CollisionShapes\SphereShape.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\CollisionShapes\StridingMeshInterface.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\CollisionShapes\StridingMeshInterface.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\CollisionShapes\TriangleCallback.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\CollisionShapes\TriangleMesh.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\CollisionShapes\TriangleMesh.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\CollisionShapes\TriangleMeshShape.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\CollisionShapes\TriangleMeshShape.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\CollisionShapes\TriangleShape.h
+# End Source File
+# End Group
+# End Target
+# End Project
diff --git a/extern/bullet/Bullet/Bullet3_vc7.vcproj b/extern/bullet/Bullet/Bullet3_vc7.vcproj
new file mode 100644
index 00000000000..dab745810a0
--- /dev/null
+++ b/extern/bullet/Bullet/Bullet3_vc7.vcproj
@@ -0,0 +1,427 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="7.10"
+ Name="Bullet3ContinuousCollision"
+ ProjectGUID="{FFD3C64A-30E2-4BC7-BC8F-51818C320400}"
+ SccProjectName=""
+ SccLocalPath="">
+ <Platforms>
+ <Platform
+ Name="Win32"/>
+ </Platforms>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory=".\Debug"
+ IntermediateDirectory=".\Debug"
+ ConfigurationType="4"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="FALSE"
+ CharacterSet="2">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=".;..\LinearMath"
+ PreprocessorDefinitions="_DEBUG;_LIB;WIN32;BUM_INLINED;USE_ALGEBRAIC"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="1"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderFile=".\Debug/Bullet.pch"
+ AssemblerListingLocation=".\Debug/"
+ ObjectFile=".\Debug/"
+ ProgramDataBaseFileName=".\Debug/"
+ WarningLevel="3"
+ SuppressStartupBanner="TRUE"
+ DebugInformationFormat="4"
+ CompileAs="0"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLibrarianTool"
+ OutputFile=".\Debug\Bullet.lib"
+ SuppressStartupBanner="TRUE"/>
+ <Tool
+ Name="VCMIDLTool"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_DEBUG"
+ Culture="1033"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory=".\Release"
+ IntermediateDirectory=".\Release"
+ ConfigurationType="4"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="FALSE"
+ CharacterSet="2">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ InlineFunctionExpansion="1"
+ AdditionalIncludeDirectories=".;..\LinearMath"
+ PreprocessorDefinitions="NDEBUG;_LIB;WIN32;BUM_INLINED;USE_ALGEBRAIC"
+ StringPooling="TRUE"
+ RuntimeLibrary="0"
+ EnableFunctionLevelLinking="TRUE"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderFile=".\Release/Bullet.pch"
+ AssemblerListingLocation=".\Release/"
+ ObjectFile=".\Release/"
+ ProgramDataBaseFileName=".\Release/"
+ WarningLevel="3"
+ SuppressStartupBanner="TRUE"
+ DebugInformationFormat="2"
+ CompileAs="0"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLibrarianTool"
+ OutputFile="..\..\..\..\build\msvc_7\libs\extern\Bullet.lib"
+ SuppressStartupBanner="TRUE"/>
+ <Tool
+ Name="VCMIDLTool"/>
+ <Tool
+ Name="VCPostBuildEventTool"
+ CommandLine="ECHO Copying header files
+IF NOT EXIST ..\..\..\..\build\msvc_7\extern\bullet\include MKDIR ..\..\..\..\build\msvc_7\extern\bullet\include
+IF NOT EXIST ..\..\..\..\build\msvc_7\extern\bullet\include\BroadphaseCollision MKDIR ..\..\..\..\build\msvc_7\extern\bullet\include\BroadphaseCollision
+IF NOT EXIST ..\..\..\..\build\msvc_7\extern\bullet\include\CollisionShapes MKDIR ..\..\..\..\build\msvc_7\extern\bullet\include\CollisionShapes
+IF NOT EXIST ..\..\..\..\build\msvc_7\extern\bullet\include\NarrowPhaseCollision MKDIR ..\..\..\..\build\msvc_7\extern\bullet\include\NarrowPhaseCollision
+
+XCOPY /Y ..\LinearMath\*.h ..\..\..\..\build\msvc_7\extern\bullet\include
+XCOPY /Y ..\Bullet\BroadphaseCollision\*.h ..\..\..\..\build\msvc_7\extern\bullet\include\BroadphaseCollision
+XCOPY /Y ..\Bullet\CollisionShapes\*.h ..\..\..\..\build\msvc_7\extern\bullet\include\CollisionShapes
+XCOPY /Y ..\Bullet\NarrowPhaseCollision\*.h ..\..\..\..\build\msvc_7\extern\bullet\include\NarrowPhaseCollision
+
+ECHO Done
+"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG"
+ Culture="1033"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="NarrowPhaseCollision"
+ Filter="">
+ <File
+ RelativePath=".\NarrowPhaseCollision\BU_AlgebraicPolynomialSolver.cpp">
+ </File>
+ <File
+ RelativePath=".\NarrowPhaseCollision\BU_AlgebraicPolynomialSolver.h">
+ </File>
+ <File
+ RelativePath=".\NarrowPhaseCollision\BU_Collidable.cpp">
+ </File>
+ <File
+ RelativePath=".\NarrowPhaseCollision\BU_Collidable.h">
+ </File>
+ <File
+ RelativePath=".\NarrowPhaseCollision\BU_CollisionPair.cpp">
+ </File>
+ <File
+ RelativePath=".\NarrowPhaseCollision\BU_CollisionPair.h">
+ </File>
+ <File
+ RelativePath=".\NarrowPhaseCollision\BU_EdgeEdge.cpp">
+ </File>
+ <File
+ RelativePath=".\NarrowPhaseCollision\BU_EdgeEdge.h">
+ </File>
+ <File
+ RelativePath=".\NarrowPhaseCollision\BU_MotionStateInterface.h">
+ </File>
+ <File
+ RelativePath=".\NarrowPhaseCollision\BU_PolynomialSolverInterface.h">
+ </File>
+ <File
+ RelativePath=".\NarrowPhaseCollision\BU_Screwing.cpp">
+ </File>
+ <File
+ RelativePath=".\NarrowPhaseCollision\BU_Screwing.h">
+ </File>
+ <File
+ RelativePath=".\NarrowPhaseCollision\BU_StaticMotionState.h">
+ </File>
+ <File
+ RelativePath=".\NarrowPhaseCollision\BU_VertexPoly.cpp">
+ </File>
+ <File
+ RelativePath=".\NarrowPhaseCollision\BU_VertexPoly.h">
+ </File>
+ <File
+ RelativePath=".\NarrowPhaseCollision\CollisionMargin.h">
+ </File>
+ <File
+ RelativePath=".\NarrowPhaseCollision\ContinuousConvexCollision.cpp">
+ </File>
+ <File
+ RelativePath=".\NarrowPhaseCollision\ContinuousConvexCollision.h">
+ </File>
+ <File
+ RelativePath=".\NarrowPhaseCollision\ConvexCast.h">
+ </File>
+ <File
+ RelativePath=".\NarrowPhaseCollision\ConvexPenetrationDepthSolver.h">
+ </File>
+ <File
+ RelativePath=".\NarrowPhaseCollision\DiscreteCollisionDetectorInterface.h">
+ </File>
+ <File
+ RelativePath=".\NarrowPhaseCollision\GjkConvexCast.cpp">
+ </File>
+ <File
+ RelativePath=".\NarrowPhaseCollision\GjkConvexCast.h">
+ </File>
+ <File
+ RelativePath=".\NarrowPhaseCollision\GjkPairDetector.cpp">
+ </File>
+ <File
+ RelativePath=".\NarrowPhaseCollision\GjkPairDetector.h">
+ </File>
+ <File
+ RelativePath=".\NarrowPhaseCollision\ManifoldPoint.h">
+ </File>
+ <File
+ RelativePath=".\NarrowPhaseCollision\MinkowskiPenetrationDepthSolver.cpp">
+ </File>
+ <File
+ RelativePath=".\NarrowPhaseCollision\MinkowskiPenetrationDepthSolver.h">
+ </File>
+ <File
+ RelativePath=".\NarrowPhaseCollision\PersistentManifold.cpp">
+ </File>
+ <File
+ RelativePath=".\NarrowPhaseCollision\PersistentManifold.h">
+ </File>
+ <File
+ RelativePath=".\NarrowPhaseCollision\PointCollector.h">
+ </File>
+ <File
+ RelativePath=".\NarrowPhaseCollision\RaycastCallback.cpp">
+ </File>
+ <File
+ RelativePath=".\NarrowPhaseCollision\RaycastCallback.h">
+ </File>
+ <File
+ RelativePath=".\NarrowPhaseCollision\SimplexSolverInterface.h">
+ </File>
+ <File
+ RelativePath=".\NarrowPhaseCollision\SubSimplexConvexCast.cpp">
+ </File>
+ <File
+ RelativePath=".\NarrowPhaseCollision\SubSimplexConvexCast.h">
+ </File>
+ <File
+ RelativePath=".\NarrowPhaseCollision\VoronoiSimplexSolver.cpp">
+ </File>
+ <File
+ RelativePath=".\NarrowPhaseCollision\VoronoiSimplexSolver.h">
+ </File>
+ </Filter>
+ <Filter
+ Name="CollisionShapes"
+ Filter="">
+ <File
+ RelativePath=".\CollisionShapes\BoxShape.cpp">
+ </File>
+ <File
+ RelativePath=".\CollisionShapes\BoxShape.h">
+ </File>
+ <File
+ RelativePath=".\CollisionShapes\CollisionShape.cpp">
+ </File>
+ <File
+ RelativePath=".\CollisionShapes\CollisionShape.h">
+ </File>
+ <File
+ RelativePath=".\CollisionShapes\ConeShape.cpp">
+ </File>
+ <File
+ RelativePath=".\CollisionShapes\ConeShape.h">
+ </File>
+ <File
+ RelativePath=".\CollisionShapes\ConvexHullShape.cpp">
+ </File>
+ <File
+ RelativePath=".\CollisionShapes\ConvexHullShape.h">
+ </File>
+ <File
+ RelativePath=".\CollisionShapes\ConvexShape.cpp">
+ </File>
+ <File
+ RelativePath=".\CollisionShapes\ConvexShape.h">
+ </File>
+ <File
+ RelativePath=".\CollisionShapes\CylinderShape.cpp">
+ </File>
+ <File
+ RelativePath=".\CollisionShapes\CylinderShape.h">
+ </File>
+ <File
+ RelativePath=".\CollisionShapes\MinkowskiSumShape.cpp">
+ </File>
+ <File
+ RelativePath=".\CollisionShapes\MinkowskiSumShape.h">
+ </File>
+ <File
+ RelativePath=".\CollisionShapes\MultiSphereShape.cpp">
+ </File>
+ <File
+ RelativePath=".\CollisionShapes\MultiSphereShape.h">
+ </File>
+ <File
+ RelativePath=".\CollisionShapes\PolyhedralConvexShape.cpp">
+ </File>
+ <File
+ RelativePath=".\CollisionShapes\PolyhedralConvexShape.h">
+ </File>
+ <File
+ RelativePath=".\CollisionShapes\Simplex1to4Shape.cpp">
+ </File>
+ <File
+ RelativePath=".\CollisionShapes\Simplex1to4Shape.h">
+ </File>
+ <File
+ RelativePath=".\CollisionShapes\SphereShape.cpp">
+ </File>
+ <File
+ RelativePath=".\CollisionShapes\SphereShape.h">
+ </File>
+ <File
+ RelativePath=".\CollisionShapes\StridingMeshInterface.cpp">
+ </File>
+ <File
+ RelativePath=".\CollisionShapes\StridingMeshInterface.h">
+ </File>
+ <File
+ RelativePath=".\CollisionShapes\TriangleCallback.h">
+ </File>
+ <File
+ RelativePath=".\CollisionShapes\TriangleMesh.cpp">
+ </File>
+ <File
+ RelativePath=".\CollisionShapes\TriangleMesh.h">
+ </File>
+ <File
+ RelativePath=".\CollisionShapes\TriangleMeshShape.cpp">
+ </File>
+ <File
+ RelativePath=".\CollisionShapes\TriangleMeshShape.h">
+ </File>
+ <File
+ RelativePath=".\CollisionShapes\TriangleShape.h">
+ </File>
+ </Filter>
+ <Filter
+ Name="BroadphaseCollision"
+ Filter="">
+ <File
+ RelativePath=".\BroadphaseCollision\BroadPhaseInterface.h">
+ </File>
+ <File
+ RelativePath=".\BroadphaseCollision\BroadphaseProxy.cpp">
+ </File>
+ <File
+ RelativePath=".\BroadphaseCollision\BroadphaseProxy.h">
+ </File>
+ <File
+ RelativePath=".\BroadphaseCollision\CollisionAlgorithm.cpp">
+ </File>
+ <File
+ RelativePath=".\BroadphaseCollision\CollisionAlgorithm.h">
+ </File>
+ <File
+ RelativePath=".\BroadphaseCollision\CollisionDispatcher.cpp">
+ </File>
+ <File
+ RelativePath=".\BroadphaseCollision\CollisionDispatcher.h">
+ </File>
+ <File
+ RelativePath=".\BroadphaseCollision\SimpleBroadphase.cpp">
+ </File>
+ <File
+ RelativePath=".\BroadphaseCollision\SimpleBroadphase.h">
+ </File>
+ </Filter>
+ <Filter
+ Name="LinearAlgebra"
+ Filter="">
+ <File
+ RelativePath="..\LinearMath\AabbUtil2.h">
+ </File>
+ <File
+ RelativePath="..\LinearMath\GEN_List.h">
+ </File>
+ <File
+ RelativePath="..\LinearMath\GEN_MinMax.h">
+ </File>
+ <File
+ RelativePath="..\LinearMath\GEN_random.h">
+ </File>
+ <File
+ RelativePath="..\LinearMath\SimdMatrix3x3.h">
+ </File>
+ <File
+ RelativePath="..\LinearMath\SimdMinMax.h">
+ </File>
+ <File
+ RelativePath="..\LinearMath\SimdPoint3.h">
+ </File>
+ <File
+ RelativePath="..\LinearMath\SimdQuadword.h">
+ </File>
+ <File
+ RelativePath="..\LinearMath\SimdQuaternion.h">
+ </File>
+ <File
+ RelativePath="..\LinearMath\SimdScalar.h">
+ </File>
+ <File
+ RelativePath="..\LinearMath\SimdTransform.h">
+ </File>
+ <File
+ RelativePath="..\LinearMath\SimdTransformUtil.h">
+ </File>
+ <File
+ RelativePath="..\LinearMath\SimdVector3.h">
+ </File>
+ </Filter>
+ <File
+ RelativePath=".\NarrowPhaseCollision\ConvexCast.cpp">
+ </File>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/extern/bullet/Bullet/Bullet3_vc8.sln b/extern/bullet/Bullet/Bullet3_vc8.sln
new file mode 100644
index 00000000000..d95ceb0fbf3
--- /dev/null
+++ b/extern/bullet/Bullet/Bullet3_vc8.sln
@@ -0,0 +1,20 @@
+
+Microsoft Visual Studio Solution File, Format Version 9.00
+# Visual Studio 2005
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Bullet3ContinuousCollision", "Bullet3_vc8.vcproj", "{FFD3C64A-30E2-4BC7-BC8F-51818C320400}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Win32 = Debug|Win32
+ Release|Win32 = Release|Win32
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {FFD3C64A-30E2-4BC7-BC8F-51818C320400}.Debug|Win32.ActiveCfg = Debug|Win32
+ {FFD3C64A-30E2-4BC7-BC8F-51818C320400}.Debug|Win32.Build.0 = Debug|Win32
+ {FFD3C64A-30E2-4BC7-BC8F-51818C320400}.Release|Win32.ActiveCfg = Release|Win32
+ {FFD3C64A-30E2-4BC7-BC8F-51818C320400}.Release|Win32.Build.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/extern/bullet/Bullet/Bullet3_vc8.vcproj b/extern/bullet/Bullet/Bullet3_vc8.vcproj
new file mode 100644
index 00000000000..c2f3e70180f
--- /dev/null
+++ b/extern/bullet/Bullet/Bullet3_vc8.vcproj
@@ -0,0 +1,552 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="8.00"
+ Name="Bullet3ContinuousCollision"
+ ProjectGUID="{FFD3C64A-30E2-4BC7-BC8F-51818C320400}"
+ SignManifests="true"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory=".\Debug"
+ IntermediateDirectory=".\Debug"
+ ConfigurationType="4"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=".;..\LinearMath"
+ PreprocessorDefinitions="_DEBUG;_LIB;WIN32;BUM_INLINED;USE_ALGEBRAIC"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="1"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderFile=""
+ AssemblerListingLocation=".\Debug/"
+ ObjectFile=".\Debug/"
+ ProgramDataBaseFileName=".\Debug/"
+ WarningLevel="3"
+ SuppressStartupBanner="true"
+ DebugInformationFormat="4"
+ CompileAs="0"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_DEBUG"
+ Culture="1033"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ OutputFile=".\Debug\Bullet.lib"
+ SuppressStartupBanner="true"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory=".\Release"
+ IntermediateDirectory=".\Release"
+ ConfigurationType="4"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ InlineFunctionExpansion="1"
+ AdditionalIncludeDirectories=".;..\LinearMath"
+ PreprocessorDefinitions="NDEBUG;_LIB;WIN32;BUM_INLINED;USE_ALGEBRAIC"
+ StringPooling="true"
+ RuntimeLibrary="0"
+ EnableFunctionLevelLinking="true"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderFile=""
+ AssemblerListingLocation=".\Release/"
+ ObjectFile=".\Release/"
+ ProgramDataBaseFileName=".\Release/"
+ WarningLevel="3"
+ SuppressStartupBanner="true"
+ DebugInformationFormat="3"
+ CompileAs="0"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG"
+ Culture="1033"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ OutputFile=".\Release\Bullet.lib"
+ SuppressStartupBanner="true"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="NarrowPhaseCollision"
+ >
+ <File
+ RelativePath=".\NarrowPhaseCollision\BU_AlgebraicPolynomialSolver.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\NarrowPhaseCollision\BU_AlgebraicPolynomialSolver.h"
+ >
+ </File>
+ <File
+ RelativePath=".\NarrowPhaseCollision\BU_Collidable.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\NarrowPhaseCollision\BU_Collidable.h"
+ >
+ </File>
+ <File
+ RelativePath=".\NarrowPhaseCollision\BU_CollisionPair.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\NarrowPhaseCollision\BU_CollisionPair.h"
+ >
+ </File>
+ <File
+ RelativePath=".\NarrowPhaseCollision\BU_EdgeEdge.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\NarrowPhaseCollision\BU_EdgeEdge.h"
+ >
+ </File>
+ <File
+ RelativePath=".\NarrowPhaseCollision\BU_MotionStateInterface.h"
+ >
+ </File>
+ <File
+ RelativePath=".\NarrowPhaseCollision\BU_PolynomialSolverInterface.h"
+ >
+ </File>
+ <File
+ RelativePath=".\NarrowPhaseCollision\BU_Screwing.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\NarrowPhaseCollision\BU_Screwing.h"
+ >
+ </File>
+ <File
+ RelativePath=".\NarrowPhaseCollision\BU_StaticMotionState.h"
+ >
+ </File>
+ <File
+ RelativePath=".\NarrowPhaseCollision\BU_VertexPoly.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\NarrowPhaseCollision\BU_VertexPoly.h"
+ >
+ </File>
+ <File
+ RelativePath=".\NarrowPhaseCollision\CollisionMargin.h"
+ >
+ </File>
+ <File
+ RelativePath=".\NarrowPhaseCollision\ContinuousConvexCollision.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\NarrowPhaseCollision\ContinuousConvexCollision.h"
+ >
+ </File>
+ <File
+ RelativePath=".\NarrowPhaseCollision\ConvexCast.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\NarrowPhaseCollision\ConvexCast.h"
+ >
+ </File>
+ <File
+ RelativePath=".\NarrowPhaseCollision\ConvexPenetrationDepthSolver.h"
+ >
+ </File>
+ <File
+ RelativePath=".\NarrowPhaseCollision\DiscreteCollisionDetectorInterface.h"
+ >
+ </File>
+ <File
+ RelativePath=".\NarrowPhaseCollision\GjkConvexCast.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\NarrowPhaseCollision\GjkConvexCast.h"
+ >
+ </File>
+ <File
+ RelativePath=".\NarrowPhaseCollision\GjkPairDetector.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\NarrowPhaseCollision\GjkPairDetector.h"
+ >
+ </File>
+ <File
+ RelativePath=".\NarrowPhaseCollision\ManifoldPoint.h"
+ >
+ </File>
+ <File
+ RelativePath=".\NarrowPhaseCollision\ManifoldPointCollector.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\NarrowPhaseCollision\ManifoldPointCollector.h"
+ >
+ </File>
+ <File
+ RelativePath=".\NarrowPhaseCollision\MinkowskiPenetrationDepthSolver.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\NarrowPhaseCollision\MinkowskiPenetrationDepthSolver.h"
+ >
+ </File>
+ <File
+ RelativePath=".\NarrowPhaseCollision\PersistentManifold.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\NarrowPhaseCollision\PersistentManifold.h"
+ >
+ </File>
+ <File
+ RelativePath=".\NarrowPhaseCollision\PointCollector.h"
+ >
+ </File>
+ <File
+ RelativePath=".\NarrowPhaseCollision\RaycastCallback.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\NarrowPhaseCollision\RaycastCallback.h"
+ >
+ </File>
+ <File
+ RelativePath=".\NarrowPhaseCollision\SimplexSolverInterface.h"
+ >
+ </File>
+ <File
+ RelativePath=".\NarrowPhaseCollision\SubSimplexConvexCast.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\NarrowPhaseCollision\SubSimplexConvexCast.h"
+ >
+ </File>
+ <File
+ RelativePath=".\NarrowPhaseCollision\VoronoiSimplexSolver.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\NarrowPhaseCollision\VoronoiSimplexSolver.h"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="CollisionShapes"
+ >
+ <File
+ RelativePath=".\CollisionShapes\BoxShape.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\CollisionShapes\BoxShape.h"
+ >
+ </File>
+ <File
+ RelativePath=".\CollisionShapes\CollisionShape.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\CollisionShapes\CollisionShape.h"
+ >
+ </File>
+ <File
+ RelativePath=".\CollisionShapes\ConeShape.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\CollisionShapes\ConeShape.h"
+ >
+ </File>
+ <File
+ RelativePath=".\CollisionShapes\ConvexHullShape.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\CollisionShapes\ConvexHullShape.h"
+ >
+ </File>
+ <File
+ RelativePath=".\CollisionShapes\ConvexShape.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\CollisionShapes\ConvexShape.h"
+ >
+ </File>
+ <File
+ RelativePath=".\CollisionShapes\CylinderShape.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\CollisionShapes\CylinderShape.h"
+ >
+ </File>
+ <File
+ RelativePath=".\CollisionShapes\MinkowskiSumShape.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\CollisionShapes\MinkowskiSumShape.h"
+ >
+ </File>
+ <File
+ RelativePath=".\CollisionShapes\MultiSphereShape.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\CollisionShapes\MultiSphereShape.h"
+ >
+ </File>
+ <File
+ RelativePath=".\CollisionShapes\PolyhedralConvexShape.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\CollisionShapes\PolyhedralConvexShape.h"
+ >
+ </File>
+ <File
+ RelativePath=".\CollisionShapes\Simplex1to4Shape.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\CollisionShapes\Simplex1to4Shape.h"
+ >
+ </File>
+ <File
+ RelativePath=".\CollisionShapes\SphereShape.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\CollisionShapes\SphereShape.h"
+ >
+ </File>
+ <File
+ RelativePath=".\CollisionShapes\StridingMeshInterface.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\CollisionShapes\StridingMeshInterface.h"
+ >
+ </File>
+ <File
+ RelativePath=".\CollisionShapes\TriangleCallback.h"
+ >
+ </File>
+ <File
+ RelativePath=".\CollisionShapes\TriangleMeshShape.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\CollisionShapes\TriangleMeshShape.h"
+ >
+ </File>
+ <File
+ RelativePath=".\CollisionShapes\TriangleShape.h"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="BroadphaseCollision"
+ >
+ <File
+ RelativePath=".\BroadphaseCollision\BroadPhaseInterface.h"
+ >
+ </File>
+ <File
+ RelativePath=".\BroadphaseCollision\BroadphaseProxy.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\BroadphaseCollision\BroadphaseProxy.h"
+ >
+ </File>
+ <File
+ RelativePath=".\BroadphaseCollision\CollisionAlgorithm.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\BroadphaseCollision\CollisionAlgorithm.h"
+ >
+ </File>
+ <File
+ RelativePath=".\BroadphaseCollision\CollisionDispatcher.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\BroadphaseCollision\CollisionDispatcher.h"
+ >
+ </File>
+ <File
+ RelativePath=".\BroadphaseCollision\SimpleBroadphase.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\BroadphaseCollision\SimpleBroadphase.h"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="LinearAlgebra"
+ >
+ <File
+ RelativePath="..\LinearMath\AabbUtil2.h"
+ >
+ </File>
+ <File
+ RelativePath="..\LinearMath\GEN_List.h"
+ >
+ </File>
+ <File
+ RelativePath="..\LinearMath\GEN_MinMax.h"
+ >
+ </File>
+ <File
+ RelativePath="..\LinearMath\GEN_random.h"
+ >
+ </File>
+ <File
+ RelativePath="..\LinearMath\SimdMatrix3x3.h"
+ >
+ </File>
+ <File
+ RelativePath="..\LinearMath\SimdMinMax.h"
+ >
+ </File>
+ <File
+ RelativePath="..\LinearMath\SimdPoint3.h"
+ >
+ </File>
+ <File
+ RelativePath="..\LinearMath\SimdQuadword.h"
+ >
+ </File>
+ <File
+ RelativePath="..\LinearMath\SimdQuaternion.h"
+ >
+ </File>
+ <File
+ RelativePath="..\LinearMath\SimdScalar.h"
+ >
+ </File>
+ <File
+ RelativePath="..\LinearMath\SimdTransform.h"
+ >
+ </File>
+ <File
+ RelativePath="..\LinearMath\SimdTransformUtil.h"
+ >
+ </File>
+ <File
+ RelativePath="..\LinearMath\SimdVector3.h"
+ >
+ </File>
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/extern/bullet/Bullet/CollisionShapes/BoxShape.cpp b/extern/bullet/Bullet/CollisionShapes/BoxShape.cpp
new file mode 100644
index 00000000000..4edd8cf9a12
--- /dev/null
+++ b/extern/bullet/Bullet/CollisionShapes/BoxShape.cpp
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies.
+ * Erwin Coumans makes no representations about the suitability
+ * of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+ */
+
+#include "BoxShape.h"
+
+
+void BoxShape::GetAabb(const SimdTransform& t,SimdVector3& aabbMin,SimdVector3& aabbMax) const
+{
+ SimdVector3 halfExtents = GetHalfExtents();
+
+ SimdMatrix3x3 abs_b = t.getBasis().absolute();
+ SimdPoint3 center = t.getOrigin();
+ SimdVector3 extent = SimdVector3(abs_b[0].dot(halfExtents),
+ abs_b[1].dot(halfExtents),
+ abs_b[2].dot(halfExtents));
+ extent += SimdVector3(GetMargin(),GetMargin(),GetMargin());
+
+
+ //todo: this is a quick fix, we need to enlarge the aabb dependent on several criteria
+ //extent += SimdVector3(.2f,.2f,.2f);
+
+ aabbMin = center - extent;
+ aabbMax = center + extent;
+
+
+}
diff --git a/extern/bullet/Bullet/CollisionShapes/BoxShape.h b/extern/bullet/Bullet/CollisionShapes/BoxShape.h
new file mode 100644
index 00000000000..620ddd7e4f6
--- /dev/null
+++ b/extern/bullet/Bullet/CollisionShapes/BoxShape.h
@@ -0,0 +1,274 @@
+/*
+ * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies.
+ * Erwin Coumans makes no representations about the suitability
+ * of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+ */
+
+#ifndef OBB_BOX_MINKOWSKI_H
+#define OBB_BOX_MINKOWSKI_H
+
+#include "PolyhedralConvexShape.h"
+#include "NarrowPhaseCollision/CollisionMargin.h"
+#include "BroadphaseCollision/BroadphaseProxy.h"
+#include "SimdPoint3.h"
+#include "SimdMinMax.h"
+
+///BoxShape implements both a feature based (vertex/edge/plane) and implicit (getSupportingVertex) Box
+class BoxShape: public PolyhedralConvexShape
+{
+
+ SimdVector3 m_boxHalfExtents1;
+
+
+public:
+
+ virtual ~BoxShape()
+ {
+
+ }
+
+ SimdVector3 GetHalfExtents() const{ return m_boxHalfExtents1 * m_localScaling;}
+ //const SimdVector3& GetHalfExtents() const{ return m_boxHalfExtents1;}
+
+
+
+ virtual int GetShapeType() const { return BOX_SHAPE_PROXYTYPE;}
+
+ virtual SimdVector3 LocalGetSupportingVertex(const SimdVector3& vec) const
+ {
+
+ SimdVector3 halfExtents = GetHalfExtents();
+
+ SimdVector3 supVertex;
+ supVertex = SimdPoint3(vec.x() < SimdScalar(0.0f) ? -halfExtents.x() : halfExtents.x(),
+ vec.y() < SimdScalar(0.0f) ? -halfExtents.y() : halfExtents.y(),
+ vec.z() < SimdScalar(0.0f) ? -halfExtents.z() : halfExtents.z());
+
+
+ if ( GetMargin()!=0.f )
+ {
+ SimdVector3 vecnorm = vec;
+ if (vecnorm .length2() == 0.f)
+ {
+ vecnorm.setValue(-1.f,-1.f,-1.f);
+ }
+ vecnorm.normalize();
+ supVertex+= GetMargin() * vecnorm;
+ }
+ return supVertex;
+ }
+
+
+ virtual SimdVector3 LocalGetSupportingVertexWithoutMargin(const SimdVector3& vec)const
+ {
+ SimdVector3 halfExtents = GetHalfExtents();
+
+ return SimdVector3(vec.x() < SimdScalar(0.0f) ? -halfExtents.x() : halfExtents.x(),
+ vec.y() < SimdScalar(0.0f) ? -halfExtents.y() : halfExtents.y(),
+ vec.z() < SimdScalar(0.0f) ? -halfExtents.z() : halfExtents.z());
+ }
+
+
+ BoxShape( const SimdVector3& boxHalfExtents) : m_boxHalfExtents1(boxHalfExtents){};
+
+ virtual void GetAabb(const SimdTransform& t,SimdVector3& aabbMin,SimdVector3& aabbMax) const;
+
+
+
+ virtual void CalculateLocalInertia(SimdScalar mass,SimdVector3& inertia)
+ {
+ float margin = GetMargin();
+ SimdVector3 halfExtents = GetHalfExtents();
+
+ SimdScalar lx=2.f*(halfExtents.x()+margin);
+ SimdScalar ly=2.f*(halfExtents.y()+margin);
+ SimdScalar lz=2.f*(halfExtents.z()+margin);
+ const SimdScalar x2 = lx*lx;
+ const SimdScalar y2 = ly*ly;
+ const SimdScalar z2 = lz*lz;
+ const SimdScalar scaledmass = mass * 0.08333333f;
+
+ inertia = scaledmass * (SimdVector3(y2+z2,x2+z2,x2+y2));
+
+// inertia.x() = scaledmass * (y2+z2);
+// inertia.y() = scaledmass * (x2+z2);
+// inertia.z() = scaledmass * (x2+y2);
+ }
+
+
+ virtual void GetPlane(SimdVector3& planeNormal,SimdPoint3& planeSupport,int i ) const
+ {
+ //this plane might not be aligned...
+ SimdVector4 plane ;
+ GetPlaneEquation(plane,i);
+ planeNormal = SimdVector3(plane.getX(),plane.getY(),plane.getZ());
+ planeSupport = LocalGetSupportingVertex(-planeNormal);
+ }
+
+
+ virtual int GetNumPlanes() const
+ {
+ return 6;
+ }
+
+ virtual int GetNumVertices() const
+ {
+ return 8;
+ }
+
+ virtual int GetNumEdges() const
+ {
+ return 12;
+ }
+
+
+ virtual void GetVertex(int i,SimdVector3& vtx) const
+ {
+ SimdVector3 halfExtents = GetHalfExtents();
+
+ vtx = SimdVector3(
+ halfExtents.x() * (1-(i&1)) - halfExtents.x() * (i&1),
+ halfExtents.y() * (1-((i&2)>>1)) - halfExtents.y() * ((i&2)>>1),
+ halfExtents.z() * (1-((i&4)>>2)) - halfExtents.z() * ((i&4)>>2));
+ }
+
+
+ virtual void GetPlaneEquation(SimdVector4& plane,int i) const
+ {
+ SimdVector3 halfExtents = GetHalfExtents();
+
+ switch (i)
+ {
+ case 0:
+ plane.setValue(1.f,0.f,0.f);
+ plane[3] = -halfExtents.x();
+ break;
+ case 1:
+ plane.setValue(-1.f,0.f,0.f);
+ plane[3] = -halfExtents.x();
+ break;
+ case 2:
+ plane.setValue(0.f,1.f,0.f);
+ plane[3] = -halfExtents.y();
+ break;
+ case 3:
+ plane.setValue(0.f,-1.f,0.f);
+ plane[3] = -halfExtents.y();
+ break;
+ case 4:
+ plane.setValue(0.f,0.f,1.f);
+ plane[3] = -halfExtents.z();
+ break;
+ case 5:
+ plane.setValue(0.f,0.f,-1.f);
+ plane[3] = -halfExtents.z();
+ break;
+ default:
+ assert(0);
+ }
+ }
+
+
+ virtual void GetEdge(int i,SimdPoint3& pa,SimdPoint3& pb) const
+ //virtual void GetEdge(int i,Edge& edge) const
+ {
+ int edgeVert0 = 0;
+ int edgeVert1 = 0;
+
+ switch (i)
+ {
+ case 0:
+ edgeVert0 = 0;
+ edgeVert1 = 1;
+ break;
+ case 1:
+ edgeVert0 = 0;
+ edgeVert1 = 2;
+ break;
+ case 2:
+ edgeVert0 = 1;
+ edgeVert1 = 3;
+
+ break;
+ case 3:
+ edgeVert0 = 2;
+ edgeVert1 = 3;
+ break;
+ case 4:
+ edgeVert0 = 0;
+ edgeVert1 = 4;
+ break;
+ case 5:
+ edgeVert0 = 1;
+ edgeVert1 = 5;
+
+ break;
+ case 6:
+ edgeVert0 = 2;
+ edgeVert1 = 6;
+ break;
+ case 7:
+ edgeVert0 = 3;
+ edgeVert1 = 7;
+ break;
+ case 8:
+ edgeVert0 = 4;
+ edgeVert1 = 5;
+ break;
+ case 9:
+ edgeVert0 = 4;
+ edgeVert1 = 6;
+ break;
+ case 10:
+ edgeVert0 = 5;
+ edgeVert1 = 7;
+ break;
+ case 11:
+ edgeVert0 = 6;
+ edgeVert1 = 7;
+ break;
+ default:
+ ASSERT(0);
+
+ }
+
+ GetVertex(edgeVert0,pa );
+ GetVertex(edgeVert1,pb );
+ }
+
+
+
+
+
+ virtual bool IsInside(const SimdPoint3& pt,SimdScalar tolerance) const
+ {
+ SimdVector3 halfExtents = GetHalfExtents();
+
+ //SimdScalar minDist = 2*tolerance;
+
+ bool result = (pt.x() <= (halfExtents.x()+tolerance)) &&
+ (pt.x() >= (-halfExtents.x()-tolerance)) &&
+ (pt.y() <= (halfExtents.y()+tolerance)) &&
+ (pt.y() >= (-halfExtents.y()-tolerance)) &&
+ (pt.z() <= (halfExtents.z()+tolerance)) &&
+ (pt.z() >= (-halfExtents.z()-tolerance));
+
+ return result;
+ }
+
+
+ //debugging
+ virtual char* GetName()const
+ {
+ return "Box";
+ }
+
+
+};
+
+#endif //OBB_BOX_MINKOWSKI_H
diff --git a/extern/bullet/Bullet/CollisionShapes/CollisionShape.cpp b/extern/bullet/Bullet/CollisionShapes/CollisionShape.cpp
new file mode 100644
index 00000000000..4bd1619cbf3
--- /dev/null
+++ b/extern/bullet/Bullet/CollisionShapes/CollisionShape.cpp
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies.
+ * Erwin Coumans makes no representations about the suitability
+ * of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+*/
+#include "CollisionShapes/CollisionShape.h"
+
+void CollisionShape::GetBoundingSphere(SimdVector3& center,SimdScalar& radius) const
+{
+ SimdTransform tr;
+ tr.setIdentity();
+ SimdVector3 aabbMin,aabbMax;
+
+ GetAabb(tr,aabbMin,aabbMax);
+
+ radius = (aabbMax-aabbMin).length()*0.5f;
+ center = (aabbMin+aabbMax)*0.5f;
+}
+
+float CollisionShape::GetAngularMotionDisc() const
+{
+ SimdVector3 center;
+ float disc;
+ GetBoundingSphere(center,disc);
+ disc += (center).length();
+ return disc;
+}
+
+void CollisionShape::CalculateTemporalAabb(const SimdTransform& curTrans,const SimdVector3& linvel,const SimdVector3& angvel,SimdScalar timeStep, SimdVector3& temporalAabbMin,SimdVector3& temporalAabbMax)
+{
+ //start with static aabb
+ GetAabb(curTrans,temporalAabbMin,temporalAabbMax);
+
+ float temporalAabbMaxx = temporalAabbMax.getX();
+ float temporalAabbMaxy = temporalAabbMax.getY();
+ float temporalAabbMaxz = temporalAabbMax.getZ();
+ float temporalAabbMinx = temporalAabbMin.getX();
+ float temporalAabbMiny = temporalAabbMin.getY();
+ float temporalAabbMinz = temporalAabbMin.getZ();
+
+ // add linear motion
+ SimdVector3 linMotion = linvel*timeStep;
+ //todo: simd would have a vector max/min operation, instead of per-element access
+ if (linMotion.x() > 0.f)
+ temporalAabbMaxx += linMotion.x();
+ else
+ temporalAabbMinx += linMotion.x();
+ if (linMotion.y() > 0.f)
+ temporalAabbMaxy += linMotion.y();
+ else
+ temporalAabbMiny += linMotion.y();
+ if (linMotion.z() > 0.f)
+ temporalAabbMaxz += linMotion.z();
+ else
+ temporalAabbMinz += linMotion.z();
+
+ //add conservative angular motion
+ SimdScalar angularMotion = angvel.length() * GetAngularMotionDisc() * timeStep;
+ SimdVector3 angularMotion3d(angularMotion,angularMotion,angularMotion);
+ temporalAabbMin = SimdVector3(temporalAabbMinx,temporalAabbMiny,temporalAabbMinz);
+ temporalAabbMax = SimdVector3(temporalAabbMaxx,temporalAabbMaxy,temporalAabbMaxz);
+
+ temporalAabbMin -= angularMotion3d;
+ temporalAabbMax += angularMotion3d;
+}
diff --git a/extern/bullet/Bullet/CollisionShapes/CollisionShape.h b/extern/bullet/Bullet/CollisionShapes/CollisionShape.h
new file mode 100644
index 00000000000..6969075f38c
--- /dev/null
+++ b/extern/bullet/Bullet/CollisionShapes/CollisionShape.h
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies.
+ * Erwin Coumans makes no representations about the suitability
+ * of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+*/
+#ifndef COLLISION_SHAPE_H
+#define COLLISION_SHAPE_H
+
+#include "SimdTransform.h"
+#include "SimdVector3.h"
+#include <SimdMatrix3x3.h>
+#include "SimdPoint3.h"
+#include "BroadphaseCollision/BroadphaseProxy.h" //for the shape types
+
+///CollisionShape provides generic interface for collidable objects
+class CollisionShape
+{
+
+public:
+
+ CollisionShape()
+ :m_tempDebug(0)
+ {
+ }
+ virtual ~CollisionShape()
+ {
+ }
+
+ virtual void GetAabb(const SimdTransform& t,SimdVector3& aabbMin,SimdVector3& aabbMax) const =0;
+
+ virtual void GetBoundingSphere(SimdVector3& center,SimdScalar& radius) const;
+
+ virtual float GetAngularMotionDisc() const;
+
+ virtual int GetShapeType() const=0;
+
+ ///CalculateTemporalAabb calculates the enclosing aabb for the moving object over interval [0..timeStep)
+ ///result is conservative
+ void CalculateTemporalAabb(const SimdTransform& curTrans,const SimdVector3& linvel,const SimdVector3& angvel,SimdScalar timeStep, SimdVector3& temporalAabbMin,SimdVector3& temporalAabbMax);
+
+ bool IsPolyhedral() const
+ {
+ return (GetShapeType() < IMPLICIT_CONVEX_SHAPES_START_HERE);
+ }
+
+ bool IsConvex() const
+ {
+ return (GetShapeType() < CONCAVE_SHAPES_START_HERE);
+ }
+ bool IsConcave() const
+ {
+ return (GetShapeType() > CONCAVE_SHAPES_START_HERE);
+ }
+
+
+ virtual void setLocalScaling(const SimdVector3& scaling) =0;
+
+ virtual void CalculateLocalInertia(SimdScalar mass,SimdVector3& inertia) = 0;
+
+//debugging support
+ virtual char* GetName()const =0 ;
+ const char* GetExtraDebugInfo() const { return m_tempDebug;}
+ void SetExtraDebugInfo(const char* extraDebugInfo) { m_tempDebug = extraDebugInfo;}
+ const char * m_tempDebug;
+//endif debugging support
+
+
+};
+
+#endif //COLLISION_SHAPE_H
+
diff --git a/extern/bullet/Bullet/CollisionShapes/ConeShape.cpp b/extern/bullet/Bullet/CollisionShapes/ConeShape.cpp
new file mode 100644
index 00000000000..40e762125ac
--- /dev/null
+++ b/extern/bullet/Bullet/CollisionShapes/ConeShape.cpp
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies.
+ * Erwin Coumans makes no representations about the suitability
+ * of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+*/
+#include "ConeShape.h"
+#include "SimdPoint3.h"
+
+#ifdef WIN32
+static int coneindices[3] = {1,2,0};
+#else
+static int coneindices[3] = {2,1,0};
+#endif
+
+ConeShape::ConeShape (SimdScalar radius,SimdScalar height):
+m_radius (radius),
+m_height(height)
+{
+ SimdVector3 halfExtents;
+ m_sinAngle = (m_radius / sqrt(m_radius * m_radius + m_height * m_height));
+}
+
+
+SimdVector3 ConeShape::ConeLocalSupport(const SimdVector3& v) const
+{
+
+ float halfHeight = m_height * 0.5f;
+
+ if (v[coneindices[1]] > v.length() * m_sinAngle)
+ {
+ SimdVector3 tmp;
+
+ tmp[coneindices[0]] = 0.f;
+ tmp[coneindices[1]] = halfHeight;
+ tmp[coneindices[2]] = 0.f;
+ return tmp;
+ }
+ else {
+ SimdScalar s = sqrtf(v[coneindices[0]] * v[coneindices[0]] + v[coneindices[2]] * v[coneindices[2]]);
+ if (s > SIMD_EPSILON) {
+ SimdScalar d = m_radius / s;
+ SimdVector3 tmp;
+ tmp[coneindices[0]] = v[coneindices[0]] * d;
+ tmp[coneindices[1]] = -halfHeight;
+ tmp[coneindices[2]] = v[coneindices[2]] * d;
+ return tmp;
+ }
+ else {
+ SimdVector3 tmp;
+ tmp[coneindices[0]] = 0.f;
+ tmp[coneindices[1]] = -halfHeight;
+ tmp[coneindices[2]] = 0.f;
+ return tmp;
+ }
+ }
+
+}
+
+SimdVector3 ConeShape::LocalGetSupportingVertexWithoutMargin(const SimdVector3& vec) const
+{
+ return ConeLocalSupport(vec);
+}
+
+SimdVector3 ConeShape::LocalGetSupportingVertex(const SimdVector3& vec) const
+{
+ SimdVector3 supVertex = ConeLocalSupport(vec);
+ if ( GetMargin()!=0.f )
+ {
+ SimdVector3 vecnorm = vec;
+ if (vecnorm .length2() == 0.f)
+ {
+ vecnorm.setValue(-1.f,-1.f,-1.f);
+ }
+ vecnorm.normalize();
+ supVertex+= GetMargin() * vecnorm;
+ }
+ return supVertex;
+}
+
+
diff --git a/extern/bullet/Bullet/CollisionShapes/ConeShape.h b/extern/bullet/Bullet/CollisionShapes/ConeShape.h
new file mode 100644
index 00000000000..88117e1bec3
--- /dev/null
+++ b/extern/bullet/Bullet/CollisionShapes/ConeShape.h
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies.
+ * Erwin Coumans makes no representations about the suitability
+ * of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+*/
+#ifndef CONE_MINKOWSKI_H
+#define CONE_MINKOWSKI_H
+
+#include "ConvexShape.h"
+#include "BroadphaseCollision/BroadphaseProxy.h" // for the types
+
+/// implements cone shape interface
+class ConeShape : public ConvexShape
+
+{
+
+ float m_sinAngle;
+ float m_radius;
+ float m_height;
+
+ SimdVector3 ConeLocalSupport(const SimdVector3& v) const;
+
+
+public:
+ ConeShape (SimdScalar radius,SimdScalar height);
+
+ virtual SimdVector3 LocalGetSupportingVertex(const SimdVector3& vec) const;
+ virtual SimdVector3 LocalGetSupportingVertexWithoutMargin(const SimdVector3& vec) const;
+
+
+ virtual void CalculateLocalInertia(SimdScalar mass,SimdVector3& inertia)
+ {
+ SimdTransform identity;
+ identity.setIdentity();
+ SimdVector3 aabbMin,aabbMax;
+ GetAabb(identity,aabbMin,aabbMax);
+
+ SimdVector3 halfExtents = (aabbMax-aabbMin)*0.5f;
+
+ float margin = GetMargin();
+
+ SimdScalar lx=2.f*(halfExtents.x()+margin);
+ SimdScalar ly=2.f*(halfExtents.y()+margin);
+ SimdScalar lz=2.f*(halfExtents.z()+margin);
+ const SimdScalar x2 = lx*lx;
+ const SimdScalar y2 = ly*ly;
+ const SimdScalar z2 = lz*lz;
+ const SimdScalar scaledmass = mass * 0.08333333f;
+
+ inertia = scaledmass * (SimdVector3(y2+z2,x2+z2,x2+y2));
+
+// inertia.x() = scaledmass * (y2+z2);
+// inertia.y() = scaledmass * (x2+z2);
+// inertia.z() = scaledmass * (x2+y2);
+ }
+
+
+
+ virtual int GetShapeType() const { return CONE_SHAPE_PROXYTYPE; }
+
+ virtual char* GetName()const
+ {
+ return "Cone";
+ }
+};
+
+
+#endif //CONE_MINKOWSKI_H \ No newline at end of file
diff --git a/extern/bullet/Bullet/CollisionShapes/ConvexHullShape.cpp b/extern/bullet/Bullet/CollisionShapes/ConvexHullShape.cpp
new file mode 100644
index 00000000000..0206324fa04
--- /dev/null
+++ b/extern/bullet/Bullet/CollisionShapes/ConvexHullShape.cpp
@@ -0,0 +1,146 @@
+/*
+ * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies.
+ * Erwin Coumans makes no representations about the suitability
+ * of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+ */
+
+#include "ConvexHullShape.h"
+#include "NarrowPhaseCollision/CollisionMargin.h"
+
+#include "SimdQuaternion.h"
+
+
+ConvexHullShape ::ConvexHullShape (SimdPoint3* points,int numPoints)
+{
+ m_points.resize(numPoints);
+ for (int i=0;i<numPoints;i++)
+ m_points[i] = points[i];
+}
+
+SimdVector3 ConvexHullShape::LocalGetSupportingVertexWithoutMargin(const SimdVector3& vec0)const
+{
+ SimdVector3 supVec(0.f,0.f,0.f);
+ SimdScalar newDot,maxDot = -1e30f;
+
+ SimdVector3 vec = vec0;
+ SimdScalar lenSqr = vec.length2();
+ if (lenSqr < 0.0001f)
+ {
+ vec.setValue(1,0,0);
+ } else
+ {
+ float rlen = 1.f / sqrtf(lenSqr );
+ vec *= rlen;
+ }
+
+
+ for (int i=0;i<m_points.size();i++)
+ {
+ SimdPoint3 vtx = m_points[i] * m_localScaling;
+
+ newDot = vec.dot(vtx);
+ if (newDot > maxDot)
+ {
+ maxDot = newDot;
+ supVec = vtx;
+ }
+ }
+ return supVec;
+}
+
+
+SimdVector3 ConvexHullShape::LocalGetSupportingVertex(const SimdVector3& vec)const
+{
+ SimdVector3 supVertex = LocalGetSupportingVertexWithoutMargin(vec);
+
+ if ( GetMargin()!=0.f )
+ {
+ SimdVector3 vecnorm = vec;
+ if (vecnorm .length2() == 0.f)
+ {
+ vecnorm.setValue(-1.f,-1.f,-1.f);
+ }
+ vecnorm.normalize();
+ supVertex+= GetMargin() * vecnorm;
+ }
+ return supVertex;
+}
+
+
+
+
+
+void ConvexHullShape::CalculateLocalInertia(SimdScalar mass,SimdVector3& inertia)
+{
+ //not yet, return box inertia
+
+ float margin = GetMargin();
+
+ SimdTransform ident;
+ ident.setIdentity();
+ SimdVector3 aabbMin,aabbMax;
+ GetAabb(ident,aabbMin,aabbMax);
+ SimdVector3 halfExtents = (aabbMax-aabbMin)*0.5f;
+
+ SimdScalar lx=2.f*(halfExtents.x()+margin);
+ SimdScalar ly=2.f*(halfExtents.y()+margin);
+ SimdScalar lz=2.f*(halfExtents.z()+margin);
+ const SimdScalar x2 = lx*lx;
+ const SimdScalar y2 = ly*ly;
+ const SimdScalar z2 = lz*lz;
+ const SimdScalar scaledmass = mass * 0.08333333f;
+
+ inertia = scaledmass * (SimdVector3(y2+z2,x2+z2,x2+y2));
+
+}
+
+
+
+//currently just for debugging (drawing), perhaps future support for algebraic continuous collision detection
+//Please note that you can debug-draw ConvexHullShape with the Raytracer Demo
+int ConvexHullShape::GetNumVertices() const
+{
+ return m_points.size();
+}
+
+int ConvexHullShape::GetNumEdges() const
+{
+ return m_points.size()*m_points.size();
+}
+
+void ConvexHullShape::GetEdge(int i,SimdPoint3& pa,SimdPoint3& pb) const
+{
+
+ int index0 = i%m_points.size();
+ int index1 = i/m_points.size();
+ pa = m_points[index0];
+ pb = m_points[index1];
+}
+
+void ConvexHullShape::GetVertex(int i,SimdPoint3& vtx) const
+{
+ vtx = m_points[i];
+}
+
+int ConvexHullShape::GetNumPlanes() const
+{
+ return 0;
+}
+
+void ConvexHullShape::GetPlane(SimdVector3& planeNormal,SimdPoint3& planeSupport,int i ) const
+{
+ assert(0);
+}
+
+//not yet
+bool ConvexHullShape::IsInside(const SimdPoint3& pt,SimdScalar tolerance) const
+{
+ assert(0);
+ return false;
+}
+
diff --git a/extern/bullet/Bullet/CollisionShapes/ConvexHullShape.h b/extern/bullet/Bullet/CollisionShapes/ConvexHullShape.h
new file mode 100644
index 00000000000..5be0b61da6f
--- /dev/null
+++ b/extern/bullet/Bullet/CollisionShapes/ConvexHullShape.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies.
+ * Erwin Coumans makes no representations about the suitability
+ * of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+ */
+
+#ifndef CONVEX_HULL_SHAPE_H
+#define CONVEX_HULL_SHAPE_H
+
+#include "PolyhedralConvexShape.h"
+#include "BroadphaseCollision/BroadphaseProxy.h" // for the types
+
+#include <vector>
+
+///ConvexHullShape implements an implicit (getSupportingVertex) Convex Hull of a Point Cloud (vertices)
+///No connectivity is needed. LocalGetSupportingVertex iterates linearly though all vertices.
+///on modern hardware, due to cache coherency this isn't that bad. Complex algorithms tend to trash the cash.
+///(memory is much slower then the cpu)
+class ConvexHullShape : public PolyhedralConvexShape
+{
+ std::vector<SimdPoint3> m_points;
+
+public:
+ ConvexHullShape(SimdPoint3* points,int numPoints);
+
+ void AddPoint(const SimdPoint3& point)
+ {
+ m_points.push_back(point);
+ }
+ virtual SimdVector3 LocalGetSupportingVertex(const SimdVector3& vec)const;
+ virtual SimdVector3 LocalGetSupportingVertexWithoutMargin(const SimdVector3& vec)const;
+
+ virtual void CalculateLocalInertia(SimdScalar mass,SimdVector3& inertia);
+
+ virtual int GetShapeType()const { return CONVEX_HULL_SHAPE_PROXYTYPE; }
+
+ //debugging
+ virtual char* GetName()const {return "Convex";}
+
+
+ virtual int GetNumVertices() const;
+ virtual int GetNumEdges() const;
+ virtual void GetEdge(int i,SimdPoint3& pa,SimdPoint3& pb) const;
+ virtual void GetVertex(int i,SimdPoint3& vtx) const;
+ virtual int GetNumPlanes() const;
+ virtual void GetPlane(SimdVector3& planeNormal,SimdPoint3& planeSupport,int i ) const;
+ virtual bool IsInside(const SimdPoint3& pt,SimdScalar tolerance) const;
+
+
+
+};
+
+
+#endif //CONVEX_HULL_SHAPE_H \ No newline at end of file
diff --git a/extern/bullet/Bullet/CollisionShapes/ConvexShape.cpp b/extern/bullet/Bullet/CollisionShapes/ConvexShape.cpp
new file mode 100644
index 00000000000..f2afb338166
--- /dev/null
+++ b/extern/bullet/Bullet/CollisionShapes/ConvexShape.cpp
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies.
+ * Erwin Coumans makes no representations about the suitability
+ * of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+ */
+
+#include "ConvexShape.h"
+
+ConvexShape::~ConvexShape()
+{
+
+}
+
+ConvexShape::ConvexShape()
+:m_collisionMargin(CONVEX_DISTANCE_MARGIN),
+m_localScaling(1.f,1.f,1.f)
+{
+}
+
+
+void ConvexShape::setLocalScaling(const SimdVector3& scaling)
+{
+ m_localScaling = scaling;
+}
+
+
+
+void ConvexShape::GetAabbSlow(const SimdTransform& trans,SimdVector3&minAabb,SimdVector3&maxAabb) const
+{
+
+ SimdScalar margin = 0.05f;
+ for (int i=0;i<3;i++)
+ {
+ SimdVector3 vec(0.f,0.f,0.f);
+ vec[i] = 1.f;
+ SimdVector3 tmp = trans(LocalGetSupportingVertex(vec*trans.getBasis()));
+ maxAabb[i] = tmp[i]+margin;
+ vec[i] = -1.f;
+ tmp = trans(LocalGetSupportingVertex(vec*trans.getBasis()));
+ minAabb[i] = tmp[i]-margin;
+ }
+};
+
+SimdVector3 ConvexShape::LocalGetSupportingVertex(const SimdVector3& vec)const
+ {
+ SimdVector3 supVertex = LocalGetSupportingVertexWithoutMargin(vec);
+
+ if ( GetMargin()!=0.f )
+ {
+ SimdVector3 vecnorm = vec;
+ if (vecnorm .length2() == 0.f)
+ {
+ vecnorm.setValue(-1.f,-1.f,-1.f);
+ }
+ vecnorm.normalize();
+ supVertex+= GetMargin() * vecnorm;
+ }
+ return supVertex;
+
+ }
+
+
diff --git a/extern/bullet/Bullet/CollisionShapes/ConvexShape.h b/extern/bullet/Bullet/CollisionShapes/ConvexShape.h
new file mode 100644
index 00000000000..345358e47fc
--- /dev/null
+++ b/extern/bullet/Bullet/CollisionShapes/ConvexShape.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies.
+ * Erwin Coumans makes no representations about the suitability
+ * of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+ */
+
+#ifndef CONVEX_SHAPE_INTERFACE1
+#define CONVEX_SHAPE_INTERFACE1
+
+#include "CollisionShape.h"
+
+#include "SimdVector3.h"
+#include "SimdTransform.h"
+#include "SimdMatrix3x3.h"
+#include <vector>
+#include "NarrowPhaseCollision/CollisionMargin.h"
+
+//todo: get rid of this ConvexCastResult thing!
+struct ConvexCastResult;
+
+
+/// ConvexShape is an abstract shape interface.
+/// The explicit part provides plane-equations, the implicit part provides GetClosestPoint interface.
+/// used in combination with GJK or ConvexCast
+class ConvexShape : public CollisionShape
+{
+public:
+ ConvexShape();
+
+ virtual ~ConvexShape();
+
+ virtual SimdVector3 LocalGetSupportingVertex(const SimdVector3& vec)const;
+ virtual SimdVector3 LocalGetSupportingVertexWithoutMargin(const SimdVector3& vec) const= 0;
+
+ // testing for hullnode code
+
+ ///GetAabb's default implementation is brute force, expected derived classes to implement a fast dedicated version
+ void GetAabb(const SimdTransform& t,SimdVector3& aabbMin,SimdVector3& aabbMax) const
+ {
+ GetAabbSlow(t,aabbMin,aabbMax);
+ }
+
+
+
+ virtual void GetAabbSlow(const SimdTransform& t,SimdVector3& aabbMin,SimdVector3& aabbMax) const;
+
+
+ virtual void setLocalScaling(const SimdVector3& scaling);
+
+
+ virtual void SetMargin(float margin)
+ {
+ m_collisionMargin = margin;
+ }
+ virtual float GetMargin() const
+ {
+ return m_collisionMargin;
+ }
+private:
+ SimdScalar m_collisionMargin;
+ //local scaling. collisionMargin is not scaled !
+protected:
+ SimdVector3 m_localScaling;
+
+};
+
+
+
+#endif //CONVEX_SHAPE_INTERFACE1
diff --git a/extern/bullet/Bullet/CollisionShapes/CylinderShape.cpp b/extern/bullet/Bullet/CollisionShapes/CylinderShape.cpp
new file mode 100644
index 00000000000..4af83d55a68
--- /dev/null
+++ b/extern/bullet/Bullet/CollisionShapes/CylinderShape.cpp
@@ -0,0 +1,169 @@
+/*
+ * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies.
+ * Erwin Coumans makes no representations about the suitability
+ * of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+ */
+
+#include "CylinderShape.h"
+#include "SimdPoint3.h"
+
+CylinderShape::CylinderShape (const SimdVector3& halfExtents)
+:BoxShape(halfExtents)
+{
+
+}
+
+
+CylinderShapeX::CylinderShapeX (const SimdVector3& halfExtents)
+:CylinderShape(halfExtents)
+{
+}
+
+
+CylinderShapeZ::CylinderShapeZ (const SimdVector3& halfExtents)
+:CylinderShape(halfExtents)
+{
+}
+
+
+
+SimdVector3 CylinderLocalSupportX(const SimdVector3& halfExtents,const SimdVector3& v)
+{
+const int cylinderUpAxis = 0;
+const int XX = 1;
+const int YY = 0;
+const int ZZ = 2;
+
+ //mapping depends on how cylinder local orientation is
+ // extents of the cylinder is: X,Y is for radius, and Z for height
+
+
+ float radius = halfExtents[XX];
+ float halfHeight = halfExtents[cylinderUpAxis];
+
+
+ SimdVector3 tmp;
+ SimdScalar d ;
+
+ SimdScalar s = sqrtf(v[XX] * v[XX] + v[ZZ] * v[ZZ]);
+ if (s != SimdScalar(0.0))
+ {
+ d = radius / s;
+ tmp[XX] = v[XX] * d;
+ tmp[YY] = v[YY] < 0.0 ? -halfHeight : halfHeight;
+ tmp[ZZ] = v[ZZ] * d;
+ return tmp;
+ }
+ else
+ {
+ tmp[XX] = radius;
+ tmp[YY] = v[YY] < 0.0 ? -halfHeight : halfHeight;
+ tmp[ZZ] = SimdScalar(0.0);
+ return tmp;
+ }
+
+
+}
+
+
+
+
+
+
+SimdVector3 CylinderLocalSupportY(const SimdVector3& halfExtents,const SimdVector3& v)
+{
+
+const int cylinderUpAxis = 1;
+const int XX = 0;
+const int YY = 1;
+const int ZZ = 2;
+
+
+ float radius = halfExtents[XX];
+ float halfHeight = halfExtents[cylinderUpAxis];
+
+
+ SimdVector3 tmp;
+ SimdScalar d ;
+
+ SimdScalar s = sqrtf(v[XX] * v[XX] + v[ZZ] * v[ZZ]);
+ if (s != SimdScalar(0.0))
+ {
+ d = radius / s;
+ tmp[XX] = v[XX] * d;
+ tmp[YY] = v[YY] < 0.0 ? -halfHeight : halfHeight;
+ tmp[ZZ] = v[ZZ] * d;
+ return tmp;
+ }
+ else
+ {
+ tmp[XX] = radius;
+ tmp[YY] = v[YY] < 0.0 ? -halfHeight : halfHeight;
+ tmp[ZZ] = SimdScalar(0.0);
+ return tmp;
+ }
+
+}
+
+SimdVector3 CylinderLocalSupportZ(const SimdVector3& halfExtents,const SimdVector3& v)
+{
+const int cylinderUpAxis = 2;
+const int XX = 0;
+const int YY = 2;
+const int ZZ = 1;
+
+ //mapping depends on how cylinder local orientation is
+ // extents of the cylinder is: X,Y is for radius, and Z for height
+
+
+ float radius = halfExtents[XX];
+ float halfHeight = halfExtents[cylinderUpAxis];
+
+
+ SimdVector3 tmp;
+ SimdScalar d ;
+
+ SimdScalar s = sqrtf(v[XX] * v[XX] + v[ZZ] * v[ZZ]);
+ if (s != SimdScalar(0.0))
+ {
+ d = radius / s;
+ tmp[XX] = v[XX] * d;
+ tmp[YY] = v[YY] < 0.0 ? -halfHeight : halfHeight;
+ tmp[ZZ] = v[ZZ] * d;
+ return tmp;
+ }
+ else
+ {
+ tmp[XX] = radius;
+ tmp[YY] = v[YY] < 0.0 ? -halfHeight : halfHeight;
+ tmp[ZZ] = SimdScalar(0.0);
+ return tmp;
+ }
+
+
+}
+
+SimdVector3 CylinderShapeX::LocalGetSupportingVertexWithoutMargin(const SimdVector3& vec)const
+{
+ return CylinderLocalSupportX(GetHalfExtents(),vec);
+}
+SimdVector3 CylinderShapeZ::LocalGetSupportingVertexWithoutMargin(const SimdVector3& vec)const
+{
+ return CylinderLocalSupportZ(GetHalfExtents(),vec);
+}
+SimdVector3 CylinderShape::LocalGetSupportingVertexWithoutMargin(const SimdVector3& vec)const
+{
+ return CylinderLocalSupportY(GetHalfExtents(),vec);
+}
+
+
+
+
+
+
+
diff --git a/extern/bullet/Bullet/CollisionShapes/CylinderShape.h b/extern/bullet/Bullet/CollisionShapes/CylinderShape.h
new file mode 100644
index 00000000000..d60bacff962
--- /dev/null
+++ b/extern/bullet/Bullet/CollisionShapes/CylinderShape.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies.
+ * Erwin Coumans makes no representations about the suitability
+ * of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+ */
+
+#ifndef CYLINDER_MINKOWSKI_H
+#define CYLINDER_MINKOWSKI_H
+
+#include "BoxShape.h"
+#include "BroadphaseCollision/BroadphaseProxy.h" // for the types
+#include "SimdVector3.h"
+
+/// implements cylinder shape interface
+class CylinderShape : public BoxShape
+
+{
+
+public:
+ CylinderShape (const SimdVector3& halfExtents);
+
+
+ virtual SimdVector3 LocalGetSupportingVertexWithoutMargin(const SimdVector3& vec)const;
+
+
+
+
+ //use box inertia
+ // virtual void CalculateLocalInertia(SimdScalar mass,SimdVector3& inertia);
+
+ virtual int GetShapeType() const
+ {
+ return CYLINDER_SHAPE_PROXYTYPE;
+ }
+
+
+
+};
+
+class CylinderShapeX : public CylinderShape
+{
+public:
+ CylinderShapeX (const SimdVector3& halfExtents);
+
+ virtual SimdVector3 LocalGetSupportingVertexWithoutMargin(const SimdVector3& vec)const;
+};
+
+class CylinderShapeZ : public CylinderShape
+{
+public:
+ CylinderShapeZ (const SimdVector3& halfExtents);
+
+ virtual SimdVector3 LocalGetSupportingVertexWithoutMargin(const SimdVector3& vec)const;
+
+};
+
+
+#endif //CYLINDER_MINKOWSKI_H \ No newline at end of file
diff --git a/extern/bullet/Bullet/CollisionShapes/MinkowskiSumShape.cpp b/extern/bullet/Bullet/CollisionShapes/MinkowskiSumShape.cpp
new file mode 100644
index 00000000000..abb1bfd2449
--- /dev/null
+++ b/extern/bullet/Bullet/CollisionShapes/MinkowskiSumShape.cpp
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies.
+ * Erwin Coumans makes no representations about the suitability
+ * of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+*/
+#include "MinkowskiSumShape.h"
+
+
+MinkowskiSumShape::MinkowskiSumShape(ConvexShape* shapeA,ConvexShape* shapeB)
+:m_shapeA(shapeA),
+m_shapeB(shapeB)
+{
+ m_transA.setIdentity();
+ m_transB.setIdentity();
+}
+
+SimdVector3 MinkowskiSumShape::LocalGetSupportingVertexWithoutMargin(const SimdVector3& vec)const
+{
+ SimdVector3 supVertexA = m_transA(m_shapeA->LocalGetSupportingVertexWithoutMargin(vec*m_transA.getBasis()));
+ SimdVector3 supVertexB = m_transB(m_shapeB->LocalGetSupportingVertexWithoutMargin(vec*m_transB.getBasis()));
+ return supVertexA + supVertexB;
+}
+
+float MinkowskiSumShape::GetMargin() const
+{
+ return m_shapeA->GetMargin() + m_shapeB->GetMargin();
+}
+
+
+void MinkowskiSumShape::CalculateLocalInertia(SimdScalar mass,SimdVector3& inertia)
+{
+ assert(0);
+ inertia.setValue(0,0,0);
+}
diff --git a/extern/bullet/Bullet/CollisionShapes/MinkowskiSumShape.h b/extern/bullet/Bullet/CollisionShapes/MinkowskiSumShape.h
new file mode 100644
index 00000000000..a286b66252b
--- /dev/null
+++ b/extern/bullet/Bullet/CollisionShapes/MinkowskiSumShape.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies.
+ * Erwin Coumans makes no representations about the suitability
+ * of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+*/
+#ifndef MINKOWSKI_SUM_SHAPE_H
+#define MINKOWSKI_SUM_SHAPE_H
+
+#include "ConvexShape.h"
+#include "BroadphaseCollision/BroadphaseProxy.h" // for the types
+
+/// MinkowskiSumShape represents implicit (getSupportingVertex) based minkowski sum of two convex implicit shapes.
+class MinkowskiSumShape : public ConvexShape
+{
+
+ SimdTransform m_transA;
+ SimdTransform m_transB;
+ ConvexShape* m_shapeA;
+ ConvexShape* m_shapeB;
+
+public:
+
+ MinkowskiSumShape(ConvexShape* shapeA,ConvexShape* shapeB);
+
+ virtual SimdVector3 LocalGetSupportingVertexWithoutMargin(const SimdVector3& vec)const;
+
+ virtual void CalculateLocalInertia(SimdScalar mass,SimdVector3& inertia);
+
+ void SetTransformA(const SimdTransform& transA) { m_transA = transA;}
+ void SetTransformB(const SimdTransform& transB) { m_transB = transB;}
+
+ const SimdTransform& GetTransformA()const { return m_transA;}
+ const SimdTransform& GetTransformB()const { return m_transB;}
+
+
+ virtual int GetShapeType() const { return MINKOWSKI_SUM_SHAPE_PROXYTYPE; }
+
+ virtual float GetMargin() const;
+
+ const ConvexShape* GetShapeA() const { return m_shapeA;}
+ const ConvexShape* GetShapeB() const { return m_shapeB;}
+
+ virtual char* GetName()const
+ {
+ return "MinkowskiSum";
+ }
+};
+
+#endif //MINKOWSKI_SUM_SHAPE_H
diff --git a/extern/bullet/Bullet/CollisionShapes/MultiSphereShape.cpp b/extern/bullet/Bullet/CollisionShapes/MultiSphereShape.cpp
new file mode 100644
index 00000000000..d2e7fcc273e
--- /dev/null
+++ b/extern/bullet/Bullet/CollisionShapes/MultiSphereShape.cpp
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies.
+ * Erwin Coumans makes no representations about the suitability
+ * of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+*/
+#include "MultiSphereShape.h"
+#include "NarrowPhaseCollision/CollisionMargin.h"
+#include "SimdQuaternion.h"
+
+MultiSphereShape::MultiSphereShape (const SimdVector3& inertiaHalfExtents,const SimdVector3* positions,const SimdScalar* radi,int numSpheres)
+:m_inertiaHalfExtents(inertiaHalfExtents)
+{
+ m_minRadius = 1e30f;
+
+ m_numSpheres = numSpheres;
+ for (int i=0;i<m_numSpheres;i++)
+ {
+ m_localPositions[i] = positions[i];
+ m_radi[i] = radi[i];
+ if (radi[i] < m_minRadius)
+ m_minRadius = radi[i];
+ }
+ SetMargin(m_minRadius);
+
+}
+
+
+
+
+ SimdVector3 MultiSphereShape::LocalGetSupportingVertexWithoutMargin(const SimdVector3& vec0)const
+{
+ int i;
+ SimdVector3 supVec(0,0,0);
+
+ SimdScalar maxDot(-1e30f);
+
+
+ SimdVector3 vec = vec0;
+ SimdScalar lenSqr = vec.length2();
+ if (lenSqr < 0.0001f)
+ {
+ vec.setValue(1,0,0);
+ } else
+ {
+ float rlen = 1.f / sqrtf(lenSqr );
+ vec *= rlen;
+ }
+
+ SimdVector3 vtx;
+ SimdScalar newDot;
+
+ const SimdVector3* pos = &m_localPositions[0];
+ const SimdScalar* rad = &m_radi[0];
+
+ for (i=0;i<m_numSpheres;i++)
+ {
+ vtx = (*pos) +vec*((*rad)-m_minRadius);
+ pos++;
+ rad++;
+ newDot = vec.dot(vtx);
+ if (newDot > maxDot)
+ {
+ maxDot = newDot;
+ supVec = vtx;
+ }
+ }
+
+ return supVec;
+
+}
+
+
+
+
+
+
+
+
+
+
+void MultiSphereShape::CalculateLocalInertia(SimdScalar mass,SimdVector3& inertia)
+{
+ //as an approximation, take the inertia of the box that bounds the spheres
+
+ SimdTransform ident;
+ ident.setIdentity();
+// SimdVector3 aabbMin,aabbMax;
+
+// GetAabb(ident,aabbMin,aabbMax);
+
+ SimdVector3 halfExtents = m_inertiaHalfExtents;//(aabbMax - aabbMin)* 0.5f;
+
+ float margin = CONVEX_DISTANCE_MARGIN;
+
+ SimdScalar lx=2.f*(halfExtents[0]+margin);
+ SimdScalar ly=2.f*(halfExtents[1]+margin);
+ SimdScalar lz=2.f*(halfExtents[2]+margin);
+ const SimdScalar x2 = lx*lx;
+ const SimdScalar y2 = ly*ly;
+ const SimdScalar z2 = lz*lz;
+ const SimdScalar scaledmass = mass * 0.08333333f;
+
+ inertia[0] = scaledmass * (y2+z2);
+ inertia[1] = scaledmass * (x2+z2);
+ inertia[2] = scaledmass * (x2+y2);
+
+}
+
+
+
diff --git a/extern/bullet/Bullet/CollisionShapes/MultiSphereShape.h b/extern/bullet/Bullet/CollisionShapes/MultiSphereShape.h
new file mode 100644
index 00000000000..fd23be65e84
--- /dev/null
+++ b/extern/bullet/Bullet/CollisionShapes/MultiSphereShape.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies.
+ * Erwin Coumans makes no representations about the suitability
+ * of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+*/
+#ifndef MULTI_SPHERE_MINKOWSKI_H
+#define MULTI_SPHERE_MINKOWSKI_H
+
+#include "ConvexShape.h"
+#include "BroadphaseCollision/BroadphaseProxy.h" // for the types
+
+#define MAX_NUM_SPHERES 5
+
+///MultiSphereShape represents implicit convex hull of a collection of spheres (using getSupportingVertex)
+class MultiSphereShape : public ConvexShape
+
+{
+
+ SimdVector3 m_localPositions[MAX_NUM_SPHERES];
+ SimdScalar m_radi[MAX_NUM_SPHERES];
+ SimdVector3 m_inertiaHalfExtents;
+
+ int m_numSpheres;
+ float m_minRadius;
+
+
+
+
+
+public:
+ MultiSphereShape (const SimdVector3& inertiaHalfExtents,const SimdVector3* positions,const SimdScalar* radi,int numSpheres);
+
+ ///CollisionShape Interface
+ virtual void CalculateLocalInertia(SimdScalar mass,SimdVector3& inertia);
+
+ /// ConvexShape Interface
+ virtual SimdVector3 LocalGetSupportingVertexWithoutMargin(const SimdVector3& vec)const;
+
+
+ virtual int GetShapeType() const { return MULTI_SPHERE_SHAPE_PROXYTYPE; }
+
+ virtual char* GetName()const
+ {
+ return "MultiSphere";
+ }
+
+};
+
+
+#endif //MULTI_SPHERE_MINKOWSKI_H
diff --git a/extern/bullet/Bullet/CollisionShapes/PolyhedralConvexShape.cpp b/extern/bullet/Bullet/CollisionShapes/PolyhedralConvexShape.cpp
new file mode 100644
index 00000000000..84b164dd5c6
--- /dev/null
+++ b/extern/bullet/Bullet/CollisionShapes/PolyhedralConvexShape.cpp
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies.
+ * Erwin Coumans makes no representations about the suitability
+ * of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+*/
+#include <CollisionShapes/PolyhedralConvexShape.h>
+
+PolyhedralConvexShape::PolyhedralConvexShape()
+
+{
+}
+
+SimdVector3 PolyhedralConvexShape::LocalGetSupportingVertexWithoutMargin(const SimdVector3& vec0)const
+{
+ int i;
+ SimdVector3 supVec(0,0,0);
+
+ SimdScalar maxDot(-1e30f);
+
+ SimdVector3 vec = vec0;
+ SimdScalar lenSqr = vec.length2();
+ if (lenSqr < 0.0001f)
+ {
+ vec.setValue(1,0,0);
+ } else
+ {
+ float rlen = 1.f / sqrtf(lenSqr );
+ vec *= rlen;
+ }
+
+ SimdVector3 vtx;
+ SimdScalar newDot;
+
+ for (i=0;i<GetNumVertices();i++)
+ {
+ GetVertex(i,vtx);
+ newDot = vec.dot(vtx);
+ if (newDot > maxDot)
+ {
+ maxDot = newDot;
+ supVec = vtx;
+ }
+ }
+
+ return supVec;
+
+}
diff --git a/extern/bullet/Bullet/CollisionShapes/PolyhedralConvexShape.h b/extern/bullet/Bullet/CollisionShapes/PolyhedralConvexShape.h
new file mode 100644
index 00000000000..faab0f39523
--- /dev/null
+++ b/extern/bullet/Bullet/CollisionShapes/PolyhedralConvexShape.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies.
+ * Erwin Coumans makes no representations about the suitability
+ * of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+*/
+#ifndef BU_SHAPE
+#define BU_SHAPE
+
+#include <SimdPoint3.h>
+#include <SimdMatrix3x3.h>
+#include <CollisionShapes/ConvexShape.h>
+
+
+///PolyhedralConvexShape is an interface class for feature based (vertex/edge/face) convex shapes.
+class PolyhedralConvexShape : public ConvexShape
+{
+
+public:
+
+ PolyhedralConvexShape();
+
+ //brute force implementations
+ virtual SimdVector3 LocalGetSupportingVertexWithoutMargin(const SimdVector3& vec)const;
+
+
+ virtual int GetNumVertices() const = 0 ;
+ virtual int GetNumEdges() const = 0;
+ virtual void GetEdge(int i,SimdPoint3& pa,SimdPoint3& pb) const = 0;
+ virtual void GetVertex(int i,SimdPoint3& vtx) const = 0;
+ virtual int GetNumPlanes() const = 0;
+ virtual void GetPlane(SimdVector3& planeNormal,SimdPoint3& planeSupport,int i ) const = 0;
+// virtual int GetIndex(int i) const = 0 ;
+
+ virtual bool IsInside(const SimdPoint3& pt,SimdScalar tolerance) const = 0;
+
+};
+
+#endif //BU_SHAPE
diff --git a/extern/bullet/Bullet/CollisionShapes/Simplex1to4Shape.cpp b/extern/bullet/Bullet/CollisionShapes/Simplex1to4Shape.cpp
new file mode 100644
index 00000000000..8a3833c20b1
--- /dev/null
+++ b/extern/bullet/Bullet/CollisionShapes/Simplex1to4Shape.cpp
@@ -0,0 +1,188 @@
+/*
+ * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies.
+ * Erwin Coumans makes no representations about the suitability
+ * of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+*/
+#include "Simplex1to4Shape.h"
+#include "SimdMatrix3x3.h"
+
+BU_Simplex1to4::BU_Simplex1to4()
+:m_numVertices(0)
+{
+}
+
+BU_Simplex1to4::BU_Simplex1to4(const SimdPoint3& pt0)
+:m_numVertices(0)
+{
+ AddVertex(pt0);
+}
+
+BU_Simplex1to4::BU_Simplex1to4(const SimdPoint3& pt0,const SimdPoint3& pt1)
+:m_numVertices(0)
+{
+ AddVertex(pt0);
+ AddVertex(pt1);
+}
+
+BU_Simplex1to4::BU_Simplex1to4(const SimdPoint3& pt0,const SimdPoint3& pt1,const SimdPoint3& pt2)
+:m_numVertices(0)
+{
+ AddVertex(pt0);
+ AddVertex(pt1);
+ AddVertex(pt2);
+}
+
+BU_Simplex1to4::BU_Simplex1to4(const SimdPoint3& pt0,const SimdPoint3& pt1,const SimdPoint3& pt2,const SimdPoint3& pt3)
+:m_numVertices(0)
+{
+ AddVertex(pt0);
+ AddVertex(pt1);
+ AddVertex(pt2);
+ AddVertex(pt3);
+}
+
+
+
+
+
+void BU_Simplex1to4::AddVertex(const SimdPoint3& pt)
+{
+ m_vertices[m_numVertices++] = pt;
+}
+
+
+int BU_Simplex1to4::GetNumVertices() const
+{
+ return m_numVertices;
+}
+
+int BU_Simplex1to4::GetNumEdges() const
+{
+ //euler formula, F-E+V = 2, so E = F+V-2
+
+ switch (m_numVertices)
+ {
+ case 0:
+ return 0;
+ case 1: return 0;
+ case 2: return 1;
+ case 3: return 3;
+ case 4: return 6;
+
+
+ }
+
+ return 0;
+}
+
+void BU_Simplex1to4::GetEdge(int i,SimdPoint3& pa,SimdPoint3& pb) const
+{
+
+ switch (m_numVertices)
+ {
+
+ case 2:
+ pa = m_vertices[0];
+ pb = m_vertices[1];
+ break;
+ case 3:
+ switch (i)
+ {
+ case 0:
+ pa = m_vertices[0];
+ pb = m_vertices[1];
+ break;
+ case 1:
+ pa = m_vertices[1];
+ pb = m_vertices[2];
+ break;
+ case 2:
+ pa = m_vertices[2];
+ pb = m_vertices[0];
+ break;
+
+ }
+ break;
+ case 4:
+ switch (i)
+ {
+ case 0:
+ pa = m_vertices[0];
+ pb = m_vertices[1];
+ break;
+ case 1:
+ pa = m_vertices[1];
+ pb = m_vertices[2];
+ break;
+ case 2:
+ pa = m_vertices[2];
+ pb = m_vertices[0];
+ break;
+ case 3:
+ pa = m_vertices[0];
+ pb = m_vertices[3];
+ break;
+ case 4:
+ pa = m_vertices[1];
+ pb = m_vertices[3];
+ break;
+ case 5:
+ pa = m_vertices[2];
+ pb = m_vertices[3];
+ break;
+ }
+
+ }
+
+
+
+
+}
+
+void BU_Simplex1to4::GetVertex(int i,SimdPoint3& vtx) const
+{
+ vtx = m_vertices[i];
+}
+
+int BU_Simplex1to4::GetNumPlanes() const
+{
+ switch (m_numVertices)
+ {
+ case 0:
+ return 0;
+ case 1:
+ return 0;
+ case 2:
+ return 0;
+ case 3:
+ return 2;
+ case 4:
+ return 4;
+ default:
+ {
+ }
+ }
+ return 0;
+}
+
+
+void BU_Simplex1to4::GetPlane(SimdVector3& planeNormal,SimdPoint3& planeSupport,int i) const
+{
+
+}
+
+int BU_Simplex1to4::GetIndex(int i) const
+{
+ return 0;
+}
+
+bool BU_Simplex1to4::IsInside(const SimdPoint3& pt,SimdScalar tolerance) const
+{
+ return false;
+}
+
diff --git a/extern/bullet/Bullet/CollisionShapes/Simplex1to4Shape.h b/extern/bullet/Bullet/CollisionShapes/Simplex1to4Shape.h
new file mode 100644
index 00000000000..8feb995a26c
--- /dev/null
+++ b/extern/bullet/Bullet/CollisionShapes/Simplex1to4Shape.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies.
+ * Erwin Coumans makes no representations about the suitability
+ * of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+*/
+#ifndef BU_SIMPLEX_1TO4_SHAPE
+#define BU_SIMPLEX_1TO4_SHAPE
+
+
+#include <CollisionShapes/PolyhedralConvexShape.h>
+#include "BroadphaseCollision/BroadphaseProxy.h"
+
+
+///BU_Simplex1to4 implements feature based and implicit simplex of up to 4 vertices (tetrahedron, triangle, line, vertex).
+class BU_Simplex1to4 : public PolyhedralConvexShape
+{
+protected:
+
+ int m_numVertices;
+ SimdPoint3 m_vertices[4];
+
+public:
+ BU_Simplex1to4();
+
+ BU_Simplex1to4(const SimdPoint3& pt0);
+ BU_Simplex1to4(const SimdPoint3& pt0,const SimdPoint3& pt1);
+ BU_Simplex1to4(const SimdPoint3& pt0,const SimdPoint3& pt1,const SimdPoint3& pt2);
+ BU_Simplex1to4(const SimdPoint3& pt0,const SimdPoint3& pt1,const SimdPoint3& pt2,const SimdPoint3& pt3);
+
+
+ void Reset()
+ {
+ m_numVertices = 0;
+ }
+
+ virtual void CalculateLocalInertia(SimdScalar mass,SimdVector3& inertia)
+ {
+ inertia = SimdVector3(1.f,1.f,1.f);
+ }
+
+ virtual int GetShapeType() const{ return TETRAHEDRAL_SHAPE_PROXYTYPE; }
+
+ void AddVertex(const SimdPoint3& pt);
+
+ //PolyhedralConvexShape interface
+
+ virtual int GetNumVertices() const;
+
+ virtual int GetNumEdges() const;
+
+ virtual void GetEdge(int i,SimdPoint3& pa,SimdPoint3& pb) const;
+
+ virtual void GetVertex(int i,SimdPoint3& vtx) const;
+
+ virtual int GetNumPlanes() const;
+
+ virtual void GetPlane(SimdVector3& planeNormal,SimdPoint3& planeSupport,int i) const;
+
+ virtual int GetIndex(int i) const;
+
+ virtual bool IsInside(const SimdPoint3& pt,SimdScalar tolerance) const;
+
+
+ ///GetName is for debugging
+ virtual char* GetName()const { return "BU_Simplex1to4";}
+
+};
+
+#endif //BU_SIMPLEX_1TO4_SHAPE
diff --git a/extern/bullet/Bullet/CollisionShapes/SphereShape.cpp b/extern/bullet/Bullet/CollisionShapes/SphereShape.cpp
new file mode 100644
index 00000000000..182b458ec7b
--- /dev/null
+++ b/extern/bullet/Bullet/CollisionShapes/SphereShape.cpp
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies.
+ * Erwin Coumans makes no representations about the suitability
+ * of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+ */
+
+#include "SphereShape.h"
+#include "NarrowPhaseCollision/CollisionMargin.h"
+
+#include "SimdQuaternion.h"
+
+
+SphereShape ::SphereShape (SimdScalar radius)
+: m_radius(radius)
+{
+ SetMargin( radius );
+}
+
+SimdVector3 SphereShape::LocalGetSupportingVertexWithoutMargin(const SimdVector3& vec)const
+{
+ return SimdVector3(0.f,0.f,0.f);
+}
+
+SimdVector3 SphereShape::LocalGetSupportingVertex(const SimdVector3& vec)const
+{
+ SimdScalar len = vec.length2();
+ if (fabsf(len) < 0.0001f)
+ {
+ return SimdVector3(GetMargin(),GetMargin(),GetMargin());
+ }
+ return vec * (GetMargin() / sqrtf(len));
+}
+
+
+void SphereShape::GetAabb(const SimdTransform& t,SimdVector3& aabbMin,SimdVector3& aabbMax) const
+{
+ const SimdVector3& center = t.getOrigin();
+ SimdScalar radius = m_radius + CONVEX_DISTANCE_MARGIN;
+ radius += 1;
+
+ const SimdVector3 extent(radius,radius,radius);
+
+ aabbMin = center - extent;
+ aabbMax = center + extent;
+}
+
+
+
+void SphereShape::CalculateLocalInertia(SimdScalar mass,SimdVector3& inertia)
+{
+ SimdScalar elem = 0.4f * mass * m_radius*m_radius;
+ inertia[0] = inertia[1] = inertia[2] = elem;
+} \ No newline at end of file
diff --git a/extern/bullet/Bullet/CollisionShapes/SphereShape.h b/extern/bullet/Bullet/CollisionShapes/SphereShape.h
new file mode 100644
index 00000000000..6765c59f18a
--- /dev/null
+++ b/extern/bullet/Bullet/CollisionShapes/SphereShape.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies.
+ * Erwin Coumans makes no representations about the suitability
+ * of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+ */
+
+#ifndef SPHERE_MINKOWSKI_H
+#define SPHERE_MINKOWSKI_H
+
+#include "ConvexShape.h"
+#include "BroadphaseCollision/BroadphaseProxy.h" // for the types
+
+///SphereShape implements an implicit (getSupportingVertex) Sphere
+class SphereShape : public ConvexShape
+
+{
+ SimdScalar m_radius;
+
+public:
+ SphereShape (SimdScalar radius);
+
+
+ virtual SimdVector3 LocalGetSupportingVertex(const SimdVector3& vec)const;
+ virtual SimdVector3 LocalGetSupportingVertexWithoutMargin(const SimdVector3& vec)const;
+
+
+ virtual void CalculateLocalInertia(SimdScalar mass,SimdVector3& inertia);
+
+ virtual void GetAabb(const SimdTransform& t,SimdVector3& aabbMin,SimdVector3& aabbMax) const;
+
+ virtual int GetShapeType() const { return SPHERE_SHAPE_PROXYTYPE; }
+
+ SimdScalar GetRadius() { return m_radius;}
+
+ //debugging
+ virtual char* GetName()const {return "SPHERE";}
+
+};
+
+
+#endif //SPHERE_MINKOWSKI_H
diff --git a/extern/bullet/Bullet/CollisionShapes/StridingMeshInterface.cpp b/extern/bullet/Bullet/CollisionShapes/StridingMeshInterface.cpp
new file mode 100644
index 00000000000..bb0e7e29984
--- /dev/null
+++ b/extern/bullet/Bullet/CollisionShapes/StridingMeshInterface.cpp
@@ -0,0 +1,16 @@
+/*
+ * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies.
+ * Erwin Coumans makes no representations about the suitability
+ * of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+*/
+#include "StridingMeshInterface.h"
+
+StridingMeshInterface::~StridingMeshInterface()
+{
+
+} \ No newline at end of file
diff --git a/extern/bullet/Bullet/CollisionShapes/StridingMeshInterface.h b/extern/bullet/Bullet/CollisionShapes/StridingMeshInterface.h
new file mode 100644
index 00000000000..3bdcd7edb38
--- /dev/null
+++ b/extern/bullet/Bullet/CollisionShapes/StridingMeshInterface.h
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies.
+ * Erwin Coumans makes no representations about the suitability
+ * of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+*/
+#ifndef STRIDING_MESHINTERFACE_H
+#define STRIDING_MESHINTERFACE_H
+
+#include "SimdVector3.h"
+
+/// PHY_ScalarType enumerates possible scalar types.
+/// See the StridingMeshInterface for its use
+typedef enum PHY_ScalarType {
+ PHY_FLOAT,
+ PHY_DOUBLE,
+ PHY_INTEGER,
+ PHY_SHORT,
+ PHY_FIXEDPOINT88
+} PHY_ScalarType;
+
+/// StridingMeshInterface is the interface class for high performance access to triangle meshes
+/// It allows for sharing graphics and collision meshes. Also it provides locking/unlocking of graphics meshes that are in gpu memory.
+class StridingMeshInterface
+{
+ protected:
+
+ SimdVector3 m_scaling;
+
+ public:
+ StridingMeshInterface() :m_scaling(1.f,1.f,1.f)
+ {
+
+ }
+
+ virtual ~StridingMeshInterface();
+ /// get read and write access to a subpart of a triangle mesh
+ /// this subpart has a continuous array of vertices and indices
+ /// in this way the mesh can be handled as chunks of memory with striding
+ /// very similar to OpenGL vertexarray support
+ /// make a call to unLockVertexBase when the read and write access is finished
+ virtual void getLockedVertexIndexBase(unsigned char **vertexbase, int& numverts,PHY_ScalarType& type, int& stride,unsigned char **indexbase,int & indexstride,int& numfaces,PHY_ScalarType& indicestype,int subpart=0)=0;
+
+
+ /// unLockVertexBase finishes the access to a subpart of the triangle mesh
+ /// make a call to unLockVertexBase when the read and write access (using getLockedVertexIndexBase) is finished
+ virtual void unLockVertexBase(int subpart)=0;
+
+ /// getNumSubParts returns the number of seperate subparts
+ /// each subpart has a continuous array of vertices and indices
+ virtual int getNumSubParts()=0;
+
+ virtual void preallocateVertices(int numverts)=0;
+ virtual void preallocateIndices(int numindices)=0;
+
+ const SimdVector3& getScaling() {
+ return m_scaling;
+ }
+ void setScaling(const SimdVector3& scaling)
+ {
+ m_scaling = scaling;
+ }
+};
+
+#endif //STRIDING_MESHINTERFACE_H
diff --git a/extern/bullet/Bullet/CollisionShapes/TriangleCallback.h b/extern/bullet/Bullet/CollisionShapes/TriangleCallback.h
new file mode 100644
index 00000000000..67d95565891
--- /dev/null
+++ b/extern/bullet/Bullet/CollisionShapes/TriangleCallback.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies.
+ * Erwin Coumans makes no representations about the suitability
+ * of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+*/
+#ifndef TRIANGLE_CALLBACK_H
+#define TRIANGLE_CALLBACK_H
+
+#include "SimdVector3.h"
+
+
+class TriangleCallback
+{
+public:
+
+ virtual ~TriangleCallback();
+ virtual void ProcessTriangle(SimdVector3* triangle) = 0;
+};
+
+#endif //TRIANGLE_CALLBACK_H
diff --git a/extern/bullet/Bullet/CollisionShapes/TriangleMesh.cpp b/extern/bullet/Bullet/CollisionShapes/TriangleMesh.cpp
new file mode 100644
index 00000000000..b528a9329ed
--- /dev/null
+++ b/extern/bullet/Bullet/CollisionShapes/TriangleMesh.cpp
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies.
+ * Erwin Coumans makes no representations about the suitability
+ * of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+*/
+#include "TriangleMesh.h"
+#include <assert.h>
+
+static int myindices[3] = {0,1,2};
+
+TriangleMesh::TriangleMesh ()
+{
+
+}
+
+void TriangleMesh::getLockedVertexIndexBase(unsigned char **vertexbase, int& numverts,PHY_ScalarType& type, int& stride,unsigned char **indexbase,int & indexstride,int& numfaces,PHY_ScalarType& indicestype,int subpart)
+{
+ numverts = 3;
+ *vertexbase = (unsigned char*)&m_triangles[subpart];
+ type = PHY_FLOAT;
+ stride = sizeof(SimdVector3);
+
+
+ numfaces = 1;
+ *indexbase = (unsigned char*) &myindices[0];
+ indicestype = PHY_INTEGER;
+ indexstride = sizeof(int);
+
+}
+
+int TriangleMesh::getNumSubParts()
+{
+ return m_triangles.size();
+}
diff --git a/extern/bullet/Bullet/CollisionShapes/TriangleMesh.h b/extern/bullet/Bullet/CollisionShapes/TriangleMesh.h
new file mode 100644
index 00000000000..6701ccbc328
--- /dev/null
+++ b/extern/bullet/Bullet/CollisionShapes/TriangleMesh.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies.
+ * Erwin Coumans makes no representations about the suitability
+ * of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+*/
+
+#ifndef TRIANGLE_MESH_H
+#define TRIANGLE_MESH_H
+
+#include "CollisionShapes/StridingMeshInterface.h"
+#include <vector>
+#include <SimdVector3.h>
+
+struct MyTriangle
+{
+ SimdVector3 m_vert0;
+ SimdVector3 m_vert1;
+ SimdVector3 m_vert2;
+};
+
+///TriangleMesh provides storage for a concave triangle mesh. It can be used as data for the TriangleMeshShape.
+class TriangleMesh : public StridingMeshInterface
+{
+ std::vector<MyTriangle> m_triangles;
+
+ public:
+ TriangleMesh ();
+
+ void AddTriangle(const SimdVector3& vertex0,const SimdVector3& vertex1,const SimdVector3& vertex2)
+ {
+ MyTriangle tri;
+ tri.m_vert0 = vertex0;
+ tri.m_vert1 = vertex1;
+ tri.m_vert2 = vertex2;
+ m_triangles.push_back(tri);
+ }
+
+
+//StridingMeshInterface interface implementation
+
+ virtual void getLockedVertexIndexBase(unsigned char **vertexbase, int& numverts,PHY_ScalarType& type, int& stride,unsigned char **indexbase,int & indexstride,int& numfaces,PHY_ScalarType& indicestype,int subpart=0);
+
+ /// unLockVertexBase finishes the access to a subpart of the triangle mesh
+ /// make a call to unLockVertexBase when the read and write access (using getLockedVertexIndexBase) is finished
+ virtual void unLockVertexBase(int subpart) {}
+
+ /// getNumSubParts returns the number of seperate subparts
+ /// each subpart has a continuous array of vertices and indices
+ virtual int getNumSubParts();
+
+ virtual void preallocateVertices(int numverts){}
+ virtual void preallocateIndices(int numindices){}
+
+
+
+};
+
+#endif //TRIANGLE_MESH_H \ No newline at end of file
diff --git a/extern/bullet/Bullet/CollisionShapes/TriangleMeshShape.cpp b/extern/bullet/Bullet/CollisionShapes/TriangleMeshShape.cpp
new file mode 100644
index 00000000000..996c740acce
--- /dev/null
+++ b/extern/bullet/Bullet/CollisionShapes/TriangleMeshShape.cpp
@@ -0,0 +1,182 @@
+/*
+ * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies.
+ * Erwin Coumans makes no representations about the suitability
+ * of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+*/
+#include "TriangleMeshShape.h"
+#include "SimdVector3.h"
+#include "SimdQuaternion.h"
+#include "StridingMeshInterface.h"
+#include "AabbUtil2.h"
+
+
+
+TriangleMeshShape::TriangleMeshShape(StridingMeshInterface* meshInterface)
+: m_meshInterface(meshInterface)
+{
+}
+
+TriangleMeshShape::~TriangleMeshShape()
+{
+
+}
+
+
+
+
+void TriangleMeshShape::GetAabb(const SimdTransform& trans,SimdVector3& aabbMin,SimdVector3& aabbMax) const
+{
+ SimdScalar margin = 0.5f;
+ for (int i=0;i<3;i++)
+ {
+ SimdVector3 vec(0.f,0.f,0.f);
+ vec[i] = 1.f;
+ SimdVector3 tmp = trans(LocalGetSupportingVertex(vec*trans.getBasis()));
+ aabbMax[i] = tmp[i]+margin;
+ vec[i] = -1.f;
+ tmp = trans(LocalGetSupportingVertex(vec*trans.getBasis()));
+ aabbMin[i] = tmp[i]-margin;
+ }
+}
+
+
+TriangleCallback::~TriangleCallback()
+{
+
+}
+
+class SupportVertexCallback : public TriangleCallback
+{
+
+ SimdVector3 m_supportVertexLocal;
+public:
+
+ SimdTransform m_worldTrans;
+ SimdScalar m_maxDot;
+ SimdVector3 m_supportVecLocal;
+
+ SupportVertexCallback(const SimdVector3& supportVecWorld,const SimdTransform& trans)
+ : m_supportVertexLocal(0.f,0.f,0.f), m_worldTrans(trans) ,m_maxDot(-1e30f)
+
+ {
+ m_supportVecLocal = supportVecWorld * m_worldTrans.getBasis();
+ }
+
+ virtual void ProcessTriangle( SimdVector3* triangle)
+ {
+ for (int i=0;i<3;i++)
+ {
+ SimdScalar dot = m_supportVecLocal.dot(triangle[i]);
+ if (dot > m_maxDot)
+ {
+ m_maxDot = dot;
+ m_supportVertexLocal = triangle[i];
+ }
+ }
+ }
+
+ SimdVector3 GetSupportVertexWorldSpace()
+ {
+ return m_worldTrans(m_supportVertexLocal);
+ }
+
+ SimdVector3 GetSupportVertexLocal()
+ {
+ return m_supportVertexLocal;
+ }
+
+};
+
+
+void TriangleMeshShape::setLocalScaling(const SimdVector3& scaling)
+{
+ m_meshInterface->setScaling(scaling);
+}
+
+void TriangleMeshShape::ProcessAllTriangles(TriangleCallback* callback,const SimdVector3& aabbMin,const SimdVector3& aabbMax) const
+{
+
+ SimdVector3 meshScaling = m_meshInterface->getScaling();
+ int numtotalphysicsverts = 0;
+ int part,graphicssubparts = m_meshInterface->getNumSubParts();
+ for (part=0;part<graphicssubparts ;part++)
+ {
+ unsigned char * vertexbase;
+ unsigned char * indexbase;
+ int indexstride;
+ PHY_ScalarType type;
+ PHY_ScalarType gfxindextype;
+ int stride,numverts,numtriangles;
+ m_meshInterface->getLockedVertexIndexBase(&vertexbase,numverts,type,stride,&indexbase,indexstride,numtriangles,gfxindextype,part);
+ numtotalphysicsverts+=numtriangles*3; //upper bound
+
+
+ int gfxindex;
+ SimdVector3 triangle[3];
+
+ for (gfxindex=0;gfxindex<numtriangles;gfxindex++)
+ {
+
+ int graphicsindex=0;
+
+ for (int j=2;j>=0;j--)
+ {
+ ASSERT(gfxindextype == PHY_INTEGER);
+ int* gfxbase = (int*)(indexbase+gfxindex*indexstride);
+ graphicsindex = gfxbase[j];
+ float* graphicsbase = (float*)(vertexbase+graphicsindex*stride);
+
+ triangle[j] = SimdVector3(
+ graphicsbase[0]*meshScaling.getX(),
+ graphicsbase[1]*meshScaling.getY(),
+ graphicsbase[2]*meshScaling.getZ());
+ }
+
+ if (TestTriangleAgainstAabb2(&triangle[0],aabbMin,aabbMax))
+ {
+ //check aabb in triangle-space, before doing this
+ callback->ProcessTriangle(triangle);
+ }
+
+ }
+
+ m_meshInterface->unLockVertexBase(part);
+ }
+
+
+}
+
+
+
+
+
+void TriangleMeshShape::CalculateLocalInertia(SimdScalar mass,SimdVector3& inertia)
+{
+ //moving concave objects not supported
+ assert(0);
+ inertia.setValue(0.f,0.f,0.f);
+}
+
+
+SimdVector3 TriangleMeshShape::LocalGetSupportingVertex(const SimdVector3& vec) const
+{
+ SimdVector3 supportVertex;
+
+ SimdTransform ident;
+ ident.setIdentity();
+
+ SupportVertexCallback supportCallback(vec,ident);
+
+ SimdVector3 aabbMax(1e30f,1e30f,1e30f);
+
+ ProcessAllTriangles(&supportCallback,-aabbMax,aabbMax);
+
+ supportVertex = supportCallback.GetSupportVertexLocal();
+
+ return supportVertex;
+}
diff --git a/extern/bullet/Bullet/CollisionShapes/TriangleMeshShape.h b/extern/bullet/Bullet/CollisionShapes/TriangleMeshShape.h
new file mode 100644
index 00000000000..ecd9cc530fd
--- /dev/null
+++ b/extern/bullet/Bullet/CollisionShapes/TriangleMeshShape.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies.
+ * Erwin Coumans makes no representations about the suitability
+ * of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+*/
+#ifndef TRIANGLE_MESH_SHAPE_H
+#define TRIANGLE_MESH_SHAPE_H
+
+#include "CollisionShapes/CollisionShape.h"
+#include "BroadphaseCollision/BroadphaseProxy.h" // for the types
+
+#include "StridingMeshInterface.h"
+#include "TriangleCallback.h"
+
+
+
+///Concave triangle mesh. Uses an interface to access the triangles to allow for sharing graphics/physics triangles.
+class TriangleMeshShape : public CollisionShape
+{
+
+ StridingMeshInterface* m_meshInterface;
+
+public:
+ TriangleMeshShape(StridingMeshInterface* meshInterface);
+
+ virtual ~TriangleMeshShape();
+
+
+
+ virtual SimdVector3 LocalGetSupportingVertex(const SimdVector3& vec) const;
+
+ virtual SimdVector3 LocalGetSupportingVertexWithoutMargin(const SimdVector3& vec)const
+ {
+ assert(0);
+ return LocalGetSupportingVertex(vec);
+ }
+
+ virtual int GetShapeType() const
+ {
+ return TRIANGLE_MESH_SHAPE_PROXYTYPE;
+ }
+
+ virtual void GetAabb(const SimdTransform& t,SimdVector3& aabbMin,SimdVector3& aabbMax) const;
+
+ void ProcessAllTriangles(TriangleCallback* callback,const SimdVector3& aabbMin,const SimdVector3& aabbMax) const;
+
+ virtual void CalculateLocalInertia(SimdScalar mass,SimdVector3& inertia);
+
+ virtual void setLocalScaling(const SimdVector3& scaling);
+
+
+ //debugging
+ virtual char* GetName()const {return "TRIANGLEMESH";}
+
+
+};
+
+#endif //TRIANGLE_MESH_SHAPE_H
diff --git a/extern/bullet/Bullet/CollisionShapes/TriangleShape.h b/extern/bullet/Bullet/CollisionShapes/TriangleShape.h
new file mode 100644
index 00000000000..58f83a82e8c
--- /dev/null
+++ b/extern/bullet/Bullet/CollisionShapes/TriangleShape.h
@@ -0,0 +1,146 @@
+/*
+ * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies.
+ * Erwin Coumans makes no representations about the suitability
+ * of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+*/
+#ifndef OBB_TRIANGLE_MINKOWSKI_H
+#define OBB_TRIANGLE_MINKOWSKI_H
+
+#include "ConvexShape.h"
+#include "CollisionShapes/BoxShape.h"
+
+class TriangleShape : public PolyhedralConvexShape
+{
+
+
+public:
+
+ SimdVector3 m_vertices1[3];
+
+
+ virtual int GetNumVertices() const
+ {
+ return 3;
+ }
+
+ const SimdVector3& GetVertexPtr(int index) const
+ {
+ return m_vertices1[index];
+ }
+ virtual void GetVertex(int index,SimdVector3& vert) const
+ {
+ vert = m_vertices1[index];
+ }
+ virtual int GetShapeType() const
+ {
+ return TRIANGLE_SHAPE_PROXYTYPE;
+ }
+
+ virtual int GetNumEdges() const
+ {
+ return 3;
+ }
+
+ virtual void GetEdge(int i,SimdPoint3& pa,SimdPoint3& pb) const
+ {
+ GetVertex(i,pa);
+ GetVertex((i+1)%3,pb);
+ }
+
+ virtual void GetAabb(const SimdTransform& t,SimdVector3& aabbMin,SimdVector3& aabbMax)const
+ {
+// ASSERT(0);
+ GetAabbSlow(t,aabbMin,aabbMax);
+ }
+
+ SimdVector3 LocalGetSupportingVertexWithoutMargin(const SimdVector3& dir)const
+ {
+ SimdVector3 dots(dir.dot(m_vertices1[0]), dir.dot(m_vertices1[1]), dir.dot(m_vertices1[2]));
+ return m_vertices1[dots.maxAxis()];
+
+ }
+
+
+ TriangleShape(const SimdVector3& p0,const SimdVector3& p1,const SimdVector3& p2)
+ {
+ m_vertices1[0] = p0;
+ m_vertices1[1] = p1;
+ m_vertices1[2] = p2;
+ }
+
+
+
+ virtual void GetPlane(SimdVector3& planeNormal,SimdPoint3& planeSupport,int i) const
+ {
+ GetPlaneEquation(i,planeNormal,planeSupport);
+ }
+
+ virtual int GetNumPlanes() const
+ {
+ return 1;
+ }
+
+ void CalcNormal(SimdVector3& normal) const
+ {
+ normal = (m_vertices1[1]-m_vertices1[0]).cross(m_vertices1[2]-m_vertices1[0]);
+ normal.normalize();
+ }
+
+ virtual void GetPlaneEquation(int i, SimdVector3& planeNormal,SimdPoint3& planeSupport) const
+ {
+ CalcNormal(planeNormal);
+ planeSupport = m_vertices1[0];
+ }
+
+ virtual void CalculateLocalInertia(SimdScalar mass,SimdVector3& inertia)
+ {
+ ASSERT(0);
+ inertia.setValue(0.f,0.f,0.f);
+ }
+
+ virtual bool IsInside(const SimdPoint3& pt,SimdScalar tolerance) const
+ {
+ SimdVector3 normal;
+ CalcNormal(normal);
+ //distance to plane
+ SimdScalar dist = pt.dot(normal);
+ SimdScalar planeconst = m_vertices1[0].dot(normal);
+ dist -= planeconst;
+ if (dist >= -tolerance && dist <= tolerance)
+ {
+ //inside check on edge-planes
+ int i;
+ for (i=0;i<3;i++)
+ {
+ SimdPoint3 pa,pb;
+ GetEdge(i,pa,pb);
+ SimdVector3 edge = pb-pa;
+ SimdVector3 edgeNormal = edge.cross(normal);
+ edgeNormal.normalize();
+ SimdScalar dist = pt.dot( edgeNormal);
+ SimdScalar edgeConst = pa.dot(edgeNormal);
+ dist -= edgeConst;
+ if (dist < -tolerance)
+ return false;
+ }
+
+ return true;
+ }
+
+ return false;
+ }
+ //debugging
+ virtual char* GetName()const
+ {
+ return "Triangle";
+ }
+
+
+};
+
+#endif //OBB_TRIANGLE_MINKOWSKI_H \ No newline at end of file
diff --git a/extern/bullet/Bullet/Doxyfile b/extern/bullet/Bullet/Doxyfile
new file mode 100644
index 00000000000..94d1d3c4b27
--- /dev/null
+++ b/extern/bullet/Bullet/Doxyfile
@@ -0,0 +1,746 @@
+# Doxyfile 1.2.4
+
+# This file describes the settings to be used by doxygen for a project
+#
+# All text after a hash (#) is considered a comment and will be ignored
+# The format is:
+# TAG = value [value, ...]
+# For lists items can also be appended using:
+# TAG += value [value, ...]
+# Values that contain spaces should be placed between quotes (" ")
+
+#---------------------------------------------------------------------------
+# General configuration options
+#---------------------------------------------------------------------------
+
+# The PROJECT_NAME tag is a single word (or a sequence of words surrounded
+# by quotes) that should identify the project.
+PROJECT_NAME = Continuous Collision Detection Library
+
+# The PROJECT_NUMBER tag can be used to enter a project or revision number.
+# This could be handy for archiving the generated documentation or
+# if some version control system is used.
+
+PROJECT_NUMBER =
+
+# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
+# base path where the generated documentation will be put.
+# If a relative path is entered, it will be relative to the location
+# where doxygen was started. If left blank the current directory will be used.
+
+OUTPUT_DIRECTORY =
+
+# The OUTPUT_LANGUAGE tag is used to specify the language in which all
+# documentation generated by doxygen is written. Doxygen will use this
+# information to generate all constant output in the proper language.
+# The default language is English, other supported languages are:
+# Dutch, French, Italian, Czech, Swedish, German, Finnish, Japanese,
+# Korean, Hungarian, Norwegian, Spanish, Romanian, Russian, Croatian,
+# Polish, Portuguese and Slovene.
+
+OUTPUT_LANGUAGE = English
+
+# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in
+# documentation are documented, even if no documentation was available.
+# Private class members and static file members will be hidden unless
+# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
+
+EXTRACT_ALL = YES
+
+# If the EXTRACT_PRIVATE tag is set to YES all private members of a class
+# will be included in the documentation.
+
+EXTRACT_PRIVATE = YES
+
+# If the EXTRACT_STATIC tag is set to YES all static members of a file
+# will be included in the documentation.
+
+EXTRACT_STATIC = YES
+
+# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all
+# undocumented members of documented classes, files or namespaces.
+# If set to NO (the default) these members will be included in the
+# various overviews, but no documentation section is generated.
+# This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_MEMBERS = NO
+
+# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all
+# undocumented classes that are normally visible in the class hierarchy.
+# If set to NO (the default) these class will be included in the various
+# overviews. This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_CLASSES = NO
+
+# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will
+# include brief member descriptions after the members that are listed in
+# the file and class documentation (similar to JavaDoc).
+# Set to NO to disable this.
+
+BRIEF_MEMBER_DESC = YES
+
+# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend
+# the brief description of a member or function before the detailed description.
+# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
+# brief descriptions will be completely suppressed.
+
+REPEAT_BRIEF = YES
+
+# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
+# Doxygen will generate a detailed section even if there is only a brief
+# description.
+
+ALWAYS_DETAILED_SEC = NO
+
+# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full
+# path before files name in the file list and in the header files. If set
+# to NO the shortest path that makes the file name unique will be used.
+
+FULL_PATH_NAMES = NO
+
+# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag
+# can be used to strip a user defined part of the path. Stripping is
+# only done if one of the specified strings matches the left-hand part of
+# the path. It is allowed to use relative paths in the argument list.
+
+STRIP_FROM_PATH =
+
+# The INTERNAL_DOCS tag determines if documentation
+# that is typed after a \internal command is included. If the tag is set
+# to NO (the default) then the documentation will be excluded.
+# Set it to YES to include the internal documentation.
+
+INTERNAL_DOCS = NO
+
+# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will
+# generate a class diagram (in Html and LaTeX) for classes with base or
+# super classes. Setting the tag to NO turns the diagrams off.
+
+CLASS_DIAGRAMS = YES
+
+# If the SOURCE_BROWSER tag is set to YES then a list of source files will
+# be generated. Documented entities will be cross-referenced with these sources.
+
+SOURCE_BROWSER = YES
+
+# Setting the INLINE_SOURCES tag to YES will include the body
+# of functions and classes directly in the documentation.
+
+INLINE_SOURCES = NO
+
+# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct
+# doxygen to hide any special comment blocks from generated source code
+# fragments. Normal C and C++ comments will always remain visible.
+
+STRIP_CODE_COMMENTS = YES
+
+# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate
+# file names in lower case letters. If set to YES upper case letters are also
+# allowed. This is useful if you have classes or files whose names only differ
+# in case and if your file system supports case sensitive file names. Windows
+# users are adviced to set this option to NO.
+
+CASE_SENSE_NAMES = YES
+
+# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen
+# will show members with their full class and namespace scopes in the
+# documentation. If set to YES the scope will be hidden.
+
+HIDE_SCOPE_NAMES = NO
+
+# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen
+# will generate a verbatim copy of the header file for each class for
+# which an include is specified. Set to NO to disable this.
+
+VERBATIM_HEADERS = YES
+
+# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen
+# will put list of the files that are included by a file in the documentation
+# of that file.
+
+SHOW_INCLUDE_FILES = YES
+
+# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen
+# will interpret the first line (until the first dot) of a JavaDoc-style
+# comment as the brief description. If set to NO, the JavaDoc
+# comments will behave just like the Qt-style comments (thus requiring an
+# explict @brief command for a brief description.
+
+JAVADOC_AUTOBRIEF = YES
+
+# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented
+# member inherits the documentation from any documented member that it
+# reimplements.
+
+INHERIT_DOCS = YES
+
+# If the INLINE_INFO tag is set to YES (the default) then a tag [inline]
+# is inserted in the documentation for inline members.
+
+INLINE_INFO = YES
+
+# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen
+# will sort the (detailed) documentation of file and class members
+# alphabetically by member name. If set to NO the members will appear in
+# declaration order.
+
+SORT_MEMBER_DOCS = YES
+
+# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
+# tag is set to YES, then doxygen will reuse the documentation of the first
+# member in the group (if any) for the other members of the group. By default
+# all members of a group must be documented explicitly.
+
+DISTRIBUTE_GROUP_DOC = NO
+
+# The TAB_SIZE tag can be used to set the number of spaces in a tab.
+# Doxygen uses this value to replace tabs by spaces in code fragments.
+
+TAB_SIZE = 8
+
+# The ENABLE_SECTIONS tag can be used to enable conditional
+# documentation sections, marked by \if sectionname ... \endif.
+
+ENABLED_SECTIONS =
+
+# The GENERATE_TODOLIST tag can be used to enable (YES) or
+# disable (NO) the todo list. This list is created by putting \todo
+# commands in the documentation.
+
+GENERATE_TODOLIST = YES
+
+# The GENERATE_TESTLIST tag can be used to enable (YES) or
+# disable (NO) the test list. This list is created by putting \test
+# commands in the documentation.
+
+GENERATE_TESTLIST = YES
+
+# This tag can be used to specify a number of aliases that acts
+# as commands in the documentation. An alias has the form "name=value".
+# For example adding "sideeffect=\par Side Effects:\n" will allow you to
+# put the command \sideeffect (or @sideeffect) in the documentation, which
+# will result in a user defined paragraph with heading "Side Effects:".
+# You can put \n's in the value part of an alias to insert newlines.
+
+ALIASES =
+
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+
+# The QUIET tag can be used to turn on/off the messages that are generated
+# by doxygen. Possible values are YES and NO. If left blank NO is used.
+
+QUIET = NO
+
+# The WARNINGS tag can be used to turn on/off the warning messages that are
+# generated by doxygen. Possible values are YES and NO. If left blank
+# NO is used.
+
+WARNINGS = YES
+
+# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings
+# for undocumented members. If EXTRACT_ALL is set to YES then this flag will
+# automatically be disabled.
+
+WARN_IF_UNDOCUMENTED = YES
+
+# The WARN_FORMAT tag determines the format of the warning messages that
+# doxygen can produce. The string should contain the $file, $line, and $text
+# tags, which will be replaced by the file and line number from which the
+# warning originated and the warning text.
+
+WARN_FORMAT = "$file:$line: $text"
+
+# The WARN_LOGFILE tag can be used to specify a file to which warning
+# and error messages should be written. If left blank the output is written
+# to stderr.
+
+WARN_LOGFILE =
+
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+
+# The INPUT tag can be used to specify the files and/or directories that contain
+# documented source files. You may enter file names like "myfile.cpp" or
+# directories like "/usr/src/myproject". Separate the files or directories
+# with spaces.
+
+INPUT = .
+
+
+# If the value of the INPUT tag contains directories, you can use the
+# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
+# and *.h) to filter out the source-files in the directories. If left
+# blank all files are included.
+
+FILE_PATTERNS = *.h *.cpp *.c
+
+# The RECURSIVE tag can be used to turn specify whether or not subdirectories
+# should be searched for input files as well. Possible values are YES and NO.
+# If left blank NO is used.
+
+RECURSIVE = YES
+
+# The EXCLUDE tag can be used to specify files and/or directories that should
+# excluded from the INPUT source files. This way you can easily exclude a
+# subdirectory from a directory tree whose root is specified with the INPUT tag.
+
+EXCLUDE =
+
+# If the value of the INPUT tag contains directories, you can use the
+# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
+# certain files from those directories.
+
+EXCLUDE_PATTERNS =
+
+# The EXAMPLE_PATH tag can be used to specify one or more files or
+# directories that contain example code fragments that are included (see
+# the \include command).
+
+EXAMPLE_PATH =
+
+# If the value of the EXAMPLE_PATH tag contains directories, you can use the
+# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
+# and *.h) to filter out the source-files in the directories. If left
+# blank all files are included.
+
+EXAMPLE_PATTERNS =
+
+# The IMAGE_PATH tag can be used to specify one or more files or
+# directories that contain image that are included in the documentation (see
+# the \image command).
+
+IMAGE_PATH =
+
+# The INPUT_FILTER tag can be used to specify a program that doxygen should
+# invoke to filter for each input file. Doxygen will invoke the filter program
+# by executing (via popen()) the command <filter> <input-file>, where <filter>
+# is the value of the INPUT_FILTER tag, and <input-file> is the name of an
+# input file. Doxygen will then use the output that the filter program writes
+# to standard output.
+
+INPUT_FILTER =
+
+# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
+# INPUT_FILTER) will be used to filter the input files when producing source
+# files to browse.
+
+FILTER_SOURCE_FILES = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+
+# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index
+# of all compounds will be generated. Enable this if the project
+# contains a lot of classes, structs, unions or interfaces.
+
+ALPHABETICAL_INDEX = NO
+
+# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then
+# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns
+# in which this list will be split (can be a number in the range [1..20])
+
+COLS_IN_ALPHA_INDEX = 5
+
+# In case all classes in a project start with a common prefix, all
+# classes will be put under the same header in the alphabetical index.
+# The IGNORE_PREFIX tag can be used to specify one or more prefixes that
+# should be ignored while generating the index headers.
+
+IGNORE_PREFIX =
+
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_HTML tag is set to YES (the default) Doxygen will
+# generate HTML output.
+
+GENERATE_HTML = YES
+
+# The HTML_OUTPUT tag is used to specify where the HTML docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `html' will be used as the default path.
+
+HTML_OUTPUT = html
+
+# The HTML_HEADER tag can be used to specify a personal HTML header for
+# each generated HTML page. If it is left blank doxygen will generate a
+# standard header.
+
+HTML_HEADER =
+
+# The HTML_FOOTER tag can be used to specify a personal HTML footer for
+# each generated HTML page. If it is left blank doxygen will generate a
+# standard footer.
+
+HTML_FOOTER =
+
+# The HTML_STYLESHEET tag can be used to specify a user defined cascading
+# style sheet that is used by each HTML page. It can be used to
+# fine-tune the look of the HTML output. If the tag is left blank doxygen
+# will generate a default style sheet
+
+HTML_STYLESHEET =
+
+# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes,
+# files or namespaces will be aligned in HTML using tables. If set to
+# NO a bullet list will be used.
+
+HTML_ALIGN_MEMBERS = YES
+
+# If the GENERATE_HTMLHELP tag is set to YES, additional index files
+# will be generated that can be used as input for tools like the
+# Microsoft HTML help workshop to generate a compressed HTML help file (.chm)
+# of the generated HTML documentation.
+
+GENERATE_HTMLHELP = NO
+
+# The DISABLE_INDEX tag can be used to turn on/off the condensed index at
+# top of each HTML page. The value NO (the default) enables the index and
+# the value YES disables it.
+
+DISABLE_INDEX = NO
+
+# This tag can be used to set the number of enum values (range [1..20])
+# that doxygen will group on one line in the generated HTML documentation.
+
+ENUM_VALUES_PER_LINE = 4
+
+# If the GENERATE_TREEVIEW tag is set to YES, a side pannel will be
+# generated containing a tree-like index structure (just like the one that
+# is generated for HTML Help). For this to work a browser that supports
+# JavaScript and frames is required (for instance Netscape 4.0+
+# or Internet explorer 4.0+).
+
+GENERATE_TREEVIEW = NO
+
+# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be
+# used to set the initial width (in pixels) of the frame in which the tree
+# is shown.
+
+TREEVIEW_WIDTH = 250
+
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will
+# generate Latex output.
+
+GENERATE_LATEX = NO
+
+# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `latex' will be used as the default path.
+
+LATEX_OUTPUT = latex
+
+# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact
+# LaTeX documents. This may be useful for small projects and may help to
+# save some trees in general.
+
+COMPACT_LATEX = NO
+
+# The PAPER_TYPE tag can be used to set the paper type that is used
+# by the printer. Possible values are: a4, a4wide, letter, legal and
+# executive. If left blank a4wide will be used.
+
+PAPER_TYPE = a4wide
+
+# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX
+# packages that should be included in the LaTeX output.
+
+EXTRA_PACKAGES =
+
+# The LATEX_HEADER tag can be used to specify a personal LaTeX header for
+# the generated latex document. The header should contain everything until
+# the first chapter. If it is left blank doxygen will generate a
+# standard header. Notice: only use this tag if you know what you are doing!
+
+LATEX_HEADER =
+
+# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated
+# is prepared for conversion to pdf (using ps2pdf). The pdf file will
+# contain links (just like the HTML output) instead of page references
+# This makes the output suitable for online browsing using a pdf viewer.
+
+PDF_HYPERLINKS = NO
+
+# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of
+# plain latex in the generated Makefile. Set this option to YES to get a
+# higher quality PDF documentation.
+
+USE_PDFLATEX = NO
+
+# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode.
+# command to the generated LaTeX files. This will instruct LaTeX to keep
+# running if errors occur, instead of asking the user for help.
+# This option is also used when generating formulas in HTML.
+
+LATEX_BATCHMODE = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output
+# The RTF output is optimised for Word 97 and may not look very pretty with
+# other RTF readers or editors.
+
+GENERATE_RTF = NO
+
+# The RTF_OUTPUT tag is used to specify where the RTF docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `rtf' will be used as the default path.
+
+RTF_OUTPUT = rtf
+
+# If the COMPACT_RTF tag is set to YES Doxygen generates more compact
+# RTF documents. This may be useful for small projects and may help to
+# save some trees in general.
+
+COMPACT_RTF = NO
+
+# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated
+# will contain hyperlink fields. The RTF file will
+# contain links (just like the HTML output) instead of page references.
+# This makes the output suitable for online browsing using a WORD or other.
+# programs which support those fields.
+# Note: wordpad (write) and others do not support links.
+
+RTF_HYPERLINKS = NO
+
+# Load stylesheet definitions from file. Syntax is similar to doxygen's
+# config file, i.e. a series of assigments. You only have to provide
+# replacements, missing definitions are set to their default value.
+
+RTF_STYLESHEET_FILE =
+
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_MAN tag is set to YES (the default) Doxygen will
+# generate man pages
+
+GENERATE_MAN = NO
+
+# The MAN_OUTPUT tag is used to specify where the man pages will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `man' will be used as the default path.
+
+MAN_OUTPUT = man
+
+# The MAN_EXTENSION tag determines the extension that is added to
+# the generated man pages (default is the subroutine's section .3)
+
+MAN_EXTENSION = .3
+
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_XML tag is set to YES Doxygen will
+# generate an XML file that captures the structure of
+# the code including all documentation. Warning: This feature
+# is still experimental and very incomplete.
+
+GENERATE_XML = NO
+
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor
+#---------------------------------------------------------------------------
+
+# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will
+# evaluate all C-preprocessor directives found in the sources and include
+# files.
+
+ENABLE_PREPROCESSING = YES
+
+# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro
+# names in the source code. If set to NO (the default) only conditional
+# compilation will be performed. Macro expansion can be done in a controlled
+# way by setting EXPAND_ONLY_PREDEF to YES.
+
+MACRO_EXPANSION = NO
+
+# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES
+# then the macro expansion is limited to the macros specified with the
+# PREDEFINED and EXPAND_AS_PREDEFINED tags.
+
+EXPAND_ONLY_PREDEF = NO
+
+# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files
+# in the INCLUDE_PATH (see below) will be search if a #include is found.
+
+SEARCH_INCLUDES = YES
+
+# The INCLUDE_PATH tag can be used to specify one or more directories that
+# contain include files that are not input files but should be processed by
+# the preprocessor.
+
+INCLUDE_PATH = ../../generic/extern
+
+# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
+# patterns (like *.h and *.hpp) to filter out the header-files in the
+# directories. If left blank, the patterns specified with FILE_PATTERNS will
+# be used.
+
+INCLUDE_FILE_PATTERNS =
+
+# The PREDEFINED tag can be used to specify one or more macro names that
+# are defined before the preprocessor is started (similar to the -D option of
+# gcc). The argument of the tag is a list of macros of the form: name
+# or name=definition (no spaces). If the definition and the = are
+# omitted =1 is assumed.
+
+PREDEFINED =
+
+# If the MACRO_EXPANSION and EXPAND_PREDEF_ONLY tags are set to YES then
+# this tag can be used to specify a list of macro names that should be expanded.
+# The macro definition that is found in the sources will be used.
+# Use the PREDEFINED tag if you want to use a different macro definition.
+
+EXPAND_AS_DEFINED =
+
+#---------------------------------------------------------------------------
+# Configuration::addtions related to external references
+#---------------------------------------------------------------------------
+
+# The TAGFILES tag can be used to specify one or more tagfiles.
+
+TAGFILES =
+
+# When a file name is specified after GENERATE_TAGFILE, doxygen will create
+# a tag file that is based on the input files it reads.
+
+GENERATE_TAGFILE =
+
+# If the ALLEXTERNALS tag is set to YES all external classes will be listed
+# in the class index. If set to NO only the inherited external classes
+# will be listed.
+
+ALLEXTERNALS = NO
+
+# The PERL_PATH should be the absolute path and name of the perl script
+# interpreter (i.e. the result of `which perl').
+
+PERL_PATH = /usr/bin/perl
+
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool
+#---------------------------------------------------------------------------
+
+# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
+# available from the path. This tool is part of Graphviz, a graph visualization
+# toolkit from AT&T and Lucent Bell Labs. The other options in this section
+# have no effect if this option is set to NO (the default)
+
+HAVE_DOT = YES
+
+# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for each documented class showing the direct and
+# indirect inheritance relations. Setting this tag to YES will force the
+# the CLASS_DIAGRAMS tag to NO.
+
+CLASS_GRAPH = YES
+
+# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for each documented class showing the direct and
+# indirect implementation dependencies (inheritance, containment, and
+# class references variables) of the class with other documented classes.
+
+COLLABORATION_GRAPH = YES
+
+# If the ENABLE_PREPROCESSING, INCLUDE_GRAPH, and HAVE_DOT tags are set to
+# YES then doxygen will generate a graph for each documented file showing
+# the direct and indirect include dependencies of the file with other
+# documented files.
+
+INCLUDE_GRAPH = YES
+
+# If the ENABLE_PREPROCESSING, INCLUDED_BY_GRAPH, and HAVE_DOT tags are set to
+# YES then doxygen will generate a graph for each documented header file showing
+# the documented files that directly or indirectly include this file
+
+INCLUDED_BY_GRAPH = YES
+
+# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen
+# will graphical hierarchy of all classes instead of a textual one.
+
+GRAPHICAL_HIERARCHY = YES
+
+# The tag DOT_PATH can be used to specify the path where the dot tool can be
+# found. If left blank, it is assumed the dot tool can be found on the path.
+
+DOT_PATH =
+
+# The MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width
+# (in pixels) of the graphs generated by dot. If a graph becomes larger than
+# this value, doxygen will try to truncate the graph, so that it fits within
+# the specified constraint. Beware that most browsers cannot cope with very
+# large images.
+
+MAX_DOT_GRAPH_WIDTH = 1024
+
+# The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height
+# (in pixels) of the graphs generated by dot. If a graph becomes larger than
+# this value, doxygen will try to truncate the graph, so that it fits within
+# the specified constraint. Beware that most browsers cannot cope with very
+# large images.
+
+MAX_DOT_GRAPH_HEIGHT = 1024
+
+# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will
+# generate a legend page explaining the meaning of the various boxes and
+# arrows in the dot generated graphs.
+
+GENERATE_LEGEND = YES
+
+#---------------------------------------------------------------------------
+# Configuration::addtions related to the search engine
+#---------------------------------------------------------------------------
+
+# The SEARCHENGINE tag specifies whether or not a search engine should be
+# used. If set to NO the values of all tags below this one will be ignored.
+
+SEARCHENGINE = NO
+
+# The CGI_NAME tag should be the name of the CGI script that
+# starts the search engine (doxysearch) with the correct parameters.
+# A script with this name will be generated by doxygen.
+
+CGI_NAME = search.cgi
+
+# The CGI_URL tag should be the absolute URL to the directory where the
+# cgi binaries are located. See the documentation of your http daemon for
+# details.
+
+CGI_URL =
+
+# The DOC_URL tag should be the absolute URL to the directory where the
+# documentation is located. If left blank the absolute path to the
+# documentation, with file:// prepended to it, will be used.
+
+DOC_URL =
+
+# The DOC_ABSPATH tag should be the absolute path to the directory where the
+# documentation is located. If left blank the directory on the local machine
+# will be used.
+
+DOC_ABSPATH =
+
+# The BIN_ABSPATH tag must point to the directory where the doxysearch binary
+# is installed.
+
+BIN_ABSPATH = c:\program files\doxygen\bin
+
+# The EXT_DOC_PATHS tag can be used to specify one or more paths to
+# documentation generated for other projects. This allows doxysearch to search
+# the documentation for these projects as well.
+
+EXT_DOC_PATHS =
diff --git a/extern/bullet/Bullet/NarrowPhaseCollision/BU_AlgebraicPolynomialSolver.cpp b/extern/bullet/Bullet/NarrowPhaseCollision/BU_AlgebraicPolynomialSolver.cpp
new file mode 100644
index 00000000000..8253e61f17f
--- /dev/null
+++ b/extern/bullet/Bullet/NarrowPhaseCollision/BU_AlgebraicPolynomialSolver.cpp
@@ -0,0 +1,355 @@
+/*
+ * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies.
+ * Erwin Coumans makes no representations about the suitability
+ * of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+*/
+
+#include "BU_AlgebraicPolynomialSolver.h"
+#include <math.h>
+#include <SimdMinMax.h>
+
+int BU_AlgebraicPolynomialSolver::Solve2Quadratic(SimdScalar p, SimdScalar q)
+{
+
+ SimdScalar basic_h_local;
+ SimdScalar basic_h_local_delta;
+
+ basic_h_local = p * 0.5f;
+ basic_h_local_delta = basic_h_local * basic_h_local - q;
+ if (basic_h_local_delta > 0.0f) {
+ basic_h_local_delta = sqrtf(basic_h_local_delta);
+ m_roots[0] = - basic_h_local + basic_h_local_delta;
+ m_roots[1] = - basic_h_local - basic_h_local_delta;
+ return 2;
+ }
+ else if (SimdGreaterEqual(basic_h_local_delta, SIMD_EPSILON)) {
+ m_roots[0] = - basic_h_local;
+ return 1;
+ }
+ else {
+ return 0;
+ }
+ }
+
+
+int BU_AlgebraicPolynomialSolver::Solve2QuadraticFull(SimdScalar a,SimdScalar b, SimdScalar c)
+{
+ SimdScalar radical = b * b - 4.0f * a * c;
+ if(radical >= 0.f)
+ {
+ SimdScalar sqrtRadical = sqrtf(radical);
+ SimdScalar idenom = 1.0f/(2.0f * a);
+ m_roots[0]=(-b + sqrtRadical) * idenom;
+ m_roots[1]=(-b - sqrtRadical) * idenom;
+ return 2;
+ }
+ return 0;
+}
+
+
+#define cubic_rt(x) \
+ ((x) > 0.0f ? powf((SimdScalar)(x), 0.333333333333333333333333f) : \
+ ((x) < 0.0f ? -powf((SimdScalar)-(x), 0.333333333333333333333333f) : 0.0f))
+
+
+
+/* */
+/* this function solves the following cubic equation: */
+/* */
+/* 3 2 */
+/* lead * x + a * x + b * x + c = 0. */
+/* */
+/* it returns the number of different roots found, and stores the roots in */
+/* roots[0,2]. it returns -1 for a degenerate equation 0 = 0. */
+/* */
+int BU_AlgebraicPolynomialSolver::Solve3Cubic(SimdScalar lead, SimdScalar a, SimdScalar b, SimdScalar c)
+{
+ SimdScalar p, q, r;
+ SimdScalar delta, u, phi;
+ SimdScalar dummy;
+
+ if (lead != 1.0) {
+ /* */
+ /* transform into normal form: x^3 + a x^2 + b x + c = 0 */
+ /* */
+ if (SimdEqual(lead, SIMD_EPSILON)) {
+ /* */
+ /* we have a x^2 + b x + c = 0 */
+ /* */
+ if (SimdEqual(a, SIMD_EPSILON)) {
+ /* */
+ /* we have b x + c = 0 */
+ /* */
+ if (SimdEqual(b, SIMD_EPSILON)) {
+ if (SimdEqual(c, SIMD_EPSILON)) {
+ return -1;
+ }
+ else {
+ return 0;
+ }
+ }
+ else {
+ m_roots[0] = -c / b;
+ return 1;
+ }
+ }
+ else {
+ p = c / a;
+ q = b / a;
+ return Solve2QuadraticFull(a,b,c);
+ }
+ }
+ else {
+ a = a / lead;
+ b = b / lead;
+ c = c / lead;
+ }
+ }
+
+ /* */
+ /* we substitute x = y - a / 3 in order to eliminate the quadric term. */
+ /* we get x^3 + p x + q = 0 */
+ /* */
+ a /= 3.0f;
+ u = a * a;
+ p = b / 3.0f - u;
+ q = a * (2.0f * u - b) + c;
+
+ /* */
+ /* now use Cardano's formula */
+ /* */
+ if (SimdEqual(p, SIMD_EPSILON)) {
+ if (SimdEqual(q, SIMD_EPSILON)) {
+ /* */
+ /* one triple root */
+ /* */
+ m_roots[0] = -a;
+ return 1;
+ }
+ else {
+ /* */
+ /* one real and two complex roots */
+ /* */
+ m_roots[0] = cubic_rt(-q) - a;
+ return 1;
+ }
+ }
+
+ q /= 2.0f;
+ delta = p * p * p + q * q;
+ if (delta > 0.0f) {
+ /* */
+ /* one real and two complex roots. note that v = -p / u. */
+ /* */
+ u = -q + sqrtf(delta);
+ u = cubic_rt(u);
+ m_roots[0] = u - p / u - a;
+ return 1;
+ }
+ else if (delta < 0.0) {
+ /* */
+ /* Casus irreducibilis: we have three real roots */
+ /* */
+ r = sqrtf(-p);
+ p *= -r;
+ r *= 2.0;
+ phi = acosf(-q / p) / 3.0f;
+ dummy = SIMD_2_PI / 3.0f;
+ m_roots[0] = r * cosf(phi) - a;
+ m_roots[1] = r * cosf(phi + dummy) - a;
+ m_roots[2] = r * cosf(phi - dummy) - a;
+ return 3;
+ }
+ else {
+ /* */
+ /* one single and one SimdScalar root */
+ /* */
+ r = cubic_rt(-q);
+ m_roots[0] = 2.0f * r - a;
+ m_roots[1] = -r - a;
+ return 2;
+ }
+}
+
+
+/* */
+/* this function solves the following quartic equation: */
+/* */
+/* 4 3 2 */
+/* lead * x + a * x + b * x + c * x + d = 0. */
+/* */
+/* it returns the number of different roots found, and stores the roots in */
+/* roots[0,3]. it returns -1 for a degenerate equation 0 = 0. */
+/* */
+int BU_AlgebraicPolynomialSolver::Solve4Quartic(SimdScalar lead, SimdScalar a, SimdScalar b, SimdScalar c, SimdScalar d)
+{
+ SimdScalar p, q ,r;
+ SimdScalar u, v, w;
+ int i, num_roots, num_tmp;
+ //SimdScalar tmp[2];
+
+ if (lead != 1.0) {
+ /* */
+ /* transform into normal form: x^4 + a x^3 + b x^2 + c x + d = 0 */
+ /* */
+ if (SimdEqual(lead, SIMD_EPSILON)) {
+ /* */
+ /* we have a x^3 + b x^2 + c x + d = 0 */
+ /* */
+ if (SimdEqual(a, SIMD_EPSILON)) {
+ /* */
+ /* we have b x^2 + c x + d = 0 */
+ /* */
+ if (SimdEqual(b, SIMD_EPSILON)) {
+ /* */
+ /* we have c x + d = 0 */
+ /* */
+ if (SimdEqual(c, SIMD_EPSILON)) {
+ if (SimdEqual(d, SIMD_EPSILON)) {
+ return -1;
+ }
+ else {
+ return 0;
+ }
+ }
+ else {
+ m_roots[0] = -d / c;
+ return 1;
+ }
+ }
+ else {
+ p = c / b;
+ q = d / b;
+ return Solve2QuadraticFull(b,c,d);
+
+ }
+ }
+ else {
+ return Solve3Cubic(1.0, b / a, c / a, d / a);
+ }
+ }
+ else {
+ a = a / lead;
+ b = b / lead;
+ c = c / lead;
+ d = d / lead;
+ }
+ }
+
+ /* */
+ /* we substitute x = y - a / 4 in order to eliminate the cubic term. */
+ /* we get: y^4 + p y^2 + q y + r = 0. */
+ /* */
+ a /= 4.0f;
+ p = b - 6.0f * a * a;
+ q = a * (8.0f * a * a - 2.0f * b) + c;
+ r = a * (a * (b - 3.f * a * a) - c) + d;
+ if (SimdEqual(q, SIMD_EPSILON)) {
+ /* */
+ /* biquadratic equation: y^4 + p y^2 + r = 0. */
+ /* */
+ num_roots = Solve2Quadratic(p, r);
+ if (num_roots > 0) {
+ if (m_roots[0] > 0.0f) {
+ if (num_roots > 1) {
+ if ((m_roots[1] > 0.0f) && (m_roots[1] != m_roots[0])) {
+ u = sqrtf(m_roots[1]);
+ m_roots[2] = u - a;
+ m_roots[3] = -u - a;
+ u = sqrtf(m_roots[0]);
+ m_roots[0] = u - a;
+ m_roots[1] = -u - a;
+ return 4;
+ }
+ else {
+ u = sqrtf(m_roots[0]);
+ m_roots[0] = u - a;
+ m_roots[1] = -u - a;
+ return 2;
+ }
+ }
+ else {
+ u = sqrtf(m_roots[0]);
+ m_roots[0] = u - a;
+ m_roots[1] = -u - a;
+ return 2;
+ }
+ }
+ }
+ return 0;
+ }
+ else if (SimdEqual(r, SIMD_EPSILON)) {
+ /* */
+ /* no absolute term: y (y^3 + p y + q) = 0. */
+ /* */
+ num_roots = Solve3Cubic(1.0, 0.0, p, q);
+ for (i = 0; i < num_roots; ++i) m_roots[i] -= a;
+ if (num_roots != -1) {
+ m_roots[num_roots] = -a;
+ ++num_roots;
+ }
+ else {
+ m_roots[0] = -a;
+ num_roots = 1;;
+ }
+ return num_roots;
+ }
+ else {
+ /* */
+ /* we solve the resolvent cubic equation */
+ /* */
+ num_roots = Solve3Cubic(1.0f, -0.5f * p, -r, 0.5f * r * p - 0.125f * q * q);
+ if (num_roots == -1) {
+ num_roots = 1;
+ m_roots[0] = 0.0f;
+ }
+
+ /* */
+ /* build two quadric equations */
+ /* */
+ w = m_roots[0];
+ u = w * w - r;
+ v = 2.0f * w - p;
+
+ if (SimdEqual(u, SIMD_EPSILON))
+ u = 0.0;
+ else if (u > 0.0f)
+ u = sqrtf(u);
+ else
+ return 0;
+
+ if (SimdEqual(v, SIMD_EPSILON))
+ v = 0.0;
+ else if (v > 0.0f)
+ v = sqrtf(v);
+ else
+ return 0;
+
+ if (q < 0.0f) v = -v;
+ w -= u;
+ num_roots=Solve2Quadratic(v, w);
+ for (i = 0; i < num_roots; ++i)
+ {
+ m_roots[i] -= a;
+ }
+ w += 2.0f *u;
+ SimdScalar tmp[2];
+ tmp[0] = m_roots[0];
+ tmp[1] = m_roots[1];
+
+ num_tmp = Solve2Quadratic(-v, w);
+ for (i = 0; i < num_tmp; ++i)
+ {
+ m_roots[i + num_roots] = tmp[i] - a;
+ m_roots[i]=tmp[i];
+ }
+
+ return (num_tmp + num_roots);
+ }
+}
+
diff --git a/extern/bullet/Bullet/NarrowPhaseCollision/BU_AlgebraicPolynomialSolver.h b/extern/bullet/Bullet/NarrowPhaseCollision/BU_AlgebraicPolynomialSolver.h
new file mode 100644
index 00000000000..32986eb2e72
--- /dev/null
+++ b/extern/bullet/Bullet/NarrowPhaseCollision/BU_AlgebraicPolynomialSolver.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies.
+ * Erwin Coumans makes no representations about the suitability
+ * of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+*/
+
+#ifndef BU_ALGEBRAIC_POLYNOMIAL_SOLVER_H
+#define BU_ALGEBRAIC_POLYNOMIAL_SOLVER_H
+
+#include "BU_PolynomialSolverInterface.h"
+
+/// BU_AlgebraicPolynomialSolver implements polynomial root finding by analytically solving algebraic equations.
+/// Polynomials up to 4rd degree are supported, Cardano's formula is used for 3rd degree
+class BU_AlgebraicPolynomialSolver : public BUM_PolynomialSolverInterface
+{
+public:
+ BU_AlgebraicPolynomialSolver() {};
+
+ int Solve2Quadratic(SimdScalar p, SimdScalar q);
+ int Solve2QuadraticFull(SimdScalar a,SimdScalar b, SimdScalar c);
+ int Solve3Cubic(SimdScalar lead, SimdScalar a, SimdScalar b, SimdScalar c);
+ int Solve4Quartic(SimdScalar lead, SimdScalar a, SimdScalar b, SimdScalar c, SimdScalar d);
+
+
+ SimdScalar GetRoot(int i) const
+ {
+ return m_roots[i];
+ }
+
+private:
+ SimdScalar m_roots[4];
+
+};
+
+#endif //BU_ALGEBRAIC_POLYNOMIAL_SOLVER_H
diff --git a/extern/bullet/Bullet/NarrowPhaseCollision/BU_Collidable.cpp b/extern/bullet/Bullet/NarrowPhaseCollision/BU_Collidable.cpp
new file mode 100644
index 00000000000..fa8091a2e93
--- /dev/null
+++ b/extern/bullet/Bullet/NarrowPhaseCollision/BU_Collidable.cpp
@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies.
+ * Erwin Coumans makes no representations about the suitability
+ * of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+*/
+
+#include "BU_Collidable.h"
+#include "CollisionShapes/CollisionShape.h"
+#include <SimdTransform.h>
+#include "BU_MotionStateInterface.h"
+
+BU_Collidable::BU_Collidable(BU_MotionStateInterface& motion,PolyhedralConvexShape& shape,void* userPointer )
+:m_motionState(motion),m_shape(shape),m_userPointer(userPointer)
+{
+}
diff --git a/extern/bullet/Bullet/NarrowPhaseCollision/BU_Collidable.h b/extern/bullet/Bullet/NarrowPhaseCollision/BU_Collidable.h
new file mode 100644
index 00000000000..79164426fc4
--- /dev/null
+++ b/extern/bullet/Bullet/NarrowPhaseCollision/BU_Collidable.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies.
+ * Erwin Coumans makes no representations about the suitability
+ * of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+*/
+
+#ifndef BU_COLLIDABLE
+#define BU_COLLIDABLE
+
+
+class PolyhedralConvexShape;
+class BU_MotionStateInterface;
+#include <SimdPoint3.h>
+
+class BU_Collidable
+{
+public:
+ BU_Collidable(BU_MotionStateInterface& motion,PolyhedralConvexShape& shape, void* userPointer);
+
+ void* GetUserPointer() const
+ {
+ return m_userPointer;
+ }
+
+ BU_MotionStateInterface& GetMotionState()
+ {
+ return m_motionState;
+ }
+ inline const BU_MotionStateInterface& GetMotionState() const
+ {
+ return m_motionState;
+ }
+
+ inline const PolyhedralConvexShape& GetShape() const
+ {
+ return m_shape;
+ };
+
+
+private:
+ BU_MotionStateInterface& m_motionState;
+ PolyhedralConvexShape& m_shape;
+ void* m_userPointer;
+
+};
+
+#endif //BU_COLLIDABLE
diff --git a/extern/bullet/Bullet/NarrowPhaseCollision/BU_CollisionPair.cpp b/extern/bullet/Bullet/NarrowPhaseCollision/BU_CollisionPair.cpp
new file mode 100644
index 00000000000..3f60f5dfb86
--- /dev/null
+++ b/extern/bullet/Bullet/NarrowPhaseCollision/BU_CollisionPair.cpp
@@ -0,0 +1,576 @@
+
+/*
+ * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies.
+ * Erwin Coumans makes no representations about the suitability
+ * of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+*/
+
+#include "BU_CollisionPair.h"
+#include "NarrowPhaseCollision/BU_VertexPoly.h"
+#include "NarrowPhaseCollision/BU_EdgeEdge.h"
+#include "BU_Collidable.h"
+
+
+#include "BU_MotionStateInterface.h"
+#include "CollisionShapes/PolyhedralConvexShape.h"
+#include <SimdMinMax.h>
+#include "SimdTransformUtil.h"
+
+
+
+BU_CollisionPair::BU_CollisionPair(const PolyhedralConvexShape* convexA,const PolyhedralConvexShape* convexB,SimdScalar tolerance)
+: m_convexA(convexA),m_convexB(convexB),m_screwing(SimdVector3(0,0,0),SimdVector3(0,0,0)),
+m_tolerance(tolerance)
+{
+
+}
+
+// if there exists a time-of-impact between any feature_pair (edgeA,edgeB),
+// (vertexA,faceB) or (vertexB,faceA) in [0..1], report true and smallest time
+
+
+/*
+bool BU_CollisionPair::GetTimeOfImpact(const SimdVector3& linearMotionA,const SimdQuaternion& angularMotionA,const SimdVector3& linearMotionB,const SimdQuaternion& angularMotionB, SimdScalar& toi,SimdTransform& impactTransA,SimdTransform& impactTransB)
+
+*/
+
+bool BU_CollisionPair::calcTimeOfImpact(
+ const SimdTransform& fromA,
+ const SimdTransform& toA,
+ const SimdTransform& fromB,
+ const SimdTransform& toB,
+ CastResult& result)
+{
+
+
+
+
+ SimdVector3 linvelA,angvelA;
+ SimdVector3 linvelB,angvelB;
+
+ SimdTransformUtil::CalculateVelocity(fromA,toA,1.f,linvelA,angvelA);
+ SimdTransformUtil::CalculateVelocity(fromB,toB,1.f,linvelB,angvelB);
+
+
+ SimdVector3 linearMotionA = toA.getOrigin() - fromA.getOrigin();
+ SimdQuaternion angularMotionA(0,0,0,1.f);
+ SimdVector3 linearMotionB = toB.getOrigin() - fromB.getOrigin();
+ SimdQuaternion angularMotionB(0,0,0,1);
+
+
+
+ result.m_fraction = 1.f;
+
+ SimdTransform impactTransA;
+ SimdTransform impactTransB;
+
+ int index=0;
+
+ SimdScalar toiUnscaled=result.m_fraction;
+ const SimdScalar toiUnscaledLimit = result.m_fraction;
+
+ SimdTransform a2w;
+ a2w = fromA;
+ SimdTransform b2w = fromB;
+
+/* debugging code
+ {
+ const int numvertsB = m_convexB->GetNumVertices();
+ for (int v=0;v<numvertsB;v++)
+ {
+ SimdPoint3 pt;
+ m_convexB->GetVertex(v,pt);
+ pt = b2w * pt;
+ char buf[1000];
+
+ if (pt.y() < 0.)
+ {
+ sprintf(buf,"PRE ERROR (%d) %.20E %.20E %.20E!!!!!!!!!\n",v,pt.x(),pt.y(),pt.z());
+ if (debugFile)
+ fwrite(buf,1,strlen(buf),debugFile);
+ } else
+ {
+ sprintf(buf,"PRE %d = %.20E,%.20E,%.20E\n",v,pt.x(),pt.y(),pt.z());
+ if (debugFile)
+ fwrite(buf,1,strlen(buf),debugFile);
+
+ }
+ }
+ }
+*/
+
+
+ SimdTransform b2wp = b2w;
+
+ b2wp.setOrigin(b2w.getOrigin() + linearMotionB);
+ b2wp.setRotation( b2w.getRotation() + angularMotionB);
+
+ impactTransB = b2wp;
+
+ SimdTransform a2wp;
+ a2wp.setOrigin(a2w.getOrigin()+ linearMotionA);
+ a2wp.setRotation(a2w.getRotation()+angularMotionA);
+
+ impactTransA = a2wp;
+
+ SimdTransform a2winv;
+ a2winv = a2w.inverse();
+
+ SimdTransform b2wpinv;
+ b2wpinv = b2wp.inverse();
+
+ SimdTransform b2winv;
+ b2winv = b2w.inverse();
+
+ SimdTransform a2wpinv;
+ a2wpinv = a2wp.inverse();
+
+ //Redon's version with concatenated transforms
+
+ SimdTransform relative;
+
+ relative = b2w * b2wpinv * a2wp * a2winv;
+
+ //relative = a2winv * a2wp * b2wpinv * b2w;
+
+ SimdQuaternion qrel;
+ relative.getBasis().getRotation(qrel);
+
+ SimdVector3 linvel = relative.getOrigin();
+
+ if (linvel.length() < SCREWEPSILON)
+ {
+ linvel.setValue(0.,0.,0.);
+ }
+ SimdVector3 angvel;
+ angvel[0] = 2.f * asinf (qrel[0]);
+ angvel[1] = 2.f * asinf (qrel[1]);
+ angvel[2] = 2.f * asinf (qrel[2]);
+
+ if (angvel.length() < SCREWEPSILON)
+ {
+ angvel.setValue(0.f,0.f,0.f);
+ }
+
+ //Redon's version with concatenated transforms
+ m_screwing = BU_Screwing(linvel,angvel);
+
+ SimdTransform w2s;
+ m_screwing.LocalMatrix(w2s);
+
+ SimdTransform s2w;
+ s2w = w2s.inverse();
+
+ //impactTransA = a2w;
+ //impactTransB = b2w;
+
+ bool hit = false;
+
+ if (SimdFuzzyZero(m_screwing.GetS()) && SimdFuzzyZero(m_screwing.GetW()))
+ {
+ //W = 0 , S = 0 , no collision
+ //toi = 0;
+ /*
+ {
+ const int numvertsB = m_convexB->GetNumVertices();
+ for (int v=0;v<numvertsB;v++)
+ {
+ SimdPoint3 pt;
+ m_convexB->GetVertex(v,pt);
+ pt = impactTransB * pt;
+ char buf[1000];
+
+ if (pt.y() < 0.)
+ {
+ sprintf(buf,"EARLY POST ERROR (%d) %.20E,%.20E,%.20E!!!!!!!!!\n",v,pt.x(),pt.y(),pt.z());
+ if (debugFile)
+ fwrite(buf,1,strlen(buf),debugFile);
+ }
+ else
+ {
+ sprintf(buf,"EARLY POST %d = %.20E,%.20E,%.20E\n",v,pt.x(),pt.y(),pt.z());
+ if (debugFile)
+ fwrite(buf,1,strlen(buf),debugFile);
+ }
+ }
+ }
+ */
+
+ return false;//don't continue moving within epsilon
+ }
+
+#define EDGEEDGE
+#ifdef EDGEEDGE
+
+ BU_EdgeEdge edgeEdge;
+
+ //for all edged in A check agains all edges in B
+ for (int ea = 0;ea < m_convexA->GetNumEdges();ea++)
+ {
+ SimdPoint3 pA0,pA1;
+
+ m_convexA->GetEdge(ea,pA0,pA1);
+
+ pA0= a2w * pA0;//in world space
+ pA0 = w2s * pA0;//in screwing space
+
+ pA1= a2w * pA1;//in world space
+ pA1 = w2s * pA1;//in screwing space
+
+ int numedgesB = m_convexB->GetNumEdges();
+ for (int eb = 0; eb < numedgesB;eb++)
+ {
+ {
+ SimdPoint3 pB0,pB1;
+ m_convexB->GetEdge(eb,pB0,pB1);
+
+ pB0= b2w * pB0;//in world space
+ pB0 = w2s * pB0;//in screwing space
+
+ pB1= b2w * pB1;//in world space
+ pB1 = w2s * pB1;//in screwing space
+
+
+ SimdScalar lambda,mu;
+
+ toiUnscaled = 1.;
+
+ SimdVector3 edgeDirA(pA1-pA0);
+ SimdVector3 edgeDirB(pB1-pB0);
+
+ if (edgeEdge.GetTimeOfImpact(m_screwing,pA0,edgeDirA,pB0,edgeDirB,toiUnscaled,lambda,mu))
+ {
+ //printf("edgeedge potential hit\n");
+ if (toiUnscaled>=0)
+ {
+ if (toiUnscaled < toiUnscaledLimit)
+ {
+
+ //inside check is already done by checking the mu and gamma !
+
+ SimdPoint3 vtx = pA0+lambda * (pA1-pA0);
+ SimdPoint3 hitpt = m_screwing.InBetweenPosition(vtx,toiUnscaled);
+
+ SimdPoint3 hitptWorld = s2w * hitpt;
+ {
+
+ if (toiUnscaled < result.m_fraction)
+ result.m_fraction = toiUnscaled;
+
+ hit = true;
+
+ SimdVector3 hitNormal = edgeDirB.cross(edgeDirA);
+
+ hitNormal = m_screwing.InBetweenVector(hitNormal,toiUnscaled);
+
+
+ hitNormal.normalize();
+
+ //an approximated normal can be calculated by taking the cross product of both edges
+ //take care of the sign !
+
+ SimdVector3 hitNormalWorld = s2w.getBasis() * hitNormal ;
+
+ SimdScalar dist = m_screwing.GetU().dot(hitNormalWorld);
+ if (dist > 0)
+ hitNormalWorld *= -1;
+
+ //todo: this is the wrong point, because b2winv is still at begin of motion
+ // not at time-of-impact location!
+ //bhitpt = b2winv * hitptWorld;
+
+// m_manifold.SetContactPoint(BUM_FeatureEdgeEdge,index,ea,eb,hitptWorld,hitNormalWorld);
+ }
+
+ }
+ }
+ }
+ }
+
+ index++;
+ }
+ };
+#endif //EDGEEDGE
+
+#define VERTEXFACE
+#ifdef VERTEXFACE
+
+ // for all vertices in A, for each face in B,do vertex-face
+ {
+ const int numvertsA = m_convexA->GetNumVertices();
+ for (int v=0;v<numvertsA;v++)
+ //int v=3;
+
+ {
+ SimdPoint3 vtx;
+ m_convexA->GetVertex(v,vtx);
+
+ vtx = a2w * vtx;//in world space
+ vtx = w2s * vtx;//in screwing space
+
+ const int numplanesB = m_convexB->GetNumPlanes();
+
+ for (int p = 0 ; p < numplanesB; p++)
+ //int p=2;
+ {
+
+ {
+
+ SimdVector3 planeNorm;
+ SimdPoint3 planeSupport;
+
+ m_convexB->GetPlane(planeNorm,planeSupport,p);
+
+
+ planeSupport = b2w * planeSupport;//transform to world space
+ SimdVector3 planeNormWorld = b2w.getBasis() * planeNorm;
+
+ planeSupport = w2s * planeSupport ; //transform to screwing space
+ planeNorm = w2s.getBasis() * planeNormWorld;
+
+ planeNorm.normalize();
+
+ SimdScalar d = planeSupport.dot(planeNorm);
+
+ SimdVector4 planeEq(planeNorm[0],planeNorm[1],planeNorm[2],d);
+
+ BU_VertexPoly vtxApolyB;
+
+ toiUnscaled = 1.;
+
+ if ((p==2) && (v==6))
+ {
+// printf("%f toiUnscaled\n",toiUnscaled);
+
+ }
+ if (vtxApolyB.GetTimeOfImpact(m_screwing,vtx,planeEq,toiUnscaled,false))
+ {
+
+
+
+
+ if (toiUnscaled >= 0. )
+ {
+ //not only collect the first point, get every contactpoint, later we have to check the
+ //manifold properly!
+
+ if (toiUnscaled <= toiUnscaledLimit)
+ {
+ // printf("toiUnscaled %f\n",toiUnscaled );
+
+ SimdPoint3 hitpt = m_screwing.InBetweenPosition(vtx,toiUnscaled);
+ SimdVector3 hitNormal = m_screwing.InBetweenVector(planeNorm ,toiUnscaled);
+
+ SimdVector3 hitNormalWorld = s2w.getBasis() * hitNormal ;
+ SimdPoint3 hitptWorld = s2w * hitpt;
+
+
+ hitpt = b2winv * hitptWorld;
+ //vertex has to be 'within' the facet's boundary
+ if (m_convexB->IsInside(hitpt,m_tolerance))
+ {
+// m_manifold.SetContactPoint(BUM_FeatureVertexFace, index,v,p,hitptWorld,hitNormalWorld);
+
+ if (toiUnscaled < result.m_fraction)
+ result.m_fraction= toiUnscaled;
+ hit = true;
+
+ }
+ }
+ }
+ }
+
+ }
+
+ index++;
+ }
+ }
+ }
+
+ //
+ // for all vertices in B, for each face in A,do vertex-face
+ //copy and pasted from all verts A -> all planes B so potential typos!
+ //todo: make this into one method with a kind of 'swapped' logic
+ //
+ {
+ const int numvertsB = m_convexB->GetNumVertices();
+ for (int v=0;v<numvertsB;v++)
+ //int v=0;
+
+ {
+ SimdPoint3 vtx;
+ m_convexB->GetVertex(v,vtx);
+
+ vtx = b2w * vtx;//in world space
+/*
+
+ char buf[1000];
+
+ if (vtx.y() < 0.)
+ {
+ sprintf(buf,"ERROR !!!!!!!!!\n",v,vtx.x(),vtx.y(),vtx.z());
+ if (debugFile)
+ fwrite(buf,1,strlen(buf),debugFile);
+ }
+ sprintf(buf,"vertexWorld(%d) = (%.20E,%.20E,%.20E)\n",v,vtx.x(),vtx.y(),vtx.z());
+ if (debugFile)
+ fwrite(buf,1,strlen(buf),debugFile);
+
+*/
+ vtx = w2s * vtx;//in screwing space
+
+ const int numplanesA = m_convexA->GetNumPlanes();
+
+ for (int p = 0 ; p < numplanesA; p++)
+ //int p=2;
+ {
+
+ {
+ SimdVector3 planeNorm;
+ SimdPoint3 planeSupport;
+
+ m_convexA->GetPlane(planeNorm,planeSupport,p);
+
+
+ planeSupport = a2w * planeSupport;//transform to world space
+ SimdVector3 planeNormWorld = a2w.getBasis() * planeNorm;
+
+ planeSupport = w2s * planeSupport ; //transform to screwing space
+ planeNorm = w2s.getBasis() * planeNormWorld;
+
+ planeNorm.normalize();
+
+ SimdScalar d = planeSupport.dot(planeNorm);
+
+ SimdVector4 planeEq(planeNorm[0],planeNorm[1],planeNorm[2],d);
+
+ BU_VertexPoly vtxBpolyA;
+
+ toiUnscaled = 1.;
+
+ if (vtxBpolyA.GetTimeOfImpact(m_screwing,vtx,planeEq,toiUnscaled,true))
+ {
+ if (toiUnscaled>=0.)
+ {
+ if (toiUnscaled < toiUnscaledLimit)
+ {
+ SimdPoint3 hitpt = m_screwing.InBetweenPosition( vtx , -toiUnscaled);
+ SimdVector3 hitNormal = m_screwing.InBetweenVector(-planeNorm ,-toiUnscaled);
+ SimdScalar len = hitNormal.length()-1;
+
+ //assert( SimdFuzzyZero(len) );
+
+
+ SimdVector3 hitNormalWorld = s2w.getBasis() * hitNormal ;
+ SimdPoint3 hitptWorld = s2w * hitpt;
+ hitpt = a2winv * hitptWorld;
+
+
+ //vertex has to be 'within' the facet's boundary
+ if (m_convexA->IsInside(hitpt,m_tolerance))
+ {
+
+// m_manifold.SetContactPoint(BUM_FeatureFaceVertex,index,p,v,hitptWorld,hitNormalWorld);
+ if (toiUnscaled <result.m_fraction)
+ result.m_fraction = toiUnscaled;
+ hit = true;
+ }
+ }
+
+ }
+
+ }
+ }
+
+ }
+
+ index++;
+ }
+ }
+
+
+#endif// VERTEXFACE
+
+ //the manifold now consists of all points/normals generated by feature-pairs that have a time-of-impact within this frame
+ //in addition there are contact points from previous frames
+ //we have to cleanup the manifold, using an additional epsilon/tolerance
+ //as long as the distance from the contactpoint (in worldspace) to both objects is within this epsilon we keep the point
+ //else throw it away
+
+
+ if (hit)
+ {
+
+ //try to avoid numerical drift on close contact
+
+ if (result.m_fraction < 0.00001)
+ {
+// printf("toiUnscaledMin< 0.00001\n");
+ impactTransA = a2w;
+ impactTransB = b2w;
+
+ } else
+ {
+
+ //SimdScalar vel = linearMotionB.length();
+
+ //todo: check this margin
+ result.m_fraction *= 0.99f;
+
+ //move B to new position
+ impactTransB.setOrigin(b2w.getOrigin()+ result.m_fraction*linearMotionB);
+ SimdQuaternion ornB = b2w.getRotation()+angularMotionB*result.m_fraction;
+ ornB.normalize();
+ impactTransB.setRotation(ornB);
+
+ //now transform A
+ SimdTransform a2s,a2b;
+ a2s.mult( w2s , a2w);
+ a2s= m_screwing.InBetweenTransform(a2s,result.m_fraction);
+ a2s.multInverseLeft(w2s,a2s);
+ a2b.multInverseLeft(b2w, a2s);
+
+ //transform by motion B
+ impactTransA.mult(impactTransB, a2b);
+ //normalize rotation
+ SimdQuaternion orn;
+ impactTransA.getBasis().getRotation(orn);
+ orn.normalize();
+ impactTransA.setBasis(SimdMatrix3x3(orn));
+ }
+ }
+
+/*
+ {
+ const int numvertsB = m_convexB->GetNumVertices();
+ for (int v=0;v<numvertsB;v++)
+ {
+ SimdPoint3 pt;
+ m_convexB->GetVertex(v,pt);
+ pt = impactTransB * pt;
+ char buf[1000];
+
+ if (pt.y() < 0.)
+ {
+ sprintf(buf,"POST ERROR (%d) %.20E,%.20E,%.20E!!!!!!!!!\n",v,pt.x(),pt.y(),pt.z());
+ if (debugFile)
+ fwrite(buf,1,strlen(buf),debugFile);
+ }
+ else
+ {
+ sprintf(buf,"POST %d = %.20E,%.20E,%.20E\n",v,pt.x(),pt.y(),pt.z());
+ if (debugFile)
+ fwrite(buf,1,strlen(buf),debugFile);
+ }
+ }
+ }
+*/
+ return hit;
+}
+
+
diff --git a/extern/bullet/Bullet/NarrowPhaseCollision/BU_CollisionPair.h b/extern/bullet/Bullet/NarrowPhaseCollision/BU_CollisionPair.h
new file mode 100644
index 00000000000..6bc09c21cd5
--- /dev/null
+++ b/extern/bullet/Bullet/NarrowPhaseCollision/BU_CollisionPair.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies.
+ * Erwin Coumans makes no representations about the suitability
+ * of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+*/
+
+#ifndef BU_COLLISIONPAIR
+#define BU_COLLISIONPAIR
+
+#include <NarrowPhaseCollision/BU_Screwing.h>
+#include <NarrowPhaseCollision/ConvexCast.h>
+
+
+#include <SimdQuaternion.h>
+
+class PolyhedralConvexShape;
+
+
+///BU_CollisionPair implements collision algorithm for algebraic time of impact calculation of feature based shapes.
+class BU_CollisionPair : public ConvexCast
+{
+
+public:
+ BU_CollisionPair(const PolyhedralConvexShape* convexA,const PolyhedralConvexShape* convexB,SimdScalar tolerance=0.2f);
+ //toi
+
+ virtual bool calcTimeOfImpact(
+ const SimdTransform& fromA,
+ const SimdTransform& toA,
+ const SimdTransform& fromB,
+ const SimdTransform& toB,
+ CastResult& result);
+
+
+
+
+private:
+ const PolyhedralConvexShape* m_convexA;
+ const PolyhedralConvexShape* m_convexB;
+ BU_Screwing m_screwing;
+ SimdScalar m_tolerance;
+
+};
+#endif //BU_COLLISIONPAIR
diff --git a/extern/bullet/Bullet/NarrowPhaseCollision/BU_EdgeEdge.cpp b/extern/bullet/Bullet/NarrowPhaseCollision/BU_EdgeEdge.cpp
new file mode 100644
index 00000000000..26a4fe74fbf
--- /dev/null
+++ b/extern/bullet/Bullet/NarrowPhaseCollision/BU_EdgeEdge.cpp
@@ -0,0 +1,573 @@
+/*
+ * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies.
+ * Erwin Coumans makes no representations about the suitability
+ * of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+*/
+
+#include "BU_EdgeEdge.h"
+#include "BU_Screwing.h"
+#include <SimdPoint3.h>
+#include <SimdPoint3.h>
+
+//#include "BU_IntervalArithmeticPolynomialSolver.h"
+#include "BU_AlgebraicPolynomialSolver.h"
+
+#define USE_ALGEBRAIC
+#ifdef USE_ALGEBRAIC
+#define BU_Polynomial BU_AlgebraicPolynomialSolver
+#else
+#define BU_Polynomial BU_IntervalArithmeticPolynomialSolver
+#endif
+
+BU_EdgeEdge::BU_EdgeEdge()
+{
+}
+
+
+bool BU_EdgeEdge::GetTimeOfImpact(
+ const BU_Screwing& screwAB,
+ const SimdPoint3& a,//edge in object A
+ const SimdVector3& u,
+ const SimdPoint3& c,//edge in object B
+ const SimdVector3& v,
+ SimdScalar &minTime,
+ SimdScalar &lambda1,
+ SimdScalar& mu1
+
+ )
+{
+ bool hit=false;
+
+ SimdScalar lambda;
+ SimdScalar mu;
+
+ const SimdScalar w=screwAB.GetW();
+ const SimdScalar s=screwAB.GetS();
+
+ if (SimdFuzzyZero(s) &&
+ SimdFuzzyZero(w))
+ {
+ //no motion, no collision
+ return false;
+ }
+
+ if (SimdFuzzyZero(w) )
+ {
+ //pure translation W=0, S <> 0
+ //no trig, f(t)=t
+ SimdScalar det = u.y()*v.x()-u.x()*v.y();
+ if (!SimdFuzzyZero(det))
+ {
+ lambda = (a.x()*v.y() - c.x() * v.y() - v.x() * a.y() + v.x() * c.y()) / det;
+ mu = (u.y() * a.x() - u.y() * c.x() - u.x() * a.y() + u.x() * c.y()) / det;
+
+ if (mu >=0 && mu <= 1 && lambda >= 0 && lambda <= 1)
+ {
+ // single potential collision is
+ SimdScalar t = (c.z()-a.z()+mu*v.z()-lambda*u.z())/s;
+ //if this is on the edge, and time t within [0..1] report hit
+ if (t>=0 && t <= minTime)
+ {
+ hit = true;
+ lambda1 = lambda;
+ mu1 = mu;
+ minTime=t;
+ }
+ }
+
+ } else
+ {
+ //parallel case, not yet
+ }
+ } else
+ {
+ if (SimdFuzzyZero(s) )
+ {
+ if (SimdFuzzyZero(u.z()) )
+ {
+ if (SimdFuzzyZero(v.z()) )
+ {
+ //u.z()=0,v.z()=0
+ if (SimdFuzzyZero(a.z()-c.z()))
+ {
+ //printf("NOT YET planar problem, 4 vertex=edge cases\n");
+
+ } else
+ {
+ //printf("parallel but distinct planes, no collision\n");
+ return false;
+ }
+
+ } else
+ {
+ SimdScalar mu = (a.z() - c.z())/v.z();
+ if (0<=mu && mu <= 1)
+ {
+ // printf("NOT YET//u.z()=0,v.z()<>0\n");
+ } else
+ {
+ return false;
+ }
+
+ }
+ } else
+ {
+ //u.z()<>0
+
+ if (SimdFuzzyZero(v.z()) )
+ {
+ //printf("u.z()<>0,v.z()=0\n");
+ lambda = (c.z() - a.z())/u.z();
+ if (0<=lambda && lambda <= 1)
+ {
+ //printf("u.z()<>0,v.z()=0\n");
+ SimdPoint3 rotPt(a.x()+lambda * u.x(), a.y()+lambda * u.y(),0.f);
+ SimdScalar r2 = rotPt.length2();//px*px + py*py;
+
+ //either y=a*x+b, or x = a*x+b...
+ //depends on whether value v.x() is zero or not
+ SimdScalar aa;
+ SimdScalar bb;
+
+ if (SimdFuzzyZero(v.x()))
+ {
+ aa = v.x()/v.y();
+ bb= c.x()+ (-c.y() /v.y()) *v.x();
+ } else
+ {
+ //line is c+mu*v;
+ //x = c.x()+mu*v.x();
+ //mu = ((x-c.x())/v.x());
+ //y = c.y()+((x-c.x())/v.x())*v.y();
+ //y = c.y()+ (-c.x() /v.x()) *v.y() + (x /v.x()) *v.y();
+ //y = a*x+b,where a = v.y()/v.x(), b= c.y()+ (-c.x() /v.x()) *v.y();
+ aa = v.y()/v.x();
+ bb= c.y()+ (-c.x() /v.x()) *v.y();
+ }
+
+ SimdScalar disc = aa*aa*r2 + r2 - bb*bb;
+ if (disc <0)
+ {
+ //edge doesn't intersect the circle (motion of the vertex)
+ return false;
+ }
+ SimdScalar rad = sqrtf(r2);
+
+ if (SimdFuzzyZero(disc))
+ {
+ SimdPoint3 intersectPt;
+
+ SimdScalar mu;
+ //intersectionPoint edge with circle;
+ if (SimdFuzzyZero(v.x()))
+ {
+ intersectPt.setY( (-2*aa*bb)/(2*(aa*aa+1)));
+ intersectPt.setX( aa*intersectPt.y()+bb );
+ mu = ((intersectPt.y()-c.y())/v.y());
+ } else
+ {
+ intersectPt.setX((-2*aa*bb)/(2*(aa*aa+1)));
+ intersectPt.setY(aa*intersectPt.x()+bb);
+ mu = ((intersectPt.getX()-c.getX())/v.getX());
+
+ }
+
+ if (0 <= mu && mu <= 1)
+ {
+ hit = Calc2DRotationPointPoint(rotPt,rad,screwAB.GetW(),intersectPt,minTime);
+ }
+ //only one solution
+ } else
+ {
+ //two points...
+ //intersectionPoint edge with circle;
+ SimdPoint3 intersectPt;
+ //intersectionPoint edge with circle;
+ if (SimdFuzzyZero(v.x()))
+ {
+ SimdScalar mu;
+
+ intersectPt.setY((-2.f*aa*bb+2.f*sqrtf(disc))/(2.f*(aa*aa+1.f)));
+ intersectPt.setX(aa*intersectPt.y()+bb);
+ mu = ((intersectPt.getY()-c.getY())/v.getY());
+ if (0.f <= mu && mu <= 1.f)
+ {
+ hit = Calc2DRotationPointPoint(rotPt,rad,screwAB.GetW(),intersectPt,minTime);
+ }
+ intersectPt.setY((-2.f*aa*bb-2.f*sqrtf(disc))/(2.f*(aa*aa+1.f)));
+ intersectPt.setX(aa*intersectPt.y()+bb);
+ mu = ((intersectPt.getY()-c.getY())/v.getY());
+ if (0 <= mu && mu <= 1)
+ {
+ hit = hit || Calc2DRotationPointPoint(rotPt,rad,screwAB.GetW(),intersectPt,minTime);
+ }
+
+ } else
+ {
+ SimdScalar mu;
+
+ intersectPt.setX((-2.f*aa*bb+2.f*sqrtf(disc))/(2*(aa*aa+1.f)));
+ intersectPt.setY(aa*intersectPt.x()+bb);
+ mu = ((intersectPt.getX()-c.getX())/v.getX());
+ if (0 <= mu && mu <= 1)
+ {
+ hit = Calc2DRotationPointPoint(rotPt,rad,screwAB.GetW(),intersectPt,minTime);
+ }
+ intersectPt.setX((-2.f*aa*bb-2.f*sqrtf(disc))/(2.f*(aa*aa+1.f)));
+ intersectPt.setY(aa*intersectPt.x()+bb);
+ mu = ((intersectPt.getX()-c.getX())/v.getX());
+ if (0.f <= mu && mu <= 1.f)
+ {
+ hit = hit || Calc2DRotationPointPoint(rotPt,rad,screwAB.GetW(),intersectPt,minTime);
+ }
+ }
+ }
+
+
+
+ int k=0;
+
+ } else
+ {
+ return false;
+ }
+
+
+ } else
+ {
+ //u.z()<>0,v.z()<>0
+ //printf("general case with s=0\n");
+ hit = GetTimeOfImpactGeneralCase(screwAB,a,u,c,v,minTime,lambda,mu);
+ if (hit)
+ {
+ lambda1 = lambda;
+ mu1 = mu;
+
+ }
+ }
+ }
+
+ } else
+ {
+ //printf("general case, W<>0,S<>0\n");
+ hit = GetTimeOfImpactGeneralCase(screwAB,a,u,c,v,minTime,lambda,mu);
+ if (hit)
+ {
+ lambda1 = lambda;
+ mu1 = mu;
+ }
+
+ }
+
+
+ //W <> 0,pure rotation
+ }
+
+ return hit;
+}
+
+
+bool BU_EdgeEdge::GetTimeOfImpactGeneralCase(
+ const BU_Screwing& screwAB,
+ const SimdPoint3& a,//edge in object A
+ const SimdVector3& u,
+ const SimdPoint3& c,//edge in object B
+ const SimdVector3& v,
+ SimdScalar &minTime,
+ SimdScalar &lambda,
+ SimdScalar& mu
+
+ )
+{
+ bool hit = false;
+
+ SimdScalar coefs[4];
+ BU_Polynomial polynomialSolver;
+ int numroots = 0;
+
+ SimdScalar eps=1e-15f;
+ SimdScalar eps2=1e-20f;
+ SimdScalar s=screwAB.GetS();
+ SimdScalar w = screwAB.GetW();
+
+ SimdScalar ax = a.x();
+ SimdScalar ay = a.y();
+ SimdScalar az = a.z();
+ SimdScalar cx = c.x();
+ SimdScalar cy = c.y();
+ SimdScalar cz = c.z();
+ SimdScalar vx = v.x();
+ SimdScalar vy = v.y();
+ SimdScalar vz = v.z();
+ SimdScalar ux = u.x();
+ SimdScalar uy = u.y();
+ SimdScalar uz = u.z();
+
+
+ if (!SimdFuzzyZero(v.z()))
+ {
+
+ //Maple Autogenerated C code
+ SimdScalar t1,t2,t3,t4,t7,t8,t10;
+ SimdScalar t13,t14,t15,t16,t17,t18,t19,t20;
+ SimdScalar t21,t22,t23,t24,t25,t26,t27,t28,t29,t30;
+ SimdScalar t31,t32,t33,t34,t35,t36,t39,t40;
+ SimdScalar t41,t43,t48;
+ SimdScalar t63;
+
+ SimdScalar aa,bb,cc,dd;//the coefficients
+
+ t1 = v.y()*s; t2 = t1*u.x();
+ t3 = v.x()*s;
+ t4 = t3*u.y();
+ t7 = tanf(w/2.0f);
+ t8 = 1.0f/t7;
+ t10 = 1.0f/v.z();
+ aa = (t2-t4)*t8*t10;
+ t13 = a.x()*t7;
+ t14 = u.z()*v.y();
+ t15 = t13*t14;
+ t16 = u.x()*v.z();
+ t17 = a.y()*t7;
+ t18 = t16*t17;
+ t19 = u.y()*v.z();
+ t20 = t13*t19;
+ t21 = v.y()*u.x();
+ t22 = c.z()*t7;
+ t23 = t21*t22;
+ t24 = v.x()*a.z();
+ t25 = t7*u.y();
+ t26 = t24*t25;
+ t27 = c.y()*t7;
+ t28 = t16*t27;
+ t29 = a.z()*t7;
+ t30 = t21*t29;
+ t31 = u.z()*v.x();
+ t32 = t31*t27;
+ t33 = t31*t17;
+ t34 = c.x()*t7;
+ t35 = t34*t19;
+ t36 = t34*t14;
+ t39 = v.x()*c.z();
+ t40 = t39*t25;
+ t41 = 2.0f*t1*u.y()-t15+t18-t20-t23-t26+t28+t30+t32+t33-t35-t36+2.0f*t3*u.x()+t40;
+ bb = t41*t8*t10;
+ t43 = t7*u.x();
+ t48 = u.y()*v.y();
+ cc = (-2.0f*t39*t43+2.0f*t24*t43+t4-2.0f*t48*t22+2.0f*t34*t16-2.0f*t31*t13-t2
+ -2.0f*t17*t14+2.0f*t19*t27+2.0f*t48*t29)*t8*t10;
+ t63 = -t36+t26+t32-t40+t23+t35-t20+t18-t28-t33+t15-t30;
+ dd = t63*t8*t10;
+
+ coefs[0]=aa;
+ coefs[1]=bb;
+ coefs[2]=cc;
+ coefs[3]=dd;
+
+ } else
+ {
+
+ SimdScalar t1,t2,t3,t4,t7,t8,t10;
+ SimdScalar t13,t14,t15,t16,t17,t18,t19,t20;
+ SimdScalar t21,t22,t23,t24,t25,t26,t27,t28,t29,t30;
+ SimdScalar t31,t32,t33,t34,t35,t36,t37,t38,t57;
+ SimdScalar p1,p2,p3,p4;
+
+ t1 = uy*s;
+ t2 = t1*vx;
+ t3 = ux*s;
+ t4 = t3*vy;
+ t7 = tanf(w/2.0f);
+ t8 = 1/t7;
+ t10 = 1/uz;
+ t13 = ux*az;
+ t14 = t7*vy;
+ t15 = t13*t14;
+ t16 = ax*t7;
+ t17 = uy*vz;
+ t18 = t16*t17;
+ t19 = cx*t7;
+ t20 = t19*t17;
+ t21 = vy*uz;
+ t22 = t19*t21;
+ t23 = ay*t7;
+ t24 = vx*uz;
+ t25 = t23*t24;
+ t26 = uy*cz;
+ t27 = t7*vx;
+ t28 = t26*t27;
+ t29 = t16*t21;
+ t30 = cy*t7;
+ t31 = ux*vz;
+ t32 = t30*t31;
+ t33 = ux*cz;
+ t34 = t33*t14;
+ t35 = t23*t31;
+ t36 = t30*t24;
+ t37 = uy*az;
+ t38 = t37*t27;
+
+ p4 = (-t2+t4)*t8*t10;
+ p3 = 2.0f*t1*vy+t15-t18-t20-t22+t25+t28-t29+t32-t34+t35+t36-t38+2.0f*t3*vx;
+ p2 = -2.0f*t33*t27-2.0f*t26*t14-2.0f*t23*t21+2.0f*t37*t14+2.0f*t30*t17+2.0f*t13
+*t27+t2-t4+2.0f*t19*t31-2.0f*t16*t24;
+ t57 = -t22+t29+t36-t25-t32+t34+t35-t28-t15+t20-t18+t38;
+ p1 = t57*t8*t10;
+
+ coefs[0] = p4;
+ coefs[1] = p3;
+ coefs[2] = p2;
+ coefs[1] = p1;
+
+ }
+
+ numroots = polynomialSolver.Solve3Cubic(coefs[0],coefs[1],coefs[2],coefs[3]);
+
+ for (int i=0;i<numroots;i++)
+ {
+ //SimdScalar tau = roots[i];//polynomialSolver.GetRoot(i);
+ SimdScalar tau = polynomialSolver.GetRoot(i);
+
+ //check whether mu and lambda are in range [0..1]
+
+ if (!SimdFuzzyZero(v.z()))
+ {
+ SimdScalar A1=(ux-ux*tau*tau-2.f*tau*uy)-((1.f+tau*tau)*vx*uz/vz);
+ SimdScalar B1=((1.f+tau*tau)*(cx*tanf(1.f/2.f*w)*vz+
+ vx*az*tanf(1.f/2.f*w)-vx*cz*tanf(1.f/2.f*w)+
+ vx*s*tau)/tanf(1.f/2.f*w)/vz)-(ax-ax*tau*tau-2.f*tau*ay);
+ lambda = B1/A1;
+
+ mu = (a.z()-c.z()+lambda*u.z()+(s*tau)/(tanf(w/2.f)))/v.z();
+
+
+ //double check in original equation
+
+ SimdScalar lhs = (a.x()+lambda*u.x())
+ *((1.f-tau*tau)/(1.f+tau*tau))-
+ (a.y()+lambda*u.y())*((2.f*tau)/(1.f+tau*tau));
+
+ lhs = lambda*((ux-ux*tau*tau-2.f*tau*uy)-((1.f+tau*tau)*vx*uz/vz));
+
+ SimdScalar rhs = c.x()+mu*v.x();
+
+ rhs = ((1.f+tau*tau)*(cx*tanf(1.f/2.f*w)*vz+vx*az*tanf(1.f/2.f*w)-
+ vx*cz*tanf(1.f/2.f*w)+vx*s*tau)/(tanf(1.f/2.f*w)*vz))-
+
+ (ax-ax*tau*tau-2.f*tau*ay);
+
+ SimdScalar res = coefs[0]*tau*tau*tau+
+ coefs[1]*tau*tau+
+ coefs[2]*tau+
+ coefs[3];
+
+ //lhs should be rhs !
+
+ if (0.<= mu && mu <=1 && 0.<=lambda && lambda <= 1)
+ {
+
+ } else
+ {
+ //skip this solution, not really touching
+ continue;
+ }
+
+ }
+
+ SimdScalar t = 2.f*atanf(tau)/screwAB.GetW();
+ //tau = tan (wt/2) so 2*atan (tau)/w
+ if (t>=0.f && t<minTime)
+ {
+#ifdef STATS_EDGE_EDGE
+ printf(" ax = %12.12f\n ay = %12.12f\n az = %12.12f\n",a.x(),a.y(),a.z());
+ printf(" ux = %12.12f\n uy = %12.12f\n uz = %12.12f\n",u.x(),u.y(),u.z());
+ printf(" cx = %12.12f\n cy = %12.12f\n cz = %12.12f\n",c.x(),c.y(),c.z());
+ printf(" vx = %12.12f\n vy = %12.12f\n vz = %12.12f\n",v.x(),v.y(),v.z());
+ printf(" s = %12.12f\n w = %12.12f\n", s, w);
+
+ printf(" tau = %12.12f \n lambda = %12.12f \n mu = %f\n",tau,lambda,mu);
+ printf(" ---------------------------------------------\n");
+
+#endif
+
+ // v,u,a,c,s,w
+
+ // BU_IntervalArithmeticPolynomialSolver iaSolver;
+ // int numroots2 = iaSolver.Solve3Cubic(coefs[0],coefs[1],coefs[2],coefs[3]);
+
+ minTime = t;
+ hit = true;
+ }
+ }
+
+ return hit;
+}
+
+
+//C -S
+//S C
+
+bool BU_EdgeEdge::Calc2DRotationPointPoint(const SimdPoint3& rotPt, SimdScalar rotRadius, SimdScalar rotW,const SimdPoint3& intersectPt,SimdScalar& minTime)
+{
+ bool hit = false;
+
+ // now calculate the planeEquation for the vertex motion,
+ // and check if the intersectionpoint is at the positive side
+ SimdPoint3 rotPt1(cosf(rotW)*rotPt.x()-sinf(rotW)*rotPt.y(),
+ sinf(rotW)*rotPt.x()+cosf(rotW)*rotPt.y(),
+ 0.f);
+
+ SimdVector3 rotVec = rotPt1-rotPt;
+
+ SimdVector3 planeNormal( -rotVec.y() , rotVec.x() ,0.f);
+
+ //SimdPoint3 pt(a.x(),a.y());//for sake of readability,could write dot directly
+ SimdScalar planeD = planeNormal.dot(rotPt1);
+
+ SimdScalar dist = (planeNormal.dot(intersectPt)-planeD);
+ hit = (dist >= -0.001);
+
+ //if (hit)
+ {
+ // minTime = 0;
+ //calculate the time of impact, using the fact of
+ //toi = alpha / screwAB.getW();
+ // cos (alpha) = adjacent/hypothenuse;
+ //adjacent = dotproduct(ipedge,point);
+ //hypothenuse = sqrt(r2);
+ SimdScalar adjacent = intersectPt.dot(rotPt)/rotRadius;
+ SimdScalar hypo = rotRadius;
+ SimdScalar alpha = acosf(adjacent/hypo);
+ SimdScalar t = alpha / rotW;
+ if (t >= 0 && t < minTime)
+ {
+ hit = true;
+ minTime = t;
+ } else
+ {
+ hit = false;
+ }
+
+ }
+ return hit;
+}
+
+bool BU_EdgeEdge::GetTimeOfImpactVertexEdge(
+ const BU_Screwing& screwAB,
+ const SimdPoint3& a,//edge in object A
+ const SimdVector3& u,
+ const SimdPoint3& c,//edge in object B
+ const SimdVector3& v,
+ SimdScalar &minTime,
+ SimdScalar &lamda,
+ SimdScalar& mu
+
+ )
+{
+ return false;
+}
diff --git a/extern/bullet/Bullet/NarrowPhaseCollision/BU_EdgeEdge.h b/extern/bullet/Bullet/NarrowPhaseCollision/BU_EdgeEdge.h
new file mode 100644
index 00000000000..32eed8bc898
--- /dev/null
+++ b/extern/bullet/Bullet/NarrowPhaseCollision/BU_EdgeEdge.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies.
+ * Erwin Coumans makes no representations about the suitability
+ * of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+*/
+
+#ifndef BU_EDGEEDGE
+#define BU_EDGEEDGE
+
+class BU_Screwing;
+#include <SimdTransform.h>
+#include <SimdPoint3.h>
+#include <SimdVector3.h>
+
+//class BUM_Point2;
+
+#include <SimdScalar.h>
+
+///BU_EdgeEdge implements algebraic time of impact calculation between two (angular + linear) moving edges.
+class BU_EdgeEdge
+{
+public:
+
+
+ BU_EdgeEdge();
+ bool GetTimeOfImpact(
+ const BU_Screwing& screwAB,
+ const SimdPoint3& a,//edge in object A
+ const SimdVector3& u,
+ const SimdPoint3& c,//edge in object B
+ const SimdVector3& v,
+ SimdScalar &minTime,
+ SimdScalar &lamda,
+ SimdScalar& mu
+ );
+private:
+
+ bool Calc2DRotationPointPoint(const SimdPoint3& rotPt, SimdScalar rotRadius, SimdScalar rotW,const SimdPoint3& intersectPt,SimdScalar& minTime);
+ bool GetTimeOfImpactGeneralCase(
+ const BU_Screwing& screwAB,
+ const SimdPoint3& a,//edge in object A
+ const SimdVector3& u,
+ const SimdPoint3& c,//edge in object B
+ const SimdVector3& v,
+ SimdScalar &minTime,
+ SimdScalar &lamda,
+ SimdScalar& mu
+
+ );
+
+
+ bool GetTimeOfImpactVertexEdge(
+ const BU_Screwing& screwAB,
+ const SimdPoint3& a,//edge in object A
+ const SimdVector3& u,
+ const SimdPoint3& c,//edge in object B
+ const SimdVector3& v,
+ SimdScalar &minTime,
+ SimdScalar &lamda,
+ SimdScalar& mu
+
+ );
+
+};
+
+#endif //BU_EDGEEDGE
diff --git a/extern/bullet/Bullet/NarrowPhaseCollision/BU_MotionStateInterface.h b/extern/bullet/Bullet/NarrowPhaseCollision/BU_MotionStateInterface.h
new file mode 100644
index 00000000000..637271511e2
--- /dev/null
+++ b/extern/bullet/Bullet/NarrowPhaseCollision/BU_MotionStateInterface.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies.
+ * Erwin Coumans makes no representations about the suitability
+ * of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+*/
+
+#ifndef BU_MOTIONSTATE
+#define BU_MOTIONSTATE
+
+
+#include <SimdTransform.h>
+#include <SimdPoint3.h>
+#include <SimdQuaternion.h>
+
+class BU_MotionStateInterface
+{
+public:
+ virtual ~BU_MotionStateInterface(){};
+
+ virtual void SetTransform(const SimdTransform& trans) = 0;
+ virtual void GetTransform(SimdTransform& trans) const = 0;
+
+ virtual void SetPosition(const SimdPoint3& position) = 0;
+ virtual void GetPosition(SimdPoint3& position) const = 0;
+
+ virtual void SetOrientation(const SimdQuaternion& orientation) = 0;
+ virtual void GetOrientation(SimdQuaternion& orientation) const = 0;
+
+ virtual void SetBasis(const SimdMatrix3x3& basis) = 0;
+ virtual void GetBasis(SimdMatrix3x3& basis) const = 0;
+
+ virtual void SetLinearVelocity(const SimdVector3& linvel) = 0;
+ virtual void GetLinearVelocity(SimdVector3& linvel) const = 0;
+
+ virtual void GetAngularVelocity(SimdVector3& angvel) const = 0;
+ virtual void SetAngularVelocity(const SimdVector3& angvel) = 0;
+
+};
+
+#endif //BU_MOTIONSTATE
diff --git a/extern/bullet/Bullet/NarrowPhaseCollision/BU_PolynomialSolverInterface.h b/extern/bullet/Bullet/NarrowPhaseCollision/BU_PolynomialSolverInterface.h
new file mode 100644
index 00000000000..4926acaf824
--- /dev/null
+++ b/extern/bullet/Bullet/NarrowPhaseCollision/BU_PolynomialSolverInterface.h
@@ -0,0 +1,26 @@
+
+#ifndef BUM_POLYNOMIAL_SOLVER_INTERFACE
+#define BUM_POLYNOMIAL_SOLVER_INTERFACE
+
+#include <SimdScalar.h>
+//
+//BUM_PolynomialSolverInterface is interface class for polynomial root finding.
+//The number of roots is returned as a result, query GetRoot to get the actual solution.
+//
+class BUM_PolynomialSolverInterface
+{
+public:
+ virtual ~BUM_PolynomialSolverInterface() {};
+
+
+// virtual int Solve2QuadraticFull(SimdScalar a,SimdScalar b, SimdScalar c) = 0;
+
+ virtual int Solve3Cubic(SimdScalar lead, SimdScalar a, SimdScalar b, SimdScalar c) = 0;
+
+ virtual int Solve4Quartic(SimdScalar lead, SimdScalar a, SimdScalar b, SimdScalar c, SimdScalar d) = 0;
+
+ virtual SimdScalar GetRoot(int i) const = 0;
+
+};
+
+#endif //BUM_POLYNOMIAL_SOLVER_INTERFACE
diff --git a/extern/bullet/Bullet/NarrowPhaseCollision/BU_Screwing.cpp b/extern/bullet/Bullet/NarrowPhaseCollision/BU_Screwing.cpp
new file mode 100644
index 00000000000..f347dc4b49a
--- /dev/null
+++ b/extern/bullet/Bullet/NarrowPhaseCollision/BU_Screwing.cpp
@@ -0,0 +1,197 @@
+/*
+ * Copyright (c) 2005 Stephane Redon / Erwin Coumans http://www.erwincoumans.com
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies.
+ * Erwin Coumans makes no representations about the suitability
+ * of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+*/
+
+#include "BU_Screwing.h"
+
+
+
+
+
+BU_Screwing::BU_Screwing(const SimdVector3& relLinVel,const SimdVector3& relAngVel) {
+
+
+ const SimdScalar dx=relLinVel[0];
+ const SimdScalar dy=relLinVel[1];
+ const SimdScalar dz=relLinVel[2];
+ const SimdScalar wx=relAngVel[0];
+ const SimdScalar wy=relAngVel[1];
+ const SimdScalar wz=relAngVel[2];
+
+ // Compute the screwing parameters :
+ // w : total amount of rotation
+ // s : total amount of translation
+ // u : vector along the screwing axis (||u||=1)
+ // o : point on the screwing axis
+
+ m_w=sqrtf(wx*wx+wy*wy+wz*wz);
+ //if (!w) {
+ if (fabs(m_w)<SCREWEPSILON ) {
+
+ assert(m_w == 0.f);
+
+ m_w=0.;
+ m_s=sqrtf(dx*dx+dy*dy+dz*dz);
+ if (fabs(m_s)<SCREWEPSILON ) {
+ assert(m_s == 0.);
+
+ m_s=0.;
+ m_u=SimdPoint3(0.,0.,1.);
+ m_o=SimdPoint3(0.,0.,0.);
+ }
+ else {
+ float t=1.f/m_s;
+ m_u=SimdPoint3(dx*t,dy*t,dz*t);
+ m_o=SimdPoint3(0.f,0.f,0.f);
+ }
+ }
+ else { // there is some rotation
+
+ // we compute u
+
+ float v(1.f/m_w);
+ m_u=SimdPoint3(wx*v,wy*v,wz*v); // normalization
+
+ // decomposition of the translation along u and one orthogonal vector
+
+ SimdPoint3 t(dx,dy,dz);
+ m_s=t.dot(m_u); // component along u
+ if (fabs(m_s)<SCREWEPSILON)
+ {
+ //printf("m_s component along u < SCREWEPSILION\n");
+ m_s=0.f;
+ }
+ SimdPoint3 n1(t-(m_s*m_u)); // the remaining part (which is orthogonal to u)
+
+ // now we have to compute o
+
+ SimdScalar len = n1.length2();
+ //(len >= BUM_EPSILON2) {
+ if (n1[0] || n1[1] || n1[2]) { // n1 is not the zero vector
+ n1.normalize();
+ SimdVector3 n1orth=m_u.cross(n1);
+
+ float n2x=cosf(0.5f*m_w);
+ float n2y=sinf(0.5f*m_w);
+
+ m_o=0.5f*t.dot(n1)*(n1+n2x/n2y*n1orth);
+ }
+ else
+ {
+ m_o=SimdPoint3(0.f,0.f,0.f);
+ }
+
+ }
+
+}
+
+//Then, I need to compute Pa, the matrix from the reference (global) frame to
+//the screwing frame :
+
+
+void BU_Screwing::LocalMatrix(SimdTransform &t) const {
+//So the whole computations do this : align the Oz axis along the
+// screwing axis (thanks to u), and then find two others orthogonal axes to
+// complete the basis.
+
+ if ((m_u[0]>SCREWEPSILON)||(m_u[0]<-SCREWEPSILON)||(m_u[1]>SCREWEPSILON)||(m_u[1]<-SCREWEPSILON))
+ {
+ // to avoid numerical problems
+ float n=sqrtf(m_u[0]*m_u[0]+m_u[1]*m_u[1]);
+ float invn=1.0f/n;
+ SimdMatrix3x3 mat;
+
+ mat[0][0]=-m_u[1]*invn;
+ mat[0][1]=m_u[0]*invn;
+ mat[0][2]=0.f;
+
+ mat[1][0]=-m_u[0]*invn*m_u[2];
+ mat[1][1]=-m_u[1]*invn*m_u[2];
+ mat[1][2]=n;
+
+ mat[2][0]=m_u[0];
+ mat[2][1]=m_u[1];
+ mat[2][2]=m_u[2];
+
+ t.setOrigin(SimdPoint3(
+ m_o[0]*m_u[1]*invn-m_o[1]*m_u[0]*invn,
+ -(m_o[0]*mat[1][0]+m_o[1]*mat[1][1]+m_o[2]*n),
+ -(m_o[0]*m_u[0]+m_o[1]*m_u[1]+m_o[2]*m_u[2])));
+
+ t.setBasis(mat);
+
+ }
+ else {
+
+ SimdMatrix3x3 m;
+
+ m[0][0]=1.;
+ m[1][0]=0.;
+ m[2][0]=0.;
+
+ m[0][1]=0.f;
+ m[1][1]=float(SimdSign(m_u[2]));
+ m[2][1]=0.f;
+
+ m[0][2]=0.f;
+ m[1][2]=0.f;
+ m[2][2]=float(SimdSign(m_u[2]));
+
+ t.setOrigin(SimdPoint3(
+ -m_o[0],
+ -SimdSign(m_u[2])*m_o[1],
+ -SimdSign(m_u[2])*m_o[2]
+ ));
+ t.setBasis(m);
+
+ }
+}
+
+//gives interpolated transform for time in [0..1] in screwing frame
+SimdTransform BU_Screwing::InBetweenTransform(const SimdTransform& tr,SimdScalar t) const
+{
+ SimdPoint3 org = tr.getOrigin();
+
+ SimdPoint3 neworg (
+ org.x()*cosf(m_w*t)-org.y()*sinf(m_w*t),
+ org.x()*sinf(m_w*t)+org.y()*cosf(m_w*t),
+ org.z()+m_s*CalculateF(t));
+
+ SimdTransform newtr;
+ newtr.setOrigin(neworg);
+ SimdMatrix3x3 basis = tr.getBasis();
+ SimdMatrix3x3 basisorg = tr.getBasis();
+
+ SimdQuaternion rot(SimdVector3(0.,0.,1.),m_w*t);
+ SimdQuaternion tmpOrn;
+ tr.getBasis().getRotation(tmpOrn);
+ rot = rot * tmpOrn;
+
+ //to avoid numerical drift, normalize quaternion
+ rot.normalize();
+ newtr.setBasis(SimdMatrix3x3(rot));
+ return newtr;
+
+}
+
+
+SimdScalar BU_Screwing::CalculateF(SimdScalar t) const
+{
+ SimdScalar result;
+ if (!m_w)
+ {
+ result = t;
+ } else
+ {
+ result = ( tanf((m_w*t)/2.f) / tanf(m_w/2.f));
+ }
+ return result;
+}
+
diff --git a/extern/bullet/Bullet/NarrowPhaseCollision/BU_Screwing.h b/extern/bullet/Bullet/NarrowPhaseCollision/BU_Screwing.h
new file mode 100644
index 00000000000..09cf049d2f8
--- /dev/null
+++ b/extern/bullet/Bullet/NarrowPhaseCollision/BU_Screwing.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies.
+ * Erwin Coumans makes no representations about the suitability
+ * of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+*/
+
+#ifndef B_SCREWING_H
+#define B_SCREWING_H
+
+
+#include <SimdVector3.h>
+#include <SimdPoint3.h>
+#include <SimdTransform.h>
+
+
+#define SCREWEPSILON 0.00001f
+
+///BU_Screwing implements screwing motion interpolation.
+class BU_Screwing
+{
+public:
+
+
+ BU_Screwing(const SimdVector3& relLinVel,const SimdVector3& relAngVel);
+
+ ~BU_Screwing() {
+ };
+
+ SimdScalar CalculateF(SimdScalar t) const;
+ //gives interpolated position for time in [0..1] in screwing frame
+
+ inline SimdPoint3 InBetweenPosition(const SimdPoint3& pt,SimdScalar t) const
+ {
+ return SimdPoint3(
+ pt.x()*cosf(m_w*t)-pt.y()*sinf(m_w*t),
+ pt.x()*sinf(m_w*t)+pt.y()*cosf(m_w*t),
+ pt.z()+m_s*CalculateF(t));
+ }
+
+ inline SimdVector3 InBetweenVector(const SimdVector3& vec,SimdScalar t) const
+ {
+ return SimdVector3(
+ vec.x()*cosf(m_w*t)-vec.y()*sinf(m_w*t),
+ vec.x()*sinf(m_w*t)+vec.y()*cosf(m_w*t),
+ vec.z());
+ }
+
+ //gives interpolated transform for time in [0..1] in screwing frame
+ SimdTransform InBetweenTransform(const SimdTransform& tr,SimdScalar t) const;
+
+
+ //gives matrix from global frame into screwing frame
+ void LocalMatrix(SimdTransform &t) const;
+
+ inline const SimdVector3& GetU() const { return m_u;}
+ inline const SimdVector3& GetO() const {return m_o;}
+ inline const SimdScalar GetS() const{ return m_s;}
+ inline const SimdScalar GetW() const { return m_w;}
+
+private:
+ float m_w;
+ float m_s;
+ SimdVector3 m_u;
+ SimdVector3 m_o;
+};
+
+#endif //B_SCREWING_H
diff --git a/extern/bullet/Bullet/NarrowPhaseCollision/BU_StaticMotionState.h b/extern/bullet/Bullet/NarrowPhaseCollision/BU_StaticMotionState.h
new file mode 100644
index 00000000000..553fa6fea78
--- /dev/null
+++ b/extern/bullet/Bullet/NarrowPhaseCollision/BU_StaticMotionState.h
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies.
+ * Erwin Coumans makes no representations about the suitability
+ * of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+*/
+
+#ifndef BU_STATIC_MOTIONSTATE
+#define BU_STATIC_MOTIONSTATE
+
+
+#include <CollisionShapes/BU_MotionStateInterface.h>
+
+class BU_StaticMotionState :public BU_MotionStateInterface
+{
+public:
+ virtual ~BU_StaticMotionState(){};
+
+ virtual void SetTransform(const SimdTransform& trans)
+ {
+ m_trans = trans;
+ }
+ virtual void GetTransform(SimdTransform& trans) const
+ {
+ trans = m_trans;
+ }
+ virtual void SetPosition(const SimdPoint3& position)
+ {
+ m_trans.setOrigin( position );
+ }
+ virtual void GetPosition(SimdPoint3& position) const
+ {
+ position = m_trans.getOrigin();
+ }
+
+ virtual void SetOrientation(const SimdQuaternion& orientation)
+ {
+ m_trans.setRotation( orientation);
+ }
+ virtual void GetOrientation(SimdQuaternion& orientation) const
+ {
+ orientation = m_trans.getRotation();
+ }
+
+ virtual void SetBasis(const SimdMatrix3x3& basis)
+ {
+ m_trans.setBasis( basis);
+ }
+ virtual void GetBasis(SimdMatrix3x3& basis) const
+ {
+ basis = m_trans.getBasis();
+ }
+
+ virtual void SetLinearVelocity(const SimdVector3& linvel)
+ {
+ m_linearVelocity = linvel;
+ }
+ virtual void GetLinearVelocity(SimdVector3& linvel) const
+ {
+ linvel = m_linearVelocity;
+ }
+
+ virtual void SetAngularVelocity(const SimdVector3& angvel)
+ {
+ m_angularVelocity = angvel;
+ }
+ virtual void GetAngularVelocity(SimdVector3& angvel) const
+ {
+ angvel = m_angularVelocity;
+ }
+
+
+
+protected:
+
+ SimdTransform m_trans;
+ SimdVector3 m_angularVelocity;
+ SimdVector3 m_linearVelocity;
+
+};
+
+#endif //BU_STATIC_MOTIONSTATE
diff --git a/extern/bullet/Bullet/NarrowPhaseCollision/BU_VertexPoly.cpp b/extern/bullet/Bullet/NarrowPhaseCollision/BU_VertexPoly.cpp
new file mode 100644
index 00000000000..8486df701e7
--- /dev/null
+++ b/extern/bullet/Bullet/NarrowPhaseCollision/BU_VertexPoly.cpp
@@ -0,0 +1,154 @@
+/*
+ * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies.
+ * Erwin Coumans makes no representations about the suitability
+ * of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+*/
+
+
+#include "BU_VertexPoly.h"
+#include "BU_Screwing.h"
+#include <SimdTransform.h>
+#include <SimdPoint3.h>
+#include <SimdVector3.h>
+
+#define USE_ALGEBRAIC
+#ifdef USE_ALGEBRAIC
+ #include "BU_AlgebraicPolynomialSolver.h"
+ #define BU_Polynomial BU_AlgebraicPolynomialSolver
+#else
+ #include "BU_IntervalArithmeticPolynomialSolver.h"
+ #define BU_Polynomial BU_IntervalArithmeticPolynomialSolver
+#endif
+
+inline bool TestFuzzyZero(SimdScalar x) { return fabsf(x) < 0.0001f; }
+
+
+BU_VertexPoly::BU_VertexPoly()
+{
+
+}
+//return true if a collision will occur between [0..1]
+//false otherwise. If true, minTime contains the time of impact
+bool BU_VertexPoly::GetTimeOfImpact(
+ const BU_Screwing& screwAB,
+ const SimdPoint3& a,
+ const SimdVector4& planeEq,
+ SimdScalar &minTime,bool swapAB)
+{
+
+ bool hit = false;
+
+ // precondition: s=0 and w= 0 is catched by caller!
+ if (TestFuzzyZero(screwAB.GetS()) &&
+ TestFuzzyZero(screwAB.GetW()))
+ {
+ return false;
+ }
+
+
+ //case w<>0 and s<> 0
+ const SimdScalar w=screwAB.GetW();
+ const SimdScalar s=screwAB.GetS();
+
+ SimdScalar coefs[4];
+ const SimdScalar p=planeEq[0];
+ const SimdScalar q=planeEq[1];
+ const SimdScalar r=planeEq[2];
+ const SimdScalar d=planeEq[3];
+
+ const SimdVector3 norm(p,q,r);
+ BU_Polynomial polynomialSolver;
+ int numroots = 0;
+
+ SimdScalar eps=1e-80f;
+ SimdScalar eps2=1e-100f;
+
+ if (TestFuzzyZero(screwAB.GetS()) )
+ {
+ //S = 0 , W <> 0
+
+ //ax^3+bx^2+cx+d=0
+ coefs[0]=0.;
+ coefs[1]=(-p*a.x()-q*a.y()+r*a.z()-d);
+ coefs[2]=-2*p*a.y()+2*q*a.x();
+ coefs[3]=p*a.x()+q*a.y()+r*a.z()-d;
+
+// numroots = polynomialSolver.Solve3Cubic(coefs[0],coefs[1],coefs[2],coefs[3]);
+ numroots = polynomialSolver.Solve2QuadraticFull(coefs[1],coefs[2],coefs[3]);
+
+ } else
+ {
+ if (TestFuzzyZero(screwAB.GetW()))
+ {
+ // W = 0 , S <> 0
+ //pax+qay+r(az+st)=d
+
+ SimdScalar dist = (d - a.dot(norm));
+
+ if (TestFuzzyZero(r))
+ {
+ if (TestFuzzyZero(dist))
+ {
+ // no hit
+ } else
+ {
+ // todo a a' might hit sides of polygon T
+ //printf("unhandled case, w=0,s<>0,r<>0, a a' might hit sides of polygon T \n");
+ }
+
+ } else
+ {
+ SimdScalar etoi = (dist)/(r*screwAB.GetS());
+ if (swapAB)
+ etoi *= -1;
+
+ if (etoi >= 0. && etoi <= minTime)
+ {
+ minTime = etoi;
+ hit = true;
+ }
+ }
+
+ } else
+ {
+ //ax^3+bx^2+cx+d=0
+
+ //degenerate coefficients mess things up :(
+ SimdScalar ietsje = (r*s)/tanf(w/2.f);
+ if (ietsje*ietsje < 0.01f)
+ ietsje = 0.f;
+
+ coefs[0]=ietsje;//(r*s)/tan(w/2.);
+ coefs[1]=(-p*a.x()-q*a.y()+r*a.z()-d);
+ coefs[2]=-2.f*p*a.y()+2.f*q*a.x()+ietsje;//((r*s)/(tan(w/2.)));
+ coefs[3]=p*a.x()+q*a.y()+r*a.z()-d;
+
+ numroots = polynomialSolver.Solve3Cubic(coefs[0],coefs[1],coefs[2],coefs[3]);
+ }
+ }
+
+
+ for (int i=0;i<numroots;i++)
+ {
+ SimdScalar tau = polynomialSolver.GetRoot(i);
+
+ SimdScalar t = 2.f*atanf(tau)/w;
+ //tau = tan (wt/2) so 2*atan (tau)/w
+ if (swapAB)
+ {
+ t *= -1.;
+ }
+ if (t>=0 && t<minTime)
+ {
+ minTime = t;
+ hit = true;
+ }
+ }
+
+ return hit;
+}
diff --git a/extern/bullet/Bullet/NarrowPhaseCollision/BU_VertexPoly.h b/extern/bullet/Bullet/NarrowPhaseCollision/BU_VertexPoly.h
new file mode 100644
index 00000000000..81c2017542f
--- /dev/null
+++ b/extern/bullet/Bullet/NarrowPhaseCollision/BU_VertexPoly.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies.
+ * Erwin Coumans makes no representations about the suitability
+ * of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+*/
+
+#ifndef VERTEX_POLY_H
+#define VERTEX_POLY_H
+
+
+class BU_Screwing;
+#include <SimdTransform.h>
+#include <SimdPoint3.h>
+#include <SimdScalar.h>
+
+///BU_VertexPoly implements algebraic time of impact calculation between vertex and a plane.
+class BU_VertexPoly
+{
+public:
+ BU_VertexPoly();
+ bool GetTimeOfImpact(
+ const BU_Screwing& screwAB,
+ const SimdPoint3& vtx,
+ const SimdVector4& planeEq,
+ SimdScalar &minTime,
+ bool swapAB);
+
+private:
+
+ //cached data (frame coherency etc.) here
+
+};
+#endif //VERTEX_POLY_H
diff --git a/extern/bullet/Bullet/NarrowPhaseCollision/CollisionMargin.h b/extern/bullet/Bullet/NarrowPhaseCollision/CollisionMargin.h
new file mode 100644
index 00000000000..7e51dc7f2b3
--- /dev/null
+++ b/extern/bullet/Bullet/NarrowPhaseCollision/CollisionMargin.h
@@ -0,0 +1,11 @@
+#ifndef COLLISION_MARGIN_H
+#define COLLISION_MARGIN_H
+
+//used by Gjk and some other algorithms
+
+#define CONVEX_DISTANCE_MARGIN 0.05f// 0.1f//;//0.01f
+
+
+
+#endif //COLLISION_MARGIN_H
+
diff --git a/extern/bullet/Bullet/NarrowPhaseCollision/ContinuousConvexCollision.cpp b/extern/bullet/Bullet/NarrowPhaseCollision/ContinuousConvexCollision.cpp
new file mode 100644
index 00000000000..21baabfb864
--- /dev/null
+++ b/extern/bullet/Bullet/NarrowPhaseCollision/ContinuousConvexCollision.cpp
@@ -0,0 +1,186 @@
+/*
+ * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies.
+ * Erwin Coumans makes no representations about the suitability
+ * of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+*/
+
+#include "ContinuousConvexCollision.h"
+#include "CollisionShapes/ConvexShape.h"
+#include "CollisionShapes/MinkowskiSumShape.h"
+#include "NarrowPhaseCollision/SimplexSolverInterface.h"
+#include "SimdTransformUtil.h"
+#include "CollisionShapes/SphereShape.h"
+
+#include "GjkPairDetector.h"
+#include "PointCollector.h"
+
+
+
+ContinuousConvexCollision::ContinuousConvexCollision ( ConvexShape* convexA,ConvexShape* convexB,SimplexSolverInterface* simplexSolver, ConvexPenetrationDepthSolver* penetrationDepthSolver)
+:m_simplexSolver(simplexSolver),
+m_penetrationDepthSolver(penetrationDepthSolver),
+m_convexA(convexA),m_convexB(convexB)
+{
+}
+
+/// This maximum should not be necessary. It allows for untested/degenerate cases in production code.
+/// You don't want your game ever to lock-up.
+#define MAX_ITERATIONS 1000
+
+bool ContinuousConvexCollision::calcTimeOfImpact(
+ const SimdTransform& fromA,
+ const SimdTransform& toA,
+ const SimdTransform& fromB,
+ const SimdTransform& toB,
+ CastResult& result)
+{
+
+ m_simplexSolver->reset();
+
+ /// compute linear and angular velocity for this interval, to interpolate
+ SimdVector3 linVelA,angVelA,linVelB,angVelB;
+ SimdTransformUtil::CalculateVelocity(fromA,toA,1.f,linVelA,angVelA);
+ SimdTransformUtil::CalculateVelocity(fromB,toB,1.f,linVelB,angVelB);
+
+ SimdScalar boundingRadiusA = m_convexA->GetAngularMotionDisc();
+ SimdScalar boundingRadiusB = m_convexB->GetAngularMotionDisc();
+
+ SimdScalar maxAngularProjectedVelocity = angVelA.length() * boundingRadiusA + angVelB.length() * boundingRadiusB;
+
+ float radius = 0.001f;
+
+ SimdScalar lambda = 0.f;
+ SimdVector3 v(1,0,0);
+
+ int maxIter = MAX_ITERATIONS;
+
+ SimdVector3 n;
+ n.setValue(0.f,0.f,0.f);
+ bool hasResult = false;
+ SimdVector3 c;
+
+ float lastLambda = lambda;
+ float epsilon = 0.001f;
+
+ int numIter = 0;
+ //first solution, using GJK
+
+
+ SimdTransform identityTrans;
+ identityTrans.setIdentity();
+
+ SphereShape raySphere(0.0f);
+ raySphere.SetMargin(0.f);
+
+
+// result.DrawCoordSystem(sphereTr);
+
+ PointCollector pointCollector1;
+
+ {
+
+ GjkPairDetector gjk(m_convexA,m_convexB,m_simplexSolver,m_penetrationDepthSolver);
+ GjkPairDetector::ClosestPointInput input;
+ input.m_transformA = fromA;
+ input.m_transformB = fromB;
+ gjk.GetClosestPoints(input,pointCollector1);
+
+ hasResult = pointCollector1.m_hasResult;
+ c = pointCollector1.m_pointInWorld;
+ }
+
+ if (hasResult)
+ {
+ SimdScalar dist;
+ dist = pointCollector1.m_distance;
+ n = pointCollector1.m_normalOnBInWorld;
+
+ //not close enough
+ while (dist > radius)
+ {
+ numIter++;
+ if (numIter > maxIter)
+ return false; //todo: report a failure
+
+ float dLambda = 0.f;
+
+ //calculate safe moving fraction from distance / (linear+rotational velocity)
+
+ //float clippedDist = GEN_min(angularConservativeRadius,dist);
+ float clippedDist = dist;
+
+ float projectedLinearVelocity = (linVelB-linVelA).dot(n);
+
+ dLambda = dist / (projectedLinearVelocity+ maxAngularProjectedVelocity);
+
+ lambda = lambda + dLambda;
+
+ //todo: next check with relative epsilon
+ if (lambda <= lastLambda)
+ break;
+ lastLambda = lambda;
+
+ if (lambda > 1.f)
+ return false;
+
+ //interpolate to next lambda
+ SimdTransform interpolatedTransA,interpolatedTransB,relativeTrans;
+
+ SimdTransformUtil::IntegrateTransform(fromA,linVelA,angVelA,lambda,interpolatedTransA);
+ SimdTransformUtil::IntegrateTransform(fromB,linVelB,angVelB,lambda,interpolatedTransB);
+ relativeTrans = interpolatedTransB.inverseTimes(interpolatedTransA);
+
+ result.DebugDraw( lambda );
+
+ PointCollector pointCollector;
+ GjkPairDetector gjk(m_convexA,m_convexB,m_simplexSolver,m_penetrationDepthSolver);
+ GjkPairDetector::ClosestPointInput input;
+ input.m_transformA = interpolatedTransA;
+ input.m_transformB = interpolatedTransB;
+ gjk.GetClosestPoints(input,pointCollector);
+ if (pointCollector.m_hasResult)
+ {
+ if (pointCollector.m_distance < 0.f)
+ {
+ //degenerate ?!
+ result.m_fraction = lastLambda;
+ result.m_normal = n;
+ return true;
+ }
+ c = pointCollector.m_pointInWorld;
+
+ dist = pointCollector.m_distance;
+ } else
+ {
+ //??
+ return false;
+ }
+
+ }
+
+ result.m_fraction = lambda;
+ result.m_normal = n;
+ return true;
+ }
+
+ return false;
+
+/*
+//todo:
+ //if movement away from normal, discard result
+ SimdVector3 move = transBLocalTo.getOrigin() - transBLocalFrom.getOrigin();
+ if (result.m_fraction < 1.f)
+ {
+ if (move.dot(result.m_normal) <= 0.f)
+ {
+ }
+ }
+*/
+
+}
+
diff --git a/extern/bullet/Bullet/NarrowPhaseCollision/ContinuousConvexCollision.h b/extern/bullet/Bullet/NarrowPhaseCollision/ContinuousConvexCollision.h
new file mode 100644
index 00000000000..0f9808f2986
--- /dev/null
+++ b/extern/bullet/Bullet/NarrowPhaseCollision/ContinuousConvexCollision.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies.
+ * Erwin Coumans makes no representations about the suitability
+ * of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+*/
+
+#ifndef CONTINUOUS_COLLISION_CONVEX_CAST_H
+#define CONTINUOUS_COLLISION_CONVEX_CAST_H
+
+#include "ConvexCast.h"
+#include "SimplexSolverInterface.h"
+class ConvexPenetrationDepthSolver;
+class ConvexShape;
+
+/// ContinuousConvexCollision implements angular and linear time of impact for convex objects.
+/// Based on Brian Mirtich's Conservative Advancement idea (PhD thesis).
+/// Algorithm operates in worldspace, in order to keep inbetween motion globally consistent.
+/// It uses GJK at the moment. Future improvement would use minkowski sum / supporting vertex, merging innerloops
+class ContinuousConvexCollision : public ConvexCast
+{
+ SimplexSolverInterface* m_simplexSolver;
+ ConvexPenetrationDepthSolver* m_penetrationDepthSolver;
+ ConvexShape* m_convexA;
+ ConvexShape* m_convexB;
+
+
+public:
+
+ ContinuousConvexCollision (ConvexShape* shapeA,ConvexShape* shapeB ,SimplexSolverInterface* simplexSolver,ConvexPenetrationDepthSolver* penetrationDepthSolver);
+
+ virtual bool calcTimeOfImpact(
+ const SimdTransform& fromA,
+ const SimdTransform& toA,
+ const SimdTransform& fromB,
+ const SimdTransform& toB,
+ CastResult& result);
+
+
+};
+
+#endif //CONTINUOUS_COLLISION_CONVEX_CAST_H \ No newline at end of file
diff --git a/extern/bullet/Bullet/NarrowPhaseCollision/ConvexCast.cpp b/extern/bullet/Bullet/NarrowPhaseCollision/ConvexCast.cpp
new file mode 100644
index 00000000000..d8a4956700c
--- /dev/null
+++ b/extern/bullet/Bullet/NarrowPhaseCollision/ConvexCast.cpp
@@ -0,0 +1,5 @@
+#include "ConvexCast.h"
+
+ConvexCast::~ConvexCast()
+{
+}
diff --git a/extern/bullet/Bullet/NarrowPhaseCollision/ConvexCast.h b/extern/bullet/Bullet/NarrowPhaseCollision/ConvexCast.h
new file mode 100644
index 00000000000..f32887f6472
--- /dev/null
+++ b/extern/bullet/Bullet/NarrowPhaseCollision/ConvexCast.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies.
+ * Erwin Coumans makes no representations about the suitability
+ * of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+*/
+
+#ifndef CONVEX_CAST_H
+#define CONVEX_CAST_H
+
+#include <SimdTransform.h>
+#include <SimdVector3.h>
+#include <SimdScalar.h>
+class MinkowskiSumShape;
+
+/// ConvexCast is an interface for Casting
+class ConvexCast
+{
+public:
+
+
+ virtual ~ConvexCast();
+
+ ///RayResult stores the closest result
+ /// alternatively, add a callback method to decide about closest/all results
+ struct CastResult
+ {
+ //virtual bool addRayResult(const SimdVector3& normal,SimdScalar fraction) = 0;
+
+ virtual void DebugDraw(SimdScalar fraction) {}
+ virtual void DrawCoordSystem(const SimdTransform& trans) {}
+ CastResult()
+ :m_fraction(1e30f)
+ {
+ }
+
+ SimdVector3 m_normal;
+ SimdScalar m_fraction;
+ SimdTransform m_hitTransformA;
+ SimdTransform m_hitTransformB;
+ };
+
+
+ /// cast a convex against another convex object
+ virtual bool calcTimeOfImpact(
+ const SimdTransform& fromA,
+ const SimdTransform& toA,
+ const SimdTransform& fromB,
+ const SimdTransform& toB,
+ CastResult& result) = 0;
+};
+
+#endif //CONVEX_CAST_H
diff --git a/extern/bullet/Bullet/NarrowPhaseCollision/ConvexPenetrationDepthSolver.h b/extern/bullet/Bullet/NarrowPhaseCollision/ConvexPenetrationDepthSolver.h
new file mode 100644
index 00000000000..4eef58e9775
--- /dev/null
+++ b/extern/bullet/Bullet/NarrowPhaseCollision/ConvexPenetrationDepthSolver.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies.
+ * Erwin Coumans makes no representations about the suitability
+ * of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+*/
+
+#ifndef CONVEX_PENETRATION_DEPTH_H
+#define CONVEX_PENETRATION_DEPTH_H
+
+class SimdVector3;
+#include "SimplexSolverInterface.h"
+class ConvexShape;
+#include "SimdPoint3.h"
+class SimdTransform;
+
+///ConvexPenetrationDepthSolver provides an interface for penetration depth calculation.
+class ConvexPenetrationDepthSolver
+{
+public:
+
+ virtual bool CalcPenDepth( SimplexSolverInterface& simplexSolver,
+ ConvexShape* convexA,ConvexShape* convexB,
+ const SimdTransform& transA,const SimdTransform& transB,
+ SimdVector3& v, SimdPoint3& pa, SimdPoint3& pb) = 0;
+
+
+};
+#endif //CONVEX_PENETRATION_DEPTH_H \ No newline at end of file
diff --git a/extern/bullet/Bullet/NarrowPhaseCollision/DiscreteCollisionDetectorInterface.h b/extern/bullet/Bullet/NarrowPhaseCollision/DiscreteCollisionDetectorInterface.h
new file mode 100644
index 00000000000..c51de7388a3
--- /dev/null
+++ b/extern/bullet/Bullet/NarrowPhaseCollision/DiscreteCollisionDetectorInterface.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies.
+ * Erwin Coumans makes no representations about the suitability
+ * of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+*/
+
+#ifndef DISCRETE_COLLISION_DETECTOR_INTERFACE_H
+#define DISCRETE_COLLISION_DETECTOR_INTERFACE_H
+#include "SimdTransform.h"
+#include "SimdVector3.h"
+
+
+/// This interface is made to be used by an iterative approach to do TimeOfImpact calculations
+/// This interface allows to query for closest points and penetration depth between two (convex) objects
+/// the closest point is on the second object (B), and the normal points from the surface on B towards A.
+/// distance is between closest points on B and closest point on A. So you can calculate closest point on A
+/// by taking closestPointInA = closestPointInB + m_distance * m_normalOnSurfaceB
+struct DiscreteCollisionDetectorInterface
+{
+ void operator delete(void* ptr) {};
+
+ struct Result
+ {
+ void operator delete(void* ptr) {};
+
+ virtual void AddContactPoint(const SimdVector3& normalOnBInWorld,const SimdVector3& pointInWorld,float depth)=0;
+ };
+
+ struct ClosestPointInput
+ {
+ ClosestPointInput()
+ :m_maximumDistanceSquared(1e30f)
+ {
+ }
+
+ SimdTransform m_transformA;
+ SimdTransform m_transformB;
+ SimdScalar m_maximumDistanceSquared;
+ };
+
+ virtual ~DiscreteCollisionDetectorInterface() {};
+
+ //
+ // give either closest points (distance > 0) or penetration (distance)
+ // the normal always points from B towards A
+ //
+ virtual void GetClosestPoints(const ClosestPointInput& input,Result& output) = 0;
+
+ SimdScalar getCollisionMargin() { return 0.2f;}
+};
+
+struct StorageResult : public DiscreteCollisionDetectorInterface::Result
+{
+ SimdVector3 m_normalOnSurfaceB;
+ SimdVector3 m_closestPointInB;
+ SimdScalar m_distance; //negative means penetration !
+
+ StorageResult() : m_distance(1e30f)
+ {
+
+ }
+
+ virtual void AddContactPoint(const SimdVector3& normalOnBInWorld,const SimdVector3& pointInWorld,float depth)
+ {
+ if (depth < m_distance)
+ {
+ m_normalOnSurfaceB = normalOnBInWorld;
+ m_closestPointInB = pointInWorld;
+ m_distance = depth;
+ }
+ }
+};
+
+#endif //DISCRETE_COLLISION_DETECTOR_INTERFACE_H
diff --git a/extern/bullet/Bullet/NarrowPhaseCollision/GjkConvexCast.cpp b/extern/bullet/Bullet/NarrowPhaseCollision/GjkConvexCast.cpp
new file mode 100644
index 00000000000..10a4cb56dcf
--- /dev/null
+++ b/extern/bullet/Bullet/NarrowPhaseCollision/GjkConvexCast.cpp
@@ -0,0 +1,157 @@
+/*
+ * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies.
+ * Erwin Coumans makes no representations about the suitability
+ * of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+*/
+
+
+#include "GjkConvexCast.h"
+#include "CollisionShapes/SphereShape.h"
+#include "CollisionShapes/MinkowskiSumShape.h"
+#include "GjkPairDetector.h"
+#include "PointCollector.h"
+
+
+GjkConvexCast::GjkConvexCast(ConvexShape* convexA,ConvexShape* convexB,SimplexSolverInterface* simplexSolver)
+:m_simplexSolver(simplexSolver),
+m_convexA(convexA),
+m_convexB(convexB)
+{
+}
+
+bool GjkConvexCast::calcTimeOfImpact(
+ const SimdTransform& fromA,
+ const SimdTransform& toA,
+ const SimdTransform& fromB,
+ const SimdTransform& toB,
+ CastResult& result)
+{
+
+
+ MinkowskiSumShape combi(m_convexA,m_convexB);
+ MinkowskiSumShape* convex = &combi;
+
+ SimdTransform rayFromLocalA;
+ SimdTransform rayToLocalA;
+
+ rayFromLocalA = fromA.inverse()* fromB;
+ rayToLocalA = toA.inverse()* toB;
+
+
+ SimdTransform trA,trB;
+ trA = SimdTransform(fromA);
+ trB = SimdTransform(fromB);
+ trA.setOrigin(SimdPoint3(0,0,0));
+ trB.setOrigin(SimdPoint3(0,0,0));
+
+ convex->SetTransformA(trA);
+ convex->SetTransformB(trB);
+
+
+
+
+ float radius = 0.01f;
+
+ SimdScalar lambda = 0.f;
+ SimdVector3 s = rayFromLocalA.getOrigin();
+ SimdVector3 r = rayToLocalA.getOrigin()-rayFromLocalA.getOrigin();
+ SimdVector3 x = s;
+ SimdVector3 n;
+ n.setValue(0,0,0);
+ bool hasResult = false;
+ SimdVector3 c;
+
+ float lastLambda = lambda;
+
+ //first solution, using GJK
+
+ //no penetration support for now, perhaps pass a pointer when we really want it
+ ConvexPenetrationDepthSolver* penSolverPtr = 0;
+
+ SimdTransform identityTrans;
+ identityTrans.setIdentity();
+
+ SphereShape raySphere(0.0f);
+ raySphere.SetMargin(0.f);
+
+ SimdTransform sphereTr;
+ sphereTr.setIdentity();
+ sphereTr.setOrigin( rayFromLocalA.getOrigin());
+
+ result.DrawCoordSystem(sphereTr);
+ {
+ PointCollector pointCollector1;
+ GjkPairDetector gjk(&raySphere,convex,m_simplexSolver,penSolverPtr);
+
+ GjkPairDetector::ClosestPointInput input;
+ input.m_transformA = sphereTr;
+ input.m_transformB = identityTrans;
+ gjk.GetClosestPoints(input,pointCollector1);
+
+ hasResult = pointCollector1.m_hasResult;
+ c = pointCollector1.m_pointInWorld;
+ n = pointCollector1.m_normalOnBInWorld;
+ }
+
+ if (hasResult)
+ {
+ SimdScalar dist;
+ dist = (c-x).length();
+
+
+ //not close enough
+ while (dist > radius)
+ {
+
+ n = x - c;
+ SimdScalar nDotr = n.dot(r);
+
+ if (nDotr >= 0.f)
+ return false;
+
+ lambda = lambda - n.dot(n) / nDotr;
+ if (lambda <= lastLambda)
+ break;
+ lastLambda = lambda;
+
+ x = s + lambda * r;
+
+ sphereTr.setOrigin( x );
+ result.DrawCoordSystem(sphereTr);
+ PointCollector pointCollector;
+ GjkPairDetector gjk(&raySphere,convex,m_simplexSolver,penSolverPtr);
+ GjkPairDetector::ClosestPointInput input;
+ input.m_transformA = sphereTr;
+ input.m_transformB = identityTrans;
+ gjk.GetClosestPoints(input,pointCollector);
+ if (pointCollector.m_hasResult)
+ {
+ if (pointCollector.m_distance < 0.f)
+ {
+ //degeneracy, report a hit
+ result.m_fraction = lastLambda;
+ result.m_normal = n;
+ return true;
+ }
+ c = pointCollector.m_pointInWorld;
+ dist = (c-x).length();
+ } else
+ {
+ //??
+ return false;
+ }
+
+ }
+
+ result.m_fraction = lambda;
+ result.m_normal = n;
+ return true;
+ }
+
+ return false;
+} \ No newline at end of file
diff --git a/extern/bullet/Bullet/NarrowPhaseCollision/GjkConvexCast.h b/extern/bullet/Bullet/NarrowPhaseCollision/GjkConvexCast.h
new file mode 100644
index 00000000000..f5c800f85c6
--- /dev/null
+++ b/extern/bullet/Bullet/NarrowPhaseCollision/GjkConvexCast.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies.
+ * Erwin Coumans makes no representations about the suitability
+ * of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+*/
+
+
+#ifndef GJK_CONVEX_CAST_H
+#define GJK_CONVEX_CAST_H
+
+#include "CollisionMargin.h"
+#include "SimdVector3.h"
+#include "ConvexCast.h"
+class ConvexShape;
+class MinkowskiSumShape;
+#include "SimplexSolverInterface.h"
+
+///GjkConvexCast performs a raycast on a convex object using support mapping.
+class GjkConvexCast : public ConvexCast
+{
+ SimplexSolverInterface* m_simplexSolver;
+ ConvexShape* m_convexA;
+ ConvexShape* m_convexB;
+
+public:
+
+ GjkConvexCast(ConvexShape* convexA,ConvexShape* convexB,SimplexSolverInterface* simplexSolver);
+
+ /// cast a convex against another convex object
+ virtual bool calcTimeOfImpact(
+ const SimdTransform& fromA,
+ const SimdTransform& toA,
+ const SimdTransform& fromB,
+ const SimdTransform& toB,
+ CastResult& result);
+
+};
+
+#endif //GJK_CONVEX_CAST_H
diff --git a/extern/bullet/Bullet/NarrowPhaseCollision/GjkPairDetector.cpp b/extern/bullet/Bullet/NarrowPhaseCollision/GjkPairDetector.cpp
new file mode 100644
index 00000000000..f5db2661c01
--- /dev/null
+++ b/extern/bullet/Bullet/NarrowPhaseCollision/GjkPairDetector.cpp
@@ -0,0 +1,186 @@
+/*
+* Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com
+*
+* Permission to use, copy, modify, distribute and sell this software
+* and its documentation for any purpose is hereby granted without fee,
+* provided that the above copyright notice appear in all copies.
+* Erwin Coumans makes no representations about the suitability
+* of this software for any purpose.
+* It is provided "as is" without express or implied warranty.
+*/
+
+#include "GjkPairDetector.h"
+#include "CollisionShapes/ConvexShape.h"
+#include "NarrowPhaseCollision/SimplexSolverInterface.h"
+#include "NarrowPhaseCollision/ConvexPenetrationDepthSolver.h"
+
+static const SimdScalar rel_error = SimdScalar(1.0e-3);
+SimdScalar rel_error2 = rel_error * rel_error;
+float maxdist2 = 1.e30f;
+
+
+
+GjkPairDetector::GjkPairDetector(ConvexShape* objectA,ConvexShape* objectB,SimplexSolverInterface* simplexSolver,ConvexPenetrationDepthSolver* penetrationDepthSolver)
+:m_cachedSeparatingAxis(0.f,0.f,1.f),
+m_penetrationDepthSolver(penetrationDepthSolver),
+m_simplexSolver(simplexSolver),
+m_minkowskiA(objectA),
+m_minkowskiB(objectB)
+{
+}
+
+void GjkPairDetector::GetClosestPoints(const ClosestPointInput& input,Result& output)
+{
+ SimdScalar distance;
+ SimdVector3 normalInB(0.f,0.f,0.f);
+ SimdVector3 pointOnA,pointOnB;
+
+ float marginA = m_minkowskiA->GetMargin();
+ float marginB = m_minkowskiB->GetMargin();
+
+ bool isValid = false;
+ bool checkSimplex = false;
+ bool checkPenetration = true;
+
+ {
+ SimdScalar squaredDistance = SIMD_INFINITY;
+ SimdScalar delta = 0.f;
+
+ SimdScalar margin = marginA + marginB;
+
+
+
+ m_simplexSolver->reset();
+
+ while (true)
+ {
+
+ SimdVector3 seperatingAxisInA = (-m_cachedSeparatingAxis)* input.m_transformA.getBasis();
+ SimdVector3 seperatingAxisInB = m_cachedSeparatingAxis* input.m_transformB.getBasis();
+
+ SimdVector3 pInA = m_minkowskiA->LocalGetSupportingVertexWithoutMargin(seperatingAxisInA);
+ SimdVector3 qInB = m_minkowskiB->LocalGetSupportingVertexWithoutMargin(seperatingAxisInB);
+ SimdPoint3 pWorld = input.m_transformA(pInA);
+ SimdPoint3 qWorld = input.m_transformB(qInB);
+
+ SimdVector3 w = pWorld - qWorld;
+ delta = m_cachedSeparatingAxis.dot(w);
+
+ // potential exit, they don't overlap
+ if ((delta > SimdScalar(0.0)) && (delta * delta > squaredDistance * input.m_maximumDistanceSquared))
+ {
+ checkPenetration = false;
+ break;
+ }
+
+ //exit 0: the new point is already in the simplex, or we didn't come any closer
+ if (m_simplexSolver->inSimplex(w))
+ {
+ checkSimplex = true;
+ break;
+ }
+ // are we getting any closer ?
+ if (squaredDistance - delta <= squaredDistance * rel_error2)
+ {
+ checkSimplex = true;
+ break;
+ }
+ //add current vertex to simplex
+ m_simplexSolver->addVertex(w, pWorld, qWorld);
+
+ //calculate the closest point to the origin (update vector v)
+ if (!m_simplexSolver->closest(m_cachedSeparatingAxis))
+ {
+ checkSimplex = true;
+ break;
+ }
+
+ SimdScalar previousSquaredDistance = squaredDistance;
+ squaredDistance = m_cachedSeparatingAxis.length2();
+
+ //redundant m_simplexSolver->compute_points(pointOnA, pointOnB);
+
+ //are we getting any closer ?
+ if (previousSquaredDistance - squaredDistance <= SIMD_EPSILON * previousSquaredDistance)
+ {
+ m_simplexSolver->backup_closest(m_cachedSeparatingAxis);
+ checkSimplex = true;
+ break;
+ }
+ bool check = (!m_simplexSolver->fullSimplex() && squaredDistance > SIMD_EPSILON * m_simplexSolver->maxVertex());
+
+ if (!check)
+ {
+ //do we need this backup_closest here ?
+ m_simplexSolver->backup_closest(m_cachedSeparatingAxis);
+ break;
+ }
+ }
+
+ if (checkSimplex)
+ {
+ m_simplexSolver->compute_points(pointOnA, pointOnB);
+ normalInB = pointOnA-pointOnB;
+ float lenSqr = m_cachedSeparatingAxis.length2();
+ //valid normal
+ if (lenSqr > SIMD_EPSILON)
+ {
+ float rlen = 1.f / sqrtf(lenSqr );
+ normalInB *= rlen; //normalize
+ SimdScalar s = sqrtf(squaredDistance);
+ ASSERT(s > SimdScalar(0.0));
+ pointOnA -= m_cachedSeparatingAxis * (marginA / s);
+ pointOnB += m_cachedSeparatingAxis * (marginB / s);
+ distance = ((1.f/rlen) - margin);
+ isValid = true;
+ }
+ }
+
+ if (checkPenetration && !isValid)
+ {
+ //penetration case
+ m_minkowskiA->SetMargin(marginA);
+ m_minkowskiB->SetMargin(marginB);
+
+ //if there is no way to handle penetrations, bail out
+ if (m_penetrationDepthSolver)
+ {
+ // Penetration depth case.
+ isValid = m_penetrationDepthSolver->CalcPenDepth(
+ *m_simplexSolver,
+ m_minkowskiA,m_minkowskiB,
+ input.m_transformA,input.m_transformB,
+ m_cachedSeparatingAxis, pointOnA, pointOnB);
+
+ if (isValid)
+ {
+ normalInB = pointOnB-pointOnA;
+ float lenSqr = normalInB.length2();
+ if (lenSqr > SIMD_EPSILON)
+ {
+ normalInB /= sqrtf(lenSqr);
+ distance = -(pointOnA-pointOnB).length();
+ } else
+ {
+ isValid = false;
+ }
+ }
+ }
+ }
+ }
+
+ if (isValid)
+ {
+ output.AddContactPoint(
+ normalInB,
+ pointOnB,
+ distance);
+ }
+
+
+}
+
+
+
+
+
diff --git a/extern/bullet/Bullet/NarrowPhaseCollision/GjkPairDetector.h b/extern/bullet/Bullet/NarrowPhaseCollision/GjkPairDetector.h
new file mode 100644
index 00000000000..ad9e41682bf
--- /dev/null
+++ b/extern/bullet/Bullet/NarrowPhaseCollision/GjkPairDetector.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies.
+ * Erwin Coumans makes no representations about the suitability
+ * of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+*/
+
+
+
+#ifndef GJK_PAIR_DETECTOR_H
+#define GJK_PAIR_DETECTOR_H
+
+#include "DiscreteCollisionDetectorInterface.h"
+#include "SimdPoint3.h"
+
+#include "CollisionMargin.h"
+
+class ConvexShape;
+#include "SimplexSolverInterface.h"
+class ConvexPenetrationDepthSolver;
+
+/// GjkPairDetector uses GJK to implement the DiscreteCollisionDetectorInterface
+class GjkPairDetector : public DiscreteCollisionDetectorInterface
+{
+
+
+ SimdVector3 m_cachedSeparatingAxis;
+ ConvexPenetrationDepthSolver* m_penetrationDepthSolver;
+ SimplexSolverInterface* m_simplexSolver;
+ ConvexShape* m_minkowskiA;
+ ConvexShape* m_minkowskiB;
+
+public:
+
+ GjkPairDetector(ConvexShape* objectA,ConvexShape* objectB,SimplexSolverInterface* simplexSolver,ConvexPenetrationDepthSolver* penetrationDepthSolver);
+ virtual ~GjkPairDetector() {};
+
+ virtual void GetClosestPoints(const ClosestPointInput& input,Result& output);
+
+ void SetMinkowskiA(ConvexShape* minkA)
+ {
+ m_minkowskiA = minkA;
+ }
+
+ void SetMinkowskiB(ConvexShape* minkB)
+ {
+ m_minkowskiB = minkB;
+ }
+ void SetCachedSeperatingAxis(const SimdVector3& seperatingAxis)
+ {
+ m_cachedSeparatingAxis = seperatingAxis;
+ }
+
+};
+
+#endif //GJK_PAIR_DETECTOR_H
diff --git a/extern/bullet/Bullet/NarrowPhaseCollision/ManifoldPoint.h b/extern/bullet/Bullet/NarrowPhaseCollision/ManifoldPoint.h
new file mode 100644
index 00000000000..5376d1f51aa
--- /dev/null
+++ b/extern/bullet/Bullet/NarrowPhaseCollision/ManifoldPoint.h
@@ -0,0 +1,59 @@
+#ifndef MANIFOLD_CONTACT_POINT_H
+#define MANIFOLD_CONTACT_POINT_H
+
+#include "SimdVector3.h"
+
+/// ManifoldContactPoint collects and maintains persistent contactpoints.
+/// used to improve stability and performance of rigidbody dynamics response.
+class ManifoldPoint
+ {
+ public:
+ ManifoldPoint()
+ {
+ }
+
+ ManifoldPoint( const SimdVector3 &pointA, const SimdVector3 &pointB,
+ const SimdVector3 &normal,
+ SimdScalar distance ) :
+ m_localPointA( pointA ),
+ m_localPointB( pointB ),
+ m_normalWorldOnB( normal ),
+ m_distance1( distance )
+ ,m_appliedImpulse(0.f)
+ {}
+
+ SimdVector3 m_localPointA;
+ SimdVector3 m_localPointB;
+ SimdVector3 m_positionWorldOnB;
+ ///m_positionWorldOnA is redundant information, see GetPositionWorldOnA(), but for clarity
+ SimdVector3 m_positionWorldOnA;
+ SimdVector3 m_normalWorldOnB;
+ float m_distance1;
+ /// total applied impulse during most recent frame
+ float m_appliedImpulse;
+
+ float GetDistance() const
+ {
+ return m_distance1;
+ }
+
+ SimdVector3 GetPositionWorldOnA() {
+ return m_positionWorldOnA;
+// return m_positionWorldOnB + m_normalWorldOnB * m_distance1;
+ }
+
+ const SimdVector3& GetPositionWorldOnB()
+ {
+ return m_positionWorldOnB;
+ }
+
+ void SetDistance(float dist)
+ {
+ m_distance1 = dist;
+ }
+
+
+
+ };
+
+#endif //MANIFOLD_CONTACT_POINT_H
diff --git a/extern/bullet/Bullet/NarrowPhaseCollision/MinkowskiPenetrationDepthSolver.cpp b/extern/bullet/Bullet/NarrowPhaseCollision/MinkowskiPenetrationDepthSolver.cpp
new file mode 100644
index 00000000000..f8679addd18
--- /dev/null
+++ b/extern/bullet/Bullet/NarrowPhaseCollision/MinkowskiPenetrationDepthSolver.cpp
@@ -0,0 +1,132 @@
+#include "MinkowskiPenetrationDepthSolver.h"
+#include "CollisionShapes/MinkowskiSumShape.h"
+#include "NarrowPhaseCollision/SubSimplexConvexCast.h"
+#include "NarrowPhaseCollision/VoronoiSimplexSolver.h"
+#include "NarrowPhaseCollision/GjkPairDetector.h"
+
+
+struct MyResult : public DiscreteCollisionDetectorInterface::Result
+{
+
+ SimdVector3 m_normalOnBInWorld;
+ SimdVector3 m_pointInWorld;
+ float m_depth;
+
+ void AddContactPoint(const SimdVector3& normalOnBInWorld,const SimdVector3& pointInWorld,float depth)
+ {
+ m_normalOnBInWorld = normalOnBInWorld;
+ m_pointInWorld = pointInWorld;
+ m_depth = depth;
+ }
+};
+
+
+
+bool MinkowskiPenetrationDepthSolver::CalcPenDepth(SimplexSolverInterface& simplexSolver,
+ ConvexShape* convexA,ConvexShape* convexB,
+ const SimdTransform& transA,const SimdTransform& transB,
+ SimdVector3& v, SimdPoint3& pa, SimdPoint3& pb)
+{
+
+
+ //just take fixed number of orientation, and sample the penetration depth in that direction
+
+ int N = 3;
+ float minProj = 1e30f;
+ SimdVector3 minNorm;
+ SimdVector3 minVertex;
+ SimdVector3 minA,minB;
+
+ for (int i=-N;i<N;i++)
+ {
+ for (int j = -N;j<N;j++)
+ {
+ for (int k=-N;k<N;k++)
+ {
+ if (i | j | k)
+ {
+ SimdVector3 norm(i,j,k);
+ norm.normalize();
+
+ {
+ SimdVector3 seperatingAxisInA = (-norm)* transA.getBasis();
+ SimdVector3 seperatingAxisInB = norm* transB.getBasis();
+
+ SimdVector3 pInA = convexA->LocalGetSupportingVertex(seperatingAxisInA);
+ SimdVector3 qInB = convexB->LocalGetSupportingVertex(seperatingAxisInB);
+ SimdPoint3 pWorld = transA(pInA);
+ SimdPoint3 qWorld = transB(qInB);
+
+ SimdVector3 w = qWorld - pWorld;
+ float delta = norm.dot(w);
+ //find smallest delta
+
+ if (delta < minProj)
+ {
+ minProj = delta;
+ minNorm = norm;
+ minA = pWorld;
+ minB = qWorld;
+ }
+ }
+
+ {
+ SimdVector3 seperatingAxisInA = (norm)* transA.getBasis();
+ SimdVector3 seperatingAxisInB = -norm* transB.getBasis();
+
+ SimdVector3 pInA = convexA->LocalGetSupportingVertex(seperatingAxisInA);
+ SimdVector3 qInB = convexB->LocalGetSupportingVertex(seperatingAxisInB);
+ SimdPoint3 pWorld = transA(pInA);
+ SimdPoint3 qWorld = transB(qInB);
+
+ SimdVector3 w = qWorld - pWorld;
+ float delta = (-norm).dot(w);
+ //find smallest delta
+
+ if (delta < minProj)
+ {
+ minProj = delta ;
+ minNorm = -norm;
+ minA = pWorld;
+ minB = qWorld;
+ }
+ }
+
+
+
+ }
+ }
+ }
+ }
+
+ SimdTransform ident;
+ ident.setIdentity();
+
+ GjkPairDetector gjkdet(convexA,convexB,&simplexSolver,0);
+
+
+ v = minNorm * minProj;
+
+
+ GjkPairDetector::ClosestPointInput input;
+
+ SimdVector3 newOrg = transA.getOrigin() + v + v;
+
+ SimdTransform displacedTrans = transA;
+ displacedTrans.setOrigin(newOrg);
+
+ input.m_transformA = displacedTrans;
+ input.m_transformB = transB;
+ input.m_maximumDistanceSquared = 1e30f;
+
+ MyResult res;
+ gjkdet.GetClosestPoints(input,res);
+
+ SimdVector3 halfV = v*0.5f;
+
+ //approximate pa and pb
+ pa = res.m_pointInWorld - halfV;
+ pb = res.m_pointInWorld +halfV;
+
+ return true;
+}
diff --git a/extern/bullet/Bullet/NarrowPhaseCollision/MinkowskiPenetrationDepthSolver.h b/extern/bullet/Bullet/NarrowPhaseCollision/MinkowskiPenetrationDepthSolver.h
new file mode 100644
index 00000000000..fb40223b1d6
--- /dev/null
+++ b/extern/bullet/Bullet/NarrowPhaseCollision/MinkowskiPenetrationDepthSolver.h
@@ -0,0 +1,20 @@
+
+#ifndef MINKOWSKI_PENETRATION_DEPTH_SOLVER_H
+#define MINKOWSKI_PENETRATION_DEPTH_SOLVER_H
+
+#include "ConvexPenetrationDepthSolver.h"
+
+///MinkowskiPenetrationDepthSolver implements bruteforce penetration depth estimation.
+///Implementation is based on sampling the depth using support mapping, and using GJK step to get the witness points.
+class MinkowskiPenetrationDepthSolver : public ConvexPenetrationDepthSolver
+{
+public:
+
+ virtual bool CalcPenDepth( SimplexSolverInterface& simplexSolver,
+ ConvexShape* convexA,ConvexShape* convexB,
+ const SimdTransform& transA,const SimdTransform& transB,
+ SimdVector3& v, SimdPoint3& pa, SimdPoint3& pb);
+
+};
+
+#endif //MINKOWSKI_PENETRATION_DEPTH_SOLVER_H \ No newline at end of file
diff --git a/extern/bullet/Bullet/NarrowPhaseCollision/PersistentManifold.cpp b/extern/bullet/Bullet/NarrowPhaseCollision/PersistentManifold.cpp
new file mode 100644
index 00000000000..9085ffa0ef0
--- /dev/null
+++ b/extern/bullet/Bullet/NarrowPhaseCollision/PersistentManifold.cpp
@@ -0,0 +1,182 @@
+/*
+* Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com
+*
+* Permission to use, copy, modify, distribute and sell this software
+* and its documentation for any purpose is hereby granted without fee,
+* provided that the above copyright notice appear in all copies.
+* Erwin Coumans makes no representations about the suitability
+* of this software for any purpose.
+* It is provided "as is" without express or implied warranty.
+*/
+
+
+#include "PersistentManifold.h"
+#include "SimdTransform.h"
+#include <assert.h>
+
+
+PersistentManifold::PersistentManifold()
+:m_body0(0),
+m_body1(0),
+m_cachedPoints (0),
+m_index1(0)
+{
+}
+
+
+void PersistentManifold::ClearManifold()
+{
+ m_cachedPoints = 0;
+}
+
+
+
+
+
+int PersistentManifold::SortCachedPoints(const ManifoldPoint& pt)
+{
+
+ //calculate 4 possible cases areas, and take biggest area
+
+ SimdScalar res0,res1,res2,res3;
+
+ {
+ SimdVector3 a0 = pt.m_localPointA-m_pointCache[1].m_localPointA;
+ SimdVector3 b0 = m_pointCache[3].m_localPointA-m_pointCache[2].m_localPointA;
+ SimdVector3 cross = a0.cross(b0);
+ res0 = cross.length2();
+ }
+ {
+ SimdVector3 a1 = pt.m_localPointA-m_pointCache[0].m_localPointA;
+ SimdVector3 b1 = m_pointCache[3].m_localPointA-m_pointCache[2].m_localPointA;
+ SimdVector3 cross = a1.cross(b1);
+ res1 = cross.length2();
+ }
+ {
+ SimdVector3 a2 = pt.m_localPointA-m_pointCache[0].m_localPointA;
+ SimdVector3 b2 = m_pointCache[3].m_localPointA-m_pointCache[1].m_localPointA;
+ SimdVector3 cross = a2.cross(b2);
+ res2 = cross.length2();
+ }
+ {
+ SimdVector3 a3 = pt.m_localPointA-m_pointCache[0].m_localPointA;
+ SimdVector3 b3 = m_pointCache[2].m_localPointA-m_pointCache[1].m_localPointA;
+ SimdVector3 cross = a3.cross(b3);
+ res3 = cross.length2();
+ }
+
+ SimdVector4 maxvec(res0,res1,res2,res3);
+ int biggestarea = maxvec.closestAxis4();
+
+ return biggestarea;
+
+
+}
+
+
+
+int PersistentManifold::GetCacheEntry(const ManifoldPoint& newPoint) const
+{
+ SimdScalar shortestDist = GetManifoldMargin() * GetManifoldMargin();
+ int size = GetNumContacts();
+ int nearestPoint = -1;
+ for( int i = 0; i < size; i++ )
+ {
+ const ManifoldPoint &mp = m_pointCache[i];
+
+ SimdVector3 diffA = mp.m_localPointA- newPoint.m_localPointA;
+ const SimdScalar distToManiPoint = diffA.dot(diffA);
+ if( distToManiPoint < shortestDist )
+ {
+ shortestDist = distToManiPoint;
+ nearestPoint = i;
+ }
+ }
+ return nearestPoint;
+}
+
+void PersistentManifold::AddManifoldPoint(const ManifoldPoint& newPoint)
+{
+ assert(ValidContactDistance(newPoint));
+
+ int insertIndex = GetNumContacts();
+ if (insertIndex == MANIFOLD_CACHE_SIZE)
+ {
+ //sort cache so best points come first
+ insertIndex = SortCachedPoints(newPoint);
+ } else
+ {
+ m_cachedPoints++;
+ }
+ ReplaceContactPoint(newPoint,insertIndex);
+}
+
+
+void PersistentManifold::RefreshContactPoints(const SimdTransform& trA,const SimdTransform& trB)
+{
+ int i;
+
+ /// first refresh worldspace positions and distance
+ for (i=GetNumContacts()-1;i>=0;i--)
+ {
+ ManifoldPoint &manifoldPoint = m_pointCache[i];
+ manifoldPoint.m_positionWorldOnA = trA( manifoldPoint.m_localPointA );
+ manifoldPoint.m_positionWorldOnB = trB( manifoldPoint.m_localPointB );
+ manifoldPoint.m_distance1 = (manifoldPoint.m_positionWorldOnA - manifoldPoint.m_positionWorldOnB).dot(manifoldPoint.m_normalWorldOnB);
+ }
+
+ /// then
+ SimdScalar distance2d;
+ SimdVector3 projectedDifference,projectedPoint;
+ for (i=GetNumContacts()-1;i>=0;i--)
+ {
+
+ ManifoldPoint &manifoldPoint = m_pointCache[i];
+ //contact becomes invalid when signed distance exceeds margin (projected on contactnormal direction)
+ if (!ValidContactDistance(manifoldPoint))
+ {
+ RemoveContactPoint(i);
+ } else
+ {
+ //contact also becomes invalid when relative movement orthogonal to normal exceeds margin
+ projectedPoint = manifoldPoint.m_positionWorldOnA - manifoldPoint.m_normalWorldOnB * manifoldPoint.m_distance1;
+ projectedDifference = manifoldPoint.m_positionWorldOnB - projectedPoint;
+ distance2d = projectedDifference.dot(projectedDifference);
+ if (distance2d > GetManifoldMargin()*GetManifoldMargin() )
+ {
+ RemoveContactPoint(i);
+ }
+ }
+ }
+}
+
+
+//todo: remove this treshold
+float gPenetrationDistanceCheck = -0.05f;
+
+float PersistentManifold::GetCollisionImpulse() const
+{
+ float averageImpulse = 0.f;
+ if (GetNumContacts() > 0)
+ {
+ float totalImpulse = 0.f;
+
+ //return the sum of the applied impulses on the box
+ for (int i=0;i<GetNumContacts();i++)
+ {
+ const ManifoldPoint& cp = GetContactPoint(i);
+ //avoid conflic noice
+ if ( cp.GetDistance() <gPenetrationDistanceCheck)
+ return 0.f;
+
+ totalImpulse += cp.m_appliedImpulse;
+
+ }
+ averageImpulse = totalImpulse / ((float)GetNumContacts());
+
+ }
+ return averageImpulse;
+
+}
+
+
diff --git a/extern/bullet/Bullet/NarrowPhaseCollision/PersistentManifold.h b/extern/bullet/Bullet/NarrowPhaseCollision/PersistentManifold.h
new file mode 100644
index 00000000000..c1d0314069e
--- /dev/null
+++ b/extern/bullet/Bullet/NarrowPhaseCollision/PersistentManifold.h
@@ -0,0 +1,116 @@
+/*
+* Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com
+*
+* Permission to use, copy, modify, distribute and sell this software
+* and its documentation for any purpose is hereby granted without fee,
+* provided that the above copyright notice appear in all copies.
+* Erwin Coumans makes no representations about the suitability
+* of this software for any purpose.
+* It is provided "as is" without express or implied warranty.
+*/
+
+#ifndef PERSISTENT_MANIFOLD_H
+#define PERSISTENT_MANIFOLD_H
+
+
+#include "SimdVector3.h"
+#include "SimdTransform.h"
+#include "ManifoldPoint.h"
+
+struct CollisionResult;
+
+#define MANIFOLD_CACHE_SIZE 4
+
+///PersistentManifold maintains contact points, and reduces them to 4
+class PersistentManifold
+{
+
+ ManifoldPoint m_pointCache[MANIFOLD_CACHE_SIZE];
+
+ /// this two body pointers can point to the physics rigidbody class.
+ /// void* will allow any rigidbody class
+ void* m_body0;
+ void* m_body1;
+ int m_cachedPoints;
+
+
+ /// sort cached points so most isolated points come first
+ int SortCachedPoints(const ManifoldPoint& pt);
+
+public:
+
+ int m_index1;
+
+ PersistentManifold();
+
+ PersistentManifold(void* body0,void* body1)
+ : m_body0(body0),m_body1(body1),m_cachedPoints(0)
+ {
+ }
+
+ inline void* GetBody0() { return m_body0;}
+ inline void* GetBody1() { return m_body1;}
+
+ inline const void* GetBody0() const { return m_body0;}
+ inline const void* GetBody1() const { return m_body1;}
+
+ void SetBodies(void* body0,void* body1)
+ {
+ m_body0 = body0;
+ m_body1 = body1;
+ }
+
+
+
+ inline int GetNumContacts() const { return m_cachedPoints;}
+
+ inline const ManifoldPoint& GetContactPoint(int index) const
+ {
+ ASSERT(index < m_cachedPoints);
+ return m_pointCache[index];
+ }
+
+ inline ManifoldPoint& GetContactPoint(int index)
+ {
+ ASSERT(index < m_cachedPoints);
+ return m_pointCache[index];
+ }
+
+ /// todo: get this margin from the current physics / collision environment
+ inline float GetManifoldMargin() const
+ {
+ return 0.02f;
+ }
+
+ int GetCacheEntry(const ManifoldPoint& newPoint) const;
+
+ void AddManifoldPoint( const ManifoldPoint& newPoint);
+
+ void RemoveContactPoint (int index)
+ {
+ m_pointCache[index] = m_pointCache[GetNumContacts() - 1];
+ m_cachedPoints--;
+ }
+ void ReplaceContactPoint(const ManifoldPoint& newPoint,int insertIndex)
+ {
+ assert(ValidContactDistance(newPoint));
+ m_pointCache[insertIndex] = newPoint;
+ }
+
+ bool ValidContactDistance(const ManifoldPoint& pt) const
+ {
+ return pt.m_distance1 < GetManifoldMargin();
+ }
+ /// calculated new worldspace coordinates and depth, and reject points that exceed the collision margin
+ void RefreshContactPoints( const SimdTransform& trA,const SimdTransform& trB);
+
+ void ClearManifold();
+
+ float GetCollisionImpulse() const;
+
+
+};
+
+
+
+#endif //PERSISTENT_MANIFOLD_H
diff --git a/extern/bullet/Bullet/NarrowPhaseCollision/PointCollector.h b/extern/bullet/Bullet/NarrowPhaseCollision/PointCollector.h
new file mode 100644
index 00000000000..f39fa090ae4
--- /dev/null
+++ b/extern/bullet/Bullet/NarrowPhaseCollision/PointCollector.h
@@ -0,0 +1,36 @@
+#ifndef POINT_COLLECTOR_H
+#define POINT_COLLECTOR_H
+
+#include "DiscreteCollisionDetectorInterface.h"
+
+
+
+struct PointCollector : public DiscreteCollisionDetectorInterface::Result
+{
+
+
+ SimdVector3 m_normalOnBInWorld;
+ SimdVector3 m_pointInWorld;
+ SimdScalar m_distance;//negative means penetration
+
+ bool m_hasResult;
+
+ PointCollector ()
+ : m_hasResult(false),m_distance(1e30f)
+ {
+ }
+
+ virtual void AddContactPoint(const SimdVector3& normalOnBInWorld,const SimdVector3& pointInWorld,float depth)
+ {
+ if (depth< m_distance)
+ {
+ m_hasResult = true;
+ m_normalOnBInWorld = normalOnBInWorld;
+ m_pointInWorld = pointInWorld;
+ //negative means penetration
+ m_distance = depth;
+ }
+ }
+};
+
+#endif //POINT_COLLECTOR_H \ No newline at end of file
diff --git a/extern/bullet/Bullet/NarrowPhaseCollision/RaycastCallback.cpp b/extern/bullet/Bullet/NarrowPhaseCollision/RaycastCallback.cpp
new file mode 100644
index 00000000000..f27801d224b
--- /dev/null
+++ b/extern/bullet/Bullet/NarrowPhaseCollision/RaycastCallback.cpp
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies.
+ * Erwin Coumans makes no representations about the suitability
+ * of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+*/
+
+#include "RaycastCallback.h"
+
+RaycastCallback::RaycastCallback(const SimdVector3& from,const SimdVector3& to)
+ :
+ m_from(from),
+ m_to(to),
+ m_hitFraction(1.f),
+ m_hitProxy(0)
+{
+
+}
+
+
+
+void RaycastCallback::ProcessTriangle(SimdVector3* triangle)
+{
+
+ int hits_found=0;
+ const SimdVector3 &vert0=triangle[0];
+ const SimdVector3 &vert1=triangle[1];
+ const SimdVector3 &vert2=triangle[2];
+
+ SimdVector3 v10; v10 = vert1 - vert0 ;
+ SimdVector3 v20; v20 = vert2 - vert0 ;
+
+ SimdVector3 triangleNormal; triangleNormal = v10.cross( v20 );
+
+ const float dist = vert0.dot(triangleNormal);
+ float dist_a = triangleNormal.dot(m_from) ;
+ dist_a-= dist;
+ float dist_b = triangleNormal.dot(m_to);
+ dist_b -= dist;
+
+ if ( dist_a * dist_b >= 0.0f)
+ {
+ return ; // same sign
+ }
+
+ const float proj_length=dist_a-dist_b;
+ const float distance = (dist_a)/(proj_length);
+ // Now we have the intersection point on the plane, we'll see if it's inside the triangle
+ // Add an epsilon as a tolerance for the raycast,
+ // in case the ray hits exacly on the edge of the triangle.
+ // It must be scaled for the triangle size.
+ if(distance < m_hitFraction)
+ {
+ float edge_tolerance =triangleNormal.length2();
+ edge_tolerance *= -0.0001f;
+ SimdVector3 point; point.setInterpolate3( m_from, m_to, distance);
+ {
+ SimdVector3 v0p; v0p = vert0 - point;
+ SimdVector3 v1p; v1p = vert1 - point;
+ SimdVector3 cp0; cp0 = v0p.cross( v1p );
+
+ if ( (float)(cp0.dot(triangleNormal)) >=edge_tolerance)
+ {
+ SimdVector3 v2p; v2p = vert2 - point;
+ SimdVector3 cp1;
+ cp1 = v1p.cross( v2p);
+ if ( (float)(cp1.dot(triangleNormal)) >=edge_tolerance)
+ {
+ SimdVector3 cp2;
+ cp2 = v2p.cross(v0p);
+ if ( (float)(cp2.dot(triangleNormal)) >=edge_tolerance)
+ {
+ m_hitFraction = distance;
+ if ( dist_a > 0 )
+ {
+ m_hitNormalWorld = triangleNormal;
+ }
+ else
+ {
+ m_hitNormalWorld = -triangleNormal;
+ }
+ hits_found = 1;
+ }
+ }
+ }
+ }
+ }
+ //return hits_found;
+
+}
diff --git a/extern/bullet/Bullet/NarrowPhaseCollision/RaycastCallback.h b/extern/bullet/Bullet/NarrowPhaseCollision/RaycastCallback.h
new file mode 100644
index 00000000000..5dbffde4244
--- /dev/null
+++ b/extern/bullet/Bullet/NarrowPhaseCollision/RaycastCallback.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies.
+ * Erwin Coumans makes no representations about the suitability
+ * of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+*/
+#ifndef RAYCAST_TRI_CALLBACK_H
+#define RAYCAST_TRI_CALLBACK_H
+
+#include "CollisionShapes/TriangleCallback.h"
+struct BroadphaseProxy;
+
+
+class RaycastCallback: public TriangleCallback
+{
+public:
+
+ //input
+ SimdVector3 m_from;
+ SimdVector3 m_to;
+ //input / output
+ SimdScalar m_hitFraction;
+ BroadphaseProxy* m_hitProxy;
+
+ //output
+ SimdVector3 m_hitNormalWorld;
+
+
+
+ RaycastCallback(const SimdVector3& from,const SimdVector3& to);
+
+
+ virtual void ProcessTriangle(SimdVector3* triangle);
+};
+
+#endif //RAYCAST_TRI_CALLBACK_H \ No newline at end of file
diff --git a/extern/bullet/Bullet/NarrowPhaseCollision/SimplexSolverInterface.h b/extern/bullet/Bullet/NarrowPhaseCollision/SimplexSolverInterface.h
new file mode 100644
index 00000000000..9fe58385904
--- /dev/null
+++ b/extern/bullet/Bullet/NarrowPhaseCollision/SimplexSolverInterface.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies.
+ * Erwin Coumans makes no representations about the suitability
+ * of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+*/
+
+
+#ifndef SIMPLEX_SOLVER_INTERFACE_H
+#define SIMPLEX_SOLVER_INTERFACE_H
+
+#include "SimdVector3.h"
+#include "SimdPoint3.h"
+
+#define NO_VIRTUAL_INTERFACE
+#ifdef NO_VIRTUAL_INTERFACE
+#include "VoronoiSimplexSolver.h"
+#define SimplexSolverInterface VoronoiSimplexSolver
+#else
+/// for simplices from 1 to 4 vertices
+/// for example Johnson-algorithm or alternative approaches based on
+/// voronoi regions or barycentric coordinates
+class SimplexSolverInterface
+{
+ public:
+ virtual ~SimplexSolverInterface() {};
+
+ virtual void reset() = 0;
+
+ virtual void addVertex(const SimdVector3& w, const SimdPoint3& p, const SimdPoint3& q) = 0;
+
+ virtual bool closest(SimdVector3& v) = 0;
+
+ virtual SimdScalar maxVertex() = 0;
+
+ virtual bool fullSimplex() const = 0;
+
+ virtual int getSimplex(SimdPoint3 *pBuf, SimdPoint3 *qBuf, SimdVector3 *yBuf) const = 0;
+
+ virtual bool inSimplex(const SimdVector3& w) = 0;
+
+ virtual void backup_closest(SimdVector3& v) = 0;
+
+ virtual bool emptySimplex() const = 0;
+
+ virtual void compute_points(SimdPoint3& p1, SimdPoint3& p2) = 0;
+
+ virtual int numVertices() const =0;
+
+
+};
+#endif
+#endif //SIMPLEX_SOLVER_INTERFACE_H
+
diff --git a/extern/bullet/Bullet/NarrowPhaseCollision/SubSimplexConvexCast.cpp b/extern/bullet/Bullet/NarrowPhaseCollision/SubSimplexConvexCast.cpp
new file mode 100644
index 00000000000..80fea519887
--- /dev/null
+++ b/extern/bullet/Bullet/NarrowPhaseCollision/SubSimplexConvexCast.cpp
@@ -0,0 +1,124 @@
+/*
+ * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies.
+ * Erwin Coumans makes no representations about the suitability
+ * of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+*/
+
+#include "SubSimplexConvexCast.h"
+#include "CollisionShapes/ConvexShape.h"
+#include "CollisionShapes/MinkowskiSumShape.h"
+#include "NarrowPhaseCollision/SimplexSolverInterface.h"
+
+
+SubsimplexConvexCast::SubsimplexConvexCast (ConvexShape* convexA,ConvexShape* convexB,SimplexSolverInterface* simplexSolver)
+:m_simplexSolver(simplexSolver),
+m_convexA(convexA),m_convexB(convexB)
+{
+}
+
+
+#define MAX_ITERATIONS 1000
+
+bool SubsimplexConvexCast::calcTimeOfImpact(
+ const SimdTransform& fromA,
+ const SimdTransform& toA,
+ const SimdTransform& fromB,
+ const SimdTransform& toB,
+ CastResult& result)
+{
+
+ MinkowskiSumShape combi(m_convexA,m_convexB);
+ MinkowskiSumShape* convex = &combi;
+
+ SimdTransform rayFromLocalA;
+ SimdTransform rayToLocalA;
+
+ rayFromLocalA = fromA.inverse()* fromB;
+ rayToLocalA = toA.inverse()* toB;
+
+
+ m_simplexSolver->reset();
+
+ convex->SetTransformB(SimdTransform(rayFromLocalA.getBasis()));
+
+ float radius = 0.01f;
+
+ SimdScalar lambda = 0.f;
+ SimdVector3 s = rayFromLocalA.getOrigin();
+ SimdVector3 r = rayToLocalA.getOrigin()-rayFromLocalA.getOrigin();
+ SimdVector3 x = s;
+ SimdVector3 v;
+ SimdVector3 arbitraryPoint = convex->LocalGetSupportingVertex(r);
+
+ v = x - arbitraryPoint;
+
+ int maxIter = MAX_ITERATIONS;
+
+ SimdVector3 n;
+ n.setValue(0.f,0.f,0.f);
+ bool hasResult = false;
+ SimdVector3 c;
+
+ float lastLambda = lambda;
+
+
+ float dist2 = v.length2();
+ float epsilon = 0.0001f;
+
+ SimdVector3 w,p;
+ float VdotR;
+
+ while ( (dist2 > epsilon) && maxIter--)
+ {
+ p = convex->LocalGetSupportingVertex( v);
+ w = x - p;
+
+ float VdotW = v.dot(w);
+
+ if ( VdotW > 0.f)
+ {
+ VdotR = v.dot(r);
+
+ if (VdotR >= 0.f)
+ return false;
+ else
+ {
+ lambda = lambda - VdotW / VdotR;
+ x = s + lambda * r;
+ m_simplexSolver->reset();
+ //check next line
+ w = x-p;
+ lastLambda = lambda;
+ n = v;
+ hasResult = true;
+ }
+ }
+ m_simplexSolver->addVertex( w, x , p);
+ if (m_simplexSolver->closest(v))
+ {
+ dist2 = v.length2();
+ hasResult = true;
+ //printf("V=%f , %f, %f\n",v[0],v[1],v[2]);
+ //printf("DIST2=%f\n",dist2);
+ //printf("numverts = %i\n",m_simplexSolver->numVertices());
+ } else
+ {
+ dist2 = 0.f;
+ }
+ }
+
+ int numiter = MAX_ITERATIONS - maxIter;
+// printf("number of iterations: %d", numiter);
+ result.m_fraction = lambda;
+ result.m_normal = n;
+
+ return true;
+}
+
+
+
diff --git a/extern/bullet/Bullet/NarrowPhaseCollision/SubSimplexConvexCast.h b/extern/bullet/Bullet/NarrowPhaseCollision/SubSimplexConvexCast.h
new file mode 100644
index 00000000000..38c958304bc
--- /dev/null
+++ b/extern/bullet/Bullet/NarrowPhaseCollision/SubSimplexConvexCast.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies.
+ * Erwin Coumans makes no representations about the suitability
+ * of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+*/
+
+#ifndef SUBSIMPLEX_CONVEX_CAST_H
+#define SUBSIMPLEX_CONVEX_CAST_H
+
+#include "ConvexCast.h"
+#include "SimplexSolverInterface.h"
+class ConvexShape;
+
+/// SubsimplexConvexCast implements Gino van den Bergens' paper
+/// GJK based Ray Cast, optimized version
+class SubsimplexConvexCast : public ConvexCast
+{
+ SimplexSolverInterface* m_simplexSolver;
+ ConvexShape* m_convexA;
+ ConvexShape* m_convexB;
+
+public:
+
+ SubsimplexConvexCast (ConvexShape* shapeA,ConvexShape* shapeB,SimplexSolverInterface* simplexSolver);
+
+ //virtual ~SubsimplexConvexCast();
+
+ virtual bool calcTimeOfImpact(
+ const SimdTransform& fromA,
+ const SimdTransform& toA,
+ const SimdTransform& fromB,
+ const SimdTransform& toB,
+ CastResult& result);
+
+};
+
+#endif //SUBSIMPLEX_CONVEX_CAST_H
diff --git a/extern/bullet/Bullet/NarrowPhaseCollision/VoronoiSimplexSolver.cpp b/extern/bullet/Bullet/NarrowPhaseCollision/VoronoiSimplexSolver.cpp
new file mode 100644
index 00000000000..fed9524c66d
--- /dev/null
+++ b/extern/bullet/Bullet/NarrowPhaseCollision/VoronoiSimplexSolver.cpp
@@ -0,0 +1,582 @@
+/*
+ * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies.
+ * Erwin Coumans makes no representations about the suitability
+ * of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+*/
+
+#include "VoronoiSimplexSolver.h"
+#include <assert.h>
+#include <stdio.h>
+
+#define VERTA 0
+#define VERTB 1
+#define VERTC 2
+#define VERTD 3
+
+#define CATCH_DEGENERATE_TETRAHEDRON 1
+void VoronoiSimplexSolver::removeVertex(int index)
+{
+
+ assert(m_numVertices>0);
+ m_numVertices--;
+ m_simplexVectorW[index] = m_simplexVectorW[m_numVertices];
+ m_simplexPointsP[index] = m_simplexPointsP[m_numVertices];
+ m_simplexPointsQ[index] = m_simplexPointsQ[m_numVertices];
+}
+
+void VoronoiSimplexSolver::ReduceVertices (const UsageBitfield& usedVerts)
+{
+ if ((numVertices() >= 4) && (!usedVerts.usedVertexD))
+ removeVertex(3);
+
+ if ((numVertices() >= 3) && (!usedVerts.usedVertexC))
+ removeVertex(2);
+
+ if ((numVertices() >= 2) && (!usedVerts.usedVertexB))
+ removeVertex(1);
+
+ if ((numVertices() >= 1) && (!usedVerts.usedVertexA))
+ removeVertex(0);
+
+}
+
+
+
+
+
+//clear the simplex, remove all the vertices
+void VoronoiSimplexSolver::reset()
+{
+ m_cachedValidClosest = false;
+ m_numVertices = 0;
+ m_needsUpdate = true;
+ m_lastW = SimdVector3(1e30f,1e30f,1e30f);
+ m_cachedBC.Reset();
+}
+
+
+
+ //add a vertex
+void VoronoiSimplexSolver::addVertex(const SimdVector3& w, const SimdPoint3& p, const SimdPoint3& q)
+{
+ m_lastW = w;
+ m_needsUpdate = true;
+
+ m_simplexVectorW[m_numVertices] = w;
+ m_simplexPointsP[m_numVertices] = p;
+ m_simplexPointsQ[m_numVertices] = q;
+
+ m_numVertices++;
+}
+
+bool VoronoiSimplexSolver::UpdateClosestVectorAndPoints()
+{
+
+ if (m_needsUpdate)
+ {
+ m_cachedBC.Reset();
+
+ m_needsUpdate = false;
+
+ switch (numVertices())
+ {
+ case 0:
+ m_cachedValidClosest = false;
+ break;
+ case 1:
+ {
+ m_cachedP1 = m_simplexPointsP[0];
+ m_cachedP2 = m_simplexPointsQ[0];
+ m_cachedV = m_cachedP1-m_cachedP2; //== m_simplexVectorW[0]
+ m_cachedBC.Reset();
+ m_cachedBC.SetBarycentricCoordinates(1.f,0.f,0.f,0.f);
+ m_cachedValidClosest = m_cachedBC.IsValid();
+ break;
+ };
+ case 2:
+ {
+ //closest point origin from line segment
+ const SimdVector3& from = m_simplexVectorW[0];
+ const SimdVector3& to = m_simplexVectorW[1];
+ SimdVector3 nearest;
+
+ SimdVector3 p (0.f,0.f,0.f);
+ SimdVector3 diff = p - from;
+ SimdVector3 v = to - from;
+ float t = v.dot(diff);
+
+ if (t > 0) {
+ float dotVV = v.dot(v);
+ if (t < dotVV) {
+ t /= dotVV;
+ diff -= t*v;
+ m_cachedBC.m_usedVertices.usedVertexA = true;
+ m_cachedBC.m_usedVertices.usedVertexB = true;
+ } else {
+ t = 1;
+ diff -= v;
+ //reduce to 1 point
+ m_cachedBC.m_usedVertices.usedVertexB = true;
+ }
+ } else
+ {
+ t = 0;
+ //reduce to 1 point
+ m_cachedBC.m_usedVertices.usedVertexA = true;
+ }
+ m_cachedBC.SetBarycentricCoordinates(1-t,t);
+ nearest = from + t*v;
+
+ m_cachedP1 = m_simplexPointsP[0] + t * (m_simplexPointsP[1] - m_simplexPointsP[0]);
+ m_cachedP2 = m_simplexPointsQ[0] + t * (m_simplexPointsQ[1] - m_simplexPointsQ[0]);
+ m_cachedV = m_cachedP1 - m_cachedP2;
+
+ ReduceVertices(m_cachedBC.m_usedVertices);
+
+ m_cachedValidClosest = m_cachedBC.IsValid();
+ break;
+ }
+ case 3:
+ {
+ //closest point origin from triangle
+ SimdVector3 p (0.f,0.f,0.f);
+
+ const SimdVector3& a = m_simplexVectorW[0];
+ const SimdVector3& b = m_simplexVectorW[1];
+ const SimdVector3& c = m_simplexVectorW[2];
+
+ ClosestPtPointTriangle(p,a,b,c,m_cachedBC);
+ m_cachedP1 = m_simplexPointsP[0] * m_cachedBC.m_barycentricCoords[0] +
+ m_simplexPointsP[1] * m_cachedBC.m_barycentricCoords[1] +
+ m_simplexPointsP[2] * m_cachedBC.m_barycentricCoords[2] +
+ m_simplexPointsP[3] * m_cachedBC.m_barycentricCoords[3];
+
+ m_cachedP2 = m_simplexPointsQ[0] * m_cachedBC.m_barycentricCoords[0] +
+ m_simplexPointsQ[1] * m_cachedBC.m_barycentricCoords[1] +
+ m_simplexPointsQ[2] * m_cachedBC.m_barycentricCoords[2] +
+ m_simplexPointsQ[3] * m_cachedBC.m_barycentricCoords[3];
+
+ m_cachedV = m_cachedP1-m_cachedP2;
+
+ ReduceVertices (m_cachedBC.m_usedVertices);
+ m_cachedValidClosest = m_cachedBC.IsValid();
+
+ break;
+ }
+ case 4:
+ {
+
+
+ SimdVector3 p (0.f,0.f,0.f);
+
+ const SimdVector3& a = m_simplexVectorW[0];
+ const SimdVector3& b = m_simplexVectorW[1];
+ const SimdVector3& c = m_simplexVectorW[2];
+ const SimdVector3& d = m_simplexVectorW[3];
+
+ bool hasSeperation = ClosestPtPointTetrahedron(p,a,b,c,d,m_cachedBC);
+
+ if (hasSeperation)
+ {
+
+ m_cachedP1 = m_simplexPointsP[0] * m_cachedBC.m_barycentricCoords[0] +
+ m_simplexPointsP[1] * m_cachedBC.m_barycentricCoords[1] +
+ m_simplexPointsP[2] * m_cachedBC.m_barycentricCoords[2] +
+ m_simplexPointsP[3] * m_cachedBC.m_barycentricCoords[3];
+
+ m_cachedP2 = m_simplexPointsQ[0] * m_cachedBC.m_barycentricCoords[0] +
+ m_simplexPointsQ[1] * m_cachedBC.m_barycentricCoords[1] +
+ m_simplexPointsQ[2] * m_cachedBC.m_barycentricCoords[2] +
+ m_simplexPointsQ[3] * m_cachedBC.m_barycentricCoords[3];
+
+ m_cachedV = m_cachedP1-m_cachedP2;
+ ReduceVertices (m_cachedBC.m_usedVertices);
+ } else
+ {
+// printf("sub distance got penetration\n");
+
+ if (m_cachedBC.m_degenerate)
+ {
+ m_cachedValidClosest = false;
+ } else
+ {
+ m_cachedValidClosest = true;
+ //degenerate case == false, penetration = true + zero
+ m_cachedV.setValue(0.f,0.f,0.f);
+ }
+ break;
+ }
+
+ m_cachedValidClosest = m_cachedBC.IsValid();
+
+ //closest point origin from tetrahedron
+ break;
+ }
+ default:
+ {
+ m_cachedValidClosest = false;
+ }
+ };
+ }
+
+ return m_cachedValidClosest;
+
+}
+
+//return/calculate the closest vertex
+bool VoronoiSimplexSolver::closest(SimdVector3& v)
+{
+ bool succes = UpdateClosestVectorAndPoints();
+ v = m_cachedV;
+ return succes;
+}
+
+
+
+SimdScalar VoronoiSimplexSolver::maxVertex()
+{
+ int i, numverts = numVertices();
+ SimdScalar maxV = 0.f;
+ for (i=0;i<numverts;i++)
+ {
+ SimdScalar curLen2 = m_simplexVectorW[i].length2();
+ if (maxV < curLen2)
+ maxV = curLen2;
+ }
+ return maxV;
+}
+
+
+
+ //return the current simplex
+int VoronoiSimplexSolver::getSimplex(SimdPoint3 *pBuf, SimdPoint3 *qBuf, SimdVector3 *yBuf) const
+{
+ int i;
+ for (i=0;i<numVertices();i++)
+ {
+ yBuf[i] = m_simplexVectorW[i];
+ pBuf[i] = m_simplexPointsP[i];
+ qBuf[i] = m_simplexPointsQ[i];
+ }
+ return numVertices();
+}
+
+
+
+
+bool VoronoiSimplexSolver::inSimplex(const SimdVector3& w)
+{
+ bool found = false;
+ int i, numverts = numVertices();
+ SimdScalar maxV = 0.f;
+
+ //w is in the current (reduced) simplex
+ for (i=0;i<numverts;i++)
+ {
+ if (m_simplexVectorW[i] == w)
+ found = true;
+ }
+
+ //check in case lastW is already removed
+ if (w == m_lastW)
+ return true;
+
+ return found;
+}
+
+void VoronoiSimplexSolver::backup_closest(SimdVector3& v)
+{
+ v = m_cachedV;
+}
+
+
+bool VoronoiSimplexSolver::emptySimplex() const
+{
+ return (numVertices() == 0);
+
+}
+
+void VoronoiSimplexSolver::compute_points(SimdPoint3& p1, SimdPoint3& p2)
+{
+ UpdateClosestVectorAndPoints();
+ p1 = m_cachedP1;
+ p2 = m_cachedP2;
+
+}
+
+
+
+
+bool VoronoiSimplexSolver::ClosestPtPointTriangle(const SimdPoint3& p, const SimdPoint3& a, const SimdPoint3& b, const SimdPoint3& c,SubSimplexClosestResult& result)
+{
+ result.m_usedVertices.reset();
+
+ // Check if P in vertex region outside A
+ SimdVector3 ab = b - a;
+ SimdVector3 ac = c - a;
+ SimdVector3 ap = p - a;
+ float d1 = ab.dot(ap);
+ float d2 = ac.dot(ap);
+ if (d1 <= 0.0f && d2 <= 0.0f)
+ {
+ result.m_closestPointOnSimplex = a;
+ result.m_usedVertices.usedVertexA = true;
+ result.SetBarycentricCoordinates(1,0,0);
+ return true;// a; // barycentric coordinates (1,0,0)
+ }
+
+ // Check if P in vertex region outside B
+ SimdVector3 bp = p - b;
+ float d3 = ab.dot(bp);
+ float d4 = ac.dot(bp);
+ if (d3 >= 0.0f && d4 <= d3)
+ {
+ result.m_closestPointOnSimplex = b;
+ result.m_usedVertices.usedVertexB = true;
+ result.SetBarycentricCoordinates(0,1,0);
+
+ return true; // b; // barycentric coordinates (0,1,0)
+ }
+ // Check if P in edge region of AB, if so return projection of P onto AB
+ float vc = d1*d4 - d3*d2;
+ if (vc <= 0.0f && d1 >= 0.0f && d3 <= 0.0f) {
+ float v = d1 / (d1 - d3);
+ result.m_closestPointOnSimplex = a + v * ab;
+ result.m_usedVertices.usedVertexA = true;
+ result.m_usedVertices.usedVertexB = true;
+ result.SetBarycentricCoordinates(1-v,v,0);
+ return true;
+ //return a + v * ab; // barycentric coordinates (1-v,v,0)
+ }
+
+ // Check if P in vertex region outside C
+ SimdVector3 cp = p - c;
+ float d5 = ab.dot(cp);
+ float d6 = ac.dot(cp);
+ if (d6 >= 0.0f && d5 <= d6)
+ {
+ result.m_closestPointOnSimplex = c;
+ result.m_usedVertices.usedVertexC = true;
+ result.SetBarycentricCoordinates(0,0,1);
+ return true;//c; // barycentric coordinates (0,0,1)
+ }
+
+ // Check if P in edge region of AC, if so return projection of P onto AC
+ float vb = d5*d2 - d1*d6;
+ if (vb <= 0.0f && d2 >= 0.0f && d6 <= 0.0f) {
+ float w = d2 / (d2 - d6);
+ result.m_closestPointOnSimplex = a + w * ac;
+ result.m_usedVertices.usedVertexA = true;
+ result.m_usedVertices.usedVertexC = true;
+ result.SetBarycentricCoordinates(1-w,0,w);
+ return true;
+ //return a + w * ac; // barycentric coordinates (1-w,0,w)
+ }
+
+ // Check if P in edge region of BC, if so return projection of P onto BC
+ float va = d3*d6 - d5*d4;
+ if (va <= 0.0f && (d4 - d3) >= 0.0f && (d5 - d6) >= 0.0f) {
+ float w = (d4 - d3) / ((d4 - d3) + (d5 - d6));
+
+ result.m_closestPointOnSimplex = b + w * (c - b);
+ result.m_usedVertices.usedVertexB = true;
+ result.m_usedVertices.usedVertexC = true;
+ result.SetBarycentricCoordinates(0,1-w,w);
+ return true;
+ // return b + w * (c - b); // barycentric coordinates (0,1-w,w)
+ }
+
+ // P inside face region. Compute Q through its barycentric coordinates (u,v,w)
+ float denom = 1.0f / (va + vb + vc);
+ float v = vb * denom;
+ float w = vc * denom;
+
+ result.m_closestPointOnSimplex = a + ab * v + ac * w;
+ result.m_usedVertices.usedVertexA = true;
+ result.m_usedVertices.usedVertexB = true;
+ result.m_usedVertices.usedVertexC = true;
+ result.SetBarycentricCoordinates(1-v-w,v,w);
+
+ return true;
+// return a + ab * v + ac * w; // = u*a + v*b + w*c, u = va * denom = 1.0f - v - w
+
+}
+
+
+
+
+
+/// Test if point p and d lie on opposite sides of plane through abc
+int VoronoiSimplexSolver::PointOutsideOfPlane(const SimdPoint3& p, const SimdPoint3& a, const SimdPoint3& b, const SimdPoint3& c, const SimdPoint3& d)
+{
+ SimdVector3 normal = (b-a).cross(c-a);
+
+ float signp = (p - a).dot(normal); // [AP AB AC]
+ float signd = (d - a).dot( normal); // [AD AB AC]
+
+#ifdef CATCH_DEGENERATE_TETRAHEDRON
+ if (signd * signd < (1e-4f * 1e-4f))
+ {
+// printf("affine dependent/degenerate\n");//
+ return -1;
+ }
+#endif
+ // Points on opposite sides if expression signs are opposite
+ return signp * signd < 0.f;
+}
+
+
+bool VoronoiSimplexSolver::ClosestPtPointTetrahedron(const SimdPoint3& p, const SimdPoint3& a, const SimdPoint3& b, const SimdPoint3& c, const SimdPoint3& d, SubSimplexClosestResult& finalResult)
+{
+ SubSimplexClosestResult tempResult;
+
+ // Start out assuming point inside all halfspaces, so closest to itself
+ finalResult.m_closestPointOnSimplex = p;
+ finalResult.m_usedVertices.reset();
+ finalResult.m_usedVertices.usedVertexA = true;
+ finalResult.m_usedVertices.usedVertexB = true;
+ finalResult.m_usedVertices.usedVertexC = true;
+ finalResult.m_usedVertices.usedVertexD = true;
+
+ int pointOutsideABC = PointOutsideOfPlane(p, a, b, c, d);
+ int pointOutsideACD = PointOutsideOfPlane(p, a, c, d, b);
+ int pointOutsideADB = PointOutsideOfPlane(p, a, d, b, c);
+ int pointOutsideBDC = PointOutsideOfPlane(p, b, d, c, a);
+
+ if (pointOutsideABC < 0 || pointOutsideACD < 0 || pointOutsideADB < 0 || pointOutsideBDC < 0)
+ {
+ finalResult.m_degenerate = true;
+ return false;
+ }
+
+ if (!pointOutsideABC && !pointOutsideACD && !pointOutsideADB && !pointOutsideBDC)
+ {
+ return false;
+ }
+
+
+ float bestSqDist = FLT_MAX;
+ // If point outside face abc then compute closest point on abc
+ if (pointOutsideABC)
+ {
+ ClosestPtPointTriangle(p, a, b, c,tempResult);
+ SimdPoint3 q = tempResult.m_closestPointOnSimplex;
+
+ float sqDist = (q - p).dot( q - p);
+ // Update best closest point if (squared) distance is less than current best
+ if (sqDist < bestSqDist) {
+ bestSqDist = sqDist;
+ finalResult.m_closestPointOnSimplex = q;
+ //convert result bitmask!
+ finalResult.m_usedVertices.reset();
+ finalResult.m_usedVertices.usedVertexA = tempResult.m_usedVertices.usedVertexA;
+ finalResult.m_usedVertices.usedVertexB = tempResult.m_usedVertices.usedVertexB;
+ finalResult.m_usedVertices.usedVertexC = tempResult.m_usedVertices.usedVertexC;
+ finalResult.SetBarycentricCoordinates(
+ tempResult.m_barycentricCoords[VERTA],
+ tempResult.m_barycentricCoords[VERTB],
+ tempResult.m_barycentricCoords[VERTC],
+ 0
+ );
+
+ }
+ }
+
+
+ // Repeat test for face acd
+ if (pointOutsideACD)
+ {
+ ClosestPtPointTriangle(p, a, c, d,tempResult);
+ SimdPoint3 q = tempResult.m_closestPointOnSimplex;
+ //convert result bitmask!
+
+ float sqDist = (q - p).dot( q - p);
+ if (sqDist < bestSqDist)
+ {
+ bestSqDist = sqDist;
+ finalResult.m_closestPointOnSimplex = q;
+ finalResult.m_usedVertices.reset();
+ finalResult.m_usedVertices.usedVertexA = tempResult.m_usedVertices.usedVertexA;
+ finalResult.m_usedVertices.usedVertexC = tempResult.m_usedVertices.usedVertexB;
+ finalResult.m_usedVertices.usedVertexD = tempResult.m_usedVertices.usedVertexC;
+ finalResult.SetBarycentricCoordinates(
+ tempResult.m_barycentricCoords[VERTA],
+ 0,
+ tempResult.m_barycentricCoords[VERTB],
+ tempResult.m_barycentricCoords[VERTC]
+ );
+
+ }
+ }
+ // Repeat test for face adb
+
+
+ if (pointOutsideADB)
+ {
+ ClosestPtPointTriangle(p, a, d, b,tempResult);
+ SimdPoint3 q = tempResult.m_closestPointOnSimplex;
+ //convert result bitmask!
+
+ float sqDist = (q - p).dot( q - p);
+ if (sqDist < bestSqDist)
+ {
+ bestSqDist = sqDist;
+ finalResult.m_closestPointOnSimplex = q;
+ finalResult.m_usedVertices.reset();
+ finalResult.m_usedVertices.usedVertexA = tempResult.m_usedVertices.usedVertexA;
+ finalResult.m_usedVertices.usedVertexD = tempResult.m_usedVertices.usedVertexB;
+ finalResult.m_usedVertices.usedVertexB = tempResult.m_usedVertices.usedVertexC;
+ finalResult.SetBarycentricCoordinates(
+ tempResult.m_barycentricCoords[VERTA],
+ tempResult.m_barycentricCoords[VERTC],
+ 0,
+ tempResult.m_barycentricCoords[VERTB]
+ );
+
+ }
+ }
+ // Repeat test for face bdc
+
+
+ if (pointOutsideBDC)
+ {
+ ClosestPtPointTriangle(p, b, d, c,tempResult);
+ SimdPoint3 q = tempResult.m_closestPointOnSimplex;
+ //convert result bitmask!
+ float sqDist = (q - p).dot( q - p);
+ if (sqDist < bestSqDist)
+ {
+ bestSqDist = sqDist;
+ finalResult.m_closestPointOnSimplex = q;
+ finalResult.m_usedVertices.reset();
+ finalResult.m_usedVertices.usedVertexB = tempResult.m_usedVertices.usedVertexA;
+ finalResult.m_usedVertices.usedVertexD = tempResult.m_usedVertices.usedVertexB;
+ finalResult.m_usedVertices.usedVertexC = tempResult.m_usedVertices.usedVertexC;
+
+ finalResult.SetBarycentricCoordinates(
+ 0,
+ tempResult.m_barycentricCoords[VERTA],
+ tempResult.m_barycentricCoords[VERTC],
+ tempResult.m_barycentricCoords[VERTB]
+ );
+
+ }
+ }
+
+ //help! we ended up full !
+
+ if (finalResult.m_usedVertices.usedVertexA &&
+ finalResult.m_usedVertices.usedVertexB &&
+ finalResult.m_usedVertices.usedVertexC &&
+ finalResult.m_usedVertices.usedVertexD)
+ {
+ return true;
+ }
+
+ return true;
+} \ No newline at end of file
diff --git a/extern/bullet/Bullet/NarrowPhaseCollision/VoronoiSimplexSolver.h b/extern/bullet/Bullet/NarrowPhaseCollision/VoronoiSimplexSolver.h
new file mode 100644
index 00000000000..3328b1061e5
--- /dev/null
+++ b/extern/bullet/Bullet/NarrowPhaseCollision/VoronoiSimplexSolver.h
@@ -0,0 +1,152 @@
+/*
+ * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies.
+ * Erwin Coumans makes no representations about the suitability
+ * of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+*/
+
+
+#ifndef VoronoiSimplexSolver_H
+#define VoronoiSimplexSolver_H
+
+#include "SimplexSolverInterface.h"
+
+
+
+#define VORONOI_SIMPLEX_MAX_VERTS 5
+
+struct UsageBitfield{
+ UsageBitfield()
+ {
+ reset();
+ }
+
+ void reset()
+ {
+ usedVertexA = false;
+ usedVertexB = false;
+ usedVertexC = false;
+ usedVertexD = false;
+ }
+ unsigned short usedVertexA : 1;
+ unsigned short usedVertexB : 1;
+ unsigned short usedVertexC : 1;
+ unsigned short usedVertexD : 1;
+ unsigned short unused1 : 1;
+ unsigned short unused2 : 1;
+ unsigned short unused3 : 1;
+ unsigned short unused4 : 1;
+};
+
+
+struct SubSimplexClosestResult
+{
+ SimdPoint3 m_closestPointOnSimplex;
+ //MASK for m_usedVertices
+ //stores the simplex vertex-usage, using the MASK,
+ // if m_usedVertices & MASK then the related vertex is used
+ UsageBitfield m_usedVertices;
+ float m_barycentricCoords[4];
+ bool m_degenerate;
+
+ void Reset()
+ {
+ m_degenerate = false;
+ SetBarycentricCoordinates();
+ m_usedVertices.reset();
+ }
+ bool IsValid()
+ {
+ bool valid = (m_barycentricCoords[0] >= 0.f) &&
+ (m_barycentricCoords[1] >= 0.f) &&
+ (m_barycentricCoords[2] >= 0.f) &&
+ (m_barycentricCoords[3] >= 0.f);
+
+
+ return valid;
+ }
+ void SetBarycentricCoordinates(float a=0.f,float b=0.f,float c=0.f,float d=0.f)
+ {
+ m_barycentricCoords[0] = a;
+ m_barycentricCoords[1] = b;
+ m_barycentricCoords[2] = c;
+ m_barycentricCoords[3] = d;
+ }
+
+};
+
+/// VoronoiSimplexSolver is an implementation of the closest point distance algorithm from a 1-4 points simplex to the origin.
+/// Can be used with GJK, as an alternative to Johnson distance algorithm.
+#ifdef NO_VIRTUAL_INTERFACE
+class VoronoiSimplexSolver
+#else
+class VoronoiSimplexSolver : public SimplexSolverInterface
+#endif
+{
+public:
+
+ int m_numVertices;
+
+ SimdVector3 m_simplexVectorW[VORONOI_SIMPLEX_MAX_VERTS];
+ SimdPoint3 m_simplexPointsP[VORONOI_SIMPLEX_MAX_VERTS];
+ SimdPoint3 m_simplexPointsQ[VORONOI_SIMPLEX_MAX_VERTS];
+
+
+
+ SimdPoint3 m_cachedP1;
+ SimdPoint3 m_cachedP2;
+ SimdVector3 m_cachedV;
+ SimdVector3 m_lastW;
+ bool m_cachedValidClosest;
+
+ SubSimplexClosestResult m_cachedBC;
+
+ bool m_needsUpdate;
+
+ void removeVertex(int index);
+ void ReduceVertices (const UsageBitfield& usedVerts);
+ bool UpdateClosestVectorAndPoints();
+
+ bool ClosestPtPointTetrahedron(const SimdPoint3& p, const SimdPoint3& a, const SimdPoint3& b, const SimdPoint3& c, const SimdPoint3& d, SubSimplexClosestResult& finalResult);
+ int PointOutsideOfPlane(const SimdPoint3& p, const SimdPoint3& a, const SimdPoint3& b, const SimdPoint3& c, const SimdPoint3& d);
+ bool ClosestPtPointTriangle(const SimdPoint3& p, const SimdPoint3& a, const SimdPoint3& b, const SimdPoint3& c,SubSimplexClosestResult& result);
+
+public:
+
+ void reset();
+
+ void addVertex(const SimdVector3& w, const SimdPoint3& p, const SimdPoint3& q);
+
+
+ bool closest(SimdVector3& v);
+
+ SimdScalar maxVertex();
+
+ bool fullSimplex() const
+ {
+ return (m_numVertices == 4);
+ }
+
+ int getSimplex(SimdPoint3 *pBuf, SimdPoint3 *qBuf, SimdVector3 *yBuf) const;
+
+ bool inSimplex(const SimdVector3& w);
+
+ void backup_closest(SimdVector3& v) ;
+
+ bool emptySimplex() const ;
+
+ void compute_points(SimdPoint3& p1, SimdPoint3& p2) ;
+
+ int numVertices() const
+ {
+ return m_numVertices;
+ }
+
+
+};
+
+#endif //VoronoiSimplexSolver
diff --git a/extern/bullet/BulletDynamics/BulletDynamics.dsp b/extern/bullet/BulletDynamics/BulletDynamics.dsp
new file mode 100644
index 00000000000..1b9f9cc1985
--- /dev/null
+++ b/extern/bullet/BulletDynamics/BulletDynamics.dsp
@@ -0,0 +1,236 @@
+# Microsoft Developer Studio Project File - Name="BulletDynamics" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Static Library" 0x0104
+
+CFG=BulletDynamics - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "BulletDynamics.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "BulletDynamics.mak" CFG="BulletDynamics - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "BulletDynamics - Win32 Release" (based on "Win32 (x86) Static Library")
+!MESSAGE "BulletDynamics - Win32 Debug" (based on "Win32 (x86) Static Library")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "BulletDynamics - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "BulletDynamics___Win32_Release"
+# PROP BASE Intermediate_Dir "BulletDynamics___Win32_Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "BulletDynamics___Win32_Release"
+# PROP Intermediate_Dir "BulletDynamics___Win32_Release"
+# PROP Target_Dir ""
+LINK32=link.exe -lib
+MTL=midl.exe
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
+# ADD CPP /nologo /W3 /GX /O2 /I "../LinearMath" /I "../Bullet" /I "../BulletDynamics" /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
+# ADD BASE RSC /l 0x809 /d "NDEBUG"
+# ADD RSC /l 0x809 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LIB32=link.exe -lib
+# ADD BASE LIB32 /nologo
+# ADD LIB32 /nologo
+
+!ELSEIF "$(CFG)" == "BulletDynamics - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "BulletDynamics___Win32_Debug"
+# PROP BASE Intermediate_Dir "BulletDynamics___Win32_Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "BulletDynamics___Win32_Debug"
+# PROP Intermediate_Dir "BulletDynamics___Win32_Debug"
+# PROP Target_Dir ""
+LINK32=link.exe -lib
+MTL=midl.exe
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
+# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "../LinearMath" /I "../Bullet" /I "../BulletDynamics" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
+# ADD BASE RSC /l 0x809 /d "_DEBUG"
+# ADD RSC /l 0x809 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LIB32=link.exe -lib
+# ADD BASE LIB32 /nologo
+# ADD LIB32 /nologo
+
+!ENDIF
+
+# Begin Target
+
+# Name "BulletDynamics - Win32 Release"
+# Name "BulletDynamics - Win32 Debug"
+# Begin Group "ConstraintSolver"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=.\ConstraintSolver\ConstraintSolver.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\ConstraintSolver\ContactConstraint.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\ConstraintSolver\ContactConstraint.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\ConstraintSolver\ContactSolverInfo.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\ConstraintSolver\JacobianEntry.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\ConstraintSolver\OdeConstraintSolver.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\ConstraintSolver\OdeConstraintSolver.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\ConstraintSolver\Point2PointConstraint.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\ConstraintSolver\Point2PointConstraint.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\ConstraintSolver\SimpleConstraintSolver.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\ConstraintSolver\SimpleConstraintSolver.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\ConstraintSolver\Solve2LinearConstraint.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\ConstraintSolver\Solve2LinearConstraint.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\ConstraintSolver\SorLcp.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\ConstraintSolver\SorLcp.h
+# End Source File
+# End Group
+# Begin Group "CollisionDispatch"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=.\CollisionDispatch\ConvexConcaveCollisionAlgorithm.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\CollisionDispatch\ConvexConcaveCollisionAlgorithm.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\CollisionDispatch\ConvexConvexAlgorithm.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\CollisionDispatch\ConvexConvexAlgorithm.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\CollisionDispatch\EmptyCollisionAlgorithm.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\CollisionDispatch\EmptyCollisionAlgorithm.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\CollisionDispatch\ManifoldResult.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\CollisionDispatch\ManifoldResult.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\CollisionDispatch\ToiContactDispatcher.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\CollisionDispatch\ToiContactDispatcher.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\CollisionDispatch\UnionFind.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\CollisionDispatch\UnionFind.h
+# End Source File
+# End Group
+# Begin Group "Dynamics"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=.\Dynamics\BU_Joint.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\Dynamics\BU_Joint.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\Dynamics\ContactJoint.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\Dynamics\ContactJoint.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\Dynamics\MassProps.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\Dynamics\RigidBody.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\Dynamics\RigidBody.h
+# End Source File
+# End Group
+# End Target
+# End Project
diff --git a/extern/bullet/BulletDynamics/BulletDynamics_vc7.vcproj b/extern/bullet/BulletDynamics/BulletDynamics_vc7.vcproj
new file mode 100644
index 00000000000..e89c175720f
--- /dev/null
+++ b/extern/bullet/BulletDynamics/BulletDynamics_vc7.vcproj
@@ -0,0 +1,231 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="7.10"
+ Name="Bullet3Dynamics"
+ ProjectGUID="{3427A9EF-FF84-4B3E-9AE5-C37CF44D7DA4}"
+ Keyword="Win32Proj">
+ <Platforms>
+ <Platform
+ Name="Win32"/>
+ </Platforms>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="Debug"
+ IntermediateDirectory="Debug"
+ ConfigurationType="4"
+ CharacterSet="2">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="..\LinearMath;..\Bullet;..\BulletDynamics"
+ PreprocessorDefinitions="WIN32;_DEBUG;_LIB"
+ MinimalRebuild="TRUE"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="5"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="TRUE"
+ DebugInformationFormat="4"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLibrarianTool"
+ OutputFile="$(OutDir)/BulletDynamics.lib"/>
+ <Tool
+ Name="VCMIDLTool"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release"
+ ConfigurationType="4"
+ CharacterSet="2">
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories="..\LinearMath;..\Bullet;..\BulletDynamics"
+ PreprocessorDefinitions="WIN32;NDEBUG;_LIB"
+ RuntimeLibrary="4"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="TRUE"
+ DebugInformationFormat="3"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLibrarianTool"
+ OutputFile="..\..\..\..\build\msvc_7\libs\extern\BulletDynamics.lib"/>
+ <Tool
+ Name="VCMIDLTool"/>
+ <Tool
+ Name="VCPostBuildEventTool"
+ CommandLine="ECHO Copying header files
+IF NOT EXIST ..\..\..\..\build\msvc_7\extern\bullet\include MKDIR ..\..\..\..\build\msvc_7\extern\bullet\include
+IF NOT EXIST ..\..\..\..\build\msvc_7\extern\bullet\include\CollisionDispatch MKDIR ..\..\..\..\build\msvc_7\extern\bullet\include\CollisionDispatch
+IF NOT EXIST ..\..\..\..\build\msvc_7\extern\bullet\include\ConstraintSolver MKDIR ..\..\..\..\build\msvc_7\extern\bullet\include\ConstraintSolver
+IF NOT EXIST ..\..\..\..\build\msvc_7\extern\bullet\include\Dynamics MKDIR ..\..\..\..\build\msvc_7\extern\bullet\include\Dynamics
+
+XCOPY /Y ..\LinearMath\*.h ..\..\..\..\build\msvc_7\extern\bullet\include
+XCOPY /Y ..\BulletDynamics\CollisionDispatch\*.h ..\..\..\..\build\msvc_7\extern\bullet\include\CollisionDispatch
+XCOPY /Y ..\BulletDynamics\ConstraintSolver\*.h ..\..\..\..\build\msvc_7\extern\bullet\include\ConstraintSolver
+XCOPY /Y ..\BulletDynamics\Dynamics\*.h ..\..\..\..\build\msvc_7\extern\bullet\include\Dynamics
+
+ECHO Done
+"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="ConstraintSolver"
+ Filter="">
+ <File
+ RelativePath=".\ConstraintSolver\ConstraintSolver.h">
+ </File>
+ <File
+ RelativePath=".\ConstraintSolver\ContactConstraint.cpp">
+ </File>
+ <File
+ RelativePath=".\ConstraintSolver\ContactConstraint.h">
+ </File>
+ <File
+ RelativePath=".\ConstraintSolver\ContactSolverInfo.h">
+ </File>
+ <File
+ RelativePath=".\ConstraintSolver\JacobianEntry.h">
+ </File>
+ <File
+ RelativePath=".\ConstraintSolver\OdeConstraintSolver.cpp">
+ </File>
+ <File
+ RelativePath=".\ConstraintSolver\OdeConstraintSolver.h">
+ </File>
+ <File
+ RelativePath=".\ConstraintSolver\Point2PointConstraint.cpp">
+ </File>
+ <File
+ RelativePath=".\ConstraintSolver\Point2PointConstraint.h">
+ </File>
+ <File
+ RelativePath=".\ConstraintSolver\SimpleConstraintSolver.cpp">
+ </File>
+ <File
+ RelativePath=".\ConstraintSolver\SimpleConstraintSolver.h">
+ </File>
+ <File
+ RelativePath=".\ConstraintSolver\Solve2LinearConstraint.cpp">
+ </File>
+ <File
+ RelativePath=".\ConstraintSolver\Solve2LinearConstraint.h">
+ </File>
+ <File
+ RelativePath=".\ConstraintSolver\SorLcp.cpp">
+ </File>
+ <File
+ RelativePath=".\ConstraintSolver\SorLcp.h">
+ </File>
+ </Filter>
+ <Filter
+ Name="CollisionDispatch"
+ Filter="">
+ <File
+ RelativePath=".\CollisionDispatch\ConvexConcaveCollisionAlgorithm.cpp">
+ </File>
+ <File
+ RelativePath=".\CollisionDispatch\ConvexConcaveCollisionAlgorithm.h">
+ </File>
+ <File
+ RelativePath=".\CollisionDispatch\ConvexConvexAlgorithm.cpp">
+ </File>
+ <File
+ RelativePath=".\CollisionDispatch\ConvexConvexAlgorithm.h">
+ </File>
+ <File
+ RelativePath=".\CollisionDispatch\EmptyCollisionAlgorithm.cpp">
+ </File>
+ <File
+ RelativePath=".\CollisionDispatch\EmptyCollisionAlgorithm.h">
+ </File>
+ <File
+ RelativePath=".\CollisionDispatch\ManifoldResult.cpp">
+ </File>
+ <File
+ RelativePath=".\CollisionDispatch\ManifoldResult.h">
+ </File>
+ <File
+ RelativePath=".\CollisionDispatch\ToiContactDispatcher.cpp">
+ </File>
+ <File
+ RelativePath=".\CollisionDispatch\ToiContactDispatcher.h">
+ </File>
+ <File
+ RelativePath=".\CollisionDispatch\UnionFind.cpp">
+ </File>
+ <File
+ RelativePath=".\CollisionDispatch\UnionFind.h">
+ </File>
+ </Filter>
+ <Filter
+ Name="Dynamics"
+ Filter="">
+ <File
+ RelativePath=".\Dynamics\BU_Joint.cpp">
+ </File>
+ <File
+ RelativePath=".\Dynamics\BU_Joint.h">
+ </File>
+ <File
+ RelativePath=".\Dynamics\ContactJoint.cpp">
+ </File>
+ <File
+ RelativePath=".\Dynamics\ContactJoint.h">
+ </File>
+ <File
+ RelativePath=".\Dynamics\MassProps.h">
+ </File>
+ <File
+ RelativePath=".\Dynamics\RigidBody.cpp">
+ </File>
+ <File
+ RelativePath=".\Dynamics\RigidBody.h">
+ </File>
+ </Filter>
+ <File
+ RelativePath=".\ReadMe.txt">
+ </File>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/extern/bullet/BulletDynamics/BulletDynamics_vc8.vcproj b/extern/bullet/BulletDynamics/BulletDynamics_vc8.vcproj
new file mode 100644
index 00000000000..2efa75b0f55
--- /dev/null
+++ b/extern/bullet/BulletDynamics/BulletDynamics_vc8.vcproj
@@ -0,0 +1,301 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="8.00"
+ Name="Bullet3Dynamics"
+ ProjectGUID="{3427A9EF-FF84-4B3E-9AE5-C37CF44D7DA4}"
+ Keyword="Win32Proj"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="Debug"
+ IntermediateDirectory="Debug"
+ ConfigurationType="4"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="..\LinearMath;..\Bullet;..\BulletDynamics"
+ PreprocessorDefinitions="WIN32;_DEBUG;_LIB"
+ MinimalRebuild="TRUE"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="1"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="TRUE"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ OutputFile="$(OutDir)/BulletDynamics.lib"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release"
+ ConfigurationType="4"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories="..\LinearMath;..\Bullet;..\BulletDynamics"
+ PreprocessorDefinitions="WIN32;NDEBUG;_LIB"
+ RuntimeLibrary="0"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="TRUE"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ OutputFile="$(OutDir)/BulletDynamics.lib"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="ConstraintSolver"
+ >
+ <File
+ RelativePath=".\ConstraintSolver\ConstraintSolver.h"
+ >
+ </File>
+ <File
+ RelativePath=".\ConstraintSolver\ContactConstraint.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\ConstraintSolver\ContactConstraint.h"
+ >
+ </File>
+ <File
+ RelativePath=".\ConstraintSolver\ContactSolverInfo.h"
+ >
+ </File>
+ <File
+ RelativePath=".\ConstraintSolver\JacobianEntry.h"
+ >
+ </File>
+ <File
+ RelativePath=".\ConstraintSolver\OdeConstraintSolver.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\ConstraintSolver\OdeConstraintSolver.h"
+ >
+ </File>
+ <File
+ RelativePath=".\ConstraintSolver\Point2PointConstraint.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\ConstraintSolver\Point2PointConstraint.h"
+ >
+ </File>
+ <File
+ RelativePath=".\ConstraintSolver\SimpleConstraintSolver.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\ConstraintSolver\SimpleConstraintSolver.h"
+ >
+ </File>
+ <File
+ RelativePath=".\ConstraintSolver\Solve2LinearConstraint.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\ConstraintSolver\Solve2LinearConstraint.h"
+ >
+ </File>
+ <File
+ RelativePath=".\ConstraintSolver\SorLcp.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\ConstraintSolver\SorLcp.h"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="CollisionDispatch"
+ >
+ <File
+ RelativePath=".\CollisionDispatch\ConvexConcaveCollisionAlgorithm.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\CollisionDispatch\ConvexConcaveCollisionAlgorithm.h"
+ >
+ </File>
+ <File
+ RelativePath=".\CollisionDispatch\ConvexConvexAlgorithm.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\CollisionDispatch\ConvexConvexAlgorithm.h"
+ >
+ </File>
+ <File
+ RelativePath=".\CollisionDispatch\EmptyCollisionAlgorithm.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\CollisionDispatch\EmptyCollisionAlgorithm.h"
+ >
+ </File>
+ <File
+ RelativePath=".\CollisionDispatch\ManifoldResult.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\CollisionDispatch\ManifoldResult.h"
+ >
+ </File>
+ <File
+ RelativePath=".\CollisionDispatch\ToiContactDispatcher.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\CollisionDispatch\ToiContactDispatcher.h"
+ >
+ </File>
+ <File
+ RelativePath=".\CollisionDispatch\UnionFind.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\CollisionDispatch\UnionFind.h"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Dynamics"
+ >
+ <File
+ RelativePath=".\Dynamics\BU_Joint.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\Dynamics\BU_Joint.h"
+ >
+ </File>
+ <File
+ RelativePath=".\Dynamics\ContactJoint.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\Dynamics\ContactJoint.h"
+ >
+ </File>
+ <File
+ RelativePath=".\Dynamics\MassProps.h"
+ >
+ </File>
+ <File
+ RelativePath=".\Dynamics\RigidBody.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\Dynamics\RigidBody.h"
+ >
+ </File>
+ </Filter>
+ <File
+ RelativePath=".\ReadMe.txt"
+ >
+ </File>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/extern/bullet/BulletDynamics/CollisionDispatch/ConvexConcaveCollisionAlgorithm.cpp b/extern/bullet/BulletDynamics/CollisionDispatch/ConvexConcaveCollisionAlgorithm.cpp
new file mode 100644
index 00000000000..5dac60a9e06
--- /dev/null
+++ b/extern/bullet/BulletDynamics/CollisionDispatch/ConvexConcaveCollisionAlgorithm.cpp
@@ -0,0 +1,212 @@
+/*
+ * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies.
+ * Erwin Coumans makes no representations about the suitability
+ * of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+*/
+#include "ConvexConcaveCollisionAlgorithm.h"
+#include "Dynamics/RigidBody.h"
+#include "CollisionShapes/MultiSphereShape.h"
+#include "ConstraintSolver/ContactConstraint.h"
+#include "CollisionShapes/BoxShape.h"
+#include "ConvexConvexAlgorithm.h"
+#include "BroadphaseCollision/BroadphaseProxy.h"
+#include "CollisionShapes/TriangleShape.h"
+#include "ConstraintSolver/ConstraintSolver.h"
+#include "ConstraintSolver/ContactSolverInfo.h"
+#include "CollisionDispatch/ManifoldResult.h"
+#include "NarrowphaseCollision/RaycastCallback.h"
+#include "CollisionShapes/TriangleMeshShape.h"
+
+
+ConvexConcaveCollisionAlgorithm::ConvexConcaveCollisionAlgorithm( const CollisionAlgorithmConstructionInfo& ci,BroadphaseProxy* proxy0,BroadphaseProxy* proxy1)
+: CollisionAlgorithm(ci),m_convex(*proxy0),m_concave(*proxy1),
+m_boxTriangleCallback(ci.m_dispatcher,proxy0,proxy1)
+{
+}
+
+ConvexConcaveCollisionAlgorithm::~ConvexConcaveCollisionAlgorithm()
+{
+}
+
+
+
+BoxTriangleCallback::BoxTriangleCallback(Dispatcher* dispatcher,BroadphaseProxy* proxy0,BroadphaseProxy* proxy1):
+ m_boxProxy(proxy0),m_triangleProxy(*proxy1),m_dispatcher(dispatcher),
+ m_timeStep(0.f),
+ m_stepCount(-1)
+{
+
+ m_triangleProxy.SetClientObjectType(TRIANGLE_SHAPE_PROXYTYPE);
+
+ //
+ // create the manifold from the dispatcher 'manifold pool'
+ //
+ m_manifoldPtr = m_dispatcher->GetNewManifold(proxy0->m_clientObject,proxy1->m_clientObject);
+
+ ClearCache();
+}
+
+BoxTriangleCallback::~BoxTriangleCallback()
+{
+ ClearCache();
+ m_dispatcher->ReleaseManifold( m_manifoldPtr );
+
+}
+
+
+void BoxTriangleCallback::ClearCache()
+{
+
+ m_manifoldPtr->ClearManifold();
+};
+
+
+
+void BoxTriangleCallback::ProcessTriangle(SimdVector3* triangle)
+{
+
+
+ RigidBody* triangleBody = (RigidBody*)m_triangleProxy.m_clientObject;
+
+ //aabb filter is already applied!
+
+ CollisionAlgorithmConstructionInfo ci;
+ ci.m_dispatcher = m_dispatcher;
+
+ ConvexShape* tmp = static_cast<ConvexShape*>(triangleBody->GetCollisionShape());
+
+ if (m_boxProxy->IsConvexShape())
+ {
+ TriangleShape tm(triangle[0],triangle[1],triangle[2]);
+ RigidBody* triangleBody = (RigidBody* )m_triangleProxy.m_clientObject;
+
+ triangleBody->SetCollisionShape(&tm);
+ ConvexConvexAlgorithm cvxcvxalgo(m_manifoldPtr,ci,m_boxProxy,&m_triangleProxy);
+ triangleBody->SetCollisionShape(&tm);
+ cvxcvxalgo.ProcessCollision(m_boxProxy,&m_triangleProxy,m_timeStep,m_stepCount,m_useContinuous);
+ }
+
+ triangleBody->SetCollisionShape(tmp);
+
+}
+
+
+
+void BoxTriangleCallback::SetTimeStepAndCounters(float timeStep,int stepCount,bool useContinuous)
+{
+ m_timeStep = timeStep;
+ m_stepCount = stepCount;
+ m_useContinuous = useContinuous;
+
+ //recalc aabbs
+ RigidBody* boxBody = (RigidBody* )m_boxProxy->m_clientObject;
+ RigidBody* triBody = (RigidBody* )m_triangleProxy.m_clientObject;
+
+ SimdTransform boxInTriangleSpace;
+ boxInTriangleSpace = triBody->getCenterOfMassTransform().inverse() * boxBody->getCenterOfMassTransform();
+
+ boxBody->GetCollisionShape()->GetAabb(boxInTriangleSpace,m_aabbMin,m_aabbMax);
+
+ float extraMargin = CONVEX_DISTANCE_MARGIN+0.1f;
+
+ SimdVector3 extra(extraMargin,extraMargin,extraMargin);
+
+ m_aabbMax += extra;
+ m_aabbMin -= extra;
+
+}
+
+void ConvexConcaveCollisionAlgorithm::ClearCache()
+{
+ m_boxTriangleCallback.ClearCache();
+
+}
+
+void ConvexConcaveCollisionAlgorithm::ProcessCollision (BroadphaseProxy* ,BroadphaseProxy* ,float timeStep,int stepCount,bool useContinuous)
+{
+
+
+ if (m_concave.GetClientObjectType() == TRIANGLE_MESH_SHAPE_PROXYTYPE)
+ {
+
+ RigidBody* convexbody = (RigidBody* )m_convex.m_clientObject;
+ RigidBody* concavebody = (RigidBody* )m_concave.m_clientObject;
+
+ TriangleMeshShape* triangleMesh = (TriangleMeshShape*) concavebody->GetCollisionShape();
+
+ if (m_convex.IsConvexShape())
+ {
+
+ m_boxTriangleCallback.SetTimeStepAndCounters(timeStep,stepCount, useContinuous);
+#ifdef USE_BOX_TRIANGLE
+ m_boxTriangleCallback.m_manifoldPtr->ClearManifold();
+#endif
+ m_boxTriangleCallback.m_manifoldPtr->SetBodies(convexbody,concavebody);
+
+ triangleMesh->ProcessAllTriangles( &m_boxTriangleCallback,m_boxTriangleCallback.GetAabbMin(),m_boxTriangleCallback.GetAabbMax());
+
+
+ }
+
+ }
+
+}
+
+
+float ConvexConcaveCollisionAlgorithm::CalculateTimeOfImpact(BroadphaseProxy* ,BroadphaseProxy* ,float timeStep,int stepCount)
+{
+
+ //quick approximation using raycast, todo: use proper continuou collision detection
+ RigidBody* convexbody = (RigidBody* )m_convex.m_clientObject;
+ const SimdVector3& from = convexbody->getCenterOfMassPosition();
+
+ SimdVector3 radVec(0,0,0);
+
+ float minradius = 0.05f;
+ float lenSqr = convexbody->getLinearVelocity().length2();
+ if (lenSqr > SIMD_EPSILON)
+ {
+ radVec = convexbody->getLinearVelocity();
+ radVec.normalize();
+ radVec *= minradius;
+ }
+
+ SimdVector3 to = from + radVec + convexbody->getLinearVelocity() * timeStep*1.01f;
+ //only do if the motion exceeds the 'radius'
+
+
+ RaycastCallback raycastCallback(from,to);
+
+ raycastCallback.m_hitFraction = convexbody->m_hitFraction;
+
+ SimdVector3 aabbMin (-1e30f,-1e30f,-1e30f);
+ SimdVector3 aabbMax (SIMD_INFINITY,SIMD_INFINITY,SIMD_INFINITY);
+
+ if (m_concave.GetClientObjectType() == TRIANGLE_MESH_SHAPE_PROXYTYPE)
+ {
+
+ RigidBody* concavebody = (RigidBody* )m_concave.m_clientObject;
+
+ TriangleMeshShape* triangleMesh = (TriangleMeshShape*) concavebody->GetCollisionShape();
+
+ if (triangleMesh)
+ {
+ triangleMesh->ProcessAllTriangles(&raycastCallback,aabbMin,aabbMax);
+ }
+ }
+
+
+ if (raycastCallback.m_hitFraction < convexbody->m_hitFraction)
+ {
+ convexbody->m_hitFraction = raycastCallback.m_hitFraction;
+ return raycastCallback.m_hitFraction;
+ }
+
+ return 1.f;
+
+}
diff --git a/extern/bullet/BulletDynamics/CollisionDispatch/ConvexConcaveCollisionAlgorithm.h b/extern/bullet/BulletDynamics/CollisionDispatch/ConvexConcaveCollisionAlgorithm.h
new file mode 100644
index 00000000000..35248c841c6
--- /dev/null
+++ b/extern/bullet/BulletDynamics/CollisionDispatch/ConvexConcaveCollisionAlgorithm.h
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies.
+ * Erwin Coumans makes no representations about the suitability
+ * of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+*/
+#ifndef CONVEX_CONCAVE_COLLISION_ALGORITHM_H
+#define CONVEX_CONCAVE_COLLISION_ALGORITHM_H
+
+#include "BroadphaseCollision/CollisionAlgorithm.h"
+#include "BroadphaseCollision/CollisionDispatcher.h"
+#include "BroadphaseCollision/BroadphaseInterface.h"
+#include "CollisionShapes/TriangleCallback.h"
+#include "NarrowPhaseCollision/PersistentManifold.h"
+class Dispatcher;
+#include "BroadphaseCollision/BroadphaseProxy.h"
+
+
+
+class BoxTriangleCallback : public TriangleCallback
+{
+ BroadphaseProxy* m_boxProxy;
+ BroadphaseProxy m_triangleProxy;
+
+ SimdVector3 m_aabbMin;
+ SimdVector3 m_aabbMax ;
+
+ Dispatcher* m_dispatcher;
+ float m_timeStep;
+ int m_stepCount;
+ bool m_useContinuous;
+
+public:
+
+ PersistentManifold* m_manifoldPtr;
+
+ BoxTriangleCallback(Dispatcher* dispatcher,BroadphaseProxy* proxy0,BroadphaseProxy* proxy1);
+
+ void SetTimeStepAndCounters(float timeStep,int stepCount, bool useContinuous);
+
+ virtual ~BoxTriangleCallback();
+
+ virtual void ProcessTriangle(SimdVector3* triangle);
+
+ void ClearCache();
+
+ inline const SimdVector3& GetAabbMin() const
+ {
+ return m_aabbMin;
+ }
+ inline const SimdVector3& GetAabbMax() const
+ {
+ return m_aabbMax;
+ }
+
+};
+
+
+
+
+/// ConvexConcaveCollisionAlgorithm supports collision between convex shapes and (concave) trianges meshes.
+class ConvexConcaveCollisionAlgorithm : public CollisionAlgorithm
+{
+
+ BroadphaseProxy m_convex;
+
+ BroadphaseProxy m_concave;
+
+ BoxTriangleCallback m_boxTriangleCallback;
+
+
+public:
+
+ ConvexConcaveCollisionAlgorithm( const CollisionAlgorithmConstructionInfo& ci,BroadphaseProxy* proxy0,BroadphaseProxy* proxy1);
+
+ virtual ~ConvexConcaveCollisionAlgorithm();
+
+ virtual void ProcessCollision (BroadphaseProxy* proxy0,BroadphaseProxy* proxy1,float timeStep,int stepCount, bool useContinuous);
+
+ float CalculateTimeOfImpact(BroadphaseProxy* proxy0,BroadphaseProxy* proxy1,float timeStep,int stepCount);
+
+ void ClearCache();
+
+};
+
+#endif //CONVEX_CONCAVE_COLLISION_ALGORITHM_H
diff --git a/extern/bullet/BulletDynamics/CollisionDispatch/ConvexConvexAlgorithm.cpp b/extern/bullet/BulletDynamics/CollisionDispatch/ConvexConvexAlgorithm.cpp
new file mode 100644
index 00000000000..42387ba271e
--- /dev/null
+++ b/extern/bullet/BulletDynamics/CollisionDispatch/ConvexConvexAlgorithm.cpp
@@ -0,0 +1,250 @@
+/*
+ * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies.
+ * Erwin Coumans makes no representations about the suitability
+ * of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+*/
+#include "ConvexConvexAlgorithm.h"
+
+#include <stdio.h>
+#include "NarrowPhaseCollision/DiscreteCollisionDetectorInterface.h"
+#include "BroadphaseCollision/BroadphaseInterface.h"
+#include "Dynamics/RigidBody.h"
+#include "CollisionShapes/ConvexShape.h"
+#include "NarrowPhaseCollision/GjkPairDetector.h"
+#include "BroadphaseCollision/BroadphaseProxy.h"
+#include "BroadphaseCollision/CollisionDispatcher.h"
+#include "CollisionShapes/BoxShape.h"
+#include "CollisionDispatch/ManifoldResult.h"
+
+#include "NarrowPhaseCollision/ConvexPenetrationDepthSolver.h"
+#include "NarrowPhaseCollision/ContinuousConvexCollision.h"
+#include "NarrowPhaseCollision/SubsimplexConvexCast.h"
+#include "NarrowPhaseCollision/GjkConvexCast.h"
+
+
+
+#include "CollisionShapes/MinkowskiSumShape.h"
+#include "NarrowPhaseCollision/VoronoiSimplexSolver.h"
+#include "CollisionShapes/SphereShape.h"
+
+
+#ifdef WIN32
+void DrawRasterizerLine(const float* from,const float* to,int color);
+#endif
+
+
+
+
+//#define PROCESS_SINGLE_CONTACT
+#ifdef WIN32
+bool gForceBoxBox = false;//false;//true;
+
+#else
+bool gForceBoxBox = false;//false;//true;
+#endif
+bool gBoxBoxUseGjk = true;//true;//false;
+bool gDisableConvexCollision = false;
+
+
+
+
+ConvexConvexAlgorithm::ConvexConvexAlgorithm(PersistentManifold* mf,const CollisionAlgorithmConstructionInfo& ci,BroadphaseProxy* proxy0,BroadphaseProxy* proxy1)
+: CollisionAlgorithm(ci),
+m_gjkPairDetector(0,0,&m_simplexSolver,&m_penetrationDepthSolver),
+m_box0(*proxy0),
+m_box1(*proxy1),
+m_collisionImpulse(0.f),
+m_ownManifold (false),
+m_manifoldPtr(mf),
+m_lowLevelOfDetail(false)
+
+{
+
+
+ RigidBody* body0 = (RigidBody*)m_box0.m_clientObject;
+ RigidBody* body1 = (RigidBody*)m_box1.m_clientObject;
+
+ if ((body0->getInvMass() != 0.f) ||
+ (body1->getInvMass() != 0.f))
+ {
+ if (!m_manifoldPtr)
+ {
+ m_manifoldPtr = m_dispatcher->GetNewManifold(proxy0->m_clientObject,proxy1->m_clientObject);
+ m_ownManifold = true;
+ }
+ }
+
+}
+
+
+
+ConvexConvexAlgorithm::~ConvexConvexAlgorithm()
+{
+ if (m_ownManifold)
+ {
+ if (m_manifoldPtr)
+ m_dispatcher->ReleaseManifold(m_manifoldPtr);
+ }
+}
+
+void ConvexConvexAlgorithm ::SetLowLevelOfDetail(bool useLowLevel)
+{
+ m_lowLevelOfDetail = useLowLevel;
+}
+
+float ConvexConvexAlgorithm::GetCollisionImpulse() const
+{
+ if (m_manifoldPtr)
+ return m_manifoldPtr->GetCollisionImpulse();
+
+ return 0.f;
+}
+
+
+class FlippedContactResult : public DiscreteCollisionDetectorInterface::Result
+{
+ DiscreteCollisionDetectorInterface::Result* m_org;
+
+public:
+
+ FlippedContactResult(DiscreteCollisionDetectorInterface::Result* org)
+ : m_org(org)
+ {
+
+ }
+
+ virtual void AddContactPoint(const SimdVector3& normalOnBInWorld,const SimdVector3& pointInWorld,float depth)
+ {
+ SimdVector3 flippedNormal = -normalOnBInWorld;
+
+ m_org->AddContactPoint(flippedNormal,pointInWorld,depth);
+ }
+
+};
+
+bool extra = false;
+
+float gFriction = 0.5f;
+//
+// box-box collision algorithm, for simplicity also applies resolution-impulse
+//
+void ConvexConvexAlgorithm ::ProcessCollision (BroadphaseProxy* ,BroadphaseProxy* ,float timeStep,int stepCount, bool useContinuous)
+{
+
+// printf("ConvexConvexAlgorithm::ProcessCollision\n");
+m_collisionImpulse = 0.f;
+
+ RigidBody* body0 = (RigidBody*)m_box0.m_clientObject;
+ RigidBody* body1 = (RigidBody*)m_box1.m_clientObject;
+
+ if (!m_manifoldPtr)
+ return;
+
+ if ((body0->getInvMass() == 0.f) &&
+ (body1->getInvMass() == 0.f))
+ {
+ return;
+ }
+
+ ManifoldResult output(body0,body1,m_manifoldPtr);
+
+ ConvexShape* min0 = static_cast<ConvexShape*>(body0->GetCollisionShape());
+ ConvexShape* min1 = static_cast<ConvexShape*>(body1->GetCollisionShape());
+ GjkPairDetector::ClosestPointInput input;
+
+ SphereShape sphere(0.2f);
+ MinkowskiSumShape expanded0(min0,&sphere);
+ MinkowskiSumShape expanded1(min1,&sphere);
+
+ if (useContinuous)
+ {
+ m_gjkPairDetector.SetMinkowskiA(&expanded0);
+ m_gjkPairDetector.SetMinkowskiB(&expanded1);
+ input.m_maximumDistanceSquared = expanded0.GetMargin()+expanded1.GetMargin();
+ input.m_maximumDistanceSquared *= input.m_maximumDistanceSquared;
+ }
+ else
+ {
+ m_gjkPairDetector.SetMinkowskiA(min0);
+ m_gjkPairDetector.SetMinkowskiB(min1);
+ input.m_maximumDistanceSquared = min0->GetMargin() + min1->GetMargin() + m_manifoldPtr->GetManifoldMargin();
+ input.m_maximumDistanceSquared*= input.m_maximumDistanceSquared;
+ }
+
+ input.m_transformA = body0->getCenterOfMassTransform();
+ input.m_transformB = body1->getCenterOfMassTransform();
+
+ m_gjkPairDetector.GetClosestPoints(input,output);
+
+}
+bool disableCcd = false;
+float ConvexConvexAlgorithm::CalculateTimeOfImpact(BroadphaseProxy* proxy0,BroadphaseProxy* proxy1,float timeStep,int stepCount)
+{
+
+ m_collisionImpulse = 0.f;
+
+ RigidBody* body0 = (RigidBody*)m_box0.m_clientObject;
+ RigidBody* body1 = (RigidBody*)m_box1.m_clientObject;
+
+ if (!m_manifoldPtr)
+ return 1.f;
+
+ if ((body0->getInvMass() == 0.f) &&
+ (body1->getInvMass() == 0.f))
+ {
+ return 1.f;
+ }
+
+
+ ConvexShape* min0 = static_cast<ConvexShape*>(body0->GetCollisionShape());
+ ConvexShape* min1 = static_cast<ConvexShape*>(body1->GetCollisionShape());
+
+ GjkPairDetector::ClosestPointInput input;
+ input.m_transformA = body0->getCenterOfMassTransform();
+ input.m_transformB = body1->getCenterOfMassTransform();
+ SimdTransform predictA,predictB;
+
+ body0->predictIntegratedTransform(timeStep,predictA);
+ body1->predictIntegratedTransform(timeStep,predictB);
+
+
+ ConvexCast::CastResult result;
+
+
+ VoronoiSimplexSolver voronoiSimplex;
+ //SubsimplexConvexCast ccd(&voronoiSimplex);
+ //GjkConvexCast ccd(&voronoiSimplex);
+
+ ContinuousConvexCollision ccd(min0,min1,&voronoiSimplex,&m_penetrationDepthSolver);
+
+ if (disableCcd)
+ return 1.f;
+
+ if (ccd.calcTimeOfImpact(input.m_transformA,predictA,input.m_transformB,predictB,result))
+ {
+
+ //store result.m_fraction in both bodies
+ int i;
+ i=0;
+
+// if (result.m_fraction< 0.1f)
+// result.m_fraction = 0.1f;
+
+ if (body0->m_hitFraction > result.m_fraction)
+ body0->m_hitFraction = result.m_fraction;
+
+ if (body1->m_hitFraction > result.m_fraction)
+ body1->m_hitFraction = result.m_fraction;
+
+ return result.m_fraction;
+ }
+
+ return 1.f;
+
+
+}
diff --git a/extern/bullet/BulletDynamics/CollisionDispatch/ConvexConvexAlgorithm.h b/extern/bullet/BulletDynamics/CollisionDispatch/ConvexConvexAlgorithm.h
new file mode 100644
index 00000000000..d77d6465d6b
--- /dev/null
+++ b/extern/bullet/BulletDynamics/CollisionDispatch/ConvexConvexAlgorithm.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies.
+ * Erwin Coumans makes no representations about the suitability
+ * of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+*/
+#ifndef CONVEX_CONVEX_ALGORITHM_H
+#define CONVEX_CONVEX_ALGORITHM_H
+
+#include "BroadphaseCollision/CollisionAlgorithm.h"
+#include "NarrowPhaseCollision/GjkPairDetector.h"
+#include "NarrowPhaseCollision/PersistentManifold.h"
+#include "BroadphaseCollision/BroadphaseProxy.h"
+#include "NarrowPhaseCollision/VoronoiSimplexSolver.h"
+#include "NarrowPhaseCollision/MinkowskiPenetrationDepthSolver.h"
+
+
+class ConvexPenetrationDepthSolver;
+
+///ConvexConvexAlgorithm collision algorithm implements time of impact, convex closest points and penetration depth calculations.
+class ConvexConvexAlgorithm : public CollisionAlgorithm
+{
+ //hardcoded penetration and simplex solver, its easy to make this flexible later
+ MinkowskiPenetrationDepthSolver m_penetrationDepthSolver;
+ VoronoiSimplexSolver m_simplexSolver;
+ GjkPairDetector m_gjkPairDetector;
+public:
+ BroadphaseProxy m_box0;
+ BroadphaseProxy m_box1;
+ float m_collisionImpulse;
+ bool m_ownManifold;
+ PersistentManifold* m_manifoldPtr;
+ bool m_lowLevelOfDetail;
+
+
+
+public:
+
+ ConvexConvexAlgorithm(PersistentManifold* mf,const CollisionAlgorithmConstructionInfo& ci,BroadphaseProxy* proxy0,BroadphaseProxy* proxy1);
+
+ virtual ~ConvexConvexAlgorithm();
+
+ virtual void ProcessCollision (BroadphaseProxy* proxy0,BroadphaseProxy* proxy1,float timeStep,int stepCount, bool useContinuous);
+
+ virtual float CalculateTimeOfImpact(BroadphaseProxy* proxy0,BroadphaseProxy* proxy1,float timeStep,int stepCount);
+
+ void SetLowLevelOfDetail(bool useLowLevel);
+
+ float GetCollisionImpulse() const;
+
+ const PersistentManifold* GetManifold()
+ {
+ return m_manifoldPtr;
+ }
+
+};
+
+#endif //CONVEX_CONVEX_ALGORITHM_H
diff --git a/extern/bullet/BulletDynamics/CollisionDispatch/EmptyCollisionAlgorithm.cpp b/extern/bullet/BulletDynamics/CollisionDispatch/EmptyCollisionAlgorithm.cpp
new file mode 100644
index 00000000000..4fd6000c7aa
--- /dev/null
+++ b/extern/bullet/BulletDynamics/CollisionDispatch/EmptyCollisionAlgorithm.cpp
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies.
+ * Erwin Coumans makes no representations about the suitability
+ * of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+*/
+#include "EmptyCollisionAlgorithm.h"
+
+
+
+EmptyAlgorithm::EmptyAlgorithm(const CollisionAlgorithmConstructionInfo& ci)
+ : CollisionAlgorithm(ci)
+{
+}
+
+void EmptyAlgorithm::ProcessCollision (BroadphaseProxy* proxy0,BroadphaseProxy* proxy1,float timeStep, int stepCount,bool useContinuous)
+{
+
+}
+
+float EmptyAlgorithm::CalculateTimeOfImpact(BroadphaseProxy* proxy0,BroadphaseProxy* proxy1,float timeStep,int stepCount)
+{
+ return 1.f;
+}
+
+
diff --git a/extern/bullet/BulletDynamics/CollisionDispatch/EmptyCollisionAlgorithm.h b/extern/bullet/BulletDynamics/CollisionDispatch/EmptyCollisionAlgorithm.h
new file mode 100644
index 00000000000..85a64df5b40
--- /dev/null
+++ b/extern/bullet/BulletDynamics/CollisionDispatch/EmptyCollisionAlgorithm.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies.
+ * Erwin Coumans makes no representations about the suitability
+ * of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+*/
+#ifndef EMPTY_ALGORITH
+#define EMPTY_ALGORITH
+#include "BroadphaseCollision/CollisionAlgorithm.h"
+
+#define ATTRIBUTE_ALIGNED(a)
+
+///EmptyAlgorithm is a stub for unsupported collision pairs.
+///The dispatcher can dispatch a persistent EmptyAlgorithm to avoid a search every frame.
+class EmptyAlgorithm : public CollisionAlgorithm
+{
+
+public:
+
+ EmptyAlgorithm(const CollisionAlgorithmConstructionInfo& ci);
+
+ virtual void ProcessCollision (BroadphaseProxy* proxy0,BroadphaseProxy* proxy1,float timeStep, int stepCount, bool useContinuous);
+
+ virtual float CalculateTimeOfImpact(BroadphaseProxy* proxy0,BroadphaseProxy* proxy1,float timeStep,int stepCount);
+
+
+
+
+} ATTRIBUTE_ALIGNED(16);
+
+#endif //EMPTY_ALGORITH
diff --git a/extern/bullet/BulletDynamics/CollisionDispatch/ManifoldResult.cpp b/extern/bullet/BulletDynamics/CollisionDispatch/ManifoldResult.cpp
new file mode 100644
index 00000000000..2fd712221ac
--- /dev/null
+++ b/extern/bullet/BulletDynamics/CollisionDispatch/ManifoldResult.cpp
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies.
+ * Erwin Coumans makes no representations about the suitability
+ * of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+*/
+
+#include "ManifoldResult.h"
+#include "NarrowPhaseCollision/PersistentManifold.h"
+#include "Dynamics/RigidBody.h"
+
+ManifoldResult::ManifoldResult(RigidBody* body0,RigidBody* body1,PersistentManifold* manifoldPtr)
+ :m_manifoldPtr(manifoldPtr),
+ m_body0(body0),
+ m_body1(body1)
+ {
+ }
+
+void ManifoldResult::AddContactPoint(const SimdVector3& normalOnBInWorld,const SimdVector3& pointInWorld,float depth)
+{
+ if (depth > m_manifoldPtr->GetManifoldMargin())
+ return;
+
+ SimdTransform transAInv = m_body0->getCenterOfMassTransform().inverse();
+ SimdTransform transBInv= m_body1->getCenterOfMassTransform().inverse();
+ SimdVector3 pointA = pointInWorld + normalOnBInWorld * depth;
+ SimdVector3 localA = transAInv(pointA );
+ SimdVector3 localB = transBInv(pointInWorld);
+ ManifoldPoint newPt(localA,localB,normalOnBInWorld,depth);
+
+
+
+ int insertIndex = m_manifoldPtr->GetCacheEntry(newPt);
+ if (insertIndex >= 0)
+ {
+ m_manifoldPtr->ReplaceContactPoint(newPt,insertIndex);
+ } else
+ {
+ m_manifoldPtr->AddManifoldPoint(newPt);
+ }
+}
+
diff --git a/extern/bullet/BulletDynamics/CollisionDispatch/ManifoldResult.h b/extern/bullet/BulletDynamics/CollisionDispatch/ManifoldResult.h
new file mode 100644
index 00000000000..a06497e315c
--- /dev/null
+++ b/extern/bullet/BulletDynamics/CollisionDispatch/ManifoldResult.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies.
+ * Erwin Coumans makes no representations about the suitability
+ * of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+*/
+
+#ifndef MANIFOLD_RESULT_H
+#define MANIFOLD_RESULT_H
+
+#include "NarrowPhaseCollision/DiscreteCollisionDetectorInterface.h"
+class RigidBody;
+class PersistentManifold;
+
+
+class ManifoldResult : public DiscreteCollisionDetectorInterface::Result
+{
+ PersistentManifold* m_manifoldPtr;
+ RigidBody* m_body0;
+ RigidBody* m_body1;
+
+public:
+
+ ManifoldResult(RigidBody* body0,RigidBody* body1,PersistentManifold* manifoldPtr);
+
+
+ virtual void AddContactPoint(const SimdVector3& normalOnBInWorld,const SimdVector3& pointInWorld,float depth);
+
+};
+
+#endif //MANIFOLD_RESULT_H
diff --git a/extern/bullet/BulletDynamics/CollisionDispatch/ToiContactDispatcher.cpp b/extern/bullet/BulletDynamics/CollisionDispatch/ToiContactDispatcher.cpp
new file mode 100644
index 00000000000..fab0d7e384d
--- /dev/null
+++ b/extern/bullet/BulletDynamics/CollisionDispatch/ToiContactDispatcher.cpp
@@ -0,0 +1,221 @@
+#include "ToiContactDispatcher.h"
+#include "ConstraintSolver/ConstraintSolver.h"
+#include "Dynamics/RigidBody.h"
+#include "BroadphaseCollision/CollisionAlgorithm.h"
+#include "ConstraintSolver/ContactSolverInfo.h"
+#include "CollisionDispatch/ConvexConvexAlgorithm.h"
+#include "CollisionDispatch/EmptyCollisionAlgorithm.h"
+#include "CollisionDispatch/ConvexConcaveCollisionAlgorithm.h"
+
+#define MAX_RIGIDBODIES 128
+
+
+void ToiContactDispatcher::FindUnions()
+{
+ if (m_useIslands)
+ {
+ for (int i=0;i<GetNumManifolds();i++)
+ {
+ const PersistentManifold* manifold = this->GetManifoldByIndexInternal(i);
+ //static objects (invmass 0.f) don't merge !
+ if ((((RigidBody*)manifold->GetBody0()) && (((RigidBody*)manifold->GetBody0())->mergesSimulationIslands())) &&
+ (((RigidBody*)manifold->GetBody1()) && (((RigidBody*)manifold->GetBody1())->mergesSimulationIslands())))
+ {
+
+ m_unionFind.unite(((RigidBody*)manifold->GetBody0())->m_islandTag1,
+ ((RigidBody*)manifold->GetBody1())->m_islandTag1);
+ }
+
+
+ }
+ }
+
+}
+
+
+
+ToiContactDispatcher::ToiContactDispatcher (ConstraintSolver* solver):
+ m_useIslands(true),
+ m_unionFind(MAX_RIGIDBODIES),
+ m_solver(solver),
+ m_count(0)
+
+{
+ int i;
+
+ for (i=0;i<MAX_BROADPHASE_COLLISION_TYPES;i++)
+ {
+ for (int j=0;j<MAX_BROADPHASE_COLLISION_TYPES;j++)
+ {
+ m_doubleDispatch[i][j] = 0;
+ }
+ }
+
+
+};
+
+PersistentManifold* ToiContactDispatcher::GetNewManifold(void* b0,void* b1)
+{
+
+ RigidBody* body0 = (RigidBody*)b0;
+ RigidBody* body1 = (RigidBody*)b1;
+
+ PersistentManifold* manifold = new PersistentManifold (body0,body1);
+ m_manifoldsPtr.push_back(manifold);
+
+ return manifold;
+}
+#include <algorithm>
+
+void ToiContactDispatcher::ReleaseManifold(PersistentManifold* manifold)
+{
+ manifold->ClearManifold();
+
+ std::vector<PersistentManifold*>::iterator i =
+ std::find(m_manifoldsPtr.begin(), m_manifoldsPtr.end(), manifold);
+ if (!(i == m_manifoldsPtr.end()))
+ {
+ std::swap(*i, m_manifoldsPtr.back());
+ m_manifoldsPtr.pop_back();
+ }
+
+
+}
+
+
+//
+// todo: this is random access, it can be walked 'cache friendly'!
+//
+void ToiContactDispatcher::SolveConstraints(float timeStep, int numIterations,int numRigidBodies)
+{
+ int i;
+
+ int numManifolds;
+
+ for (int islandId=0;islandId<numRigidBodies;islandId++)
+ {
+ numManifolds = 0;
+
+ PersistentManifold* manifolds[MAX_MANIFOLDS];
+
+
+ //int numSleeping = 0;
+
+ bool allSleeping = true;
+
+ for (i=0;i<GetNumManifolds();i++)
+ {
+ PersistentManifold* manifold = this->GetManifoldByIndexInternal(i);
+ if ((((RigidBody*)manifold->GetBody0()) && ((RigidBody*)manifold->GetBody0())->m_islandTag1 == (islandId)) ||
+ (((RigidBody*)manifold->GetBody1()) && ((RigidBody*)manifold->GetBody1())->m_islandTag1 == (islandId)))
+ {
+
+ if ((((RigidBody*)manifold->GetBody0()) && ((RigidBody*)manifold->GetBody0())->GetActivationState()== ACTIVE_TAG) ||
+ (((RigidBody*)manifold->GetBody1()) && ((RigidBody*)manifold->GetBody1())->GetActivationState() == ACTIVE_TAG))
+ {
+ allSleeping = false;
+ }
+
+ manifolds[numManifolds] = manifold;
+ numManifolds++;
+ }
+ }
+ if (allSleeping)
+ {
+ //tag all as 'ISLAND_SLEEPING'
+ for (i=0;i<numManifolds;i++)
+ {
+ PersistentManifold* manifold = manifolds[i];
+ if (((RigidBody*)manifold->GetBody0()))
+ {
+ ((RigidBody*)manifold->GetBody0())->SetActivationState( ISLAND_SLEEPING );
+ }
+ if (((RigidBody*)manifold->GetBody1()))
+ {
+ ((RigidBody*)manifold->GetBody1())->SetActivationState( ISLAND_SLEEPING);
+ }
+
+ }
+ } else
+ {
+
+ //tag all as 'ISLAND_SLEEPING'
+ for (i=0;i<numManifolds;i++)
+ {
+ PersistentManifold* manifold = manifolds[i];
+ if (((RigidBody*)manifold->GetBody0()))
+ {
+ if ( ((RigidBody*)manifold->GetBody0())->GetActivationState() == ISLAND_SLEEPING)
+ {
+ ((RigidBody*)manifold->GetBody0())->SetActivationState( WANTS_DEACTIVATION );//ACTIVE_TAG;
+ }
+ }
+ if (((RigidBody*)manifold->GetBody1()))
+ {
+ if ( ((RigidBody*)manifold->GetBody1())->GetActivationState() == ISLAND_SLEEPING)
+ {
+ ((RigidBody*)manifold->GetBody1())->SetActivationState(WANTS_DEACTIVATION);//ACTIVE_TAG;
+ }
+ }
+
+ }
+
+ ///This island solving can all be scheduled in parallel
+ ContactSolverInfo info;
+ info.m_damping = 0.9f;
+ info.m_friction = 0.9f;
+ info.m_numIterations = numIterations;
+ info.m_timeStep = timeStep;
+ info.m_tau = 0.4f;
+ info.m_restitution = 0.1f;//m_restitution;
+
+ /*
+ int numManifolds = 0;
+
+ for (i=0;i<m_firstFreeManifold;i++)
+ {
+ PersistentManifold* manifold = &m_manifolds[m_freeManifolds[i]];
+ //ASSERT(((RigidBody*)manifold->GetBody0()));
+ //ASSERT(((RigidBody*)manifold->GetBody1()));
+ manifolds[i] = manifold;
+ numManifolds++;
+ }
+*/
+ m_solver->SolveGroup( manifolds, numManifolds,info );
+
+ }
+ }
+
+
+
+
+}
+
+
+
+CollisionAlgorithm* ToiContactDispatcher::InternalFindAlgorithm(BroadphaseProxy& proxy0,BroadphaseProxy& proxy1)
+{
+ m_count++;
+
+ CollisionAlgorithmConstructionInfo ci;
+ ci.m_dispatcher = this;
+
+ if (proxy0.IsConvexShape() && proxy1.IsConvexShape() )
+ {
+ return new ConvexConvexAlgorithm(0,ci,&proxy0,&proxy1);
+ }
+
+ if (proxy0.IsConvexShape() && proxy1.IsConcaveShape())
+ {
+ return new ConvexConcaveCollisionAlgorithm(ci,&proxy0,&proxy1);
+ }
+
+ if (proxy1.IsConvexShape() && proxy0.IsConcaveShape())
+ {
+ return new ConvexConcaveCollisionAlgorithm(ci,&proxy1,&proxy0);
+ }
+
+ //failed to find an algorithm
+ return new EmptyAlgorithm(ci);
+
+}
diff --git a/extern/bullet/BulletDynamics/CollisionDispatch/ToiContactDispatcher.h b/extern/bullet/BulletDynamics/CollisionDispatch/ToiContactDispatcher.h
new file mode 100644
index 00000000000..818901cb901
--- /dev/null
+++ b/extern/bullet/BulletDynamics/CollisionDispatch/ToiContactDispatcher.h
@@ -0,0 +1,105 @@
+#ifndef TOI_CONTACT_DISPATCHER_H
+#define TOI_CONTACT_DISPATCHER_H
+
+#include "BroadphaseCollision/CollisionDispatcher.h"
+#include "NarrowPhaseCollision/PersistentManifold.h"
+#include "CollisionDispatch/UnionFind.h"
+#include "BroadphaseCollision/BroadphaseProxy.h"
+
+class ConstraintSolver;
+
+//island management
+#define ACTIVE_TAG 1
+#define ISLAND_SLEEPING 2
+#define WANTS_DEACTIVATION 3
+
+#define MAX_MANIFOLDS 512
+
+struct CollisionAlgorithmCreateFunc
+{
+ bool m_swapped;
+
+ CollisionAlgorithmCreateFunc()
+ :m_swapped(false)
+ {
+ }
+ virtual CollisionAlgorithm* CreateCollisionAlgorithm(BroadphaseProxy& proxy0,BroadphaseProxy& proxy1)
+ {
+ return 0;
+ }
+};
+#include <vector>
+///ToiContactDispatcher (Time of Impact) is the main collision dispatcher.
+///Basic implementation supports algorithms that handle ConvexConvex and ConvexConcave collision pairs.
+///Time of Impact, Closest Points and Penetration Depth.
+class ToiContactDispatcher : public Dispatcher
+{
+
+ bool m_useIslands;
+
+
+ std::vector<PersistentManifold*> m_manifoldsPtr;
+
+// PersistentManifold m_manifolds[MAX_MANIFOLDS];
+// int m_freeManifolds[MAX_MANIFOLDS];
+
+ UnionFind m_unionFind;
+ ConstraintSolver* m_solver;
+
+ CollisionAlgorithmCreateFunc* m_doubleDispatch[MAX_BROADPHASE_COLLISION_TYPES][MAX_BROADPHASE_COLLISION_TYPES];
+
+public:
+
+ UnionFind& GetUnionFind() { return m_unionFind;}
+
+// int m_firstFreeManifold;
+
+// const PersistentManifold* GetManifoldByIndexInternal(int index)
+// {
+// return &m_manifolds[index];
+// }
+
+ int GetNumManifolds() { return m_manifoldsPtr.size();}
+
+ PersistentManifold* GetManifoldByIndexInternal(int index)
+ {
+ return m_manifoldsPtr[index];
+ }
+
+
+ void InitUnionFind()
+ {
+ if (m_useIslands)
+ m_unionFind.reset();
+ }
+
+ void FindUnions();
+
+ int m_count;
+
+ ToiContactDispatcher (ConstraintSolver* solver);
+
+ virtual PersistentManifold* GetNewManifold(void* b0,void* b1);
+
+ virtual void ReleaseManifold(PersistentManifold* manifold);
+
+ //
+ // todo: this is random access, it can be walked 'cache friendly'!
+ //
+ virtual void SolveConstraints(float timeStep, int numIterations,int numRigidBodies);
+
+
+ CollisionAlgorithm* FindAlgorithm(BroadphaseProxy& proxy0,BroadphaseProxy& proxy1)
+ {
+ CollisionAlgorithm* algo = InternalFindAlgorithm(proxy0,proxy1);
+ return algo;
+ }
+
+ CollisionAlgorithm* InternalFindAlgorithm(BroadphaseProxy& proxy0,BroadphaseProxy& proxy1);
+
+ virtual int GetUniqueId() { return RIGIDBODY_DISPATCHER;}
+
+};
+
+#endif //TOI_CONTACT_DISPATCHER_H
+
diff --git a/extern/bullet/BulletDynamics/CollisionDispatch/UnionFind.cpp b/extern/bullet/BulletDynamics/CollisionDispatch/UnionFind.cpp
new file mode 100644
index 00000000000..2983b409aa3
--- /dev/null
+++ b/extern/bullet/BulletDynamics/CollisionDispatch/UnionFind.cpp
@@ -0,0 +1,54 @@
+#include "UnionFind.h"
+#include <assert.h>
+
+
+int UnionFind::find(int x)
+{
+ assert(x < m_N);
+ assert(x >= 0);
+
+ while (x != id[x])
+ {
+ x = id[x];
+ assert(x < m_N);
+ assert(x >= 0);
+
+ }
+ return x;
+}
+
+UnionFind::UnionFind(int N)
+:m_N(N)
+{
+ id = new int[N]; sz = new int[N];
+ reset();
+}
+
+void UnionFind::reset()
+{
+ for (int i = 0; i < m_N; i++)
+ {
+ id[i] = i; sz[i] = 1;
+ }
+}
+
+
+int UnionFind ::find(int p, int q)
+{
+ return (find(p) == find(q));
+}
+
+void UnionFind ::unite(int p, int q)
+{
+ int i = find(p), j = find(q);
+ if (i == j)
+ return;
+ if (sz[i] < sz[j])
+ {
+ id[i] = j; sz[j] += sz[i];
+ }
+ else
+ {
+ id[j] = i; sz[i] += sz[j];
+ }
+}
diff --git a/extern/bullet/BulletDynamics/CollisionDispatch/UnionFind.h b/extern/bullet/BulletDynamics/CollisionDispatch/UnionFind.h
new file mode 100644
index 00000000000..0dc57783283
--- /dev/null
+++ b/extern/bullet/BulletDynamics/CollisionDispatch/UnionFind.h
@@ -0,0 +1,21 @@
+#ifndef UNION_FIND_H
+#define UNION_FIND_H
+
+///UnionFind calculates connected subsets
+class UnionFind
+ {
+ private:
+ int *id, *sz;
+ int m_N;
+
+ public:
+ int find(int x);
+ UnionFind(int N);
+ void reset();
+
+ int find(int p, int q);
+ void unite(int p, int q);
+ };
+
+
+#endif //UNION_FIND_H
diff --git a/extern/bullet/BulletDynamics/ConstraintSolver/ConstraintSolver.h b/extern/bullet/BulletDynamics/ConstraintSolver/ConstraintSolver.h
new file mode 100644
index 00000000000..e1512ae1756
--- /dev/null
+++ b/extern/bullet/BulletDynamics/ConstraintSolver/ConstraintSolver.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies.
+ * Erwin Coumans makes no representations about the suitability
+ * of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+*/
+#ifndef CONSTRAINT_SOLVER_H
+#define CONSTRAINT_SOLVER_H
+
+class PersistentManifold;
+class RigidBody;
+
+struct ContactSolverInfo;
+struct BroadphaseProxy;
+
+/// ConstraintSolver provides solver interface
+class ConstraintSolver
+{
+
+public:
+
+ virtual ~ConstraintSolver() {}
+
+ virtual float SolveGroup(PersistentManifold** manifold,int numManifolds,const ContactSolverInfo& info) = 0;
+
+};
+
+
+
+
+#endif //CONSTRAINT_SOLVER_H
diff --git a/extern/bullet/BulletDynamics/ConstraintSolver/ContactConstraint.cpp b/extern/bullet/BulletDynamics/ConstraintSolver/ContactConstraint.cpp
new file mode 100644
index 00000000000..e3603ccec67
--- /dev/null
+++ b/extern/bullet/BulletDynamics/ConstraintSolver/ContactConstraint.cpp
@@ -0,0 +1,324 @@
+/*
+ * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies.
+ * Erwin Coumans makes no representations about the suitability
+ * of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+*/
+#include "ContactConstraint.h"
+#include "Dynamics/RigidBody.h"
+#include "SimdVector3.h"
+#include "JacobianEntry.h"
+#include "ContactSolverInfo.h"
+#include "GEN_minmax.h"
+
+#define ASSERT2 assert
+
+
+static SimdScalar ContactThreshold = -10.0f;
+
+float useGlobalSettingContacts = false;//true;
+
+SimdScalar contactDamping = 0.9f;
+SimdScalar contactTau = .2f;//0.02f;//*0.02f;
+
+
+
+SimdScalar restitutionCurve(SimdScalar rel_vel, SimdScalar restitution)
+{
+ return restitution;
+// return restitution * GEN_min(1.0f, rel_vel / ContactThreshold);
+}
+
+void applyFrictionInContactPointOld(RigidBody& body1, const SimdVector3& pos1,
+ RigidBody& body2, const SimdVector3& pos2,
+ const SimdVector3& normal,float normalImpulse,
+ const ContactSolverInfo& solverInfo)
+{
+
+
+ if (normalImpulse>0.f)
+ {
+ SimdVector3 rel_pos1 = pos1 - body1.getCenterOfMassPosition();
+ SimdVector3 rel_pos2 = pos2 - body2.getCenterOfMassPosition();
+
+ SimdVector3 vel1 = body1.getVelocityInLocalPoint(rel_pos1);
+ SimdVector3 vel2 = body2.getVelocityInLocalPoint(rel_pos2);
+ SimdVector3 vel = vel1 - vel2;
+
+ SimdScalar rel_vel = normal.dot(vel);
+
+#define PER_CONTACT_FRICTION
+#ifdef PER_CONTACT_FRICTION
+ SimdVector3 lat_vel = vel - normal * rel_vel;
+ SimdScalar lat_rel_vel = lat_vel.length();
+
+ if (lat_rel_vel > SIMD_EPSILON)
+ {
+ lat_vel /= lat_rel_vel;
+ SimdVector3 temp1 = body1.getInvInertiaTensorWorld() * rel_pos1.cross(lat_vel);
+ SimdVector3 temp2 = body2.getInvInertiaTensorWorld() * rel_pos2.cross(lat_vel);
+ SimdScalar frictionMaxImpulse = lat_rel_vel /
+ (body1.getInvMass() + body2.getInvMass() + lat_vel.dot(temp1.cross(rel_pos1) + temp2.cross(rel_pos2)));
+ SimdScalar frictionImpulse = (normalImpulse) * solverInfo.m_friction;
+ GEN_set_min(frictionImpulse,frictionMaxImpulse );
+
+ body1.applyImpulse(lat_vel * -frictionImpulse, rel_pos1);
+ body2.applyImpulse(lat_vel * frictionImpulse, rel_pos2);
+
+ }
+#endif
+ }
+}
+
+
+//bilateral constraint between two dynamic objects
+void resolveSingleBilateral(RigidBody& body1, const SimdVector3& pos1,
+ RigidBody& body2, const SimdVector3& pos2,
+ SimdScalar depth, const SimdVector3& normal,SimdScalar& impulse ,float timeStep)
+{
+ float normalLenSqr = normal.length2();
+ ASSERT2(fabs(normalLenSqr) < 1.1f);
+ if (normalLenSqr > 1.1f)
+ {
+ impulse = 0.f;
+ return;
+ }
+ SimdVector3 rel_pos1 = pos1 - body1.getCenterOfMassPosition();
+ SimdVector3 rel_pos2 = pos2 - body2.getCenterOfMassPosition();
+ //this jacobian entry could be re-used for all iterations
+
+ SimdVector3 vel1 = body1.getVelocityInLocalPoint(rel_pos1);
+ SimdVector3 vel2 = body2.getVelocityInLocalPoint(rel_pos2);
+ SimdVector3 vel = vel1 - vel2;
+
+ SimdScalar rel_vel;
+
+ /*
+
+ JacobianEntry jac(body1.getCenterOfMassTransform().getBasis().transpose(),
+ body2.getCenterOfMassTransform().getBasis().transpose(),
+ rel_pos1,rel_pos2,normal,body1.getInvInertiaDiagLocal(),body1.getInvMass(),
+ body2.getInvInertiaDiagLocal(),body2.getInvMass());
+
+ SimdScalar jacDiagAB = jac.getDiagonal();
+ SimdScalar jacDiagABInv = 1.f / jacDiagAB;
+
+ SimdScalar rel_vel = jac.getRelativeVelocity(
+ body1.getLinearVelocity(),
+ body1.getCenterOfMassTransform().getBasis().transpose() * body1.getAngularVelocity(),
+ body2.getLinearVelocity(),
+ body2.getCenterOfMassTransform().getBasis().transpose() * body2.getAngularVelocity());
+ float a;
+ a=jacDiagABInv;
+
+ */
+ rel_vel = normal.dot(vel);
+
+
+
+
+ /*int color = 255+255*256;
+
+ DrawRasterizerLine(pos1,pos1+normal,color);
+*/
+
+
+ SimdScalar massTerm = 1.f / (body1.getInvMass() + body2.getInvMass());
+
+ float contactDamping = 0.9f;
+ impulse = - contactDamping * rel_vel * massTerm;//jacDiagABInv;
+
+ //SimdScalar velocityImpulse = -contactDamping * rel_vel * jacDiagABInv;
+ //impulse = velocityImpulse;
+
+}
+
+
+
+
+
+//velocity + friction
+//response between two dynamic objects with friction
+float resolveSingleCollision(RigidBody& body1, const SimdVector3& pos1,
+ RigidBody& body2, const SimdVector3& pos2,
+ SimdScalar depth, const SimdVector3& normal,
+ const ContactSolverInfo& solverInfo
+ )
+{
+
+ float normalLenSqr = normal.length2();
+ ASSERT2(fabs(normalLenSqr) < 1.1f);
+ if (normalLenSqr > 1.1f)
+ return 0.f;
+
+ SimdVector3 rel_pos1 = pos1 - body1.getCenterOfMassPosition();
+ SimdVector3 rel_pos2 = pos2 - body2.getCenterOfMassPosition();
+ //this jacobian entry could be re-used for all iterations
+
+ SimdVector3 vel1 = body1.getVelocityInLocalPoint(rel_pos1);
+ SimdVector3 vel2 = body2.getVelocityInLocalPoint(rel_pos2);
+ SimdVector3 vel = vel1 - vel2;
+ SimdScalar rel_vel;
+ rel_vel = normal.dot(vel);
+
+// if (rel_vel< 0.f)//-SIMD_EPSILON)
+// {
+ SimdScalar rest = restitutionCurve(rel_vel, solverInfo.m_restitution);
+
+ SimdScalar timeCorrection = 1.f;///timeStep;
+ float damping = solverInfo.m_damping ;
+ float tau = solverInfo.m_tau;
+
+ if (useGlobalSettingContacts)
+ {
+ damping = contactDamping;
+ tau = contactTau;
+ }
+
+ if (depth < 0.f)
+ return 0.f;//bdepth = 0.f;
+
+ SimdScalar penetrationImpulse = (depth*tau*timeCorrection);// * massTerm;//jacDiagABInv
+
+ SimdScalar velocityImpulse = -(1.0f + rest) * damping * rel_vel;
+
+ SimdScalar impulse = penetrationImpulse + velocityImpulse;
+ SimdVector3 temp1 = body1.getInvInertiaTensorWorld() * rel_pos1.cross(normal);
+ SimdVector3 temp2 = body2.getInvInertiaTensorWorld() * rel_pos2.cross(normal);
+ impulse /=
+ (body1.getInvMass() + body2.getInvMass() + normal.dot(temp1.cross(rel_pos1) + temp2.cross(rel_pos2)));
+
+ if (impulse > 0.f)
+ {
+
+ body1.applyImpulse(normal*(impulse), rel_pos1);
+ body2.applyImpulse(-normal*(impulse), rel_pos2);
+ } else
+ {
+ impulse = 0.f;
+ }
+
+ return impulse;//velocityImpulse;//impulse;
+
+}
+
+
+
+//velocity + friction
+//response between two dynamic objects with friction
+float resolveSingleCollisionWithFriction(
+
+ RigidBody& body1,
+ const SimdVector3& pos1,
+ RigidBody& body2,
+ const SimdVector3& pos2,
+ SimdScalar depth,
+ const SimdVector3& normal,
+
+ const ContactSolverInfo& solverInfo
+ )
+{
+ float normalLenSqr = normal.length2();
+ ASSERT2(fabs(normalLenSqr) < 1.1f);
+ if (normalLenSqr > 1.1f)
+ return 0.f;
+
+ SimdVector3 rel_pos1 = pos1 - body1.getCenterOfMassPosition();
+ SimdVector3 rel_pos2 = pos2 - body2.getCenterOfMassPosition();
+ //this jacobian entry could be re-used for all iterations
+
+ JacobianEntry jac(body1.getCenterOfMassTransform().getBasis().transpose(),
+ body2.getCenterOfMassTransform().getBasis().transpose(),
+ rel_pos1,rel_pos2,normal,body1.getInvInertiaDiagLocal(),body1.getInvMass(),
+ body2.getInvInertiaDiagLocal(),body2.getInvMass());
+
+ SimdScalar jacDiagAB = jac.getDiagonal();
+ SimdScalar jacDiagABInv = 1.f / jacDiagAB;
+ SimdVector3 vel1 = body1.getVelocityInLocalPoint(rel_pos1);
+ SimdVector3 vel2 = body2.getVelocityInLocalPoint(rel_pos2);
+ SimdVector3 vel = vel1 - vel2;
+SimdScalar rel_vel;
+ /* rel_vel = jac.getRelativeVelocity(
+ body1.getLinearVelocity(),
+ body1.getTransform().getBasis().transpose() * body1.getAngularVelocity(),
+ body2.getLinearVelocity(),
+ body2.getTransform().getBasis().transpose() * body2.getAngularVelocity());
+*/
+ rel_vel = normal.dot(vel);
+
+// if (rel_vel< 0.f)//-SIMD_EPSILON)
+// {
+ SimdScalar rest = restitutionCurve(rel_vel, solverInfo.m_restitution);
+// SimdScalar massTerm = 1.f / (body1.getInvMass() + body2.getInvMass());
+
+ SimdScalar timeCorrection = 0.5f / solverInfo.m_timeStep ;
+
+ float damping = solverInfo.m_damping ;
+ float tau = solverInfo.m_tau;
+
+ if (useGlobalSettingContacts)
+ {
+ damping = contactDamping;
+ tau = contactTau;
+ }
+ SimdScalar penetrationImpulse = (depth* tau *timeCorrection) * jacDiagABInv;
+
+ if (penetrationImpulse < 0.f)
+ penetrationImpulse = 0.f;
+
+
+
+ SimdScalar velocityImpulse = -(1.0f + rest) * damping * rel_vel * jacDiagABInv;
+
+ SimdScalar friction_impulse = 0.f;
+
+ if (velocityImpulse <= 0.f)
+ velocityImpulse = 0.f;
+
+// SimdScalar impulse = penetrationImpulse + velocityImpulse;
+ //if (impulse > 0.f)
+ {
+// SimdVector3 impulse_vector = normal * impulse;
+ body1.applyImpulse(normal*(velocityImpulse+penetrationImpulse), rel_pos1);
+
+ body2.applyImpulse(-normal*(velocityImpulse+penetrationImpulse), rel_pos2);
+
+ //friction
+
+ {
+
+ SimdVector3 vel1 = body1.getVelocityInLocalPoint(rel_pos1);
+ SimdVector3 vel2 = body2.getVelocityInLocalPoint(rel_pos2);
+ SimdVector3 vel = vel1 - vel2;
+
+ rel_vel = normal.dot(vel);
+
+#define PER_CONTACT_FRICTION
+#ifdef PER_CONTACT_FRICTION
+ SimdVector3 lat_vel = vel - normal * rel_vel;
+ SimdScalar lat_rel_vel = lat_vel.length();
+
+ if (lat_rel_vel > SIMD_EPSILON)
+ {
+ lat_vel /= lat_rel_vel;
+ SimdVector3 temp1 = body1.getInvInertiaTensorWorld() * rel_pos1.cross(lat_vel);
+ SimdVector3 temp2 = body2.getInvInertiaTensorWorld() * rel_pos2.cross(lat_vel);
+ friction_impulse = lat_rel_vel /
+ (body1.getInvMass() + body2.getInvMass() + lat_vel.dot(temp1.cross(rel_pos1) + temp2.cross(rel_pos2)));
+ SimdScalar normal_impulse = (penetrationImpulse+
+ velocityImpulse) * solverInfo.m_friction;
+ GEN_set_min(friction_impulse, normal_impulse);
+
+ body1.applyImpulse(lat_vel * -friction_impulse, rel_pos1);
+ body2.applyImpulse(lat_vel * friction_impulse, rel_pos2);
+
+ }
+#endif
+ }
+ }
+ return velocityImpulse + friction_impulse;
+}
diff --git a/extern/bullet/BulletDynamics/ConstraintSolver/ContactConstraint.h b/extern/bullet/BulletDynamics/ConstraintSolver/ContactConstraint.h
new file mode 100644
index 00000000000..0f835546783
--- /dev/null
+++ b/extern/bullet/BulletDynamics/ConstraintSolver/ContactConstraint.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies.
+ * Erwin Coumans makes no representations about the suitability
+ * of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+*/
+#ifndef CONTACT_CONSTRAINT_H
+#define CONTACT_CONSTRAINT_H
+
+//todo: make into a proper class working with the iterative constraint solver
+
+class RigidBody;
+#include "SimdVector3.h"
+#include "SimdScalar.h"
+struct ContactSolverInfo;
+
+///bilateral constraint between two dynamic objects
+void resolveSingleBilateral(RigidBody& body1, const SimdVector3& pos1,
+ RigidBody& body2, const SimdVector3& pos2,
+ SimdScalar depth, const SimdVector3& normal,SimdScalar& impulse ,float timeStep);
+
+
+//contact constraint resolution:
+//calculate and apply impulse to satisfy non-penetration and non-negative relative velocity constraint
+float resolveSingleCollision(RigidBody& body1, const SimdVector3& pos1,
+ RigidBody& body2, const SimdVector3& pos2,
+ SimdScalar depth, const SimdVector3& normal,
+ const ContactSolverInfo& info);
+
+
+/// apply friction force to simulate friction in a contact point related to the normal impulse
+void applyFrictionInContactPointOld(RigidBody& body1, const SimdVector3& pos1,
+ RigidBody& body2, const SimdVector3& pos2,
+ const SimdVector3& normal,float normalImpulse,
+ const ContactSolverInfo& info);
+
+//contact constraint resolution:
+//calculate and apply impulse to satisfy non-penetration and non-negative relative velocity constraint
+float resolveSingleCollisionWithFriction(RigidBody& body1, const SimdVector3& pos1,
+ RigidBody& body2, const SimdVector3& pos2,
+ SimdScalar depth, const SimdVector3& normal,
+ const ContactSolverInfo& info);
+
+#endif //CONTACT_CONSTRAINT_H
diff --git a/extern/bullet/BulletDynamics/ConstraintSolver/ContactSolverInfo.h b/extern/bullet/BulletDynamics/ConstraintSolver/ContactSolverInfo.h
new file mode 100644
index 00000000000..83460771279
--- /dev/null
+++ b/extern/bullet/BulletDynamics/ConstraintSolver/ContactSolverInfo.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies.
+ * Erwin Coumans makes no representations about the suitability
+ * of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+*/
+#ifndef CONTACT_SOLVER_INFO
+#define CONTACT_SOLVER_INFO
+
+
+struct ContactSolverInfo
+{
+
+ inline ContactSolverInfo()
+ {
+ m_tau = 0.4f;
+ m_damping = 0.9f;
+ m_friction = 0.3f;
+ m_restitution = 0.f;
+ m_maxErrorReduction = 20.f;
+ m_numIterations = 10;
+ }
+
+ float m_tau;
+ float m_damping;
+ float m_friction;
+ float m_timeStep;
+ float m_restitution;
+ int m_numIterations;
+ float m_maxErrorReduction;
+
+
+};
+
+#endif //CONTACT_SOLVER_INFO
diff --git a/extern/bullet/BulletDynamics/ConstraintSolver/JacobianEntry.h b/extern/bullet/BulletDynamics/ConstraintSolver/JacobianEntry.h
new file mode 100644
index 00000000000..c1f3a521f2d
--- /dev/null
+++ b/extern/bullet/BulletDynamics/ConstraintSolver/JacobianEntry.h
@@ -0,0 +1,129 @@
+/*
+ * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies.
+ * Erwin Coumans makes no representations about the suitability
+ * of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+*/
+#ifndef JACOBIAN_ENTRY_H
+#define JACOBIAN_ENTRY_H
+
+#include "SimdVector3.h"
+#include "Dynamics/RigidBody.h"
+
+
+//notes:
+// Another memory optimization would be to store m_MbJ in the remaining 3 w components
+// which makes the JacobianEntry memory layout 16 bytes
+// if you only are interested in angular part, just feed massInvA and massInvB zero
+
+/// Jacobian entry is an abstraction that allows to describe constraints
+/// it can be used in combination with a constraint solver
+/// Can be used to relate the effect of an impulse to the constraint error
+class JacobianEntry
+{
+public:
+ JacobianEntry() {};
+ //constraint between two different rigidbodies
+ JacobianEntry(
+ const SimdMatrix3x3& world2A,
+ const SimdMatrix3x3& world2B,
+ const SimdVector3& rel_pos1,const SimdVector3& rel_pos2,
+ const SimdVector3& normal,
+ const SimdVector3& inertiaInvA,
+ const SimdScalar massInvA,
+ const SimdVector3& inertiaInvB,
+ const SimdScalar massInvB)
+ :m_normalAxis(normal)
+ {
+ m_aJ = world2A*(rel_pos1.cross(normal));
+ m_bJ = world2B*(rel_pos2.cross(normal));
+ m_MaJ = inertiaInvA * m_aJ;
+ m_MbJ = inertiaInvB * m_bJ;
+ m_jacDiagAB = massInvA + m_MaJ.dot(m_aJ) + massInvB + m_MbJ.dot(m_bJ);
+ }
+
+ //angular constraint between two different rigidbodies
+ JacobianEntry(const SimdVector3& normal,
+ const SimdMatrix3x3& world2A,
+ const SimdMatrix3x3& world2B,
+ const SimdVector3& inertiaInvA,
+ const SimdVector3& inertiaInvB)
+ :m_normalAxis(normal)
+ {
+ m_aJ= world2A*normal;
+ m_bJ = world2B*-normal;
+ m_MaJ = inertiaInvA * m_aJ;
+ m_MbJ = inertiaInvB * m_bJ;
+ m_jacDiagAB = m_MaJ.dot(m_aJ) + m_MbJ.dot(m_bJ);
+ }
+
+ //constraint on one rigidbody
+ JacobianEntry(
+ const SimdMatrix3x3& world2A,
+ const SimdVector3& rel_pos1,const SimdVector3& rel_pos2,
+ const SimdVector3& normal,
+ const SimdVector3& inertiaInvA,
+ const SimdScalar massInvA)
+ :m_normalAxis(normal)
+ {
+ m_aJ= world2A*(rel_pos1.cross(normal));
+ m_bJ = world2A*(rel_pos2.cross(normal));
+ m_MaJ = inertiaInvA * m_aJ;
+ m_MbJ = SimdVector3(0.f,0.f,0.f);
+ m_jacDiagAB = massInvA + m_MaJ.dot(m_aJ);
+ }
+
+ SimdScalar getDiagonal() const { return m_jacDiagAB; }
+
+ // for two constraints on the same rigidbody (for example vehicle friction)
+ SimdScalar getNonDiagonal(const JacobianEntry& jacB, const SimdScalar massInvA) const
+ {
+ const JacobianEntry& jacA = *this;
+ SimdScalar lin = massInvA * jacA.m_normalAxis.dot(jacB.m_normalAxis);
+ SimdScalar ang = jacA.m_MaJ.dot(jacB.m_aJ);
+ return lin + ang;
+ }
+
+
+
+ // for two constraints on sharing two same rigidbodies (for example two contact points between two rigidbodies)
+ SimdScalar getNonDiagonal(const JacobianEntry& jacB,const SimdScalar massInvA,const SimdScalar massInvB) const
+ {
+ const JacobianEntry& jacA = *this;
+ SimdVector3 lin = jacA.m_normalAxis * jacB.m_normalAxis;
+ SimdVector3 ang0 = jacA.m_MaJ * jacB.m_aJ;
+ SimdVector3 ang1 = jacA.m_MbJ * jacB.m_bJ;
+ SimdVector3 lin0 = massInvA * lin ;
+ SimdVector3 lin1 = massInvB * lin;
+ SimdVector3 sum = ang0+ang1+lin0+lin1;
+ return sum[0]+sum[1]+sum[2];
+ }
+
+ SimdScalar getRelativeVelocity(const SimdVector3& linvelA,const SimdVector3& angvelA,const SimdVector3& linvelB,const SimdVector3& angvelB)
+ {
+ SimdVector3 linrel = linvelA - linvelB;
+ SimdVector3 angvela = angvelA * m_aJ;
+ SimdVector3 angvelb = angvelB * m_bJ;
+ linrel *= m_normalAxis;
+ angvela += angvelb;
+ angvela += linrel;
+ SimdScalar rel_vel2 = angvela[0]+angvela[1]+angvela[2];
+ return rel_vel2 + SIMD_EPSILON;
+ }
+//private:
+
+ SimdVector3 m_normalAxis;
+ SimdVector3 m_aJ;
+ SimdVector3 m_bJ;
+ SimdVector3 m_MaJ;
+ SimdVector3 m_MbJ;
+ //Optimization: can be stored in the w/last component of one of the vectors
+ SimdScalar m_jacDiagAB;
+
+};
+
+#endif //JACOBIAN_ENTRY_H
diff --git a/extern/bullet/BulletDynamics/ConstraintSolver/OdeConstraintSolver.cpp b/extern/bullet/BulletDynamics/ConstraintSolver/OdeConstraintSolver.cpp
new file mode 100644
index 00000000000..8dc666d588f
--- /dev/null
+++ b/extern/bullet/BulletDynamics/ConstraintSolver/OdeConstraintSolver.cpp
@@ -0,0 +1,256 @@
+/*
+ * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies.
+ * Erwin Coumans makes no representations about the suitability
+ * of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+*/
+
+#include "OdeConstraintSolver.h"
+
+#include "NarrowPhaseCollision/PersistentManifold.h"
+#include "Dynamics/RigidBody.h"
+#include "ContactConstraint.h"
+#include "Solve2LinearConstraint.h"
+#include "ContactSolverInfo.h"
+#include "Dynamics/BU_Joint.h"
+#include "Dynamics/ContactJoint.h"
+
+#define USE_SOR_SOLVER
+
+#include "SorLcp.h"
+
+#include <math.h>
+#include <float.h>//FLT_MAX
+#ifdef WIN32
+#include <memory.h>
+#endif
+#include <string.h>
+#include <stdio.h>
+
+#ifdef WIN32
+#include <malloc.h>
+#else
+#include <alloca.h>
+#endif
+
+class BU_Joint;
+
+//see below
+
+int gCurBody = 0;
+int gCurJoint= 0;
+
+int ConvertBody(RigidBody* body,RigidBody** bodies,int& numBodies);
+void ConvertConstraint(PersistentManifold* manifold,BU_Joint** joints,int& numJoints,
+ RigidBody** bodies,int bodyId0,int bodyId1);
+
+
+
+
+
+//iterative lcp and penalty method
+float OdeConstraintSolver::SolveGroup(PersistentManifold** manifoldPtr, int numManifolds,const ContactSolverInfo& infoGlobal)
+{
+ gCurBody = 0;
+ gCurJoint = 0;
+
+ float cfm = 1e-5f;
+ float erp = 0.2f;
+
+ RigidBody* bodies [128];
+
+ int numBodies = 0;
+ BU_Joint* joints [128*5];
+ int numJoints = 0;
+
+ for (int j=0;j<numManifolds;j++)
+ {
+
+ int body0=-1,body1=-1;
+
+ PersistentManifold* manifold = manifoldPtr[j];
+ if (manifold->GetNumContacts() > 0)
+ {
+ body0 = ConvertBody((RigidBody*)manifold->GetBody0(),bodies,numBodies);
+ body1 = ConvertBody((RigidBody*)manifold->GetBody1(),bodies,numBodies);
+ ConvertConstraint(manifold,joints,numJoints,bodies,body0,body1);
+ }
+ }
+
+ SolveInternal1(cfm,erp,bodies,numBodies,joints,numJoints,infoGlobal);
+
+ return 0.f;
+
+}
+
+/////////////////////////////////////////////////////////////////////////////////
+
+
+typedef SimdScalar dQuaternion[4];
+#define _R(i,j) R[(i)*4+(j)]
+
+void dRfromQ1 (dMatrix3 R, const dQuaternion q)
+{
+ // q = (s,vx,vy,vz)
+ SimdScalar qq1 = 2*q[1]*q[1];
+ SimdScalar qq2 = 2*q[2]*q[2];
+ SimdScalar qq3 = 2*q[3]*q[3];
+ _R(0,0) = 1 - qq2 - qq3;
+ _R(0,1) = 2*(q[1]*q[2] - q[0]*q[3]);
+ _R(0,2) = 2*(q[1]*q[3] + q[0]*q[2]);
+ _R(1,0) = 2*(q[1]*q[2] + q[0]*q[3]);
+ _R(1,1) = 1 - qq1 - qq3;
+ _R(1,2) = 2*(q[2]*q[3] - q[0]*q[1]);
+ _R(2,0) = 2*(q[1]*q[3] - q[0]*q[2]);
+ _R(2,1) = 2*(q[2]*q[3] + q[0]*q[1]);
+ _R(2,2) = 1 - qq1 - qq2;
+}
+
+
+
+int ConvertBody(RigidBody* body,RigidBody** bodies,int& numBodies)
+{
+ if (!body || (body->getInvMass() == 0.f) )
+ {
+ return -1;
+ }
+ //first try to find
+ int i,j;
+ for (i=0;i<numBodies;i++)
+ {
+ if (bodies[i] == body)
+ return i;
+ }
+ //if not found, create a new body
+ bodies[numBodies++] = body;
+ //convert data
+
+
+ body->m_facc.setValue(0,0,0);
+ body->m_tacc.setValue(0,0,0);
+
+ //are the indices the same ?
+ for (i=0;i<4;i++)
+ {
+ for ( j=0;j<3;j++)
+ {
+ body->m_invI[i+4*j] = 0.f;
+ body->m_I[i+4*j] = 0.f;
+ }
+ }
+ body->m_invI[0+4*0] = body->getInvInertiaDiagLocal()[0];
+ body->m_invI[1+4*1] = body->getInvInertiaDiagLocal()[1];
+ body->m_invI[2+4*2] = body->getInvInertiaDiagLocal()[2];
+
+ body->m_I[0+0*4] = body->getInvInertiaDiagLocal()[0];
+ body->m_I[1+1*4] = body->getInvInertiaDiagLocal()[1];
+ body->m_I[2+2*4] = body->getInvInertiaDiagLocal()[2];
+
+
+ /*
+
+ SimdMatrix3x3 invI;
+ invI.setIdentity();
+ invI[0][0] = body->getInvInertiaDiagLocal()[0];
+ invI[1][1] = body->getInvInertiaDiagLocal()[1];
+ invI[2][2] = body->getInvInertiaDiagLocal()[2];
+ SimdMatrix3x3 inertia = invI.inverse();
+
+ for (i=0;i<3;i++)
+ {
+ for (j=0;j<3;j++)
+ {
+ body->m_I[i+4*j] = inertia[i][j];
+ }
+ }
+ */
+// body->m_I[3+0*4] = 0.f;
+// body->m_I[3+1*4] = 0.f;
+// body->m_I[3+2*4] = 0.f;
+// body->m_I[3+3*4] = 0.f;
+
+
+ dQuaternion q;
+
+ q[1] = body->getOrientation()[0];
+ q[2] = body->getOrientation()[1];
+ q[3] = body->getOrientation()[2];
+ q[0] = body->getOrientation()[3];
+
+ dRfromQ1(body->m_R,q);
+
+ return numBodies-1;
+}
+
+
+
+
+
+#define MAX_JOINTS_1 8192
+
+static ContactJoint gJointArray[MAX_JOINTS_1];
+
+
+void ConvertConstraint(PersistentManifold* manifold,BU_Joint** joints,int& numJoints,
+ RigidBody** bodies,int _bodyId0,int _bodyId1)
+{
+
+
+ manifold->RefreshContactPoints(((RigidBody*)manifold->GetBody0())->getCenterOfMassTransform(),
+ ((RigidBody*)manifold->GetBody1())->getCenterOfMassTransform());
+
+ int bodyId0 = _bodyId0,bodyId1 = _bodyId1;
+
+ int i,numContacts = manifold->GetNumContacts();
+
+ bool swapBodies = (bodyId0 < 0);
+
+
+ RigidBody* body0,*body1;
+
+ if (swapBodies)
+ {
+ bodyId0 = _bodyId1;
+ bodyId1 = _bodyId0;
+
+ body0 = (RigidBody*)manifold->GetBody1();
+ body1 = (RigidBody*)manifold->GetBody0();
+
+ } else
+ {
+ body0 = (RigidBody*)manifold->GetBody0();
+ body1 = (RigidBody*)manifold->GetBody1();
+ }
+
+ assert(bodyId0 >= 0);
+
+ for (i=0;i<numContacts;i++)
+ {
+
+ assert (gCurJoint < MAX_JOINTS_1);
+
+ if (manifold->GetContactPoint(i).GetDistance() < 0.f)
+ {
+ ContactJoint* cont = new (&gJointArray[gCurJoint++]) ContactJoint( manifold ,i, swapBodies,body0,body1);
+
+ cont->node[0].joint = cont;
+ cont->node[0].body = bodyId0 >= 0 ? bodies[bodyId0] : 0;
+
+ cont->node[1].joint = cont;
+ cont->node[1].body = bodyId1 >= 0 ? bodies[bodyId1] : 0;
+
+ joints[numJoints++] = cont;
+ for (int i=0;i<6;i++)
+ cont->lambda[i] = 0.f;
+
+ cont->flags = 0;
+ }
+ }
+
+ //create a new contact constraint
+};
+
diff --git a/extern/bullet/BulletDynamics/ConstraintSolver/OdeConstraintSolver.h b/extern/bullet/BulletDynamics/ConstraintSolver/OdeConstraintSolver.h
new file mode 100644
index 00000000000..7ae8d0eaa49
--- /dev/null
+++ b/extern/bullet/BulletDynamics/ConstraintSolver/OdeConstraintSolver.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies.
+ * Erwin Coumans makes no representations about the suitability
+ * of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+*/
+#ifndef ODE_CONSTRAINT_SOLVER_H
+#define ODE_CONSTRAINT_SOLVER_H
+
+#include "ConstraintSolver.h"
+
+
+class OdeConstraintSolver : public ConstraintSolver
+{
+
+public:
+
+ virtual ~OdeConstraintSolver() {}
+
+ virtual float SolveGroup(PersistentManifold** manifold,int numManifolds,const ContactSolverInfo& info);
+
+};
+
+
+
+
+#endif //ODE_CONSTRAINT_SOLVER_H
diff --git a/extern/bullet/BulletDynamics/ConstraintSolver/OdeConstraintSolver2.cpp b/extern/bullet/BulletDynamics/ConstraintSolver/OdeConstraintSolver2.cpp
new file mode 100644
index 00000000000..4b343251f03
--- /dev/null
+++ b/extern/bullet/BulletDynamics/ConstraintSolver/OdeConstraintSolver2.cpp
@@ -0,0 +1,246 @@
+/*
+ * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies.
+ * Erwin Coumans makes no representations about the suitability
+ * of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+*/
+
+#include "OdeConstraintSolver.h"
+
+#include "NarrowPhaseCollision/PersistentManifold.h"
+#include "Dynamics/RigidBody.h"
+#include "ContactConstraint.h"
+#include "Solve2LinearConstraint.h"
+#include "ContactSolverInfo.h"
+#include "Dynamics/BU_Joint.h"
+#include "Dynamics/ContactJoint.h"
+
+#define USE_SOR_SOLVER
+
+#include "SorLcp.h"
+
+#include <math.h>
+#include <float.h>//FLT_MAX
+#ifdef WIN32
+#include <memory.h>
+#endif
+#include <string.h>
+#include <stdio.h>
+
+#ifdef WIN32
+#include <malloc.h>
+#else
+#include <alloca.h>
+#endif
+
+class BU_Joint;
+
+//see below
+
+int gCurBody = 0;
+int gCurJoint= 0;
+
+int ConvertBody(RigidBody* body,RigidBody** bodies,int& numBodies);
+void ConvertConstraint(PersistentManifold* manifold,BU_Joint** joints,int& numJoints,
+ RigidBody** bodies,int bodyId0,int bodyId1);
+
+
+
+
+
+//iterative lcp and penalty method
+float OdeConstraintSolver::SolveGroup(PersistentManifold** manifoldPtr, int numManifolds,const ContactSolverInfo& infoGlobal)
+{
+ gCurBody = 0;
+ gCurJoint = 0;
+
+ float cfm = 1e-5f;
+ float erp = 0.2f;
+
+ RigidBody* bodies [128];
+
+ int numBodies = 0;
+ BU_Joint* joints [128*5];
+ int numJoints = 0;
+
+ for (int j=0;j<numManifolds;j++)
+ {
+
+ int body0=-1,body1=-1;
+
+ PersistentManifold* manifold = manifoldPtr[j];
+ if (manifold->GetNumContacts() > 0)
+ {
+ body0 = ConvertBody((RigidBody*)manifold->GetBody0(),bodies,numBodies);
+ body1 = ConvertBody((RigidBody*)manifold->GetBody1(),bodies,numBodies);
+ ConvertConstraint(manifold,joints,numJoints,bodies,body0,body1);
+ }
+ }
+
+ SolveInternal1(cfm,erp,bodies,numBodies,joints,numJoints,infoGlobal);
+
+ return 0.f;
+
+}
+
+/////////////////////////////////////////////////////////////////////////////////
+
+
+typedef SimdScalar dQuaternion[4];
+#define _R(i,j) R[(i)*4+(j)]
+
+void dRfromQ1 (dMatrix3 R, const dQuaternion q)
+{
+ // q = (s,vx,vy,vz)
+ SimdScalar qq1 = 2*q[1]*q[1];
+ SimdScalar qq2 = 2*q[2]*q[2];
+ SimdScalar qq3 = 2*q[3]*q[3];
+ _R(0,0) = 1 - qq2 - qq3;
+ _R(0,1) = 2*(q[1]*q[2] - q[0]*q[3]);
+ _R(0,2) = 2*(q[1]*q[3] + q[0]*q[2]);
+ _R(1,0) = 2*(q[1]*q[2] + q[0]*q[3]);
+ _R(1,1) = 1 - qq1 - qq3;
+ _R(1,2) = 2*(q[2]*q[3] - q[0]*q[1]);
+ _R(2,0) = 2*(q[1]*q[3] - q[0]*q[2]);
+ _R(2,1) = 2*(q[2]*q[3] + q[0]*q[1]);
+ _R(2,2) = 1 - qq1 - qq2;
+}
+
+
+
+int ConvertBody(RigidBody* body,RigidBody** bodies,int& numBodies)
+{
+ if (!body || (body->getInvMass() == 0.f) )
+ {
+ return -1;
+ }
+ //first try to find
+ int i,j;
+ for (i=0;i<numBodies;i++)
+ {
+ if (bodies[i] == body)
+ return i;
+ }
+ //if not found, create a new body
+ bodies[numBodies++] = body;
+ //convert data
+
+
+ body->m_facc.setValue(0,0,0);
+ body->m_tacc.setValue(0,0,0);
+
+ //are the indices the same ?
+ for (i=0;i<4;i++)
+ {
+ for ( j=0;j<3;j++)
+ {
+ body->m_invI[i+4*j] = 0.f;
+ }
+ }
+ body->m_invI[0+4*0] = body->getInvInertiaDiagLocal()[0];
+ body->m_invI[1+4*1] = body->getInvInertiaDiagLocal()[1];
+ body->m_invI[2+4*2] = body->getInvInertiaDiagLocal()[2];
+
+
+ SimdMatrix3x3 invI;
+ invI.setIdentity();
+ invI[0][0] = body->getInvInertiaDiagLocal()[0];
+ invI[1][1] = body->getInvInertiaDiagLocal()[1];
+ invI[2][2] = body->getInvInertiaDiagLocal()[2];
+ SimdMatrix3x3 inertia = invI.inverse();
+
+ for (i=0;i<3;i++)
+ {
+ for (j=0;j<3;j++)
+ {
+ body->m_I[i+4*j] = inertia[i][j];
+ }
+ }
+ body->m_I[3+0*4] = 0.f;
+ body->m_I[3+1*4] = 0.f;
+ body->m_I[3+2*4] = 0.f;
+ body->m_I[3+3*4] = 0.f;
+
+
+ dQuaternion q;
+
+ q[1] = body->getOrientation()[0];
+ q[2] = body->getOrientation()[1];
+ q[3] = body->getOrientation()[2];
+ q[0] = body->getOrientation()[3];
+
+ dRfromQ1(body->m_R,q);
+
+ return numBodies-1;
+}
+
+
+
+
+
+#define MAX_JOINTS_1 8192
+
+static ContactJoint gJointArray[MAX_JOINTS_1];
+
+
+void ConvertConstraint(PersistentManifold* manifold,BU_Joint** joints,int& numJoints,
+ RigidBody** bodies,int _bodyId0,int _bodyId1)
+{
+
+
+ manifold->RefreshContactPoints(((RigidBody*)manifold->GetBody0())->getCenterOfMassTransform(),
+ ((RigidBody*)manifold->GetBody1())->getCenterOfMassTransform());
+
+ int bodyId0 = _bodyId0,bodyId1 = _bodyId1;
+
+ int i,numContacts = manifold->GetNumContacts();
+
+ bool swapBodies = (bodyId0 < 0);
+
+
+ RigidBody* body0,*body1;
+
+ if (swapBodies)
+ {
+ bodyId0 = _bodyId1;
+ bodyId1 = _bodyId0;
+
+ body0 = (RigidBody*)manifold->GetBody1();
+ body1 = (RigidBody*)manifold->GetBody0();
+
+ } else
+ {
+ body0 = (RigidBody*)manifold->GetBody0();
+ body1 = (RigidBody*)manifold->GetBody1();
+ }
+
+ assert(bodyId0 >= 0);
+
+ for (i=0;i<numContacts;i++)
+ {
+
+ assert (gCurJoint < MAX_JOINTS_1);
+
+ ContactJoint* cont = new (&gJointArray[gCurJoint++]) ContactJoint( manifold ,i, swapBodies,body0,body1);
+
+ cont->node[0].joint = cont;
+ cont->node[0].body = bodyId0 >= 0 ? bodies[bodyId0] : 0;
+
+ cont->node[1].joint = cont;
+ cont->node[1].body = bodyId1 >= 0 ? bodies[bodyId1] : 0;
+
+ joints[numJoints++] = cont;
+ for (int i=0;i<6;i++)
+ cont->lambda[i] = 0.f;
+
+ cont->flags = 0;
+
+ }
+
+ //create a new contact constraint
+};
+
diff --git a/extern/bullet/BulletDynamics/ConstraintSolver/OdeConstraintSolver2.h b/extern/bullet/BulletDynamics/ConstraintSolver/OdeConstraintSolver2.h
new file mode 100644
index 00000000000..7ae8d0eaa49
--- /dev/null
+++ b/extern/bullet/BulletDynamics/ConstraintSolver/OdeConstraintSolver2.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies.
+ * Erwin Coumans makes no representations about the suitability
+ * of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+*/
+#ifndef ODE_CONSTRAINT_SOLVER_H
+#define ODE_CONSTRAINT_SOLVER_H
+
+#include "ConstraintSolver.h"
+
+
+class OdeConstraintSolver : public ConstraintSolver
+{
+
+public:
+
+ virtual ~OdeConstraintSolver() {}
+
+ virtual float SolveGroup(PersistentManifold** manifold,int numManifolds,const ContactSolverInfo& info);
+
+};
+
+
+
+
+#endif //ODE_CONSTRAINT_SOLVER_H
diff --git a/extern/bullet/BulletDynamics/ConstraintSolver/Point2PointConstraint.cpp b/extern/bullet/BulletDynamics/ConstraintSolver/Point2PointConstraint.cpp
new file mode 100644
index 00000000000..89b554cdad9
--- /dev/null
+++ b/extern/bullet/BulletDynamics/ConstraintSolver/Point2PointConstraint.cpp
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies.
+ * Erwin Coumans makes no representations about the suitability
+ * of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+*/
+#include "Point2PointConstraint.h"
+#include "Dynamics/RigidBody.h"
+#include "Dynamics/MassProps.h"
+
+
+static RigidBody s_fixed(MassProps(0,SimdVector3(0.f,0.f,0.f)),0.f,0.f);
+
+Point2PointConstraint::Point2PointConstraint():
+m_rbA(s_fixed),m_rbB(s_fixed)
+{
+ s_fixed.setMassProps(0.f,SimdVector3(0.f,0.f,0.f));
+}
+
+Point2PointConstraint::Point2PointConstraint(RigidBody& rbA,RigidBody& rbB, const SimdVector3& pivotInA,const SimdVector3& pivotInB)
+:m_rbA(rbA),m_rbB(rbB),m_pivotInA(pivotInA),m_pivotInB(pivotInB)
+{
+
+}
+
+
+Point2PointConstraint::Point2PointConstraint(RigidBody& rbA,const SimdVector3& pivotInA)
+:m_rbA(rbA),m_rbB(s_fixed),m_pivotInA(pivotInA),m_pivotInB(rbA.getCenterOfMassTransform()(pivotInA))
+{
+ s_fixed.setMassProps(0.f,SimdVector3(1e10f,1e10f,1e10f));
+}
+
+void Point2PointConstraint::BuildJacobian()
+{
+ SimdVector3 normal(0,0,0);
+
+ for (int i=0;i<3;i++)
+ {
+ normal[i] = 1;
+ new (&m_jac[i]) JacobianEntry(
+ m_rbA.getCenterOfMassTransform().getBasis().transpose(),
+ m_rbB.getCenterOfMassTransform().getBasis().transpose(),
+ m_rbA.getCenterOfMassTransform()*m_pivotInA - m_rbA.getCenterOfMassPosition(),
+ m_rbB.getCenterOfMassTransform()*m_pivotInB - m_rbB.getCenterOfMassPosition(),
+ normal,
+ m_rbA.getInvInertiaDiagLocal(),
+ m_rbA.getInvMass(),
+ m_rbB.getInvInertiaDiagLocal(),
+ m_rbB.getInvMass());
+ normal[i] = 0;
+ }
+
+}
+
+void Point2PointConstraint::SolveConstraint(SimdScalar timeStep)
+{
+ SimdVector3 pivotAInW = m_rbA.getCenterOfMassTransform()*m_pivotInA;
+ SimdVector3 pivotBInW = m_rbB.getCenterOfMassTransform()*m_pivotInB;
+
+
+ SimdVector3 normal(0,0,0);
+ SimdScalar tau = 0.3f;
+ SimdScalar damping = 1.f;
+
+// SimdVector3 angvelA = m_rbA.getCenterOfMassTransform().getBasis().transpose() * m_rbA.getAngularVelocity();
+// SimdVector3 angvelB = m_rbB.getCenterOfMassTransform().getBasis().transpose() * m_rbB.getAngularVelocity();
+
+ for (int i=0;i<3;i++)
+ {
+ normal[i] = 1;
+ SimdScalar jacDiagABInv = 1.f / m_jac[i].getDiagonal();
+
+ SimdVector3 rel_pos1 = pivotAInW - m_rbA.getCenterOfMassPosition();
+ SimdVector3 rel_pos2 = pivotBInW - m_rbB.getCenterOfMassPosition();
+ //this jacobian entry could be re-used for all iterations
+
+ SimdVector3 vel1 = m_rbA.getVelocityInLocalPoint(rel_pos1);
+ SimdVector3 vel2 = m_rbB.getVelocityInLocalPoint(rel_pos2);
+ SimdVector3 vel = vel1 - vel2;
+
+ SimdScalar rel_vel;
+ rel_vel = normal.dot(vel);
+
+ /*
+ //velocity error (first order error)
+ SimdScalar rel_vel = m_jac[i].getRelativeVelocity(m_rbA.getLinearVelocity(),angvelA,
+ m_rbB.getLinearVelocity(),angvelB);
+ */
+
+ //positional error (zeroth order error)
+ SimdScalar depth = -(pivotAInW - pivotBInW).dot(normal); //this is the error projected on the normal
+
+ SimdScalar impulse = depth*tau/timeStep * jacDiagABInv - damping * rel_vel * jacDiagABInv * damping;
+
+ SimdVector3 impulse_vector = normal * impulse;
+ m_rbA.applyImpulse(impulse_vector, pivotAInW - m_rbA.getCenterOfMassPosition());
+ m_rbB.applyImpulse(-impulse_vector, pivotBInW - m_rbB.getCenterOfMassPosition());
+
+ normal[i] = 0;
+ }
+}
+
+void Point2PointConstraint::UpdateRHS(SimdScalar timeStep)
+{
+
+}
+
diff --git a/extern/bullet/BulletDynamics/ConstraintSolver/Point2PointConstraint.h b/extern/bullet/BulletDynamics/ConstraintSolver/Point2PointConstraint.h
new file mode 100644
index 00000000000..85e13cde21e
--- /dev/null
+++ b/extern/bullet/BulletDynamics/ConstraintSolver/Point2PointConstraint.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies.
+ * Erwin Coumans makes no representations about the suitability
+ * of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+*/
+#ifndef POINT2POINTCONSTRAINT_H
+#define POINT2POINTCONSTRAINT_H
+
+#include "SimdVector3.h"
+
+#include "ConstraintSolver/JacobianEntry.h"
+class RigidBody;
+
+
+/// point to point constraint between two rigidbodies each with a pivotpoint that descibes the 'ballsocket' location in local space
+class Point2PointConstraint
+{
+ JacobianEntry m_jac[3]; //3 orthogonal linear constraints
+ RigidBody& m_rbA;
+ RigidBody& m_rbB;
+
+ SimdVector3 m_pivotInA;
+ SimdVector3 m_pivotInB;
+
+public:
+
+ Point2PointConstraint(RigidBody& rbA,RigidBody& rbB, const SimdVector3& pivotInA,const SimdVector3& pivotInB);
+
+ Point2PointConstraint(RigidBody& rbA,const SimdVector3& pivotInA);
+
+ Point2PointConstraint();
+
+ void BuildJacobian();
+
+ void SolveConstraint(SimdScalar timeStep);
+
+ void UpdateRHS(SimdScalar timeStep);
+
+ const RigidBody& GetRigidBodyA() const
+ {
+ return m_rbA;
+ }
+ const RigidBody& GetRigidBodyB() const
+ {
+ return m_rbB;
+ }
+
+
+};
+
+#endif //POINT2POINTCONSTRAINT_H
diff --git a/extern/bullet/BulletDynamics/ConstraintSolver/SimpleConstraintSolver.cpp b/extern/bullet/BulletDynamics/ConstraintSolver/SimpleConstraintSolver.cpp
new file mode 100644
index 00000000000..3243140b823
--- /dev/null
+++ b/extern/bullet/BulletDynamics/ConstraintSolver/SimpleConstraintSolver.cpp
@@ -0,0 +1,127 @@
+/*
+ * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies.
+ * Erwin Coumans makes no representations about the suitability
+ * of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+*/
+#include "SimpleConstraintSolver.h"
+#include "NarrowPhaseCollision/PersistentManifold.h"
+#include "Dynamics/RigidBody.h"
+#include "ContactConstraint.h"
+#include "Solve2LinearConstraint.h"
+#include "ContactSolverInfo.h"
+#include "Dynamics/BU_Joint.h"
+#include "Dynamics/ContactJoint.h"
+
+//debugging
+bool doApplyImpulse = true;
+
+
+
+bool useImpulseFriction = true;//true;//false;
+
+
+
+
+//iterative lcp and penalty method
+float SimpleConstraintSolver::SolveGroup(PersistentManifold** manifoldPtr, int numManifolds,const ContactSolverInfo& infoGlobal)
+{
+
+ ContactSolverInfo info = infoGlobal;
+
+ int numiter = infoGlobal.m_numIterations;
+
+ float substep = infoGlobal.m_timeStep / float(numiter);
+
+ for (int i = 0;i<numiter;i++)
+ {
+ for (int j=0;j<numManifolds;j++)
+ {
+ Solve(manifoldPtr[j],info,i);
+ }
+ }
+ return 0.f;
+}
+
+
+float penetrationResolveFactor = 0.9f;
+
+
+float SimpleConstraintSolver::Solve(PersistentManifold* manifoldPtr, const ContactSolverInfo& info,int iter)
+{
+
+ RigidBody* body0 = (RigidBody*)manifoldPtr->GetBody0();
+ RigidBody* body1 = (RigidBody*)manifoldPtr->GetBody1();
+
+ float maxImpulse = 0.f;
+
+
+ float invNumIterFl = 1.f / float(info.m_numIterations);
+
+ float timeSubStep = info.m_timeStep * invNumIterFl;
+
+ //only necessary to refresh the manifold once (first iteration). The integration is done outside the loop
+ if (iter == 0)
+ {
+ manifoldPtr->RefreshContactPoints(body0->getCenterOfMassTransform(),body1->getCenterOfMassTransform());
+ }
+
+ {
+ const int numpoints = manifoldPtr->GetNumContacts();
+
+ for (int i=0;i<numpoints ;i++)
+ {
+
+ int j=i;
+ if (iter % 2)
+ j = numpoints-1-i;
+ else
+ j=i;
+
+ ManifoldPoint& cp = manifoldPtr->GetContactPoint(j);
+
+ {
+
+
+ float dist = invNumIterFl * cp.GetDistance() * penetrationResolveFactor / info.m_timeStep;// / timeStep;//penetrationResolveFactor*cp.m_solveDistance /timeStep;//cp.GetDistance();
+
+
+ float impulse = 0.f;
+
+ if (doApplyImpulse)
+ {
+ impulse = resolveSingleCollision(*body0,
+ cp.GetPositionWorldOnA(),
+ *body1,
+ cp.GetPositionWorldOnB(),
+ -dist,
+ cp.m_normalWorldOnB,
+ info);
+
+ if (useImpulseFriction)
+ {
+ applyFrictionInContactPointOld(
+ *body0,cp.GetPositionWorldOnA(),*body1,cp.GetPositionWorldOnB(),
+ cp.m_normalWorldOnB,impulse,info) ;
+ }
+ }
+ if (iter == 0)
+ {
+ cp.m_appliedImpulse = impulse;
+ } else
+ {
+ cp.m_appliedImpulse += impulse;
+ }
+
+ if (maxImpulse < impulse)
+ maxImpulse = impulse;
+
+ }
+ }
+ }
+ return maxImpulse;
+}
diff --git a/extern/bullet/BulletDynamics/ConstraintSolver/SimpleConstraintSolver.h b/extern/bullet/BulletDynamics/ConstraintSolver/SimpleConstraintSolver.h
new file mode 100644
index 00000000000..6bdcf3a2ac2
--- /dev/null
+++ b/extern/bullet/BulletDynamics/ConstraintSolver/SimpleConstraintSolver.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies.
+ * Erwin Coumans makes no representations about the suitability
+ * of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+*/
+#ifndef SIMPLE_CONSTRAINT_SOLVER_H
+#define SIMPLE_CONSTRAINT_SOLVER_H
+
+#include "ConstraintSolver.h"
+
+
+class SimpleConstraintSolver : public ConstraintSolver
+{
+ float Solve(PersistentManifold* manifold, const ContactSolverInfo& info,int iter);
+
+public:
+
+ virtual ~SimpleConstraintSolver() {}
+
+ virtual float SolveGroup(PersistentManifold** manifold,int numManifolds,const ContactSolverInfo& info);
+
+};
+
+
+
+
+#endif //SIMPLE_CONSTRAINT_SOLVER_H \ No newline at end of file
diff --git a/extern/bullet/BulletDynamics/ConstraintSolver/Solve2LinearConstraint.cpp b/extern/bullet/BulletDynamics/ConstraintSolver/Solve2LinearConstraint.cpp
new file mode 100644
index 00000000000..28773d5faa8
--- /dev/null
+++ b/extern/bullet/BulletDynamics/ConstraintSolver/Solve2LinearConstraint.cpp
@@ -0,0 +1,234 @@
+/*
+ * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies.
+ * Erwin Coumans makes no representations about the suitability
+ * of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+*/
+
+#include "Solve2LinearConstraint.h"
+
+#include "Dynamics/RigidBody.h"
+#include "SimdVector3.h"
+#include "JacobianEntry.h"
+
+
+void Solve2LinearConstraint::resolveUnilateralPairConstraint(
+ RigidBody* body1,
+ RigidBody* body2,
+
+ const SimdMatrix3x3& world2A,
+ const SimdMatrix3x3& world2B,
+
+ const SimdVector3& invInertiaADiag,
+ const SimdScalar invMassA,
+ const SimdVector3& linvelA,const SimdVector3& angvelA,
+ const SimdVector3& rel_posA1,
+ const SimdVector3& invInertiaBDiag,
+ const SimdScalar invMassB,
+ const SimdVector3& linvelB,const SimdVector3& angvelB,
+ const SimdVector3& rel_posA2,
+
+ SimdScalar depthA, const SimdVector3& normalA,
+ const SimdVector3& rel_posB1,const SimdVector3& rel_posB2,
+ SimdScalar depthB, const SimdVector3& normalB,
+ SimdScalar& imp0,SimdScalar& imp1)
+{
+
+ imp0 = 0.f;
+ imp1 = 0.f;
+
+ SimdScalar len = fabs(normalA.length())-1.f;
+ if (fabs(len) >= SIMD_EPSILON)
+ return;
+
+ ASSERT(len < SIMD_EPSILON);
+
+
+ //this jacobian entry could be re-used for all iterations
+ JacobianEntry jacA(world2A,world2B,rel_posA1,rel_posA2,normalA,invInertiaADiag,invMassA,
+ invInertiaBDiag,invMassB);
+ JacobianEntry jacB(world2A,world2B,rel_posB1,rel_posB2,normalB,invInertiaADiag,invMassA,
+ invInertiaBDiag,invMassB);
+
+ //const SimdScalar vel0 = jacA.getRelativeVelocity(linvelA,angvelA,linvelB,angvelB);
+ //const SimdScalar vel1 = jacB.getRelativeVelocity(linvelA,angvelA,linvelB,angvelB);
+
+ const SimdScalar vel0 = normalA.dot(body1->getVelocityInLocalPoint(rel_posA1)-body2->getVelocityInLocalPoint(rel_posA1));
+ const SimdScalar vel1 = normalB.dot(body1->getVelocityInLocalPoint(rel_posB1)-body2->getVelocityInLocalPoint(rel_posB1));
+
+// SimdScalar penetrationImpulse = (depth*contactTau*timeCorrection) * massTerm;//jacDiagABInv
+ SimdScalar massTerm = 1.f / (invMassA + invMassB);
+
+
+ // calculate rhs (or error) terms
+ const SimdScalar dv0 = depthA * m_tau * massTerm - vel0 * m_damping;
+ const SimdScalar dv1 = depthB * m_tau * massTerm - vel1 * m_damping;
+
+
+ // dC/dv * dv = -C
+
+ // jacobian * impulse = -error
+ //
+
+ //impulse = jacobianInverse * -error
+
+ // inverting 2x2 symmetric system (offdiagonal are equal!)
+ //
+
+
+ SimdScalar nonDiag = jacA.getNonDiagonal(jacB,invMassA,invMassB);
+ SimdScalar invDet = 1.0f / (jacA.getDiagonal() * jacB.getDiagonal() - nonDiag * nonDiag );
+
+ //imp0 = dv0 * jacA.getDiagonal() * invDet + dv1 * -nonDiag * invDet;
+ //imp1 = dv1 * jacB.getDiagonal() * invDet + dv0 * - nonDiag * invDet;
+
+ imp0 = dv0 * jacA.getDiagonal() * invDet + dv1 * -nonDiag * invDet;
+ imp1 = dv1 * jacB.getDiagonal() * invDet + dv0 * - nonDiag * invDet;
+
+ //[a b] [d -c]
+ //[c d] inverse = (1 / determinant) * [-b a] where determinant is (ad - bc)
+
+ //[jA nD] * [imp0] = [dv0]
+ //[nD jB] [imp1] [dv1]
+
+}
+
+
+
+void Solve2LinearConstraint::resolveBilateralPairConstraint(
+ RigidBody* body1,
+ RigidBody* body2,
+ const SimdMatrix3x3& world2A,
+ const SimdMatrix3x3& world2B,
+
+ const SimdVector3& invInertiaADiag,
+ const SimdScalar invMassA,
+ const SimdVector3& linvelA,const SimdVector3& angvelA,
+ const SimdVector3& rel_posA1,
+ const SimdVector3& invInertiaBDiag,
+ const SimdScalar invMassB,
+ const SimdVector3& linvelB,const SimdVector3& angvelB,
+ const SimdVector3& rel_posA2,
+
+ SimdScalar depthA, const SimdVector3& normalA,
+ const SimdVector3& rel_posB1,const SimdVector3& rel_posB2,
+ SimdScalar depthB, const SimdVector3& normalB,
+ SimdScalar& imp0,SimdScalar& imp1)
+{
+
+ imp0 = 0.f;
+ imp1 = 0.f;
+
+ SimdScalar len = fabs(normalA.length())-1.f;
+ if (fabs(len) >= SIMD_EPSILON)
+ return;
+
+ ASSERT(len < SIMD_EPSILON);
+
+
+ //this jacobian entry could be re-used for all iterations
+ JacobianEntry jacA(world2A,world2B,rel_posA1,rel_posA2,normalA,invInertiaADiag,invMassA,
+ invInertiaBDiag,invMassB);
+ JacobianEntry jacB(world2A,world2B,rel_posB1,rel_posB2,normalB,invInertiaADiag,invMassA,
+ invInertiaBDiag,invMassB);
+
+ //const SimdScalar vel0 = jacA.getRelativeVelocity(linvelA,angvelA,linvelB,angvelB);
+ //const SimdScalar vel1 = jacB.getRelativeVelocity(linvelA,angvelA,linvelB,angvelB);
+
+ const SimdScalar vel0 = normalA.dot(body1->getVelocityInLocalPoint(rel_posA1)-body2->getVelocityInLocalPoint(rel_posA1));
+ const SimdScalar vel1 = normalB.dot(body1->getVelocityInLocalPoint(rel_posB1)-body2->getVelocityInLocalPoint(rel_posB1));
+
+ // calculate rhs (or error) terms
+ const SimdScalar dv0 = depthA * m_tau - vel0 * m_damping;
+ const SimdScalar dv1 = depthB * m_tau - vel1 * m_damping;
+
+ // dC/dv * dv = -C
+
+ // jacobian * impulse = -error
+ //
+
+ //impulse = jacobianInverse * -error
+
+ // inverting 2x2 symmetric system (offdiagonal are equal!)
+ //
+
+
+ SimdScalar nonDiag = jacA.getNonDiagonal(jacB,invMassA,invMassB);
+ SimdScalar invDet = 1.0f / (jacA.getDiagonal() * jacB.getDiagonal() - nonDiag * nonDiag );
+
+ //imp0 = dv0 * jacA.getDiagonal() * invDet + dv1 * -nonDiag * invDet;
+ //imp1 = dv1 * jacB.getDiagonal() * invDet + dv0 * - nonDiag * invDet;
+
+ imp0 = dv0 * jacA.getDiagonal() * invDet + dv1 * -nonDiag * invDet;
+ imp1 = dv1 * jacB.getDiagonal() * invDet + dv0 * - nonDiag * invDet;
+
+ //[a b] [d -c]
+ //[c d] inverse = (1 / determinant) * [-b a] where determinant is (ad - bc)
+
+ //[jA nD] * [imp0] = [dv0]
+ //[nD jB] [imp1] [dv1]
+
+ if ( imp0 > 0.0f)
+ {
+ if ( imp1 > 0.0f )
+ {
+ //both positive
+ }
+ else
+ {
+ imp1 = 0.f;
+
+ // now imp0>0 imp1<0
+ imp0 = dv0 / jacA.getDiagonal();
+ if ( imp0 > 0.0f )
+ {
+ } else
+ {
+ imp0 = 0.f;
+ }
+ }
+ }
+ else
+ {
+ imp0 = 0.f;
+
+ imp1 = dv1 / jacB.getDiagonal();
+ if ( imp1 <= 0.0f )
+ {
+ imp1 = 0.f;
+ // now imp0>0 imp1<0
+ imp0 = dv0 / jacA.getDiagonal();
+ if ( imp0 > 0.0f )
+ {
+ } else
+ {
+ imp0 = 0.f;
+ }
+ } else
+ {
+ }
+ }
+}
+
+
+
+void Solve2LinearConstraint::resolveAngularConstraint( const SimdMatrix3x3& invInertiaAWS,
+ const SimdScalar invMassA,
+ const SimdVector3& linvelA,const SimdVector3& angvelA,
+ const SimdVector3& rel_posA1,
+ const SimdMatrix3x3& invInertiaBWS,
+ const SimdScalar invMassB,
+ const SimdVector3& linvelB,const SimdVector3& angvelB,
+ const SimdVector3& rel_posA2,
+
+ SimdScalar depthA, const SimdVector3& normalA,
+ const SimdVector3& rel_posB1,const SimdVector3& rel_posB2,
+ SimdScalar depthB, const SimdVector3& normalB,
+ SimdScalar& imp0,SimdScalar& imp1)
+{
+
+} \ No newline at end of file
diff --git a/extern/bullet/BulletDynamics/ConstraintSolver/Solve2LinearConstraint.h b/extern/bullet/BulletDynamics/ConstraintSolver/Solve2LinearConstraint.h
new file mode 100644
index 00000000000..710f9589c18
--- /dev/null
+++ b/extern/bullet/BulletDynamics/ConstraintSolver/Solve2LinearConstraint.h
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies.
+ * Erwin Coumans makes no representations about the suitability
+ * of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+*/
+#ifndef SOLVE_2LINEAR_CONSTRAINT_H
+#define SOLVE_2LINEAR_CONSTRAINT_H
+
+#include "SimdMatrix3x3.h"
+#include "SimdVector3.h"
+
+
+class RigidBody;
+
+
+
+/// constraint class used for lateral tyre friction.
+class Solve2LinearConstraint
+{
+ SimdScalar m_tau;
+ SimdScalar m_damping;
+
+public:
+
+ Solve2LinearConstraint(SimdScalar tau,SimdScalar damping)
+ {
+ m_tau = tau;
+ m_damping = damping;
+ }
+ //
+ // solve unilateral constraint (equality, direct method)
+ //
+ void resolveUnilateralPairConstraint(
+ RigidBody* body0,
+ RigidBody* body1,
+
+ const SimdMatrix3x3& world2A,
+ const SimdMatrix3x3& world2B,
+
+ const SimdVector3& invInertiaADiag,
+ const SimdScalar invMassA,
+ const SimdVector3& linvelA,const SimdVector3& angvelA,
+ const SimdVector3& rel_posA1,
+ const SimdVector3& invInertiaBDiag,
+ const SimdScalar invMassB,
+ const SimdVector3& linvelB,const SimdVector3& angvelB,
+ const SimdVector3& rel_posA2,
+
+ SimdScalar depthA, const SimdVector3& normalA,
+ const SimdVector3& rel_posB1,const SimdVector3& rel_posB2,
+ SimdScalar depthB, const SimdVector3& normalB,
+ SimdScalar& imp0,SimdScalar& imp1);
+
+
+ //
+ // solving 2x2 lcp problem (inequality, direct solution )
+ //
+ void resolveBilateralPairConstraint(
+ RigidBody* body0,
+ RigidBody* body1,
+ const SimdMatrix3x3& world2A,
+ const SimdMatrix3x3& world2B,
+
+ const SimdVector3& invInertiaADiag,
+ const SimdScalar invMassA,
+ const SimdVector3& linvelA,const SimdVector3& angvelA,
+ const SimdVector3& rel_posA1,
+ const SimdVector3& invInertiaBDiag,
+ const SimdScalar invMassB,
+ const SimdVector3& linvelB,const SimdVector3& angvelB,
+ const SimdVector3& rel_posA2,
+
+ SimdScalar depthA, const SimdVector3& normalA,
+ const SimdVector3& rel_posB1,const SimdVector3& rel_posB2,
+ SimdScalar depthB, const SimdVector3& normalB,
+ SimdScalar& imp0,SimdScalar& imp1);
+
+
+ void resolveAngularConstraint( const SimdMatrix3x3& invInertiaAWS,
+ const SimdScalar invMassA,
+ const SimdVector3& linvelA,const SimdVector3& angvelA,
+ const SimdVector3& rel_posA1,
+ const SimdMatrix3x3& invInertiaBWS,
+ const SimdScalar invMassB,
+ const SimdVector3& linvelB,const SimdVector3& angvelB,
+ const SimdVector3& rel_posA2,
+
+ SimdScalar depthA, const SimdVector3& normalA,
+ const SimdVector3& rel_posB1,const SimdVector3& rel_posB2,
+ SimdScalar depthB, const SimdVector3& normalB,
+ SimdScalar& imp0,SimdScalar& imp1);
+
+
+};
+
+#endif //SOLVE_2LINEAR_CONSTRAINT_H
diff --git a/extern/bullet/BulletDynamics/ConstraintSolver/SorLcp.cpp b/extern/bullet/BulletDynamics/ConstraintSolver/SorLcp.cpp
new file mode 100644
index 00000000000..d5c6d80552d
--- /dev/null
+++ b/extern/bullet/BulletDynamics/ConstraintSolver/SorLcp.cpp
@@ -0,0 +1,821 @@
+/*
+ * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies.
+ * Erwin Coumans makes no representations about the suitability
+ * of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+*/
+#include "SorLcp.h"
+
+#ifdef USE_SOR_SOLVER
+
+// SOR LCP taken from ode quickstep,
+// todo: write own successive overrelaxation gauss-seidel, or jacobi iterative solver
+
+
+#include "SimdScalar.h"
+
+#include "Dynamics/RigidBody.h"
+#include <math.h>
+#include <float.h>//FLT_MAX
+#ifdef WIN32
+#include <memory.h>
+#endif
+#include <string.h>
+#include <stdio.h>
+
+#ifdef WIN32
+#include <malloc.h>
+#else
+#include <alloca.h>
+#endif
+
+#include "Dynamics/BU_Joint.h"
+#include "ContactSolverInfo.h"
+
+////////////////////////////////////////////////////////////////////
+//math stuff
+
+typedef SimdScalar dVector4[4];
+typedef SimdScalar dMatrix3[4*3];
+#define dInfinity FLT_MAX
+
+
+
+#define dRecip(x) ((float)(1.0f/(x))) /* reciprocal */
+
+
+
+#define dMULTIPLY0_331NEW(A,op,B,C) \
+{\
+ float tmp[3];\
+ tmp[0] = C.getX();\
+ tmp[1] = C.getY();\
+ tmp[2] = C.getZ();\
+ dMULTIPLYOP0_331(A,op,B,tmp);\
+}
+
+#define dMULTIPLY0_331(A,B,C) dMULTIPLYOP0_331(A,=,B,C)
+#define dMULTIPLYOP0_331(A,op,B,C) \
+ (A)[0] op dDOT1((B),(C)); \
+ (A)[1] op dDOT1((B+4),(C)); \
+ (A)[2] op dDOT1((B+8),(C));
+
+#define dAASSERT ASSERT
+#define dIASSERT ASSERT
+
+#define REAL float
+#define dDOTpq(a,b,p,q) ((a)[0]*(b)[0] + (a)[p]*(b)[q] + (a)[2*(p)]*(b)[2*(q)])
+SimdScalar dDOT1 (const SimdScalar *a, const SimdScalar *b) { return dDOTpq(a,b,1,1); }
+#define dDOT14(a,b) dDOTpq(a,b,1,4)
+
+#define dCROSS(a,op,b,c) \
+ (a)[0] op ((b)[1]*(c)[2] - (b)[2]*(c)[1]); \
+ (a)[1] op ((b)[2]*(c)[0] - (b)[0]*(c)[2]); \
+ (a)[2] op ((b)[0]*(c)[1] - (b)[1]*(c)[0]);
+
+
+#define dMULTIPLYOP2_333(A,op,B,C) \
+ (A)[0] op dDOT1((B),(C)); \
+ (A)[1] op dDOT1((B),(C+4)); \
+ (A)[2] op dDOT1((B),(C+8)); \
+ (A)[4] op dDOT1((B+4),(C)); \
+ (A)[5] op dDOT1((B+4),(C+4)); \
+ (A)[6] op dDOT1((B+4),(C+8)); \
+ (A)[8] op dDOT1((B+8),(C)); \
+ (A)[9] op dDOT1((B+8),(C+4)); \
+ (A)[10] op dDOT1((B+8),(C+8));
+#define dMULTIPLYOP0_333(A,op,B,C) \
+ (A)[0] op dDOT14((B),(C)); \
+ (A)[1] op dDOT14((B),(C+1)); \
+ (A)[2] op dDOT14((B),(C+2)); \
+ (A)[4] op dDOT14((B+4),(C)); \
+ (A)[5] op dDOT14((B+4),(C+1)); \
+ (A)[6] op dDOT14((B+4),(C+2)); \
+ (A)[8] op dDOT14((B+8),(C)); \
+ (A)[9] op dDOT14((B+8),(C+1)); \
+ (A)[10] op dDOT14((B+8),(C+2));
+
+#define dMULTIPLY2_333(A,B,C) dMULTIPLYOP2_333(A,=,B,C)
+#define dMULTIPLY0_333(A,B,C) dMULTIPLYOP0_333(A,=,B,C)
+#define dMULTIPLYADD0_331(A,B,C) dMULTIPLYOP0_331(A,+=,B,C)
+
+
+////////////////////////////////////////////////////////////////////
+#define EFFICIENT_ALIGNMENT 16
+#define dEFFICIENT_SIZE(x) ((((x)-1)|(EFFICIENT_ALIGNMENT-1))+1)
+/* alloca aligned to the EFFICIENT_ALIGNMENT. note that this can waste
+ * up to 15 bytes per allocation, depending on what alloca() returns.
+ */
+
+#define dALLOCA16(n) \
+ ((char*)dEFFICIENT_SIZE(((size_t)(alloca((n)+(EFFICIENT_ALIGNMENT-1))))))
+
+
+
+/////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////
+
+#ifdef DEBUG
+#define ANSI_FTOL 1
+
+extern "C" {
+ __declspec(naked) void _ftol2() {
+ __asm {
+#if ANSI_FTOL
+ fnstcw WORD PTR [esp-2]
+ mov ax, WORD PTR [esp-2]
+
+ OR AX, 0C00h
+
+ mov WORD PTR [esp-4], ax
+ fldcw WORD PTR [esp-4]
+ fistp QWORD PTR [esp-12]
+ fldcw WORD PTR [esp-2]
+ mov eax, DWORD PTR [esp-12]
+ mov edx, DWORD PTR [esp-8]
+#else
+ fistp DWORD PTR [esp-12]
+ mov eax, DWORD PTR [esp-12]
+ mov ecx, DWORD PTR [esp-8]
+#endif
+ ret
+ }
+ }
+}
+#endif //DEBUG
+
+
+
+
+
+
+#define ALLOCA dALLOCA16
+
+typedef const SimdScalar *dRealPtr;
+typedef SimdScalar *dRealMutablePtr;
+#define dRealArray(name,n) SimdScalar name[n];
+#define dRealAllocaArray(name,n) SimdScalar *name = (SimdScalar*) ALLOCA ((n)*sizeof(SimdScalar));
+
+void dSetZero1 (SimdScalar *a, int n)
+{
+ dAASSERT (a && n >= 0);
+ while (n > 0) {
+ *(a++) = 0;
+ n--;
+ }
+}
+
+void dSetValue1 (SimdScalar *a, int n, SimdScalar value)
+{
+ dAASSERT (a && n >= 0);
+ while (n > 0) {
+ *(a++) = value;
+ n--;
+ }
+}
+
+
+//***************************************************************************
+// configuration
+
+// for the SOR and CG methods:
+// uncomment the following line to use warm starting. this definitely
+// help for motor-driven joints. unfortunately it appears to hurt
+// with high-friction contacts using the SOR method. use with care
+
+//#define WARM_STARTING 1
+
+// for the SOR method:
+// uncomment the following line to randomly reorder constraint rows
+// during the solution. depending on the situation, this can help a lot
+// or hardly at all, but it doesn't seem to hurt.
+
+//#define RANDOMLY_REORDER_CONSTRAINTS 1
+
+
+
+//***************************************************************************
+// various common computations involving the matrix J
+
+// compute iMJ = inv(M)*J'
+
+static void compute_invM_JT (int m, dRealMutablePtr J, dRealMutablePtr iMJ, int *jb,
+ RigidBody * const *body, dRealPtr invI)
+{
+ int i,j;
+ dRealMutablePtr iMJ_ptr = iMJ;
+ dRealMutablePtr J_ptr = J;
+ for (i=0; i<m; i++) {
+ int b1 = jb[i*2];
+ int b2 = jb[i*2+1];
+ SimdScalar k = body[b1]->getInvMass();
+ for (j=0; j<3; j++) iMJ_ptr[j] = k*J_ptr[j];
+ dMULTIPLY0_331 (iMJ_ptr + 3, invI + 12*b1, J_ptr + 3);
+ if (b2 >= 0) {
+ k = body[b2]->getInvMass();
+ for (j=0; j<3; j++) iMJ_ptr[j+6] = k*J_ptr[j+6];
+ dMULTIPLY0_331 (iMJ_ptr + 9, invI + 12*b2, J_ptr + 9);
+ }
+ J_ptr += 12;
+ iMJ_ptr += 12;
+ }
+}
+
+static void multiply_invM_JTSpecial (int m, int nb, dRealMutablePtr iMJ, int *jb,
+ dRealMutablePtr in, dRealMutablePtr out,int onlyBody1,int onlyBody2)
+{
+ int i,j;
+
+
+
+ dRealMutablePtr out_ptr1 = out + onlyBody1*6;
+
+ for (j=0; j<6; j++)
+ out_ptr1[j] = 0;
+
+ if (onlyBody2 >= 0)
+ {
+ out_ptr1 = out + onlyBody2*6;
+
+ for (j=0; j<6; j++)
+ out_ptr1[j] = 0;
+ }
+
+ dRealPtr iMJ_ptr = iMJ;
+ for (i=0; i<m; i++) {
+
+ int b1 = jb[i*2];
+
+ dRealMutablePtr out_ptr = out + b1*6;
+ if ((b1 == onlyBody1) || (b1 == onlyBody2))
+ {
+ for (j=0; j<6; j++)
+ out_ptr[j] += iMJ_ptr[j] * in[i] ;
+ }
+
+ iMJ_ptr += 6;
+
+ int b2 = jb[i*2+1];
+ if ((b2 == onlyBody1) || (b2 == onlyBody2))
+ {
+ if (b2 >= 0)
+ {
+ out_ptr = out + b2*6;
+ for (j=0; j<6; j++)
+ out_ptr[j] += iMJ_ptr[j] * in[i];
+ }
+ }
+
+ iMJ_ptr += 6;
+
+ }
+}
+
+
+// compute out = inv(M)*J'*in.
+
+static void multiply_invM_JT (int m, int nb, dRealMutablePtr iMJ, int *jb,
+ dRealMutablePtr in, dRealMutablePtr out)
+{
+ int i,j;
+ dSetZero1 (out,6*nb);
+ dRealPtr iMJ_ptr = iMJ;
+ for (i=0; i<m; i++) {
+ int b1 = jb[i*2];
+ int b2 = jb[i*2+1];
+ dRealMutablePtr out_ptr = out + b1*6;
+ for (j=0; j<6; j++)
+ out_ptr[j] += iMJ_ptr[j] * in[i];
+ iMJ_ptr += 6;
+ if (b2 >= 0) {
+ out_ptr = out + b2*6;
+ for (j=0; j<6; j++) out_ptr[j] += iMJ_ptr[j] * in[i];
+ }
+ iMJ_ptr += 6;
+ }
+}
+
+
+// compute out = J*in.
+
+static void multiply_J (int m, dRealMutablePtr J, int *jb,
+ dRealMutablePtr in, dRealMutablePtr out)
+{
+ int i,j;
+ dRealPtr J_ptr = J;
+ for (i=0; i<m; i++) {
+ int b1 = jb[i*2];
+ int b2 = jb[i*2+1];
+ SimdScalar sum = 0;
+ dRealMutablePtr in_ptr = in + b1*6;
+ for (j=0; j<6; j++) sum += J_ptr[j] * in_ptr[j];
+ J_ptr += 6;
+ if (b2 >= 0) {
+ in_ptr = in + b2*6;
+ for (j=0; j<6; j++) sum += J_ptr[j] * in_ptr[j];
+ }
+ J_ptr += 6;
+ out[i] = sum;
+ }
+}
+
+//***************************************************************************
+// SOR-LCP method
+
+// nb is the number of bodies in the body array.
+// J is an m*12 matrix of constraint rows
+// jb is an array of first and second body numbers for each constraint row
+// invI is the global frame inverse inertia for each body (stacked 3x3 matrices)
+//
+// this returns lambda and fc (the constraint force).
+// note: fc is returned as inv(M)*J'*lambda, the constraint force is actually J'*lambda
+//
+// b, lo and hi are modified on exit
+
+
+struct IndexError {
+ SimdScalar error; // error to sort on
+ int findex;
+ int index; // row index
+};
+
+static unsigned long seed2 = 0;
+
+unsigned long dRand2()
+{
+ seed2 = (1664525L*seed2 + 1013904223L) & 0xffffffff;
+ return seed2;
+}
+
+int dRandInt2 (int n)
+{
+ float a = float(n) / 4294967296.0f;
+ return (int) (float(dRand2()) * a);
+}
+
+
+static void SOR_LCP (int m, int nb, dRealMutablePtr J, int *jb, RigidBody * const *body,
+ dRealPtr invI, dRealMutablePtr lambda, dRealMutablePtr invMforce, dRealMutablePtr rhs,
+ dRealMutablePtr lo, dRealMutablePtr hi, dRealPtr cfm, int *findex,
+ int numiter,float overRelax)
+{
+ const int num_iterations = numiter;
+ const float sor_w = overRelax; // SOR over-relaxation parameter
+
+ int i,j;
+
+#ifdef WARM_STARTING
+ // for warm starting, this seems to be necessary to prevent
+ // jerkiness in motor-driven joints. i have no idea why this works.
+ for (i=0; i<m; i++) lambda[i] *= 0.9;
+#else
+ dSetZero1 (lambda,m);
+#endif
+
+ // the lambda computed at the previous iteration.
+ // this is used to measure error for when we are reordering the indexes.
+ dRealAllocaArray (last_lambda,m);
+
+ // a copy of the 'hi' vector in case findex[] is being used
+ dRealAllocaArray (hicopy,m);
+ memcpy (hicopy,hi,m*sizeof(float));
+
+ // precompute iMJ = inv(M)*J'
+ dRealAllocaArray (iMJ,m*12);
+ compute_invM_JT (m,J,iMJ,jb,body,invI);
+
+ // compute fc=(inv(M)*J')*lambda. we will incrementally maintain fc
+ // as we change lambda.
+#ifdef WARM_STARTING
+ multiply_invM_JT (m,nb,iMJ,jb,lambda,fc);
+#else
+ dSetZero1 (invMforce,nb*6);
+#endif
+
+ // precompute 1 / diagonals of A
+ dRealAllocaArray (Ad,m);
+ dRealPtr iMJ_ptr = iMJ;
+ dRealMutablePtr J_ptr = J;
+ for (i=0; i<m; i++) {
+ float sum = 0;
+ for (j=0; j<6; j++) sum += iMJ_ptr[j] * J_ptr[j];
+ if (jb[i*2+1] >= 0) {
+ for (j=6; j<12; j++) sum += iMJ_ptr[j] * J_ptr[j];
+ }
+ iMJ_ptr += 12;
+ J_ptr += 12;
+ Ad[i] = sor_w / (sum + cfm[i]);
+ }
+
+ // scale J and b by Ad
+ J_ptr = J;
+ for (i=0; i<m; i++) {
+ for (j=0; j<12; j++) {
+ J_ptr[0] *= Ad[i];
+ J_ptr++;
+ }
+ rhs[i] *= Ad[i];
+ }
+
+ // scale Ad by CFM
+ for (i=0; i<m; i++) Ad[i] *= cfm[i];
+
+ // order to solve constraint rows in
+ IndexError *order = (IndexError*) alloca (m*sizeof(IndexError));
+
+#ifndef REORDER_CONSTRAINTS
+ // make sure constraints with findex < 0 come first.
+ j=0;
+ for (i=0; i<m; i++) if (findex[i] < 0) order[j++].index = i;
+ for (i=0; i<m; i++) if (findex[i] >= 0) order[j++].index = i;
+ dIASSERT (j==m);
+#endif
+
+ for (int iteration=0; iteration < num_iterations; iteration++) {
+
+#ifdef REORDER_CONSTRAINTS
+ // constraints with findex < 0 always come first.
+ if (iteration < 2) {
+ // for the first two iterations, solve the constraints in
+ // the given order
+ for (i=0; i<m; i++) {
+ order[i].error = i;
+ order[i].findex = findex[i];
+ order[i].index = i;
+ }
+ }
+ else {
+ // sort the constraints so that the ones converging slowest
+ // get solved last. use the absolute (not relative) error.
+ for (i=0; i<m; i++) {
+ float v1 = dFabs (lambda[i]);
+ float v2 = dFabs (last_lambda[i]);
+ float max = (v1 > v2) ? v1 : v2;
+ if (max > 0) {
+ //@@@ relative error: order[i].error = dFabs(lambda[i]-last_lambda[i])/max;
+ order[i].error = dFabs(lambda[i]-last_lambda[i]);
+ }
+ else {
+ order[i].error = dInfinity;
+ }
+ order[i].findex = findex[i];
+ order[i].index = i;
+ }
+ }
+ qsort (order,m,sizeof(IndexError),&compare_index_error);
+#endif
+#ifdef RANDOMLY_REORDER_CONSTRAINTS
+ if ((iteration & 7) == 0) {
+ for (i=1; i<m; ++i) {
+ IndexError tmp = order[i];
+ int swapi = dRandInt2(i+1);
+ order[i] = order[swapi];
+ order[swapi] = tmp;
+ }
+ }
+#endif
+
+ //@@@ potential optimization: swap lambda and last_lambda pointers rather
+ // than copying the data. we must make sure lambda is properly
+ // returned to the caller
+ memcpy (last_lambda,lambda,m*sizeof(float));
+
+ for (int i=0; i<m; i++) {
+ // @@@ potential optimization: we could pre-sort J and iMJ, thereby
+ // linearizing access to those arrays. hmmm, this does not seem
+ // like a win, but we should think carefully about our memory
+ // access pattern.
+
+ int index = order[i].index;
+ J_ptr = J + index*12;
+ iMJ_ptr = iMJ + index*12;
+
+ // set the limits for this constraint. note that 'hicopy' is used.
+ // this is the place where the QuickStep method differs from the
+ // direct LCP solving method, since that method only performs this
+ // limit adjustment once per time step, whereas this method performs
+ // once per iteration per constraint row.
+ // the constraints are ordered so that all lambda[] values needed have
+ // already been computed.
+ if (findex[index] >= 0) {
+ hi[index] = fabsf (hicopy[index] * lambda[findex[index]]);
+ lo[index] = -hi[index];
+ }
+
+ int b1 = jb[index*2];
+ int b2 = jb[index*2+1];
+ float delta = rhs[index] - lambda[index]*Ad[index];
+ dRealMutablePtr fc_ptr = invMforce + 6*b1;
+
+ // @@@ potential optimization: SIMD-ize this and the b2 >= 0 case
+ delta -=fc_ptr[0] * J_ptr[0] + fc_ptr[1] * J_ptr[1] +
+ fc_ptr[2] * J_ptr[2] + fc_ptr[3] * J_ptr[3] +
+ fc_ptr[4] * J_ptr[4] + fc_ptr[5] * J_ptr[5];
+ // @@@ potential optimization: handle 1-body constraints in a separate
+ // loop to avoid the cost of test & jump?
+ if (b2 >= 0) {
+ fc_ptr = invMforce + 6*b2;
+ delta -=fc_ptr[0] * J_ptr[6] + fc_ptr[1] * J_ptr[7] +
+ fc_ptr[2] * J_ptr[8] + fc_ptr[3] * J_ptr[9] +
+ fc_ptr[4] * J_ptr[10] + fc_ptr[5] * J_ptr[11];
+ }
+
+ // compute lambda and clamp it to [lo,hi].
+ // @@@ potential optimization: does SSE have clamping instructions
+ // to save test+jump penalties here?
+ float new_lambda = lambda[index] + delta;
+ if (new_lambda < lo[index]) {
+ delta = lo[index]-lambda[index];
+ lambda[index] = lo[index];
+ }
+ else if (new_lambda > hi[index]) {
+ delta = hi[index]-lambda[index];
+ lambda[index] = hi[index];
+ }
+ else {
+ lambda[index] = new_lambda;
+ }
+
+ //@@@ a trick that may or may not help
+ //float ramp = (1-((float)(iteration+1)/(float)num_iterations));
+ //delta *= ramp;
+
+ // update invMforce.
+ // @@@ potential optimization: SIMD for this and the b2 >= 0 case
+ fc_ptr = invMforce + 6*b1;
+ fc_ptr[0] += delta * iMJ_ptr[0];
+ fc_ptr[1] += delta * iMJ_ptr[1];
+ fc_ptr[2] += delta * iMJ_ptr[2];
+ fc_ptr[3] += delta * iMJ_ptr[3];
+ fc_ptr[4] += delta * iMJ_ptr[4];
+ fc_ptr[5] += delta * iMJ_ptr[5];
+ // @@@ potential optimization: handle 1-body constraints in a separate
+ // loop to avoid the cost of test & jump?
+ if (b2 >= 0) {
+ fc_ptr = invMforce + 6*b2;
+ fc_ptr[0] += delta * iMJ_ptr[6];
+ fc_ptr[1] += delta * iMJ_ptr[7];
+ fc_ptr[2] += delta * iMJ_ptr[8];
+ fc_ptr[3] += delta * iMJ_ptr[9];
+ fc_ptr[4] += delta * iMJ_ptr[10];
+ fc_ptr[5] += delta * iMJ_ptr[11];
+ }
+ }
+ }
+}
+
+
+
+void SolveInternal1 (float global_cfm,
+ float global_erp,
+ RigidBody * const *body, int nb,
+ BU_Joint * const *_joint,
+ int nj,
+ const ContactSolverInfo& solverInfo)
+{
+
+ int numIter = 30;
+ float sOr = 1.3f;
+
+ int i,j;
+
+ SimdScalar stepsize1 = dRecip(solverInfo.m_timeStep);
+
+ // number all bodies in the body list - set their tag values
+ for (i=0; i<nb; i++)
+ body[i]->m_odeTag = i;
+
+ // make a local copy of the joint array, because we might want to modify it.
+ // (the "BU_Joint *const*" declaration says we're allowed to modify the joints
+ // but not the joint array, because the caller might need it unchanged).
+ //@@@ do we really need to do this? we'll be sorting constraint rows individually, not joints
+ BU_Joint **joint = (BU_Joint**) alloca (nj * sizeof(BU_Joint*));
+ memcpy (joint,_joint,nj * sizeof(BU_Joint*));
+
+ // for all bodies, compute the inertia tensor and its inverse in the global
+ // frame, and compute the rotational force and add it to the torque
+ // accumulator. I and invI are a vertical stack of 3x4 matrices, one per body.
+ dRealAllocaArray (I,3*4*nb);
+ dRealAllocaArray (invI,3*4*nb);
+/* for (i=0; i<nb; i++) {
+ dMatrix3 tmp;
+ // compute inertia tensor in global frame
+ dMULTIPLY2_333 (tmp,body[i]->m_I,body[i]->m_R);
+ // compute inverse inertia tensor in global frame
+ dMULTIPLY2_333 (tmp,body[i]->m_invI,body[i]->m_R);
+ dMULTIPLY0_333 (invI+i*12,body[i]->m_R,tmp);
+ // compute rotational force
+ dCROSS (body[i]->m_tacc,-=,body[i]->getAngularVelocity(),tmp);
+ }
+*/
+ for (i=0; i<nb; i++) {
+ dMatrix3 tmp;
+ // compute inertia tensor in global frame
+ dMULTIPLY2_333 (tmp,body[i]->m_I,body[i]->m_R);
+ dMULTIPLY0_333 (I+i*12,body[i]->m_R,tmp);
+ // compute inverse inertia tensor in global frame
+ dMULTIPLY2_333 (tmp,body[i]->m_invI,body[i]->m_R);
+ dMULTIPLY0_333 (invI+i*12,body[i]->m_R,tmp);
+ // compute rotational force
+ dMULTIPLY0_331 (tmp,I+i*12,body[i]->getAngularVelocity());
+ //dCROSS (body[i]->tacc,-=,body[i]->avel,tmp);
+ dCROSS (body[i]->m_tacc,-=,body[i]->getAngularVelocity(),tmp);
+
+ }
+
+
+ // get joint information (m = total constraint dimension, nub = number of unbounded variables).
+ // joints with m=0 are inactive and are removed from the joints array
+ // entirely, so that the code that follows does not consider them.
+ //@@@ do we really need to save all the info1's
+ BU_Joint::Info1 *info = (BU_Joint::Info1*) alloca (nj*sizeof(BU_Joint::Info1));
+ for (i=0, j=0; j<nj; j++) { // i=dest, j=src
+ joint[j]->GetInfo1 (info+i);
+ dIASSERT (info[i].m >= 0 && info[i].m <= 6 && info[i].nub >= 0 && info[i].nub <= info[i].m);
+ if (info[i].m > 0) {
+ joint[i] = joint[j];
+ i++;
+ }
+ }
+ nj = i;
+
+ // create the row offset array
+ int m = 0;
+ int *ofs = (int*) alloca (nj*sizeof(int));
+ for (i=0; i<nj; i++) {
+ ofs[i] = m;
+ m += info[i].m;
+ }
+
+ // if there are constraints, compute the constraint force
+ dRealAllocaArray (J,m*12);
+ int *jb = (int*) alloca (m*2*sizeof(int));
+ if (m > 0) {
+ // create a constraint equation right hand side vector `c', a constraint
+ // force mixing vector `cfm', and LCP low and high bound vectors, and an
+ // 'findex' vector.
+ dRealAllocaArray (c,m);
+ dRealAllocaArray (cfm,m);
+ dRealAllocaArray (lo,m);
+ dRealAllocaArray (hi,m);
+ int *findex = (int*) alloca (m*sizeof(int));
+ dSetZero1 (c,m);
+ dSetValue1 (cfm,m,global_cfm);
+ dSetValue1 (lo,m,-dInfinity);
+ dSetValue1 (hi,m, dInfinity);
+ for (i=0; i<m; i++) findex[i] = -1;
+
+ // get jacobian data from constraints. an m*12 matrix will be created
+ // to store the two jacobian blocks from each constraint. it has this
+ // format:
+ //
+ // l1 l1 l1 a1 a1 a1 l2 l2 l2 a2 a2 a2 \ .
+ // l1 l1 l1 a1 a1 a1 l2 l2 l2 a2 a2 a2 }-- jacobian for joint 0, body 1 and body 2 (3 rows)
+ // l1 l1 l1 a1 a1 a1 l2 l2 l2 a2 a2 a2 /
+ // l1 l1 l1 a1 a1 a1 l2 l2 l2 a2 a2 a2 }--- jacobian for joint 1, body 1 and body 2 (3 rows)
+ // etc...
+ //
+ // (lll) = linear jacobian data
+ // (aaa) = angular jacobian data
+ //
+ dSetZero1 (J,m*12);
+ BU_Joint::Info2 Jinfo;
+ Jinfo.rowskip = 12;
+ Jinfo.fps = stepsize1;
+ Jinfo.erp = global_erp;
+ for (i=0; i<nj; i++) {
+ Jinfo.J1l = J + ofs[i]*12;
+ Jinfo.J1a = Jinfo.J1l + 3;
+ Jinfo.J2l = Jinfo.J1l + 6;
+ Jinfo.J2a = Jinfo.J1l + 9;
+ Jinfo.c = c + ofs[i];
+ Jinfo.cfm = cfm + ofs[i];
+ Jinfo.lo = lo + ofs[i];
+ Jinfo.hi = hi + ofs[i];
+ Jinfo.findex = findex + ofs[i];
+ joint[i]->GetInfo2 (&Jinfo);
+
+ if (Jinfo.c[0] > solverInfo.m_maxErrorReduction)
+ Jinfo.c[0] = solverInfo.m_maxErrorReduction;
+
+
+
+
+ // adjust returned findex values for global index numbering
+ for (j=0; j<info[i].m; j++) {
+ if (findex[ofs[i] + j] >= 0)
+ findex[ofs[i] + j] += ofs[i];
+ }
+ }
+
+ // create an array of body numbers for each joint row
+ int *jb_ptr = jb;
+ for (i=0; i<nj; i++) {
+ int b1 = (joint[i]->node[0].body) ? (joint[i]->node[0].body->m_odeTag) : -1;
+ int b2 = (joint[i]->node[1].body) ? (joint[i]->node[1].body->m_odeTag) : -1;
+ for (j=0; j<info[i].m; j++) {
+ jb_ptr[0] = b1;
+ jb_ptr[1] = b2;
+ jb_ptr += 2;
+ }
+ }
+ dIASSERT (jb_ptr == jb+2*m);
+
+ // compute the right hand side `rhs'
+ dRealAllocaArray (tmp1,nb*6);
+ // put v/h + invM*fe into tmp1
+ for (i=0; i<nb; i++) {
+ SimdScalar body_invMass = body[i]->getInvMass();
+ for (j=0; j<3; j++) tmp1[i*6+j] = body[i]->m_facc[j] * body_invMass + body[i]->getLinearVelocity()[j] * stepsize1;
+ dMULTIPLY0_331NEW (tmp1 + i*6 + 3,=,invI + i*12,body[i]->m_tacc);
+ for (j=0; j<3; j++) tmp1[i*6+3+j] += body[i]->getAngularVelocity()[j] * stepsize1;
+ }
+
+ // put J*tmp1 into rhs
+ dRealAllocaArray (rhs,m);
+ multiply_J (m,J,jb,tmp1,rhs);
+
+ // complete rhs
+ for (i=0; i<m; i++) rhs[i] = c[i]*stepsize1 - rhs[i];
+
+ // scale CFM
+ for (i=0; i<m; i++)
+ cfm[i] =0;//*= stepsize1;
+
+ // load lambda from the value saved on the previous iteration
+ dRealAllocaArray (lambda,m);
+#ifdef WARM_STARTING
+ dSetZero1 (lambda,m); //@@@ shouldn't be necessary
+ for (i=0; i<nj; i++) {
+ memcpy (lambda+ofs[i],joint[i]->lambda,info[i].m * sizeof(SimdScalar));
+ }
+#endif
+
+ // solve the LCP problem and get lambda and invM*constraint_force
+ dRealAllocaArray (cforce,nb*6);
+
+ SOR_LCP (m,nb,J,jb,body,invI,lambda,cforce,rhs,lo,hi,cfm,findex,numIter,sOr);
+
+#ifdef WARM_STARTING
+ // save lambda for the next iteration
+ //@@@ note that this doesn't work for contact joints yet, as they are
+ // recreated every iteration
+ for (i=0; i<nj; i++) {
+ memcpy (joint[i]->lambda,lambda+ofs[i],info[i].m * sizeof(SimdScalar));
+ }
+#endif
+
+
+ // note that the SOR method overwrites rhs and J at this point, so
+ // they should not be used again.
+
+ // add stepsize * cforce to the body velocity
+ for (i=0; i<nb; i++) {
+ SimdVector3 linvel = body[i]->getLinearVelocity();
+ SimdVector3 angvel = body[i]->getAngularVelocity();
+
+ for (j=0; j<3; j++)
+ linvel[j] += solverInfo.m_timeStep* cforce[i*6+j];
+ for (j=0; j<3; j++)
+ angvel[j] += solverInfo.m_timeStep* cforce[i*6+3+j];
+
+ body[i]->setLinearVelocity(linvel);
+ body[i]->setAngularVelocity(angvel);
+
+ }
+
+ }
+
+
+
+ // compute the velocity update:
+ // add stepsize * invM * fe to the body velocity
+
+ for (i=0; i<nb; i++) {
+ SimdScalar body_invMass = body[i]->getInvMass();
+ SimdVector3 linvel = body[i]->getLinearVelocity();
+ SimdVector3 angvel = body[i]->getAngularVelocity();
+
+ for (j=0; j<3; j++)
+ {
+ linvel[j] += solverInfo.m_timeStep * body_invMass * body[i]->m_facc[j];
+ }
+ for (j=0; j<3; j++)
+ {
+ body[i]->m_tacc[j] *= solverInfo.m_timeStep;
+ }
+ dMULTIPLY0_331NEW(angvel,+=,invI + i*12,body[i]->m_tacc);
+ body[i]->setAngularVelocity(angvel);
+
+ }
+
+
+
+}
+
+
+#endif //USE_SOR_SOLVER \ No newline at end of file
diff --git a/extern/bullet/BulletDynamics/ConstraintSolver/SorLcp.h b/extern/bullet/BulletDynamics/ConstraintSolver/SorLcp.h
new file mode 100644
index 00000000000..64c2f04e29d
--- /dev/null
+++ b/extern/bullet/BulletDynamics/ConstraintSolver/SorLcp.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies.
+ * Erwin Coumans makes no representations about the suitability
+ * of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+*/
+#define USE_SOR_SOLVER
+#ifdef USE_SOR_SOLVER
+
+#ifndef SOR_LCP_H
+#define SOR_LCP_H
+class RigidBody;
+class BU_Joint;
+#include "SimdScalar.h"
+
+struct ContactSolverInfo;
+
+void SolveInternal1 (float global_cfm,
+ float global_erp,
+ RigidBody * const *body, int nb,
+ BU_Joint * const *_joint, int nj, const ContactSolverInfo& info);
+
+int dRandInt2 (int n);
+
+
+#endif //SOR_LCP_H
+
+#endif //USE_SOR_SOLVER \ No newline at end of file
diff --git a/extern/bullet/BulletDynamics/Dynamics/BU_Joint.cpp b/extern/bullet/BulletDynamics/Dynamics/BU_Joint.cpp
new file mode 100644
index 00000000000..431a1eedf18
--- /dev/null
+++ b/extern/bullet/BulletDynamics/Dynamics/BU_Joint.cpp
@@ -0,0 +1,10 @@
+#include "BU_Joint.h"
+
+BU_Joint::BU_Joint()
+{
+
+}
+BU_Joint::~BU_Joint()
+{
+
+}
diff --git a/extern/bullet/BulletDynamics/Dynamics/BU_Joint.h b/extern/bullet/BulletDynamics/Dynamics/BU_Joint.h
new file mode 100644
index 00000000000..72536d6c2cf
--- /dev/null
+++ b/extern/bullet/BulletDynamics/Dynamics/BU_Joint.h
@@ -0,0 +1,78 @@
+#ifndef BU_Joint_H
+#define BU_Joint_H
+
+class RigidBody;
+class BU_Joint;
+#include "SimdScalar.h"
+
+struct BU_ContactJointNode {
+ BU_Joint *joint; // pointer to enclosing BU_Joint object
+ RigidBody*body; // *other* body this joint is connected to
+};
+typedef SimdScalar dVector3[4];
+
+
+class BU_Joint {
+
+public:
+ // naming convention: the "first" body this is connected to is node[0].body,
+ // and the "second" body is node[1].body. if this joint is only connected
+ // to one body then the second body is 0.
+
+ // info returned by getInfo1 function. the constraint dimension is m (<=6).
+ // i.e. that is the total number of rows in the jacobian. `nub' is the
+ // number of unbounded variables (which have lo,hi = -/+ infinity).
+
+ BU_Joint();
+ virtual ~BU_Joint();
+
+
+ struct Info1 {
+ int m,nub;
+ };
+
+ // info returned by getInfo2 function
+
+ struct Info2 {
+ // integrator parameters: frames per second (1/stepsize), default error
+ // reduction parameter (0..1).
+ SimdScalar fps,erp;
+
+ // for the first and second body, pointers to two (linear and angular)
+ // n*3 jacobian sub matrices, stored by rows. these matrices will have
+ // been initialized to 0 on entry. if the second body is zero then the
+ // J2xx pointers may be 0.
+ SimdScalar *J1l,*J1a,*J2l,*J2a;
+
+ // elements to jump from one row to the next in J's
+ int rowskip;
+
+ // right hand sides of the equation J*v = c + cfm * lambda. cfm is the
+ // "constraint force mixing" vector. c is set to zero on entry, cfm is
+ // set to a constant value (typically very small or zero) value on entry.
+ SimdScalar *c,*cfm;
+
+ // lo and hi limits for variables (set to -/+ infinity on entry).
+ SimdScalar *lo,*hi;
+
+ // findex vector for variables. see the LCP solver interface for a
+ // description of what this does. this is set to -1 on entry.
+ // note that the returned indexes are relative to the first index of
+ // the constraint.
+ int *findex;
+ };
+
+ // virtual function table: size of the joint structure, function pointers.
+ // we do it this way instead of using C++ virtual functions because
+ // sometimes we need to allocate joints ourself within a memory pool.
+
+ virtual void GetInfo1 (Info1 *info)=0;
+ virtual void GetInfo2 (Info2 *info)=0;
+
+ int flags; // dJOINT_xxx flags
+ BU_ContactJointNode node[2]; // connections to bodies. node[1].body can be 0
+ SimdScalar lambda[6]; // lambda generated by last step
+};
+
+
+#endif //BU_Joint_H
diff --git a/extern/bullet/BulletDynamics/Dynamics/ContactJoint.cpp b/extern/bullet/BulletDynamics/Dynamics/ContactJoint.cpp
new file mode 100644
index 00000000000..130a6b98402
--- /dev/null
+++ b/extern/bullet/BulletDynamics/Dynamics/ContactJoint.cpp
@@ -0,0 +1,233 @@
+#include "ContactJoint.h"
+#include "RigidBody.h"
+#include "NarrowPhaseCollision/PersistentManifold.h"
+
+
+
+ContactJoint::ContactJoint(PersistentManifold* manifold,int index,bool swap,RigidBody* body0,RigidBody* body1)
+:m_manifold(manifold),
+m_index(index),
+m_swapBodies(swap),
+m_body0(body0),
+m_body1(body1)
+{
+}
+
+int m_numRows = 3;
+
+float gContactFrictionFactor = 30.5f;//100.f;//1e30f;//2.9f;
+
+
+
+void ContactJoint::GetInfo1(Info1 *info)
+{
+ info->m = m_numRows;
+ //friction adds another 2...
+
+ info->nub = 0;
+}
+
+#define dCROSS(a,op,b,c) \
+ (a)[0] op ((b)[1]*(c)[2] - (b)[2]*(c)[1]); \
+ (a)[1] op ((b)[2]*(c)[0] - (b)[0]*(c)[2]); \
+ (a)[2] op ((b)[0]*(c)[1] - (b)[1]*(c)[0]);
+
+#define M_SQRT12 SimdScalar(0.7071067811865475244008443621048490)
+
+#define dRecipSqrt(x) ((float)(1.0f/sqrtf(float(x)))) /* reciprocal square root */
+
+
+
+void dPlaneSpace1 (const dVector3 n, dVector3 p, dVector3 q)
+{
+ if (fabsf(n[2]) > M_SQRT12) {
+ // choose p in y-z plane
+ SimdScalar a = n[1]*n[1] + n[2]*n[2];
+ SimdScalar k = dRecipSqrt (a);
+ p[0] = 0;
+ p[1] = -n[2]*k;
+ p[2] = n[1]*k;
+ // set q = n x p
+ q[0] = a*k;
+ q[1] = -n[0]*p[2];
+ q[2] = n[0]*p[1];
+ }
+ else {
+ // choose p in x-y plane
+ SimdScalar a = n[0]*n[0] + n[1]*n[1];
+ SimdScalar k = dRecipSqrt (a);
+ p[0] = -n[1]*k;
+ p[1] = n[0]*k;
+ p[2] = 0;
+ // set q = n x p
+ q[0] = -n[2]*p[1];
+ q[1] = n[2]*p[0];
+ q[2] = a*k;
+ }
+}
+
+
+
+void ContactJoint::GetInfo2(Info2 *info)
+{
+
+ int s = info->rowskip;
+ int s2 = 2*s;
+
+ float swapFactor = m_swapBodies ? -1.f : 1.f;
+
+ // get normal, with sign adjusted for body1/body2 polarity
+ dVector3 normal;
+
+
+ ManifoldPoint& point = m_manifold->GetContactPoint(m_index);
+
+ normal[0] = swapFactor*point.m_normalWorldOnB[0];
+ normal[1] = swapFactor*point.m_normalWorldOnB[1];
+ normal[2] = swapFactor*point.m_normalWorldOnB[2];
+ normal[3] = 0; // @@@ hmmm
+
+ // if (GetBody0())
+ SimdVector3 ccc1;
+ {
+ ccc1 = point.GetPositionWorldOnA() - m_body0->getCenterOfMassPosition();
+ dVector3 c1;
+ c1[0] = ccc1[0];
+ c1[1] = ccc1[1];
+ c1[2] = ccc1[2];
+
+ // set jacobian for normal
+ info->J1l[0] = normal[0];
+ info->J1l[1] = normal[1];
+ info->J1l[2] = normal[2];
+ dCROSS (info->J1a,=,c1,normal);
+
+ }
+ // if (GetBody1())
+ SimdVector3 ccc2;
+ {
+ dVector3 c2;
+ ccc2 = point.GetPositionWorldOnB() - m_body1->getCenterOfMassPosition();
+
+ // for (i=0; i<3; i++) c2[i] = j->contact.geom.pos[i] -
+ // j->node[1].body->pos[i];
+ c2[0] = ccc2[0];
+ c2[1] = ccc2[1];
+ c2[2] = ccc2[2];
+
+ info->J2l[0] = -normal[0];
+ info->J2l[1] = -normal[1];
+ info->J2l[2] = -normal[2];
+ dCROSS (info->J2a,= -,c2,normal);
+ }
+
+ SimdScalar k = info->fps * info->erp;
+
+ float depth = -point.GetDistance();
+ if (depth < 0.f)
+ depth = 0.f;
+
+ info->c[0] = k * depth;
+
+
+
+ // set LCP limits for normal
+ info->lo[0] = 0;
+ info->hi[0] = 1e30f;//dInfinity;
+
+#define DO_THE_FRICTION_2
+#ifdef DO_THE_FRICTION_2
+ // now do jacobian for tangential forces
+ dVector3 t1,t2; // two vectors tangential to normal
+
+ dVector3 c1;
+ c1[0] = ccc1[0];
+ c1[1] = ccc1[1];
+ c1[2] = ccc1[2];
+
+ dVector3 c2;
+ c2[0] = ccc2[0];
+ c2[1] = ccc2[1];
+ c2[2] = ccc2[2];
+ // first friction direction
+ if (m_numRows >= 2)
+ {
+
+
+
+ dPlaneSpace1 (normal,t1,t2);
+
+ info->J1l[s+0] = t1[0];
+ info->J1l[s+1] = t1[1];
+ info->J1l[s+2] = t1[2];
+ dCROSS (info->J1a+s,=,c1,t1);
+ if (1) { //j->node[1].body) {
+ info->J2l[s+0] = -t1[0];
+ info->J2l[s+1] = -t1[1];
+ info->J2l[s+2] = -t1[2];
+ dCROSS (info->J2a+s,= -,c2,t1);
+ }
+ // set right hand side
+ if (0) {//j->contact.surface.mode & dContactMotion1) {
+ //info->c[1] = j->contact.surface.motion1;
+ }
+ // set LCP bounds and friction index. this depends on the approximation
+ // mode
+ //1e30f
+
+ info->lo[1] = -gContactFrictionFactor;//-j->contact.surface.mu;
+ info->hi[1] = gContactFrictionFactor;//j->contact.surface.mu;
+ if (0)//j->contact.surface.mode & dContactApprox1_1)
+ info->findex[1] = 0;
+
+ // set slip (constraint force mixing)
+ if (0)//j->contact.surface.mode & dContactSlip1)
+ {
+ // info->cfm[1] = j->contact.surface.slip1;
+ }
+ }
+
+ // second friction direction
+ if (m_numRows >= 3) {
+ info->J1l[s2+0] = t2[0];
+ info->J1l[s2+1] = t2[1];
+ info->J1l[s2+2] = t2[2];
+ dCROSS (info->J1a+s2,=,c1,t2);
+ if (1) { //j->node[1].body) {
+ info->J2l[s2+0] = -t2[0];
+ info->J2l[s2+1] = -t2[1];
+ info->J2l[s2+2] = -t2[2];
+ dCROSS (info->J2a+s2,= -,c2,t2);
+ }
+ // set right hand side
+ if (0){//j->contact.surface.mode & dContactMotion2) {
+ //info->c[2] = j->contact.surface.motion2;
+ }
+ // set LCP bounds and friction index. this depends on the approximation
+ // mode
+ if (0){//j->contact.surface.mode & dContactMu2) {
+ //info->lo[2] = -j->contact.surface.mu2;
+ //info->hi[2] = j->contact.surface.mu2;
+ }
+ else {
+ info->lo[2] = -gContactFrictionFactor;
+ info->hi[2] = gContactFrictionFactor;
+ }
+ if (0)//j->contact.surface.mode & dContactApprox1_2)
+
+ {
+ info->findex[2] = 0;
+ }
+ // set slip (constraint force mixing)
+ if (0) //j->contact.surface.mode & dContactSlip2)
+
+ {
+ //info->cfm[2] = j->contact.surface.slip2;
+
+ }
+ }
+
+#endif //DO_THE_FRICTION_2
+
+}
+
diff --git a/extern/bullet/BulletDynamics/Dynamics/ContactJoint.h b/extern/bullet/BulletDynamics/Dynamics/ContactJoint.h
new file mode 100644
index 00000000000..54cc5283da0
--- /dev/null
+++ b/extern/bullet/BulletDynamics/Dynamics/ContactJoint.h
@@ -0,0 +1,33 @@
+#ifndef CONTACT_JOINT_H
+#define CONTACT_JOINT_H
+
+#include "BU_Joint.h"
+class RigidBody;
+class PersistentManifold;
+
+class ContactJoint : public BU_Joint
+{
+ PersistentManifold* m_manifold;
+ int m_index;
+ bool m_swapBodies;
+ RigidBody* m_body0;
+ RigidBody* m_body1;
+
+
+public:
+
+ ContactJoint() {};
+
+ ContactJoint(PersistentManifold* manifold,int index,bool swap,RigidBody* body0,RigidBody* body1);
+
+ //BU_Joint interface for solver
+
+ virtual void GetInfo1(Info1 *info);
+
+ virtual void GetInfo2(Info2 *info);
+
+
+
+
+};
+#endif //CONTACT_JOINT_H \ No newline at end of file
diff --git a/extern/bullet/BulletDynamics/Dynamics/MassProps.h b/extern/bullet/BulletDynamics/Dynamics/MassProps.h
new file mode 100644
index 00000000000..892e1c0b9a8
--- /dev/null
+++ b/extern/bullet/BulletDynamics/Dynamics/MassProps.h
@@ -0,0 +1,18 @@
+
+#ifndef MASS_PROPS_H
+#define MASS_PROPS_H
+
+#include <SimdVector3.h>
+
+struct MassProps {
+ MassProps(float mass,const SimdVector3& inertiaLocal):
+ m_mass(mass),
+ m_inertiaLocal(inertiaLocal)
+ {
+ }
+ float m_mass;
+ SimdVector3 m_inertiaLocal;
+};
+
+
+#endif \ No newline at end of file
diff --git a/extern/bullet/BulletDynamics/Dynamics/RigidBody.cpp b/extern/bullet/BulletDynamics/Dynamics/RigidBody.cpp
new file mode 100644
index 00000000000..10dccd3dd20
--- /dev/null
+++ b/extern/bullet/BulletDynamics/Dynamics/RigidBody.cpp
@@ -0,0 +1,157 @@
+#include "RigidBody.h"
+#include "MassProps.h"
+#include "CollisionShapes/ConvexShape.h"
+#include "GEN_minmax.h"
+#include <SimdTransformUtil.h>
+
+float gRigidBodyDamping = 0.5f;
+static int uniqueId = 0;
+
+RigidBody::RigidBody( const MassProps& massProps,SimdScalar linearDamping,SimdScalar angularDamping)
+: m_collisionShape(0),
+ m_activationState1(1),
+ m_hitFraction(1.f),
+ m_gravity(0.0f, 0.0f, 0.0f),
+ m_linearDamping(0.f),
+ m_angularDamping(0.5f),
+ m_totalForce(0.0f, 0.0f, 0.0f),
+ m_totalTorque(0.0f, 0.0f, 0.0f),
+ m_linearVelocity(0.0f, 0.0f, 0.0f),
+ m_angularVelocity(0.f,0.f,0.f)
+
+{
+ m_debugBodyId = uniqueId++;
+
+ setMassProps(massProps.m_mass, massProps.m_inertiaLocal);
+ setDamping(linearDamping, angularDamping);
+ updateInertiaTensor();
+ m_worldTransform.setIdentity();
+
+}
+
+void RigidBody::setLinearVelocity(const SimdVector3& lin_vel)
+{
+
+ m_linearVelocity = lin_vel;
+}
+
+
+void RigidBody::predictIntegratedTransform(SimdScalar timeStep,SimdTransform& predictedTransform) const
+{
+ SimdTransformUtil::IntegrateTransform(m_worldTransform,m_linearVelocity,m_angularVelocity,timeStep,predictedTransform);
+}
+
+
+void RigidBody::getAabb(SimdVector3& aabbMin,SimdVector3& aabbMax) const
+{
+ m_collisionShape ->GetAabb(m_worldTransform,aabbMin,aabbMax);
+}
+
+void RigidBody::SetCollisionShape(CollisionShape* mink)
+{
+ m_collisionShape = mink;
+ SimdTransform ident;
+ ident.setIdentity();
+ SimdVector3 aabbMin,aabbMax;
+ m_collisionShape ->GetAabb(ident,aabbMin,aabbMax);
+ SimdVector3 diag = (aabbMax-aabbMin)*0.5f;
+}
+
+
+void RigidBody::setGravity(const SimdVector3& acceleration)
+{
+ if (m_inverseMass != 0.0f)
+ {
+ m_gravity = acceleration * (1.0f / m_inverseMass);
+ }
+}
+
+bool RigidBody::mergesSimulationIslands() const
+{
+ return ( getInvMass() != 0) ;
+}
+
+void RigidBody::SetActivationState(int newState)
+{
+ m_activationState1 = newState;
+}
+
+
+
+void RigidBody::setDamping(SimdScalar lin_damping, SimdScalar ang_damping)
+{
+ m_linearDamping = GEN_clamped(lin_damping, 0.0f, 1.0f);
+ m_angularDamping = GEN_clamped(ang_damping, 0.0f, 1.0f);
+}
+
+
+
+#include <stdio.h>
+
+void RigidBody::applyForces(SimdScalar step)
+{
+
+ applyCentralForce(m_gravity);
+
+ m_linearVelocity *= GEN_clamped((1.f - step * m_linearDamping), 0.0f, 1.0f);
+ m_angularVelocity *= GEN_clamped((1.f - step * m_angularDamping), 0.0f, 1.0f);
+
+}
+
+void RigidBody::proceedToTransform(const SimdTransform& newTrans)
+{
+ setCenterOfMassTransform( newTrans );
+}
+
+
+void RigidBody::setMassProps(SimdScalar mass, const SimdVector3& inertia)
+{
+ m_inverseMass = mass != 0.0f ? 1.0f / mass : 0.0f;
+ m_invInertiaLocal.setValue(inertia[0] != 0.0f ? 1.0f / inertia[0]: 0.0f,
+ inertia[1] != 0.0f ? 1.0f / inertia[1]: 0.0f,
+ inertia[2] != 0.0f ? 1.0f / inertia[2]: 0.0f);
+
+}
+
+
+
+void RigidBody::updateInertiaTensor()
+{
+ m_invInertiaTensorWorld = m_worldTransform.getBasis().scaled(m_invInertiaLocal) * m_worldTransform.getBasis().transpose();
+}
+
+
+void RigidBody::integrateVelocities(SimdScalar step)
+{
+ m_linearVelocity += m_totalForce * (m_inverseMass * step);
+ m_angularVelocity += m_invInertiaTensorWorld * m_totalTorque * step;
+
+#define MAX_ANGVEL SIMD_HALF_PI
+ /// clamp angular velocity. collision calculations will fail on higher angular velocities
+ float angvel = m_angularVelocity.length();
+ if (angvel*step > MAX_ANGVEL)
+ {
+ m_angularVelocity *= (MAX_ANGVEL/step) /angvel;
+ }
+
+ clearForces();
+}
+
+SimdQuaternion RigidBody::getOrientation() const
+{
+ SimdQuaternion orn;
+ m_worldTransform.getBasis().getRotation(orn);
+ return orn;
+}
+
+
+void RigidBody::setCenterOfMassTransform(const SimdTransform& xform)
+{
+ m_worldTransform = xform;
+
+// m_worldTransform.getBasis().getRotation(m_orn1);
+ updateInertiaTensor();
+}
+
+
+
diff --git a/extern/bullet/BulletDynamics/Dynamics/RigidBody.h b/extern/bullet/BulletDynamics/Dynamics/RigidBody.h
new file mode 100644
index 00000000000..ec7eb9a8678
--- /dev/null
+++ b/extern/bullet/BulletDynamics/Dynamics/RigidBody.h
@@ -0,0 +1,165 @@
+#ifndef RIGIDBODY_H
+#define RIGIDBODY_H
+
+#include <vector>
+#include <SimdPoint3.h>
+#include <SimdTransform.h>
+
+class CollisionShape;
+struct MassProps;
+typedef SimdScalar dMatrix3[4*3];
+
+
+/// RigidBody class for RigidBody Dynamics
+///
+class RigidBody {
+public:
+
+ RigidBody(const MassProps& massProps,SimdScalar linearDamping,SimdScalar angularDamping);
+
+ void proceedToTransform(const SimdTransform& newTrans);
+
+ bool mergesSimulationIslands() const;
+
+ /// continuous collision detection needs prediction
+ void predictIntegratedTransform(SimdScalar step, SimdTransform& predictedTransform) const;
+
+ void applyForces(SimdScalar step);
+
+ void setGravity(const SimdVector3& acceleration);
+
+ void setDamping(SimdScalar lin_damping, SimdScalar ang_damping);
+
+ CollisionShape* GetCollisionShape() { return m_collisionShape; }
+
+ void setMassProps(SimdScalar mass, const SimdVector3& inertia);
+
+ SimdScalar getInvMass() const { return m_inverseMass; }
+ const SimdMatrix3x3& getInvInertiaTensorWorld() const { return m_invInertiaTensorWorld; }
+
+ void integrateVelocities(SimdScalar step);
+
+ void setCenterOfMassTransform(const SimdTransform& xform);
+
+ void applyCentralForce(const SimdVector3& force)
+ {
+ m_totalForce += force;
+ }
+
+ const SimdVector3& getInvInertiaDiagLocal()
+ {
+ return m_invInertiaLocal;
+ };
+
+ void setInvInertiaDiagLocal(const SimdVector3& diagInvInertia)
+ {
+ m_invInertiaLocal = diagInvInertia;
+ }
+
+ void applyTorque(const SimdVector3& torque)
+ {
+ m_totalTorque += torque;
+ }
+
+ void applyForce(const SimdVector3& force, const SimdVector3& rel_pos)
+ {
+ applyCentralForce(force);
+ applyTorque(rel_pos.cross(force));
+ }
+
+ void applyCentralImpulse(const SimdVector3& impulse)
+ {
+ m_linearVelocity += impulse * m_inverseMass;
+ }
+
+ void applyTorqueImpulse(const SimdVector3& torque)
+ {
+ m_angularVelocity += m_invInertiaTensorWorld * torque;
+
+ }
+
+ void applyImpulse(const SimdVector3& impulse, const SimdVector3& rel_pos)
+ {
+ if (m_inverseMass != 0.f)
+ {
+ applyCentralImpulse(impulse);
+ applyTorqueImpulse(rel_pos.cross(impulse));
+ }
+ }
+
+ void clearForces()
+ {
+ m_totalForce.setValue(0.0f, 0.0f, 0.0f);
+ m_totalTorque.setValue(0.0f, 0.0f, 0.0f);
+ }
+
+ void updateInertiaTensor();
+
+ const SimdPoint3& getCenterOfMassPosition() const { return m_worldTransform.getOrigin(); }
+ SimdQuaternion getOrientation() const;
+
+ const SimdTransform& getCenterOfMassTransform() const { return m_worldTransform; }
+ const SimdVector3& getLinearVelocity() const { return m_linearVelocity; }
+ const SimdVector3& getAngularVelocity() const { return m_angularVelocity; }
+
+
+ void setLinearVelocity(const SimdVector3& lin_vel);
+ void setAngularVelocity(const SimdVector3& ang_vel) { m_angularVelocity = ang_vel; }
+
+ SimdVector3 getVelocityInLocalPoint(const SimdVector3& rel_pos) const
+ {
+ return m_linearVelocity + m_angularVelocity.cross(rel_pos);
+ }
+
+ void translate(const SimdVector3& v)
+ {
+ m_worldTransform.getOrigin() += v;
+ }
+
+ void SetCollisionShape(CollisionShape* mink);
+
+ void getAabb(SimdVector3& aabbMin,SimdVector3& aabbMax) const;
+
+ int GetActivationState() const { return m_activationState1;}
+ void SetActivationState(int newState);
+
+
+private:
+ SimdTransform m_worldTransform;
+ SimdMatrix3x3 m_invInertiaTensorWorld;
+ SimdVector3 m_gravity;
+ SimdVector3 m_invInertiaLocal;
+ SimdVector3 m_totalForce;
+ SimdVector3 m_totalTorque;
+ SimdQuaternion m_orn1;
+
+ SimdVector3 m_linearVelocity;
+
+ SimdVector3 m_angularVelocity;
+
+ SimdScalar m_linearDamping;
+ SimdScalar m_angularDamping;
+ SimdScalar m_inverseMass;
+
+
+ CollisionShape* m_collisionShape;
+
+
+public:
+ /// for ode solver-binding
+ dMatrix3 m_R;//temp
+ dMatrix3 m_I;
+ dMatrix3 m_invI;
+ int m_islandTag1;//temp
+ int m_activationState1;//temp
+ int m_odeTag;
+ SimdVector3 m_tacc;//temp
+ SimdVector3 m_facc;
+ SimdScalar m_hitFraction; //time of impact calculation
+
+ int m_debugBodyId;
+};
+
+
+
+#endif
diff --git a/extern/bullet/BulletLicense.txt b/extern/bullet/BulletLicense.txt
new file mode 100644
index 00000000000..8405bef82e4
--- /dev/null
+++ b/extern/bullet/BulletLicense.txt
@@ -0,0 +1,14 @@
+/*
+ * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies.
+ * Erwin Coumans makes no representations about the suitability
+ * of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+*/
+
+
+Free for commercial use, but please mail bullet@erwincoumans.com to report projects, and join the forum at
+www.continuousphysics.com/Bullet/phpBB2
diff --git a/extern/bullet/Extras/PhysicsInterface/CcdPhysics/CcdPhysics.dsp b/extern/bullet/Extras/PhysicsInterface/CcdPhysics/CcdPhysics.dsp
new file mode 100644
index 00000000000..48d42617d3d
--- /dev/null
+++ b/extern/bullet/Extras/PhysicsInterface/CcdPhysics/CcdPhysics.dsp
@@ -0,0 +1,112 @@
+# Microsoft Developer Studio Project File - Name="CcdPhysics" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Static Library" 0x0104
+
+CFG=CcdPhysics - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "CcdPhysics.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "CcdPhysics.mak" CFG="CcdPhysics - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "CcdPhysics - Win32 Release" (based on "Win32 (x86) Static Library")
+!MESSAGE "CcdPhysics - Win32 Debug" (based on "Win32 (x86) Static Library")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "CcdPhysics - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "CcdPhysics___Win32_Release"
+# PROP BASE Intermediate_Dir "CcdPhysics___Win32_Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "CcdPhysics___Win32_Release"
+# PROP Intermediate_Dir "CcdPhysics___Win32_Release"
+# PROP Target_Dir ""
+LINK32=link.exe -lib
+MTL=midl.exe
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
+# ADD CPP /nologo /W3 /GX /O2 /I "..\..\..\Bullet" /I "..\..\..\LinearMath" /I "..\..\..\BulletDynamics" /I "..\..\..\Extras\PhysicsInterface\Common" /I "..\..\..\Extras\PhysicsInterface\CcdPhysics" /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
+# ADD BASE RSC /l 0x809 /d "NDEBUG"
+# ADD RSC /l 0x809 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LIB32=link.exe -lib
+# ADD BASE LIB32 /nologo
+# ADD LIB32 /nologo
+
+!ELSEIF "$(CFG)" == "CcdPhysics - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "CcdPhysics___Win32_Debug"
+# PROP BASE Intermediate_Dir "CcdPhysics___Win32_Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "CcdPhysics___Win32_Debug"
+# PROP Intermediate_Dir "CcdPhysics___Win32_Debug"
+# PROP Target_Dir ""
+LINK32=link.exe -lib
+MTL=midl.exe
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
+# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "..\..\..\Bullet" /I "..\..\..\LinearMath" /I "..\..\..\BulletDynamics" /I "..\..\..\Extras\PhysicsInterface\Common" /I "..\..\..\Extras\PhysicsInterface\CcdPhysics" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
+# ADD BASE RSC /l 0x809 /d "_DEBUG"
+# ADD RSC /l 0x809 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LIB32=link.exe -lib
+# ADD BASE LIB32 /nologo
+# ADD LIB32 /nologo
+
+!ENDIF
+
+# Begin Target
+
+# Name "CcdPhysics - Win32 Release"
+# Name "CcdPhysics - Win32 Debug"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=.\CcdPhysicsController.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\CcdPhysicsEnvironment.cpp
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# Begin Source File
+
+SOURCE=.\CcdPhysicsController.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\CcdPhysicsEnvironment.h
+# End Source File
+# End Group
+# End Target
+# End Project
diff --git a/extern/bullet/Extras/PhysicsInterface/CcdPhysics/CcdPhysicsController.cpp b/extern/bullet/Extras/PhysicsInterface/CcdPhysics/CcdPhysicsController.cpp
new file mode 100644
index 00000000000..376a75f40d3
--- /dev/null
+++ b/extern/bullet/Extras/PhysicsInterface/CcdPhysics/CcdPhysicsController.cpp
@@ -0,0 +1,230 @@
+#include "CcdPhysicsController.h"
+
+#include "Dynamics/RigidBody.h"
+#include "PHY_IMotionState.h"
+#include "BroadphaseCollision/BroadphaseProxy.h"
+#include "CollisionShapes/ConvexShape.h"
+
+class BP_Proxy;
+
+bool gEnableSleeping = true;//false;//true;
+#include "Dynamics/MassProps.h"
+
+SimdVector3 startVel(0,0,0);//-10000);
+CcdPhysicsController::CcdPhysicsController (const CcdConstructionInfo& ci)
+{
+ m_collisionDelay = 0;
+
+ m_sleepingCounter = 0;
+
+ m_MotionState = ci.m_MotionState;
+
+
+ SimdTransform trans;
+ float tmp[3];
+ m_MotionState->getWorldPosition(tmp[0],tmp[1],tmp[2]);
+ trans.setOrigin(SimdVector3(tmp[0],tmp[1],tmp[2]));
+
+ SimdQuaternion orn;
+ m_MotionState->getWorldOrientation(orn[0],orn[1],orn[2],orn[3]);
+ trans.setRotation(orn);
+
+ MassProps mp(ci.m_mass, ci.m_localInertiaTensor);
+
+ m_body = new RigidBody(mp,0,0);
+
+ m_broadphaseHandle = ci.m_broadphaseHandle;
+
+ m_collisionShape = ci.m_collisionShape;
+
+ //
+ // init the rigidbody properly
+ //
+
+ m_body->setMassProps(ci.m_mass, ci.m_localInertiaTensor);
+ m_body->setGravity( ci.m_gravity);
+
+ m_friction = ci.m_friction;
+ m_restitution = ci.m_restitution;
+
+ m_body->setDamping(ci.m_linearDamping, ci.m_angularDamping);
+
+
+ m_body->setCenterOfMassTransform( trans );
+
+ #ifdef WIN32
+ if (m_body->getInvMass())
+ m_body->setLinearVelocity(startVel);
+ #endif
+
+}
+
+CcdPhysicsController::~CcdPhysicsController()
+{
+ //will be reference counted, due to sharing
+ //delete m_collisionShape;
+ delete m_MotionState;
+ delete m_body;
+}
+
+ /**
+ SynchronizeMotionStates ynchronizes dynas, kinematic and deformable entities (and do 'late binding')
+ */
+bool CcdPhysicsController::SynchronizeMotionStates(float time)
+{
+ const SimdVector3& worldPos = m_body->getCenterOfMassPosition();
+ m_MotionState->setWorldPosition(worldPos[0],worldPos[1],worldPos[2]);
+
+ const SimdQuaternion& worldquat = m_body->getOrientation();
+ m_MotionState->setWorldOrientation(worldquat[0],worldquat[1],worldquat[2],worldquat[3]);
+
+ m_MotionState->calculateWorldTransformations();
+
+ float scale[3];
+ m_MotionState->getWorldScaling(scale[0],scale[1],scale[2]);
+
+ SimdVector3 scaling(scale[0],scale[1],scale[2]);
+ m_collisionShape->setLocalScaling(scaling);
+
+
+ return true;
+}
+
+ /**
+ WriteMotionStateToDynamics synchronizes dynas, kinematic and deformable entities (and do 'late binding')
+ */
+
+void CcdPhysicsController::WriteMotionStateToDynamics(bool nondynaonly)
+{
+
+}
+void CcdPhysicsController::WriteDynamicsToMotionState()
+{
+}
+ // controller replication
+void CcdPhysicsController::PostProcessReplica(class PHY_IMotionState* motionstate,class PHY_IPhysicsController* parentctrl)
+{
+}
+
+ // kinematic methods
+void CcdPhysicsController::RelativeTranslate(float dlocX,float dlocY,float dlocZ,bool local)
+{
+ SimdTransform xform = m_body->getCenterOfMassTransform();
+ xform.setOrigin(xform.getOrigin() + SimdVector3(dlocX,dlocY,dlocZ));
+ this->m_body->setCenterOfMassTransform(xform);
+
+}
+
+void CcdPhysicsController::RelativeRotate(const float drot[9],bool local)
+{
+}
+void CcdPhysicsController::getOrientation(float &quatImag0,float &quatImag1,float &quatImag2,float &quatReal)
+{
+}
+void CcdPhysicsController::setOrientation(float quatImag0,float quatImag1,float quatImag2,float quatReal)
+{
+}
+void CcdPhysicsController::setPosition(float posX,float posY,float posZ)
+{
+}
+void CcdPhysicsController::resolveCombinedVelocities(float linvelX,float linvelY,float linvelZ,float angVelX,float angVelY,float angVelZ)
+{
+}
+
+void CcdPhysicsController::getPosition(PHY__Vector3& pos) const
+{
+ assert(0);
+}
+
+void CcdPhysicsController::setScaling(float scaleX,float scaleY,float scaleZ)
+{
+}
+
+ // physics methods
+void CcdPhysicsController::ApplyTorque(float torqueX,float torqueY,float torqueZ,bool local)
+{
+}
+void CcdPhysicsController::ApplyForce(float forceX,float forceY,float forceZ,bool local)
+{
+}
+void CcdPhysicsController::SetAngularVelocity(float ang_velX,float ang_velY,float ang_velZ,bool local)
+{
+ SimdVector3 angvel(ang_velX,ang_velY,ang_velZ);
+
+ m_body->setAngularVelocity(angvel);
+
+}
+void CcdPhysicsController::SetLinearVelocity(float lin_velX,float lin_velY,float lin_velZ,bool local)
+{
+
+ SimdVector3 linVel(lin_velX,lin_velY,lin_velZ);
+ m_body->setLinearVelocity(linVel);
+}
+void CcdPhysicsController::applyImpulse(float attachX,float attachY,float attachZ, float impulseX,float impulseY,float impulseZ)
+{
+}
+void CcdPhysicsController::SetActive(bool active)
+{
+}
+ // reading out information from physics
+void CcdPhysicsController::GetLinearVelocity(float& linvX,float& linvY,float& linvZ)
+{
+}
+void CcdPhysicsController::GetVelocity(const float posX,const float posY,const float posZ,float& linvX,float& linvY,float& linvZ)
+{
+}
+void CcdPhysicsController::getReactionForce(float& forceX,float& forceY,float& forceZ)
+{
+}
+
+ // dyna's that are rigidbody are free in orientation, dyna's with non-rigidbody are restricted
+void CcdPhysicsController::setRigidBody(bool rigid)
+{
+}
+
+ // clientinfo for raycasts for example
+void* CcdPhysicsController::getNewClientInfo()
+{
+ return 0;
+}
+void CcdPhysicsController::setNewClientInfo(void* clientinfo)
+{
+
+}
+
+#ifdef WIN32
+float gSleepingTreshold = 0.8f;
+float gAngularSleepingTreshold = 1.f;
+
+#else
+
+float gSleepingTreshold = 0.8f;
+float gAngularSleepingTreshold = 1.0f;
+#endif
+
+
+bool CcdPhysicsController::wantsSleeping()
+{
+
+ if (!gEnableSleeping)
+ return false;
+
+ if ( (m_body->GetActivationState() == 3) || (m_body->GetActivationState() == 2))
+ return true;
+
+ if ((m_body->getLinearVelocity().length2() < gSleepingTreshold*gSleepingTreshold) &&
+ (m_body->getAngularVelocity().length2() < gAngularSleepingTreshold*gAngularSleepingTreshold))
+ {
+ m_sleepingCounter++;
+ } else
+ {
+ m_sleepingCounter=0;
+ }
+
+ if (m_sleepingCounter> 150)
+ {
+ return true;
+ }
+ return false;
+}
+
diff --git a/extern/bullet/Extras/PhysicsInterface/CcdPhysics/CcdPhysicsController.h b/extern/bullet/Extras/PhysicsInterface/CcdPhysics/CcdPhysicsController.h
new file mode 100644
index 00000000000..3a8590e261c
--- /dev/null
+++ b/extern/bullet/Extras/PhysicsInterface/CcdPhysics/CcdPhysicsController.h
@@ -0,0 +1,133 @@
+
+#ifndef BULLET2_PHYSICSCONTROLLER_H
+#define BULLET2_PHYSICSCONTROLLER_H
+
+#include "PHY_IPhysicsController.h"
+
+/// PHY_IPhysicsController is the abstract simplified Interface to a physical object.
+/// It contains the IMotionState and IDeformableMesh Interfaces.
+#include "SimdVector3.h"
+#include "SimdScalar.h"
+class CollisionShape;
+
+struct CcdConstructionInfo
+{
+ CcdConstructionInfo()
+ : m_gravity(0,0,0),
+ m_mass(0.f),
+ m_friction(0.1f),
+ m_restitution(0.1f),
+ m_linearDamping(0.1f),
+ m_angularDamping(0.1f),
+ m_MotionState(0),
+ m_collisionShape(0)
+
+ {
+ }
+ SimdVector3 m_localInertiaTensor;
+ SimdVector3 m_gravity;
+ SimdScalar m_mass;
+ SimdScalar m_friction;
+ SimdScalar m_restitution;
+
+ SimdScalar m_linearDamping;
+ SimdScalar m_angularDamping;
+ void* m_broadphaseHandle;
+ class PHY_IMotionState* m_MotionState;
+
+ CollisionShape* m_collisionShape;
+
+};
+
+
+class RigidBody;
+
+///CcdPhysicsController is a physics object that supports continuous collision detection and time of impact based physics resolution.
+class CcdPhysicsController : public PHY_IPhysicsController
+{
+ RigidBody* m_body;
+ class PHY_IMotionState* m_MotionState;
+ CollisionShape* m_collisionShape;
+
+ int m_sleepingCounter;
+ public:
+
+ int m_collisionDelay;
+
+ SimdScalar m_friction;
+ SimdScalar m_restitution;
+ void* m_broadphaseHandle;
+
+ CcdPhysicsController (const CcdConstructionInfo& ci);
+
+ virtual ~CcdPhysicsController();
+
+
+ RigidBody* GetRigidBody() { return m_body;}
+
+ CollisionShape* GetCollisionShape() { return m_collisionShape;}
+ ////////////////////////////////////
+ // PHY_IPhysicsController interface
+ ////////////////////////////////////
+
+
+ /**
+ SynchronizeMotionStates ynchronizes dynas, kinematic and deformable entities (and do 'late binding')
+ */
+ virtual bool SynchronizeMotionStates(float time);
+ /**
+ WriteMotionStateToDynamics ynchronizes dynas, kinematic and deformable entities (and do 'late binding')
+ */
+
+ virtual void WriteMotionStateToDynamics(bool nondynaonly);
+ virtual void WriteDynamicsToMotionState();
+ // controller replication
+ virtual void PostProcessReplica(class PHY_IMotionState* motionstate,class PHY_IPhysicsController* parentctrl);
+
+ // kinematic methods
+ virtual void RelativeTranslate(float dlocX,float dlocY,float dlocZ,bool local);
+ virtual void RelativeRotate(const float drot[9],bool local);
+ virtual void getOrientation(float &quatImag0,float &quatImag1,float &quatImag2,float &quatReal);
+ virtual void setOrientation(float quatImag0,float quatImag1,float quatImag2,float quatReal);
+ virtual void setPosition(float posX,float posY,float posZ);
+ virtual void getPosition(PHY__Vector3& pos) const;
+
+ virtual void setScaling(float scaleX,float scaleY,float scaleZ);
+
+ // physics methods
+ virtual void ApplyTorque(float torqueX,float torqueY,float torqueZ,bool local);
+ virtual void ApplyForce(float forceX,float forceY,float forceZ,bool local);
+ virtual void SetAngularVelocity(float ang_velX,float ang_velY,float ang_velZ,bool local);
+ virtual void SetLinearVelocity(float lin_velX,float lin_velY,float lin_velZ,bool local);
+ virtual void applyImpulse(float attachX,float attachY,float attachZ, float impulseX,float impulseY,float impulseZ);
+ virtual void SetActive(bool active);
+
+ // reading out information from physics
+ virtual void GetLinearVelocity(float& linvX,float& linvY,float& linvZ);
+ virtual void GetVelocity(const float posX,const float posY,const float posZ,float& linvX,float& linvY,float& linvZ);
+ virtual void getReactionForce(float& forceX,float& forceY,float& forceZ);
+
+ // dyna's that are rigidbody are free in orientation, dyna's with non-rigidbody are restricted
+ virtual void setRigidBody(bool rigid);
+
+
+ virtual void resolveCombinedVelocities(float linvelX,float linvelY,float linvelZ,float angVelX,float angVelY,float angVelZ);
+
+ // clientinfo for raycasts for example
+ virtual void* getNewClientInfo();
+ virtual void setNewClientInfo(void* clientinfo);
+ virtual PHY_IPhysicsController* GetReplica() {return 0;}
+
+ virtual void calcXform() {} ;
+ virtual void SetMargin(float margin) {};
+ virtual float GetMargin() const {return 0.f;};
+
+
+ bool wantsSleeping();
+
+ void SetAabb(const SimdVector3& aabbMin,const SimdVector3& aabbMax);
+
+
+};
+
+#endif //BULLET2_PHYSICSCONTROLLER_H
diff --git a/extern/bullet/Extras/PhysicsInterface/CcdPhysics/CcdPhysicsEnvironment.h b/extern/bullet/Extras/PhysicsInterface/CcdPhysics/CcdPhysicsEnvironment.h
new file mode 100644
index 00000000000..88cf4b495cf
--- /dev/null
+++ b/extern/bullet/Extras/PhysicsInterface/CcdPhysics/CcdPhysicsEnvironment.h
@@ -0,0 +1,121 @@
+#ifndef CCDPHYSICSENVIRONMENT
+#define CCDPHYSICSENVIRONMENT
+
+#include "PHY_IPhysicsEnvironment.h"
+#include <vector>
+class CcdPhysicsController;
+#include "SimdVector3.h"
+
+struct PHY_IPhysicsDebugDraw
+{
+ virtual void DrawLine(const SimdVector3& from,const SimdVector3& to,const SimdVector3& color)=0;
+};
+
+
+class Point2PointConstraint;
+class ToiContactDispatcher;
+class Dispatcher;
+//#include "BroadphaseInterface.h"
+
+class Vehicle;
+class PersistentManifold;
+class BroadphaseInterface;
+
+/// Physics Environment takes care of stepping the simulation and is a container for physics entities.
+/// It stores rigidbodies,constraints, materials etc.
+/// A derived class may be able to 'construct' entities by loading and/or converting
+class CcdPhysicsEnvironment : public PHY_IPhysicsEnvironment
+{
+ SimdVector3 m_gravity;
+ BroadphaseInterface* m_broadphase;
+ PHY_IPhysicsDebugDraw* m_debugDrawer;
+
+ public:
+ CcdPhysicsEnvironment(ToiContactDispatcher* dispatcher=0, BroadphaseInterface* broadphase=0);
+
+ virtual ~CcdPhysicsEnvironment();
+
+ /////////////////////////////////////
+ //PHY_IPhysicsEnvironment interface
+ /////////////////////////////////////
+
+ /// Perform an integration step of duration 'timeStep'.
+
+ virtual void setDebugDrawer(PHY_IPhysicsDebugDraw* debugDrawer)
+ {
+ m_debugDrawer = debugDrawer;
+ }
+
+
+ virtual void beginFrame() {};
+ virtual void endFrame() {};
+ /// Perform an integration step of duration 'timeStep'.
+ virtual bool proceedDeltaTime(double curTime,float timeStep);
+ virtual void setFixedTimeStep(bool useFixedTimeStep,float fixedTimeStep){};
+ //returns 0.f if no fixed timestep is used
+ virtual float getFixedTimeStep(){ return 0.f;};
+
+ virtual void setGravity(float x,float y,float z);
+
+ virtual int createConstraint(class PHY_IPhysicsController* ctrl,class PHY_IPhysicsController* ctrl2,PHY_ConstraintType type,
+ float pivotX,float pivotY,float pivotZ,
+ float axisX,float axisY,float axisZ);
+ virtual void removeConstraint(int constraintid);
+
+
+ virtual PHY_IPhysicsController* rayTest(PHY_IPhysicsController* ignoreClient, float fromX,float fromY,float fromZ, float toX,float toY,float toZ,
+ float& hitX,float& hitY,float& hitZ,float& normalX,float& normalY,float& normalZ);
+
+
+ //Methods for gamelogic collision/physics callbacks
+ //todo:
+ virtual void addSensor(PHY_IPhysicsController* ctrl) {};
+ virtual void removeSensor(PHY_IPhysicsController* ctrl){};
+ virtual void addTouchCallback(int response_class, PHY_ResponseCallback callback, void *user){};
+ virtual void requestCollisionCallback(PHY_IPhysicsController* ctrl){};
+ virtual PHY_IPhysicsController* CreateSphereController(float radius,const PHY__Vector3& position) {return 0;};
+ virtual PHY_IPhysicsController* CreateConeController(float coneradius,float coneheight){ return 0;};
+
+
+ virtual int getNumContactPoints();
+
+ virtual void getContactPoint(int i,float& hitX,float& hitY,float& hitZ,float& normalX,float& normalY,float& normalZ);
+
+ //////////////////////
+ //CcdPhysicsEnvironment interface
+ ////////////////////////
+
+ void addCcdPhysicsController(CcdPhysicsController* ctrl);
+
+ void removeCcdPhysicsController(CcdPhysicsController* ctrl);
+
+ BroadphaseInterface* GetBroadphase() { return m_broadphase; }
+
+ Dispatcher* GetDispatcher();
+
+ int GetNumControllers();
+
+ CcdPhysicsController* GetPhysicsController( int index);
+
+ int GetNumManifolds() const;
+
+ const PersistentManifold* GetManifold(int index) const;
+
+ private:
+
+ void UpdateActivationState();
+ void SyncMotionStates(float timeStep);
+
+ std::vector<CcdPhysicsController*> m_controllers;
+
+ std::vector<Point2PointConstraint*> m_p2pConstraints;
+
+ std::vector<Vehicle*> m_vehicles;
+
+ class ToiContactDispatcher* m_dispatcher;
+
+ bool m_scalingPropagated;
+
+};
+
+#endif //CCDPHYSICSENVIRONMENT
diff --git a/extern/bullet/Extras/PhysicsInterface/CcdPhysics/CcdPhysics_vc7.vcproj b/extern/bullet/Extras/PhysicsInterface/CcdPhysics/CcdPhysics_vc7.vcproj
new file mode 100644
index 00000000000..72f9dca3dd6
--- /dev/null
+++ b/extern/bullet/Extras/PhysicsInterface/CcdPhysics/CcdPhysics_vc7.vcproj
@@ -0,0 +1,131 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="7.10"
+ Name="CcdPhysics"
+ ProjectGUID="{E3D57F36-36AC-4E9A-B0E0-2AE4510FCBFE}"
+ Keyword="Win32Proj">
+ <Platforms>
+ <Platform
+ Name="Win32"/>
+ </Platforms>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="Debug"
+ IntermediateDirectory="Debug"
+ ConfigurationType="4"
+ CharacterSet="2">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="..\Common;..\..\..\LinearMath;..\..\..\Bullet;..\..\..\BulletDynamics"
+ PreprocessorDefinitions="WIN32;_DEBUG;_LIB"
+ MinimalRebuild="TRUE"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="5"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="TRUE"
+ DebugInformationFormat="4"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLibrarianTool"
+ OutputFile="$(OutDir)/CcdPhysics.lib"/>
+ <Tool
+ Name="VCMIDLTool"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release"
+ ConfigurationType="4"
+ CharacterSet="2">
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories="..\Common;..\..\..\LinearMath;..\..\..\Bullet;..\..\..\BulletDynamics"
+ PreprocessorDefinitions="WIN32;NDEBUG;_LIB"
+ RuntimeLibrary="4"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="TRUE"
+ DebugInformationFormat="3"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLibrarianTool"
+ OutputFile="$(OutDir)/CcdPhysics.lib"/>
+ <Tool
+ Name="VCMIDLTool"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
+ <File
+ RelativePath=".\CcdPhysicsController.cpp">
+ </File>
+ <File
+ RelativePath=".\CcdPhysicsEnvironment.cpp">
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
+ <File
+ RelativePath=".\CcdPhysicsController.h">
+ </File>
+ <File
+ RelativePath=".\CcdPhysicsEnvironment.h">
+ </File>
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}">
+ </Filter>
+ <File
+ RelativePath=".\ReadMe.txt">
+ </File>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/extern/bullet/Extras/PhysicsInterface/CcdPhysics/CcdPhysics_vc8.vcproj b/extern/bullet/Extras/PhysicsInterface/CcdPhysics/CcdPhysics_vc8.vcproj
new file mode 100644
index 00000000000..9204aff8adb
--- /dev/null
+++ b/extern/bullet/Extras/PhysicsInterface/CcdPhysics/CcdPhysics_vc8.vcproj
@@ -0,0 +1,185 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="8.00"
+ Name="CcdPhysics"
+ ProjectGUID="{E3D57F36-36AC-4E9A-B0E0-2AE4510FCBFE}"
+ Keyword="Win32Proj"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="Debug"
+ IntermediateDirectory="Debug"
+ ConfigurationType="4"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="..\Common;..\..\..\LinearMath;..\..\..\Bullet;..\..\..\BulletDynamics"
+ PreprocessorDefinitions="WIN32;_DEBUG;_LIB"
+ MinimalRebuild="TRUE"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="1"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="TRUE"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ OutputFile="$(OutDir)/CcdPhysics.lib"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release"
+ ConfigurationType="4"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories="..\Common;..\..\..\LinearMath;..\..\..\Bullet;..\..\..\BulletDynamics"
+ PreprocessorDefinitions="WIN32;NDEBUG;_LIB"
+ RuntimeLibrary="0"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="TRUE"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ OutputFile="$(OutDir)/CcdPhysics.lib"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+ >
+ <File
+ RelativePath=".\CcdPhysicsController.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\CcdPhysicsEnvironment.cpp"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+ >
+ <File
+ RelativePath=".\CcdPhysicsController.h"
+ >
+ </File>
+ <File
+ RelativePath=".\CcdPhysicsEnvironment.h"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+ >
+ </Filter>
+ <File
+ RelativePath=".\ReadMe.txt"
+ >
+ </File>
+ </Files>
+</VisualStudioProject>
diff --git a/extern/bullet/Extras/PhysicsInterface/Common/PHY_DynamicTypes.h b/extern/bullet/Extras/PhysicsInterface/Common/PHY_DynamicTypes.h
new file mode 100644
index 00000000000..d85efa32829
--- /dev/null
+++ b/extern/bullet/Extras/PhysicsInterface/Common/PHY_DynamicTypes.h
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2001-2005 Erwin Coumans <phy@erwincoumans.com>
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Erwin Coumans makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ */
+
+#ifndef __PHY_DYNAMIC_TYPES
+#define __PHY_DYNAMIC_TYPES
+
+
+
+class PHY_ResponseTable;
+
+class PHY_Shape;
+
+struct PHY__Vector3
+{
+ float m_vec[4];
+ operator const float* () const
+ {
+ return &m_vec[0];
+ }
+ operator float* ()
+ {
+ return &m_vec[0];
+ }
+};
+//typedef float PHY__Vector3[4];
+
+typedef enum
+{
+ PHY_FH_RESPONSE,
+ PHY_SENSOR_RESPONSE, /* Touch Sensors */
+ PHY_CAMERA_RESPONSE, /* Visibility Culling */
+ PHY_OBJECT_RESPONSE, /* Object Dynamic Geometry Response */
+ PHY_STATIC_RESPONSE, /* Static Geometry Response */
+
+ PHY_NUM_RESPONSE
+};
+
+ typedef struct PHY_CollData {
+ PHY__Vector3 m_point1; /* Point in object1 in world coordinates */
+ PHY__Vector3 m_point2; /* Point in object2 in world coordinates */
+ PHY__Vector3 m_normal; /* point2 - point1 */
+ } PHY_CollData;
+
+
+ typedef bool (*PHY_ResponseCallback)(void *client_data,
+ void *client_object1,
+ void *client_object2,
+ const PHY_CollData *coll_data);
+
+
+
+/// PHY_PhysicsType enumerates all possible Physics Entities.
+/// It is mainly used to create/add Physics Objects
+
+typedef enum PHY_PhysicsType {
+ PHY_CONVEX_RIGIDBODY=16386,
+ PHY_CONCAVE_RIGIDBODY=16399,
+ PHY_CONVEX_FIXEDBODY=16388,//'collision object'
+ PHY_CONCAVE_FIXEDBODY=16401,
+ PHY_CONVEX_KINEMATICBODY=16387,//
+ PHY_CONCAVE_KINEMATICBODY=16400,
+ PHY_CONVEX_PHANTOMBODY=16398,
+ PHY_CONCAVE_PHANTOMBODY=16402
+} PHY_PhysicsType;
+
+/// PHY_ConstraintType enumerates all supported Constraint Types
+typedef enum PHY_ConstraintType {
+ PHY_POINT2POINT_CONSTRAINT=1,
+ PHY_LINEHINGE_CONSTRAINT,
+ PHY_VEHICLE_CONSTRAINT
+
+} PHY_ConstraintType;
+
+typedef float PHY_Vector3[3];
+
+#endif //__PHY_DYNAMIC_TYPES
+
diff --git a/extern/bullet/Extras/PhysicsInterface/Common/PHY_IMotionState.cpp b/extern/bullet/Extras/PhysicsInterface/Common/PHY_IMotionState.cpp
new file mode 100644
index 00000000000..b8521ffaf87
--- /dev/null
+++ b/extern/bullet/Extras/PhysicsInterface/Common/PHY_IMotionState.cpp
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2001-2005 Erwin Coumans <phy@erwincoumans.com>
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Erwin Coumans makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ */
+
+#include "PHY_IMotionState.h"
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+PHY_IMotionState::~PHY_IMotionState()
+{
+
+}
diff --git a/extern/bullet/Extras/PhysicsInterface/Common/PHY_IMotionState.h b/extern/bullet/Extras/PhysicsInterface/Common/PHY_IMotionState.h
new file mode 100644
index 00000000000..a951ab60d60
--- /dev/null
+++ b/extern/bullet/Extras/PhysicsInterface/Common/PHY_IMotionState.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2001-2005 Erwin Coumans <phy@erwincoumans.com>
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Erwin Coumans makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ */
+
+#ifndef PHY__MOTIONSTATE_H
+#define PHY__MOTIONSTATE_H
+
+/**
+ PHY_IMotionState is the Interface to explicitly synchronize the world transformation.
+ Default implementations for mayor graphics libraries like OpenGL and DirectX can be provided.
+*/
+class PHY_IMotionState
+
+{
+ public:
+
+ virtual ~PHY_IMotionState();
+
+ virtual void getWorldPosition(float& posX,float& posY,float& posZ)=0;
+ virtual void getWorldScaling(float& scaleX,float& scaleY,float& scaleZ)=0;
+ virtual void getWorldOrientation(float& quatIma0,float& quatIma1,float& quatIma2,float& quatReal)=0;
+
+ virtual void setWorldPosition(float posX,float posY,float posZ)=0;
+ virtual void setWorldOrientation(float quatIma0,float quatIma1,float quatIma2,float quatReal)=0;
+
+ virtual void calculateWorldTransformations()=0;
+};
+
+#endif //PHY__MOTIONSTATE_H
+
diff --git a/extern/bullet/Extras/PhysicsInterface/Common/PHY_IPhysicsController.cpp b/extern/bullet/Extras/PhysicsInterface/Common/PHY_IPhysicsController.cpp
new file mode 100644
index 00000000000..b051a45bd13
--- /dev/null
+++ b/extern/bullet/Extras/PhysicsInterface/Common/PHY_IPhysicsController.cpp
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2001-2005 Erwin Coumans <phy@erwincoumans.com>
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Erwin Coumans makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ */
+
+#include "PHY_IPhysicsController.h"
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+PHY_IPhysicsController::~PHY_IPhysicsController()
+{
+
+}
+
diff --git a/extern/bullet/Extras/PhysicsInterface/Common/PHY_IPhysicsController.h b/extern/bullet/Extras/PhysicsInterface/Common/PHY_IPhysicsController.h
new file mode 100644
index 00000000000..4102754be21
--- /dev/null
+++ b/extern/bullet/Extras/PhysicsInterface/Common/PHY_IPhysicsController.h
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2001-2005 Erwin Coumans <phy@erwincoumans.com>
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Erwin Coumans makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ */
+
+#ifndef PHY_IPHYSICSCONTROLLER_H
+#define PHY_IPHYSICSCONTROLLER_H
+
+#include "PHY_DynamicTypes.h"
+
+/**
+ PHY_IPhysicsController is the abstract simplified Interface to a physical object.
+ It contains the IMotionState and IDeformableMesh Interfaces.
+*/
+
+
+class PHY_IPhysicsController
+{
+
+ public:
+
+ virtual ~PHY_IPhysicsController();
+ /**
+ SynchronizeMotionStates ynchronizes dynas, kinematic and deformable entities (and do 'late binding')
+ */
+ virtual bool SynchronizeMotionStates(float time)=0;
+ /**
+ WriteMotionStateToDynamics ynchronizes dynas, kinematic and deformable entities (and do 'late binding')
+ */
+
+ virtual void WriteMotionStateToDynamics(bool nondynaonly)=0;
+ virtual void WriteDynamicsToMotionState()=0;
+ // controller replication
+ virtual void PostProcessReplica(class PHY_IMotionState* motionstate,class PHY_IPhysicsController* parentctrl)=0;
+
+ // kinematic methods
+ virtual void RelativeTranslate(float dlocX,float dlocY,float dlocZ,bool local)=0;
+ virtual void RelativeRotate(const float drot[12],bool local)=0;
+ virtual void getOrientation(float &quatImag0,float &quatImag1,float &quatImag2,float &quatReal)=0;
+ virtual void setOrientation(float quatImag0,float quatImag1,float quatImag2,float quatReal)=0;
+ virtual void setPosition(float posX,float posY,float posZ)=0;
+ virtual void getPosition(PHY__Vector3& pos) const=0;
+ virtual void setScaling(float scaleX,float scaleY,float scaleZ)=0;
+
+ // physics methods
+ virtual void ApplyTorque(float torqueX,float torqueY,float torqueZ,bool local)=0;
+ virtual void ApplyForce(float forceX,float forceY,float forceZ,bool local)=0;
+ virtual void SetAngularVelocity(float ang_velX,float ang_velY,float ang_velZ,bool local)=0;
+ virtual void SetLinearVelocity(float lin_velX,float lin_velY,float lin_velZ,bool local)=0;
+
+ virtual void applyImpulse(float attachX,float attachY,float attachZ, float impulseX,float impulseY,float impulseZ)=0;
+ virtual void SetActive(bool active)=0;
+
+ // reading out information from physics
+ virtual void GetLinearVelocity(float& linvX,float& linvY,float& linvZ)=0;
+ virtual void GetVelocity(const float posX,const float posY,const float posZ,float& linvX,float& linvY,float& linvZ)=0;
+ virtual void getReactionForce(float& forceX,float& forceY,float& forceZ)=0;
+
+ // dyna's that are rigidbody are free in orientation, dyna's with non-rigidbody are restricted
+ virtual void setRigidBody(bool rigid)=0;
+
+
+ // clientinfo for raycasts for example
+ virtual void* getNewClientInfo()=0;
+ virtual void setNewClientInfo(void* clientinfo)=0;
+ virtual PHY_IPhysicsController* GetReplica() {return 0;}
+
+ virtual void calcXform() =0;
+ virtual void SetMargin(float margin) =0;
+ virtual float GetMargin() const=0;
+ virtual float GetRadius() const { return 0.f;}
+ PHY__Vector3 GetWorldPosition(PHY__Vector3& localpos);
+
+};
+
+#endif //PHY_IPHYSICSCONTROLLER_H
+
diff --git a/extern/bullet/Extras/PhysicsInterface/Common/PHY_IPhysicsEnvironment.cpp b/extern/bullet/Extras/PhysicsInterface/Common/PHY_IPhysicsEnvironment.cpp
new file mode 100644
index 00000000000..1794606edf3
--- /dev/null
+++ b/extern/bullet/Extras/PhysicsInterface/Common/PHY_IPhysicsEnvironment.cpp
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2001-2005 Erwin Coumans <phy@erwincoumans.com>
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Erwin Coumans makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ */
+
+#include "PHY_IPhysicsEnvironment.h"
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+/**
+* Physics Environment takes care of stepping the simulation and is a container for physics entities (rigidbodies,constraints, materials etc.)
+* A derived class may be able to 'construct' entities by loading and/or converting
+*/
+
+
+
+PHY_IPhysicsEnvironment::~PHY_IPhysicsEnvironment()
+{
+
+}
diff --git a/extern/bullet/Extras/PhysicsInterface/Common/PHY_IPhysicsEnvironment.h b/extern/bullet/Extras/PhysicsInterface/Common/PHY_IPhysicsEnvironment.h
new file mode 100644
index 00000000000..baa645b40a6
--- /dev/null
+++ b/extern/bullet/Extras/PhysicsInterface/Common/PHY_IPhysicsEnvironment.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2001-2005 Erwin Coumans <phy@erwincoumans.com>
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Erwin Coumans makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ */
+#ifndef _IPHYSICSENVIRONMENT
+#define _IPHYSICSENVIRONMENT
+
+#include <vector>
+#include "PHY_DynamicTypes.h"
+
+/**
+* Physics Environment takes care of stepping the simulation and is a container for physics entities (rigidbodies,constraints, materials etc.)
+* A derived class may be able to 'construct' entities by loading and/or converting
+*/
+class PHY_IPhysicsEnvironment
+{
+ public:
+ virtual ~PHY_IPhysicsEnvironment();
+ /// Perform an integration step of duration 'timeStep'.
+ virtual bool proceedDeltaTime(double curTime,float timeStep)=0;
+
+
+ virtual void setGravity(float x,float y,float z)=0;
+
+ virtual int createConstraint(class PHY_IPhysicsController* ctrl,class PHY_IPhysicsController* ctrl2,PHY_ConstraintType type,
+ float pivotX,float pivotY,float pivotZ,
+ float axisX,float axisY,float axisZ)=0;
+ virtual void removeConstraint(int constraintid)=0;
+
+ virtual PHY_IPhysicsController* rayTest(PHY_IPhysicsController* ignoreClient, float fromX,float fromY,float fromZ, float toX,float toY,float toZ,
+ float& hitX,float& hitY,float& hitZ,float& normalX,float& normalY,float& normalZ)=0;
+
+
+ //Methods for gamelogic collision/physics callbacks
+ //todo:
+ virtual void addSensor(PHY_IPhysicsController* ctrl)=0;
+ virtual void removeSensor(PHY_IPhysicsController* ctrl)=0;
+ virtual void addTouchCallback(int response_class, PHY_ResponseCallback callback, void *user)=0;
+ virtual void requestCollisionCallback(PHY_IPhysicsController* ctrl)=0;
+ virtual PHY_IPhysicsController* CreateSphereController(float radius,const PHY__Vector3& position) =0;
+ virtual PHY_IPhysicsController* CreateConeController(float coneradius,float coneheight)=0;
+
+};
+
+#endif //_IPHYSICSENVIRONMENT
+
diff --git a/extern/bullet/Extras/PhysicsInterface/Common/PHY_Pro.h b/extern/bullet/Extras/PhysicsInterface/Common/PHY_Pro.h
new file mode 100644
index 00000000000..871cc64d375
--- /dev/null
+++ b/extern/bullet/Extras/PhysicsInterface/Common/PHY_Pro.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2001-2005 Erwin Coumans <phy@erwincoumans.com>
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Erwin Coumans makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ */
+
+#ifndef PHY_PROPSH
+#define PHY_PROPSH
+
+
+class CollisionShape;
+
+// Properties of dynamic objects
+struct PHY_ShapeProps {
+ float m_mass; // Total mass
+ float m_inertia; // Inertia, should be a tensor some time
+ float m_lin_drag; // Linear drag (air, water) 0 = concrete, 1 = vacuum
+ float m_ang_drag; // Angular drag
+ float m_friction_scaling[3]; // Scaling for anisotropic friction. Component in range [0, 1]
+ bool m_do_anisotropic; // Should I do anisotropic friction?
+ bool m_do_fh; // Should the object have a linear Fh spring?
+ bool m_do_rot_fh; // Should the object have an angular Fh spring?
+ CollisionShape* m_shape;
+};
+
+
+// Properties of collidable objects (non-ghost objects)
+struct PHY_MaterialProps {
+ float m_restitution; // restitution of energie after a collision 0 = inelastic, 1 = elastic
+ float m_friction; // Coulomb friction (= ratio between the normal en maximum friction force)
+ float m_fh_spring; // Spring constant (both linear and angular)
+ float m_fh_damping; // Damping factor (linear and angular) in range [0, 1]
+ float m_fh_distance; // The range above the surface where Fh is active.
+ bool m_fh_normal; // Should the object slide off slopes?
+};
+
+#endif //PHY_PROPSH
+
diff --git a/extern/bullet/Extras/PhysicsInterface/Common/PhysicsInterface.dsp b/extern/bullet/Extras/PhysicsInterface/Common/PhysicsInterface.dsp
new file mode 100644
index 00000000000..7617570f4a7
--- /dev/null
+++ b/extern/bullet/Extras/PhysicsInterface/Common/PhysicsInterface.dsp
@@ -0,0 +1,128 @@
+# Microsoft Developer Studio Project File - Name="PhysicsInterface" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Static Library" 0x0104
+
+CFG=PhysicsInterface - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "PhysicsInterface.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "PhysicsInterface.mak" CFG="PhysicsInterface - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "PhysicsInterface - Win32 Release" (based on "Win32 (x86) Static Library")
+!MESSAGE "PhysicsInterface - Win32 Debug" (based on "Win32 (x86) Static Library")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "PhysicsInterface - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Target_Dir ""
+LINK32=link.exe -lib
+MTL=midl.exe
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
+# ADD CPP /nologo /W3 /GX /O2 /I "..\..\..\LinearMath" /I "..\..\..\Extras\PhysicsInterface\Common" /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
+# ADD BASE RSC /l 0x809 /d "NDEBUG"
+# ADD RSC /l 0x809 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LIB32=link.exe -lib
+# ADD BASE LIB32 /nologo
+# ADD LIB32 /nologo
+
+!ELSEIF "$(CFG)" == "PhysicsInterface - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Target_Dir ""
+LINK32=link.exe -lib
+MTL=midl.exe
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
+# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "..\..\..\LinearMath" /I "..\..\..\Extras\PhysicsInterface\Common" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
+# ADD BASE RSC /l 0x809 /d "_DEBUG"
+# ADD RSC /l 0x809 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LIB32=link.exe -lib
+# ADD BASE LIB32 /nologo
+# ADD LIB32 /nologo
+
+!ENDIF
+
+# Begin Target
+
+# Name "PhysicsInterface - Win32 Release"
+# Name "PhysicsInterface - Win32 Debug"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=.\PHY_IMotionState.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\PHY_IPhysicsController.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\PHY_IPhysicsEnvironment.cpp
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# Begin Source File
+
+SOURCE=.\PHY_DynamicTypes.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\PHY_IMotionState.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\PHY_IPhysicsController.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\PHY_IPhysicsEnvironment.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\PHY_Pro.h
+# End Source File
+# End Group
+# End Target
+# End Project
diff --git a/extern/bullet/Extras/PhysicsInterface/Common/PhysicsInterfaceCommon/PhysicsInterfaceCommon_vc7.vcproj b/extern/bullet/Extras/PhysicsInterface/Common/PhysicsInterfaceCommon/PhysicsInterfaceCommon_vc7.vcproj
new file mode 100644
index 00000000000..a5c82f8774f
--- /dev/null
+++ b/extern/bullet/Extras/PhysicsInterface/Common/PhysicsInterfaceCommon/PhysicsInterfaceCommon_vc7.vcproj
@@ -0,0 +1,143 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="7.10"
+ Name="PhysicsInterfaceCommon"
+ ProjectGUID="{87D8C006-6DCC-4156-A03E-8CEA1B4C0580}"
+ Keyword="Win32Proj">
+ <Platforms>
+ <Platform
+ Name="Win32"/>
+ </Platforms>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="Debug"
+ IntermediateDirectory="Debug"
+ ConfigurationType="4"
+ CharacterSet="2">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="..\..\..\..\LinearMath"
+ PreprocessorDefinitions="WIN32;_DEBUG;_LIB"
+ MinimalRebuild="TRUE"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="5"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="TRUE"
+ DebugInformationFormat="4"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLibrarianTool"
+ OutputFile="$(OutDir)/PhysicsInterfaceCommon.lib"/>
+ <Tool
+ Name="VCMIDLTool"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release"
+ ConfigurationType="4"
+ CharacterSet="2">
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories="..\..\..\..\LinearMath"
+ PreprocessorDefinitions="WIN32;NDEBUG;_LIB"
+ RuntimeLibrary="4"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="TRUE"
+ DebugInformationFormat="3"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLibrarianTool"
+ OutputFile="$(OutDir)/PhysicsInterfaceCommon.lib"/>
+ <Tool
+ Name="VCMIDLTool"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
+ <File
+ RelativePath="..\PHY_IMotionState.cpp">
+ </File>
+ <File
+ RelativePath="..\PHY_IPhysicsController.cpp">
+ </File>
+ <File
+ RelativePath="..\PHY_IPhysicsEnvironment.cpp">
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
+ <File
+ RelativePath="..\PHY_DynamicTypes.h">
+ </File>
+ <File
+ RelativePath="..\PHY_IMotionState.h">
+ </File>
+ <File
+ RelativePath="..\PHY_IPhysicsController.h">
+ </File>
+ <File
+ RelativePath="..\PHY_IPhysicsEnvironment.h">
+ </File>
+ <File
+ RelativePath="..\PHY_Pro.h">
+ </File>
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}">
+ </Filter>
+ <File
+ RelativePath=".\ReadMe.txt">
+ </File>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/extern/bullet/Extras/PhysicsInterface/Common/PhysicsInterfaceCommon/PhysicsInterfaceCommon_vc8.vcproj b/extern/bullet/Extras/PhysicsInterface/Common/PhysicsInterfaceCommon/PhysicsInterfaceCommon_vc8.vcproj
new file mode 100644
index 00000000000..4df99f6db2c
--- /dev/null
+++ b/extern/bullet/Extras/PhysicsInterface/Common/PhysicsInterfaceCommon/PhysicsInterfaceCommon_vc8.vcproj
@@ -0,0 +1,201 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="8.00"
+ Name="PhysicsInterfaceCommon"
+ ProjectGUID="{87D8C006-6DCC-4156-A03E-8CEA1B4C0580}"
+ Keyword="Win32Proj"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="Debug"
+ IntermediateDirectory="Debug"
+ ConfigurationType="4"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="..\..\..\..\LinearMath"
+ PreprocessorDefinitions="WIN32;_DEBUG;_LIB"
+ MinimalRebuild="TRUE"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="1"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="TRUE"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ OutputFile="$(OutDir)/PhysicsInterfaceCommon.lib"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release"
+ ConfigurationType="4"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories="..\..\..\..\LinearMath"
+ PreprocessorDefinitions="WIN32;NDEBUG;_LIB"
+ RuntimeLibrary="0"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="TRUE"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ OutputFile="$(OutDir)/PhysicsInterfaceCommon.lib"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+ >
+ <File
+ RelativePath="..\PHY_IMotionState.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\PHY_IPhysicsController.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\PHY_IPhysicsEnvironment.cpp"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+ >
+ <File
+ RelativePath="..\PHY_DynamicTypes.h"
+ >
+ </File>
+ <File
+ RelativePath="..\PHY_IMotionState.h"
+ >
+ </File>
+ <File
+ RelativePath="..\PHY_IPhysicsController.h"
+ >
+ </File>
+ <File
+ RelativePath="..\PHY_IPhysicsEnvironment.h"
+ >
+ </File>
+ <File
+ RelativePath="..\PHY_Pro.h"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+ >
+ </Filter>
+ <File
+ RelativePath=".\ReadMe.txt"
+ >
+ </File>
+ </Files>
+</VisualStudioProject>
diff --git a/extern/bullet/LinearMath/AabbUtil2.h b/extern/bullet/LinearMath/AabbUtil2.h
new file mode 100644
index 00000000000..5b00f3bb25b
--- /dev/null
+++ b/extern/bullet/LinearMath/AabbUtil2.h
@@ -0,0 +1,67 @@
+/*
+
+Copyright (c) 2005 Gino van den Bergen / Erwin Coumans <www.erwincoumans.com>
+
+Permission is hereby granted, free of charge, to any person or organization
+obtaining a copy of the software and accompanying documentation covered by
+this license (the "Software") to use, reproduce, display, distribute,
+execute, and transmit the Software, and to prepare derivative works of the
+Software, and to permit third-parties to whom the Software is furnished to
+do so, all subject to the following:
+
+The copyright notices in the Software and this entire statement, including
+the above license grant, this restriction and the following disclaimer,
+must be included in all copies of the Software, in whole or in part, and
+all derivative works of the Software, unless such copies or derivative
+works are solely in the form of machine-executable object code generated by
+a source language processor.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+
+#ifndef AABB_UTIL2
+#define AABB_UTIL2
+
+#include "SimdVector3.h"
+
+#define SimdMin(a,b) ((a < b ? a : b))
+#define SimdMax(a,b) ((a > b ? a : b))
+
+
+/// conservative test for overlap between two aabbs
+SIMD_FORCE_INLINE bool TestAabbAgainstAabb2(const SimdVector3 &aabbMin1, const SimdVector3 &aabbMax1,
+ const SimdVector3 &aabbMin2, const SimdVector3 &aabbMax2)
+{
+ if (aabbMin1[0] > aabbMax2[0] || aabbMax1[0] < aabbMin2[0]) return false;
+ if (aabbMin1[2] > aabbMax2[2] || aabbMax1[2] < aabbMin2[2]) return false;
+ if (aabbMin1[1] > aabbMax2[1] || aabbMax1[1] < aabbMin2[1]) return false;
+ return true;
+}
+
+/// conservative test for overlap between triangle and aabb
+SIMD_FORCE_INLINE bool TestTriangleAgainstAabb2(const SimdVector3 *vertices,
+ const SimdVector3 &aabbMin, const SimdVector3 &aabbMax)
+{
+ const SimdVector3 &p1 = vertices[0];
+ const SimdVector3 &p2 = vertices[1];
+ const SimdVector3 &p3 = vertices[2];
+
+ if (SimdMin(SimdMin(p1[0], p2[0]), p3[0]) > aabbMax[0]) return false;
+ if (SimdMax(SimdMax(p1[0], p2[0]), p3[0]) < aabbMin[0]) return false;
+
+ if (SimdMin(SimdMin(p1[2], p2[2]), p3[2]) > aabbMax[2]) return false;
+ if (SimdMax(SimdMax(p1[2], p2[2]), p3[2]) < aabbMin[2]) return false;
+
+ if (SimdMin(SimdMin(p1[1], p2[1]), p3[1]) > aabbMax[1]) return false;
+ if (SimdMax(SimdMax(p1[1], p2[1]), p3[1]) < aabbMin[1]) return false;
+ return true;
+}
+
+#endif \ No newline at end of file
diff --git a/extern/bullet/LinearMath/GEN_List.h b/extern/bullet/LinearMath/GEN_List.h
new file mode 100644
index 00000000000..bbcf987b462
--- /dev/null
+++ b/extern/bullet/LinearMath/GEN_List.h
@@ -0,0 +1,85 @@
+/*
+
+Copyright (c) 2005 Gino van den Bergen / Erwin Coumans <www.erwincoumans.com>
+
+Permission is hereby granted, free of charge, to any person or organization
+obtaining a copy of the software and accompanying documentation covered by
+this license (the "Software") to use, reproduce, display, distribute,
+execute, and transmit the Software, and to prepare derivative works of the
+Software, and to permit third-parties to whom the Software is furnished to
+do so, all subject to the following:
+
+The copyright notices in the Software and this entire statement, including
+the above license grant, this restriction and the following disclaimer,
+must be included in all copies of the Software, in whole or in part, and
+all derivative works of the Software, unless such copies or derivative
+works are solely in the form of machine-executable object code generated by
+a source language processor.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+
+#ifndef GEN_LIST_H
+#define GEN_LIST_H
+
+class GEN_Link {
+public:
+ GEN_Link() : m_next(0), m_prev(0) {}
+ GEN_Link(GEN_Link *next, GEN_Link *prev) : m_next(next), m_prev(prev) {}
+
+ GEN_Link *getNext() const { return m_next; }
+ GEN_Link *getPrev() const { return m_prev; }
+
+ bool isHead() const { return m_prev == 0; }
+ bool isTail() const { return m_next == 0; }
+
+ void insertBefore(GEN_Link *link) {
+ m_next = link;
+ m_prev = link->m_prev;
+ m_next->m_prev = this;
+ m_prev->m_next = this;
+ }
+
+ void insertAfter(GEN_Link *link) {
+ m_next = link->m_next;
+ m_prev = link;
+ m_next->m_prev = this;
+ m_prev->m_next = this;
+ }
+
+ void remove() {
+ m_next->m_prev = m_prev;
+ m_prev->m_next = m_next;
+ }
+
+private:
+ GEN_Link *m_next;
+ GEN_Link *m_prev;
+};
+
+class GEN_List {
+public:
+ GEN_List() : m_head(&m_tail, 0), m_tail(0, &m_head) {}
+
+ GEN_Link *getHead() const { return m_head.getNext(); }
+ GEN_Link *getTail() const { return m_tail.getPrev(); }
+
+ void addHead(GEN_Link *link) { link->insertAfter(&m_head); }
+ void addTail(GEN_Link *link) { link->insertBefore(&m_tail); }
+
+private:
+ GEN_Link m_head;
+ GEN_Link m_tail;
+};
+
+#endif
+
+
+
diff --git a/extern/bullet/LinearMath/GEN_MinMax.h b/extern/bullet/LinearMath/GEN_MinMax.h
new file mode 100644
index 00000000000..c3ab24390f7
--- /dev/null
+++ b/extern/bullet/LinearMath/GEN_MinMax.h
@@ -0,0 +1,81 @@
+/*
+
+Copyright (c) 2005 Gino van den Bergen / Erwin Coumans <www.erwincoumans.com>
+
+Permission is hereby granted, free of charge, to any person or organization
+obtaining a copy of the software and accompanying documentation covered by
+this license (the "Software") to use, reproduce, display, distribute,
+execute, and transmit the Software, and to prepare derivative works of the
+Software, and to permit third-parties to whom the Software is furnished to
+do so, all subject to the following:
+
+The copyright notices in the Software and this entire statement, including
+the above license grant, this restriction and the following disclaimer,
+must be included in all copies of the Software, in whole or in part, and
+all derivative works of the Software, unless such copies or derivative
+works are solely in the form of machine-executable object code generated by
+a source language processor.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+
+#ifndef GEN_MINMAX_H
+#define GEN_MINMAX_H
+
+template <class T>
+SIMD_FORCE_INLINE const T& GEN_min(const T& a, const T& b)
+{
+ return b < a ? b : a;
+}
+
+template <class T>
+SIMD_FORCE_INLINE const T& GEN_max(const T& a, const T& b)
+{
+ return a < b ? b : a;
+}
+
+template <class T>
+SIMD_FORCE_INLINE const T& GEN_clamped(const T& a, const T& lb, const T& ub)
+{
+ return a < lb ? lb : (ub < a ? ub : a);
+}
+
+template <class T>
+SIMD_FORCE_INLINE void GEN_set_min(T& a, const T& b)
+{
+ if (b < a)
+ {
+ a = b;
+ }
+}
+
+template <class T>
+SIMD_FORCE_INLINE void GEN_set_max(T& a, const T& b)
+{
+ if (a < b)
+ {
+ a = b;
+ }
+}
+
+template <class T>
+SIMD_FORCE_INLINE void GEN_clamp(T& a, const T& lb, const T& ub)
+{
+ if (a < lb)
+ {
+ a = lb;
+ }
+ else if (ub < a)
+ {
+ a = ub;
+ }
+}
+
+#endif
diff --git a/extern/bullet/LinearMath/GEN_random.h b/extern/bullet/LinearMath/GEN_random.h
new file mode 100644
index 00000000000..22c77d827a2
--- /dev/null
+++ b/extern/bullet/LinearMath/GEN_random.h
@@ -0,0 +1,54 @@
+/*
+
+Copyright (c) 2005 Gino van den Bergen / Erwin Coumans <www.erwincoumans.com>
+
+Permission is hereby granted, free of charge, to any person or organization
+obtaining a copy of the software and accompanying documentation covered by
+this license (the "Software") to use, reproduce, display, distribute,
+execute, and transmit the Software, and to prepare derivative works of the
+Software, and to permit third-parties to whom the Software is furnished to
+do so, all subject to the following:
+
+The copyright notices in the Software and this entire statement, including
+the above license grant, this restriction and the following disclaimer,
+must be included in all copies of the Software, in whole or in part, and
+all derivative works of the Software, unless such copies or derivative
+works are solely in the form of machine-executable object code generated by
+a source language processor.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+
+#ifndef GEN_RANDOM_H
+#define GEN_RANDOM_H
+
+#ifdef MT19937
+
+#include <limits.h>
+#include <mt19937.h>
+
+#define GEN_RAND_MAX UINT_MAX
+
+SIMD_FORCE_INLINE void GEN_srand(unsigned int seed) { init_genrand(seed); }
+SIMD_FORCE_INLINE unsigned int GEN_rand() { return genrand_int32(); }
+
+#else
+
+#include <stdlib.h>
+
+#define GEN_RAND_MAX RAND_MAX
+
+SIMD_FORCE_INLINE void GEN_srand(unsigned int seed) { srand(seed); }
+SIMD_FORCE_INLINE unsigned int GEN_rand() { return rand(); }
+
+#endif
+
+#endif
+
diff --git a/extern/bullet/LinearMath/SimdMatrix3x3.h b/extern/bullet/LinearMath/SimdMatrix3x3.h
new file mode 100644
index 00000000000..850e2f37dea
--- /dev/null
+++ b/extern/bullet/LinearMath/SimdMatrix3x3.h
@@ -0,0 +1,407 @@
+/*
+
+Copyright (c) 2005 Gino van den Bergen / Erwin Coumans <www.erwincoumans.com>
+
+Permission is hereby granted, free of charge, to any person or organization
+obtaining a copy of the software and accompanying documentation covered by
+this license (the "Software") to use, reproduce, display, distribute,
+execute, and transmit the Software, and to prepare derivative works of the
+Software, and to permit third-parties to whom the Software is furnished to
+do so, all subject to the following:
+
+The copyright notices in the Software and this entire statement, including
+the above license grant, this restriction and the following disclaimer,
+must be included in all copies of the Software, in whole or in part, and
+all derivative works of the Software, unless such copies or derivative
+works are solely in the form of machine-executable object code generated by
+a source language processor.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+#ifndef SimdMatrix3x3_H
+#define SimdMatrix3x3_H
+
+#include "SimdScalar.h"
+
+#include "SimdVector3.h"
+#include "SimdQuaternion.h"
+
+
+class SimdMatrix3x3 {
+ public:
+ SimdMatrix3x3 () {}
+
+// explicit SimdMatrix3x3(const SimdScalar *m) { setFromOpenGLSubMatrix(m); }
+
+ explicit SimdMatrix3x3(const SimdQuaternion& q) { setRotation(q); }
+ /*
+ template <typename SimdScalar>
+ Matrix3x3(const SimdScalar& yaw, const SimdScalar& pitch, const SimdScalar& roll)
+ {
+ setEulerYPR(yaw, pitch, roll);
+ }
+ */
+ SimdMatrix3x3(const SimdScalar& xx, const SimdScalar& xy, const SimdScalar& xz,
+ const SimdScalar& yx, const SimdScalar& yy, const SimdScalar& yz,
+ const SimdScalar& zx, const SimdScalar& zy, const SimdScalar& zz)
+ {
+ setValue(xx, xy, xz,
+ yx, yy, yz,
+ zx, zy, zz);
+ }
+
+ SimdVector3 getColumn(int i) const
+ {
+ return SimdVector3(m_el[0][i],m_el[1][i],m_el[2][i]);
+ }
+
+ const SimdVector3& getRow(int i) const
+ {
+ return m_el[i];
+ }
+
+
+ SIMD_FORCE_INLINE SimdVector3& operator[](int i)
+ {
+ assert(0 <= i && i < 3);
+ return m_el[i];
+ }
+
+ const SimdVector3& operator[](int i) const
+ {
+ assert(0 <= i && i < 3);
+ return m_el[i];
+ }
+
+ SimdMatrix3x3& operator*=(const SimdMatrix3x3& m);
+
+
+ void setFromOpenGLSubMatrix(const SimdScalar *m)
+ {
+ m_el[0][0] = (m[0]);
+ m_el[1][0] = (m[1]);
+ m_el[2][0] = (m[2]);
+ m_el[0][1] = (m[4]);
+ m_el[1][1] = (m[5]);
+ m_el[2][1] = (m[6]);
+ m_el[0][2] = (m[8]);
+ m_el[1][2] = (m[9]);
+ m_el[2][2] = (m[10]);
+ }
+
+ void setValue(const SimdScalar& xx, const SimdScalar& xy, const SimdScalar& xz,
+ const SimdScalar& yx, const SimdScalar& yy, const SimdScalar& yz,
+ const SimdScalar& zx, const SimdScalar& zy, const SimdScalar& zz)
+ {
+ m_el[0][0] = SimdScalar(xx);
+ m_el[0][1] = SimdScalar(xy);
+ m_el[0][2] = SimdScalar(xz);
+ m_el[1][0] = SimdScalar(yx);
+ m_el[1][1] = SimdScalar(yy);
+ m_el[1][2] = SimdScalar(yz);
+ m_el[2][0] = SimdScalar(zx);
+ m_el[2][1] = SimdScalar(zy);
+ m_el[2][2] = SimdScalar(zz);
+ }
+
+ void setRotation(const SimdQuaternion& q)
+ {
+ SimdScalar d = q.length2();
+ assert(d != SimdScalar(0.0));
+ SimdScalar s = SimdScalar(2.0) / d;
+ SimdScalar xs = q[0] * s, ys = q[1] * s, zs = q[2] * s;
+ SimdScalar wx = q[3] * xs, wy = q[3] * ys, wz = q[3] * zs;
+ SimdScalar xx = q[0] * xs, xy = q[0] * ys, xz = q[0] * zs;
+ SimdScalar yy = q[1] * ys, yz = q[1] * zs, zz = q[2] * zs;
+ setValue(SimdScalar(1.0) - (yy + zz), xy - wz, xz + wy,
+ xy + wz, SimdScalar(1.0) - (xx + zz), yz - wx,
+ xz - wy, yz + wx, SimdScalar(1.0) - (xx + yy));
+ }
+
+
+
+ void setEulerYPR(const SimdScalar& yaw, const SimdScalar& pitch, const SimdScalar& roll)
+ {
+
+ SimdScalar cy(cosf(yaw));
+ SimdScalar sy(sinf(yaw));
+ SimdScalar cp(cosf(pitch));
+ SimdScalar sp(sinf(pitch));
+ SimdScalar cr(cosf(roll));
+ SimdScalar sr(sinf(roll));
+ SimdScalar cc = cy * cr;
+ SimdScalar cs = cy * sr;
+ SimdScalar sc = sy * cr;
+ SimdScalar ss = sy * sr;
+ setValue(cc - sp * ss, -cs - sp * sc, -sy * cp,
+ cp * sr, cp * cr, -sp,
+ sc + sp * cs, -ss + sp * cc, cy * cp);
+
+ }
+
+ /**
+ * setEulerZYX
+ * @param euler a const reference to a SimdVector3 of euler angles
+ * These angles are used to produce a rotation matrix. The euler
+ * angles are applied in ZYX order. I.e a vector is first rotated
+ * about X then Y and then Z
+ **/
+
+ void setEulerZYX(SimdScalar eulerX,SimdScalar eulerY,SimdScalar eulerZ) {
+ SimdScalar ci ( cosf(eulerX));
+ SimdScalar cj ( cosf(eulerY));
+ SimdScalar ch ( cosf(eulerZ));
+ SimdScalar si ( sinf(eulerX));
+ SimdScalar sj ( sinf(eulerY));
+ SimdScalar sh ( sinf(eulerZ));
+ SimdScalar cc = ci * ch;
+ SimdScalar cs = ci * sh;
+ SimdScalar sc = si * ch;
+ SimdScalar ss = si * sh;
+
+ setValue(cj * ch, sj * sc - cs, sj * cc + ss,
+ cj * sh, sj * ss + cc, sj * cs - sc,
+ -sj, cj * si, cj * ci);
+ }
+
+ void setIdentity()
+ {
+ setValue(SimdScalar(1.0), SimdScalar(0.0), SimdScalar(0.0),
+ SimdScalar(0.0), SimdScalar(1.0), SimdScalar(0.0),
+ SimdScalar(0.0), SimdScalar(0.0), SimdScalar(1.0));
+ }
+
+ void getOpenGLSubMatrix(SimdScalar *m) const
+ {
+ m[0] = SimdScalar(m_el[0][0]);
+ m[1] = SimdScalar(m_el[1][0]);
+ m[2] = SimdScalar(m_el[2][0]);
+ m[3] = SimdScalar(0.0);
+ m[4] = SimdScalar(m_el[0][1]);
+ m[5] = SimdScalar(m_el[1][1]);
+ m[6] = SimdScalar(m_el[2][1]);
+ m[7] = SimdScalar(0.0);
+ m[8] = SimdScalar(m_el[0][2]);
+ m[9] = SimdScalar(m_el[1][2]);
+ m[10] = SimdScalar(m_el[2][2]);
+ m[11] = SimdScalar(0.0);
+ }
+
+ void getRotation(SimdQuaternion& q) const
+ {
+ SimdScalar trace = m_el[0][0] + m_el[1][1] + m_el[2][2];
+
+ if (trace > SimdScalar(0.0))
+ {
+ SimdScalar s = sqrtf(trace + SimdScalar(1.0));
+ q[3] = s * SimdScalar(0.5);
+ s = SimdScalar(0.5) / s;
+
+ q[0] = (m_el[2][1] - m_el[1][2]) * s;
+ q[1] = (m_el[0][2] - m_el[2][0]) * s;
+ q[2] = (m_el[1][0] - m_el[0][1]) * s;
+ }
+ else
+ {
+ int i = m_el[0][0] < m_el[1][1] ?
+ (m_el[1][1] < m_el[2][2] ? 2 : 1) :
+ (m_el[0][0] < m_el[2][2] ? 2 : 0);
+ int j = (i + 1) % 3;
+ int k = (i + 2) % 3;
+
+ SimdScalar s = sqrtf(m_el[i][i] - m_el[j][j] - m_el[k][k] + SimdScalar(1.0));
+ q[i] = s * SimdScalar(0.5);
+ s = SimdScalar(0.5) / s;
+
+ q[3] = (m_el[k][j] - m_el[j][k]) * s;
+ q[j] = (m_el[j][i] + m_el[i][j]) * s;
+ q[k] = (m_el[k][i] + m_el[i][k]) * s;
+ }
+ }
+
+
+
+ void getEuler(SimdScalar& yaw, SimdScalar& pitch, SimdScalar& roll) const
+ {
+ pitch = SimdScalar(asinf(-m_el[2][0]));
+ if (pitch < SIMD_2_PI)
+ {
+ if (pitch > SIMD_2_PI)
+ {
+ yaw = SimdScalar(atan2f(m_el[1][0], m_el[0][0]));
+ roll = SimdScalar(atan2f(m_el[2][1], m_el[2][2]));
+ }
+ else
+ {
+ yaw = SimdScalar(-atan2f(-m_el[0][1], m_el[0][2]));
+ roll = SimdScalar(0.0);
+ }
+ }
+ else
+ {
+ yaw = SimdScalar(atan2f(-m_el[0][1], m_el[0][2]));
+ roll = SimdScalar(0.0);
+ }
+ }
+
+ SimdVector3 getScaling() const
+ {
+ return SimdVector3(m_el[0][0] * m_el[0][0] + m_el[1][0] * m_el[1][0] + m_el[2][0] * m_el[2][0],
+ m_el[0][1] * m_el[0][1] + m_el[1][1] * m_el[1][1] + m_el[2][1] * m_el[2][1],
+ m_el[0][2] * m_el[0][2] + m_el[1][2] * m_el[1][2] + m_el[2][2] * m_el[2][2]);
+ }
+
+
+ SimdMatrix3x3 scaled(const SimdVector3& s) const
+ {
+ return SimdMatrix3x3(m_el[0][0] * s[0], m_el[0][1] * s[1], m_el[0][2] * s[2],
+ m_el[1][0] * s[0], m_el[1][1] * s[1], m_el[1][2] * s[2],
+ m_el[2][0] * s[0], m_el[2][1] * s[1], m_el[2][2] * s[2]);
+ }
+
+ SimdScalar determinant() const;
+ SimdMatrix3x3 adjoint() const;
+ SimdMatrix3x3 absolute() const;
+ SimdMatrix3x3 transpose() const;
+ SimdMatrix3x3 inverse() const;
+
+ SimdMatrix3x3 transposeTimes(const SimdMatrix3x3& m) const;
+ SimdMatrix3x3 timesTranspose(const SimdMatrix3x3& m) const;
+
+ SimdScalar tdot(int c, const SimdVector3& v) const
+ {
+ return m_el[0][c] * v[0] + m_el[1][c] * v[1] + m_el[2][c] * v[2];
+ }
+
+ protected:
+ SimdScalar cofac(int r1, int c1, int r2, int c2) const
+ {
+ return m_el[r1][c1] * m_el[r2][c2] - m_el[r1][c2] * m_el[r2][c1];
+ }
+
+ SimdVector3 m_el[3];
+ };
+
+ SIMD_FORCE_INLINE SimdMatrix3x3&
+ SimdMatrix3x3::operator*=(const SimdMatrix3x3& m)
+ {
+ setValue(m.tdot(0, m_el[0]), m.tdot(1, m_el[0]), m.tdot(2, m_el[0]),
+ m.tdot(0, m_el[1]), m.tdot(1, m_el[1]), m.tdot(2, m_el[1]),
+ m.tdot(0, m_el[2]), m.tdot(1, m_el[2]), m.tdot(2, m_el[2]));
+ return *this;
+ }
+
+ SIMD_FORCE_INLINE SimdScalar
+ SimdMatrix3x3::determinant() const
+ {
+ return triple((*this)[0], (*this)[1], (*this)[2]);
+ }
+
+
+ SIMD_FORCE_INLINE SimdMatrix3x3
+ SimdMatrix3x3::absolute() const
+ {
+ return SimdMatrix3x3(
+ fabsf(m_el[0][0]), fabsf(m_el[0][1]), fabsf(m_el[0][2]),
+ fabsf(m_el[1][0]), fabsf(m_el[1][1]), fabsf(m_el[1][2]),
+ fabsf(m_el[2][0]), fabsf(m_el[2][1]), fabsf(m_el[2][2]));
+ }
+
+ SIMD_FORCE_INLINE SimdMatrix3x3
+ SimdMatrix3x3::transpose() const
+ {
+ return SimdMatrix3x3(m_el[0][0], m_el[1][0], m_el[2][0],
+ m_el[0][1], m_el[1][1], m_el[2][1],
+ m_el[0][2], m_el[1][2], m_el[2][2]);
+ }
+
+ SIMD_FORCE_INLINE SimdMatrix3x3
+ SimdMatrix3x3::adjoint() const
+ {
+ return SimdMatrix3x3(cofac(1, 1, 2, 2), cofac(0, 2, 2, 1), cofac(0, 1, 1, 2),
+ cofac(1, 2, 2, 0), cofac(0, 0, 2, 2), cofac(0, 2, 1, 0),
+ cofac(1, 0, 2, 1), cofac(0, 1, 2, 0), cofac(0, 0, 1, 1));
+ }
+
+ SIMD_FORCE_INLINE SimdMatrix3x3
+ SimdMatrix3x3::inverse() const
+ {
+ SimdVector3 co(cofac(1, 1, 2, 2), cofac(1, 2, 2, 0), cofac(1, 0, 2, 1));
+ SimdScalar det = (*this)[0].dot(co);
+ assert(det != SimdScalar(0.0f));
+ SimdScalar s = SimdScalar(1.0f) / det;
+ return SimdMatrix3x3(co[0] * s, cofac(0, 2, 2, 1) * s, cofac(0, 1, 1, 2) * s,
+ co[1] * s, cofac(0, 0, 2, 2) * s, cofac(0, 2, 1, 0) * s,
+ co[2] * s, cofac(0, 1, 2, 0) * s, cofac(0, 0, 1, 1) * s);
+ }
+
+ SIMD_FORCE_INLINE SimdMatrix3x3
+ SimdMatrix3x3::transposeTimes(const SimdMatrix3x3& m) const
+ {
+ return SimdMatrix3x3(
+ m_el[0][0] * m[0][0] + m_el[1][0] * m[1][0] + m_el[2][0] * m[2][0],
+ m_el[0][0] * m[0][1] + m_el[1][0] * m[1][1] + m_el[2][0] * m[2][1],
+ m_el[0][0] * m[0][2] + m_el[1][0] * m[1][2] + m_el[2][0] * m[2][2],
+ m_el[0][1] * m[0][0] + m_el[1][1] * m[1][0] + m_el[2][1] * m[2][0],
+ m_el[0][1] * m[0][1] + m_el[1][1] * m[1][1] + m_el[2][1] * m[2][1],
+ m_el[0][1] * m[0][2] + m_el[1][1] * m[1][2] + m_el[2][1] * m[2][2],
+ m_el[0][2] * m[0][0] + m_el[1][2] * m[1][0] + m_el[2][2] * m[2][0],
+ m_el[0][2] * m[0][1] + m_el[1][2] * m[1][1] + m_el[2][2] * m[2][1],
+ m_el[0][2] * m[0][2] + m_el[1][2] * m[1][2] + m_el[2][2] * m[2][2]);
+ }
+
+ SIMD_FORCE_INLINE SimdMatrix3x3
+ SimdMatrix3x3::timesTranspose(const SimdMatrix3x3& m) const
+ {
+ return SimdMatrix3x3(
+ m_el[0].dot(m[0]), m_el[0].dot(m[1]), m_el[0].dot(m[2]),
+ m_el[1].dot(m[0]), m_el[1].dot(m[1]), m_el[1].dot(m[2]),
+ m_el[2].dot(m[0]), m_el[2].dot(m[1]), m_el[2].dot(m[2]));
+
+ }
+
+ SIMD_FORCE_INLINE SimdVector3
+ operator*(const SimdMatrix3x3& m, const SimdVector3& v)
+ {
+ return SimdVector3(m[0].dot(v), m[1].dot(v), m[2].dot(v));
+ }
+
+
+ SIMD_FORCE_INLINE SimdVector3
+ operator*(const SimdVector3& v, const SimdMatrix3x3& m)
+ {
+ return SimdVector3(m.tdot(0, v), m.tdot(1, v), m.tdot(2, v));
+ }
+
+ SIMD_FORCE_INLINE SimdMatrix3x3
+ operator*(const SimdMatrix3x3& m1, const SimdMatrix3x3& m2)
+ {
+ return SimdMatrix3x3(
+ m2.tdot(0, m1[0]), m2.tdot(1, m1[0]), m2.tdot(2, m1[0]),
+ m2.tdot(0, m1[1]), m2.tdot(1, m1[1]), m2.tdot(2, m1[1]),
+ m2.tdot(0, m1[2]), m2.tdot(1, m1[2]), m2.tdot(2, m1[2]));
+ }
+
+
+ SIMD_FORCE_INLINE SimdMatrix3x3 SimdMultTransposeLeft(const SimdMatrix3x3& m1, const SimdMatrix3x3& m2) {
+ return SimdMatrix3x3(
+ m1[0][0] * m2[0][0] + m1[1][0] * m2[1][0] + m1[2][0] * m2[2][0],
+ m1[0][0] * m2[0][1] + m1[1][0] * m2[1][1] + m1[2][0] * m2[2][1],
+ m1[0][0] * m2[0][2] + m1[1][0] * m2[1][2] + m1[2][0] * m2[2][2],
+ m1[0][1] * m2[0][0] + m1[1][1] * m2[1][0] + m1[2][1] * m2[2][0],
+ m1[0][1] * m2[0][1] + m1[1][1] * m2[1][1] + m1[2][1] * m2[2][1],
+ m1[0][1] * m2[0][2] + m1[1][1] * m2[1][2] + m1[2][1] * m2[2][2],
+ m1[0][2] * m2[0][0] + m1[1][2] * m2[1][0] + m1[2][2] * m2[2][0],
+ m1[0][2] * m2[0][1] + m1[1][2] * m2[1][1] + m1[2][2] * m2[2][1],
+ m1[0][2] * m2[0][2] + m1[1][2] * m2[1][2] + m1[2][2] * m2[2][2]);
+}
+
+
+#endif
diff --git a/extern/bullet/LinearMath/SimdMinMax.h b/extern/bullet/LinearMath/SimdMinMax.h
new file mode 100644
index 00000000000..999cfb0c919
--- /dev/null
+++ b/extern/bullet/LinearMath/SimdMinMax.h
@@ -0,0 +1,52 @@
+/*
+
+Copyright (c) 2005 Gino van den Bergen / Erwin Coumans <www.erwincoumans.com>
+
+Permission is hereby granted, free of charge, to any person or organization
+obtaining a copy of the software and accompanying documentation covered by
+this license (the "Software") to use, reproduce, display, distribute,
+execute, and transmit the Software, and to prepare derivative works of the
+Software, and to permit third-parties to whom the Software is furnished to
+do so, all subject to the following:
+
+The copyright notices in the Software and this entire statement, including
+the above license grant, this restriction and the following disclaimer,
+must be included in all copies of the Software, in whole or in part, and
+all derivative works of the Software, unless such copies or derivative
+works are solely in the form of machine-executable object code generated by
+a source language processor.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+
+#ifndef SIMD_MINMAX_H
+#define SIMD_MINMAX_H
+
+template <class T>
+SIMD_FORCE_INLINE const T& SimdMin(const T& a, const T& b) {
+ return b < a ? b : a;
+}
+
+template <class T>
+SIMD_FORCE_INLINE const T& SimdMax(const T& a, const T& b) {
+ return a < b ? b : a;
+}
+
+template <class T>
+SIMD_FORCE_INLINE void SimdSetMin(T& a, const T& b) {
+ if (a > b) a = b;
+}
+
+template <class T>
+SIMD_FORCE_INLINE void SimdSetMax(T& a, const T& b) {
+ if (a < b) a = b;
+}
+
+#endif
diff --git a/extern/bullet/LinearMath/SimdPoint3.h b/extern/bullet/LinearMath/SimdPoint3.h
new file mode 100644
index 00000000000..711ac5c76cc
--- /dev/null
+++ b/extern/bullet/LinearMath/SimdPoint3.h
@@ -0,0 +1,36 @@
+/*
+
+Copyright (c) 2005 Gino van den Bergen / Erwin Coumans <www.erwincoumans.com>
+
+Permission is hereby granted, free of charge, to any person or organization
+obtaining a copy of the software and accompanying documentation covered by
+this license (the "Software") to use, reproduce, display, distribute,
+execute, and transmit the Software, and to prepare derivative works of the
+Software, and to permit third-parties to whom the Software is furnished to
+do so, all subject to the following:
+
+The copyright notices in the Software and this entire statement, including
+the above license grant, this restriction and the following disclaimer,
+must be included in all copies of the Software, in whole or in part, and
+all derivative works of the Software, unless such copies or derivative
+works are solely in the form of machine-executable object code generated by
+a source language processor.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+
+#ifndef SimdPoint3_H
+#define SimdPoint3_H
+
+#include "SimdVector3.h"
+
+typedef SimdVector3 SimdPoint3;
+
+#endif
diff --git a/extern/bullet/LinearMath/SimdQuadWord.h b/extern/bullet/LinearMath/SimdQuadWord.h
new file mode 100644
index 00000000000..cf720ef4b32
--- /dev/null
+++ b/extern/bullet/LinearMath/SimdQuadWord.h
@@ -0,0 +1,113 @@
+/*
+
+Copyright (c) 2005 Gino van den Bergen / Erwin Coumans <www.erwincoumans.com>
+
+Permission is hereby granted, free of charge, to any person or organization
+obtaining a copy of the software and accompanying documentation covered by
+this license (the "Software") to use, reproduce, display, distribute,
+execute, and transmit the Software, and to prepare derivative works of the
+Software, and to permit third-parties to whom the Software is furnished to
+do so, all subject to the following:
+
+The copyright notices in the Software and this entire statement, including
+the above license grant, this restriction and the following disclaimer,
+must be included in all copies of the Software, in whole or in part, and
+all derivative works of the Software, unless such copies or derivative
+works are solely in the form of machine-executable object code generated by
+a source language processor.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+#ifndef SIMD_QUADWORD_H
+#define SIMD_QUADWORD_H
+
+#include "SimdScalar.h"
+
+
+
+
+
+class SimdQuadWord
+{
+ protected:
+ ATTRIBUTE_ALIGNED16 (SimdScalar m_x);
+ SimdScalar m_y;
+ SimdScalar m_z;
+ SimdScalar m_unusedW;
+
+ public:
+
+ SIMD_FORCE_INLINE SimdScalar& operator[](int i) { return (&m_x)[i]; }
+ SIMD_FORCE_INLINE const SimdScalar& operator[](int i) const { return (&m_x)[i]; }
+
+ SIMD_FORCE_INLINE const SimdScalar& getX() const { return m_x; }
+
+ SIMD_FORCE_INLINE const SimdScalar& getY() const { return m_y; }
+
+ SIMD_FORCE_INLINE const SimdScalar& getZ() const { return m_z; }
+
+ SIMD_FORCE_INLINE void setX(float x) { m_x = x;};
+
+ SIMD_FORCE_INLINE void setY(float y) { m_y = y;};
+
+ SIMD_FORCE_INLINE void setZ(float z) { m_z = z;};
+
+ SIMD_FORCE_INLINE const SimdScalar& x() const { return m_x; }
+
+ SIMD_FORCE_INLINE const SimdScalar& y() const { return m_y; }
+
+ SIMD_FORCE_INLINE const SimdScalar& z() const { return m_z; }
+
+
+ operator SimdScalar *() { return &m_x; }
+ operator const SimdScalar *() const { return &m_x; }
+
+ SIMD_FORCE_INLINE void setValue(const SimdScalar& x, const SimdScalar& y, const SimdScalar& z)
+ {
+ m_x=x;
+ m_y=y;
+ m_z=z;
+ }
+
+/* void getValue(SimdScalar *m) const
+ {
+ m[0] = m_x;
+ m[1] = m_y;
+ m[2] = m_z;
+ }
+*/
+ SIMD_FORCE_INLINE void setValue(const SimdScalar& x, const SimdScalar& y, const SimdScalar& z,const SimdScalar& w)
+ {
+ m_x=x;
+ m_y=y;
+ m_z=z;
+ m_unusedW=w;
+ }
+
+ SIMD_FORCE_INLINE SimdQuadWord()
+ {
+ }
+
+ SIMD_FORCE_INLINE SimdQuadWord(const SimdScalar& x, const SimdScalar& y, const SimdScalar& z)
+ :m_x(x),m_y(y),m_z(z)
+ //todo, remove this in release/simd ?
+ ,m_unusedW(1e30f)
+ {
+ }
+
+ SIMD_FORCE_INLINE SimdQuadWord(const SimdScalar& x, const SimdScalar& y, const SimdScalar& z,const SimdScalar& w)
+ :m_x(x),m_y(y),m_z(z),m_unusedW(w)
+ {
+ }
+
+
+};
+
+#endif //SIMD_QUADWORD_H
diff --git a/extern/bullet/LinearMath/SimdQuaternion.h b/extern/bullet/LinearMath/SimdQuaternion.h
new file mode 100644
index 00000000000..6a8513ae0d9
--- /dev/null
+++ b/extern/bullet/LinearMath/SimdQuaternion.h
@@ -0,0 +1,302 @@
+/*
+
+Copyright (c) 2005 Gino van den Bergen / Erwin Coumans <www.erwincoumans.com>
+
+Permission is hereby granted, free of charge, to any person or organization
+obtaining a copy of the software and accompanying documentation covered by
+this license (the "Software") to use, reproduce, display, distribute,
+execute, and transmit the Software, and to prepare derivative works of the
+Software, and to permit third-parties to whom the Software is furnished to
+do so, all subject to the following:
+
+The copyright notices in the Software and this entire statement, including
+the above license grant, this restriction and the following disclaimer,
+must be included in all copies of the Software, in whole or in part, and
+all derivative works of the Software, unless such copies or derivative
+works are solely in the form of machine-executable object code generated by
+a source language processor.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+
+#ifndef SIMD__QUATERNION_H_
+#define SIMD__QUATERNION_H_
+
+#include "SimdVector3.h"
+
+class SimdQuaternion : public SimdQuadWord {
+public:
+ SimdQuaternion() {}
+
+ // template <typename SimdScalar>
+ // explicit Quaternion(const SimdScalar *v) : Tuple4<SimdScalar>(v) {}
+
+ SimdQuaternion(const SimdScalar& x, const SimdScalar& y, const SimdScalar& z, const SimdScalar& w)
+ : SimdQuadWord(x, y, z, w)
+ {}
+
+ SimdQuaternion(const SimdVector3& axis, const SimdScalar& angle)
+ {
+ setRotation(axis, angle);
+ }
+
+ SimdQuaternion(const SimdScalar& yaw, const SimdScalar& pitch, const SimdScalar& roll)
+ {
+ setEuler(yaw, pitch, roll);
+ }
+
+ void setRotation(const SimdVector3& axis, const SimdScalar& angle)
+ {
+ SimdScalar d = axis.length();
+ assert(d != SimdScalar(0.0));
+ SimdScalar s = sinf(angle * SimdScalar(0.5)) / d;
+ setValue(axis.x() * s, axis.y() * s, axis.z() * s,
+ cosf(angle * SimdScalar(0.5)));
+ }
+
+ void setEuler(const SimdScalar& yaw, const SimdScalar& pitch, const SimdScalar& roll)
+ {
+ SimdScalar halfYaw = SimdScalar(yaw) * SimdScalar(0.5);
+ SimdScalar halfPitch = SimdScalar(pitch) * SimdScalar(0.5);
+ SimdScalar halfRoll = SimdScalar(roll) * SimdScalar(0.5);
+ SimdScalar cosYaw = cosf(halfYaw);
+ SimdScalar sinYaw = sinf(halfYaw);
+ SimdScalar cosPitch = cosf(halfPitch);
+ SimdScalar sinPitch = sinf(halfPitch);
+ SimdScalar cosRoll = cosf(halfRoll);
+ SimdScalar sinRoll = sinf(halfRoll);
+ setValue(cosRoll * sinPitch * cosYaw + sinRoll * cosPitch * sinYaw,
+ cosRoll * cosPitch * sinYaw - sinRoll * sinPitch * cosYaw,
+ sinRoll * cosPitch * cosYaw - cosRoll * sinPitch * sinYaw,
+ cosRoll * cosPitch * cosYaw + sinRoll * sinPitch * sinYaw);
+ }
+
+ SimdQuaternion& operator+=(const SimdQuaternion& q)
+ {
+ m_x += q.x(); m_y += q.y(); m_z += q.z(); m_unusedW += q[3];
+ return *this;
+ }
+
+ SimdQuaternion& operator-=(const SimdQuaternion& q)
+ {
+ m_x -= q.x(); m_y -= q.y(); m_z -= q.z(); m_unusedW -= q[3];
+ return *this;
+ }
+
+ SimdQuaternion& operator*=(const SimdScalar& s)
+ {
+ m_x *= s; m_y *= s; m_z *= s; m_unusedW *= s;
+ return *this;
+ }
+
+
+ SimdQuaternion& operator*=(const SimdQuaternion& q)
+ {
+ setValue(m_unusedW * q.x() + m_x * q[3] + m_y * q.z() - m_z * q.y(),
+ m_unusedW * q.y() + m_y * q[3] + m_z * q.x() - m_x * q.z(),
+ m_unusedW * q.z() + m_z * q[3] + m_x * q.y() - m_y * q.x(),
+ m_unusedW * q[3] - m_x * q.x() - m_y * q.y() - m_z * q.z());
+ return *this;
+ }
+
+ SimdScalar dot(const SimdQuaternion& q) const
+ {
+ return m_x * q.x() + m_y * q.y() + m_z * q.z() + m_unusedW * q[3];
+ }
+
+ SimdScalar length2() const
+ {
+ return dot(*this);
+ }
+
+ SimdScalar length() const
+ {
+ return sqrtf(length2());
+ }
+
+ SimdQuaternion& normalize()
+ {
+ return *this /= length();
+ }
+
+ SIMD_FORCE_INLINE SimdQuaternion
+ operator*(const SimdScalar& s) const
+ {
+ return SimdQuaternion(x() * s, y() * s, z() * s, m_unusedW * s);
+ }
+
+
+
+ SimdQuaternion operator/(const SimdScalar& s) const
+ {
+ assert(s != SimdScalar(0.0));
+ return *this * (SimdScalar(1.0) / s);
+ }
+
+
+ SimdQuaternion& operator/=(const SimdScalar& s)
+ {
+ assert(s != SimdScalar(0.0));
+ return *this *= SimdScalar(1.0) / s;
+ }
+
+
+ SimdQuaternion normalized() const
+ {
+ return *this / length();
+ }
+
+ SimdScalar angle(const SimdQuaternion& q) const
+ {
+ SimdScalar s = sqrtf(length2() * q.length2());
+ assert(s != SimdScalar(0.0));
+ return acosf(dot(q) / s);
+ }
+
+ SimdScalar getAngle() const
+ {
+ SimdScalar s = 2.f * acosf(m_unusedW);
+ return s;
+ }
+
+
+
+ SimdQuaternion inverse() const
+ {
+ return SimdQuaternion(m_x, m_y, m_z, -m_unusedW);
+ }
+
+ SIMD_FORCE_INLINE SimdQuaternion
+ operator+(const SimdQuaternion& q2) const
+ {
+ const SimdQuaternion& q1 = *this;
+ return SimdQuaternion(q1.x() + q2.x(), q1.y() + q2.y(), q1.z() + q2.z(), q1[3] + q2[3]);
+ }
+
+ SIMD_FORCE_INLINE SimdQuaternion
+ operator-(const SimdQuaternion& q2) const
+ {
+ const SimdQuaternion& q1 = *this;
+ return SimdQuaternion(q1.x() - q2.x(), q1.y() - q2.y(), q1.z() - q2.z(), q1[3] - q2[3]);
+ }
+
+ SIMD_FORCE_INLINE SimdQuaternion operator-() const
+ {
+ const SimdQuaternion& q2 = *this;
+ return SimdQuaternion( - q2.x(), - q2.y(), - q2.z(), - q2[3]);
+ }
+
+ SIMD_FORCE_INLINE SimdQuaternion farthest( const SimdQuaternion& qd) const
+ {
+ SimdQuaternion diff,sum;
+ diff = *this - qd;
+ sum = *this + qd;
+ if( diff.dot(diff) > sum.dot(sum) )
+ return qd;
+ return (-qd);
+ }
+
+ SimdQuaternion slerp(const SimdQuaternion& q, const SimdScalar& t) const
+ {
+ SimdScalar theta = angle(q);
+ if (theta != SimdScalar(0.0))
+ {
+ SimdScalar d = SimdScalar(1.0) / sinf(theta);
+ SimdScalar s0 = sinf((SimdScalar(1.0) - t) * theta);
+ SimdScalar s1 = sinf(t * theta);
+ return SimdQuaternion((m_x * s0 + q.x() * s1) * d,
+ (m_y * s0 + q.y() * s1) * d,
+ (m_z * s0 + q.z() * s1) * d,
+ (m_unusedW * s0 + q[3] * s1) * d);
+ }
+ else
+ {
+ return *this;
+ }
+ }
+
+
+
+};
+
+
+
+SIMD_FORCE_INLINE SimdQuaternion
+operator-(const SimdQuaternion& q)
+{
+ return SimdQuaternion(-q.x(), -q.y(), -q.z(), -q[3]);
+}
+
+
+
+
+SIMD_FORCE_INLINE SimdQuaternion
+operator*(const SimdQuaternion& q1, const SimdQuaternion& q2) {
+ return SimdQuaternion(q1[3] * q2.x() + q1.x() * q2[3] + q1.y() * q2.z() - q1.z() * q2.y(),
+ q1[3] * q2.y() + q1.y() * q2[3] + q1.z() * q2.x() - q1.x() * q2.z(),
+ q1[3] * q2.z() + q1.z() * q2[3] + q1.x() * q2.y() - q1.y() * q2.x(),
+ q1[3] * q2[3] - q1.x() * q2.x() - q1.y() * q2.y() - q1.z() * q2.z());
+}
+
+SIMD_FORCE_INLINE SimdQuaternion
+operator*(const SimdQuaternion& q, const SimdVector3& w)
+{
+ return SimdQuaternion( q[3] * w.x() + q.y() * w.z() - q.z() * w.y(),
+ q[3] * w.y() + q.z() * w.x() - q.x() * w.z(),
+ q[3] * w.z() + q.x() * w.y() - q.y() * w.x(),
+ -q.x() * w.x() - q.y() * w.y() - q.z() * w.z());
+}
+
+SIMD_FORCE_INLINE SimdQuaternion
+operator*(const SimdVector3& w, const SimdQuaternion& q)
+{
+ return SimdQuaternion( w.x() * q[3] + w.y() * q.z() - w.z() * q.y(),
+ w.y() * q[3] + w.z() * q.x() - w.x() * q.z(),
+ w.z() * q[3] + w.x() * q.y() - w.y() * q.x(),
+ -w.x() * q.x() - w.y() * q.y() - w.z() * q.z());
+}
+
+SIMD_FORCE_INLINE SimdScalar
+dot(const SimdQuaternion& q1, const SimdQuaternion& q2)
+{
+ return q1.dot(q2);
+}
+
+
+SIMD_FORCE_INLINE SimdScalar
+length(const SimdQuaternion& q)
+{
+ return q.length();
+}
+
+SIMD_FORCE_INLINE SimdScalar
+angle(const SimdQuaternion& q1, const SimdQuaternion& q2)
+{
+ return q1.angle(q2);
+}
+
+
+SIMD_FORCE_INLINE SimdQuaternion
+inverse(const SimdQuaternion& q)
+{
+ return q.inverse();
+}
+
+SIMD_FORCE_INLINE SimdQuaternion
+slerp(const SimdQuaternion& q1, const SimdQuaternion& q2, const SimdScalar& t)
+{
+ return q1.slerp(q2, t);
+}
+
+
+#endif
+
+
+
diff --git a/extern/bullet/LinearMath/SimdScalar.h b/extern/bullet/LinearMath/SimdScalar.h
new file mode 100644
index 00000000000..6feaee53f8e
--- /dev/null
+++ b/extern/bullet/LinearMath/SimdScalar.h
@@ -0,0 +1,95 @@
+/*
+
+Copyright (c) 2005 Gino van den Bergen / Erwin Coumans <www.erwincoumans.com>
+
+Permission is hereby granted, free of charge, to any person or organization
+obtaining a copy of the software and accompanying documentation covered by
+this license (the "Software") to use, reproduce, display, distribute,
+execute, and transmit the Software, and to prepare derivative works of the
+Software, and to permit third-parties to whom the Software is furnished to
+do so, all subject to the following:
+
+The copyright notices in the Software and this entire statement, including
+the above license grant, this restriction and the following disclaimer,
+must be included in all copies of the Software, in whole or in part, and
+all derivative works of the Software, unless such copies or derivative
+works are solely in the form of machine-executable object code generated by
+a source language processor.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+
+#ifndef SIMD___SCALAR_H
+#define SIMD___SCALAR_H
+
+#include <math.h>
+#undef max
+
+
+
+#include <cstdlib>
+#include <cfloat>
+#include <float.h>
+
+#ifdef WIN32
+#define SIMD_FORCE_INLINE __forceinline
+//#define ATTRIBUTE_ALIGNED16(a) __declspec(align(16)) a
+#define ATTRIBUTE_ALIGNED16(a) a
+
+#include <assert.h>
+#define ASSERT assert
+#else
+#define SIMD_FORCE_INLINE inline
+#define ATTRIBUTE_ALIGNED16(a) a
+#ifndef assert
+#include <assert.h>
+#endif
+
+
+#define ASSERT assert
+
+#endif
+
+
+
+typedef float SimdScalar;
+
+const SimdScalar SIMD_2_PI = 6.283185307179586232f;
+const SimdScalar SIMD_PI = SIMD_2_PI * SimdScalar(0.5f);
+const SimdScalar SIMD_HALF_PI = SIMD_2_PI * SimdScalar(0.25f);
+const SimdScalar SIMD_RADS_PER_DEG = SIMD_2_PI / SimdScalar(360.0f);
+const SimdScalar SIMD_DEGS_PER_RAD = SimdScalar(360.0f) / SIMD_2_PI;
+const SimdScalar SIMD_EPSILON = FLT_EPSILON;
+const SimdScalar SIMD_INFINITY = FLT_MAX;
+
+SIMD_FORCE_INLINE bool SimdFuzzyZero(SimdScalar x) { return fabsf(x) < SIMD_EPSILON; }
+
+SIMD_FORCE_INLINE bool SimdEqual(SimdScalar a, SimdScalar eps) {
+ return (((a) <= eps) && !((a) < -eps));
+}
+SIMD_FORCE_INLINE bool SimdGreaterEqual (SimdScalar a, SimdScalar eps) {
+ return (!((a) <= eps));
+}
+
+SIMD_FORCE_INLINE SimdScalar SimdCos(SimdScalar x) { return cosf(x); }
+SIMD_FORCE_INLINE SimdScalar SimdSin(SimdScalar x) { return sinf(x); }
+SIMD_FORCE_INLINE SimdScalar SimdTan(SimdScalar x) { return tanf(x); }
+SIMD_FORCE_INLINE int SimdSign(SimdScalar x) {
+ return x < 0.0f ? -1 : x > 0.0f ? 1 : 0;
+}
+SIMD_FORCE_INLINE SimdScalar SimdAcos(SimdScalar x) { return acosf(x); }
+SIMD_FORCE_INLINE SimdScalar SimdAsin(SimdScalar x) { return asinf(x); }
+SIMD_FORCE_INLINE SimdScalar SimdAtan(SimdScalar x) { return atanf(x); }
+SIMD_FORCE_INLINE SimdScalar SimdAtan2(SimdScalar x, SimdScalar y) { return atan2f(x, y); }
+
+SIMD_FORCE_INLINE SimdScalar SimdRadians(SimdScalar x) { return x * SIMD_RADS_PER_DEG; }
+SIMD_FORCE_INLINE SimdScalar SimdDegrees(SimdScalar x) { return x * SIMD_DEGS_PER_RAD; }
+
+#endif
diff --git a/extern/bullet/LinearMath/SimdTransform.h b/extern/bullet/LinearMath/SimdTransform.h
new file mode 100644
index 00000000000..cbf9a95a41f
--- /dev/null
+++ b/extern/bullet/LinearMath/SimdTransform.h
@@ -0,0 +1,248 @@
+/*
+
+Copyright (c) 2005 Gino van den Bergen / Erwin Coumans <www.erwincoumans.com>
+
+Permission is hereby granted, free of charge, to any person or organization
+obtaining a copy of the software and accompanying documentation covered by
+this license (the "Software") to use, reproduce, display, distribute,
+execute, and transmit the Software, and to prepare derivative works of the
+Software, and to permit third-parties to whom the Software is furnished to
+do so, all subject to the following:
+
+The copyright notices in the Software and this entire statement, including
+the above license grant, this restriction and the following disclaimer,
+must be included in all copies of the Software, in whole or in part, and
+all derivative works of the Software, unless such copies or derivative
+works are solely in the form of machine-executable object code generated by
+a source language processor.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+
+#ifndef SimdTransform_H
+#define SimdTransform_H
+
+#include "SimdVector3.h"
+#include "SimdMatrix3x3.h"
+
+
+
+class SimdTransform {
+ enum {
+ TRANSLATION = 0x01,
+ ROTATION = 0x02,
+ RIGID = TRANSLATION | ROTATION,
+ SCALING = 0x04,
+ LINEAR = ROTATION | SCALING,
+ AFFINE = TRANSLATION | LINEAR
+ };
+
+public:
+ SimdTransform() {}
+
+ // template <typename Scalar2>
+ // explicit Transform(const Scalar2 *m) { setValue(m); }
+
+ explicit SIMD_FORCE_INLINE SimdTransform(const SimdQuaternion& q,
+ const SimdVector3& c = SimdVector3(SimdScalar(0), SimdScalar(0), SimdScalar(0)))
+ : m_basis(q),
+ m_origin(c),
+ m_type(RIGID)
+ {}
+
+ explicit SIMD_FORCE_INLINE SimdTransform(const SimdMatrix3x3& b,
+ const SimdVector3& c = SimdVector3(SimdScalar(0), SimdScalar(0), SimdScalar(0)),
+ unsigned int type = AFFINE)
+ : m_basis(b),
+ m_origin(c),
+ m_type(type)
+ {}
+
+
+ SIMD_FORCE_INLINE void mult(const SimdTransform& t1, const SimdTransform& t2) {
+ m_basis = t1.m_basis * t2.m_basis;
+ m_origin = t1(t2.m_origin);
+ m_type = t1.m_type | t2.m_type;
+ }
+
+ void multInverseLeft(const SimdTransform& t1, const SimdTransform& t2) {
+ SimdVector3 v = t2.m_origin - t1.m_origin;
+ if (t1.m_type & SCALING) {
+ SimdMatrix3x3 inv = t1.m_basis.inverse();
+ m_basis = inv * t2.m_basis;
+ m_origin = inv * v;
+ }
+ else {
+ m_basis = SimdMultTransposeLeft(t1.m_basis, t2.m_basis);
+ m_origin = v * t1.m_basis;
+ }
+ m_type = t1.m_type | t2.m_type;
+ }
+
+ SIMD_FORCE_INLINE SimdVector3 operator()(const SimdVector3& x) const
+ {
+ return SimdVector3(m_basis[0].dot(x) + m_origin[0],
+ m_basis[1].dot(x) + m_origin[1],
+ m_basis[2].dot(x) + m_origin[2]);
+ }
+
+ SIMD_FORCE_INLINE SimdVector3 operator*(const SimdVector3& x) const
+ {
+ return (*this)(x);
+ }
+
+ SIMD_FORCE_INLINE SimdMatrix3x3& getBasis() { return m_basis; }
+ SIMD_FORCE_INLINE const SimdMatrix3x3& getBasis() const { return m_basis; }
+
+ SIMD_FORCE_INLINE SimdVector3& getOrigin() { return m_origin; }
+ SIMD_FORCE_INLINE const SimdVector3& getOrigin() const { return m_origin; }
+
+ SimdQuaternion getRotation() const {
+ SimdQuaternion q;
+ m_basis.getRotation(q);
+ return q;
+ }
+ template <typename Scalar2>
+ void setValue(const Scalar2 *m)
+ {
+ m_basis.setValue(m);
+ m_origin.setValue(&m[12]);
+ m_type = AFFINE;
+ }
+
+
+ void setFromOpenGLMatrix(const SimdScalar *m)
+ {
+ m_basis.setFromOpenGLSubMatrix(m);
+ m_origin[0] = m[12];
+ m_origin[1] = m[13];
+ m_origin[2] = m[14];
+ }
+
+ void getOpenGLMatrix(SimdScalar *m) const
+ {
+ m_basis.getOpenGLSubMatrix(m);
+ m[12] = m_origin[0];
+ m[13] = m_origin[1];
+ m[14] = m_origin[2];
+ m[15] = SimdScalar(1.0f);
+ }
+
+ SIMD_FORCE_INLINE void setOrigin(const SimdVector3& origin)
+ {
+ m_origin = origin;
+ m_type |= TRANSLATION;
+ }
+
+ SIMD_FORCE_INLINE SimdVector3 invXform(const SimdVector3& inVec) const;
+
+
+
+ SIMD_FORCE_INLINE void setBasis(const SimdMatrix3x3& basis)
+ {
+ m_basis = basis;
+ m_type |= LINEAR;
+ }
+
+ SIMD_FORCE_INLINE void setRotation(const SimdQuaternion& q)
+ {
+ m_basis.setRotation(q);
+ m_type = (m_type & ~LINEAR) | ROTATION;
+ }
+
+ SIMD_FORCE_INLINE void scale(const SimdVector3& scaling)
+ {
+ m_basis = m_basis.scaled(scaling);
+ m_type |= SCALING;
+ }
+
+ void setIdentity()
+ {
+ m_basis.setIdentity();
+ m_origin.setValue(SimdScalar(0.0), SimdScalar(0.0), SimdScalar(0.0));
+ m_type = 0x0;
+ }
+
+ SIMD_FORCE_INLINE bool isIdentity() const { return m_type == 0x0; }
+
+ SimdTransform& operator*=(const SimdTransform& t)
+ {
+ m_origin += m_basis * t.m_origin;
+ m_basis *= t.m_basis;
+ m_type |= t.m_type;
+ return *this;
+ }
+
+ SimdTransform inverse() const
+ {
+ if (m_type)
+ {
+ SimdMatrix3x3 inv = (m_type & SCALING) ?
+ m_basis.inverse() :
+ m_basis.transpose();
+
+ return SimdTransform(inv, inv * -m_origin, m_type);
+ }
+
+ return *this;
+ }
+
+ SimdTransform inverseTimes(const SimdTransform& t) const;
+
+ SimdTransform operator*(const SimdTransform& t) const;
+
+private:
+
+ SimdMatrix3x3 m_basis;
+ SimdVector3 m_origin;
+ unsigned int m_type;
+};
+
+
+SIMD_FORCE_INLINE SimdVector3
+SimdTransform::invXform(const SimdVector3& inVec) const
+{
+ SimdVector3 v = inVec - m_origin;
+ return (m_basis.transpose() * v);
+}
+
+SIMD_FORCE_INLINE SimdTransform
+SimdTransform::inverseTimes(const SimdTransform& t) const
+{
+ SimdVector3 v = t.getOrigin() - m_origin;
+ if (m_type & SCALING)
+ {
+ SimdMatrix3x3 inv = m_basis.inverse();
+ return SimdTransform(inv * t.getBasis(), inv * v,
+ m_type | t.m_type);
+ }
+ else
+ {
+ return SimdTransform(m_basis.transposeTimes(t.m_basis),
+ v * m_basis, m_type | t.m_type);
+ }
+}
+
+SIMD_FORCE_INLINE SimdTransform
+SimdTransform::operator*(const SimdTransform& t) const
+{
+ return SimdTransform(m_basis * t.m_basis,
+ (*this)(t.m_origin),
+ m_type | t.m_type);
+}
+
+
+
+#endif
+
+
+
+
+
diff --git a/extern/bullet/LinearMath/SimdTransformUtil.h b/extern/bullet/LinearMath/SimdTransformUtil.h
new file mode 100644
index 00000000000..f3ee76de77b
--- /dev/null
+++ b/extern/bullet/LinearMath/SimdTransformUtil.h
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies.
+ * Erwin Coumans makes no representations about the suitability
+ * of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+*/
+
+#ifndef SIMD_TRANSFORM_UTIL_H
+#define SIMD_TRANSFORM_UTIL_H
+
+#include "SimdTransform.h"
+#define ANGULAR_MOTION_TRESHOLD 0.5f*SIMD_HALF_PI
+
+/// Utils related to temporal transforms
+class SimdTransformUtil
+{
+
+public:
+
+ static void IntegrateTransform(const SimdTransform& curTrans,const SimdVector3& linvel,const SimdVector3& angvel,SimdScalar timeStep,SimdTransform& predictedTransform)
+ {
+ predictedTransform.setOrigin(curTrans.getOrigin() + linvel * timeStep);
+// #define QUATERNION_DERIVATIVE
+ #ifdef QUATERNION_DERIVATIVE
+ SimdQuaternion orn = curTrans.getRotation();
+ orn += (angvel * orn) * (timeStep * 0.5f);
+ orn.normalize();
+ #else
+ //exponential map
+ SimdVector3 axis;
+ SimdScalar fAngle = angvel.length();
+ //limit the angular motion
+ if (fAngle*timeStep > ANGULAR_MOTION_TRESHOLD)
+ {
+ fAngle = ANGULAR_MOTION_TRESHOLD / timeStep;
+ }
+
+ if ( fAngle < 0.001f )
+ {
+ // use Taylor's expansions of sync function
+ axis = angvel*( 0.5f*timeStep-(timeStep*timeStep*timeStep)*(0.020833333333f)*fAngle*fAngle );
+ }
+ else
+ {
+ // sync(fAngle) = sin(c*fAngle)/t
+ axis = angvel*( sinf(0.5f*fAngle*timeStep)/fAngle );
+ }
+ SimdQuaternion dorn (axis.x(),axis.y(),axis.z(),cosf( fAngle*timeStep*0.5f ));
+ SimdQuaternion orn0 = curTrans.getRotation();
+
+ SimdQuaternion predictedOrn = dorn * orn0;
+ #endif
+ predictedTransform.setRotation(predictedOrn);
+ }
+
+ static void CalculateVelocity(const SimdTransform& transform0,const SimdTransform& transform1,SimdScalar timeStep,SimdVector3& linVel,SimdVector3& angVel)
+ {
+ linVel = (transform1.getOrigin() - transform0.getOrigin()) / timeStep;
+#ifdef USE_QUATERNION_DIFF
+ SimdQuaternion orn0 = transform0.getRotation();
+ SimdQuaternion orn1a = transform1.getRotation();
+ SimdQuaternion orn1 = orn0.farthest(orn1a);
+ SimdQuaternion dorn = orn1 * orn0.inverse();
+#else
+ SimdMatrix3x3 dmat = transform1.getBasis() * transform0.getBasis().inverse();
+ SimdQuaternion dorn;
+ dmat.getRotation(dorn);
+#endif//USE_QUATERNION_DIFF
+
+ SimdVector3 axis;
+ SimdScalar angle;
+ angle = dorn.getAngle();
+ axis = SimdVector3(dorn.x(),dorn.y(),dorn.z());
+ axis[3] = 0.f;
+ //check for axis length
+ SimdScalar len = axis.length2();
+ if (len < 0.001f)
+ axis = SimdVector3(1.f,0.f,0.f);
+ else
+ axis /= sqrtf(len);
+
+
+ angVel = axis * angle / timeStep;
+
+ }
+
+
+};
+
+#endif //SIMD_TRANSFORM_UTIL_H \ No newline at end of file
diff --git a/extern/bullet/LinearMath/SimdVector3.h b/extern/bullet/LinearMath/SimdVector3.h
new file mode 100644
index 00000000000..b7077d828b9
--- /dev/null
+++ b/extern/bullet/LinearMath/SimdVector3.h
@@ -0,0 +1,396 @@
+/*
+
+Copyright (c) 2005 Gino van den Bergen / Erwin Coumans <www.erwincoumans.com>
+
+Permission is hereby granted, free of charge, to any person or organization
+obtaining a copy of the software and accompanying documentation covered by
+this license (the "Software") to use, reproduce, display, distribute,
+execute, and transmit the Software, and to prepare derivative works of the
+Software, and to permit third-parties to whom the Software is furnished to
+do so, all subject to the following:
+
+The copyright notices in the Software and this entire statement, including
+the above license grant, this restriction and the following disclaimer,
+must be included in all copies of the Software, in whole or in part, and
+all derivative works of the Software, unless such copies or derivative
+works are solely in the form of machine-executable object code generated by
+a source language processor.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+
+#ifndef SIMD__VECTOR3_H
+#define SIMD__VECTOR3_H
+
+#include "SimdQuadWord.h"
+
+
+///SimdVector3 is 16byte aligned, and has an extra unused component m_w
+///this extra component can be used by derived classes (Quaternion?) or by user
+class SimdVector3 : public SimdQuadWord {
+
+
+public:
+ SIMD_FORCE_INLINE SimdVector3() {}
+
+
+
+ SIMD_FORCE_INLINE SimdVector3(const SimdScalar& x, const SimdScalar& y, const SimdScalar& z)
+ :SimdQuadWord(x,y,z,0.f)
+ {
+ }
+
+// SIMD_FORCE_INLINE SimdVector3(const SimdScalar& x, const SimdScalar& y, const SimdScalar& z,const SimdScalar& w)
+// : SimdQuadWord(x,y,z,w)
+// {
+// }
+
+
+
+ SIMD_FORCE_INLINE SimdVector3& operator+=(const SimdVector3& v)
+ {
+ m_x += v.x(); m_y += v.y(); m_z += v.z();
+ return *this;
+ }
+
+
+
+ SIMD_FORCE_INLINE SimdVector3& operator-=(const SimdVector3& v)
+ {
+ m_x -= v.x(); m_y -= v.y(); m_z -= v.z();
+ return *this;
+ }
+
+ SIMD_FORCE_INLINE SimdVector3& operator*=(const SimdScalar& s)
+ {
+ m_x *= s; m_y *= s; m_z *= s;
+ return *this;
+ }
+
+ SIMD_FORCE_INLINE SimdVector3& operator/=(const SimdScalar& s)
+ {
+ assert(s != SimdScalar(0.0));
+ return *this *= SimdScalar(1.0) / s;
+ }
+
+ SIMD_FORCE_INLINE SimdScalar dot(const SimdVector3& v) const
+ {
+ return m_x * v.x() + m_y * v.y() + m_z * v.z();
+ }
+
+ SIMD_FORCE_INLINE SimdScalar length2() const
+ {
+ return dot(*this);
+ }
+
+ SIMD_FORCE_INLINE SimdScalar length() const
+ {
+ return sqrtf(length2());
+ }
+
+ SIMD_FORCE_INLINE SimdScalar distance2(const SimdVector3& v) const;
+
+ SIMD_FORCE_INLINE SimdScalar distance(const SimdVector3& v) const;
+
+ SIMD_FORCE_INLINE SimdVector3& normalize()
+ {
+ return *this /= length();
+ }
+
+ SIMD_FORCE_INLINE SimdVector3 normalized() const;
+
+ SIMD_FORCE_INLINE SimdScalar angle(const SimdVector3& v) const
+ {
+ SimdScalar s = sqrtf(length2() * v.length2());
+ assert(s != SimdScalar(0.0));
+ return acosf(dot(v) / s);
+ }
+
+ SIMD_FORCE_INLINE SimdVector3 absolute() const
+ {
+ return SimdVector3(
+ fabsf(m_x),
+ fabsf(m_y),
+ fabsf(m_z));
+ }
+
+ SIMD_FORCE_INLINE SimdVector3 cross(const SimdVector3& v) const
+ {
+ return SimdVector3(
+ m_y * v.z() - m_z * v.y(),
+ m_z * v.x() - m_x * v.z(),
+ m_x * v.y() - m_y * v.x());
+ }
+
+ SIMD_FORCE_INLINE SimdScalar triple(const SimdVector3& v1, const SimdVector3& v2) const
+ {
+ return m_x * (v1.y() * v2.z() - v1.z() * v2.y()) +
+ m_y * (v1.z() * v2.x() - v1.x() * v2.z()) +
+ m_z * (v1.x() * v2.y() - v1.y() * v2.x());
+ }
+
+ SIMD_FORCE_INLINE int minAxis() const
+ {
+ return m_x < m_y ? (m_x < m_z ? 0 : 2) : (m_y < m_z ? 1 : 2);
+ }
+
+ SIMD_FORCE_INLINE int maxAxis() const
+ {
+ return m_x < m_y ? (m_y < m_z ? 2 : 1) : (m_x < m_z ? 2 : 0);
+ }
+
+ SIMD_FORCE_INLINE int furthestAxis() const
+ {
+ return absolute().minAxis();
+ }
+
+ SIMD_FORCE_INLINE int closestAxis() const
+ {
+ return absolute().maxAxis();
+ }
+
+ SIMD_FORCE_INLINE void setInterpolate3(const SimdVector3& v0, const SimdVector3& v1, SimdScalar rt)
+ {
+ SimdScalar s = 1.0f - rt;
+ m_x = s * v0[0] + rt * v1.x();
+ m_y = s * v0[1] + rt * v1.y();
+ m_z = s * v0[2] + rt * v1.z();
+ //don't do the unused w component
+ // m_co[3] = s * v0[3] + rt * v1[3];
+ }
+
+ SIMD_FORCE_INLINE SimdVector3 lerp(const SimdVector3& v, const SimdScalar& t) const
+ {
+ return SimdVector3(m_x + (v.x() - m_x) * t,
+ m_y + (v.y() - m_y) * t,
+ m_z + (v.z() - m_z) * t);
+ }
+
+
+ SIMD_FORCE_INLINE SimdVector3& operator*=(const SimdVector3& v)
+ {
+ m_x *= v.x(); m_y *= v.y(); m_z *= v.z();
+ return *this;
+ }
+
+
+
+};
+
+SIMD_FORCE_INLINE SimdVector3
+operator+(const SimdVector3& v1, const SimdVector3& v2)
+{
+ return SimdVector3(v1.x() + v2.x(), v1.y() + v2.y(), v1.z() + v2.z());
+}
+
+SIMD_FORCE_INLINE SimdVector3
+operator*(const SimdVector3& v1, const SimdVector3& v2)
+{
+ return SimdVector3(v1.x() * v2.x(), v1.y() * v2.y(), v1.z() *+ v2.z());
+}
+
+SIMD_FORCE_INLINE SimdVector3
+operator-(const SimdVector3& v1, const SimdVector3& v2)
+{
+ return SimdVector3(v1.x() - v2.x(), v1.y() - v2.y(), v1.z() - v2.z());
+}
+
+SIMD_FORCE_INLINE SimdVector3
+operator-(const SimdVector3& v)
+{
+ return SimdVector3(-v.x(), -v.y(), -v.z());
+}
+
+SIMD_FORCE_INLINE SimdVector3
+operator*(const SimdVector3& v, const SimdScalar& s)
+{
+ return SimdVector3(v.x() * s, v.y() * s, v.z() * s);
+}
+
+SIMD_FORCE_INLINE SimdVector3
+operator*(const SimdScalar& s, const SimdVector3& v)
+{
+ return v * s;
+}
+
+SIMD_FORCE_INLINE SimdVector3
+operator/(const SimdVector3& v, const SimdScalar& s)
+{
+ assert(s != SimdScalar(0.0));
+ return v * (SimdScalar(1.0) / s);
+}
+
+SIMD_FORCE_INLINE SimdScalar
+dot(const SimdVector3& v1, const SimdVector3& v2)
+{
+ return v1.dot(v2);
+}
+
+
+
+SIMD_FORCE_INLINE SimdScalar
+distance2(const SimdVector3& v1, const SimdVector3& v2)
+{
+ return v1.distance2(v2);
+}
+
+
+SIMD_FORCE_INLINE SimdScalar
+distance(const SimdVector3& v1, const SimdVector3& v2)
+{
+ return v1.distance(v2);
+}
+
+SIMD_FORCE_INLINE SimdScalar
+angle(const SimdVector3& v1, const SimdVector3& v2)
+{
+ return v1.angle(v2);
+}
+
+SIMD_FORCE_INLINE SimdVector3
+cross(const SimdVector3& v1, const SimdVector3& v2)
+{
+ return v1.cross(v2);
+}
+
+SIMD_FORCE_INLINE SimdScalar
+triple(const SimdVector3& v1, const SimdVector3& v2, const SimdVector3& v3)
+{
+ return v1.triple(v2, v3);
+}
+
+SIMD_FORCE_INLINE SimdVector3
+lerp(const SimdVector3& v1, const SimdVector3& v2, const SimdScalar& t)
+{
+ return v1.lerp(v2, t);
+}
+
+
+SIMD_FORCE_INLINE bool operator==(const SimdVector3& p1, const SimdVector3& p2)
+{
+ return p1[0] == p2[0] && p1[1] == p2[1] && p1[2] == p2[2];
+}
+
+SIMD_FORCE_INLINE SimdScalar SimdVector3::distance2(const SimdVector3& v) const
+{
+ return (v - *this).length2();
+}
+
+SIMD_FORCE_INLINE SimdScalar SimdVector3::distance(const SimdVector3& v) const
+{
+ return (v - *this).length();
+}
+
+SIMD_FORCE_INLINE SimdVector3 SimdVector3::normalized() const
+{
+ return *this / length();
+}
+
+class SimdVector4 : public SimdVector3
+{
+public:
+
+ SIMD_FORCE_INLINE SimdVector4() {}
+
+
+ SIMD_FORCE_INLINE SimdVector4(const SimdScalar& x, const SimdScalar& y, const SimdScalar& z,const SimdScalar& w)
+ : SimdVector3(x,y,z)
+ {
+ m_unusedW = w;
+ }
+
+
+ SIMD_FORCE_INLINE SimdVector4 absolute4() const
+ {
+ return SimdVector4(
+ fabsf(m_x),
+ fabsf(m_y),
+ fabsf(m_z),
+ fabsf(m_unusedW));
+ }
+
+
+
+ float getW() const { return m_unusedW;}
+
+
+ SIMD_FORCE_INLINE int maxAxis4() const
+ {
+ int maxIndex = -1;
+ float maxVal = -1e30f;
+ if (m_x > maxVal)
+ {
+ maxIndex = 0;
+ maxVal = m_x;
+ }
+ if (m_y > maxVal)
+ {
+ maxIndex = 1;
+ maxVal = m_y;
+ }
+ if (m_z > maxVal)
+ {
+ maxIndex = 2;
+ maxVal = m_z;
+ }
+ if (m_unusedW > maxVal)
+ {
+ maxIndex = 3;
+ maxVal = m_unusedW;
+ }
+
+
+
+
+ return maxIndex;
+
+ }
+
+
+ SIMD_FORCE_INLINE int minAxis4() const
+ {
+ int minIndex = -1;
+ float minVal = 1e30f;
+ if (m_x < minVal)
+ {
+ minIndex = 0;
+ minVal = m_x;
+ }
+ if (m_y < minVal)
+ {
+ minIndex = 1;
+ minVal = m_y;
+ }
+ if (m_z < minVal)
+ {
+ minIndex = 2;
+ minVal = m_z;
+ }
+ if (m_unusedW < minVal)
+ {
+ minIndex = 3;
+ minVal = m_unusedW;
+ }
+
+ return minIndex;
+
+ }
+
+
+ SIMD_FORCE_INLINE int closestAxis4() const
+ {
+ return absolute4().maxAxis4();
+ }
+
+
+
+};
+
+#endif //SIMD__VECTOR3_H
diff --git a/extern/bullet/continuous.dsw b/extern/bullet/continuous.dsw
new file mode 100644
index 00000000000..2ad95b3af62
--- /dev/null
+++ b/extern/bullet/continuous.dsw
@@ -0,0 +1,239 @@
+Microsoft Developer Studio Workspace File, Format Version 6.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "Bullet"=.\Bullet\Bullet3.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Project: "BulletDynamics"=.\BulletDynamics\BulletDynamics.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Project: "CcdPhysics"=.\EXTRAS\PHYSICSINTERFACE\CcdPhysics\CcdPhysics.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Project: "CcdPhysicsDemo"=.\Demos\CcdPhysicsDemo\CcdPhysicsDemo.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+ Begin Project Dependency
+ Project_Dep_Name Bullet
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name BulletDynamics
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name OpenGL
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name CcdPhysics
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name PhysicsInterface
+ End Project Dependency
+}}}
+
+###############################################################################
+
+Project: "CollisionDemo"=.\Demos\CollisionDemo\CollisionDemo.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+ Begin Project Dependency
+ Project_Dep_Name Bullet
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name OpenGL
+ End Project Dependency
+}}}
+
+###############################################################################
+
+Project: "ConcaveDemo"=.\DEMOS\ConcaveDemo\ConcaveDemo.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+ Begin Project Dependency
+ Project_Dep_Name Bullet
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name BulletDynamics
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name CcdPhysics
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name OpenGL
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name PhysicsInterface
+ End Project Dependency
+}}}
+
+###############################################################################
+
+Project: "ContinuousConvexCollision"=.\Demos\ContinuousConvexCollision\ContinuousConvexCollision.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+ Begin Project Dependency
+ Project_Dep_Name Bullet
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name OpenGL
+ End Project Dependency
+}}}
+
+###############################################################################
+
+Project: "ConvexHullDistance"=.\DEMOS\ConvexHullDistance\ConvexHullDistance.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+ Begin Project Dependency
+ Project_Dep_Name Bullet
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name OpenGL
+ End Project Dependency
+}}}
+
+###############################################################################
+
+Project: "GjkConvexCastDemo"=.\Demos\GjkConvexCastDemo\GjkConvexCastDemo.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+ Begin Project Dependency
+ Project_Dep_Name Bullet
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name OpenGL
+ End Project Dependency
+}}}
+
+###############################################################################
+
+Project: "OpenGL"=.\Demos\OpenGL\OpenGL.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Project: "PhysicsInterface"=.\EXTRAS\PHYSICSINTERFACE\Common\PhysicsInterface.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Project: "Raytracer"=.\Demos\Raytracer\Raytracer.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+ Begin Project Dependency
+ Project_Dep_Name Bullet
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name OpenGL
+ End Project Dependency
+}}}
+
+###############################################################################
+
+Project: "SimplexDemo"=.\Demos\SimplexDemo\SimplexDemo.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+ Begin Project Dependency
+ Project_Dep_Name Bullet
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name OpenGL
+ End Project Dependency
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
diff --git a/extern/bullet/continuous_vc7.sln b/extern/bullet/continuous_vc7.sln
new file mode 100644
index 00000000000..015e91e2e11
--- /dev/null
+++ b/extern/bullet/continuous_vc7.sln
@@ -0,0 +1,140 @@
+Microsoft Visual Studio Solution File, Format Version 8.00
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "OpenGLSupport", "Demos\OpenGL\OpenGL_vc7.vcproj", "{47328C1E-54A4-4065-B3DA-F88EE281D1E5}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Bullet3ContinuousCollision", "Bullet\Bullet3_vc7.vcproj", "{FFD3C64A-30E2-4BC7-BC8F-51818C320400}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SimplexDemo", "Demos\SimplexDemo\SimplexDemo_vc7.vcproj", "{F6B9DD8D-8C40-4F2B-B492-56B167D01CC0}"
+ ProjectSection(ProjectDependencies) = postProject
+ {47328C1E-54A4-4065-B3DA-F88EE281D1E5} = {47328C1E-54A4-4065-B3DA-F88EE281D1E5}
+ {FFD3C64A-30E2-4BC7-BC8F-51818C320400} = {FFD3C64A-30E2-4BC7-BC8F-51818C320400}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CollisionDemo", "Demos\CollisionDemo\CollisionDemo_vc7.vcproj", "{F43EFC77-3CFA-4669-BAEA-1E2BC8ABA897}"
+ ProjectSection(ProjectDependencies) = postProject
+ {47328C1E-54A4-4065-B3DA-F88EE281D1E5} = {47328C1E-54A4-4065-B3DA-F88EE281D1E5}
+ {47328C1E-54A4-4065-B3DA-F88EE281D1E5} = {47328C1E-54A4-4065-B3DA-F88EE281D1E5}
+ {FFD3C64A-30E2-4BC7-BC8F-51818C320400} = {FFD3C64A-30E2-4BC7-BC8F-51818C320400}
+ {FFD3C64A-30E2-4BC7-BC8F-51818C320400} = {FFD3C64A-30E2-4BC7-BC8F-51818C320400}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "LinearConvexCastDemo", "Demos\GjkConvexCastDemo\GjkConvexCastDemo_vc7.vcproj", "{B395AFF6-94FE-4A2C-9E26-58E5BE85083C}"
+ ProjectSection(ProjectDependencies) = postProject
+ {47328C1E-54A4-4065-B3DA-F88EE281D1E5} = {47328C1E-54A4-4065-B3DA-F88EE281D1E5}
+ {FFD3C64A-30E2-4BC7-BC8F-51818C320400} = {FFD3C64A-30E2-4BC7-BC8F-51818C320400}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ContinuousConvexCollisionDemo", "Demos\ContinuousConvexCollision\ContinuousConvexCollision_vc7.vcproj", "{6A4E3433-D0CD-4A10-BE09-78C9A5F7508B}"
+ ProjectSection(ProjectDependencies) = postProject
+ {47328C1E-54A4-4065-B3DA-F88EE281D1E5} = {47328C1E-54A4-4065-B3DA-F88EE281D1E5}
+ {FFD3C64A-30E2-4BC7-BC8F-51818C320400} = {FFD3C64A-30E2-4BC7-BC8F-51818C320400}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Raytracer", "Demos\Raytracer\Raytracer_vc7.vcproj", "{F8B0A298-14C9-4006-8D53-51032892BEDD}"
+ ProjectSection(ProjectDependencies) = postProject
+ {47328C1E-54A4-4065-B3DA-F88EE281D1E5} = {47328C1E-54A4-4065-B3DA-F88EE281D1E5}
+ {FFD3C64A-30E2-4BC7-BC8F-51818C320400} = {FFD3C64A-30E2-4BC7-BC8F-51818C320400}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Bullet3Dynamics", "BulletDynamics\BulletDynamics_vc7.vcproj", "{3427A9EF-FF84-4B3E-9AE5-C37CF44D7DA4}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CcdPhysics", "Extras\PhysicsInterface\CcdPhysics\CcdPhysics_vc7.vcproj", "{E3D57F36-36AC-4E9A-B0E0-2AE4510FCBFE}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PhysicsInterfaceCommon", "Extras\PhysicsInterface\Common\PhysicsInterfaceCommon\PhysicsInterfaceCommon_vc7.vcproj", "{87D8C006-6DCC-4156-A03E-8CEA1B4C0580}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CcdPhysicsDemo", "Demos\CcdPhysicsDemo\CcdPhysicsDemo_vc7.vcproj", "{E9C93159-EC18-4121-9D73-1DE7053D81D7}"
+ ProjectSection(ProjectDependencies) = postProject
+ {87D8C006-6DCC-4156-A03E-8CEA1B4C0580} = {87D8C006-6DCC-4156-A03E-8CEA1B4C0580}
+ {47328C1E-54A4-4065-B3DA-F88EE281D1E5} = {47328C1E-54A4-4065-B3DA-F88EE281D1E5}
+ {E3D57F36-36AC-4E9A-B0E0-2AE4510FCBFE} = {E3D57F36-36AC-4E9A-B0E0-2AE4510FCBFE}
+ {FFD3C64A-30E2-4BC7-BC8F-51818C320400} = {FFD3C64A-30E2-4BC7-BC8F-51818C320400}
+ {3427A9EF-FF84-4B3E-9AE5-C37CF44D7DA4} = {3427A9EF-FF84-4B3E-9AE5-C37CF44D7DA4}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ConcaveDemo", "Demos\ConcaveDemo\ConcaveDemo.vcproj", "{F20F38CC-CFA7-40C7-81AE-945C8C09E473}"
+ ProjectSection(ProjectDependencies) = postProject
+ {87D8C006-6DCC-4156-A03E-8CEA1B4C0580} = {87D8C006-6DCC-4156-A03E-8CEA1B4C0580}
+ {47328C1E-54A4-4065-B3DA-F88EE281D1E5} = {47328C1E-54A4-4065-B3DA-F88EE281D1E5}
+ {E3D57F36-36AC-4E9A-B0E0-2AE4510FCBFE} = {E3D57F36-36AC-4E9A-B0E0-2AE4510FCBFE}
+ {FFD3C64A-30E2-4BC7-BC8F-51818C320400} = {FFD3C64A-30E2-4BC7-BC8F-51818C320400}
+ {3427A9EF-FF84-4B3E-9AE5-C37CF44D7DA4} = {3427A9EF-FF84-4B3E-9AE5-C37CF44D7DA4}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ConvexHullDistance", "Demos\ConvexHullDistance\ConvexHullDistance_vc7.vcproj", "{AF9E7C2B-BE49-4101-B056-4A628B276389}"
+ ProjectSection(ProjectDependencies) = postProject
+ {47328C1E-54A4-4065-B3DA-F88EE281D1E5} = {47328C1E-54A4-4065-B3DA-F88EE281D1E5}
+ EndProjectSection
+EndProject
+Global
+ GlobalSection(SolutionConfiguration) = preSolution
+ Debug = Debug
+ Release = Release
+ EndGlobalSection
+ GlobalSection(ProjectConfiguration) = postSolution
+ {47328C1E-54A4-4065-B3DA-F88EE281D1E5}.Debug.ActiveCfg = Debug|Win32
+ {47328C1E-54A4-4065-B3DA-F88EE281D1E5}.Debug.Build.0 = Debug|Win32
+ {47328C1E-54A4-4065-B3DA-F88EE281D1E5}.Release.ActiveCfg = Release|Win32
+ {47328C1E-54A4-4065-B3DA-F88EE281D1E5}.Release.Build.0 = Release|Win32
+ {FFD3C64A-30E2-4BC7-BC8F-51818C320400}.Debug.ActiveCfg = Debug|Win32
+ {FFD3C64A-30E2-4BC7-BC8F-51818C320400}.Debug.Build.0 = Debug|Win32
+ {FFD3C64A-30E2-4BC7-BC8F-51818C320400}.Release.ActiveCfg = Release|Win32
+ {FFD3C64A-30E2-4BC7-BC8F-51818C320400}.Release.Build.0 = Release|Win32
+ {F6B9DD8D-8C40-4F2B-B492-56B167D01CC0}.Debug.ActiveCfg = Debug|Win32
+ {F6B9DD8D-8C40-4F2B-B492-56B167D01CC0}.Debug.Build.0 = Debug|Win32
+ {F6B9DD8D-8C40-4F2B-B492-56B167D01CC0}.Release.ActiveCfg = Release|Win32
+ {F6B9DD8D-8C40-4F2B-B492-56B167D01CC0}.Release.Build.0 = Release|Win32
+ {F43EFC77-3CFA-4669-BAEA-1E2BC8ABA897}.Debug.ActiveCfg = Debug|Win32
+ {F43EFC77-3CFA-4669-BAEA-1E2BC8ABA897}.Debug.Build.0 = Debug|Win32
+ {F43EFC77-3CFA-4669-BAEA-1E2BC8ABA897}.Release.ActiveCfg = Release|Win32
+ {F43EFC77-3CFA-4669-BAEA-1E2BC8ABA897}.Release.Build.0 = Release|Win32
+ {B395AFF6-94FE-4A2C-9E26-58E5BE85083C}.Debug.ActiveCfg = Debug|Win32
+ {B395AFF6-94FE-4A2C-9E26-58E5BE85083C}.Debug.Build.0 = Debug|Win32
+ {B395AFF6-94FE-4A2C-9E26-58E5BE85083C}.Release.ActiveCfg = Release|Win32
+ {B395AFF6-94FE-4A2C-9E26-58E5BE85083C}.Release.Build.0 = Release|Win32
+ {6A4E3433-D0CD-4A10-BE09-78C9A5F7508B}.Debug.ActiveCfg = Debug|Win32
+ {6A4E3433-D0CD-4A10-BE09-78C9A5F7508B}.Debug.Build.0 = Debug|Win32
+ {6A4E3433-D0CD-4A10-BE09-78C9A5F7508B}.Release.ActiveCfg = Release|Win32
+ {6A4E3433-D0CD-4A10-BE09-78C9A5F7508B}.Release.Build.0 = Release|Win32
+ {F8B0A298-14C9-4006-8D53-51032892BEDD}.Debug.ActiveCfg = Debug|Win32
+ {F8B0A298-14C9-4006-8D53-51032892BEDD}.Debug.Build.0 = Debug|Win32
+ {F8B0A298-14C9-4006-8D53-51032892BEDD}.Release.ActiveCfg = Release|Win32
+ {F8B0A298-14C9-4006-8D53-51032892BEDD}.Release.Build.0 = Release|Win32
+ {3427A9EF-FF84-4B3E-9AE5-C37CF44D7DA4}.Debug.ActiveCfg = Debug|Win32
+ {3427A9EF-FF84-4B3E-9AE5-C37CF44D7DA4}.Debug.Build.0 = Debug|Win32
+ {3427A9EF-FF84-4B3E-9AE5-C37CF44D7DA4}.Release.ActiveCfg = Release|Win32
+ {3427A9EF-FF84-4B3E-9AE5-C37CF44D7DA4}.Release.Build.0 = Release|Win32
+ {E3D57F36-36AC-4E9A-B0E0-2AE4510FCBFE}.Debug.ActiveCfg = Debug|Win32
+ {E3D57F36-36AC-4E9A-B0E0-2AE4510FCBFE}.Debug.Build.0 = Debug|Win32
+ {E3D57F36-36AC-4E9A-B0E0-2AE4510FCBFE}.Release.ActiveCfg = Release|Win32
+ {E3D57F36-36AC-4E9A-B0E0-2AE4510FCBFE}.Release.Build.0 = Release|Win32
+ {87D8C006-6DCC-4156-A03E-8CEA1B4C0580}.Debug.ActiveCfg = Debug|Win32
+ {87D8C006-6DCC-4156-A03E-8CEA1B4C0580}.Debug.Build.0 = Debug|Win32
+ {87D8C006-6DCC-4156-A03E-8CEA1B4C0580}.Release.ActiveCfg = Release|Win32
+ {87D8C006-6DCC-4156-A03E-8CEA1B4C0580}.Release.Build.0 = Release|Win32
+ {E9C93159-EC18-4121-9D73-1DE7053D81D7}.Debug.ActiveCfg = Debug|Win32
+ {E9C93159-EC18-4121-9D73-1DE7053D81D7}.Debug.Build.0 = Debug|Win32
+ {E9C93159-EC18-4121-9D73-1DE7053D81D7}.Release.ActiveCfg = Release|Win32
+ {E9C93159-EC18-4121-9D73-1DE7053D81D7}.Release.Build.0 = Release|Win32
+ {F20F38CC-CFA7-40C7-81AE-945C8C09E473}.Debug.ActiveCfg = Debug|Win32
+ {F20F38CC-CFA7-40C7-81AE-945C8C09E473}.Debug.Build.0 = Debug|Win32
+ {F20F38CC-CFA7-40C7-81AE-945C8C09E473}.Release.ActiveCfg = Release|Win32
+ {F20F38CC-CFA7-40C7-81AE-945C8C09E473}.Release.Build.0 = Release|Win32
+ {AF9E7C2B-BE49-4101-B056-4A628B276389}.Debug.ActiveCfg = Debug|Win32
+ {AF9E7C2B-BE49-4101-B056-4A628B276389}.Debug.Build.0 = Debug|Win32
+ {AF9E7C2B-BE49-4101-B056-4A628B276389}.Release.ActiveCfg = Release|Win32
+ {AF9E7C2B-BE49-4101-B056-4A628B276389}.Release.Build.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ EndGlobalSection
+ GlobalSection(ExtensibilityAddIns) = postSolution
+ EndGlobalSection
+EndGlobal
diff --git a/extern/bullet/continuous_vc8.sln b/extern/bullet/continuous_vc8.sln
new file mode 100644
index 00000000000..38a29f14627
--- /dev/null
+++ b/extern/bullet/continuous_vc8.sln
@@ -0,0 +1,129 @@
+Microsoft Visual Studio Solution File, Format Version 9.00
+# Visual Studio 2005
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "OpenGLSupport", "Demos\OpenGL\OpenGL_vc8.vcproj", "{47328C1E-54A4-4065-B3DA-F88EE281D1E5}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Bullet3ContinuousCollision", "Bullet\Bullet3_vc8.vcproj", "{FFD3C64A-30E2-4BC7-BC8F-51818C320400}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SimplexDemo", "Demos\SimplexDemo\SimplexDemo_vc8.vcproj", "{F6B9DD8D-8C40-4F2B-B492-56B167D01CC0}"
+ ProjectSection(ProjectDependencies) = postProject
+ {FFD3C64A-30E2-4BC7-BC8F-51818C320400} = {FFD3C64A-30E2-4BC7-BC8F-51818C320400}
+ {47328C1E-54A4-4065-B3DA-F88EE281D1E5} = {47328C1E-54A4-4065-B3DA-F88EE281D1E5}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CollisionDemo", "Demos\CollisionDemo\CollisionDemo_vc8.vcproj", "{F43EFC77-3CFA-4669-BAEA-1E2BC8ABA897}"
+ ProjectSection(ProjectDependencies) = postProject
+ {FFD3C64A-30E2-4BC7-BC8F-51818C320400} = {FFD3C64A-30E2-4BC7-BC8F-51818C320400}
+ {47328C1E-54A4-4065-B3DA-F88EE281D1E5} = {47328C1E-54A4-4065-B3DA-F88EE281D1E5}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "LinearConvexCastDemo", "Demos\GjkConvexCastDemo\GjkConvexCastDemo_vc8.vcproj", "{B395AFF6-94FE-4A2C-9E26-58E5BE85083C}"
+ ProjectSection(ProjectDependencies) = postProject
+ {FFD3C64A-30E2-4BC7-BC8F-51818C320400} = {FFD3C64A-30E2-4BC7-BC8F-51818C320400}
+ {47328C1E-54A4-4065-B3DA-F88EE281D1E5} = {47328C1E-54A4-4065-B3DA-F88EE281D1E5}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ContinuousConvexCollisionDemo", "Demos\ContinuousConvexCollision\ContinuousConvexCollision_vc8.vcproj", "{6A4E3433-D0CD-4A10-BE09-78C9A5F7508B}"
+ ProjectSection(ProjectDependencies) = postProject
+ {FFD3C64A-30E2-4BC7-BC8F-51818C320400} = {FFD3C64A-30E2-4BC7-BC8F-51818C320400}
+ {47328C1E-54A4-4065-B3DA-F88EE281D1E5} = {47328C1E-54A4-4065-B3DA-F88EE281D1E5}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Raytracer", "Demos\Raytracer\Raytracer_vc8.vcproj", "{F8B0A298-14C9-4006-8D53-51032892BEDD}"
+ ProjectSection(ProjectDependencies) = postProject
+ {FFD3C64A-30E2-4BC7-BC8F-51818C320400} = {FFD3C64A-30E2-4BC7-BC8F-51818C320400}
+ {47328C1E-54A4-4065-B3DA-F88EE281D1E5} = {47328C1E-54A4-4065-B3DA-F88EE281D1E5}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Bullet3Dynamics", "BulletDynamics\BulletDynamics_vc8.vcproj", "{3427A9EF-FF84-4B3E-9AE5-C37CF44D7DA4}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CcdPhysicsDemo", "Demos\CcdPhysicsDemo\CcdPhysicsDemo_vc8.vcproj", "{E9C93159-EC18-4121-9D73-1DE7053D81D7}"
+ ProjectSection(ProjectDependencies) = postProject
+ {3427A9EF-FF84-4B3E-9AE5-C37CF44D7DA4} = {3427A9EF-FF84-4B3E-9AE5-C37CF44D7DA4}
+ {FFD3C64A-30E2-4BC7-BC8F-51818C320400} = {FFD3C64A-30E2-4BC7-BC8F-51818C320400}
+ {E3D57F36-36AC-4E9A-B0E0-2AE4510FCBFE} = {E3D57F36-36AC-4E9A-B0E0-2AE4510FCBFE}
+ {47328C1E-54A4-4065-B3DA-F88EE281D1E5} = {47328C1E-54A4-4065-B3DA-F88EE281D1E5}
+ {87D8C006-6DCC-4156-A03E-8CEA1B4C0580} = {87D8C006-6DCC-4156-A03E-8CEA1B4C0580}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CcdPhysics", "Extras\PhysicsInterface\CcdPhysics\CcdPhysics_vc8.vcproj", "{E3D57F36-36AC-4E9A-B0E0-2AE4510FCBFE}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PhysicsInterfaceCommon", "Extras\PhysicsInterface\Common\PhysicsInterfaceCommon\PhysicsInterfaceCommon_vc8.vcproj", "{87D8C006-6DCC-4156-A03E-8CEA1B4C0580}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ConvexHullDistance", "Demos\ConvexHullDistance\ConvexHullDistance_vc8.vcproj", "{39A0C0E0-773B-498D-B9B1-B54525FB6223}"
+ ProjectSection(ProjectDependencies) = postProject
+ {FFD3C64A-30E2-4BC7-BC8F-51818C320400} = {FFD3C64A-30E2-4BC7-BC8F-51818C320400}
+ {47328C1E-54A4-4065-B3DA-F88EE281D1E5} = {47328C1E-54A4-4065-B3DA-F88EE281D1E5}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ConcaveDemo", "Demos\ConcaveDemo\ConcaveDemo_vc8.vcproj", "{F20F38CC-CFA7-40C7-81AE-945C8C09E473}"
+ ProjectSection(ProjectDependencies) = postProject
+ {87D8C006-6DCC-4156-A03E-8CEA1B4C0580} = {87D8C006-6DCC-4156-A03E-8CEA1B4C0580}
+ {47328C1E-54A4-4065-B3DA-F88EE281D1E5} = {47328C1E-54A4-4065-B3DA-F88EE281D1E5}
+ {E3D57F36-36AC-4E9A-B0E0-2AE4510FCBFE} = {E3D57F36-36AC-4E9A-B0E0-2AE4510FCBFE}
+ {FFD3C64A-30E2-4BC7-BC8F-51818C320400} = {FFD3C64A-30E2-4BC7-BC8F-51818C320400}
+ {3427A9EF-FF84-4B3E-9AE5-C37CF44D7DA4} = {3427A9EF-FF84-4B3E-9AE5-C37CF44D7DA4}
+ EndProjectSection
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Win32 = Debug|Win32
+ Release|Win32 = Release|Win32
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {47328C1E-54A4-4065-B3DA-F88EE281D1E5}.Debug|Win32.ActiveCfg = Debug|Win32
+ {47328C1E-54A4-4065-B3DA-F88EE281D1E5}.Debug|Win32.Build.0 = Debug|Win32
+ {47328C1E-54A4-4065-B3DA-F88EE281D1E5}.Release|Win32.ActiveCfg = Release|Win32
+ {47328C1E-54A4-4065-B3DA-F88EE281D1E5}.Release|Win32.Build.0 = Release|Win32
+ {FFD3C64A-30E2-4BC7-BC8F-51818C320400}.Debug|Win32.ActiveCfg = Debug|Win32
+ {FFD3C64A-30E2-4BC7-BC8F-51818C320400}.Debug|Win32.Build.0 = Debug|Win32
+ {FFD3C64A-30E2-4BC7-BC8F-51818C320400}.Release|Win32.ActiveCfg = Release|Win32
+ {FFD3C64A-30E2-4BC7-BC8F-51818C320400}.Release|Win32.Build.0 = Release|Win32
+ {F6B9DD8D-8C40-4F2B-B492-56B167D01CC0}.Debug|Win32.ActiveCfg = Debug|Win32
+ {F6B9DD8D-8C40-4F2B-B492-56B167D01CC0}.Debug|Win32.Build.0 = Debug|Win32
+ {F6B9DD8D-8C40-4F2B-B492-56B167D01CC0}.Release|Win32.ActiveCfg = Release|Win32
+ {F6B9DD8D-8C40-4F2B-B492-56B167D01CC0}.Release|Win32.Build.0 = Release|Win32
+ {F43EFC77-3CFA-4669-BAEA-1E2BC8ABA897}.Debug|Win32.ActiveCfg = Debug|Win32
+ {F43EFC77-3CFA-4669-BAEA-1E2BC8ABA897}.Debug|Win32.Build.0 = Debug|Win32
+ {F43EFC77-3CFA-4669-BAEA-1E2BC8ABA897}.Release|Win32.ActiveCfg = Release|Win32
+ {F43EFC77-3CFA-4669-BAEA-1E2BC8ABA897}.Release|Win32.Build.0 = Release|Win32
+ {B395AFF6-94FE-4A2C-9E26-58E5BE85083C}.Debug|Win32.ActiveCfg = Debug|Win32
+ {B395AFF6-94FE-4A2C-9E26-58E5BE85083C}.Debug|Win32.Build.0 = Debug|Win32
+ {B395AFF6-94FE-4A2C-9E26-58E5BE85083C}.Release|Win32.ActiveCfg = Release|Win32
+ {B395AFF6-94FE-4A2C-9E26-58E5BE85083C}.Release|Win32.Build.0 = Release|Win32
+ {6A4E3433-D0CD-4A10-BE09-78C9A5F7508B}.Debug|Win32.ActiveCfg = Debug|Win32
+ {6A4E3433-D0CD-4A10-BE09-78C9A5F7508B}.Debug|Win32.Build.0 = Debug|Win32
+ {6A4E3433-D0CD-4A10-BE09-78C9A5F7508B}.Release|Win32.ActiveCfg = Release|Win32
+ {6A4E3433-D0CD-4A10-BE09-78C9A5F7508B}.Release|Win32.Build.0 = Release|Win32
+ {F8B0A298-14C9-4006-8D53-51032892BEDD}.Debug|Win32.ActiveCfg = Debug|Win32
+ {F8B0A298-14C9-4006-8D53-51032892BEDD}.Debug|Win32.Build.0 = Debug|Win32
+ {F8B0A298-14C9-4006-8D53-51032892BEDD}.Release|Win32.ActiveCfg = Release|Win32
+ {F8B0A298-14C9-4006-8D53-51032892BEDD}.Release|Win32.Build.0 = Release|Win32
+ {3427A9EF-FF84-4B3E-9AE5-C37CF44D7DA4}.Debug|Win32.ActiveCfg = Debug|Win32
+ {3427A9EF-FF84-4B3E-9AE5-C37CF44D7DA4}.Debug|Win32.Build.0 = Debug|Win32
+ {3427A9EF-FF84-4B3E-9AE5-C37CF44D7DA4}.Release|Win32.ActiveCfg = Release|Win32
+ {3427A9EF-FF84-4B3E-9AE5-C37CF44D7DA4}.Release|Win32.Build.0 = Release|Win32
+ {E9C93159-EC18-4121-9D73-1DE7053D81D7}.Debug|Win32.ActiveCfg = Debug|Win32
+ {E9C93159-EC18-4121-9D73-1DE7053D81D7}.Debug|Win32.Build.0 = Debug|Win32
+ {E9C93159-EC18-4121-9D73-1DE7053D81D7}.Release|Win32.ActiveCfg = Release|Win32
+ {E9C93159-EC18-4121-9D73-1DE7053D81D7}.Release|Win32.Build.0 = Release|Win32
+ {E3D57F36-36AC-4E9A-B0E0-2AE4510FCBFE}.Debug|Win32.ActiveCfg = Debug|Win32
+ {E3D57F36-36AC-4E9A-B0E0-2AE4510FCBFE}.Debug|Win32.Build.0 = Debug|Win32
+ {E3D57F36-36AC-4E9A-B0E0-2AE4510FCBFE}.Release|Win32.ActiveCfg = Release|Win32
+ {E3D57F36-36AC-4E9A-B0E0-2AE4510FCBFE}.Release|Win32.Build.0 = Release|Win32
+ {87D8C006-6DCC-4156-A03E-8CEA1B4C0580}.Debug|Win32.ActiveCfg = Debug|Win32
+ {87D8C006-6DCC-4156-A03E-8CEA1B4C0580}.Debug|Win32.Build.0 = Debug|Win32
+ {87D8C006-6DCC-4156-A03E-8CEA1B4C0580}.Release|Win32.ActiveCfg = Release|Win32
+ {87D8C006-6DCC-4156-A03E-8CEA1B4C0580}.Release|Win32.Build.0 = Release|Win32
+ {39A0C0E0-773B-498D-B9B1-B54525FB6223}.Debug|Win32.ActiveCfg = Debug|Win32
+ {39A0C0E0-773B-498D-B9B1-B54525FB6223}.Debug|Win32.Build.0 = Debug|Win32
+ {39A0C0E0-773B-498D-B9B1-B54525FB6223}.Release|Win32.ActiveCfg = Release|Win32
+ {39A0C0E0-773B-498D-B9B1-B54525FB6223}.Release|Win32.Build.0 = Release|Win32
+ {F20F38CC-CFA7-40C7-81AE-945C8C09E473}.Debug|Win32.ActiveCfg = Debug|Win32
+ {F20F38CC-CFA7-40C7-81AE-945C8C09E473}.Debug|Win32.Build.0 = Debug|Win32
+ {F20F38CC-CFA7-40C7-81AE-945C8C09E473}.Release|Win32.ActiveCfg = Release|Win32
+ {F20F38CC-CFA7-40C7-81AE-945C8C09E473}.Release|Win32.Build.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal