[Bf-blender-cvs] [45dbc3d] fracture_modifier: attempt to make compounds a bit more predictable, they should work now when colliding with passive objects too

Martin Felke noreply at git.blender.org
Sat Mar 26 16:07:34 CET 2016


Commit: 45dbc3d19c8b35acd06cc53159db1531d156f3b1
Author: Martin Felke
Date:   Sat Mar 26 16:07:04 2016 +0100
Branches: fracture_modifier
https://developer.blender.org/rB45dbc3d19c8b35acd06cc53159db1531d156f3b1

attempt to make compounds a bit more predictable, they should work now when colliding with passive objects too

===================================================================

M	extern/bullet2/src/BulletDynamics/Dynamics/btFractureBody.cpp
M	extern/bullet2/src/BulletDynamics/Dynamics/btFractureBody.h
M	extern/bullet2/src/BulletDynamics/Dynamics/btFractureDynamicsWorld.cpp
M	extern/bullet2/src/BulletDynamics/Dynamics/btFractureDynamicsWorld.h
M	intern/rigidbody/RBI_api.h
M	intern/rigidbody/rb_bullet_api.cpp
M	source/blender/blenkernel/intern/rigidbody.c

===================================================================

diff --git a/extern/bullet2/src/BulletDynamics/Dynamics/btFractureBody.cpp b/extern/bullet2/src/BulletDynamics/Dynamics/btFractureBody.cpp
index 7eaf035..a846cf7 100644
--- a/extern/bullet2/src/BulletDynamics/Dynamics/btFractureBody.cpp
+++ b/extern/bullet2/src/BulletDynamics/Dynamics/btFractureBody.cpp
@@ -7,6 +7,32 @@
 #include "BulletDynamics/Dynamics/btFractureDynamicsWorld.h"
 
 
+class btConnectionSortPredicate
+{
+	public:
+
+		bool operator() ( const btConnection& lhs, const btConnection& rhs ) const
+		{
+			btVector3 locLhsA = lhs.m_parent->getWorldTransform().inverse() * lhs.m_obA->getWorldTransform().getOrigin();
+			btVector3 locLhsB = lhs.m_parent->getWorldTransform().inverse() * lhs.m_obB->getWorldTransform().getOrigin();
+
+			btVector3 locRhsA = rhs.m_parent->getWorldTransform().inverse() * rhs.m_obA->getWorldTransform().getOrigin();
+			btVector3 locRhsB = rhs.m_parent->getWorldTransform().inverse() * rhs.m_obB->getWorldTransform().getOrigin();
+
+			btVector3 locLhs = (locLhsA + locLhsB) * 0.5f;
+			btVector3 locRhs = (locRhsA + locRhsB) * 0.5f;
+
+			//lhs.parent should match rhs.parent... same object
+			btScalar dLhs = lhs.m_parent->getWorldTransform().getOrigin().distance(locLhs);
+			btScalar dRhs = rhs.m_parent->getWorldTransform().getOrigin().distance(locRhs);
+			//btTransform id = btTransform::getIdentity();
+			//btScalar dLhs = id.getOrigin().distance(locLhs);
+			//btScalar dRhs = id.getOrigin().distance(locRhs);
+
+			return dLhs < dRhs;
+		}
+};
+
 
 void	btFractureBody::recomputeConnectivity(btCollisionWorld* world)
 {
@@ -58,8 +84,6 @@ void	btFractureBody::recomputeConnectivity(btCollisionWorld* world)
 			}
 		}
 	}
-	
-
 }
 
 void btFractureBody::recomputeConnectivityByConstraints(btCollisionWorld *world1)
@@ -99,6 +123,10 @@ void btFractureBody::recomputeConnectivityByConstraints(btCollisionWorld *world1
 						tmp.m_childShape0 = obA->getCollisionShape();
 						tmp.m_childShape1 = obB->getCollisionShape();
 						tmp.m_strength = con->getBreakingImpulseThreshold();
+						tmp.m_obA = obA;
+						tmp.m_obB = obB;
+						tmp.m_parent = this;
+						tmp.m_id = i;
 						m_connections.push_back(tmp);
 					}
 
@@ -107,6 +135,7 @@ void btFractureBody::recomputeConnectivityByConstraints(btCollisionWorld *world1
 			}
 		}
 
+		m_connections.quickSort(btConnectionSortPredicate());
 		//build a connection map
 		m_connection_map->clear();
 
diff --git a/extern/bullet2/src/BulletDynamics/Dynamics/btFractureBody.h b/extern/bullet2/src/BulletDynamics/Dynamics/btFractureBody.h
index 6e785e4..92c5bd4 100644
--- a/extern/bullet2/src/BulletDynamics/Dynamics/btFractureBody.h
+++ b/extern/bullet2/src/BulletDynamics/Dynamics/btFractureBody.h
@@ -32,6 +32,12 @@ struct btConnection
 	int	m_childIndex0;
 	int	m_childIndex1;
 	btScalar	m_strength;
+	//btVector3	m_location; //this must be local to the "Parent" compound
+	//better calc this "live" from the objects themselves, so also keep ob pointers here
+	btCollisionObject* m_obA;
+	btCollisionObject* m_obB;
+	btCollisionObject* m_parent;
+	btScalar m_id;
 };
 
 struct btPropagationParameter
diff --git a/extern/bullet2/src/BulletDynamics/Dynamics/btFractureDynamicsWorld.cpp b/extern/bullet2/src/BulletDynamics/Dynamics/btFractureDynamicsWorld.cpp
index a58e003..87fadaa 100644
--- a/extern/bullet2/src/BulletDynamics/Dynamics/btFractureDynamicsWorld.cpp
+++ b/extern/bullet2/src/BulletDynamics/Dynamics/btFractureDynamicsWorld.cpp
@@ -867,6 +867,7 @@ void	btFractureDynamicsWorld::breakDisconnectedParts( btFractureBody* fracObj)
 
 #include <stdio.h>
 
+#if 0
 void btFractureDynamicsWorld::propagateDamage(btFractureBody *body, btScalar *impulse, int connection_index,
                                               bool* needsBreakingCheck, const btVector3& direction, int* depth)
 {
@@ -958,6 +959,7 @@ void btFractureDynamicsWorld::breakNeighborhood(btFractureBody *body, int connec
 		}
 	}
 }
+#endif
 
 void btFractureDynamicsWorld::fractureCallback( )
 {
@@ -1176,7 +1178,7 @@ void btFractureDynamicsWorld::fractureCallback( )
 												needsBreakingCheck = true;
 												sFracturePairs[i].m_fracObj->m_connections.remove(connection);
 
-												breakNeighborhood(sFracturePairs[i].m_fracObj, pt.m_index0);
+											//	breakNeighborhood(sFracturePairs[i].m_fracObj, pt.m_index0);
 											}
 										}
 									}
@@ -1198,7 +1200,7 @@ void btFractureDynamicsWorld::fractureCallback( )
 												needsBreakingCheck = true;
 												sFracturePairs[i].m_fracObj->m_connections.remove(connection);
 
-												breakNeighborhood(sFracturePairs[i].m_fracObj, pt.m_index1);
+											//	breakNeighborhood(sFracturePairs[i].m_fracObj, pt.m_index1);
 											}
 										}
 									}
diff --git a/extern/bullet2/src/BulletDynamics/Dynamics/btFractureDynamicsWorld.h b/extern/bullet2/src/BulletDynamics/Dynamics/btFractureDynamicsWorld.h
index 5df2a19..9f62404 100644
--- a/extern/bullet2/src/BulletDynamics/Dynamics/btFractureDynamicsWorld.h
+++ b/extern/bullet2/src/BulletDynamics/Dynamics/btFractureDynamicsWorld.h
@@ -24,8 +24,6 @@ class btFractureDynamicsWorld : public btDiscreteDynamicsWorld
 {
 	btFractureBody* addNewBody(const btTransform& oldTransform, btScalar* masses, btCompoundShape* oldCompound, btPropagationParameter &param);
 
-	void	breakDisconnectedParts( btFractureBody* fracObj);
-
 	bool	m_addBroadPhaseHandle;
 
 public:
@@ -75,6 +73,8 @@ public:
 
 	void breakNeighborhood(btFractureBody *body, int connection_index);
 
+	void	breakDisconnectedParts( btFractureBody* fracObj);
+
 	virtual void updateAabbs();
 };
 
diff --git a/intern/rigidbody/RBI_api.h b/intern/rigidbody/RBI_api.h
index 3499d85..765397f 100644
--- a/intern/rigidbody/RBI_api.h
+++ b/intern/rigidbody/RBI_api.h
@@ -141,7 +141,7 @@ void RB_world_convex_sweep_test(
 
 /* Create new RigidBody instance */
 rbRigidBody *RB_body_new(rbCollisionShape *shape, const float loc[3], const float rot[4], bool use_compounds, float dampening, float factor,
-                         float min_impulse, float stability_factor);
+                         float min_impulse, float stability_factor, const float bbox[3]);
 
 /* Delete the given RigidBody instance */
 void RB_body_delete(rbRigidBody *body);
diff --git a/intern/rigidbody/rb_bullet_api.cpp b/intern/rigidbody/rb_bullet_api.cpp
index 265ec4f..2e29995 100644
--- a/intern/rigidbody/rb_bullet_api.cpp
+++ b/intern/rigidbody/rb_bullet_api.cpp
@@ -148,6 +148,7 @@ struct rbRigidBody {
 	int linear_index;
 	void *meshIsland;
 	void *blenderOb;
+	btVector3 *bbox;
 	rbDynamicsWorld *world;
 };
 
@@ -189,12 +190,111 @@ class TickDiscreteDynamicsWorld : public btFractureDynamicsWorld
 		virtual void debugDrawWorld(draw_string str_callback);
 };
 
+btScalar connection_dist(btFractureBody *fbody, int index, btVector3 impact)
+{
+	btConnection& con = fbody->m_connections[index];
+	btVector3 con_posA = fbody->getWorldTransform().inverse() * con.m_obA->getWorldTransform().getOrigin();
+	btVector3 con_posB = fbody->getWorldTransform().inverse() * con.m_obB->getWorldTransform().getOrigin();
+	btVector3 con_pos = (con_posA + con_posB) * 0.5f;
+
+	return impact.distance(con_pos);
+}
+
+//KDTree needed here, we need a range search of which points are closer than distance x to the impact point
+int connection_binary_search(btFractureBody *fbody, btVector3 impact, btScalar range)
+{
+	int mid, low = 0, high = fbody->m_connections.size();
+
+	while (low <= high) {
+		mid = (low + high)/2;
+
+		if (mid == high-1)
+			return mid;
+
+		btScalar dist = connection_dist(fbody, mid, impact);
+		btScalar dist1 = connection_dist(fbody, mid+1, impact);
+
+		if (dist < range && range <= dist1)
+		{
+			return mid;
+		}
+
+		if (dist >= range)
+			high= mid - 1;
+		else if (dist < range)
+			low= mid + 1;
+		else
+			return mid;
+	}
+
+	return low;
+}
+
+bool weakenCompound(const btCollisionObject *body, btScalar force, btVector3 impact, btFractureDynamicsWorld *world)
+{
+	//just weaken strengths of this obA and obB according to force !
+	if (body->getInternalType() & CUSTOM_FRACTURE_TYPE && force > 0.0f)
+	{
+		btFractureBody *fbody = (btFractureBody*)body;
+		int size = fbody->m_connections.size();
+		bool needs_break = false;
+
+		if (size == 0)
+			return false;
+
+		btVector3 *bbox = ((rbRigidBody*)fbody->getUserPointer())->bbox;
+		btScalar dim = (*bbox)[bbox->maxAxis()] * 2;
+
+		//stop at this limit, distances are sorted... so no closer object will come later
+		//int mid = connection_binary_search(fbody, impact, dim * (1.0f - fbody->m_propagationParameter.m_stability_factor));
+		for (int i = 0; i < size; i++)
+		{
+			btVector3 imp = fbody->getWorldTransform().inverse() * impact;
+			btScalar dist = connection_dist(fbody, i, imp);
+			btConnection& con = fbody->m_connections[i];
+			btScalar lforce = force; //* (1.0f - fbody->m_propagationParameter.m_stability_factor);
+			if (dist > 0.0f)
+				lforce = lforce / dist; // the closer, the higher the force
+
+			if (lforce > fbody->m_propagationParameter.m_minimum_impulse)
+			{
+				if (con.m_strength > 0.0f)
+				{
+					con.m_strength -= lforce;
+					//printf("Damaged connection %d %d with %f\n", fbody->m_connections[i].m_childIndex0,
+					//   fbody->m_connections[i].m_childIndex1, force);
+
+					if (con.m_strength <= 0)
+					{
+						con.m_strength = 0;
+						needs_break = true;
+					}
+				}
+			}
+
+			btScalar pdist = connection_dist(fbody, i, fbody->getWorldTransform().getOrigin());
+			if (pdist > (dim * (1.0f - fbody->m_propagationParameter.m_stability_factor)))
+			{
+				break;
+			}
+		}
+
+		if (needs_break)
+			world->breakDisconnectedParts(fbody);
+
+		return needs_break;
+	}
+
+	return false;
+}
+
 void tickCallback(btDynamicsWorld *world, btScalar timeStep)
 {
 	btFractureDynamicsWorld *fworld = (btFractureDynamicsWorld*)world;
 	fworld->updateBodies();
 
 	TickDiscreteDynamicsWorld* tworld = (TickDiscreteDynamicsWorld*)world;
+	bool broken = false;
 
 	int numManifolds = world->getDispatcher()->getNumManifolds();
 	for (int i=0;i<numManifolds;i++)
@@ -216,12 +316,21 @@ void tickCallback(btDynamicsWorld *world, btScalar timeStep)
 				//TickDiscreteDynamicsWorld* tworld = (TickDiscreteDynamicsWorld*)world;
 			

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list