Browse Source

WIP bullet updates.

Mark Sibly 8 years ago
parent
commit
ed8dcbde77

+ 74 - 15
modules/bullet/bullet.monkey2

@@ -6,13 +6,13 @@ Namespace bullet
 
 #Import "bullet3-2.85.1/src/*.h"
 
+#Import "bullet_glue.cpp"
+#Import "bullet_glue.h"
+
 #Import "makefile_linearmath"
 #Import "makefile_collision"
 #Import "makefile_dynamics"
 
-#Import "bullet_glue.cpp"
-#Import "bullet_glue.h"
-
 Using std.geom
 
 Alias btScalar:Float
@@ -51,7 +51,8 @@ Struct btMatrix3x3
 	Method New( xx:btScalar,xy:btScalar,xz:btScalar,yx:btScalar,yy:btScalar,yz:btScalar,zx:btScalar,zy:btScalar,zz:btScalar )
 	
 	Method getRow:btVector3( i:Int )
-	
+		
+	Method getColumn:btVector3( j:Int )
 End
 
 Struct btQuaternion
@@ -198,6 +199,60 @@ Class btSphereShape Extends btConvexShape
 	Method New( radius:btScalar )
 End
 
+Class btCapsuleShape Extends btConvexShape
+	
+	Method New( radius:btScalar,height:btScalar )
+		
+End
+
+Class btCapsuleShapeX Extends btCapsuleShape
+	
+	Method New( radius:btScalar,height:btScalar )
+		
+End
+
+Class btCapsuleShapeZ Extends btCapsuleShape
+	
+	Method New( radius:btScalar,height:btScalar )
+		
+End
+
+Class btCylinderShape Extends btConvexShape
+	
+	Method New( halfExtents:btVector3 )
+		
+End
+
+Class btCylinderShapeX Extends btCylinderShape
+	
+	Method New( halfExtents:btVector3 )
+		
+End
+
+Class btCylinderShapeZ Extends btCylinderShape
+	
+	Method New( halfExtents:btVector3 )
+		
+End
+
+Class btConeShape Extends btConvexShape
+
+	Method New( radius:btScalar,height:btScalar )
+			
+End
+
+Class btConeShapeX Extends btConeShape
+
+	Method New( radius:btScalar,height:btScalar )
+			
+End
+
+Class btConeShapeZ Extends btConeShape
+
+	Method New( radius:btScalar,height:btScalar )
+			
+End
+
 Enum PHY_ScalarType
 End
 
@@ -218,6 +273,13 @@ Class btHeightfieldTerrainShape Extends btConcaveShape
 End
 
 Class btTriangleMeshShape Extends btConcaveShape
+	
+	Field m_convexEpsilon:btScalar
+	Field m_planarEpsilon:btScalar
+	Field m_equalVertexThreshold:btScalar
+	Field m_edgeDistanceThreshold:btScalar
+	Field m_maxEdgeAngleThreshold:btScalar
+	Field m_zeroAreaThreshold:btScalar
 
 End
 
@@ -234,7 +296,6 @@ End
 Class btTriangleIndexVertexArray Extends btStridingMeshInterface
 
 	Method New( numTriangles:Int,triangleIndexBase:Int Ptr,triangleIndexStride:Int,numVertices:Int,vertexBase:btScalar Ptr,vertexStride:Int )
-	
 
 End
 
@@ -262,15 +323,15 @@ Class btDefaultMotionState Extends btMotionState
 
 End
 
-Const CF_STATIC_OBJECT:Int
-Const CF_KINEMATIC_OBJECT:Int
-Const CF_NO_CONTACT_RESPONSE:Int
-Const CF_CUSTOM_MATERIAL_CALLBACK:Int
-Const CF_CHARACTER_OBJECT:Int
-Const CF_DISABLE_VISUALIZE_OBJECT:Int
-Const CF_DISABLE_SPU_COLLISION_PROCESSING:Int
- 	
 Class btCollisionObject Extends btObject
+	
+	Const CF_STATIC_OBJECT:Int="btCollisionObject::CF_STATIC_OBJECT"
+	Const CF_KINEMATIC_OBJECT:Int="btCollisionObject::CF_KINEMATIC_OBJECT"
+	Const CF_NO_CONTACT_RESPONSE:Int="btCollisionObject::CF_NO_CONTACT_RESPONSE"
+	Const CF_CUSTOM_MATERIAL_CALLBACK:Int="btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK"
+	Const CF_CHARACTER_OBJECT:Int="btCollisionObject::CF_CHARACTER_OBJECT"
+	Const CF_DISABLE_VISUALIZE_OBJECT:Int="btCollisionObject::CF_DISABLE_VISUALIZE_OBJECT"
+	Const CF_DISABLE_SPU_COLLISION_PROCESSING:Int="btCollisionObject::CF_DISABLE_SPU_COLLISION_PROCESSING"
 
 	Method setWorldTransform( transform:btTransform )
 	
@@ -336,5 +397,3 @@ Class btRigidBody Extends btCollisionObject
 	Method getLinearVelocity:btVector3()
 End
 
-Function BulletKludge1( obj:btCollisionObject )="bbBullet::bulletKludge1"
-

+ 201 - 200
modules/bullet/bullet3-2.85.1/src/BulletCollision/CollisionDispatch/SphereTriangleDetector.cpp

@@ -1,200 +1,201 @@
-/*
-Bullet Continuous Collision Detection and Physics Library
-Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/
-
-This software is provided 'as-is', without any express or implied warranty.
-In no event will the authors be held liable for any damages arising from the use of this software.
-Permission is granted to anyone to use this software for any purpose, 
-including commercial applications, and to alter it and redistribute it freely, 
-subject to the following restrictions:
-
-1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
-2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
-3. This notice may not be removed or altered from any source distribution.
-*/
-
-#include "LinearMath/btScalar.h"
-#include "SphereTriangleDetector.h"
-#include "BulletCollision/CollisionShapes/btTriangleShape.h"
-#include "BulletCollision/CollisionShapes/btSphereShape.h"
-
-
-SphereTriangleDetector::SphereTriangleDetector(btSphereShape* sphere,btTriangleShape* triangle,btScalar contactBreakingThreshold)
-:m_sphere(sphere),
-m_triangle(triangle),
-m_contactBreakingThreshold(contactBreakingThreshold)
-{
-
-}
-
-void	SphereTriangleDetector::getClosestPoints(const ClosestPointInput& input,Result& output,class btIDebugDraw* debugDraw,bool swapResults)
-{
-
-	(void)debugDraw;
-	const btTransform& transformA = input.m_transformA;
-	const btTransform& transformB = input.m_transformB;
-
-	btVector3 point,normal;
-	btScalar timeOfImpact = btScalar(1.);
-	btScalar depth = btScalar(0.);
-//	output.m_distance = btScalar(BT_LARGE_FLOAT);
-	//move sphere into triangle space
-	btTransform	sphereInTr = transformB.inverseTimes(transformA);
-
-	if (collide(sphereInTr.getOrigin(),point,normal,depth,timeOfImpact,m_contactBreakingThreshold))
-	{
-		if (swapResults)
-		{
-			btVector3 normalOnB = transformB.getBasis()*normal;
-			btVector3 normalOnA = -normalOnB;
-			btVector3 pointOnA = transformB*point+normalOnB*depth;
-			output.addContactPoint(normalOnA,pointOnA,depth);
-		} else
-		{
-			output.addContactPoint(transformB.getBasis()*normal,transformB*point,depth);
-		}
-	}
-
-}
-
-
-
-// See also geometrictools.com
-// Basic idea: D = |p - (lo + t0*lv)| where t0 = lv . (p - lo) / lv . lv
-btScalar SegmentSqrDistance(const btVector3& from, const btVector3& to,const btVector3 &p, btVector3 &nearest);
-
-btScalar SegmentSqrDistance(const btVector3& from, const btVector3& to,const btVector3 &p, btVector3 &nearest) {
-	btVector3 diff = p - from;
-	btVector3 v = to - from;
-	btScalar t = v.dot(diff);
-	
-	if (t > 0) {
-		btScalar dotVV = v.dot(v);
-		if (t < dotVV) {
-			t /= dotVV;
-			diff -= t*v;
-		} else {
-			t = 1;
-			diff -= v;
-		}
-	} else
-		t = 0;
-
-	nearest = from + t*v;
-	return diff.dot(diff);	
-}
-
-bool SphereTriangleDetector::facecontains(const btVector3 &p,const btVector3* vertices,btVector3& normal)  {
-	btVector3 lp(p);
-	btVector3 lnormal(normal);
-	
-	return pointInTriangle(vertices, lnormal, &lp);
-}
-
-bool SphereTriangleDetector::collide(const btVector3& sphereCenter,btVector3 &point, btVector3& resultNormal, btScalar& depth, btScalar &timeOfImpact, btScalar contactBreakingThreshold)
-{
-
-	const btVector3* vertices = &m_triangle->getVertexPtr(0);
-	
-	btScalar radius = m_sphere->getRadius();
-	btScalar radiusWithThreshold = radius + contactBreakingThreshold;
-
-	btVector3 normal = (vertices[1]-vertices[0]).cross(vertices[2]-vertices[0]);
-	normal.normalize();
-	btVector3 p1ToCentre = sphereCenter - vertices[0];
-	btScalar distanceFromPlane = p1ToCentre.dot(normal);
-
-	if (distanceFromPlane < btScalar(0.))
-	{
-		//triangle facing the other way
-		distanceFromPlane *= btScalar(-1.);
-		normal *= btScalar(-1.);
-	}
-
-	bool isInsideContactPlane = distanceFromPlane < radiusWithThreshold;
-	
-	// Check for contact / intersection
-	bool hasContact = false;
-	btVector3 contactPoint;
-	if (isInsideContactPlane) {
-		if (facecontains(sphereCenter,vertices,normal)) {
-			// Inside the contact wedge - touches a point on the shell plane
-			hasContact = true;
-			contactPoint = sphereCenter - normal*distanceFromPlane;
-		} else {
-			// Could be inside one of the contact capsules
-			btScalar contactCapsuleRadiusSqr = radiusWithThreshold*radiusWithThreshold;
-			btVector3 nearestOnEdge;
-			for (int i = 0; i < m_triangle->getNumEdges(); i++) {
-				
-				btVector3 pa;
-				btVector3 pb;
-				
-				m_triangle->getEdge(i,pa,pb);
-
-				btScalar distanceSqr = SegmentSqrDistance(pa,pb,sphereCenter, nearestOnEdge);
-				if (distanceSqr < contactCapsuleRadiusSqr) {
-					// Yep, we're inside a capsule
-					hasContact = true;
-					contactPoint = nearestOnEdge;
-				}
-				
-			}
-		}
-	}
-
-	if (hasContact) {
-		btVector3 contactToCentre = sphereCenter - contactPoint;
-		btScalar distanceSqr = contactToCentre.length2();
-
-		if (distanceSqr < radiusWithThreshold*radiusWithThreshold)
-		{
-			if (distanceSqr>SIMD_EPSILON)
-			{
-				btScalar distance = btSqrt(distanceSqr);
-				resultNormal = contactToCentre;
-				resultNormal.normalize();
-				point = contactPoint;
-				depth = -(radius-distance);
-			} else
-			{
-				resultNormal = normal;
-				point = contactPoint;
-				depth = -radius;
-			}
-			return true;
-		}
-	}
-	
-	return false;
-}
-
-
-bool SphereTriangleDetector::pointInTriangle(const btVector3 vertices[], const btVector3 &normal, btVector3 *p )
-{
-	const btVector3* p1 = &vertices[0];
-	const btVector3* p2 = &vertices[1];
-	const btVector3* p3 = &vertices[2];
-
-	btVector3 edge1( *p2 - *p1 );
-	btVector3 edge2( *p3 - *p2 );
-	btVector3 edge3( *p1 - *p3 );
-
-	btVector3 p1_to_p( *p - *p1 );
-	btVector3 p2_to_p( *p - *p2 );
-	btVector3 p3_to_p( *p - *p3 );
-
-	btVector3 edge1_normal( edge1.cross(normal));
-	btVector3 edge2_normal( edge2.cross(normal));
-	btVector3 edge3_normal( edge3.cross(normal));
-	
-	btScalar r1, r2, r3;
-	r1 = edge1_normal.dot( p1_to_p );
-	r2 = edge2_normal.dot( p2_to_p );
-	r3 = edge3_normal.dot( p3_to_p );
-	if ( ( r1 > 0 && r2 > 0 && r3 > 0 ) ||
-	     ( r1 <= 0 && r2 <= 0 && r3 <= 0 ) )
-		return true;
-	return false;
-
-}
+/*
+Bullet Continuous Collision Detection and Physics Library
+Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/
+
+This software is provided 'as-is', without any express or implied warranty.
+In no event will the authors be held liable for any damages arising from the use of this software.
+Permission is granted to anyone to use this software for any purpose, 
+including commercial applications, and to alter it and redistribute it freely, 
+subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
+2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
+3. This notice may not be removed or altered from any source distribution.
+*/
+
+#include "LinearMath/btScalar.h"
+#include "SphereTriangleDetector.h"
+#include "BulletCollision/CollisionShapes/btTriangleShape.h"
+#include "BulletCollision/CollisionShapes/btSphereShape.h"
+
+
+SphereTriangleDetector::SphereTriangleDetector(btSphereShape* sphere,btTriangleShape* triangle,btScalar contactBreakingThreshold)
+:m_sphere(sphere),
+m_triangle(triangle),
+m_contactBreakingThreshold(contactBreakingThreshold)
+{
+
+}
+
+void	SphereTriangleDetector::getClosestPoints(const ClosestPointInput& input,Result& output,class btIDebugDraw* debugDraw,bool swapResults)
+{
+
+	(void)debugDraw;
+	const btTransform& transformA = input.m_transformA;
+	const btTransform& transformB = input.m_transformB;
+
+	btVector3 point,normal;
+	btScalar timeOfImpact = btScalar(1.);
+	btScalar depth = btScalar(0.);
+//	output.m_distance = btScalar(BT_LARGE_FLOAT);
+	//move sphere into triangle space
+	btTransform	sphereInTr = transformB.inverseTimes(transformA);
+
+	if (collide(sphereInTr.getOrigin(),point,normal,depth,timeOfImpact,m_contactBreakingThreshold))
+	{
+		if (swapResults)
+		{
+			btVector3 normalOnB = transformB.getBasis()*normal;
+			btVector3 normalOnA = -normalOnB;
+			btVector3 pointOnA = transformB*point+normalOnB*depth;
+			output.addContactPoint(normalOnA,pointOnA,depth);
+		} else
+		{
+			output.addContactPoint(transformB.getBasis()*normal,transformB*point,depth);
+		}
+	}
+
+}
+
+
+
+// See also geometrictools.com
+// Basic idea: D = |p - (lo + t0*lv)| where t0 = lv . (p - lo) / lv . lv
+btScalar SegmentSqrDistance(const btVector3& from, const btVector3& to,const btVector3 &p, btVector3 &nearest);
+
+btScalar SegmentSqrDistance(const btVector3& from, const btVector3& to,const btVector3 &p, btVector3 &nearest) {
+	btVector3 diff = p - from;
+	btVector3 v = to - from;
+	btScalar t = v.dot(diff);
+	
+	if (t > 0) {
+		btScalar dotVV = v.dot(v);
+		if (t < dotVV) {
+			t /= dotVV;
+			diff -= t*v;
+		} else {
+			t = 1;
+			diff -= v;
+		}
+	} else
+		t = 0;
+		
+	nearest = from + t*v;
+	return diff.dot(diff);	
+}
+
+bool SphereTriangleDetector::facecontains(const btVector3 &p,const btVector3* vertices,btVector3& normal)  {
+	btVector3 lp(p);
+	btVector3 lnormal(normal);
+	
+	return pointInTriangle(vertices, lnormal, &lp);
+}
+
+bool SphereTriangleDetector::collide(const btVector3& sphereCenter,btVector3 &point, btVector3& resultNormal, btScalar& depth, btScalar &timeOfImpact, btScalar contactBreakingThreshold)
+{
+
+	const btVector3* vertices = &m_triangle->getVertexPtr(0);
+	
+	btScalar radius = m_sphere->getRadius();
+	btScalar radiusWithThreshold = radius + contactBreakingThreshold;
+
+	btVector3 normal = (vertices[1]-vertices[0]).cross(vertices[2]-vertices[0]);
+	normal.normalize();
+	btVector3 p1ToCentre = sphereCenter - vertices[0];
+	btScalar distanceFromPlane = p1ToCentre.dot(normal);
+
+	if (distanceFromPlane < btScalar(0.))
+	{
+		//triangle facing the other way
+		distanceFromPlane *= btScalar(-1.);
+		normal *= btScalar(-1.);
+	}
+
+	bool isInsideContactPlane = distanceFromPlane < radiusWithThreshold;
+	
+	// Check for contact / intersection
+	bool hasContact = false;
+	btVector3 contactPoint;
+	if (isInsideContactPlane) {
+		if (facecontains(sphereCenter,vertices,normal)) {
+			// Inside the contact wedge - touches a point on the shell plane
+			hasContact = true;
+			contactPoint = sphereCenter - normal*distanceFromPlane;
+		} else {
+			// Could be inside one of the contact capsules
+			btScalar contactCapsuleRadiusSqr = radiusWithThreshold*radiusWithThreshold;
+			btVector3 nearestOnEdge;
+			for (int i = 0; i < m_triangle->getNumEdges(); i++) {
+				
+				btVector3 pa;
+				btVector3 pb;
+				
+				m_triangle->getEdge(i,pa,pb);
+
+				btScalar distanceSqr = SegmentSqrDistance(pa,pb,sphereCenter, nearestOnEdge);
+				if (distanceSqr < contactCapsuleRadiusSqr) {
+					// Yep, we're inside a capsule
+					hasContact = true;
+					
+					contactPoint = nearestOnEdge;
+				}
+				
+			}
+		}
+	}
+
+	if (hasContact) {
+		btVector3 contactToCentre = sphereCenter - contactPoint;
+		btScalar distanceSqr = contactToCentre.length2();
+
+		if (distanceSqr < radiusWithThreshold*radiusWithThreshold)
+		{
+			if (distanceSqr>SIMD_EPSILON)
+			{
+				btScalar distance = btSqrt(distanceSqr);
+				resultNormal = contactToCentre;
+				resultNormal.normalize();
+				point = contactPoint;
+				depth = -(radius-distance);
+			} else
+			{
+				resultNormal = normal;
+				point = contactPoint;
+				depth = -radius;
+			}
+			return true;
+		}
+	}
+	
+	return false;
+}
+
+
+bool SphereTriangleDetector::pointInTriangle(const btVector3 vertices[], const btVector3 &normal, btVector3 *p )
+{
+	const btVector3* p1 = &vertices[0];
+	const btVector3* p2 = &vertices[1];
+	const btVector3* p3 = &vertices[2];
+
+	btVector3 edge1( *p2 - *p1 );
+	btVector3 edge2( *p3 - *p2 );
+	btVector3 edge3( *p1 - *p3 );
+
+	btVector3 p1_to_p( *p - *p1 );
+	btVector3 p2_to_p( *p - *p2 );
+	btVector3 p3_to_p( *p - *p3 );
+
+	btVector3 edge1_normal( edge1.cross(normal));
+	btVector3 edge2_normal( edge2.cross(normal));
+	btVector3 edge3_normal( edge3.cross(normal));
+	
+	btScalar r1, r2, r3;
+	r1 = edge1_normal.dot( p1_to_p );
+	r2 = edge2_normal.dot( p2_to_p );
+	r3 = edge3_normal.dot( p3_to_p );
+	if ( ( r1 > 0 && r2 > 0 && r3 > 0 ) ||
+	     ( r1 <= 0 && r2 <= 0 && r3 <= 0 ) )
+		return true;
+	return false;
+
+}

+ 0 - 52
modules/bullet/bullet_glue.cpp

@@ -1,46 +1,6 @@
 
 #include "bullet_glue.h"
 
-namespace{
-
-	bool kludge1Callback(
-		btManifoldPoint& cp,
-		const btCollisionObjectWrapper* colObj0Wrap,
-		int partId0,
-		int index0,
-		const btCollisionObjectWrapper* colObj1Wrap,
-		int partId1,
-		int index1
-	){
-	
-//		auto n=cp.m_normalWorldOnB;
-//		printf( "%f %f %f\n",n.x(),n.y(),n.z() );
-		
-//		cp.m_normalWorldOnA=btVector3( 0,1,0 );
-	
-	/*
-		// one-sided triangles
-		if (colObj1Wrap->getCollisionShape()->getShapeType() == TRIANGLE_SHAPE_PROXYTYPE)
-		{
-			auto triShape = static_cast<const btTriangleShape*>( colObj1Wrap->getCollisionShape() );
-			const btVector3* v = triShape->m_vertices1;
-			btVector3 faceNormalLs = btCross(v[1] - v[0], v[2] - v[0]);
-			faceNormalLs.normalize();
-			btVector3 faceNormalWs = colObj1Wrap->getWorldTransform().getBasis() * faceNormalLs;
-			float nDotF = btDot( faceNormalWs, cp.m_normalWorldOnB );
-			if ( nDotF <= 0.0f )
-			{
-				// flip the contact normal to be aligned with the face normal
-				cp.m_normalWorldOnB += -2.0f * nDotF * faceNormalWs;
-			}
-		}
-	*/
-	
-		//this return value is currently ignored, but to be on the safe side: return false if you don't calculate friction
-		return false;
-	}
-}
-
 namespace bbBullet{
 
 	btVector3 calculateLocalInertia( btCollisionShape *self,btScalar mass ){
@@ -54,16 +14,4 @@ namespace bbBullet{
 		self->getWorldTransform( t );
 		return t;
 	}
-	
-	void bulletKludge1( btCollisionObject *obj ){
-	
-		static bool done;
-		if( !done ){
-		    gContactAddedCallback = kludge1Callback;
-		    done=true;
-		}
-	
-		obj->setCollisionFlags( obj->getCollisionFlags() | btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK );
-	}
-	
 }

+ 2 - 3
modules/bullet/bullet_glue.h

@@ -2,15 +2,14 @@
 #ifndef BB_BULLET_H
 #define BB_BULLET_H
 
-#include "bullet3-2.85.1/src/btBulletDynamicsCommon.h"
+//#include "bullet3-2.85.1/src/btBulletDynamicsCommon.h"
+#include "btBulletDynamicsCommon.h"
 
 namespace bbBullet{
 
 	btVector3 calculateLocalInertia( btCollisionShape *self,btScalar mass );
 	
 	btTransform getWorldTransform( btMotionState *self );
-	
-	void bulletKludge1( btCollisionObject *obj );
 }
 
 #endif