[Bf-blender-cvs] [0749338] fracture_modifier: added new trigger settings: propagate trigger, dynamic trigger and constraint dissolve

Martin Felke noreply at git.blender.org
Sun Dec 11 19:44:24 CET 2016


Commit: 0749338492e82ec2faf5bf22b8cde83a1b252528
Author: Martin Felke
Date:   Sun Dec 11 19:44:01 2016 +0100
Branches: fracture_modifier
https://developer.blender.org/rB0749338492e82ec2faf5bf22b8cde83a1b252528

added new trigger settings: propagate trigger, dynamic trigger and constraint dissolve

propagate trigger allows to propagate impulses across different FM objects, dynamic trigger can start a dynamic fracture independent from force, and constraint dissolve means that all constraints of activated shards will be disabled immediately

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

M	release/scripts/startup/bl_ui/properties_physics_rigidbody.py
M	source/blender/blenkernel/intern/rigidbody.c
M	source/blender/makesdna/DNA_rigidbody_types.h
M	source/blender/makesrna/intern/rna_rigidbody.c

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

diff --git a/release/scripts/startup/bl_ui/properties_physics_rigidbody.py b/release/scripts/startup/bl_ui/properties_physics_rigidbody.py
index 6a69914..984b780 100644
--- a/release/scripts/startup/bl_ui/properties_physics_rigidbody.py
+++ b/release/scripts/startup/bl_ui/properties_physics_rigidbody.py
@@ -53,12 +53,33 @@ class PHYSICS_PT_rigid_body(PHYSICS_PT_rigidbody_panel, Panel):
                 row = layout.row()
                 row.prop(rbo, "use_kinematic_deactivation", text="Triggered")
                 row.prop(rbo, "is_trigger")
-                row = layout.row()
-                row.prop(rbo, "is_ghost")
 
             if rbo.type == 'ACTIVE':
                 layout.prop(rbo, "mass")
 
+class PHYSICS_PT_rigid_body_trigger_advanced(PHYSICS_PT_rigidbody_panel, Panel):
+    bl_label = "Rigid Body Trigger Advanced"
+    COMPAT_ENGINES = {'BLENDER_RENDER'}
+
+    @classmethod
+    def poll(cls, context):
+        obj = context.object
+        return (obj and obj.rigid_body and
+        (context.scene.render.engine in cls.COMPAT_ENGINES))
+
+    def draw(self, context):
+        layout = self.layout
+
+        ob = context.object
+        rbo = ob.rigid_body
+
+        row = layout.row()
+        row.prop(rbo, "is_ghost")
+        row.prop(rbo, "propagate_trigger")
+        row = layout.row()
+        row.prop(rbo, "constraint_dissolve")
+        row.prop(rbo, "dynamic_trigger")
+
 
 class PHYSICS_PT_rigid_body_collisions(PHYSICS_PT_rigidbody_panel, Panel):
     bl_label = "Rigid Body Collisions"
diff --git a/source/blender/blenkernel/intern/rigidbody.c b/source/blender/blenkernel/intern/rigidbody.c
index 9f56921..1a38c06 100644
--- a/source/blender/blenkernel/intern/rigidbody.c
+++ b/source/blender/blenkernel/intern/rigidbody.c
@@ -82,14 +82,33 @@ static void resetDynamic(RigidBodyWorld *rbw, bool do_reset_always);
 static void validateShard(RigidBodyWorld *rbw, MeshIsland *mi, Object *ob, int rebuild, int transfer_speed, float size[3]);
 static void rigidbody_passive_fake_parenting(FractureModifierData *fmd, Object *ob, RigidBodyOb *rbo, float imat[4][4]);
 static void rigidbody_passive_hook(FractureModifierData *fmd, MeshIsland *mi, Object* ob);
+static void check_fracture(rbContactPoint *cp, RigidBodyWorld *rbw, Object *obA, Object *obB);
 
 
-static void activateRigidbody(RigidBodyOb* rbo, RigidBodyWorld *UNUSED(rbw), MeshIsland *UNUSED(mi), Object *UNUSED(ob))
+static void activateRigidbody(RigidBodyOb* rbo, RigidBodyWorld *UNUSED(rbw), MeshIsland *mi, Object *ob)
 {
 	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;
+
+		//propagate trigger on impact / activation
+		if (ob->rigidbody_object->flag & RBO_FLAG_PROPAGATE_TRIGGER) {
+			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);
@@ -1886,7 +1905,7 @@ static bool colgroup_check(int group1, int group2)
 	return false;
 }
 
-static void do_activate(Object* ob, Object *ob2, MeshIsland *mi_compare, RigidBodyWorld *rbw)
+static void do_activate(Object* ob, Object *ob2, MeshIsland *mi_compare, RigidBodyWorld *rbw, MeshIsland *mi_trigger)
 {
 	FractureModifierData *fmd;
 	bool valid = true;
@@ -1895,7 +1914,8 @@ static void do_activate(Object* ob, Object *ob2, MeshIsland *mi_compare, RigidBo
 	fmd = (FractureModifierData*)modifiers_findByType(ob, eModifierType_Fracture);
 	valid = valid && (fmd != NULL);
 	valid = valid && (ob->rigidbody_object->flag & RBO_FLAG_USE_KINEMATIC_DEACTIVATION);
-	valid = valid && (ob2->rigidbody_object->flag & RBO_FLAG_IS_TRIGGER);
+	valid = valid && ((ob2->rigidbody_object->flag & RBO_FLAG_IS_TRIGGER) || ((ob2->rigidbody_object->flag & RBO_FLAG_PROPAGATE_TRIGGER) &&
+	        ((mi_trigger) && (mi_trigger->rigidbody->flag & RBO_FLAG_PROPAGATE_TRIGGER))));
 
 	if (valid)
 	{
@@ -1932,6 +1952,40 @@ static int check_colgroup_ghost(Object* ob1, Object *ob2)
 	return ret && (!(ob1->rigidbody_object->flag & RBO_FLAG_IS_GHOST) && !(ob2->rigidbody_object->flag & RBO_FLAG_IS_GHOST));
 }
 
+static void fake_dynamic_collide(Object *ob1, Object *ob2, MeshIsland *mi1, MeshIsland *mi2, RigidBodyWorld *rbw)
+{
+	if (((ob1->rigidbody_object->flag & RBO_FLAG_IS_GHOST) && (ob1->rigidbody_object->flag & RBO_FLAG_DYNAMIC_TRIGGER)) ||
+		((ob1->rigidbody_object->flag & RBO_FLAG_IS_GHOST) && (ob2->rigidbody_object->flag & RBO_FLAG_DYNAMIC_TRIGGER)) ||
+		((ob2->rigidbody_object->flag & RBO_FLAG_IS_GHOST) && (ob1->rigidbody_object->flag & RBO_FLAG_DYNAMIC_TRIGGER)) ||
+		((ob2->rigidbody_object->flag & RBO_FLAG_IS_GHOST) && (ob2->rigidbody_object->flag & RBO_FLAG_DYNAMIC_TRIGGER)))
+	{
+		rbContactPoint point;
+		point.contact_force = 0;
+
+		if (mi1 || mi2) {
+			if (mi1) {
+				copy_v3_v3(point.contact_pos_world_onA, mi1->centroid);
+				point.contact_body_indexA = mi1->linear_index;
+			}
+			else {
+				copy_v3_v3(point.contact_pos_world_onA, ob1->loc);
+				point.contact_body_indexA = -1;
+			}
+
+			if (mi2) {
+				copy_v3_v3(point.contact_pos_world_onB, mi2->centroid);
+				point.contact_body_indexB = mi2->linear_index;
+			}
+			else {
+				copy_v3_v3(point.contact_pos_world_onB, ob2->loc);
+				point.contact_body_indexB = -1;
+			}
+
+			check_fracture(&point, rbw, ob1, ob2);
+		}
+	}
+}
+
 /* this allows partial object activation, only some shards will be activated, called from bullet(!) */
 static int filterCallback(void* world, void* island1, void* island2, void *blenderOb1, void* blenderOb2) {
 	MeshIsland* mi1, *mi2;
@@ -2016,22 +2070,26 @@ static int filterCallback(void* world, void* island1, void* island2, void *blend
 	{
 		if (ob1->rigidbody_object->flag & RBO_FLAG_USE_KINEMATIC_DEACTIVATION)
 		{
-			do_activate(ob1, ob2, mi1, rbw);
+			do_activate(ob1, ob2, mi1, rbw, mi2);
 		}
 
 		if (ob2->rigidbody_object->flag & RBO_FLAG_USE_KINEMATIC_DEACTIVATION)
 		{
-			do_activate(ob2, ob1, mi2, rbw);
+			do_activate(ob2, ob1, mi2, rbw, mi1);
 		}
 	}
 
+	//if ghost is involved, and dynafrac trigger is enabled, try to call check_fracture manually here, without forces and with centroid as contact point
+	fake_dynamic_collide(ob1, ob2, mi1, mi2, rbw);
+	fake_dynamic_collide(ob2, ob1, mi2, mi1, rbw);
+
 	return check_colgroup_ghost(ob1, ob2);
 }
 
 static bool can_break(Object* collider, Object* ob, bool limit)
 {
 	//allow limit impact only on initial shard and 1st level shards ?
-	if (collider && collider->rigidbody_object && (collider->rigidbody_object->flag & RBO_FLAG_IS_TRIGGER))
+	if (collider && collider->rigidbody_object && (collider->rigidbody_object->flag & RBO_FLAG_DYNAMIC_TRIGGER))
 	{
 		if (limit && (collider == ob)) {
 			return false;
@@ -2150,7 +2208,7 @@ static bool check_constraints(FractureModifierData *fmd, MeshIsland *mi) {
 	return false;
 }
 
-static void check_fracture(rbContactPoint* cp, RigidBodyWorld *rbw)
+static void check_fracture(rbContactPoint* cp, RigidBodyWorld *rbw, Object *obA, Object *obB)
 {
 	int linear_index1, linear_index2;
 	Object* ob1 = NULL, *ob2 = NULL;
@@ -2158,6 +2216,8 @@ static void check_fracture(rbContactPoint* cp, RigidBodyWorld *rbw)
 	FractureModifierData *fmd1, *fmd2;
 	float force;
 
+	//printf("checkfracture\n");
+
 	if (cp == NULL)
 		return;
 
@@ -2176,6 +2236,9 @@ static void check_fracture(rbContactPoint* cp, RigidBodyWorld *rbw)
 		ob_index2 = rbw->cache_offset_map[linear_index2];
 		ob2 = rbw->objects[ob_index2];
 	}
+	else if (obB) {
+		ob2 = obB;
+	}
 
 	if (linear_index1 > -1 && linear_index1 < rbw->numbodies)
 	{
@@ -2196,7 +2259,7 @@ static void check_fracture(rbContactPoint* cp, RigidBodyWorld *rbw)
 				}
 
 				//printf("FORCE1:%f\n",force);
-				bool canbreak = (force > fmd1->dynamic_force) || (fmd1->limit_impact && can_break(ob2, ob1, fmd1->limit_impact));
+				bool canbreak = (force > fmd1->dynamic_force) || ((fmd1->limit_impact || obB) && can_break(ob2, ob1, fmd1->limit_impact));
 
 				if (canbreak && check_constraints(fmd1, mi))
 				{
@@ -2227,6 +2290,9 @@ static void check_fracture(rbContactPoint* cp, RigidBodyWorld *rbw)
 			}
 		}
 	}
+	else if (obA) {
+		ob1 = obA;
+	}
 
 	if (linear_index2 > -1 && linear_index2 < rbw->numbodies)
 	{
@@ -2248,7 +2314,7 @@ static void check_fracture(rbContactPoint* cp, RigidBodyWorld *rbw)
 				}
 
 				//printf("FORCE2:%f\n",force);
-				bool canbreak = (force > fmd2->dynamic_force) || (fmd2->limit_impact && can_break(ob1, ob2, fmd2->limit_impact));
+				bool canbreak = (force > fmd2->dynamic_force) || ((fmd2->limit_impact || obA) && can_break(ob1, ob2, fmd2->limit_impact));
 
 				if (canbreak && check_constraints(fmd2, mi))
 				{
@@ -2283,7 +2349,7 @@ static void check_fracture(rbContactPoint* cp, RigidBodyWorld *rbw)
 static void contactCallback(rbContactPoint* cp, void* world)
 {
 	RigidBodyWorld *rbw = (RigidBodyWorld*)world;
-	check_fracture(cp, rbw);
+	check_fracture(cp, rbw, NULL, NULL);
 }
 
 static void idCallback(void *world, void* island, int* objectId, int* islandId)
@@ -3757,6 +3823,7 @@ static bool do_update_modifier(Scene* scene, Object* ob, RigidBodyWorld *rbw, bo
 					zero_v3(mi->rigidbody->lin_vel);
 					zero_v3(mi->rigidbody->ang_vel);
 					mi->rigidbody->flag |= RBO_FLAG_NEEDS_VALIDATE;
+					mi->rigidbody->flag &= ~RBO_FLAG_PROPAGATE_TRIGGER;
 				}
 
 				rigidbody_passive_hook(fmd, mi, ob);
@@ -4445,7 +4512,7 @@ static bool restoreKinematic(RigidBodyWorld *rbw)
 					}
 				}
 			}
-			else if (go->ob->rigidbody_object->flag & RBO_FLAG_USE_KINEMATIC_DEACTIVATION)
+			else if (!fmd && (go->ob->rigidbody_object->flag & RBO_FLAG_USE_KINEMATIC_DEACTIVATION))
 			{	/* restore regular triggered objects back to kinematic at all, they very likely were kinematic before...
 				 * user has to disable triggered if be

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list