[Bf-blender-cvs] [a7b4582] fracture_modifier: added very basic damage propagation scheme to compoundbased fracture (direct damage is too small, can be increased this way, but you mostly get single parts falling off only)

Martin Felke noreply at git.blender.org
Wed Oct 21 17:32:09 CEST 2015


Commit: a7b45823be011dace76ed43e480f827e0ca36e3d
Author: Martin Felke
Date:   Wed Oct 21 17:32:01 2015 +0200
Branches: fracture_modifier
https://developer.blender.org/rBa7b45823be011dace76ed43e480f827e0ca36e3d

added very basic damage propagation scheme to compoundbased fracture (direct damage is too small, can be increased this way, but you mostly get single parts falling off only)

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

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

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

diff --git a/extern/bullet2/src/BulletDynamics/Dynamics/btFractureBody.cpp b/extern/bullet2/src/BulletDynamics/Dynamics/btFractureBody.cpp
index 7457ed6..eebd79e 100644
--- a/extern/bullet2/src/BulletDynamics/Dynamics/btFractureBody.cpp
+++ b/extern/bullet2/src/BulletDynamics/Dynamics/btFractureBody.cpp
@@ -68,10 +68,10 @@ void btFractureBody::recomputeConnectivityByConstraints(btCollisionWorld *world1
 
 	if (world->m_idCallback != NULL)
 	{
-		int i;
+		int i, size = world->m_compoundConstraints.size();
 		m_connections.clear();
 
-		for (i=0; i<world->m_compoundConstraints.size();i++)
+		for (i=0; i<size;i++)
 		{
 			btCompoundConstraint *con = world->m_compoundConstraints[i];
 
@@ -106,6 +106,26 @@ void btFractureBody::recomputeConnectivityByConstraints(btCollisionWorld *world1
 				}
 			}
 		}
+
+		//build a connection map
+		m_connection_map->clear();
+
+		size = m_connections.size();
+		for (i=0; i < size; i++)
+		{
+			btConnection con = m_connections[i];
+			btAlignedObjectArray<int> *adjacents = m_connection_map->find(con.m_childIndex0);
+			if (!adjacents) {
+				btAlignedObjectArray<int> adj;
+				adj.push_back(con.m_childIndex1);
+				m_connection_map->insert(con.m_childIndex0, adj);
+			}
+			else
+			{
+				if (adjacents->size() != adjacents->findLinearSearch(con.m_childIndex1))
+					adjacents->push_back(con.m_childIndex1);
+			}
+		}
 	}
 }
 
diff --git a/extern/bullet2/src/BulletDynamics/Dynamics/btFractureBody.h b/extern/bullet2/src/BulletDynamics/Dynamics/btFractureBody.h
index 3b088c6..a46d975 100644
--- a/extern/bullet2/src/BulletDynamics/Dynamics/btFractureBody.h
+++ b/extern/bullet2/src/BulletDynamics/Dynamics/btFractureBody.h
@@ -9,6 +9,7 @@ class btCompoundShape;
 class btManifoldPoint;
 
 #include "LinearMath/btAlignedObjectArray.h"
+#include "LinearMath/btHashMap.h"
 #include "BulletDynamics/Dynamics/btRigidBody.h"
 
 #define CUSTOM_FRACTURE_TYPE (btRigidBody::CO_USER_TYPE+1)
@@ -31,13 +32,15 @@ public:
 
 	btDynamicsWorld*	m_world;
 	btAlignedObjectArray<btScalar>	m_masses;
-	btAlignedObjectArray<btConnection>	m_connections;
+	btAlignedObjectArray<btConnection> m_connections;
+	btHashMap<btHashInt, btAlignedObjectArray<int> > *m_connection_map;
 
 
 
 	btFractureBody(	const btRigidBodyConstructionInfo& constructionInfo)
 		:btRigidBody(constructionInfo),
-		m_world(0)
+		m_world(0),
+		m_connection_map(NULL)
 	{
 		m_masses.push_back(constructionInfo.m_mass);
 		m_internalType=CUSTOM_FRACTURE_TYPE+CO_RIGID_BODY;
@@ -56,6 +59,7 @@ public:
 			m_masses.push_back(masses[i]);
 
 		m_internalType=CUSTOM_FRACTURE_TYPE+CO_RIGID_BODY;
+		m_connection_map = new btHashMap<btHashInt, btAlignedObjectArray<int> >();
 	}
 
 	void setWorld(btDynamicsWorld *world)
@@ -74,6 +78,10 @@ public:
 	
 	static bool collisionCallback(btManifoldPoint& cp,	const btCollisionObject* colObj0,int partId0,int index0,const btCollisionObject* colObj1,int partId1,int index1);
 
+	~btFractureBody()
+	{
+		delete m_connection_map;
+	}
 };
 
 
diff --git a/extern/bullet2/src/BulletDynamics/Dynamics/btFractureDynamicsWorld.cpp b/extern/bullet2/src/BulletDynamics/Dynamics/btFractureDynamicsWorld.cpp
index 848d011..37656ef 100644
--- a/extern/bullet2/src/BulletDynamics/Dynamics/btFractureDynamicsWorld.cpp
+++ b/extern/bullet2/src/BulletDynamics/Dynamics/btFractureDynamicsWorld.cpp
@@ -515,12 +515,12 @@ void	btFractureDynamicsWorld::breakDisconnectedParts( btFractureBody* fracObj)
 	for (i=0;i<fracObj->m_connections.size();i++)
 	{
 		btConnection& connection = fracObj->m_connections[i];
-		/*if (connection.m_childIndex0 >= tags.size() ||
+		if (connection.m_childIndex0 >= tags.size() ||
 		    connection.m_childIndex1 >= tags.size() )
 		{
 			//fracObj->m_connections.remove(connection);
 			continue;
-		}*/
+		}
 
 		if (connection.m_strength > 0.)
 		{
@@ -612,10 +612,36 @@ void	btFractureDynamicsWorld::breakDisconnectedParts( btFractureBody* fracObj)
 
 #include <stdio.h>
 
-/*void btFractureDynamicsWorld::propagateWeaken(btFractureBody *body, btManifoldPoint *pt)
+void btFractureDynamicsWorld::propagateDamage(btFractureBody *body, btScalar *impulse, int connection_index, bool* needsBreakingCheck)
 {
+	//min break impulse, todo expose
+	if (*impulse > 0.5f)
+	{
+		btConnection& connection = body->m_connections[connection_index];
+		connection.m_strength -= *impulse;
+		//printf("strengthp=%f %f\n",connection.m_strength, *impulse);
+
+		if (connection.m_strength<0)
+		{
+			//remove or set to zero
+			connection.m_strength=0.f;
+			*needsBreakingCheck = true;
+		}
 
-}*/
+		//impulse dampening, todo expose
+		*impulse *= 0.85f;
+
+		btAlignedObjectArray<int> *adjacents = body->m_connection_map->find(connection_index);
+		if (adjacents)
+		{
+			int i, size = adjacents->size();
+			for (i=0;i<size;i++)
+			{
+				propagateDamage(body, impulse, adjacents->at(i), needsBreakingCheck);
+			}
+		}
+	}
+}
 
 void btFractureDynamicsWorld::fractureCallback( )
 {
@@ -653,7 +679,7 @@ void btFractureDynamicsWorld::fractureCallback( )
 			maxImpact = totalImpact;
 
 		//some threshold otherwise resting contact would break objects after a while
-		if (totalImpact < 0.1f) //40.f
+		if (totalImpact < 1.f) //40.f
 			continue;
 
 		//		printf("strong impact\n");
@@ -789,14 +815,13 @@ void btFractureDynamicsWorld::fractureCallback( )
 							{
 								for (int f=0;f<sFracturePairs[i].m_fracObj->m_connections.size();f++)
 								{
+									//direct damage
 									btConnection& connection = sFracturePairs[i].m_fracObj->m_connections[f];
 									if ((connection.m_childIndex0 == pt.m_index0) ||
 										(connection.m_childIndex1 == pt.m_index0))
-									    //(connection.m_childIndex0 == pt.m_index1) ||
-									    //(connection.m_childIndex1 == pt.m_index1))
 									{
 										connection.m_strength -= pt.m_appliedImpulse;
-										printf("strength0=%f\n",connection.m_strength);
+										//printf("strength0=%f\n",connection.m_strength);
 
 										if (connection.m_strength<0)
 										{	
@@ -805,19 +830,26 @@ void btFractureDynamicsWorld::fractureCallback( )
 											needsBreakingCheck = true;
 										}
 									}
+
+									//propagated damage
+									if (pt.m_appliedImpulse > 0.f) {
+										btScalar impulse = pt.m_appliedImpulse;
+										propagateDamage(sFracturePairs[i].m_fracObj,&impulse, connection.m_childIndex0, &needsBreakingCheck);
+
+										impulse = pt.m_appliedImpulse;
+										propagateDamage(sFracturePairs[i].m_fracObj,&impulse, connection.m_childIndex1, &needsBreakingCheck);
+									}
 								}
 							} else
 							{
-								//propagate
+								//direct damage
 								for (int f=0;f<sFracturePairs[i].m_fracObj->m_connections.size();f++)
 								{
 									btConnection& connection = sFracturePairs[i].m_fracObj->m_connections[f];
 									if ((connection.m_childIndex0 == pt.m_index1) ||
 									       (connection.m_childIndex1 == pt.m_index1))
-									//	   (connection.m_childIndex0 == pt.m_index0) ||
-									//       (connection.m_childIndex1 == pt.m_index0))
 									{
-										printf("strength1=%f\n",connection.m_strength);
+										//printf("strength1=%f\n",connection.m_strength);
 										connection.m_strength -= pt.m_appliedImpulse;
 										if (connection.m_strength<0)
 										{
@@ -826,6 +858,15 @@ void btFractureDynamicsWorld::fractureCallback( )
 											needsBreakingCheck = true;
 										}
 									}
+
+									//propagated damage
+									if (pt.m_appliedImpulse > 0.f) {
+										btScalar impulse = pt.m_appliedImpulse;
+										propagateDamage(sFracturePairs[i].m_fracObj, &impulse, connection.m_childIndex0, &needsBreakingCheck);
+
+										impulse = pt.m_appliedImpulse;
+										propagateDamage(sFracturePairs[i].m_fracObj, &impulse, connection.m_childIndex1, &needsBreakingCheck);
+									}
 								}
 							}
 						}
diff --git a/extern/bullet2/src/BulletDynamics/Dynamics/btFractureDynamicsWorld.h b/extern/bullet2/src/BulletDynamics/Dynamics/btFractureDynamicsWorld.h
index c78ae84..88f01d5 100644
--- a/extern/bullet2/src/BulletDynamics/Dynamics/btFractureDynamicsWorld.h
+++ b/extern/bullet2/src/BulletDynamics/Dynamics/btFractureDynamicsWorld.h
@@ -35,7 +35,9 @@ public:
 	btAlignedObjectArray<btFractureBody*> m_fractureBodies;
 
 	IdCallback m_idCallback;
+
 	ShapeBodyCallback m_shapeBodyCallback;
+
 	btHashMap<btHashInt, int> *m_childIndexHash;
 
 	virtual void	addRigidBody(btRigidBody* body);
@@ -63,6 +65,8 @@ public:
 	void fractureCallback();
 
 	void updateBodies();
+
+	void propagateDamage(btFractureBody *body, btScalar *impulse, int connection_index, bool *needsBreakingCheck);
 };
 
 #endif //_BT_FRACTURE_DYNAMICS_WORLD_H




More information about the Bf-blender-cvs mailing list