[Bf-blender-cvs] [3a40e2b] fracture_modifier: dynamic fracture: new option to limit the first impact (shard activation area can be limited to impact object)

Martin Felke noreply at git.blender.org
Wed Jun 3 16:45:46 CEST 2015


Commit: 3a40e2b657dd182ecda88164b5d2194440126fb0
Author: Martin Felke
Date:   Wed Jun 3 16:43:05 2015 +0200
Branches: fracture_modifier
https://developer.blender.org/rB3a40e2b657dd182ecda88164b5d2194440126fb0

dynamic fracture: new option to limit the first impact (shard activation area can be limited to impact object)

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

M	release/scripts/startup/bl_operators/presets.py
M	release/scripts/startup/bl_ui/properties_physics_fracture.py
M	source/blender/blenkernel/intern/fracture.c
M	source/blender/blenkernel/intern/rigidbody.c
M	source/blender/makesdna/DNA_fracture_types.h
M	source/blender/makesdna/DNA_modifier_types.h
M	source/blender/makesrna/intern/rna_modifier.c
M	source/blender/modifiers/intern/MOD_fracture.c

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

diff --git a/release/scripts/startup/bl_operators/presets.py b/release/scripts/startup/bl_operators/presets.py
index 6606d40..b6ce5ee 100644
--- a/release/scripts/startup/bl_operators/presets.py
+++ b/release/scripts/startup/bl_operators/presets.py
@@ -649,6 +649,9 @@ class AddPresetFracture(AddPresetBase, Operator):
         "fracture.cutter_axis",
         "fracture.cluster_constraint_type",
         "fracture.constraint_target",
+        "fracture.fracture_mode",
+        "fracture.dynamic_force",
+        "fracture.limit_impact"
     ]
 
     preset_subdir = "fracture"
diff --git a/release/scripts/startup/bl_ui/properties_physics_fracture.py b/release/scripts/startup/bl_ui/properties_physics_fracture.py
index 3ac3760..bc5205b 100644
--- a/release/scripts/startup/bl_ui/properties_physics_fracture.py
+++ b/release/scripts/startup/bl_ui/properties_physics_fracture.py
@@ -74,6 +74,7 @@ class PHYSICS_PT_fracture(PhysicButtonsPanel, Panel):
         row.prop(md, "fracture_mode")
         if md.fracture_mode == 'DYNAMIC':
             layout.prop(md, "dynamic_force")
+            layout.prop(md, "limit_impact")
 
         layout.prop(md, "frac_algorithm")
         col = layout.column(align=True)
diff --git a/source/blender/blenkernel/intern/fracture.c b/source/blender/blenkernel/intern/fracture.c
index c66d76b..fbdd953 100644
--- a/source/blender/blenkernel/intern/fracture.c
+++ b/source/blender/blenkernel/intern/fracture.c
@@ -293,7 +293,7 @@ Shard *BKE_shard_by_id(FracMesh *mesh, ShardID id, DerivedMesh *dm) {
 
 		return NULL;
 	}
-	else if (id == -1)
+	else if (id == -1 && dm != NULL)
 	{
 		/* create temporary shard covering the entire mesh */
 		Shard *s = BKE_create_fracture_shard(dm->getVertArray(dm), dm->getPolyArray(dm), dm->getLoopArray(dm),
@@ -356,6 +356,10 @@ Shard *BKE_create_fracture_shard(MVert *mvert, MPoly *mpoly, MLoop *mloop, int t
 
 	BKE_fracture_shard_center_centroid(shard, shard->centroid);
 	copy_v3_v3(shard->raw_centroid, shard->centroid);
+	zero_v3(shard->impact_loc);
+	shard->impact_size[0] = 1.0f;
+	shard->impact_size[1] = 1.0f;
+	shard->impact_size[2] = 1.0f;
 
 	return shard;
 }
diff --git a/source/blender/blenkernel/intern/rigidbody.c b/source/blender/blenkernel/intern/rigidbody.c
index 3c73073..c6b10bd 100644
--- a/source/blender/blenkernel/intern/rigidbody.c
+++ b/source/blender/blenkernel/intern/rigidbody.c
@@ -1317,7 +1317,7 @@ static void rigidbody_validate_sim_object(RigidBodyWorld *rbw, Object *ob, bool
 	}
 
 	if (rbw && rbw->physics_world)
-		RB_dworld_add_body(rbw->physics_world, rbo->physics_object, rbo->col_groups, NULL, ob, -1);
+		RB_dworld_add_body(rbw->physics_world, rbo->physics_object, rbo->col_groups, NULL, ob, rbo->meshisland_index);
 }
 
 /* --------------------- */
@@ -1847,12 +1847,13 @@ static int filterCallback(void* world, void* island1, void* island2, void *blend
 	return check_colgroup_ghost(ob1, ob2);
 }
 
-static bool check_shard_size(FractureModifierData *fmd, int id)
+static bool check_shard_size(FractureModifierData *fmd, int id, float impact_loc[3], Object* collider)
 {
 	FractureID *fid;
 	float size = 0.1f;
 	Shard *t = fmd->frac_mesh->shard_map.first;
 	Shard *s = NULL;
+	float dim[3];
 
 	while (t)
 	{
@@ -1887,6 +1888,12 @@ static bool check_shard_size(FractureModifierData *fmd, int id)
 		}
 	}
 
+	//simple calc, take just the 1st dimension here.... will be refined later, TODO
+	BKE_object_dimensions_get(collider, dim);
+
+	copy_v3_v3(s->impact_loc, impact_loc);
+	copy_v3_v3(s->impact_size, dim);
+
 	printf("FRACTURE : %d\n", id);
 
 	return true;
@@ -1939,6 +1946,12 @@ static void check_fracture(rbContactPoint* cp, RigidBodyWorld *rbw)
 		return;
 	}
 
+	if (linear_index2 > -1)
+	{
+		ob_index2 = rbw->cache_offset_map[linear_index2];
+		ob2 = rbw->objects[ob_index2];
+	}
+
 	if (linear_index1 > -1)
 	{
 		ob_index1 = rbw->cache_offset_map[linear_index1];
@@ -1952,7 +1965,7 @@ static void check_fracture(rbContactPoint* cp, RigidBodyWorld *rbw)
 					/*only fracture on new entries, this is necessary because after loading a file
 					 *the pointcache thinks it is empty and a fracture is attempted ! */
 					int id = rbw->cache_index_map[linear_index1]->meshisland_index;
-					if(check_shard_size(fmd1, id))
+					if(check_shard_size(fmd1, id, cp->contact_pos_world_onA, ob2))
 					{
 						FractureID* fid1 = MEM_mallocN(sizeof(FractureID), "contact_callback_fractureid1");
 						fid1->shardID = rbw->cache_index_map[linear_index1]->meshisland_index;
@@ -1969,8 +1982,8 @@ static void check_fracture(rbContactPoint* cp, RigidBodyWorld *rbw)
 
 	if (linear_index2 > -1)
 	{
-		ob_index2 = rbw->cache_offset_map[linear_index2];
-		ob2 = rbw->objects[ob_index2];
+		//ob_index2 = rbw->cache_offset_map[linear_index2];
+		//ob2 = rbw->objects[ob_index2];
 		fmd2 = (FractureModifierData*)modifiers_findByType(ob2, eModifierType_Fracture);
 
 		if (fmd2 && fmd2->fracture_mode == MOD_FRACTURE_DYNAMIC) {
@@ -1978,7 +1991,7 @@ static void check_fracture(rbContactPoint* cp, RigidBodyWorld *rbw)
 				if (fmd2->current_shard_entry && fmd2->current_shard_entry->is_new)
 				{
 					int id = rbw->cache_index_map[linear_index2]->meshisland_index;
-					if(check_shard_size(fmd2, id))
+					if(check_shard_size(fmd2, id, cp->contact_pos_world_onB, ob1))
 					{
 						FractureID* fid2 = MEM_mallocN(sizeof(FractureID), "contact_callback_fractureid2");
 						fid2->shardID = id;
@@ -2639,7 +2652,7 @@ static void rigidbody_update_ob_array(RigidBodyWorld *rbw)
 		if (!ismapped) {
 			rbw->cache_index_map[counter] = ob->rigidbody_object; /*1 object 1 index here (normal case)*/
 			rbw->cache_offset_map[counter] = i;
-			ob->rigidbody_object->meshisland_index = -1;
+			ob->rigidbody_object->meshisland_index = counter;
 			counter++;
 		}
 
diff --git a/source/blender/makesdna/DNA_fracture_types.h b/source/blender/makesdna/DNA_fracture_types.h
index 3c69f51..8ef4e46 100644
--- a/source/blender/makesdna/DNA_fracture_types.h
+++ b/source/blender/makesdna/DNA_fracture_types.h
@@ -73,6 +73,8 @@ typedef struct Shard {
 	int parent_id;      /* the shard from which this shard originates, we keep all shards in the shardmap */
 	int flag;           /* flag for fracture state (INTACT, FRACTURED)*/
 	float raw_volume;
+	float impact_loc[3]; /* last impact location on this shard */
+	float impact_size[3]; /* size of impact area (simplified) */
 	char pad2[4];
 } Shard;
 
diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h
index ffd1232..600b99a 100644
--- a/source/blender/makesdna/DNA_modifier_types.h
+++ b/source/blender/makesdna/DNA_modifier_types.h
@@ -1586,6 +1586,7 @@ typedef struct FractureModifierData {
 	int breaking_angle_weighted;
 	int breaking_percentage_weighted;
 	int constraint_target;
+	int limit_impact;
 
 	/* internal flags */
 	int use_experimental;
@@ -1597,7 +1598,7 @@ typedef struct FractureModifierData {
 	float max_vol;
 	int last_frame;
 
-	//char pad[4];
+	char pad[4];
 } FractureModifierData;
 
 typedef struct DataTransferModifierData {
diff --git a/source/blender/makesrna/intern/rna_modifier.c b/source/blender/makesrna/intern/rna_modifier.c
index 268d4a9..e012224 100644
--- a/source/blender/makesrna/intern/rna_modifier.c
+++ b/source/blender/makesrna/intern/rna_modifier.c
@@ -4745,6 +4745,12 @@ static void rna_def_modifier_fracture(BlenderRNA *brna)
 	RNA_def_property_ui_text(prop, "Dynamic force threshold", "Only break dynamically when force is above this threshold");
 	RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
 	RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+	prop = RNA_def_property(srna, "limit_impact", PROP_BOOLEAN, PROP_NONE);
+	RNA_def_property_boolean_sdna(prop, NULL, "limit_impact", false);
+	RNA_def_property_ui_text(prop, "Limit Impact", "Activates only shards within the impact object size approximately");
+	RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+	RNA_def_property_update(prop, 0, "rna_Modifier_update");
 }
 
 static void rna_def_modifier_datatransfer(BlenderRNA *brna)
diff --git a/source/blender/modifiers/intern/MOD_fracture.c b/source/blender/modifiers/intern/MOD_fracture.c
index 0b7dc5c..33ecd9f 100644
--- a/source/blender/modifiers/intern/MOD_fracture.c
+++ b/source/blender/modifiers/intern/MOD_fracture.c
@@ -212,6 +212,7 @@ static void initData(ModifierData *md)
 	fmd->update_dynamic = false;
 	fmd->lookup_mesh_state = lookup_mesh_state;
 	fmd->do_match_vertex_coords = do_match_vertex_coords;
+	fmd->limit_impact = true;
 }
 
 static void freeMeshIsland(FractureModifierData *rmd, MeshIsland *mi, bool remove_rigidbody)
@@ -991,7 +992,7 @@ static void points_from_particles(Object **ob, int totobj, Scene *scene, FracPoi
 						/* birth coordinates are not sufficient in case we did pre-simulate the particles, so they are not
 						 * aligned with the emitter any more BUT as the particle cache is messy and shows initially wrong
 						 * positions "sabotaging" fracture, default use case is using birth coordinates, let user decide... */
-						if (fmd->use_particle_birth_coordinates)
+						if (fmd->use_particle_birth_coordinates && fmd->fracture_mode == MOD_FRACTURE_PREFRACTURED)
 						{
 							psys_get_birth_coords(&sim, pa, &birth, 0, 0);
 						}
@@ -1541,10 +1542,13 @@ static void do_rigidbody(FractureModifierData *fmd, MeshIsland* mi, Object* ob,
 
 	if (fmd->frac_algorithm == MOD_FRACTURE_BOOLEAN_FRACTAL)
 	{
-		/* cant be kept together in other ways */
-		fmd->use_constraints = true;
-		fmd->contact_dist = 2.0f;
-		fmd->breaking_angle = DEG2RADF(1.0f);
+		if (fmd->fracture_mode == MOD_FRACTURE_PREFRACTURED)
+		{
+			/* cant be kept together in other ways */
+			fmd->use_constraints = true;
+			fmd->contact_dist = 2.0f;
+			fmd->breaking_angle = DEG2RADF(1.0f);
+		}
 
 		/* this most likely will only work with "Mesh" shape*/
 		mi->rigidbody->shape = RB_SHAPE_TRIMESH;
@@ -2913,6 +2917,47 @@ static MeshIsland* find_meshisland(ListBase* meshIslands, int id)
 	return NULL;
 }
 
+static bool contains(float loc[3], float size[3], float point[3])
+{
+	if ((fabsf(loc[0] - point[0]) < size[0]) &&
+	    (fabsf(loc[1] - point[1]) < size[1]) &&
+	    (fabsf(loc[2] - point[2]) < size[2]))
+	{
+		return 

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list