Browse Source

Merge pull request #29418 from AndreaCatania/upbul

Updated Bullet version to the actual bullet master commit
Rémi Verschelde 6 years ago
parent
commit
c499f1475f
52 changed files with 1334 additions and 389 deletions
  1. 5 1
      modules/bullet/SCsub
  2. 3 3
      platform/server/detect.py
  3. 3 3
      platform/x11/detect.py
  4. 1 1
      thirdparty/README.md
  5. 4 1
      thirdparty/bullet/Bullet3Common/b3Quaternion.h
  6. 1 1
      thirdparty/bullet/Bullet3Common/b3Vector3.h
  7. 3 2
      thirdparty/bullet/BulletCollision/BroadphaseCollision/btDbvt.cpp
  8. 2 2
      thirdparty/bullet/BulletCollision/BroadphaseCollision/btSimpleBroadphase.cpp
  9. 1 0
      thirdparty/bullet/BulletCollision/CollisionDispatch/btCollisionObject.cpp
  10. 12 0
      thirdparty/bullet/BulletCollision/CollisionDispatch/btCollisionObject.h
  11. 8 6
      thirdparty/bullet/BulletCollision/CollisionDispatch/btCollisionWorld.cpp
  12. 3 3
      thirdparty/bullet/BulletCollision/CollisionShapes/btConvexPolyhedron.cpp
  13. 128 78
      thirdparty/bullet/BulletCollision/CollisionShapes/btHeightfieldTerrainShape.cpp
  14. 18 9
      thirdparty/bullet/BulletCollision/CollisionShapes/btHeightfieldTerrainShape.h
  15. 1 22
      thirdparty/bullet/BulletCollision/Gimpact/btGImpactBvhStructs.h
  16. 13 3
      thirdparty/bullet/BulletCollision/Gimpact/btGImpactCollisionAlgorithm.cpp
  17. 1 1
      thirdparty/bullet/BulletCollision/Gimpact/btGImpactShape.h
  18. 1 22
      thirdparty/bullet/BulletCollision/Gimpact/gim_box_set.h
  19. 28 0
      thirdparty/bullet/BulletCollision/Gimpact/gim_pair.h
  20. 6 6
      thirdparty/bullet/BulletCollision/NarrowPhaseCollision/btConvexCast.h
  21. 1 1
      thirdparty/bullet/BulletCollision/NarrowPhaseCollision/btGjkPairDetector.cpp
  22. 1 0
      thirdparty/bullet/BulletCollision/NarrowPhaseCollision/btRaycastCallback.h
  23. 3 1
      thirdparty/bullet/BulletDynamics/ConstraintSolver/btBatchedConstraints.cpp
  24. 3 2
      thirdparty/bullet/BulletDynamics/ConstraintSolver/btConeTwistConstraint.cpp
  25. 1 0
      thirdparty/bullet/BulletDynamics/ConstraintSolver/btConstraintSolver.h
  26. 2 0
      thirdparty/bullet/BulletDynamics/ConstraintSolver/btContactSolverInfo.h
  27. 7 6
      thirdparty/bullet/BulletDynamics/ConstraintSolver/btGeneric6DofSpring2Constraint.cpp
  28. 1 1
      thirdparty/bullet/BulletDynamics/ConstraintSolver/btGeneric6DofSpring2Constraint.h
  29. 551 129
      thirdparty/bullet/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.cpp
  30. 147 17
      thirdparty/bullet/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.h
  31. 2 2
      thirdparty/bullet/BulletDynamics/Dynamics/btSimulationIslandManagerMt.cpp
  32. 11 4
      thirdparty/bullet/BulletDynamics/Featherstone/btMultiBody.cpp
  33. 33 12
      thirdparty/bullet/BulletDynamics/Featherstone/btMultiBody.h
  34. 78 8
      thirdparty/bullet/BulletDynamics/Featherstone/btMultiBodyConstraintSolver.cpp
  35. 5 0
      thirdparty/bullet/BulletDynamics/Featherstone/btMultiBodyConstraintSolver.h
  36. 30 7
      thirdparty/bullet/BulletDynamics/Featherstone/btMultiBodyDynamicsWorld.cpp
  37. 2 0
      thirdparty/bullet/BulletDynamics/Featherstone/btMultiBodyDynamicsWorld.h
  38. 4 0
      thirdparty/bullet/BulletDynamics/Featherstone/btMultiBodyLinkCollider.h
  39. 6 6
      thirdparty/bullet/BulletDynamics/Featherstone/btMultiBodyMLCPConstraintSolver.cpp
  40. 1 1
      thirdparty/bullet/BulletDynamics/Featherstone/btMultiBodyMLCPConstraintSolver.h
  41. 3 3
      thirdparty/bullet/BulletDynamics/MLCPSolvers/btLemkeSolver.h
  42. 1 1
      thirdparty/bullet/BulletInverseDynamics/MultiBodyTree.cpp
  43. 30 3
      thirdparty/bullet/BulletInverseDynamics/details/MultiBodyTreeImpl.cpp
  44. 2 2
      thirdparty/bullet/BulletSoftBody/btSoftBody.cpp
  45. 3 3
      thirdparty/bullet/LinearMath/TaskScheduler/btThreadSupportPosix.cpp
  46. 4 11
      thirdparty/bullet/LinearMath/btAlignedObjectArray.h
  47. 5 2
      thirdparty/bullet/LinearMath/btMatrixX.h
  48. 2 2
      thirdparty/bullet/LinearMath/btScalar.h
  49. 1 1
      thirdparty/bullet/LinearMath/btVector3.h
  50. 96 0
      thirdparty/bullet/btBulletCollisionAll.cpp
  51. 42 0
      thirdparty/bullet/btBulletDynamicsAll.cpp
  52. 14 0
      thirdparty/bullet/btLinearMathAll.cpp

+ 5 - 1
modules/bullet/SCsub

@@ -186,7 +186,11 @@ if env['builtin_bullet']:
 
 
     thirdparty_sources = [thirdparty_dir + file for file in bullet2_src]
     thirdparty_sources = [thirdparty_dir + file for file in bullet2_src]
 
 
-    env_bullet.Prepend(CPPPATH=[thirdparty_dir])
+    # Treat Bullet headers as system headers to avoid raising warnings. Not supported on MSVC.
+    if not env.msvc:
+        env_bullet.Append(CPPFLAGS=['-isystem', Dir(thirdparty_dir).path])
+    else:
+        env_bullet.Prepend(CPPPATH=[thirdparty_dir])
     # if env['target'] == "debug" or env['target'] == "release_debug":
     # if env['target'] == "debug" or env['target'] == "release_debug":
     #     env_bullet.Append(CPPFLAGS=['-DBT_DEBUG'])
     #     env_bullet.Append(CPPFLAGS=['-DBT_DEBUG'])
 
 

+ 3 - 3
platform/server/detect.py

@@ -145,12 +145,12 @@ def configure(env):
         env.ParseConfig('pkg-config libpng --cflags --libs')
         env.ParseConfig('pkg-config libpng --cflags --libs')
 
 
     if not env['builtin_bullet']:
     if not env['builtin_bullet']:
-        # We need at least version 2.88
+        # We need at least version 2.89
         import subprocess
         import subprocess
         bullet_version = subprocess.check_output(['pkg-config', 'bullet', '--modversion']).strip()
         bullet_version = subprocess.check_output(['pkg-config', 'bullet', '--modversion']).strip()
-        if str(bullet_version) < "2.88":
+        if str(bullet_version) < "2.89":
             # Abort as system bullet was requested but too old
             # Abort as system bullet was requested but too old
-            print("Bullet: System version {0} does not match minimal requirements ({1}). Aborting.".format(bullet_version, "2.88"))
+            print("Bullet: System version {0} does not match minimal requirements ({1}). Aborting.".format(bullet_version, "2.89"))
             sys.exit(255)
             sys.exit(255)
         env.ParseConfig('pkg-config bullet --cflags --libs')
         env.ParseConfig('pkg-config bullet --cflags --libs')
 
 

+ 3 - 3
platform/x11/detect.py

@@ -219,12 +219,12 @@ def configure(env):
         env.ParseConfig('pkg-config libpng --cflags --libs')
         env.ParseConfig('pkg-config libpng --cflags --libs')
 
 
     if not env['builtin_bullet']:
     if not env['builtin_bullet']:
-        # We need at least version 2.88
+        # We need at least version 2.89
         import subprocess
         import subprocess
         bullet_version = subprocess.check_output(['pkg-config', 'bullet', '--modversion']).strip()
         bullet_version = subprocess.check_output(['pkg-config', 'bullet', '--modversion']).strip()
-        if str(bullet_version) < "2.88":
+        if str(bullet_version) < "2.89":
             # Abort as system bullet was requested but too old
             # Abort as system bullet was requested but too old
-            print("Bullet: System version {0} does not match minimal requirements ({1}). Aborting.".format(bullet_version, "2.88"))
+            print("Bullet: System version {0} does not match minimal requirements ({1}). Aborting.".format(bullet_version, "2.89"))
             sys.exit(255)
             sys.exit(255)
         env.ParseConfig('pkg-config bullet --cflags --libs')
         env.ParseConfig('pkg-config bullet --cflags --libs')
 
 

+ 1 - 1
thirdparty/README.md

@@ -26,7 +26,7 @@ comments.
 ## bullet
 ## bullet
 
 
 - Upstream: https://github.com/bulletphysics/bullet3
 - Upstream: https://github.com/bulletphysics/bullet3
-- Version: 2.88
+- Version: git (5ec8339, 2019)
 - License: zlib
 - License: zlib
 
 
 Files extracted from upstream source:
 Files extracted from upstream source:

+ 4 - 1
thirdparty/bullet/Bullet3Common/b3Quaternion.h

@@ -92,8 +92,11 @@ public:
 	/**@brief Set the rotation using axis angle notation 
 	/**@brief Set the rotation using axis angle notation 
    * @param axis The axis around which to rotate
    * @param axis The axis around which to rotate
    * @param angle The magnitude of the rotation in Radians */
    * @param angle The magnitude of the rotation in Radians */
-	void setRotation(const b3Vector3& axis, const b3Scalar& _angle)
+	void setRotation(const b3Vector3& axis1, const b3Scalar& _angle)
 	{
 	{
+		b3Vector3 axis = axis1;
+		axis.safeNormalize();
+		
 		b3Scalar d = axis.length();
 		b3Scalar d = axis.length();
 		b3Assert(d != b3Scalar(0.0));
 		b3Assert(d != b3Scalar(0.0));
 		if (d < B3_EPSILON)
 		if (d < B3_EPSILON)

+ 1 - 1
thirdparty/bullet/Bullet3Common/b3Vector3.h

@@ -36,7 +36,7 @@ subject to the following restrictions:
 #pragma warning(disable : 4556)  // value of intrinsic immediate argument '4294967239' is out of range '0 - 255'
 #pragma warning(disable : 4556)  // value of intrinsic immediate argument '4294967239' is out of range '0 - 255'
 #endif
 #endif
 
 
-#define B3_SHUFFLE(x, y, z, w) ((w) << 6 | (z) << 4 | (y) << 2 | (x))
+#define B3_SHUFFLE(x, y, z, w) (((w) << 6 | (z) << 4 | (y) << 2 | (x)) & 0xff)
 //#define b3_pshufd_ps( _a, _mask ) (__m128) _mm_shuffle_epi32((__m128i)(_a), (_mask) )
 //#define b3_pshufd_ps( _a, _mask ) (__m128) _mm_shuffle_epi32((__m128i)(_a), (_mask) )
 #define b3_pshufd_ps(_a, _mask) _mm_shuffle_ps((_a), (_a), (_mask))
 #define b3_pshufd_ps(_a, _mask) _mm_shuffle_ps((_a), (_a), (_mask))
 #define b3_splat3_ps(_a, _i) b3_pshufd_ps((_a), B3_SHUFFLE(_i, _i, _i, 3))
 #define b3_splat3_ps(_a, _i) b3_pshufd_ps((_a), B3_SHUFFLE(_i, _i, _i, 3))

+ 3 - 2
thirdparty/bullet/BulletCollision/BroadphaseCollision/btDbvt.cpp

@@ -37,7 +37,7 @@ static DBVT_INLINE int indexof(const btDbvtNode* node)
 static DBVT_INLINE btDbvtVolume merge(const btDbvtVolume& a,
 static DBVT_INLINE btDbvtVolume merge(const btDbvtVolume& a,
 									  const btDbvtVolume& b)
 									  const btDbvtVolume& b)
 {
 {
-#if (DBVT_MERGE_IMPL == DBVT_IMPL_SSE)
+#ifdef BT_USE_SSE
 	ATTRIBUTE_ALIGNED16(char locals[sizeof(btDbvtAabbMm)]);
 	ATTRIBUTE_ALIGNED16(char locals[sizeof(btDbvtAabbMm)]);
 	btDbvtVolume* ptr = (btDbvtVolume*)locals;
 	btDbvtVolume* ptr = (btDbvtVolume*)locals;
 	btDbvtVolume& res = *ptr;
 	btDbvtVolume& res = *ptr;
@@ -80,6 +80,7 @@ static DBVT_INLINE void deletenode(btDbvt* pdbvt,
 static void recursedeletenode(btDbvt* pdbvt,
 static void recursedeletenode(btDbvt* pdbvt,
 							  btDbvtNode* node)
 							  btDbvtNode* node)
 {
 {
+	if (node == 0) return;
 	if (!node->isleaf())
 	if (!node->isleaf())
 	{
 	{
 		recursedeletenode(pdbvt, node->childs[0]);
 		recursedeletenode(pdbvt, node->childs[0]);
@@ -298,7 +299,7 @@ static int split(btDbvtNode** leaves,
 static btDbvtVolume bounds(btDbvtNode** leaves,
 static btDbvtVolume bounds(btDbvtNode** leaves,
 						   int count)
 						   int count)
 {
 {
-#if DBVT_MERGE_IMPL == DBVT_IMPL_SSE
+#ifdef BT_USE_SSE
 	ATTRIBUTE_ALIGNED16(char locals[sizeof(btDbvtVolume)]);
 	ATTRIBUTE_ALIGNED16(char locals[sizeof(btDbvtVolume)]);
 	btDbvtVolume* ptr = (btDbvtVolume*)locals;
 	btDbvtVolume* ptr = (btDbvtVolume*)locals;
 	btDbvtVolume& volume = *ptr;
 	btDbvtVolume& volume = *ptr;

+ 2 - 2
thirdparty/bullet/BulletCollision/BroadphaseCollision/btSimpleBroadphase.cpp

@@ -123,11 +123,11 @@ protected:
 
 
 void btSimpleBroadphase::destroyProxy(btBroadphaseProxy* proxyOrg, btDispatcher* dispatcher)
 void btSimpleBroadphase::destroyProxy(btBroadphaseProxy* proxyOrg, btDispatcher* dispatcher)
 {
 {
+	m_pairCache->removeOverlappingPairsContainingProxy(proxyOrg, dispatcher);
+
 	btSimpleBroadphaseProxy* proxy0 = static_cast<btSimpleBroadphaseProxy*>(proxyOrg);
 	btSimpleBroadphaseProxy* proxy0 = static_cast<btSimpleBroadphaseProxy*>(proxyOrg);
 	freeHandle(proxy0);
 	freeHandle(proxy0);
 
 
-	m_pairCache->removeOverlappingPairsContainingProxy(proxyOrg, dispatcher);
-
 	//validate();
 	//validate();
 }
 }
 
 

+ 1 - 0
thirdparty/bullet/BulletCollision/CollisionDispatch/btCollisionObject.cpp

@@ -43,6 +43,7 @@ btCollisionObject::btCollisionObject()
 	  m_userObjectPointer(0),
 	  m_userObjectPointer(0),
 	  m_userIndex2(-1),
 	  m_userIndex2(-1),
 	  m_userIndex(-1),
 	  m_userIndex(-1),
+	  m_userIndex3(-1),
 	  m_hitFraction(btScalar(1.)),
 	  m_hitFraction(btScalar(1.)),
 	  m_ccdSweptSphereRadius(btScalar(0.)),
 	  m_ccdSweptSphereRadius(btScalar(0.)),
 	  m_ccdMotionThreshold(btScalar(0.)),
 	  m_ccdMotionThreshold(btScalar(0.)),

+ 12 - 0
thirdparty/bullet/BulletCollision/CollisionDispatch/btCollisionObject.h

@@ -101,6 +101,8 @@ protected:
 
 
 	int m_userIndex;
 	int m_userIndex;
 
 
+	int m_userIndex3;
+
 	///time of impact calculation
 	///time of impact calculation
 	btScalar m_hitFraction;
 	btScalar m_hitFraction;
 
 
@@ -526,6 +528,11 @@ public:
 		return m_userIndex2;
 		return m_userIndex2;
 	}
 	}
 
 
+	int getUserIndex3() const
+	{
+		return m_userIndex3;
+	}
+
 	///users can point to their objects, userPointer is not used by Bullet
 	///users can point to their objects, userPointer is not used by Bullet
 	void setUserPointer(void* userPointer)
 	void setUserPointer(void* userPointer)
 	{
 	{
@@ -543,6 +550,11 @@ public:
 		m_userIndex2 = index;
 		m_userIndex2 = index;
 	}
 	}
 
 
+	void setUserIndex3(int index)
+	{
+		m_userIndex3 = index;
+	}
+
 	int getUpdateRevisionInternal() const
 	int getUpdateRevisionInternal() const
 	{
 	{
 		return m_updateRevision;
 		return m_updateRevision;

+ 8 - 6
thirdparty/bullet/BulletCollision/CollisionDispatch/btCollisionWorld.cpp

@@ -19,10 +19,10 @@ subject to the following restrictions:
 #include "BulletCollision/CollisionShapes/btCollisionShape.h"
 #include "BulletCollision/CollisionShapes/btCollisionShape.h"
 #include "BulletCollision/CollisionShapes/btConvexShape.h"
 #include "BulletCollision/CollisionShapes/btConvexShape.h"
 #include "BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.h"
 #include "BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.h"
-#include "BulletCollision/CollisionShapes/btSphereShape.h" //for raycasting
-#include "BulletCollision/CollisionShapes/btBvhTriangleMeshShape.h" //for raycasting
-#include "BulletCollision/CollisionShapes/btScaledBvhTriangleMeshShape.h" //for raycasting
-#include "BulletCollision/CollisionShapes/btHeightfieldTerrainShape.h" //for raycasting
+#include "BulletCollision/CollisionShapes/btSphereShape.h"                 //for raycasting
+#include "BulletCollision/CollisionShapes/btBvhTriangleMeshShape.h"        //for raycasting
+#include "BulletCollision/CollisionShapes/btScaledBvhTriangleMeshShape.h"  //for raycasting
+#include "BulletCollision/CollisionShapes/btHeightfieldTerrainShape.h"     //for raycasting
 #include "BulletCollision/NarrowPhaseCollision/btRaycastCallback.h"
 #include "BulletCollision/NarrowPhaseCollision/btRaycastCallback.h"
 #include "BulletCollision/CollisionShapes/btCompoundShape.h"
 #include "BulletCollision/CollisionShapes/btCompoundShape.h"
 #include "BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.h"
 #include "BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.h"
@@ -414,7 +414,9 @@ void btCollisionWorld::rayTestSingleInternal(const btTransform& rayFromTrans, co
 				rcb.m_hitFraction = resultCallback.m_closestHitFraction;
 				rcb.m_hitFraction = resultCallback.m_closestHitFraction;
 				triangleMesh->performRaycast(&rcb, rayFromLocalScaled, rayToLocalScaled);
 				triangleMesh->performRaycast(&rcb, rayFromLocalScaled, rayToLocalScaled);
 			}
 			}
-			else if (collisionShape->getShapeType()==TERRAIN_SHAPE_PROXYTYPE)
+			else if (((resultCallback.m_flags&btTriangleRaycastCallback::kF_DisableHeightfieldAccelerator)==0) 
+				&& collisionShape->getShapeType() == TERRAIN_SHAPE_PROXYTYPE 
+				)
 			{
 			{
 				///optimized version for btHeightfieldTerrainShape
 				///optimized version for btHeightfieldTerrainShape
 				btHeightfieldTerrainShape* heightField = (btHeightfieldTerrainShape*)collisionShape;
 				btHeightfieldTerrainShape* heightField = (btHeightfieldTerrainShape*)collisionShape;
@@ -422,7 +424,7 @@ void btCollisionWorld::rayTestSingleInternal(const btTransform& rayFromTrans, co
 				btVector3 rayFromLocal = worldTocollisionObject * rayFromTrans.getOrigin();
 				btVector3 rayFromLocal = worldTocollisionObject * rayFromTrans.getOrigin();
 				btVector3 rayToLocal = worldTocollisionObject * rayToTrans.getOrigin();
 				btVector3 rayToLocal = worldTocollisionObject * rayToTrans.getOrigin();
 
 
-				BridgeTriangleRaycastCallback rcb(rayFromLocal,rayToLocal,&resultCallback,collisionObjectWrap->getCollisionObject(),heightField,colObjWorldTransform);
+				BridgeTriangleRaycastCallback rcb(rayFromLocal, rayToLocal, &resultCallback, collisionObjectWrap->getCollisionObject(), heightField, colObjWorldTransform);
 				rcb.m_hitFraction = resultCallback.m_closestHitFraction;
 				rcb.m_hitFraction = resultCallback.m_closestHitFraction;
 				heightField->performRaycast(&rcb, rayFromLocal, rayToLocal);
 				heightField->performRaycast(&rcb, rayFromLocal, rayToLocal);
 			}
 			}

+ 3 - 3
thirdparty/bullet/BulletCollision/CollisionShapes/btConvexPolyhedron.cpp

@@ -27,7 +27,7 @@ btConvexPolyhedron::~btConvexPolyhedron()
 {
 {
 }
 }
 
 
-inline bool IsAlmostZero(const btVector3& v)
+inline bool IsAlmostZero1(const btVector3& v)
 {
 {
 	if (btFabs(v.x()) > 1e-6 || btFabs(v.y()) > 1e-6 || btFabs(v.z()) > 1e-6) return false;
 	if (btFabs(v.x()) > 1e-6 || btFabs(v.y()) > 1e-6 || btFabs(v.z()) > 1e-6) return false;
 	return true;
 	return true;
@@ -122,8 +122,8 @@ void btConvexPolyhedron::initialize()
 
 
 			for (int p = 0; p < m_uniqueEdges.size(); p++)
 			for (int p = 0; p < m_uniqueEdges.size(); p++)
 			{
 			{
-				if (IsAlmostZero(m_uniqueEdges[p] - edge) ||
-					IsAlmostZero(m_uniqueEdges[p] + edge))
+				if (IsAlmostZero1(m_uniqueEdges[p] - edge) ||
+					IsAlmostZero1(m_uniqueEdges[p] + edge))
 				{
 				{
 					found = true;
 					found = true;
 					break;
 					break;

+ 128 - 78
thirdparty/bullet/BulletCollision/CollisionShapes/btHeightfieldTerrainShape.cpp

@@ -71,9 +71,10 @@ void btHeightfieldTerrainShape::initialize(
 	m_flipQuadEdges = flipQuadEdges;
 	m_flipQuadEdges = flipQuadEdges;
 	m_useDiamondSubdivision = false;
 	m_useDiamondSubdivision = false;
 	m_useZigzagSubdivision = false;
 	m_useZigzagSubdivision = false;
+	m_flipTriangleWinding = false;
 	m_upAxis = upAxis;
 	m_upAxis = upAxis;
 	m_localScaling.setValue(btScalar(1.), btScalar(1.), btScalar(1.));
 	m_localScaling.setValue(btScalar(1.), btScalar(1.), btScalar(1.));
-	m_vboundsGrid = NULL;
+	
 	m_vboundsChunkSize = 0;
 	m_vboundsChunkSize = 0;
 	m_vboundsGridWidth = 0;
 	m_vboundsGridWidth = 0;
 	m_vboundsGridLength = 0;
 	m_vboundsGridLength = 0;
@@ -335,30 +336,37 @@ void btHeightfieldTerrainShape::processAllTriangles(btTriangleCallback* callback
 		for (int x = startX; x < endX; x++)
 		for (int x = startX; x < endX; x++)
 		{
 		{
 			btVector3 vertices[3];
 			btVector3 vertices[3];
+			int indices[3] = { 0, 1, 2 };
+			if (m_flipTriangleWinding)
+			{
+				indices[0] = 2;
+				indices[2] = 0;
+			}
+
 			if (m_flipQuadEdges || (m_useDiamondSubdivision && !((j + x) & 1)) || (m_useZigzagSubdivision && !(j & 1)))
 			if (m_flipQuadEdges || (m_useDiamondSubdivision && !((j + x) & 1)) || (m_useZigzagSubdivision && !(j & 1)))
 			{
 			{
 				//first triangle
 				//first triangle
-				getVertex(x, j, vertices[0]);
-				getVertex(x, j + 1, vertices[1]);
-				getVertex(x + 1, j + 1, vertices[2]);
+				getVertex(x, j, vertices[indices[0]]);
+				getVertex(x, j + 1, vertices[indices[1]]);
+				getVertex(x + 1, j + 1, vertices[indices[2]]);
 				callback->processTriangle(vertices, x, j);
 				callback->processTriangle(vertices, x, j);
 				//second triangle
 				//second triangle
 				//  getVertex(x,j,vertices[0]);//already got this vertex before, thanks to Danny Chapman
 				//  getVertex(x,j,vertices[0]);//already got this vertex before, thanks to Danny Chapman
-				getVertex(x + 1, j + 1, vertices[1]);
-				getVertex(x + 1, j, vertices[2]);
+				getVertex(x + 1, j + 1, vertices[indices[1]]);
+				getVertex(x + 1, j, vertices[indices[2]]);
 				callback->processTriangle(vertices, x, j);
 				callback->processTriangle(vertices, x, j);
 			}
 			}
 			else
 			else
 			{
 			{
 				//first triangle
 				//first triangle
-				getVertex(x, j, vertices[0]);
-				getVertex(x, j + 1, vertices[1]);
-				getVertex(x + 1, j, vertices[2]);
+				getVertex(x, j, vertices[indices[0]]);
+				getVertex(x, j + 1, vertices[indices[1]]);
+				getVertex(x + 1, j, vertices[indices[2]]);
 				callback->processTriangle(vertices, x, j);
 				callback->processTriangle(vertices, x, j);
 				//second triangle
 				//second triangle
-				getVertex(x + 1, j, vertices[0]);
+				getVertex(x + 1, j, vertices[indices[0]]);
 				//getVertex(x,j+1,vertices[1]);
 				//getVertex(x,j+1,vertices[1]);
-				getVertex(x + 1, j + 1, vertices[2]);
+				getVertex(x + 1, j + 1, vertices[indices[2]]);
 				callback->processTriangle(vertices, x, j);
 				callback->processTriangle(vertices, x, j);
 			}
 			}
 		}
 		}
@@ -381,39 +389,42 @@ const btVector3& btHeightfieldTerrainShape::getLocalScaling() const
 	return m_localScaling;
 	return m_localScaling;
 }
 }
 
 
-
-
-struct GridRaycastState
+namespace
 {
 {
-	int x; // Next quad coords
-	int z;
-	int prev_x; // Previous quad coords
-	int prev_z;
-	btScalar param; // Exit param for previous quad
-	btScalar prevParam; // Enter param for previous quad
-	btScalar maxDistanceFlat;
-	btScalar maxDistance3d;
-};
-
+	struct GridRaycastState
+	{
+		int x;  // Next quad coords
+		int z;
+		int prev_x;  // Previous quad coords
+		int prev_z;
+		btScalar param;      // Exit param for previous quad
+		btScalar prevParam;  // Enter param for previous quad
+		btScalar maxDistanceFlat;
+		btScalar maxDistance3d;
+	};
+}
 
 
 // TODO Does it really need to take 3D vectors?
 // TODO Does it really need to take 3D vectors?
 /// Iterates through a virtual 2D grid of unit-sized square cells,
 /// Iterates through a virtual 2D grid of unit-sized square cells,
 /// and executes an action on each cell intersecting the given segment, ordered from begin to end.
 /// and executes an action on each cell intersecting the given segment, ordered from begin to end.
 /// Initially inspired by http://www.cse.yorku.ca/~amana/research/grid.pdf
 /// Initially inspired by http://www.cse.yorku.ca/~amana/research/grid.pdf
 template <typename Action_T>
 template <typename Action_T>
-void gridRaycast(Action_T &quadAction, const btVector3 &beginPos, const btVector3 &endPos)
+void gridRaycast(Action_T& quadAction, const btVector3& beginPos, const btVector3& endPos, int indices[3])
 {
 {
 	GridRaycastState rs;
 	GridRaycastState rs;
 	rs.maxDistance3d = beginPos.distance(endPos);
 	rs.maxDistance3d = beginPos.distance(endPos);
 	if (rs.maxDistance3d < 0.0001)
 	if (rs.maxDistance3d < 0.0001)
+	{
 		// Consider the ray is too small to hit anything
 		// Consider the ray is too small to hit anything
 		return;
 		return;
+	}
+	
 
 
-	btScalar rayDirectionFlatX = endPos[0] - beginPos[0];
-	btScalar rayDirectionFlatZ = endPos[2] - beginPos[2];
+	btScalar rayDirectionFlatX = endPos[indices[0]] - beginPos[indices[0]];
+	btScalar rayDirectionFlatZ = endPos[indices[2]] - beginPos[indices[2]];
 	rs.maxDistanceFlat = btSqrt(rayDirectionFlatX * rayDirectionFlatX + rayDirectionFlatZ * rayDirectionFlatZ);
 	rs.maxDistanceFlat = btSqrt(rayDirectionFlatX * rayDirectionFlatX + rayDirectionFlatZ * rayDirectionFlatZ);
 
 
-	if(rs.maxDistanceFlat < 0.0001)
+	if (rs.maxDistanceFlat < 0.0001)
 	{
 	{
 		// Consider the ray vertical
 		// Consider the ray vertical
 		rayDirectionFlatX = 0;
 		rayDirectionFlatX = 0;
@@ -433,34 +444,46 @@ void gridRaycast(Action_T &quadAction, const btVector3 &beginPos, const btVector
 	const btScalar paramDeltaZ = ziStep != 0 ? 1.f / btFabs(rayDirectionFlatZ) : infinite;
 	const btScalar paramDeltaZ = ziStep != 0 ? 1.f / btFabs(rayDirectionFlatZ) : infinite;
 
 
 	// pos = param * dir
 	// pos = param * dir
-	btScalar paramCrossX; // At which value of `param` we will cross a x-axis lane?
-	btScalar paramCrossZ; // At which value of `param` we will cross a z-axis lane?
+	btScalar paramCrossX;  // At which value of `param` we will cross a x-axis lane?
+	btScalar paramCrossZ;  // At which value of `param` we will cross a z-axis lane?
 
 
 	// paramCrossX and paramCrossZ are initialized as being the first cross
 	// paramCrossX and paramCrossZ are initialized as being the first cross
 	// X initialization
 	// X initialization
 	if (xiStep != 0)
 	if (xiStep != 0)
 	{
 	{
 		if (xiStep == 1)
 		if (xiStep == 1)
-			paramCrossX = (ceil(beginPos[0]) - beginPos[0]) * paramDeltaX;
+		{
+			paramCrossX = (ceil(beginPos[indices[0]]) - beginPos[indices[0]]) * paramDeltaX;
+		}
 		else
 		else
-			paramCrossX = (beginPos[0] - floor(beginPos[0])) * paramDeltaX;
+		{
+			paramCrossX = (beginPos[indices[0]] - floor(beginPos[indices[0]])) * paramDeltaX;
+		}
 	}
 	}
 	else
 	else
-		paramCrossX = infinite; // Will never cross on X
+	{
+		paramCrossX = infinite;  // Will never cross on X
+	}
 
 
 	// Z initialization
 	// Z initialization
 	if (ziStep != 0)
 	if (ziStep != 0)
 	{
 	{
 		if (ziStep == 1)
 		if (ziStep == 1)
-			paramCrossZ = (ceil(beginPos[2]) - beginPos[2]) * paramDeltaZ;
+		{
+			paramCrossZ = (ceil(beginPos[indices[2]]) - beginPos[indices[2]]) * paramDeltaZ;
+		}
 		else
 		else
-			paramCrossZ = (beginPos[2] - floor(beginPos[2])) * paramDeltaZ;
+		{
+			paramCrossZ = (beginPos[indices[2]] - floor(beginPos[indices[2]])) * paramDeltaZ;
+		}
 	}
 	}
 	else
 	else
-		paramCrossZ = infinite; // Will never cross on Z
+	{
+		paramCrossZ = infinite;  // Will never cross on Z
+	}
 
 
-	rs.x = static_cast<int>(floor(beginPos[0]));
-	rs.z = static_cast<int>(floor(beginPos[2]));
+	rs.x = static_cast<int>(floor(beginPos[indices[0]]));
+	rs.z = static_cast<int>(floor(beginPos[indices[2]]));
 
 
 	// Workaround cases where the ray starts at an integer position
 	// Workaround cases where the ray starts at an integer position
 	if (paramCrossX == 0.0)
 	if (paramCrossX == 0.0)
@@ -469,7 +492,9 @@ void gridRaycast(Action_T &quadAction, const btVector3 &beginPos, const btVector
 		// If going backwards, we should ignore the position we would get by the above flooring,
 		// If going backwards, we should ignore the position we would get by the above flooring,
 		// because the ray is not heading in that direction
 		// because the ray is not heading in that direction
 		if (xiStep == -1)
 		if (xiStep == -1)
+		{
 			rs.x -= 1;
 			rs.x -= 1;
+		}
 	}
 	}
 
 
 	if (paramCrossZ == 0.0)
 	if (paramCrossZ == 0.0)
@@ -513,14 +538,15 @@ void gridRaycast(Action_T &quadAction, const btVector3 &beginPos, const btVector
 			break;
 			break;
 		}
 		}
 		else
 		else
+		{
 			quadAction(rs);
 			quadAction(rs);
+		}
 	}
 	}
 }
 }
 
 
-
 struct ProcessTrianglesAction
 struct ProcessTrianglesAction
 {
 {
-	const btHeightfieldTerrainShape *shape;
+	const btHeightfieldTerrainShape* shape;
 	bool flipQuadEdges;
 	bool flipQuadEdges;
 	bool useDiamondSubdivision;
 	bool useDiamondSubdivision;
 	int width;
 	int width;
@@ -529,11 +555,15 @@ struct ProcessTrianglesAction
 
 
 	void exec(int x, int z) const
 	void exec(int x, int z) const
 	{
 	{
-		if(x < 0 || z < 0 || x >= width || z >= length)
+		if (x < 0 || z < 0 || x >= width || z >= length)
+		{
 			return;
 			return;
+		}
 
 
 		btVector3 vertices[3];
 		btVector3 vertices[3];
 
 
+		// TODO Since this is for raycasts, we could greatly benefit from an early exit on the first hit
+
 		// Check quad
 		// Check quad
 		if (flipQuadEdges || (useDiamondSubdivision && (((z + x) & 1) > 0)))
 		if (flipQuadEdges || (useDiamondSubdivision && (((z + x) & 1) > 0)))
 		{
 		{
@@ -565,16 +595,15 @@ struct ProcessTrianglesAction
 		}
 		}
 	}
 	}
 
 
-	void operator ()(const GridRaycastState &bs) const
+	void operator()(const GridRaycastState& bs) const
 	{
 	{
 		exec(bs.prev_x, bs.prev_z);
 		exec(bs.prev_x, bs.prev_z);
 	}
 	}
 };
 };
 
 
-
 struct ProcessVBoundsAction
 struct ProcessVBoundsAction
 {
 {
-	const btHeightfieldTerrainShape::Range *vbounds;
+	const btAlignedObjectArray<btHeightfieldTerrainShape::Range>& vbounds;
 	int width;
 	int width;
 	int length;
 	int length;
 	int chunkSize;
 	int chunkSize;
@@ -583,15 +612,23 @@ struct ProcessVBoundsAction
 	btVector3 rayEnd;
 	btVector3 rayEnd;
 	btVector3 rayDir;
 	btVector3 rayDir;
 
 
+	int* m_indices;
 	ProcessTrianglesAction processTriangles;
 	ProcessTrianglesAction processTriangles;
 
 
-	void operator ()(const GridRaycastState &rs) const
+	ProcessVBoundsAction(const btAlignedObjectArray<btHeightfieldTerrainShape::Range>& bnd, int* indices)
+		: vbounds(bnd),
+		m_indices(indices)
+	{
+	}
+	void operator()(const GridRaycastState& rs) const
 	{
 	{
 		int x = rs.prev_x;
 		int x = rs.prev_x;
 		int z = rs.prev_z;
 		int z = rs.prev_z;
 
 
-		if(x < 0 || z < 0 || x >= width || z >= length)
+		if (x < 0 || z < 0 || x >= width || z >= length)
+		{
 			return;
 			return;
+		}
 
 
 		const btHeightfieldTerrainShape::Range chunk = vbounds[x + z * width];
 		const btHeightfieldTerrainShape::Range chunk = vbounds[x + z * width];
 
 
@@ -608,10 +645,14 @@ struct ProcessVBoundsAction
 
 
 			// We did enter the flat projection of the AABB,
 			// We did enter the flat projection of the AABB,
 			// but we have to check if we intersect it on the vertical axis
 			// but we have to check if we intersect it on the vertical axis
-			if (enterPos[1] > chunk.max && exitPos[1] > chunk.max)
+			if (enterPos[1] > chunk.max && exitPos[m_indices[1]] > chunk.max)
+			{
 				return;
 				return;
-			if (enterPos[1] < chunk.min && exitPos[1] < chunk.min)
+			}
+			if (enterPos[1] < chunk.min && exitPos[m_indices[1]] < chunk.min)
+			{
 				return;
 				return;
+			}
 		}
 		}
 		else
 		else
 		{
 		{
@@ -621,13 +662,12 @@ struct ProcessVBoundsAction
 			exitPos = rayEnd;
 			exitPos = rayEnd;
 		}
 		}
 
 
-		gridRaycast(processTriangles, enterPos, exitPos);
+		gridRaycast(processTriangles, enterPos, exitPos, m_indices);
 		// Note: it could be possible to have more than one grid at different levels,
 		// Note: it could be possible to have more than one grid at different levels,
 		// to do this there would be a branch using a pointer to another ProcessVBoundsAction
 		// to do this there would be a branch using a pointer to another ProcessVBoundsAction
 	}
 	}
 };
 };
 
 
-
 // TODO How do I interrupt the ray when there is a hit? `callback` does not return any result
 // TODO How do I interrupt the ray when there is a hit? `callback` does not return any result
 /// Performs a raycast using a hierarchical Bresenham algorithm.
 /// Performs a raycast using a hierarchical Bresenham algorithm.
 /// Does not allocate any memory by itself.
 /// Does not allocate any memory by itself.
@@ -648,10 +688,16 @@ void btHeightfieldTerrainShape::performRaycast(btTriangleCallback* callback, con
 	processTriangles.length = m_heightStickLength - 1;
 	processTriangles.length = m_heightStickLength - 1;
 
 
 	// TODO Transform vectors to account for m_upAxis
 	// TODO Transform vectors to account for m_upAxis
-	int iBeginX = static_cast<int>(floor(beginPos[0]));
-	int iBeginZ = static_cast<int>(floor(beginPos[2]));
-	int iEndX = static_cast<int>(floor(endPos[0]));
-	int iEndZ = static_cast<int>(floor(endPos[2]));
+	int indices[3] = { 0, 1, 2 };
+	if (m_upAxis == 2)
+	{
+		indices[1] = 2;
+		indices[2] = 1;
+	}
+	int iBeginX = static_cast<int>(floor(beginPos[indices[0]]));
+	int iBeginZ = static_cast<int>(floor(beginPos[indices[2]]));
+	int iEndX = static_cast<int>(floor(endPos[indices[0]]));
+	int iEndZ = static_cast<int>(floor(endPos[indices[2]]));
 
 
 	if (iBeginX == iEndX && iBeginZ == iEndZ)
 	if (iBeginX == iEndX && iBeginZ == iEndZ)
 	{
 	{
@@ -662,36 +708,36 @@ void btHeightfieldTerrainShape::performRaycast(btTriangleCallback* callback, con
 		return;
 		return;
 	}
 	}
 
 
-	if (m_vboundsGrid == NULL)
+	
+
+	if (m_vboundsGrid.size()==0)
 	{
 	{
 		// Process all quads intersecting the flat projection of the ray
 		// Process all quads intersecting the flat projection of the ray
-		gridRaycast(processTriangles, beginPos, endPos);
+		gridRaycast(processTriangles, beginPos, endPos, &indices[0]);
 	}
 	}
 	else
 	else
 	{
 	{
 		btVector3 rayDiff = endPos - beginPos;
 		btVector3 rayDiff = endPos - beginPos;
-		btScalar flatDistance2 = rayDiff[0] * rayDiff[0] + rayDiff[2] * rayDiff[2];
+		btScalar flatDistance2 = rayDiff[indices[0]] * rayDiff[indices[0]] + rayDiff[indices[2]] * rayDiff[indices[2]];
 		if (flatDistance2 < m_vboundsChunkSize * m_vboundsChunkSize)
 		if (flatDistance2 < m_vboundsChunkSize * m_vboundsChunkSize)
 		{
 		{
 			// Don't use chunks, the ray is too short in the plane
 			// Don't use chunks, the ray is too short in the plane
-			gridRaycast(processTriangles, beginPos, endPos);
+			gridRaycast(processTriangles, beginPos, endPos, &indices[0]);
 		}
 		}
 
 
-		ProcessVBoundsAction processVBounds;
+		ProcessVBoundsAction processVBounds(m_vboundsGrid, &indices[0]);
 		processVBounds.width = m_vboundsGridWidth;
 		processVBounds.width = m_vboundsGridWidth;
 		processVBounds.length = m_vboundsGridLength;
 		processVBounds.length = m_vboundsGridLength;
-		processVBounds.vbounds = m_vboundsGrid;
 		processVBounds.rayBegin = beginPos;
 		processVBounds.rayBegin = beginPos;
 		processVBounds.rayEnd = endPos;
 		processVBounds.rayEnd = endPos;
 		processVBounds.rayDir = rayDiff.normalized();
 		processVBounds.rayDir = rayDiff.normalized();
 		processVBounds.processTriangles = processTriangles;
 		processVBounds.processTriangles = processTriangles;
 		processVBounds.chunkSize = m_vboundsChunkSize;
 		processVBounds.chunkSize = m_vboundsChunkSize;
 		// The ray is long, run raycast on a higher-level grid
 		// The ray is long, run raycast on a higher-level grid
-		gridRaycast(processVBounds, beginPos / m_vboundsChunkSize, endPos / m_vboundsChunkSize);
+		gridRaycast(processVBounds, beginPos / m_vboundsChunkSize, endPos / m_vboundsChunkSize, indices);
 	}
 	}
 }
 }
 
 
-
 /// Builds a grid data structure storing the min and max heights of the terrain in chunks.
 /// Builds a grid data structure storing the min and max heights of the terrain in chunks.
 /// if chunkSize is zero, that accelerator is removed.
 /// if chunkSize is zero, that accelerator is removed.
 /// If you modify the heights, you need to rebuild this accelerator.
 /// If you modify the heights, you need to rebuild this accelerator.
@@ -708,11 +754,15 @@ void btHeightfieldTerrainShape::buildAccelerator(int chunkSize)
 	int nChunksZ = m_heightStickLength / chunkSize;
 	int nChunksZ = m_heightStickLength / chunkSize;
 
 
 	if (m_heightStickWidth % chunkSize > 0)
 	if (m_heightStickWidth % chunkSize > 0)
-		++nChunksX; // In case terrain size isn't dividable by chunk size
+	{
+		++nChunksX;  // In case terrain size isn't dividable by chunk size
+	}
 	if (m_heightStickLength % chunkSize > 0)
 	if (m_heightStickLength % chunkSize > 0)
+	{
 		++nChunksZ;
 		++nChunksZ;
+	}
 
 
-	if(m_vboundsGridWidth != nChunksX || m_vboundsGridLength != nChunksZ)
+	if (m_vboundsGridWidth != nChunksX || m_vboundsGridLength != nChunksZ)
 	{
 	{
 		clearAccelerator();
 		clearAccelerator();
 		m_vboundsGridWidth = nChunksX;
 		m_vboundsGridWidth = nChunksX;
@@ -720,13 +770,13 @@ void btHeightfieldTerrainShape::buildAccelerator(int chunkSize)
 	}
 	}
 
 
 	if (nChunksX == 0 || nChunksZ == 0)
 	if (nChunksX == 0 || nChunksZ == 0)
+	{
 		return;
 		return;
+	}
 
 
-	// TODO What is the recommended way to allocate this?
 	// This data structure is only reallocated if the required size changed
 	// This data structure is only reallocated if the required size changed
-	if (m_vboundsGrid == NULL)
-		m_vboundsGrid = new Range[nChunksX * nChunksZ];
-
+	m_vboundsGrid.resize(nChunksX * nChunksZ);
+	
 	// Compute min and max height for all chunks
 	// Compute min and max height for all chunks
 	for (int cz = 0; cz < nChunksZ; ++cz)
 	for (int cz = 0; cz < nChunksZ; ++cz)
 	{
 	{
@@ -760,19 +810,27 @@ void btHeightfieldTerrainShape::buildAccelerator(int chunkSize)
 			for (int z = z0; z < z0 + chunkSize + 1; ++z)
 			for (int z = z0; z < z0 + chunkSize + 1; ++z)
 			{
 			{
 				if (z >= m_heightStickLength)
 				if (z >= m_heightStickLength)
+				{
 					continue;
 					continue;
+				}
 
 
 				for (int x = x0; x < x0 + chunkSize + 1; ++x)
 				for (int x = x0; x < x0 + chunkSize + 1; ++x)
 				{
 				{
 					if (x >= m_heightStickWidth)
 					if (x >= m_heightStickWidth)
+					{
 						continue;
 						continue;
+					}
 
 
 					btScalar height = getRawHeightFieldValue(x, z);
 					btScalar height = getRawHeightFieldValue(x, z);
 
 
 					if (height < r.min)
 					if (height < r.min)
+					{
 						r.min = height;
 						r.min = height;
+					}
 					else if (height > r.max)
 					else if (height > r.max)
+					{
 						r.max = height;
 						r.max = height;
+					}
 				}
 				}
 			}
 			}
 
 
@@ -781,15 +839,7 @@ void btHeightfieldTerrainShape::buildAccelerator(int chunkSize)
 	}
 	}
 }
 }
 
 
-
 void btHeightfieldTerrainShape::clearAccelerator()
 void btHeightfieldTerrainShape::clearAccelerator()
 {
 {
-	if (m_vboundsGrid)
-	{
-		// TODO What is the recommended way to deallocate this?
-		delete[] m_vboundsGrid;
-		m_vboundsGrid = 0;
-	}
-}
-
-
+	m_vboundsGrid.clear();
+}

+ 18 - 9
thirdparty/bullet/BulletCollision/CollisionShapes/btHeightfieldTerrainShape.h

@@ -17,7 +17,7 @@ subject to the following restrictions:
 #define BT_HEIGHTFIELD_TERRAIN_SHAPE_H
 #define BT_HEIGHTFIELD_TERRAIN_SHAPE_H
 
 
 #include "btConcaveShape.h"
 #include "btConcaveShape.h"
-
+#include "LinearMath/btAlignedObjectArray.h"
 
 
 ///btHeightfieldTerrainShape simulates a 2D heightfield terrain
 ///btHeightfieldTerrainShape simulates a 2D heightfield terrain
 /**
 /**
@@ -73,7 +73,8 @@ ATTRIBUTE_ALIGNED16(class)
 btHeightfieldTerrainShape : public btConcaveShape
 btHeightfieldTerrainShape : public btConcaveShape
 {
 {
 public:
 public:
-	struct Range {
+	struct Range
+	{
 		btScalar min;
 		btScalar min;
 		btScalar max;
 		btScalar max;
 	};
 	};
@@ -102,13 +103,13 @@ protected:
 	bool m_flipQuadEdges;
 	bool m_flipQuadEdges;
 	bool m_useDiamondSubdivision;
 	bool m_useDiamondSubdivision;
 	bool m_useZigzagSubdivision;
 	bool m_useZigzagSubdivision;
-
+	bool m_flipTriangleWinding;
 	int m_upAxis;
 	int m_upAxis;
 
 
 	btVector3 m_localScaling;
 	btVector3 m_localScaling;
 
 
 	// Accelerator
 	// Accelerator
-	Range *m_vboundsGrid;
+	btAlignedObjectArray<Range> m_vboundsGrid;
 	int m_vboundsGridWidth;
 	int m_vboundsGridWidth;
 	int m_vboundsGridLength;
 	int m_vboundsGridLength;
 	int m_vboundsChunkSize;
 	int m_vboundsChunkSize;
@@ -157,6 +158,10 @@ public:
 	///could help compatibility with Ogre heightfields. See https://code.google.com/p/bullet/issues/detail?id=625
 	///could help compatibility with Ogre heightfields. See https://code.google.com/p/bullet/issues/detail?id=625
 	void setUseZigzagSubdivision(bool useZigzagSubdivision = true) { m_useZigzagSubdivision = useZigzagSubdivision; }
 	void setUseZigzagSubdivision(bool useZigzagSubdivision = true) { m_useZigzagSubdivision = useZigzagSubdivision; }
 
 
+	void setFlipTriangleWinding(bool flipTriangleWinding)
+	{
+		m_flipTriangleWinding = flipTriangleWinding;
+	}
 	virtual void getAabb(const btTransform& t, btVector3& aabbMin, btVector3& aabbMax) const;
 	virtual void getAabb(const btTransform& t, btVector3& aabbMin, btVector3& aabbMax) const;
 
 
 	virtual void processAllTriangles(btTriangleCallback * callback, const btVector3& aabbMin, const btVector3& aabbMax) const;
 	virtual void processAllTriangles(btTriangleCallback * callback, const btVector3& aabbMin, const btVector3& aabbMax) const;
@@ -166,16 +171,20 @@ public:
 	virtual void setLocalScaling(const btVector3& scaling);
 	virtual void setLocalScaling(const btVector3& scaling);
 
 
 	virtual const btVector3& getLocalScaling() const;
 	virtual const btVector3& getLocalScaling() const;
-	
-	void		getVertex(int x,int y,btVector3& vertex) const;
 
 
-	void performRaycast (btTriangleCallback* callback, const btVector3& raySource, const btVector3& rayTarget) const;
+	void getVertex(int x, int y, btVector3& vertex) const;
+
+	void performRaycast(btTriangleCallback * callback, const btVector3& raySource, const btVector3& rayTarget) const;
 
 
-	void buildAccelerator(int chunkSize=16);
+	void buildAccelerator(int chunkSize = 16);
 	void clearAccelerator();
 	void clearAccelerator();
 
 
+	int getUpAxis() const
+	{
+		return m_upAxis;
+	}
 	//debugging
 	//debugging
 	virtual const char* getName() const { return "HEIGHTFIELD"; }
 	virtual const char* getName() const { return "HEIGHTFIELD"; }
 };
 };
 
 
-#endif  //BT_HEIGHTFIELD_TERRAIN_SHAPE_H
+#endif  //BT_HEIGHTFIELD_TERRAIN_SHAPE_H

+ 1 - 22
thirdparty/bullet/BulletCollision/Gimpact/btGImpactBvhStructs.h

@@ -28,28 +28,7 @@ subject to the following restrictions:
 
 
 #include "btBoxCollision.h"
 #include "btBoxCollision.h"
 #include "btTriangleShapeEx.h"
 #include "btTriangleShapeEx.h"
-
-//! Overlapping pair
-struct GIM_PAIR
-{
-	int m_index1;
-	int m_index2;
-	GIM_PAIR()
-	{
-	}
-
-	GIM_PAIR(const GIM_PAIR& p)
-	{
-		m_index1 = p.m_index1;
-		m_index2 = p.m_index2;
-	}
-
-	GIM_PAIR(int index1, int index2)
-	{
-		m_index1 = index1;
-		m_index2 = index2;
-	}
-};
+#include "gim_pair.h" //for GIM_PAIR
 
 
 ///GIM_BVH_DATA is an internal GIMPACT collision structure to contain axis aligned bounding box
 ///GIM_BVH_DATA is an internal GIMPACT collision structure to contain axis aligned bounding box
 struct GIM_BVH_DATA
 struct GIM_BVH_DATA

+ 13 - 3
thirdparty/bullet/BulletCollision/Gimpact/btGImpactCollisionAlgorithm.cpp

@@ -18,7 +18,7 @@ subject to the following restrictions:
 3. This notice may not be removed or altered from any source distribution.
 3. This notice may not be removed or altered from any source distribution.
 */
 */
 /*
 /*
-Author: Francisco Len Nßjera
+Author: Francisco Leon Najera
 Concave-Concave Collision
 Concave-Concave Collision
 
 
 */
 */
@@ -590,14 +590,16 @@ void btGImpactCollisionAlgorithm::gimpact_vs_shape(const btCollisionObjectWrappe
 		}
 		}
 
 
 		btCollisionObjectWrapper ob0(body0Wrap, colshape0, body0Wrap->getCollisionObject(), body0Wrap->getWorldTransform(), m_part0, m_triface0);
 		btCollisionObjectWrapper ob0(body0Wrap, colshape0, body0Wrap->getCollisionObject(), body0Wrap->getWorldTransform(), m_part0, m_triface0);
-		const btCollisionObjectWrapper* prevObj0 = m_resultOut->getBody0Wrap();
+		const btCollisionObjectWrapper* prevObj;
 
 
 		if (m_resultOut->getBody0Wrap()->getCollisionObject() == ob0.getCollisionObject())
 		if (m_resultOut->getBody0Wrap()->getCollisionObject() == ob0.getCollisionObject())
 		{
 		{
+			prevObj = m_resultOut->getBody0Wrap();
 			m_resultOut->setBody0Wrap(&ob0);
 			m_resultOut->setBody0Wrap(&ob0);
 		}
 		}
 		else
 		else
 		{
 		{
+			prevObj = m_resultOut->getBody1Wrap();
 			m_resultOut->setBody1Wrap(&ob0);
 			m_resultOut->setBody1Wrap(&ob0);
 		}
 		}
 
 
@@ -610,7 +612,15 @@ void btGImpactCollisionAlgorithm::gimpact_vs_shape(const btCollisionObjectWrappe
 		{
 		{
 			shape_vs_shape_collision(&ob0, body1Wrap, colshape0, shape1);
 			shape_vs_shape_collision(&ob0, body1Wrap, colshape0, shape1);
 		}
 		}
-		m_resultOut->setBody0Wrap(prevObj0);
+
+		if (m_resultOut->getBody0Wrap()->getCollisionObject() == ob0.getCollisionObject())
+		{
+			m_resultOut->setBody0Wrap(prevObj);
+		}
+		else
+		{
+			m_resultOut->setBody1Wrap(prevObj);
+		}
 	}
 	}
 
 
 	shape0->unlockChildShapes();
 	shape0->unlockChildShapes();

+ 1 - 1
thirdparty/bullet/BulletCollision/Gimpact/btGImpactShape.h

@@ -1,5 +1,5 @@
 /*! \file btGImpactShape.h
 /*! \file btGImpactShape.h
-\author Francisco Len Nßjera
+\author Francisco Leon Najera
 */
 */
 /*
 /*
 This source file is part of GIMPACT Library.
 This source file is part of GIMPACT Library.

+ 1 - 22
thirdparty/bullet/BulletCollision/Gimpact/gim_box_set.h

@@ -37,28 +37,7 @@ email: [email protected]
 #include "gim_radixsort.h"
 #include "gim_radixsort.h"
 #include "gim_box_collision.h"
 #include "gim_box_collision.h"
 #include "gim_tri_collision.h"
 #include "gim_tri_collision.h"
-
-//! Overlapping pair
-struct GIM_PAIR
-{
-	GUINT m_index1;
-	GUINT m_index2;
-	GIM_PAIR()
-	{
-	}
-
-	GIM_PAIR(const GIM_PAIR& p)
-	{
-		m_index1 = p.m_index1;
-		m_index2 = p.m_index2;
-	}
-
-	GIM_PAIR(GUINT index1, GUINT index2)
-	{
-		m_index1 = index1;
-		m_index2 = index2;
-	}
-};
+#include "gim_pair.h"
 
 
 //! A pairset array
 //! A pairset array
 class gim_pair_set : public gim_array<GIM_PAIR>
 class gim_pair_set : public gim_array<GIM_PAIR>

+ 28 - 0
thirdparty/bullet/BulletCollision/Gimpact/gim_pair.h

@@ -0,0 +1,28 @@
+#ifndef GIM_PAIR_H
+#define GIM_PAIR_H
+
+
+//! Overlapping pair
+struct GIM_PAIR
+{
+        int m_index1;
+        int m_index2;
+        GIM_PAIR()
+        {
+        }
+
+        GIM_PAIR(const GIM_PAIR& p)
+        {
+                m_index1 = p.m_index1;
+                m_index2 = p.m_index2;
+        }
+
+        GIM_PAIR(int index1, int index2)
+        {
+                m_index1 = index1;
+                m_index2 = index2;
+        }
+};
+
+#endif //GIM_PAIR_H
+

+ 6 - 6
thirdparty/bullet/BulletCollision/NarrowPhaseCollision/btConvexCast.h

@@ -23,11 +23,11 @@ class btMinkowskiSumShape;
 #include "LinearMath/btIDebugDraw.h"
 #include "LinearMath/btIDebugDraw.h"
 
 
 #ifdef BT_USE_DOUBLE_PRECISION
 #ifdef BT_USE_DOUBLE_PRECISION
-#define MAX_ITERATIONS 64
-#define MAX_EPSILON (SIMD_EPSILON * 10)
+#define MAX_CONVEX_CAST_ITERATIONS 64
+#define MAX_CONVEX_CAST_EPSILON (SIMD_EPSILON * 10)
 #else
 #else
-#define MAX_ITERATIONS 32
-#define MAX_EPSILON btScalar(0.0001)
+#define MAX_CONVEX_CAST_ITERATIONS 32
+#define MAX_CONVEX_CAST_EPSILON btScalar(0.0001)
 #endif
 #endif
 ///Typically the conservative advancement reaches solution in a few iterations, clip it to 32 for degenerate cases.
 ///Typically the conservative advancement reaches solution in a few iterations, clip it to 32 for degenerate cases.
 ///See discussion about this here http://continuousphysics.com/Bullet/phpBB2/viewtopic.php?t=565
 ///See discussion about this here http://continuousphysics.com/Bullet/phpBB2/viewtopic.php?t=565
@@ -58,8 +58,8 @@ public:
 			: m_fraction(btScalar(BT_LARGE_FLOAT)),
 			: m_fraction(btScalar(BT_LARGE_FLOAT)),
 			  m_debugDrawer(0),
 			  m_debugDrawer(0),
 			  m_allowedPenetration(btScalar(0)),
 			  m_allowedPenetration(btScalar(0)),
-			  m_subSimplexCastMaxIterations(MAX_ITERATIONS),
-			  m_subSimplexCastEpsilon(MAX_EPSILON)
+			  m_subSimplexCastMaxIterations(MAX_CONVEX_CAST_ITERATIONS),
+			  m_subSimplexCastEpsilon(MAX_CONVEX_CAST_EPSILON)
 		{
 		{
 		}
 		}
 
 

+ 1 - 1
thirdparty/bullet/BulletCollision/NarrowPhaseCollision/btGjkPairDetector.cpp

@@ -1,4 +1,4 @@
-/*
+/*
 Bullet Continuous Collision Detection and Physics Library
 Bullet Continuous Collision Detection and Physics Library
 Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/
 Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/
 
 

+ 1 - 0
thirdparty/bullet/BulletCollision/NarrowPhaseCollision/btRaycastCallback.h

@@ -37,6 +37,7 @@ public:
 													 ///SubSimplexConvexCastRaytest is the default, even if kF_None is set.
 													 ///SubSimplexConvexCastRaytest is the default, even if kF_None is set.
 		kF_UseSubSimplexConvexCastRaytest = 1 << 2,  // Uses an approximate but faster ray versus convex intersection algorithm
 		kF_UseSubSimplexConvexCastRaytest = 1 << 2,  // Uses an approximate but faster ray versus convex intersection algorithm
 		kF_UseGjkConvexCastRaytest = 1 << 3,
 		kF_UseGjkConvexCastRaytest = 1 << 3,
+		kF_DisableHeightfieldAccelerator  = 1 << 4, //don't use the heightfield raycast accelerator. See https://github.com/bulletphysics/bullet3/pull/2062
 		kF_Terminator = 0xFFFFFFFF
 		kF_Terminator = 0xFFFFFFFF
 	};
 	};
 	unsigned int m_flags;
 	unsigned int m_flags;

+ 3 - 1
thirdparty/bullet/BulletDynamics/ConstraintSolver/btBatchedConstraints.cpp

@@ -22,6 +22,8 @@ subject to the following restrictions:
 
 
 #include <string.h>  //for memset
 #include <string.h>  //for memset
 
 
+#include <cmath>
+
 const int kNoMerge = -1;
 const int kNoMerge = -1;
 
 
 bool btBatchedConstraints::s_debugDrawBatches = false;
 bool btBatchedConstraints::s_debugDrawBatches = false;
@@ -520,7 +522,7 @@ static void writeGrainSizes(btBatchedConstraints* bc)
 	{
 	{
 		const Range& phase = bc->m_phases[iPhase];
 		const Range& phase = bc->m_phases[iPhase];
 		int numBatches = phase.end - phase.begin;
 		int numBatches = phase.end - phase.begin;
-		float grainSize = floor((0.25f * numBatches / float(numThreads)) + 0.0f);
+		float grainSize = std::floor((0.25f * numBatches / float(numThreads)) + 0.0f);
 		bc->m_phaseGrainSize[iPhase] = btMax(1, int(grainSize));
 		bc->m_phaseGrainSize[iPhase] = btMax(1, int(grainSize));
 	}
 	}
 }
 }

+ 3 - 2
thirdparty/bullet/BulletDynamics/ConstraintSolver/btConeTwistConstraint.cpp

@@ -19,6 +19,7 @@ Written by: Marcus Hennix
 #include "BulletDynamics/Dynamics/btRigidBody.h"
 #include "BulletDynamics/Dynamics/btRigidBody.h"
 #include "LinearMath/btTransformUtil.h"
 #include "LinearMath/btTransformUtil.h"
 #include "LinearMath/btMinMax.h"
 #include "LinearMath/btMinMax.h"
+#include <cmath>
 #include <new>
 #include <new>
 
 
 //#define CONETWIST_USE_OBSOLETE_SOLVER true
 //#define CONETWIST_USE_OBSOLETE_SOLVER true
@@ -842,7 +843,7 @@ void btConeTwistConstraint::computeConeLimitInfo(const btQuaternion& qCone,
 			btScalar norm = 1 / (m_swingSpan2 * m_swingSpan2);
 			btScalar norm = 1 / (m_swingSpan2 * m_swingSpan2);
 			norm += surfaceSlope2 / (m_swingSpan1 * m_swingSpan1);
 			norm += surfaceSlope2 / (m_swingSpan1 * m_swingSpan1);
 			btScalar swingLimit2 = (1 + surfaceSlope2) / norm;
 			btScalar swingLimit2 = (1 + surfaceSlope2) / norm;
-			swingLimit = sqrt(swingLimit2);
+			swingLimit = std::sqrt(swingLimit2);
 		}
 		}
 
 
 		// test!
 		// test!
@@ -887,7 +888,7 @@ btVector3 btConeTwistConstraint::GetPointForAngle(btScalar fAngleInRadians, btSc
 		btScalar norm = 1 / (m_swingSpan2 * m_swingSpan2);
 		btScalar norm = 1 / (m_swingSpan2 * m_swingSpan2);
 		norm += surfaceSlope2 / (m_swingSpan1 * m_swingSpan1);
 		norm += surfaceSlope2 / (m_swingSpan1 * m_swingSpan1);
 		btScalar swingLimit2 = (1 + surfaceSlope2) / norm;
 		btScalar swingLimit2 = (1 + surfaceSlope2) / norm;
-		swingLimit = sqrt(swingLimit2);
+		swingLimit = std::sqrt(swingLimit2);
 	}
 	}
 
 
 	// convert into point in constraint space:
 	// convert into point in constraint space:

+ 1 - 0
thirdparty/bullet/BulletDynamics/ConstraintSolver/btConstraintSolver.h

@@ -35,6 +35,7 @@ enum btConstraintSolverType
 	BT_MLCP_SOLVER = 2,
 	BT_MLCP_SOLVER = 2,
 	BT_NNCG_SOLVER = 4,
 	BT_NNCG_SOLVER = 4,
 	BT_MULTIBODY_SOLVER = 8,
 	BT_MULTIBODY_SOLVER = 8,
+	BT_BLOCK_SOLVER = 16,
 };
 };
 
 
 class btConstraintSolver
 class btConstraintSolver

+ 2 - 0
thirdparty/bullet/BulletDynamics/ConstraintSolver/btContactSolverInfo.h

@@ -64,6 +64,7 @@ struct btContactSolverInfoData
 	btScalar m_restitutionVelocityThreshold;
 	btScalar m_restitutionVelocityThreshold;
 	bool m_jointFeedbackInWorldSpace;
 	bool m_jointFeedbackInWorldSpace;
 	bool m_jointFeedbackInJointFrame;
 	bool m_jointFeedbackInJointFrame;
+	int m_reportSolverAnalytics;
 };
 };
 
 
 struct btContactSolverInfo : public btContactSolverInfoData
 struct btContactSolverInfo : public btContactSolverInfoData
@@ -98,6 +99,7 @@ struct btContactSolverInfo : public btContactSolverInfoData
 		m_restitutionVelocityThreshold = 0.2f;  //if the relative velocity is below this threshold, there is zero restitution
 		m_restitutionVelocityThreshold = 0.2f;  //if the relative velocity is below this threshold, there is zero restitution
 		m_jointFeedbackInWorldSpace = false;
 		m_jointFeedbackInWorldSpace = false;
 		m_jointFeedbackInJointFrame = false;
 		m_jointFeedbackInJointFrame = false;
+		m_reportSolverAnalytics = 0;
 	}
 	}
 };
 };
 
 

+ 7 - 6
thirdparty/bullet/BulletDynamics/ConstraintSolver/btGeneric6DofSpring2Constraint.cpp

@@ -32,7 +32,7 @@ Cons:
 
 
 /*
 /*
 2007-09-09
 2007-09-09
-btGeneric6DofConstraint Refactored by Francisco Le?n
+btGeneric6DofConstraint Refactored by Francisco Leon
 email: [email protected]
 email: [email protected]
 http://gimpact.sf.net
 http://gimpact.sf.net
 */
 */
@@ -40,6 +40,7 @@ http://gimpact.sf.net
 #include "btGeneric6DofSpring2Constraint.h"
 #include "btGeneric6DofSpring2Constraint.h"
 #include "BulletDynamics/Dynamics/btRigidBody.h"
 #include "BulletDynamics/Dynamics/btRigidBody.h"
 #include "LinearMath/btTransformUtil.h"
 #include "LinearMath/btTransformUtil.h"
+#include <cmath>
 #include <new>
 #include <new>
 
 
 btGeneric6DofSpring2Constraint::btGeneric6DofSpring2Constraint(btRigidBody& rbA, btRigidBody& rbB, const btTransform& frameInA, const btTransform& frameInB, RotateOrder rotOrder)
 btGeneric6DofSpring2Constraint::btGeneric6DofSpring2Constraint(btRigidBody& rbA, btRigidBody& rbB, const btTransform& frameInA, const btTransform& frameInB, RotateOrder rotOrder)
@@ -310,9 +311,9 @@ void btGeneric6DofSpring2Constraint::calculateAngleInfo()
 		case RO_XYZ:
 		case RO_XYZ:
 		{
 		{
 			//Is this the "line of nodes" calculation choosing planes YZ (B coordinate system) and xy (A coordinate system)? (http://en.wikipedia.org/wiki/Euler_angles)
 			//Is this the "line of nodes" calculation choosing planes YZ (B coordinate system) and xy (A coordinate system)? (http://en.wikipedia.org/wiki/Euler_angles)
-			//The two planes are non-homologous, so this is a TaitBryan angle formalism and not a proper Euler
+			//The two planes are non-homologous, so this is a Tait-Bryan angle formalism and not a proper Euler
 			//Extrinsic rotations are equal to the reversed order intrinsic rotations so the above xyz extrinsic rotations (axes are fixed) are the same as the zy'x" intrinsic rotations (axes are refreshed after each rotation)
 			//Extrinsic rotations are equal to the reversed order intrinsic rotations so the above xyz extrinsic rotations (axes are fixed) are the same as the zy'x" intrinsic rotations (axes are refreshed after each rotation)
-			//that is why xy and YZ planes are chosen (this will describe a zy'x" intrinsic rotation) (see the figure on the left at http://en.wikipedia.org/wiki/Euler_angles under TaitBryan angles)
+			//that is why xy and YZ planes are chosen (this will describe a zy'x" intrinsic rotation) (see the figure on the left at http://en.wikipedia.org/wiki/Euler_angles under Tait-Bryan angles)
 			// x' = Nperp = N.cross(axis2)
 			// x' = Nperp = N.cross(axis2)
 			// y' = N = axis2.cross(axis0)
 			// y' = N = axis2.cross(axis0)
 			// z' = z
 			// z' = z
@@ -845,7 +846,7 @@ int btGeneric6DofSpring2Constraint::get_limit_motor_info2(
 		if (m_rbA.getInvMass() == 0) m = mB; else
 		if (m_rbA.getInvMass() == 0) m = mB; else
 		if (m_rbB.getInvMass() == 0) m = mA; else
 		if (m_rbB.getInvMass() == 0) m = mA; else
 			m = mA*mB / (mA + mB);
 			m = mA*mB / (mA + mB);
-		btScalar angularfreq = sqrt(ks / m);
+		btScalar angularfreq = btSqrt(ks / m);
 
 
 		//limit stiffness (the spring should not be sampled faster that the quarter of its angular frequency)
 		//limit stiffness (the spring should not be sampled faster that the quarter of its angular frequency)
 		if (limot->m_springStiffnessLimited && 0.25 < angularfreq * dt)
 		if (limot->m_springStiffnessLimited && 0.25 < angularfreq * dt)
@@ -865,7 +866,7 @@ int btGeneric6DofSpring2Constraint::get_limit_motor_info2(
 		// vel + f / m * (rotational ? -1 : 1)
 		// vel + f / m * (rotational ? -1 : 1)
 		// so in theory this should be set here for m_constraintError
 		// so in theory this should be set here for m_constraintError
 		// (with m_constraintError we set a desired velocity for the affected body(es))
 		// (with m_constraintError we set a desired velocity for the affected body(es))
-		// however in practice any value is fine as long as it is greater then the "proper" velocity,
+		// however in practice any value is fine as long as it is greater than the "proper" velocity,
 		// because the m_lowerLimit and the m_upperLimit will determinate the strength of the final pulling force
 		// because the m_lowerLimit and the m_upperLimit will determinate the strength of the final pulling force
 		// so it is much simpler (and more robust) just to simply use inf (with the proper sign)
 		// so it is much simpler (and more robust) just to simply use inf (with the proper sign)
 		// (Even with our best intent the "new" velocity is only an estimation. If we underestimate
 		// (Even with our best intent the "new" velocity is only an estimation. If we underestimate
@@ -1085,7 +1086,7 @@ void btGeneric6DofSpring2Constraint::setServoTarget(int index, btScalar targetOr
 		btScalar target = targetOrg + SIMD_PI;
 		btScalar target = targetOrg + SIMD_PI;
 		if (1)
 		if (1)
 		{
 		{
-			btScalar m = target - SIMD_2_PI * floor(target / SIMD_2_PI);
+			btScalar m = target - SIMD_2_PI * std::floor(target / SIMD_2_PI);
 			// handle boundary cases resulted from floating-point cut off:
 			// handle boundary cases resulted from floating-point cut off:
 			{
 			{
 				if (m >= SIMD_2_PI)
 				if (m >= SIMD_2_PI)

+ 1 - 1
thirdparty/bullet/BulletDynamics/ConstraintSolver/btGeneric6DofSpring2Constraint.h

@@ -294,7 +294,7 @@ protected:
 	bool m_hasStaticBody;
 	bool m_hasStaticBody;
 	int m_flags;
 	int m_flags;
 
 
-	btGeneric6DofSpring2Constraint& operator=(btGeneric6DofSpring2Constraint&)
+	btGeneric6DofSpring2Constraint& operator=(const btGeneric6DofSpring2Constraint&)
 	{
 	{
 		btAssert(0);
 		btAssert(0);
 		return *this;
 		return *this;

File diff suppressed because it is too large
+ 551 - 129
thirdparty/bullet/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.cpp


+ 147 - 17
thirdparty/bullet/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.h

@@ -29,10 +29,91 @@ class btCollisionObject;
 
 
 typedef btScalar (*btSingleConstraintRowSolver)(btSolverBody&, btSolverBody&, const btSolverConstraint&);
 typedef btScalar (*btSingleConstraintRowSolver)(btSolverBody&, btSolverBody&, const btSolverConstraint&);
 
 
+struct btSISolverSingleIterationData
+{
+	btAlignedObjectArray<btSolverBody>& m_tmpSolverBodyPool;
+	btConstraintArray& m_tmpSolverContactConstraintPool;
+	btConstraintArray& m_tmpSolverNonContactConstraintPool;
+	btConstraintArray& m_tmpSolverContactFrictionConstraintPool;
+	btConstraintArray& m_tmpSolverContactRollingFrictionConstraintPool;
+
+	btAlignedObjectArray<int>& m_orderTmpConstraintPool;
+	btAlignedObjectArray<int>& m_orderNonContactConstraintPool;
+	btAlignedObjectArray<int>& m_orderFrictionConstraintPool;
+	btAlignedObjectArray<btTypedConstraint::btConstraintInfo1>& m_tmpConstraintSizesPool;
+	unsigned long& m_seed;
+
+	btSingleConstraintRowSolver& m_resolveSingleConstraintRowGeneric;
+	btSingleConstraintRowSolver& m_resolveSingleConstraintRowLowerLimit;
+	btSingleConstraintRowSolver& m_resolveSplitPenetrationImpulse;
+	btAlignedObjectArray<int>& m_kinematicBodyUniqueIdToSolverBodyTable;
+	int& m_fixedBodyId;
+	int& m_maxOverrideNumSolverIterations;
+	int getOrInitSolverBody(btCollisionObject & body, btScalar timeStep);
+	static void initSolverBody(btSolverBody * solverBody, btCollisionObject * collisionObject, btScalar timeStep);
+	int getSolverBody(btCollisionObject& body) const;
+
+
+	btSISolverSingleIterationData(btAlignedObjectArray<btSolverBody>& tmpSolverBodyPool,
+		btConstraintArray& tmpSolverContactConstraintPool,
+		btConstraintArray& tmpSolverNonContactConstraintPool,
+		btConstraintArray& tmpSolverContactFrictionConstraintPool,
+		btConstraintArray& tmpSolverContactRollingFrictionConstraintPool,
+		btAlignedObjectArray<int>& orderTmpConstraintPool,
+		btAlignedObjectArray<int>& orderNonContactConstraintPool,
+		btAlignedObjectArray<int>& orderFrictionConstraintPool,
+		btAlignedObjectArray<btTypedConstraint::btConstraintInfo1>& tmpConstraintSizesPool,
+		btSingleConstraintRowSolver& resolveSingleConstraintRowGeneric,
+		btSingleConstraintRowSolver& resolveSingleConstraintRowLowerLimit,
+		btSingleConstraintRowSolver& resolveSplitPenetrationImpulse,
+		btAlignedObjectArray<int>& kinematicBodyUniqueIdToSolverBodyTable,
+		unsigned long& seed,
+		int& fixedBodyId,
+		int& maxOverrideNumSolverIterations
+	)
+		:m_tmpSolverBodyPool(tmpSolverBodyPool),
+		m_tmpSolverContactConstraintPool(tmpSolverContactConstraintPool),
+		m_tmpSolverNonContactConstraintPool(tmpSolverNonContactConstraintPool),
+		m_tmpSolverContactFrictionConstraintPool(tmpSolverContactFrictionConstraintPool),
+		m_tmpSolverContactRollingFrictionConstraintPool(tmpSolverContactRollingFrictionConstraintPool),
+		m_orderTmpConstraintPool(orderTmpConstraintPool),
+		m_orderNonContactConstraintPool(orderNonContactConstraintPool),
+		m_orderFrictionConstraintPool(orderFrictionConstraintPool),
+		m_tmpConstraintSizesPool(tmpConstraintSizesPool),
+		m_seed(seed),
+		m_resolveSingleConstraintRowGeneric(resolveSingleConstraintRowGeneric),
+		m_resolveSingleConstraintRowLowerLimit(resolveSingleConstraintRowLowerLimit),
+		m_resolveSplitPenetrationImpulse(resolveSplitPenetrationImpulse),
+		m_kinematicBodyUniqueIdToSolverBodyTable(kinematicBodyUniqueIdToSolverBodyTable),
+		m_fixedBodyId(fixedBodyId),
+		m_maxOverrideNumSolverIterations(maxOverrideNumSolverIterations)
+	{
+	}
+};
+
+struct btSolverAnalyticsData
+{
+	btSolverAnalyticsData()
+	{
+		m_numSolverCalls = 0;
+		m_numIterationsUsed = -1;
+		m_remainingLeastSquaresResidual = -1;
+		m_islandId = -2;
+	}
+	int m_islandId;
+	int m_numBodies;
+	int m_numContactManifolds;
+	int m_numSolverCalls;
+	int m_numIterationsUsed;
+	double m_remainingLeastSquaresResidual;
+};
+
 ///The btSequentialImpulseConstraintSolver is a fast SIMD implementation of the Projected Gauss Seidel (iterative LCP) method.
 ///The btSequentialImpulseConstraintSolver is a fast SIMD implementation of the Projected Gauss Seidel (iterative LCP) method.
 ATTRIBUTE_ALIGNED16(class)
 ATTRIBUTE_ALIGNED16(class)
 btSequentialImpulseConstraintSolver : public btConstraintSolver
 btSequentialImpulseConstraintSolver : public btConstraintSolver
 {
 {
+	
+
 protected:
 protected:
 	btAlignedObjectArray<btSolverBody> m_tmpSolverBodyPool;
 	btAlignedObjectArray<btSolverBody> m_tmpSolverBodyPool;
 	btConstraintArray m_tmpSolverContactConstraintPool;
 	btConstraintArray m_tmpSolverContactConstraintPool;
@@ -64,26 +145,26 @@ protected:
 	btScalar m_leastSquaresResidual;
 	btScalar m_leastSquaresResidual;
 
 
 	void setupFrictionConstraint(btSolverConstraint & solverConstraint, const btVector3& normalAxis, int solverBodyIdA, int solverBodyIdB,
 	void setupFrictionConstraint(btSolverConstraint & solverConstraint, const btVector3& normalAxis, int solverBodyIdA, int solverBodyIdB,
-								 btManifoldPoint& cp, const btVector3& rel_pos1, const btVector3& rel_pos2,
-								 btCollisionObject* colObj0, btCollisionObject* colObj1, btScalar relaxation,
-								 const btContactSolverInfo& infoGlobal,
-								 btScalar desiredVelocity = 0., btScalar cfmSlip = 0.);
+		btManifoldPoint& cp, const btVector3& rel_pos1, const btVector3& rel_pos2,
+		btCollisionObject* colObj0, btCollisionObject* colObj1, btScalar relaxation,
+		const btContactSolverInfo& infoGlobal,
+		btScalar desiredVelocity = 0., btScalar cfmSlip = 0.);
 
 
 	void setupTorsionalFrictionConstraint(btSolverConstraint & solverConstraint, const btVector3& normalAxis, int solverBodyIdA, int solverBodyIdB,
 	void setupTorsionalFrictionConstraint(btSolverConstraint & solverConstraint, const btVector3& normalAxis, int solverBodyIdA, int solverBodyIdB,
-										  btManifoldPoint& cp, btScalar combinedTorsionalFriction, const btVector3& rel_pos1, const btVector3& rel_pos2,
-										  btCollisionObject* colObj0, btCollisionObject* colObj1, btScalar relaxation,
-										  btScalar desiredVelocity = 0., btScalar cfmSlip = 0.);
+		btManifoldPoint& cp, btScalar combinedTorsionalFriction, const btVector3& rel_pos1, const btVector3& rel_pos2,
+		btCollisionObject* colObj0, btCollisionObject* colObj1, btScalar relaxation,
+		btScalar desiredVelocity = 0., btScalar cfmSlip = 0.);
 
 
 	btSolverConstraint& addFrictionConstraint(const btVector3& normalAxis, int solverBodyIdA, int solverBodyIdB, int frictionIndex, btManifoldPoint& cp, const btVector3& rel_pos1, const btVector3& rel_pos2, btCollisionObject* colObj0, btCollisionObject* colObj1, btScalar relaxation, const btContactSolverInfo& infoGlobal, btScalar desiredVelocity = 0., btScalar cfmSlip = 0.);
 	btSolverConstraint& addFrictionConstraint(const btVector3& normalAxis, int solverBodyIdA, int solverBodyIdB, int frictionIndex, btManifoldPoint& cp, const btVector3& rel_pos1, const btVector3& rel_pos2, btCollisionObject* colObj0, btCollisionObject* colObj1, btScalar relaxation, const btContactSolverInfo& infoGlobal, btScalar desiredVelocity = 0., btScalar cfmSlip = 0.);
 	btSolverConstraint& addTorsionalFrictionConstraint(const btVector3& normalAxis, int solverBodyIdA, int solverBodyIdB, int frictionIndex, btManifoldPoint& cp, btScalar torsionalFriction, const btVector3& rel_pos1, const btVector3& rel_pos2, btCollisionObject* colObj0, btCollisionObject* colObj1, btScalar relaxation, btScalar desiredVelocity = 0, btScalar cfmSlip = 0.f);
 	btSolverConstraint& addTorsionalFrictionConstraint(const btVector3& normalAxis, int solverBodyIdA, int solverBodyIdB, int frictionIndex, btManifoldPoint& cp, btScalar torsionalFriction, const btVector3& rel_pos1, const btVector3& rel_pos2, btCollisionObject* colObj0, btCollisionObject* colObj1, btScalar relaxation, btScalar desiredVelocity = 0, btScalar cfmSlip = 0.f);
 
 
 	void setupContactConstraint(btSolverConstraint & solverConstraint, int solverBodyIdA, int solverBodyIdB, btManifoldPoint& cp,
 	void setupContactConstraint(btSolverConstraint & solverConstraint, int solverBodyIdA, int solverBodyIdB, btManifoldPoint& cp,
-								const btContactSolverInfo& infoGlobal, btScalar& relaxation, const btVector3& rel_pos1, const btVector3& rel_pos2);
+		const btContactSolverInfo& infoGlobal, btScalar& relaxation, const btVector3& rel_pos1, const btVector3& rel_pos2);
 
 
 	static void applyAnisotropicFriction(btCollisionObject * colObj, btVector3 & frictionDirection, int frictionMode);
 	static void applyAnisotropicFriction(btCollisionObject * colObj, btVector3 & frictionDirection, int frictionMode);
 
 
 	void setFrictionConstraintImpulse(btSolverConstraint & solverConstraint, int solverBodyIdA, int solverBodyIdB,
 	void setFrictionConstraintImpulse(btSolverConstraint & solverConstraint, int solverBodyIdA, int solverBodyIdB,
-									  btManifoldPoint& cp, const btContactSolverInfo& infoGlobal);
+		btManifoldPoint& cp, const btContactSolverInfo& infoGlobal);
 
 
 	///m_btSeed2 is used for re-arranging the constraint rows. improves convergence/quality of friction
 	///m_btSeed2 is used for re-arranging the constraint rows. improves convergence/quality of friction
 	unsigned long m_btSeed2;
 	unsigned long m_btSeed2;
@@ -97,6 +178,7 @@ protected:
 	virtual void convertJoints(btTypedConstraint * *constraints, int numConstraints, const btContactSolverInfo& infoGlobal);
 	virtual void convertJoints(btTypedConstraint * *constraints, int numConstraints, const btContactSolverInfo& infoGlobal);
 	void convertJoint(btSolverConstraint * currentConstraintRow, btTypedConstraint * constraint, const btTypedConstraint::btConstraintInfo1& info1, int solverBodyIdA, int solverBodyIdB, const btContactSolverInfo& infoGlobal);
 	void convertJoint(btSolverConstraint * currentConstraintRow, btTypedConstraint * constraint, const btTypedConstraint::btConstraintInfo1& info1, int solverBodyIdA, int solverBodyIdB, const btContactSolverInfo& infoGlobal);
 
 
+
 	virtual void convertBodies(btCollisionObject * *bodies, int numBodies, const btContactSolverInfo& infoGlobal);
 	virtual void convertBodies(btCollisionObject * *bodies, int numBodies, const btContactSolverInfo& infoGlobal);
 
 
 	btScalar resolveSplitPenetrationSIMD(btSolverBody & bodyA, btSolverBody & bodyB, const btSolverConstraint& contactConstraint)
 	btScalar resolveSplitPenetrationSIMD(btSolverBody & bodyA, btSolverBody & bodyB, const btSolverConstraint& contactConstraint)
@@ -122,7 +204,8 @@ protected:
 		return m_resolveSplitPenetrationImpulse(bodyA, bodyB, contactConstraint);
 		return m_resolveSplitPenetrationImpulse(bodyA, bodyB, contactConstraint);
 	}
 	}
 
 
-protected:
+public:
+
 	void writeBackContacts(int iBegin, int iEnd, const btContactSolverInfo& infoGlobal);
 	void writeBackContacts(int iBegin, int iEnd, const btContactSolverInfo& infoGlobal);
 	void writeBackJoints(int iBegin, int iEnd, const btContactSolverInfo& infoGlobal);
 	void writeBackJoints(int iBegin, int iEnd, const btContactSolverInfo& infoGlobal);
 	void writeBackBodies(int iBegin, int iEnd, const btContactSolverInfo& infoGlobal);
 	void writeBackBodies(int iBegin, int iEnd, const btContactSolverInfo& infoGlobal);
@@ -130,6 +213,7 @@ protected:
 	virtual btScalar solveGroupCacheFriendlyFinish(btCollisionObject * *bodies, int numBodies, const btContactSolverInfo& infoGlobal);
 	virtual btScalar solveGroupCacheFriendlyFinish(btCollisionObject * *bodies, int numBodies, const btContactSolverInfo& infoGlobal);
 	virtual btScalar solveSingleIteration(int iteration, btCollisionObject** bodies, int numBodies, btPersistentManifold** manifoldPtr, int numManifolds, btTypedConstraint** constraints, int numConstraints, const btContactSolverInfo& infoGlobal, btIDebugDraw* debugDrawer);
 	virtual btScalar solveSingleIteration(int iteration, btCollisionObject** bodies, int numBodies, btPersistentManifold** manifoldPtr, int numManifolds, btTypedConstraint** constraints, int numConstraints, const btContactSolverInfo& infoGlobal, btIDebugDraw* debugDrawer);
 
 
+
 	virtual btScalar solveGroupCacheFriendlySetup(btCollisionObject * *bodies, int numBodies, btPersistentManifold** manifoldPtr, int numManifolds, btTypedConstraint** constraints, int numConstraints, const btContactSolverInfo& infoGlobal, btIDebugDraw* debugDrawer);
 	virtual btScalar solveGroupCacheFriendlySetup(btCollisionObject * *bodies, int numBodies, btPersistentManifold** manifoldPtr, int numManifolds, btTypedConstraint** constraints, int numConstraints, const btContactSolverInfo& infoGlobal, btIDebugDraw* debugDrawer);
 	virtual btScalar solveGroupCacheFriendlyIterations(btCollisionObject * *bodies, int numBodies, btPersistentManifold** manifoldPtr, int numManifolds, btTypedConstraint** constraints, int numConstraints, const btContactSolverInfo& infoGlobal, btIDebugDraw* debugDrawer);
 	virtual btScalar solveGroupCacheFriendlyIterations(btCollisionObject * *bodies, int numBodies, btPersistentManifold** manifoldPtr, int numManifolds, btTypedConstraint** constraints, int numConstraints, const btContactSolverInfo& infoGlobal, btIDebugDraw* debugDrawer);
 
 
@@ -141,13 +225,52 @@ public:
 
 
 	virtual btScalar solveGroup(btCollisionObject * *bodies, int numBodies, btPersistentManifold** manifold, int numManifolds, btTypedConstraint** constraints, int numConstraints, const btContactSolverInfo& info, btIDebugDraw* debugDrawer, btDispatcher* dispatcher);
 	virtual btScalar solveGroup(btCollisionObject * *bodies, int numBodies, btPersistentManifold** manifold, int numManifolds, btTypedConstraint** constraints, int numConstraints, const btContactSolverInfo& info, btIDebugDraw* debugDrawer, btDispatcher* dispatcher);
 
 
+	static btScalar solveSingleIterationInternal(btSISolverSingleIterationData& siData, int iteration, btTypedConstraint** constraints, int numConstraints, const btContactSolverInfo& infoGlobal);
+	static void convertBodiesInternal(btSISolverSingleIterationData& siData, btCollisionObject** bodies, int numBodies, const btContactSolverInfo& infoGlobal);
+	static void convertJointsInternal(btSISolverSingleIterationData& siData, btTypedConstraint** constraints, int numConstraints, const btContactSolverInfo& infoGlobal);
+	static void convertContactInternal(btSISolverSingleIterationData& siData, btPersistentManifold * manifold, const btContactSolverInfo& infoGlobal);
+	static void setupContactConstraintInternal(btSISolverSingleIterationData& siData, btSolverConstraint& solverConstraint, int solverBodyIdA, int solverBodyIdB, btManifoldPoint& cp, const btContactSolverInfo& infoGlobal, btScalar& relaxation,
+		const btVector3& rel_pos1, const btVector3& rel_pos2);
+	static btScalar restitutionCurveInternal(btScalar rel_vel, btScalar restitution, btScalar velocityThreshold);
+	static btSolverConstraint& addTorsionalFrictionConstraintInternal(btAlignedObjectArray<btSolverBody>& tmpSolverBodyPool, btConstraintArray& tmpSolverContactRollingFrictionConstraintPool, const btVector3& normalAxis, int solverBodyIdA, int solverBodyIdB, int frictionIndex, btManifoldPoint& cp, btScalar combinedTorsionalFriction, const btVector3& rel_pos1, const btVector3& rel_pos2, btCollisionObject* colObj0, btCollisionObject* colObj1, btScalar relaxation, btScalar desiredVelocity = 0, btScalar cfmSlip = 0.);
+	static void setupTorsionalFrictionConstraintInternal(btAlignedObjectArray<btSolverBody>& tmpSolverBodyPool, btSolverConstraint& solverConstraint, const btVector3& normalAxis1, int solverBodyIdA, int solverBodyIdB,
+		btManifoldPoint& cp, btScalar combinedTorsionalFriction, const btVector3& rel_pos1, const btVector3& rel_pos2,
+		btCollisionObject* colObj0, btCollisionObject* colObj1, btScalar relaxation,
+		btScalar desiredVelocity, btScalar cfmSlip);
+	static void setupFrictionConstraintInternal(btAlignedObjectArray<btSolverBody>& tmpSolverBodyPool, btSolverConstraint& solverConstraint, const btVector3& normalAxis, int solverBodyIdA, int solverBodyIdB, btManifoldPoint& cp, const btVector3& rel_pos1, const btVector3& rel_pos2, btCollisionObject* colObj0, btCollisionObject* colObj1, btScalar relaxation, const btContactSolverInfo& infoGlobal, btScalar desiredVelocity, btScalar cfmSlip);
+	static btSolverConstraint& addFrictionConstraintInternal(btAlignedObjectArray<btSolverBody>& tmpSolverBodyPool, btConstraintArray& tmpSolverContactFrictionConstraintPool, const btVector3& normalAxis, int solverBodyIdA, int solverBodyIdB, int frictionIndex, btManifoldPoint& cp, const btVector3& rel_pos1, const btVector3& rel_pos2, btCollisionObject* colObj0, btCollisionObject* colObj1, btScalar relaxation, const btContactSolverInfo& infoGlobal, btScalar desiredVelocity = 0., btScalar cfmSlip = 0.);
+	static void setFrictionConstraintImpulseInternal(btAlignedObjectArray<btSolverBody>& tmpSolverBodyPool, btConstraintArray& tmpSolverContactFrictionConstraintPool,
+
+		btSolverConstraint& solverConstraint,
+		int solverBodyIdA, int solverBodyIdB,
+		btManifoldPoint& cp, const btContactSolverInfo& infoGlobal);
+	static void convertJointInternal(btAlignedObjectArray<btSolverBody>& tmpSolverBodyPool,
+		int& maxOverrideNumSolverIterations,
+		btSolverConstraint* currentConstraintRow,
+		btTypedConstraint* constraint,
+		const btTypedConstraint::btConstraintInfo1& info1,
+		int solverBodyIdA,
+		int solverBodyIdB,
+		const btContactSolverInfo& infoGlobal);
+
+	static btScalar solveGroupCacheFriendlyFinishInternal(btSISolverSingleIterationData& siData, btCollisionObject** bodies, int numBodies, const btContactSolverInfo& infoGlobal);
+
+	static void writeBackContactsInternal(btConstraintArray& tmpSolverContactConstraintPool, btConstraintArray& tmpSolverContactFrictionConstraintPool, int iBegin, int iEnd, const btContactSolverInfo& infoGlobal);
+
+	static void writeBackJointsInternal(btConstraintArray& tmpSolverNonContactConstraintPool, int iBegin, int iEnd, const btContactSolverInfo& infoGlobal);
+	static void writeBackBodiesInternal(btAlignedObjectArray<btSolverBody>& tmpSolverBodyPool, int iBegin, int iEnd, const btContactSolverInfo& infoGlobal);
+	static void solveGroupCacheFriendlySplitImpulseIterationsInternal(btSISolverSingleIterationData& siData, btCollisionObject** bodies, int numBodies, btPersistentManifold** manifoldPtr, int numManifolds, btTypedConstraint** constraints, int numConstraints, const btContactSolverInfo& infoGlobal, btIDebugDraw* debugDrawer);
+
+
 	///clear internal cached data and reset random seed
 	///clear internal cached data and reset random seed
 	virtual void reset();
 	virtual void reset();
 
 
 	unsigned long btRand2();
 	unsigned long btRand2();
-
 	int btRandInt2(int n);
 	int btRandInt2(int n);
 
 
+	static unsigned long btRand2a(unsigned long& seed);
+	static int btRandInt2a(int n, unsigned long& seed);
+
 	void setRandSeed(unsigned long seed)
 	void setRandSeed(unsigned long seed)
 	{
 	{
 		m_btSeed2 = seed;
 		m_btSeed2 = seed;
@@ -179,15 +302,22 @@ public:
 		m_resolveSingleConstraintRowLowerLimit = rowSolver;
 		m_resolveSingleConstraintRowLowerLimit = rowSolver;
 	}
 	}
 
 
+
+
 	///Various implementations of solving a single constraint row using a generic equality constraint, using scalar reference, SSE2 or SSE4
 	///Various implementations of solving a single constraint row using a generic equality constraint, using scalar reference, SSE2 or SSE4
-	btSingleConstraintRowSolver getScalarConstraintRowSolverGeneric();
-	btSingleConstraintRowSolver getSSE2ConstraintRowSolverGeneric();
-	btSingleConstraintRowSolver getSSE4_1ConstraintRowSolverGeneric();
+	static btSingleConstraintRowSolver getScalarConstraintRowSolverGeneric();
+	static btSingleConstraintRowSolver getSSE2ConstraintRowSolverGeneric();
+	static btSingleConstraintRowSolver getSSE4_1ConstraintRowSolverGeneric();
 
 
 	///Various implementations of solving a single constraint row using an inequality (lower limit) constraint, using scalar reference, SSE2 or SSE4
 	///Various implementations of solving a single constraint row using an inequality (lower limit) constraint, using scalar reference, SSE2 or SSE4
-	btSingleConstraintRowSolver getScalarConstraintRowSolverLowerLimit();
-	btSingleConstraintRowSolver getSSE2ConstraintRowSolverLowerLimit();
-	btSingleConstraintRowSolver getSSE4_1ConstraintRowSolverLowerLimit();
+	static btSingleConstraintRowSolver getScalarConstraintRowSolverLowerLimit();
+	static btSingleConstraintRowSolver getSSE2ConstraintRowSolverLowerLimit();
+	static btSingleConstraintRowSolver getSSE4_1ConstraintRowSolverLowerLimit();
+
+	static btSingleConstraintRowSolver getScalarSplitPenetrationImpulseGeneric();
+	static btSingleConstraintRowSolver getSSE2SplitPenetrationImpulseGeneric();
+
+	btSolverAnalyticsData m_analyticsData;
 };
 };
 
 
 #endif  //BT_SEQUENTIAL_IMPULSE_CONSTRAINT_SOLVER_H
 #endif  //BT_SEQUENTIAL_IMPULSE_CONSTRAINT_SOLVER_H

+ 2 - 2
thirdparty/bullet/BulletDynamics/Dynamics/btSimulationIslandManagerMt.cpp

@@ -65,7 +65,7 @@ inline int getIslandId(const btPersistentManifold* lhs)
 	return islandId;
 	return islandId;
 }
 }
 
 
-SIMD_FORCE_INLINE int btGetConstraintIslandId(const btTypedConstraint* lhs)
+SIMD_FORCE_INLINE int btGetConstraintIslandId1(const btTypedConstraint* lhs)
 {
 {
 	const btCollisionObject& rcolObj0 = lhs->getRigidBodyA();
 	const btCollisionObject& rcolObj0 = lhs->getRigidBodyA();
 	const btCollisionObject& rcolObj1 = lhs->getRigidBodyB();
 	const btCollisionObject& rcolObj1 = lhs->getRigidBodyB();
@@ -452,7 +452,7 @@ void btSimulationIslandManagerMt::addConstraintsToIslands(btAlignedObjectArray<b
 		btTypedConstraint* constraint = constraints[i];
 		btTypedConstraint* constraint = constraints[i];
 		if (constraint->isEnabled())
 		if (constraint->isEnabled())
 		{
 		{
-			int islandId = btGetConstraintIslandId(constraint);
+			int islandId = btGetConstraintIslandId1(constraint);
 			// if island is not sleeping,
 			// if island is not sleeping,
 			if (Island* island = getIsland(islandId))
 			if (Island* island = getIsland(islandId))
 			{
 			{

+ 11 - 4
thirdparty/bullet/BulletDynamics/Featherstone/btMultiBody.cpp

@@ -106,6 +106,7 @@ btMultiBody::btMultiBody(int n_links,
 	  m_fixedBase(fixedBase),
 	  m_fixedBase(fixedBase),
 	  m_awake(true),
 	  m_awake(true),
 	  m_canSleep(canSleep),
 	  m_canSleep(canSleep),
+	  m_canWakeup(true),
 	  m_sleepTimer(0),
 	  m_sleepTimer(0),
 	  m_userObjectPointer(0),
 	  m_userObjectPointer(0),
 	  m_userIndex2(-1),
 	  m_userIndex2(-1),
@@ -343,6 +344,7 @@ void btMultiBody::finalizeMultiDof()
 	m_deltaV.resize(6 + m_dofCount);
 	m_deltaV.resize(6 + m_dofCount);
 	m_realBuf.resize(6 + m_dofCount + m_dofCount * m_dofCount + 6 + m_dofCount);  //m_dofCount for joint-space vels + m_dofCount^2 for "D" matrices + delta-pos vector (6 base "vels" + joint "vels")
 	m_realBuf.resize(6 + m_dofCount + m_dofCount * m_dofCount + 6 + m_dofCount);  //m_dofCount for joint-space vels + m_dofCount^2 for "D" matrices + delta-pos vector (6 base "vels" + joint "vels")
 	m_vectorBuf.resize(2 * m_dofCount);                                           //two 3-vectors (i.e. one six-vector) for each system dof	("h" matrices)
 	m_vectorBuf.resize(2 * m_dofCount);                                           //two 3-vectors (i.e. one six-vector) for each system dof	("h" matrices)
+	m_matrixBuf.resize(m_links.size() + 1);
 	for (int i = 0; i < m_vectorBuf.size(); i++)
 	for (int i = 0; i < m_vectorBuf.size(); i++)
 	{
 	{
 		m_vectorBuf[i].setValue(0, 0, 0);
 		m_vectorBuf[i].setValue(0, 0, 0);
@@ -350,9 +352,9 @@ void btMultiBody::finalizeMultiDof()
 	updateLinksDofOffsets();
 	updateLinksDofOffsets();
 }
 }
 
 
-int btMultiBody::getParent(int i) const
+int btMultiBody::getParent(int link_num) const
 {
 {
-	return m_links[i].m_parent;
+	return m_links[link_num].m_parent;
 }
 }
 
 
 btScalar btMultiBody::getLinkMass(int i) const
 btScalar btMultiBody::getLinkMass(int i) const
@@ -1882,6 +1884,8 @@ void btMultiBody::checkMotionAndSleepIfRequired(btScalar timestep)
 		return;
 		return;
 	}
 	}
 
 
+	
+
 	// motion is computed as omega^2 + v^2 + (sum of squares of joint velocities)
 	// motion is computed as omega^2 + v^2 + (sum of squares of joint velocities)
 	btScalar motion = 0;
 	btScalar motion = 0;
 	{
 	{
@@ -1900,8 +1904,11 @@ void btMultiBody::checkMotionAndSleepIfRequired(btScalar timestep)
 	else
 	else
 	{
 	{
 		m_sleepTimer = 0;
 		m_sleepTimer = 0;
-		if (!m_awake)
-			wakeUp();
+		if (m_canWakeup)
+		{
+			if (!m_awake)
+				wakeUp();
+		}
 	}
 	}
 }
 }
 
 

+ 33 - 12
thirdparty/bullet/BulletDynamics/Featherstone/btMultiBody.h

@@ -65,7 +65,7 @@ public:
 	virtual ~btMultiBody();
 	virtual ~btMultiBody();
 
 
 	//note: fixed link collision with parent is always disabled
 	//note: fixed link collision with parent is always disabled
-	void setupFixed(int linkIndex,
+	void setupFixed(int i, //linkIndex
 					btScalar mass,
 					btScalar mass,
 					const btVector3 &inertia,
 					const btVector3 &inertia,
 					int parent,
 					int parent,
@@ -83,7 +83,7 @@ public:
 						const btVector3 &thisPivotToThisComOffset,
 						const btVector3 &thisPivotToThisComOffset,
 						bool disableParentCollision);
 						bool disableParentCollision);
 
 
-	void setupRevolute(int linkIndex,  // 0 to num_links-1
+	void setupRevolute(int i,  // 0 to num_links-1
 					   btScalar mass,
 					   btScalar mass,
 					   const btVector3 &inertia,
 					   const btVector3 &inertia,
 					   int parentIndex,
 					   int parentIndex,
@@ -93,7 +93,7 @@ public:
 					   const btVector3 &thisPivotToThisComOffset,    // vector from joint axis to my COM, in MY frame
 					   const btVector3 &thisPivotToThisComOffset,    // vector from joint axis to my COM, in MY frame
 					   bool disableParentCollision = false);
 					   bool disableParentCollision = false);
 
 
-	void setupSpherical(int linkIndex,  // 0 to num_links-1
+	void setupSpherical(int i,  // linkIndex, 0 to num_links-1
 						btScalar mass,
 						btScalar mass,
 						const btVector3 &inertia,
 						const btVector3 &inertia,
 						int parent,
 						int parent,
@@ -182,7 +182,10 @@ public:
 	// get/set pos/vel/rot/omega for the base link
 	// get/set pos/vel/rot/omega for the base link
 	//
 	//
 
 
-	const btVector3 &getBasePos() const { return m_basePos; }  // in world frame
+	const btVector3 &getBasePos() const 
+	{ 
+		return m_basePos; 
+	}  // in world frame
 	const btVector3 getBaseVel() const
 	const btVector3 getBaseVel() const
 	{
 	{
 		return btVector3(m_realBuf[3], m_realBuf[4], m_realBuf[5]);
 		return btVector3(m_realBuf[3], m_realBuf[4], m_realBuf[5]);
@@ -274,15 +277,15 @@ public:
 	//
 	//
 	// transform vectors in local frame of link i to world frame (or vice versa)
 	// transform vectors in local frame of link i to world frame (or vice versa)
 	//
 	//
-	btVector3 localPosToWorld(int i, const btVector3 &vec) const;
-	btVector3 localDirToWorld(int i, const btVector3 &vec) const;
-	btVector3 worldPosToLocal(int i, const btVector3 &vec) const;
-	btVector3 worldDirToLocal(int i, const btVector3 &vec) const;
+	btVector3 localPosToWorld(int i, const btVector3 &local_pos) const;
+	btVector3 localDirToWorld(int i, const btVector3 &local_dir) const;
+	btVector3 worldPosToLocal(int i, const btVector3 &world_pos) const;
+	btVector3 worldDirToLocal(int i, const btVector3 &world_dir) const;
 
 
 	//
 	//
 	// transform a frame in local coordinate to a frame in world coordinate
 	// transform a frame in local coordinate to a frame in world coordinate
 	//
 	//
-	btMatrix3x3 localFrameToWorld(int i, const btMatrix3x3 &mat) const;
+	btMatrix3x3 localFrameToWorld(int i, const btMatrix3x3 &local_frame) const;
 
 
 	//
 	//
 	// calculate kinetic energy and angular momentum
 	// calculate kinetic energy and angular momentum
@@ -451,7 +454,10 @@ public:
 	//
 	//
 	void setCanSleep(bool canSleep)
 	void setCanSleep(bool canSleep)
 	{
 	{
-		m_canSleep = canSleep;
+		if (m_canWakeup)
+		{
+			m_canSleep = canSleep;
+		}
 	}
 	}
 
 
 	bool getCanSleep() const
 	bool getCanSleep() const
@@ -459,6 +465,15 @@ public:
 		return m_canSleep;
 		return m_canSleep;
 	}
 	}
 
 
+	bool getCanWakeup() const
+	{
+		return m_canWakeup;
+	}
+	
+	void setCanWakeup(bool canWakeup) 
+	{
+		m_canWakeup = canWakeup;
+	}
 	bool isAwake() const { return m_awake; }
 	bool isAwake() const { return m_awake; }
 	void wakeUp();
 	void wakeUp();
 	void goToSleep();
 	void goToSleep();
@@ -469,6 +484,11 @@ public:
 		return m_fixedBase;
 		return m_fixedBase;
 	}
 	}
 
 
+	void setFixedBase(bool fixedBase)
+	{
+		m_fixedBase = fixedBase;
+	}
+
 	int getCompanionId() const
 	int getCompanionId() const
 	{
 	{
 		return m_companionId;
 		return m_companionId;
@@ -556,11 +576,11 @@ public:
 	{
 	{
 		return m_internalNeedsJointFeedback;
 		return m_internalNeedsJointFeedback;
 	}
 	}
-	void forwardKinematics(btAlignedObjectArray<btQuaternion> & scratch_q, btAlignedObjectArray<btVector3> & scratch_m);
+	void forwardKinematics(btAlignedObjectArray<btQuaternion>& world_to_local, btAlignedObjectArray<btVector3> & local_origin);
 
 
 	void compTreeLinkVelocities(btVector3 * omega, btVector3 * vel) const;
 	void compTreeLinkVelocities(btVector3 * omega, btVector3 * vel) const;
 
 
-	void updateCollisionObjectWorldTransforms(btAlignedObjectArray<btQuaternion> & scratch_q, btAlignedObjectArray<btVector3> & scratch_m);
+	void updateCollisionObjectWorldTransforms(btAlignedObjectArray<btQuaternion> & world_to_local, btAlignedObjectArray<btVector3> & local_origin);
 
 
 	virtual int calculateSerializeBufferSize() const;
 	virtual int calculateSerializeBufferSize() const;
 
 
@@ -688,6 +708,7 @@ private:
 	// Sleep parameters.
 	// Sleep parameters.
 	bool m_awake;
 	bool m_awake;
 	bool m_canSleep;
 	bool m_canSleep;
+	bool m_canWakeup;
 	btScalar m_sleepTimer;
 	btScalar m_sleepTimer;
 
 
 	void *m_userObjectPointer;
 	void *m_userObjectPointer;

+ 78 - 8
thirdparty/bullet/BulletDynamics/Featherstone/btMultiBodyConstraintSolver.cpp

@@ -70,6 +70,30 @@ btScalar btMultiBodyConstraintSolver::solveSingleIteration(int iteration, btColl
 	//solve featherstone frictional contact
 	//solve featherstone frictional contact
 	if (infoGlobal.m_solverMode & SOLVER_USE_2_FRICTION_DIRECTIONS && ((infoGlobal.m_solverMode & SOLVER_DISABLE_IMPLICIT_CONE_FRICTION) == 0))
 	if (infoGlobal.m_solverMode & SOLVER_USE_2_FRICTION_DIRECTIONS && ((infoGlobal.m_solverMode & SOLVER_DISABLE_IMPLICIT_CONE_FRICTION) == 0))
 	{
 	{
+		for (int j1 = 0; j1 < this->m_multiBodySpinningFrictionContactConstraints.size(); j1++)
+		{
+			if (iteration < infoGlobal.m_numIterations)
+			{
+				int index = j1;
+
+				btMultiBodySolverConstraint& frictionConstraint = m_multiBodySpinningFrictionContactConstraints[index];
+				btScalar totalImpulse = m_multiBodyNormalContactConstraints[frictionConstraint.m_frictionIndex].m_appliedImpulse;
+				//adjust friction limits here
+				if (totalImpulse > btScalar(0))
+				{
+					frictionConstraint.m_lowerLimit = -(frictionConstraint.m_friction * totalImpulse);
+					frictionConstraint.m_upperLimit = frictionConstraint.m_friction * totalImpulse;
+					btScalar residual = resolveSingleConstraintRowGeneric(frictionConstraint);
+					leastSquaredResidual = btMax(leastSquaredResidual, residual * residual);
+
+					if (frictionConstraint.m_multiBodyA)
+						frictionConstraint.m_multiBodyA->setPosUpdated(false);
+					if (frictionConstraint.m_multiBodyB)
+						frictionConstraint.m_multiBodyB->setPosUpdated(false);
+				}
+			}
+		}
+
 		for (int j1 = 0; j1 < this->m_multiBodyTorsionalFrictionContactConstraints.size(); j1++)
 		for (int j1 = 0; j1 < this->m_multiBodyTorsionalFrictionContactConstraints.size(); j1++)
 		{
 		{
 			if (iteration < infoGlobal.m_numIterations)
 			if (iteration < infoGlobal.m_numIterations)
@@ -78,18 +102,29 @@ btScalar btMultiBodyConstraintSolver::solveSingleIteration(int iteration, btColl
 
 
 				btMultiBodySolverConstraint& frictionConstraint = m_multiBodyTorsionalFrictionContactConstraints[index];
 				btMultiBodySolverConstraint& frictionConstraint = m_multiBodyTorsionalFrictionContactConstraints[index];
 				btScalar totalImpulse = m_multiBodyNormalContactConstraints[frictionConstraint.m_frictionIndex].m_appliedImpulse;
 				btScalar totalImpulse = m_multiBodyNormalContactConstraints[frictionConstraint.m_frictionIndex].m_appliedImpulse;
+				j1++;
+				int index2 = j1;
+				btMultiBodySolverConstraint& frictionConstraintB = m_multiBodyTorsionalFrictionContactConstraints[index2];
 				//adjust friction limits here
 				//adjust friction limits here
-				if (totalImpulse > btScalar(0))
+				if (totalImpulse > btScalar(0) && frictionConstraint.m_frictionIndex == frictionConstraintB.m_frictionIndex)
 				{
 				{
 					frictionConstraint.m_lowerLimit = -(frictionConstraint.m_friction * totalImpulse);
 					frictionConstraint.m_lowerLimit = -(frictionConstraint.m_friction * totalImpulse);
 					frictionConstraint.m_upperLimit = frictionConstraint.m_friction * totalImpulse;
 					frictionConstraint.m_upperLimit = frictionConstraint.m_friction * totalImpulse;
-					btScalar residual = resolveSingleConstraintRowGeneric(frictionConstraint);
+					frictionConstraintB.m_lowerLimit = -(frictionConstraintB.m_friction * totalImpulse);
+					frictionConstraintB.m_upperLimit = frictionConstraintB.m_friction * totalImpulse;
+
+					btScalar residual = resolveConeFrictionConstraintRows(frictionConstraint, frictionConstraintB);
 					leastSquaredResidual = btMax(leastSquaredResidual, residual * residual);
 					leastSquaredResidual = btMax(leastSquaredResidual, residual * residual);
 
 
 					if (frictionConstraint.m_multiBodyA)
 					if (frictionConstraint.m_multiBodyA)
 						frictionConstraint.m_multiBodyA->setPosUpdated(false);
 						frictionConstraint.m_multiBodyA->setPosUpdated(false);
 					if (frictionConstraint.m_multiBodyB)
 					if (frictionConstraint.m_multiBodyB)
 						frictionConstraint.m_multiBodyB->setPosUpdated(false);
 						frictionConstraint.m_multiBodyB->setPosUpdated(false);
+
+					if (frictionConstraintB.m_multiBodyA)
+						frictionConstraintB.m_multiBodyA->setPosUpdated(false);
+					if (frictionConstraintB.m_multiBodyB)
+						frictionConstraintB.m_multiBodyB->setPosUpdated(false);
 				}
 				}
 			}
 			}
 		}
 		}
@@ -164,6 +199,7 @@ btScalar btMultiBodyConstraintSolver::solveGroupCacheFriendlySetup(btCollisionOb
 	m_multiBodyNormalContactConstraints.resize(0);
 	m_multiBodyNormalContactConstraints.resize(0);
 	m_multiBodyFrictionContactConstraints.resize(0);
 	m_multiBodyFrictionContactConstraints.resize(0);
 	m_multiBodyTorsionalFrictionContactConstraints.resize(0);
 	m_multiBodyTorsionalFrictionContactConstraints.resize(0);
+	m_multiBodySpinningFrictionContactConstraints.resize(0);
 
 
 	m_data.m_jacobians.resize(0);
 	m_data.m_jacobians.resize(0);
 	m_data.m_deltaVelocitiesUnitImpulse.resize(0);
 	m_data.m_deltaVelocitiesUnitImpulse.resize(0);
@@ -1169,6 +1205,43 @@ btMultiBodySolverConstraint& btMultiBodyConstraintSolver::addMultiBodyTorsionalF
 	return solverConstraint;
 	return solverConstraint;
 }
 }
 
 
+btMultiBodySolverConstraint& btMultiBodyConstraintSolver::addMultiBodySpinningFrictionConstraint(const btVector3& normalAxis, btPersistentManifold* manifold, int frictionIndex, btManifoldPoint& cp,
+	btScalar combinedTorsionalFriction,
+	btCollisionObject* colObj0, btCollisionObject* colObj1, btScalar relaxation, const btContactSolverInfo& infoGlobal, btScalar desiredVelocity, btScalar cfmSlip)
+{
+	BT_PROFILE("addMultiBodyRollingFrictionConstraint");
+
+	btMultiBodySolverConstraint& solverConstraint = m_multiBodySpinningFrictionContactConstraints.expandNonInitializing();
+	solverConstraint.m_orgConstraint = 0;
+	solverConstraint.m_orgDofIndex = -1;
+
+	solverConstraint.m_frictionIndex = frictionIndex;
+	bool isFriction = true;
+
+	const btMultiBodyLinkCollider* fcA = btMultiBodyLinkCollider::upcast(manifold->getBody0());
+	const btMultiBodyLinkCollider* fcB = btMultiBodyLinkCollider::upcast(manifold->getBody1());
+
+	btMultiBody* mbA = fcA ? fcA->m_multiBody : 0;
+	btMultiBody* mbB = fcB ? fcB->m_multiBody : 0;
+
+	int solverBodyIdA = mbA ? -1 : getOrInitSolverBody(*colObj0, infoGlobal.m_timeStep);
+	int solverBodyIdB = mbB ? -1 : getOrInitSolverBody(*colObj1, infoGlobal.m_timeStep);
+
+	solverConstraint.m_solverBodyIdA = solverBodyIdA;
+	solverConstraint.m_solverBodyIdB = solverBodyIdB;
+	solverConstraint.m_multiBodyA = mbA;
+	if (mbA)
+		solverConstraint.m_linkA = fcA->m_link;
+
+	solverConstraint.m_multiBodyB = mbB;
+	if (mbB)
+		solverConstraint.m_linkB = fcB->m_link;
+
+	solverConstraint.m_originalContactPoint = &cp;
+
+	setupMultiBodyTorsionalFrictionConstraint(solverConstraint, normalAxis, cp, combinedTorsionalFriction, infoGlobal, relaxation, isFriction, desiredVelocity, cfmSlip);
+	return solverConstraint;
+}
 void btMultiBodyConstraintSolver::convertMultiBodyContact(btPersistentManifold* manifold, const btContactSolverInfo& infoGlobal)
 void btMultiBodyConstraintSolver::convertMultiBodyContact(btPersistentManifold* manifold, const btContactSolverInfo& infoGlobal)
 {
 {
 	const btMultiBodyLinkCollider* fcA = btMultiBodyLinkCollider::upcast(manifold->getBody0());
 	const btMultiBodyLinkCollider* fcA = btMultiBodyLinkCollider::upcast(manifold->getBody0());
@@ -1258,7 +1331,7 @@ void btMultiBodyConstraintSolver::convertMultiBodyContact(btPersistentManifold*
 			{
 			{
 				if (cp.m_combinedSpinningFriction > 0)
 				if (cp.m_combinedSpinningFriction > 0)
 				{
 				{
-					addMultiBodyTorsionalFrictionConstraint(cp.m_normalWorldOnB, manifold, frictionIndex, cp, cp.m_combinedSpinningFriction, colObj0, colObj1, relaxation, infoGlobal);
+					addMultiBodySpinningFrictionConstraint(cp.m_normalWorldOnB, manifold, frictionIndex, cp, cp.m_combinedSpinningFriction, colObj0, colObj1, relaxation, infoGlobal);
 				}
 				}
 				if (cp.m_combinedRollingFriction > 0)
 				if (cp.m_combinedRollingFriction > 0)
 				{
 				{
@@ -1267,11 +1340,8 @@ void btMultiBodyConstraintSolver::convertMultiBodyContact(btPersistentManifold*
 					applyAnisotropicFriction(colObj0, cp.m_lateralFrictionDir2, btCollisionObject::CF_ANISOTROPIC_ROLLING_FRICTION);
 					applyAnisotropicFriction(colObj0, cp.m_lateralFrictionDir2, btCollisionObject::CF_ANISOTROPIC_ROLLING_FRICTION);
 					applyAnisotropicFriction(colObj1, cp.m_lateralFrictionDir2, btCollisionObject::CF_ANISOTROPIC_ROLLING_FRICTION);
 					applyAnisotropicFriction(colObj1, cp.m_lateralFrictionDir2, btCollisionObject::CF_ANISOTROPIC_ROLLING_FRICTION);
 
 
-					if (cp.m_lateralFrictionDir1.length() > 0.001)
-						addMultiBodyTorsionalFrictionConstraint(cp.m_lateralFrictionDir1, manifold, frictionIndex, cp, cp.m_combinedRollingFriction, colObj0, colObj1, relaxation, infoGlobal);
-
-					if (cp.m_lateralFrictionDir2.length() > 0.001)
-						addMultiBodyTorsionalFrictionConstraint(cp.m_lateralFrictionDir2, manifold, frictionIndex, cp, cp.m_combinedRollingFriction, colObj0, colObj1, relaxation, infoGlobal);
+					addMultiBodyTorsionalFrictionConstraint(cp.m_lateralFrictionDir1, manifold, frictionIndex, cp, cp.m_combinedRollingFriction, colObj0, colObj1, relaxation, infoGlobal);
+					addMultiBodyTorsionalFrictionConstraint(cp.m_lateralFrictionDir2, manifold, frictionIndex, cp, cp.m_combinedRollingFriction, colObj0, colObj1, relaxation, infoGlobal);
 				}
 				}
 				rollingFriction--;
 				rollingFriction--;
 			}
 			}

+ 5 - 0
thirdparty/bullet/BulletDynamics/Featherstone/btMultiBodyConstraintSolver.h

@@ -34,6 +34,7 @@ protected:
 	btMultiBodyConstraintArray m_multiBodyNormalContactConstraints;
 	btMultiBodyConstraintArray m_multiBodyNormalContactConstraints;
 	btMultiBodyConstraintArray m_multiBodyFrictionContactConstraints;
 	btMultiBodyConstraintArray m_multiBodyFrictionContactConstraints;
 	btMultiBodyConstraintArray m_multiBodyTorsionalFrictionContactConstraints;
 	btMultiBodyConstraintArray m_multiBodyTorsionalFrictionContactConstraints;
+	btMultiBodyConstraintArray m_multiBodySpinningFrictionContactConstraints;
 
 
 	btMultiBodyJacobianData m_data;
 	btMultiBodyJacobianData m_data;
 
 
@@ -54,6 +55,10 @@ protected:
 																		 btScalar combinedTorsionalFriction,
 																		 btScalar combinedTorsionalFriction,
 																		 btCollisionObject* colObj0, btCollisionObject* colObj1, btScalar relaxation, const btContactSolverInfo& infoGlobal, btScalar desiredVelocity = 0, btScalar cfmSlip = 0);
 																		 btCollisionObject* colObj0, btCollisionObject* colObj1, btScalar relaxation, const btContactSolverInfo& infoGlobal, btScalar desiredVelocity = 0, btScalar cfmSlip = 0);
 
 
+	btMultiBodySolverConstraint& addMultiBodySpinningFrictionConstraint(const btVector3& normalAxis, btPersistentManifold* manifold, int frictionIndex, btManifoldPoint& cp,
+		btScalar combinedTorsionalFriction,
+		btCollisionObject* colObj0, btCollisionObject* colObj1, btScalar relaxation, const btContactSolverInfo& infoGlobal, btScalar desiredVelocity = 0, btScalar cfmSlip = 0);
+
 	void setupMultiBodyJointLimitConstraint(btMultiBodySolverConstraint & constraintRow,
 	void setupMultiBodyJointLimitConstraint(btMultiBodySolverConstraint & constraintRow,
 											btScalar * jacA, btScalar * jacB,
 											btScalar * jacA, btScalar * jacB,
 											btScalar penetration, btScalar combinedFrictionCoeff, btScalar combinedRestitutionCoeff,
 											btScalar penetration, btScalar combinedFrictionCoeff, btScalar combinedRestitutionCoeff,

+ 30 - 7
thirdparty/bullet/BulletDynamics/Featherstone/btMultiBodyDynamicsWorld.cpp

@@ -207,6 +207,7 @@ public:
 	}
 	}
 };
 };
 
 
+
 struct MultiBodyInplaceSolverIslandCallback : public btSimulationIslandManager::IslandCallback
 struct MultiBodyInplaceSolverIslandCallback : public btSimulationIslandManager::IslandCallback
 {
 {
 	btContactSolverInfo* m_solverInfo;
 	btContactSolverInfo* m_solverInfo;
@@ -224,6 +225,8 @@ struct MultiBodyInplaceSolverIslandCallback : public btSimulationIslandManager::
 	btAlignedObjectArray<btTypedConstraint*> m_constraints;
 	btAlignedObjectArray<btTypedConstraint*> m_constraints;
 	btAlignedObjectArray<btMultiBodyConstraint*> m_multiBodyConstraints;
 	btAlignedObjectArray<btMultiBodyConstraint*> m_multiBodyConstraints;
 
 
+	btAlignedObjectArray<btSolverAnalyticsData> m_islandAnalyticsData;
+
 	MultiBodyInplaceSolverIslandCallback(btMultiBodyConstraintSolver* solver,
 	MultiBodyInplaceSolverIslandCallback(btMultiBodyConstraintSolver* solver,
 										 btDispatcher* dispatcher)
 										 btDispatcher* dispatcher)
 		: m_solverInfo(NULL),
 		: m_solverInfo(NULL),
@@ -235,7 +238,7 @@ struct MultiBodyInplaceSolverIslandCallback : public btSimulationIslandManager::
 	{
 	{
 	}
 	}
 
 
-	MultiBodyInplaceSolverIslandCallback& operator=(MultiBodyInplaceSolverIslandCallback& other)
+	MultiBodyInplaceSolverIslandCallback& operator=(const MultiBodyInplaceSolverIslandCallback& other)
 	{
 	{
 		btAssert(0);
 		btAssert(0);
 		(void)other;
 		(void)other;
@@ -244,6 +247,7 @@ struct MultiBodyInplaceSolverIslandCallback : public btSimulationIslandManager::
 
 
 	SIMD_FORCE_INLINE void setup(btContactSolverInfo* solverInfo, btTypedConstraint** sortedConstraints, int numConstraints, btMultiBodyConstraint** sortedMultiBodyConstraints, int numMultiBodyConstraints, btIDebugDraw* debugDrawer)
 	SIMD_FORCE_INLINE void setup(btContactSolverInfo* solverInfo, btTypedConstraint** sortedConstraints, int numConstraints, btMultiBodyConstraint** sortedMultiBodyConstraints, int numMultiBodyConstraints, btIDebugDraw* debugDrawer)
 	{
 	{
+		m_islandAnalyticsData.clear();
 		btAssert(solverInfo);
 		btAssert(solverInfo);
 		m_solverInfo = solverInfo;
 		m_solverInfo = solverInfo;
 
 
@@ -270,6 +274,11 @@ struct MultiBodyInplaceSolverIslandCallback : public btSimulationIslandManager::
 		{
 		{
 			///we don't split islands, so all constraints/contact manifolds/bodies are passed into the solver regardless the island id
 			///we don't split islands, so all constraints/contact manifolds/bodies are passed into the solver regardless the island id
 			m_solver->solveMultiBodyGroup(bodies, numBodies, manifolds, numManifolds, m_sortedConstraints, m_numConstraints, &m_multiBodySortedConstraints[0], m_numConstraints, *m_solverInfo, m_debugDrawer, m_dispatcher);
 			m_solver->solveMultiBodyGroup(bodies, numBodies, manifolds, numManifolds, m_sortedConstraints, m_numConstraints, &m_multiBodySortedConstraints[0], m_numConstraints, *m_solverInfo, m_debugDrawer, m_dispatcher);
+			if (m_solverInfo->m_reportSolverAnalytics&1)
+			{
+				m_solver->m_analyticsData.m_islandId = islandId;
+				m_islandAnalyticsData.push_back(m_solver->m_analyticsData);
+			}
 		}
 		}
 		else
 		else
 		{
 		{
@@ -335,7 +344,7 @@ struct MultiBodyInplaceSolverIslandCallback : public btSimulationIslandManager::
 
 
 				if ((m_multiBodyConstraints.size() + m_constraints.size() + m_manifolds.size()) > m_solverInfo->m_minimumSolverBatchSize)
 				if ((m_multiBodyConstraints.size() + m_constraints.size() + m_manifolds.size()) > m_solverInfo->m_minimumSolverBatchSize)
 				{
 				{
-					processConstraints();
+					processConstraints(islandId);
 				}
 				}
 				else
 				else
 				{
 				{
@@ -344,7 +353,7 @@ struct MultiBodyInplaceSolverIslandCallback : public btSimulationIslandManager::
 			}
 			}
 		}
 		}
 	}
 	}
-	void processConstraints()
+	void processConstraints(int islandId=-1)
 	{
 	{
 		btCollisionObject** bodies = m_bodies.size() ? &m_bodies[0] : 0;
 		btCollisionObject** bodies = m_bodies.size() ? &m_bodies[0] : 0;
 		btPersistentManifold** manifold = m_manifolds.size() ? &m_manifolds[0] : 0;
 		btPersistentManifold** manifold = m_manifolds.size() ? &m_manifolds[0] : 0;
@@ -354,6 +363,11 @@ struct MultiBodyInplaceSolverIslandCallback : public btSimulationIslandManager::
 		//printf("mb contacts = %d, mb constraints = %d\n", mbContacts, m_multiBodyConstraints.size());
 		//printf("mb contacts = %d, mb constraints = %d\n", mbContacts, m_multiBodyConstraints.size());
 
 
 		m_solver->solveMultiBodyGroup(bodies, m_bodies.size(), manifold, m_manifolds.size(), constraints, m_constraints.size(), multiBodyConstraints, m_multiBodyConstraints.size(), *m_solverInfo, m_debugDrawer, m_dispatcher);
 		m_solver->solveMultiBodyGroup(bodies, m_bodies.size(), manifold, m_manifolds.size(), constraints, m_constraints.size(), multiBodyConstraints, m_multiBodyConstraints.size(), *m_solverInfo, m_debugDrawer, m_dispatcher);
+		if (m_bodies.size() && (m_solverInfo->m_reportSolverAnalytics&1))
+		{
+			m_solver->m_analyticsData.m_islandId = islandId;
+			m_islandAnalyticsData.push_back(m_solver->m_analyticsData);
+		}
 		m_bodies.resize(0);
 		m_bodies.resize(0);
 		m_manifolds.resize(0);
 		m_manifolds.resize(0);
 		m_constraints.resize(0);
 		m_constraints.resize(0);
@@ -361,6 +375,11 @@ struct MultiBodyInplaceSolverIslandCallback : public btSimulationIslandManager::
 	}
 	}
 };
 };
 
 
+void btMultiBodyDynamicsWorld::getAnalyticsData(btAlignedObjectArray<btSolverAnalyticsData>& islandAnalyticsData) const
+{
+	islandAnalyticsData = m_solverMultiBodyIslandCallback->m_islandAnalyticsData;
+}
+
 btMultiBodyDynamicsWorld::btMultiBodyDynamicsWorld(btDispatcher* dispatcher, btBroadphaseInterface* pairCache, btMultiBodyConstraintSolver* constraintSolver, btCollisionConfiguration* collisionConfiguration)
 btMultiBodyDynamicsWorld::btMultiBodyDynamicsWorld(btDispatcher* dispatcher, btBroadphaseInterface* pairCache, btMultiBodyConstraintSolver* constraintSolver, btCollisionConfiguration* collisionConfiguration)
 	: btDiscreteDynamicsWorld(dispatcher, pairCache, constraintSolver, collisionConfiguration),
 	: btDiscreteDynamicsWorld(dispatcher, pairCache, constraintSolver, collisionConfiguration),
 	  m_multiBodyConstraintSolver(constraintSolver)
 	  m_multiBodyConstraintSolver(constraintSolver)
@@ -717,13 +736,17 @@ void btMultiBodyDynamicsWorld::solveConstraints(btContactSolverInfo& solverInfo)
 				m_scratch_v.resize(bod->getNumLinks() + 1);
 				m_scratch_v.resize(bod->getNumLinks() + 1);
 				m_scratch_m.resize(bod->getNumLinks() + 1);
 				m_scratch_m.resize(bod->getNumLinks() + 1);
 
 
+				if (bod->internalNeedsJointFeedback())
 				{
 				{
 					if (!bod->isUsingRK4Integration())
 					if (!bod->isUsingRK4Integration())
 					{
 					{
-						bool isConstraintPass = true;
-						bod->computeAccelerationsArticulatedBodyAlgorithmMultiDof(solverInfo.m_timeStep, m_scratch_r, m_scratch_v, m_scratch_m, isConstraintPass,
-						getSolverInfo().m_jointFeedbackInWorldSpace,
-						getSolverInfo().m_jointFeedbackInJointFrame);
+						if (bod->internalNeedsJointFeedback())
+						{
+							bool isConstraintPass = true;
+							bod->computeAccelerationsArticulatedBodyAlgorithmMultiDof(solverInfo.m_timeStep, m_scratch_r, m_scratch_v, m_scratch_m, isConstraintPass,
+								getSolverInfo().m_jointFeedbackInWorldSpace,
+								getSolverInfo().m_jointFeedbackInJointFrame);
+						}
 					}
 					}
 				}
 				}
 			}
 			}

+ 2 - 0
thirdparty/bullet/BulletDynamics/Featherstone/btMultiBodyDynamicsWorld.h

@@ -109,5 +109,7 @@ public:
 	virtual void serialize(btSerializer* serializer);
 	virtual void serialize(btSerializer* serializer);
 	virtual void setMultiBodyConstraintSolver(btMultiBodyConstraintSolver* solver);
 	virtual void setMultiBodyConstraintSolver(btMultiBodyConstraintSolver* solver);
 	virtual void setConstraintSolver(btConstraintSolver* solver);
 	virtual void setConstraintSolver(btConstraintSolver* solver);
+	virtual void getAnalyticsData(btAlignedObjectArray<struct btSolverAnalyticsData>& m_islandAnalyticsData) const;
+
 };
 };
 #endif  //BT_MULTIBODY_DYNAMICS_WORLD_H
 #endif  //BT_MULTIBODY_DYNAMICS_WORLD_H

+ 4 - 0
thirdparty/bullet/BulletDynamics/Featherstone/btMultiBodyLinkCollider.h

@@ -36,6 +36,10 @@ public:
 	btMultiBody* m_multiBody;
 	btMultiBody* m_multiBody;
 	int m_link;
 	int m_link;
 
 
+	virtual ~btMultiBodyLinkCollider()
+	{
+
+	}
 	btMultiBodyLinkCollider(btMultiBody* multiBody, int link)
 	btMultiBodyLinkCollider(btMultiBody* multiBody, int link)
 		: m_multiBody(multiBody),
 		: m_multiBody(multiBody),
 		  m_link(link)
 		  m_link(link)

+ 6 - 6
thirdparty/bullet/BulletDynamics/Featherstone/btMultiBodyMLCPConstraintSolver.cpp

@@ -22,9 +22,9 @@ subject to the following restrictions:
 
 
 #define DIRECTLY_UPDATE_VELOCITY_DURING_SOLVER_ITERATIONS
 #define DIRECTLY_UPDATE_VELOCITY_DURING_SOLVER_ITERATIONS
 
 
-static bool interleaveContactAndFriction = false;
+static bool interleaveContactAndFriction1 = false;
 
 
-struct btJointNode
+struct btJointNode1
 {
 {
 	int jointIndex;          // pointer to enclosing dxJoint object
 	int jointIndex;          // pointer to enclosing dxJoint object
 	int otherBodyIndex;      // *other* body this joint is connected to
 	int otherBodyIndex;      // *other* body this joint is connected to
@@ -241,7 +241,7 @@ void btMultiBodyMLCPConstraintSolver::createMLCPFast(const btContactSolverInfo&
 
 
 void btMultiBodyMLCPConstraintSolver::createMLCPFastRigidBody(const btContactSolverInfo& infoGlobal)
 void btMultiBodyMLCPConstraintSolver::createMLCPFastRigidBody(const btContactSolverInfo& infoGlobal)
 {
 {
-	int numContactRows = interleaveContactAndFriction ? 3 : 1;
+	int numContactRows = interleaveContactAndFriction1 ? 3 : 1;
 
 
 	int numConstraintRows = m_allConstraintPtrArray.size();
 	int numConstraintRows = m_allConstraintPtrArray.size();
 
 
@@ -301,7 +301,7 @@ void btMultiBodyMLCPConstraintSolver::createMLCPFastRigidBody(const btContactSol
 		BT_PROFILE("bodyJointNodeArray.resize");
 		BT_PROFILE("bodyJointNodeArray.resize");
 		bodyJointNodeArray.resize(numBodies, -1);
 		bodyJointNodeArray.resize(numBodies, -1);
 	}
 	}
-	btAlignedObjectArray<btJointNode> jointNodeArray;
+	btAlignedObjectArray<btJointNode1> jointNodeArray;
 	{
 	{
 		BT_PROFILE("jointNodeArray.reserve");
 		BT_PROFILE("jointNodeArray.reserve");
 		jointNodeArray.reserve(2 * m_allConstraintPtrArray.size());
 		jointNodeArray.reserve(2 * m_allConstraintPtrArray.size());
@@ -729,7 +729,7 @@ btScalar btMultiBodyMLCPConstraintSolver::solveGroupCacheFriendlySetup(
 		int firstContactConstraintOffset = dindex;
 		int firstContactConstraintOffset = dindex;
 
 
 		// The btSequentialImpulseConstraintSolver moves all friction constraints at the very end, we can also interleave them instead
 		// The btSequentialImpulseConstraintSolver moves all friction constraints at the very end, we can also interleave them instead
-		if (interleaveContactAndFriction)
+		if (interleaveContactAndFriction1)
 		{
 		{
 			for (int i = 0; i < m_tmpSolverContactConstraintPool.size(); i++)
 			for (int i = 0; i < m_tmpSolverContactConstraintPool.size(); i++)
 			{
 			{
@@ -785,7 +785,7 @@ btScalar btMultiBodyMLCPConstraintSolver::solveGroupCacheFriendlySetup(
 		firstContactConstraintOffset = dindex;
 		firstContactConstraintOffset = dindex;
 
 
 		// The btSequentialImpulseConstraintSolver moves all friction constraints at the very end, we can also interleave them instead
 		// The btSequentialImpulseConstraintSolver moves all friction constraints at the very end, we can also interleave them instead
-		if (interleaveContactAndFriction)
+		if (interleaveContactAndFriction1)
 		{
 		{
 			for (int i = 0; i < m_multiBodyNormalContactConstraints.size(); ++i)
 			for (int i = 0; i < m_multiBodyNormalContactConstraints.size(); ++i)
 			{
 			{

+ 1 - 1
thirdparty/bullet/BulletDynamics/Featherstone/btMultiBodyMLCPConstraintSolver.h

@@ -156,7 +156,7 @@ protected:
 		btTypedConstraint** constraints,
 		btTypedConstraint** constraints,
 		int numConstraints,
 		int numConstraints,
 		const btContactSolverInfo& infoGlobal,
 		const btContactSolverInfo& infoGlobal,
-		btIDebugDraw* debugDrawer) BT_OVERRIDE;
+		btIDebugDraw* debugDrawer) ;
 
 
 public:
 public:
 	BT_DECLARE_ALIGNED_ALLOCATOR()
 	BT_DECLARE_ALIGNED_ALLOCATOR()

+ 3 - 3
thirdparty/bullet/BulletDynamics/MLCPSolvers/btLemkeSolver.h

@@ -20,7 +20,7 @@ subject to the following restrictions:
 #include "btMLCPSolverInterface.h"
 #include "btMLCPSolverInterface.h"
 #include "btLemkeAlgorithm.h"
 #include "btLemkeAlgorithm.h"
 
 
-///The btLemkeSolver is based on "Fast Implementation of Lemkes Algorithm for Rigid Body Contact Simulation (John E. Lloyd) "
+///The btLemkeSolver is based on "Fast Implementation of Lemke's Algorithm for Rigid Body Contact Simulation (John E. Lloyd) "
 ///It is a slower but more accurate solver. Increase the m_maxLoops for better convergence, at the cost of more CPU time.
 ///It is a slower but more accurate solver. Increase the m_maxLoops for better convergence, at the cost of more CPU time.
 ///The original implementation of the btLemkeAlgorithm was done by Kilian Grundl from the MBSim team
 ///The original implementation of the btLemkeAlgorithm was done by Kilian Grundl from the MBSim team
 class btLemkeSolver : public btMLCPSolverInterface
 class btLemkeSolver : public btMLCPSolverInterface
@@ -67,7 +67,7 @@ public:
 			btMatrixXu A1;
 			btMatrixXu A1;
 			btMatrixXu B(n, n);
 			btMatrixXu B(n, n);
 			{
 			{
-				BT_PROFILE("inverse(slow)");
+				//BT_PROFILE("inverse(slow)");
 				A1.resize(A.rows(), A.cols());
 				A1.resize(A.rows(), A.cols());
 				for (int row = 0; row < A.rows(); row++)
 				for (int row = 0; row < A.rows(); row++)
 				{
 				{
@@ -174,7 +174,7 @@ public:
 			y1.resize(n, 1);
 			y1.resize(n, 1);
 			btLemkeAlgorithm lemke(M, qq, m_debugLevel);
 			btLemkeAlgorithm lemke(M, qq, m_debugLevel);
 			{
 			{
-				BT_PROFILE("lemke.solve");
+				//BT_PROFILE("lemke.solve");
 				lemke.setSystem(M, qq);
 				lemke.setSystem(M, qq);
 				z1 = lemke.solve(m_maxLoops);
 				z1 = lemke.solve(m_maxLoops);
 			}
 			}

+ 1 - 1
thirdparty/bullet/BulletInverseDynamics/MultiBodyTree.cpp

@@ -349,7 +349,7 @@ int MultiBodyTree::finalize()
 	const int &num_bodies = m_init_cache->numBodies();
 	const int &num_bodies = m_init_cache->numBodies();
 	const int &num_dofs = m_init_cache->numDoFs();
 	const int &num_dofs = m_init_cache->numDoFs();
 
 
-	if (num_dofs <= 0)
+	if (num_dofs < 0)
 	{
 	{
 		bt_id_error_message("Need num_dofs>=1, but num_dofs= %d\n", num_dofs);
 		bt_id_error_message("Need num_dofs>=1, but num_dofs= %d\n", num_dofs);
 		//return -1;
 		//return -1;

+ 30 - 3
thirdparty/bullet/BulletInverseDynamics/details/MultiBodyTreeImpl.cpp

@@ -479,9 +479,17 @@ int MultiBodyTree::MultiBodyImpl::calculateKinematics(const vecx &q, const vecx
 		//todo: review
 		//todo: review
 		RigidBody &body = m_body_list[m_body_spherical_list[i]];
 		RigidBody &body = m_body_list[m_body_spherical_list[i]];
 
 
-		body.m_body_T_parent = transformZ(q(body.m_q_index + 2)) *
-							   transformY(q(body.m_q_index + 1)) *
-							   transformX(q(body.m_q_index));
+		mat33 T;
+
+		T = transformX(q(body.m_q_index)) *
+				transformY(q(body.m_q_index + 1)) *
+				transformZ(q(body.m_q_index + 2));
+		body.m_body_T_parent = T * body.m_body_T_parent_ref;
+			
+		body.m_parent_pos_parent_body(0)=0;
+		body.m_parent_pos_parent_body(1)=0;
+		body.m_parent_pos_parent_body(2)=0;
+		
 		body.m_parent_pos_parent_body = body.m_body_T_parent * body.m_parent_pos_parent_body;
 		body.m_parent_pos_parent_body = body.m_body_T_parent * body.m_parent_pos_parent_body;
 
 
 		if (type >= POSITION_VELOCITY)
 		if (type >= POSITION_VELOCITY)
@@ -832,6 +840,25 @@ int MultiBodyTree::MultiBodyImpl::calculateMassMatrix(const vecx &q, const bool
 
 
 			body.m_parent_pos_parent_body = body.m_body_T_parent * body.m_parent_pos_parent_body;
 			body.m_parent_pos_parent_body = body.m_body_T_parent * body.m_parent_pos_parent_body;
 		}
 		}
+
+		for (idArrayIdx i = 0; i < m_body_spherical_list.size(); i++)
+		{
+			//todo: review
+			RigidBody &body = m_body_list[m_body_spherical_list[i]];
+
+			mat33 T;
+
+			T = transformX(q(body.m_q_index)) *
+				transformY(q(body.m_q_index + 1)) *
+				transformZ(q(body.m_q_index + 2));
+			body.m_body_T_parent = T * body.m_body_T_parent_ref;
+
+			body.m_parent_pos_parent_body(0)=0;
+			body.m_parent_pos_parent_body(1)=0;
+			body.m_parent_pos_parent_body(2)=0;
+			
+			body.m_parent_pos_parent_body = body.m_body_T_parent * body.m_parent_pos_parent_body;
+		}
 	}
 	}
 	for (int i = m_body_list.size() - 1; i >= 0; i--)
 	for (int i = m_body_list.size() - 1; i >= 0; i--)
 	{
 	{

+ 2 - 2
thirdparty/bullet/BulletSoftBody/btSoftBody.cpp

@@ -518,7 +518,7 @@ void btSoftBody::addAeroForceToNode(const btVector3& windVelocity, int nodeIndex
 					fDrag = 0.5f * kDG * medium.m_density * rel_v2 * tri_area * n_dot_v * (-rel_v_nrm);
 					fDrag = 0.5f * kDG * medium.m_density * rel_v2 * tri_area * n_dot_v * (-rel_v_nrm);
 
 
 					// Check angle of attack
 					// Check angle of attack
-					// cos(10º) = 0.98480
+					// cos(10°) = 0.98480
 					if (0 < n_dot_v && n_dot_v < 0.98480f)
 					if (0 < n_dot_v && n_dot_v < 0.98480f)
 						fLift = 0.5f * kLF * medium.m_density * rel_v_len * tri_area * btSqrt(1.0f - n_dot_v * n_dot_v) * (nrm.cross(rel_v_nrm).cross(rel_v_nrm));
 						fLift = 0.5f * kLF * medium.m_density * rel_v_len * tri_area * btSqrt(1.0f - n_dot_v * n_dot_v) * (nrm.cross(rel_v_nrm).cross(rel_v_nrm));
 
 
@@ -604,7 +604,7 @@ void btSoftBody::addAeroForceToFace(const btVector3& windVelocity, int faceIndex
 				fDrag = 0.5f * kDG * medium.m_density * rel_v2 * tri_area * n_dot_v * (-rel_v_nrm);
 				fDrag = 0.5f * kDG * medium.m_density * rel_v2 * tri_area * n_dot_v * (-rel_v_nrm);
 
 
 				// Check angle of attack
 				// Check angle of attack
-				// cos(10º) = 0.98480
+				// cos(10°) = 0.98480
 				if (0 < n_dot_v && n_dot_v < 0.98480f)
 				if (0 < n_dot_v && n_dot_v < 0.98480f)
 					fLift = 0.5f * kLF * medium.m_density * rel_v_len * tri_area * btSqrt(1.0f - n_dot_v * n_dot_v) * (nrm.cross(rel_v_nrm).cross(rel_v_nrm));
 					fLift = 0.5f * kLF * medium.m_density * rel_v_len * tri_area * btSqrt(1.0f - n_dot_v * n_dot_v) * (nrm.cross(rel_v_nrm).cross(rel_v_nrm));
 
 

+ 3 - 3
thirdparty/bullet/LinearMath/TaskScheduler/btThreadSupportPosix.cpp

@@ -45,14 +45,14 @@ subject to the following restrictions:
 
 
 int btGetNumHardwareThreads()
 int btGetNumHardwareThreads()
 {
 {
-	return btMin<int>(BT_MAX_THREAD_COUNT, std::thread::hardware_concurrency());
+	return btMax(1u, btMin(BT_MAX_THREAD_COUNT, std::thread::hardware_concurrency()));
 }
 }
 
 
 #else
 #else
 
 
 int btGetNumHardwareThreads()
 int btGetNumHardwareThreads()
 {
 {
-	return btMin<int>(BT_MAX_THREAD_COUNT, sysconf(_SC_NPROCESSORS_ONLN));
+	return btMax(1, btMin<int>(BT_MAX_THREAD_COUNT, sysconf(_SC_NPROCESSORS_ONLN)));
 }
 }
 
 
 #endif
 #endif
@@ -304,8 +304,8 @@ void btThreadSupportPosix::stopThreads()
 		checkPThreadFunction(sem_post(threadStatus.startSemaphore));
 		checkPThreadFunction(sem_post(threadStatus.startSemaphore));
 		checkPThreadFunction(sem_wait(m_mainSemaphore));
 		checkPThreadFunction(sem_wait(m_mainSemaphore));
 
 
-		destroySem(threadStatus.startSemaphore);
 		checkPThreadFunction(pthread_join(threadStatus.thread, 0));
 		checkPThreadFunction(pthread_join(threadStatus.thread, 0));
+		destroySem(threadStatus.startSemaphore);
 	}
 	}
 	destroySem(m_mainSemaphore);
 	destroySem(m_mainSemaphore);
 	m_activeThreadStatus.clear();
 	m_activeThreadStatus.clear();

+ 4 - 11
thirdparty/bullet/LinearMath/btAlignedObjectArray.h

@@ -38,13 +38,6 @@ subject to the following restrictions:
 #include <new>  //for placement new
 #include <new>  //for placement new
 #endif          //BT_USE_PLACEMENT_NEW
 #endif          //BT_USE_PLACEMENT_NEW
 
 
-// The register keyword is deprecated in C++11 so don't use it.
-#if __cplusplus > 199711L
-#define BT_REGISTER
-#else
-#define BT_REGISTER register
-#endif
-
 ///The btAlignedObjectArray template class uses a subset of the stl::vector interface for its methods
 ///The btAlignedObjectArray template class uses a subset of the stl::vector interface for its methods
 ///It is developed to replace stl::vector to avoid portability issues, including STL alignment issues to add SIMD/SSE data
 ///It is developed to replace stl::vector to avoid portability issues, including STL alignment issues to add SIMD/SSE data
 template <typename T>
 template <typename T>
@@ -209,7 +202,7 @@ public:
 
 
 	SIMD_FORCE_INLINE void resize(int newsize, const T& fillData = T())
 	SIMD_FORCE_INLINE void resize(int newsize, const T& fillData = T())
 	{
 	{
-		const BT_REGISTER int curSize = size();
+		const int curSize = size();
 
 
 		if (newsize < curSize)
 		if (newsize < curSize)
 		{
 		{
@@ -236,7 +229,7 @@ public:
 	}
 	}
 	SIMD_FORCE_INLINE T& expandNonInitializing()
 	SIMD_FORCE_INLINE T& expandNonInitializing()
 	{
 	{
-		const BT_REGISTER int sz = size();
+		const int sz = size();
 		if (sz == capacity())
 		if (sz == capacity())
 		{
 		{
 			reserve(allocSize(size()));
 			reserve(allocSize(size()));
@@ -248,7 +241,7 @@ public:
 
 
 	SIMD_FORCE_INLINE T& expand(const T& fillValue = T())
 	SIMD_FORCE_INLINE T& expand(const T& fillValue = T())
 	{
 	{
-		const BT_REGISTER int sz = size();
+		const int sz = size();
 		if (sz == capacity())
 		if (sz == capacity())
 		{
 		{
 			reserve(allocSize(size()));
 			reserve(allocSize(size()));
@@ -263,7 +256,7 @@ public:
 
 
 	SIMD_FORCE_INLINE void push_back(const T& _Val)
 	SIMD_FORCE_INLINE void push_back(const T& _Val)
 	{
 	{
-		const BT_REGISTER int sz = size();
+		const int sz = size();
 		if (sz == capacity())
 		if (sz == capacity())
 		{
 		{
 			reserve(allocSize(size()));
 			reserve(allocSize(size()));

+ 5 - 2
thirdparty/bullet/LinearMath/btMatrixX.h

@@ -263,7 +263,10 @@ struct btMatrixX
 	{
 	{
 		{
 		{
 			BT_PROFILE("storage=0");
 			BT_PROFILE("storage=0");
-			btSetZero(&m_storage[0], m_storage.size());
+			if (m_storage.size())
+			{
+				btSetZero(&m_storage[0], m_storage.size());
+			}
 			//memset(&m_storage[0],0,sizeof(T)*m_storage.size());
 			//memset(&m_storage[0],0,sizeof(T)*m_storage.size());
 			//for (int i=0;i<m_storage.size();i++)
 			//for (int i=0;i<m_storage.size();i++)
 			//			m_storage[i]=0;
 			//			m_storage[i]=0;
@@ -281,7 +284,7 @@ struct btMatrixX
 		}
 		}
 	}
 	}
 
 
-	void printMatrix(const char* msg)
+	void printMatrix(const char* msg) const
 	{
 	{
 		printf("%s ---------------------\n", msg);
 		printf("%s ---------------------\n", msg);
 		for (int i = 0; i < rows(); i++)
 		for (int i = 0; i < rows(); i++)

+ 2 - 2
thirdparty/bullet/LinearMath/btScalar.h

@@ -124,7 +124,7 @@ inline int btGetVersion()
 	#ifdef BT_DEBUG
 	#ifdef BT_DEBUG
 		#ifdef _MSC_VER
 		#ifdef _MSC_VER
 			#include <stdio.h>
 			#include <stdio.h>
-			#define btAssert(x) { if(!(x)){printf("Assert "__FILE__ ":%u (%s)\n", __LINE__, #x);__debugbreak();	}}
+			#define btAssert(x) { if(!(x)){printf("Assert " __FILE__ ":%u (%s)\n", __LINE__, #x);__debugbreak();	}}
 		#else//_MSC_VER
 		#else//_MSC_VER
 			#include <assert.h>
 			#include <assert.h>
 			#define btAssert assert
 			#define btAssert assert
@@ -152,7 +152,7 @@ inline int btGetVersion()
 			#ifdef __SPU__
 			#ifdef __SPU__
 				#include <spu_printf.h>
 				#include <spu_printf.h>
 				#define printf spu_printf
 				#define printf spu_printf
-				#define btAssert(x) {if(!(x)){printf("Assert "__FILE__ ":%u ("#x")\n", __LINE__);spu_hcmpeq(0,0);}}
+				#define btAssert(x) {if(!(x)){printf("Assert " __FILE__ ":%u ("#x")\n", __LINE__);spu_hcmpeq(0,0);}}
 			#else
 			#else
 				#define btAssert assert
 				#define btAssert assert
 			#endif
 			#endif

+ 1 - 1
thirdparty/bullet/LinearMath/btVector3.h

@@ -36,7 +36,7 @@ subject to the following restrictions:
 #pragma warning(disable : 4556)  // value of intrinsic immediate argument '4294967239' is out of range '0 - 255'
 #pragma warning(disable : 4556)  // value of intrinsic immediate argument '4294967239' is out of range '0 - 255'
 #endif
 #endif
 
 
-#define BT_SHUFFLE(x, y, z, w) ((w) << 6 | (z) << 4 | (y) << 2 | (x))
+#define BT_SHUFFLE(x, y, z, w) (((w) << 6 | (z) << 4 | (y) << 2 | (x)) & 0xff)
 //#define bt_pshufd_ps( _a, _mask ) (__m128) _mm_shuffle_epi32((__m128i)(_a), (_mask) )
 //#define bt_pshufd_ps( _a, _mask ) (__m128) _mm_shuffle_epi32((__m128i)(_a), (_mask) )
 #define bt_pshufd_ps(_a, _mask) _mm_shuffle_ps((_a), (_a), (_mask))
 #define bt_pshufd_ps(_a, _mask) _mm_shuffle_ps((_a), (_a), (_mask))
 #define bt_splat3_ps(_a, _i) bt_pshufd_ps((_a), BT_SHUFFLE(_i, _i, _i, 3))
 #define bt_splat3_ps(_a, _i) bt_pshufd_ps((_a), BT_SHUFFLE(_i, _i, _i, 3))

+ 96 - 0
thirdparty/bullet/btBulletCollisionAll.cpp

@@ -0,0 +1,96 @@
+#include "BulletCollision/BroadphaseCollision/btAxisSweep3.cpp"
+#include "BulletCollision/BroadphaseCollision/btDbvt.cpp"
+#include "BulletCollision/BroadphaseCollision/btOverlappingPairCache.cpp"
+#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.cpp"
+#include "BulletCollision/BroadphaseCollision/btDbvtBroadphase.cpp"
+#include "BulletCollision/BroadphaseCollision/btQuantizedBvh.cpp"
+#include "BulletCollision/BroadphaseCollision/btCollisionAlgorithm.cpp"
+#include "BulletCollision/BroadphaseCollision/btDispatcher.cpp"
+#include "BulletCollision/BroadphaseCollision/btSimpleBroadphase.cpp"
+#include "BulletCollision/CollisionDispatch/SphereTriangleDetector.cpp"
+#include "BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.cpp"
+#include "BulletCollision/CollisionDispatch/btHashedSimplePairCache.cpp"
+#include "BulletCollision/CollisionDispatch/btActivatingCollisionAlgorithm.cpp"
+#include "BulletCollision/CollisionDispatch/btCompoundCompoundCollisionAlgorithm.cpp"
+#include "BulletCollision/CollisionDispatch/btInternalEdgeUtility.cpp"
+#include "BulletCollision/CollisionDispatch/btBox2dBox2dCollisionAlgorithm.cpp"
+#include "BulletCollision/CollisionDispatch/btConvex2dConvex2dAlgorithm.cpp"
+#include "BulletCollision/CollisionDispatch/btManifoldResult.cpp"
+#include "BulletCollision/CollisionDispatch/btBoxBoxCollisionAlgorithm.cpp"
+#include "BulletCollision/CollisionDispatch/btConvexConcaveCollisionAlgorithm.cpp"
+#include "BulletCollision/CollisionDispatch/btSimulationIslandManager.cpp"
+#include "BulletCollision/CollisionDispatch/btBoxBoxDetector.cpp"
+#include "BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.cpp"
+#include "BulletCollision/CollisionDispatch/btSphereBoxCollisionAlgorithm.cpp"
+#include "BulletCollision/CollisionDispatch/btCollisionDispatcher.cpp"
+#include "BulletCollision/CollisionDispatch/btConvexPlaneCollisionAlgorithm.cpp"
+#include "BulletCollision/CollisionDispatch/btSphereSphereCollisionAlgorithm.cpp"
+#include "BulletCollision/CollisionDispatch/btCollisionObject.cpp"
+#include "BulletCollision/CollisionDispatch/btDefaultCollisionConfiguration.cpp"
+#include "BulletCollision/CollisionDispatch/btSphereTriangleCollisionAlgorithm.cpp"
+#include "BulletCollision/CollisionDispatch/btCollisionWorld.cpp"
+#include "BulletCollision/CollisionDispatch/btEmptyCollisionAlgorithm.cpp"
+#include "BulletCollision/CollisionDispatch/btUnionFind.cpp"
+#include "BulletCollision/CollisionDispatch/btCollisionWorldImporter.cpp"
+#include "BulletCollision/CollisionDispatch/btGhostObject.cpp"
+#include "BulletCollision/NarrowPhaseCollision/btContinuousConvexCollision.cpp"
+#include "BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.cpp"
+#include "BulletCollision/NarrowPhaseCollision/btPolyhedralContactClipping.cpp"
+#include "BulletCollision/NarrowPhaseCollision/btConvexCast.cpp"
+#include "BulletCollision/NarrowPhaseCollision/btGjkPairDetector.cpp"
+#include "BulletCollision/NarrowPhaseCollision/btRaycastCallback.cpp"
+#include "BulletCollision/NarrowPhaseCollision/btGjkConvexCast.cpp"
+#include "BulletCollision/NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.cpp"
+#include "BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.cpp"
+#include "BulletCollision/NarrowPhaseCollision/btGjkEpa2.cpp"
+#include "BulletCollision/NarrowPhaseCollision/btPersistentManifold.cpp"
+#include "BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.cpp"
+#include "BulletCollision/CollisionShapes/btBox2dShape.cpp"
+#include "BulletCollision/CollisionShapes/btConvexPolyhedron.cpp"
+#include "BulletCollision/CollisionShapes/btShapeHull.cpp"
+#include "BulletCollision/CollisionShapes/btBoxShape.cpp"
+#include "BulletCollision/CollisionShapes/btConvexShape.cpp"
+#include "BulletCollision/CollisionShapes/btSphereShape.cpp"
+#include "BulletCollision/CollisionShapes/btBvhTriangleMeshShape.cpp"
+#include "BulletCollision/CollisionShapes/btConvexTriangleMeshShape.cpp"
+#include "BulletCollision/CollisionShapes/btStaticPlaneShape.cpp"
+#include "BulletCollision/CollisionShapes/btCapsuleShape.cpp"
+#include "BulletCollision/CollisionShapes/btCylinderShape.cpp"
+#include "BulletCollision/CollisionShapes/btStridingMeshInterface.cpp"
+#include "BulletCollision/CollisionShapes/btCollisionShape.cpp"
+#include "BulletCollision/CollisionShapes/btEmptyShape.cpp"
+#include "BulletCollision/CollisionShapes/btTetrahedronShape.cpp"
+#include "BulletCollision/CollisionShapes/btCompoundShape.cpp"
+#include "BulletCollision/CollisionShapes/btHeightfieldTerrainShape.cpp"
+#include "BulletCollision/CollisionShapes/btTriangleBuffer.cpp"
+#include "BulletCollision/CollisionShapes/btConcaveShape.cpp"
+#include "BulletCollision/CollisionShapes/btMinkowskiSumShape.cpp"
+#include "BulletCollision/CollisionShapes/btTriangleCallback.cpp"
+#include "BulletCollision/CollisionShapes/btConeShape.cpp"
+#include "BulletCollision/CollisionShapes/btMultiSphereShape.cpp"
+#include "BulletCollision/CollisionShapes/btTriangleIndexVertexArray.cpp"
+#include "BulletCollision/CollisionShapes/btConvex2dShape.cpp"
+#include "BulletCollision/CollisionShapes/btMultimaterialTriangleMeshShape.cpp"
+#include "BulletCollision/CollisionShapes/btTriangleIndexVertexMaterialArray.cpp"
+#include "BulletCollision/CollisionShapes/btConvexHullShape.cpp"
+#include "BulletCollision/CollisionShapes/btOptimizedBvh.cpp"
+#include "BulletCollision/CollisionShapes/btTriangleMesh.cpp"
+#include "BulletCollision/CollisionShapes/btConvexInternalShape.cpp"
+#include "BulletCollision/CollisionShapes/btPolyhedralConvexShape.cpp"
+#include "BulletCollision/CollisionShapes/btTriangleMeshShape.cpp"
+#include "BulletCollision/CollisionShapes/btConvexPointCloudShape.cpp"
+#include "BulletCollision/CollisionShapes/btScaledBvhTriangleMeshShape.cpp"
+#include "BulletCollision/CollisionShapes/btSdfCollisionShape.cpp"
+#include "BulletCollision/CollisionShapes/btMiniSDF.cpp"
+#include "BulletCollision/CollisionShapes/btUniformScalingShape.cpp"
+#include "BulletCollision/Gimpact/btContactProcessing.cpp"
+#include "BulletCollision/Gimpact/btGImpactQuantizedBvh.cpp"
+#include "BulletCollision/Gimpact/btTriangleShapeEx.cpp"
+#include "BulletCollision/Gimpact/gim_memory.cpp"
+#include "BulletCollision/Gimpact/btGImpactBvh.cpp"
+#include "BulletCollision/Gimpact/btGImpactShape.cpp"
+#include "BulletCollision/Gimpact/gim_box_set.cpp"
+#include "BulletCollision/Gimpact/gim_tri_collision.cpp"
+#include "BulletCollision/Gimpact/btGImpactCollisionAlgorithm.cpp"
+#include "BulletCollision/Gimpact/btGenericPoolAllocator.cpp"
+#include "BulletCollision/Gimpact/gim_contact.cpp"

+ 42 - 0
thirdparty/bullet/btBulletDynamicsAll.cpp

@@ -0,0 +1,42 @@
+#include "BulletDynamics/Dynamics/btDiscreteDynamicsWorld.cpp"
+#include "BulletDynamics/Dynamics/btRigidBody.cpp"
+#include "BulletDynamics/Dynamics/btSimulationIslandManagerMt.cpp"
+#include "BulletDynamics/Dynamics/btDiscreteDynamicsWorldMt.cpp"
+#include "BulletDynamics/Dynamics/btSimpleDynamicsWorld.cpp"
+#include "BulletDynamics/ConstraintSolver/btBatchedConstraints.cpp"
+#include "BulletDynamics/ConstraintSolver/btConeTwistConstraint.cpp"
+#include "BulletDynamics/ConstraintSolver/btGeneric6DofSpringConstraint.cpp"
+#include "BulletDynamics/ConstraintSolver/btSliderConstraint.cpp"
+#include "BulletDynamics/ConstraintSolver/btContactConstraint.cpp"
+#include "BulletDynamics/ConstraintSolver/btHinge2Constraint.cpp"
+#include "BulletDynamics/ConstraintSolver/btSolve2LinearConstraint.cpp"
+#include "BulletDynamics/ConstraintSolver/btFixedConstraint.cpp"
+#include "BulletDynamics/ConstraintSolver/btHingeConstraint.cpp"
+#include "BulletDynamics/ConstraintSolver/btTypedConstraint.cpp"
+#include "BulletDynamics/ConstraintSolver/btGearConstraint.cpp"
+#include "BulletDynamics/ConstraintSolver/btNNCGConstraintSolver.cpp"
+#include "BulletDynamics/ConstraintSolver/btUniversalConstraint.cpp"
+#include "BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.cpp"
+#include "BulletDynamics/ConstraintSolver/btPoint2PointConstraint.cpp"
+#include "BulletDynamics/ConstraintSolver/btGeneric6DofSpring2Constraint.cpp"
+#include "BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.cpp"
+#include "BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolverMt.cpp"
+#include "BulletDynamics/MLCPSolvers/btDantzigLCP.cpp"
+#include "BulletDynamics/MLCPSolvers/btLemkeAlgorithm.cpp"
+#include "BulletDynamics/MLCPSolvers/btMLCPSolver.cpp"
+#include "BulletDynamics/Featherstone/btMultiBody.cpp"
+#include "BulletDynamics/Featherstone/btMultiBodyDynamicsWorld.cpp"
+#include "BulletDynamics/Featherstone/btMultiBodyJointMotor.cpp"
+#include "BulletDynamics/Featherstone/btMultiBodyGearConstraint.cpp"
+#include "BulletDynamics/Featherstone/btMultiBodyConstraint.cpp"
+#include "BulletDynamics/Featherstone/btMultiBodyFixedConstraint.cpp"
+#include "BulletDynamics/Featherstone/btMultiBodyPoint2Point.cpp"
+#include "BulletDynamics/Featherstone/btMultiBodyConstraintSolver.cpp"
+#include "BulletDynamics/Featherstone/btMultiBodyMLCPConstraintSolver.cpp"
+#include "BulletDynamics/Featherstone/btMultiBodyJointLimitConstraint.cpp"
+#include "BulletDynamics/Featherstone/btMultiBodySliderConstraint.cpp"
+#include "BulletDynamics/Featherstone/btMultiBodySphericalJointMotor.cpp"
+#include "BulletDynamics/Vehicle/btRaycastVehicle.cpp"
+#include "BulletDynamics/Vehicle/btWheelInfo.cpp"
+#include "BulletDynamics/Character/btKinematicCharacterController.cpp"
+

+ 14 - 0
thirdparty/bullet/btLinearMathAll.cpp

@@ -0,0 +1,14 @@
+#include "LinearMath/btAlignedAllocator.cpp"
+#include "LinearMath/btGeometryUtil.cpp"
+#include "LinearMath/btSerializer.cpp"
+#include "LinearMath/btVector3.cpp"
+#include "LinearMath/btConvexHull.cpp"
+#include "LinearMath/btPolarDecomposition.cpp"
+#include "LinearMath/btSerializer64.cpp"
+#include "LinearMath/btConvexHullComputer.cpp"
+#include "LinearMath/btQuickprof.cpp"
+#include "LinearMath/btThreads.cpp"
+#include "LinearMath/TaskScheduler/btTaskScheduler.cpp"
+#include "LinearMath/TaskScheduler/btThreadSupportPosix.cpp"
+#include "LinearMath/TaskScheduler/btThreadSupportWin32.cpp"
+

Some files were not shown because too many files changed in this diff