[Bf-blender-cvs] [30fc776] fracture_modifier: improvements for inter-object constraints and fix for dissolve constraint when not kinematic (needs to be triggered still)

Martin Felke noreply at git.blender.org
Mon Dec 12 14:24:36 CET 2016


Commit: 30fc776a6860cc66d002d03d0cf99080faf358d7
Author: Martin Felke
Date:   Mon Dec 12 14:24:04 2016 +0100
Branches: fracture_modifier
https://developer.blender.org/rB30fc776a6860cc66d002d03d0cf99080faf358d7

improvements for inter-object constraints and fix for dissolve constraint when not kinematic (needs to be triggered still)

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

M	source/blender/blenkernel/intern/rigidbody.c

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

diff --git a/source/blender/blenkernel/intern/rigidbody.c b/source/blender/blenkernel/intern/rigidbody.c
index a51274a..dbd1da9 100644
--- a/source/blender/blenkernel/intern/rigidbody.c
+++ b/source/blender/blenkernel/intern/rigidbody.c
@@ -88,11 +88,11 @@ static MeshIsland* findMeshIsland(FractureModifierData *fmd, int id);
 
 static void activateRigidbody(RigidBodyOb* rbo, RigidBodyWorld *UNUSED(rbw), MeshIsland *mi, Object *ob)
 {
+	RigidBodyShardCon *con;
+	int i;
+
 	if (rbo->flag & RBO_FLAG_KINEMATIC && rbo->type == RBO_TYPE_ACTIVE)
 	{
-		RigidBodyShardCon *con;
-		int i;
-
 		rbo->flag &= ~RBO_FLAG_KINEMATIC;
 		rbo->flag |= RBO_FLAG_NEEDS_VALIDATE;
 
@@ -101,21 +101,21 @@ static void activateRigidbody(RigidBodyOb* rbo, RigidBodyWorld *UNUSED(rbw), Mes
 			rbo->flag |= RBO_FLAG_PROPAGATE_TRIGGER;
 		}
 
-		if (mi && ob->rigidbody_object->flag & RBO_FLAG_CONSTRAINT_DISSOLVE) {
-			for (i = 0; i < mi->participating_constraint_count; i++) {
-				con = mi->participating_constraints[i];
-				if (con->physics_constraint) {
-					RB_constraint_set_enabled(con->physics_constraint, false);
-				}
-			}
-		}
-
 		//RB_dworld_remove_body(rbw->physics_world, rbo->physics_object);
 		RB_body_set_mass(rbo->physics_object, RBO_GET_MASS(rbo));
 		RB_body_set_kinematic_state(rbo->physics_object, false);
 		//RB_dworld_add_body(rbw->physics_world, rbo->physics_object, rbo->col_groups, mi, ob);
 		RB_body_activate(rbo->physics_object);
 	}
+
+	if (mi && ob->rigidbody_object->flag & RBO_FLAG_CONSTRAINT_DISSOLVE) {
+		for (i = 0; i < mi->participating_constraint_count; i++) {
+			con = mi->participating_constraints[i];
+			if (con->physics_constraint) {
+				RB_constraint_set_enabled(con->physics_constraint, false);
+			}
+		}
+	}
 }
 
 static bool isModifierActive(FractureModifierData *rmd) {
@@ -1414,19 +1414,52 @@ static void rigidbody_validate_sim_object(RigidBodyWorld *rbw, Object *ob, bool
 
 /* --------------------- */
 
-static MeshIsland* find_closest_meshisland_to_point(FractureModifierData* fmd, Object *ob, Object *ob2) {
+static int connected_island_cons(RigidBodyWorld *rbw, Object* ob, RigidBodyCon*** cons)
+{
+	GroupObject* go;
+	int count = 0, i = 0;
+
+	for (go = rbw->constraints->gobject.first; go; go = go->next ) {
+		RigidBodyCon *con = go->ob->rigidbody_constraint;
+		if ((con->ob1 == ob) || (con->ob2 == ob))
+		{
+			count++;
+		}
+	}
+
+	*cons = MEM_mallocN(sizeof(RigidBodyCon*) * count, "connected_island_cons");
+
+	for (go = rbw->constraints->gobject.first; go; go = go->next ) {
+		RigidBodyCon *con = go->ob->rigidbody_constraint;
+		if ((con->ob1 == ob) || (con->ob2 == ob))
+		{
+			(*cons)[i] = con;
+			i++;
+		}
+	}
+
+	return count;
+}
+
+static MeshIsland* find_closest_meshisland_to_point(FractureModifierData* fmd, Object *ob, Object *ob2, RigidBodyWorld* rbw, RigidBodyCon *con) {
 
 	MeshIsland *mi, **mi_array = NULL;
 	KDTree *tree;
-	KDTreeNearest n;
-	int count = BLI_listbase_count(&fmd->meshIslands);
-	int index = 0;
+	KDTreeNearest *n;
+	int count = 0;
+	int con_count = 0;
+	int index = 0, con_index = 0;
 	float loc[3];
+	int i = 0, j = 0;
+	RigidBodyCon **cons = NULL;
+
+	count = BLI_listbase_count(&fmd->meshIslands);
+	n = MEM_mallocN(sizeof(KDTreeNearest) * con_count, "n nearest find_closest_meshisland");
 
 	tree = BLI_kdtree_new(count);
 	mi_array = MEM_mallocN(sizeof(MeshIsland*) * count, "mi_array find_closest_meshisland");
 
-	int i = 0;
+
 	for (mi = fmd->meshIslands.first; mi; mi = mi->next) {
 		mul_v3_m4v3(loc, ob->obmat, mi->centroid);
 		BLI_kdtree_insert(tree, i, loc);
@@ -1435,10 +1468,30 @@ static MeshIsland* find_closest_meshisland_to_point(FractureModifierData* fmd, O
 	}
 
 	BLI_kdtree_balance(tree);
-	index = BLI_kdtree_find_nearest(tree, ob2->loc, &n);
+
+	con_count = connected_island_cons(rbw, ob, &cons);
+	BLI_kdtree_find_nearest_n(tree, ob2->loc, n, con_count);
+
+	for (j = 0; j < con_count; j++) {
+		if (cons[j] == con) {
+			index = n[j].index;
+			break;
+		}
+	}
+
+	if (index == -1) {
+		MEM_freeN(mi_array);
+		MEM_freeN(n);
+		MEM_freeN(cons);
+		BLI_kdtree_free(tree);
+		return NULL;
+	}
 
 	mi = mi_array[index];
+
 	MEM_freeN(mi_array);
+	MEM_freeN(n);
+	MEM_freeN(cons);
 	BLI_kdtree_free(tree);
 
 	return mi;
@@ -1490,8 +1543,8 @@ static void rigidbody_validate_sim_constraint(RigidBodyWorld *rbw, Object *ob, b
 		fmd2 = (FractureModifierData*)modifiers_findByType(rbc->ob2, eModifierType_Fracture);
 
 		if (fmd1 && fmd2) {
-			mi1 = find_closest_meshisland_to_point(fmd1, rbc->ob1, rbc->ob2);
-			mi2 = find_closest_meshisland_to_point(fmd2, rbc->ob2, rbc->ob1);
+			mi1 = find_closest_meshisland_to_point(fmd1, rbc->ob1, rbc->ob2, rbw, rbc);
+			mi2 = find_closest_meshisland_to_point(fmd2, rbc->ob2, rbc->ob1, rbw, rbc);
 
 			if (mi1 && mi2) {
 				rb1 = mi1->rigidbody->physics_object;
@@ -1499,14 +1552,14 @@ static void rigidbody_validate_sim_constraint(RigidBodyWorld *rbw, Object *ob, b
 			}
 		}
 		else if (fmd1) {
-			mi1 = find_closest_meshisland_to_point(fmd1, rbc->ob1, rbc->ob2);
+			mi1 = find_closest_meshisland_to_point(fmd1, rbc->ob1, rbc->ob2, rbw, rbc);
 			if (mi1) {
 				rb1 = mi1->rigidbody->physics_object;
 				rb2 = rbc->ob2->rigidbody_object->physics_object;
 			}
 		}
 		else if (fmd2) {
-			mi2 = find_closest_meshisland_to_point(fmd2, rbc->ob2, rbc->ob1);
+			mi2 = find_closest_meshisland_to_point(fmd2, rbc->ob2, rbc->ob1, rbw, rbc);
 			if (mi2)
 			{
 				rb2 = mi2->rigidbody->physics_object;
@@ -1991,7 +2044,8 @@ static void do_activate(Object* ob, Object *ob2, MeshIsland *mi_compare, RigidBo
 			                    (mi->particle_index == mi_compare->particle_index);
 
 			RigidBodyOb* rbo = mi->rigidbody;
-			if ((rbo->flag & RBO_FLAG_KINEMATIC) && ((mi_compare == mi) || same_cluster))
+			if (((rbo->flag & RBO_FLAG_KINEMATIC) || (ob->rigidbody_object->flag & RBO_FLAG_CONSTRAINT_DISSOLVE)) &&
+			     ((mi_compare == mi) || same_cluster))
 			{
 				if (rbo->physics_object) {
 					activateRigidbody(rbo, rbw, mi, ob);
@@ -2132,7 +2186,7 @@ static int filterCallback(void* world, void* island1, void* island2, void *blend
 		          ((ob1->rigidbody_object->type == RBO_TYPE_ACTIVE) && (ob2->rigidbody_object->type == RBO_TYPE_ACTIVE)));
 	}
 
-	if (validOb)
+	if (validOb || (ob1->rigidbody_object->flag & RBO_FLAG_CONSTRAINT_DISSOLVE) || (ob2->rigidbody_object->flag & RBO_FLAG_CONSTRAINT_DISSOLVE))
 	{
 		if (ob1->rigidbody_object->flag & RBO_FLAG_USE_KINEMATIC_DEACTIVATION)
 		{




More information about the Bf-blender-cvs mailing list