[Bf-blender-cvs] [a2e1051] fracture_modifier: some improvement for dynamic fracture, it now takes location and size of impact object into account with "Limit Impact"

Martin Felke noreply at git.blender.org
Sun Sep 25 21:38:33 CEST 2016


Commit: a2e105186f0016f98c881aad40396b537908f94a
Author: Martin Felke
Date:   Sun Sep 25 21:38:06 2016 +0200
Branches: fracture_modifier
https://developer.blender.org/rBa2e105186f0016f98c881aad40396b537908f94a

some improvement for dynamic fracture, it now takes location and size of impact object into account with "Limit Impact"

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

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

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

diff --git a/source/blender/blenkernel/intern/rigidbody.c b/source/blender/blenkernel/intern/rigidbody.c
index a4d0f50..7dd87ea 100644
--- a/source/blender/blenkernel/intern/rigidbody.c
+++ b/source/blender/blenkernel/intern/rigidbody.c
@@ -2030,13 +2030,29 @@ 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, float impact_loc[3], Object* collider)
+static bool contains(float loc[3], Object* collider, float point[3], Object* ob, bool limit)
+{
+	float size[3];
+	BKE_object_dimensions_get(collider, size);
+
+	if ((fabsf(loc[0] - point[0]) < size[0]) &&
+	    (fabsf(loc[1] - point[1]) < size[1]) &&
+	    (fabsf(loc[2] - point[2]) < size[2]))
+	{
+		if (limit && (collider == ob)) {
+			return false;
+		}
+
+		return true;
+	}
+
+	return false;
+}
+
+static Shard* findShard(FractureModifierData *fmd, int id)
 {
-	FractureID *fid;
-	float size = 0.1f;
 	Shard *t = fmd->frac_mesh->shard_map.first;
 	Shard *s = NULL;
-	float dim[3];
 
 	while (t)
 	{
@@ -2049,6 +2065,17 @@ static bool check_shard_size(FractureModifierData *fmd, int id, float impact_loc
 		t = t->next;
 	}
 
+	return s;
+}
+
+static bool check_shard_size(FractureModifierData *fmd, int id)
+{
+	FractureID *fid;
+	float size = 0.1f;
+	Shard *s = NULL;
+
+	s = findShard(fmd, id);
+
 	if (s == NULL)
 	{
 		return false;
@@ -2071,15 +2098,6 @@ static bool check_shard_size(FractureModifierData *fmd, int id, float impact_loc
 		}
 	}
 
-	if (collider)
-	{
-		//simple calc, take just dimensions here.... will be refined later
-		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;
@@ -2088,7 +2106,7 @@ static bool check_shard_size(FractureModifierData *fmd, int id, float impact_loc
 static void check_fracture(rbContactPoint* cp, RigidBodyWorld *rbw)
 {
 	int linear_index1, linear_index2;
-	Object* ob1, *ob2;
+	Object* ob1 = NULL, *ob2 = NULL;
 	int ob_index1, ob_index2;
 	FractureModifierData *fmd1, *fmd2;
 	float force;
@@ -2118,14 +2136,25 @@ static void check_fracture(rbContactPoint* cp, RigidBodyWorld *rbw)
 		ob1 = rbw->objects[ob_index1];
 		fmd1 = (FractureModifierData*)modifiers_findByType(ob1, eModifierType_Fracture);
 
-		if (fmd1 && fmd1->fracture_mode == MOD_FRACTURE_DYNAMIC) {
-			if (force > fmd1->dynamic_force) {
-				if (fmd1->current_shard_entry && fmd1->current_shard_entry->is_new)
+		if (fmd1 && fmd1->fracture_mode == MOD_FRACTURE_DYNAMIC)
+		{
+			if (fmd1->current_shard_entry && fmd1->current_shard_entry->is_new)
+			{
+				int id = rbw->cache_index_map[linear_index1]->meshisland_index;
+				Shard *s = findShard(fmd1, id);
+
+				if (force > fmd1->dynamic_force || (s && ob2 && (fmd1->limit_impact &&
+				   contains(cp->contact_pos_world_onA, ob2, s->centroid, ob1, fmd1->limit_impact))))
 				{
+					if (s) {
+						float size[3];
+						BKE_object_dimensions_get(ob2, size);
+						copy_v3_v3(s->impact_loc, cp->contact_pos_world_onA);
+						copy_v3_v3(s->impact_size, size);
+					}
 					/*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, cp->contact_pos_world_onA, ob2))
+					if (check_shard_size(fmd1, id))
 					{
 						FractureID* fid1 = MEM_mallocN(sizeof(FractureID), "contact_callback_fractureid1");
 						fid1->shardID = rbw->cache_index_map[linear_index1]->meshisland_index;
@@ -2143,12 +2172,24 @@ static void check_fracture(rbContactPoint* cp, RigidBodyWorld *rbw)
 		//ob2 = rbw->objects[ob_index2];
 		fmd2 = (FractureModifierData*)modifiers_findByType(ob2, eModifierType_Fracture);
 
-		if (fmd2 && fmd2->fracture_mode == MOD_FRACTURE_DYNAMIC) {
-			if (force > fmd2->dynamic_force){
-				if (fmd2->current_shard_entry && fmd2->current_shard_entry->is_new)
+		if (fmd2 && fmd2->fracture_mode == MOD_FRACTURE_DYNAMIC)
+		{
+			if (fmd2->current_shard_entry && fmd2->current_shard_entry->is_new)
+			{
+				int id = rbw->cache_index_map[linear_index1]->meshisland_index;
+				Shard *s = findShard(fmd2, id);
+
+				if (force > fmd2->dynamic_force || (ob1 && s && (fmd2->limit_impact &&
+				   contains(cp->contact_pos_world_onB, ob1, s->centroid, ob2, fmd2->limit_impact))))
 				{
-					int id = rbw->cache_index_map[linear_index2]->meshisland_index;
-					if(check_shard_size(fmd2, id, cp->contact_pos_world_onB, ob1))
+					if (s) {
+						float size[3];
+						BKE_object_dimensions_get(ob1, size);
+						copy_v3_v3(s->impact_loc, cp->contact_pos_world_onB);
+						copy_v3_v3(s->impact_size, size);
+					}
+
+					if (check_shard_size(fmd2, id))
 					{
 						FractureID* fid2 = MEM_mallocN(sizeof(FractureID), "contact_callback_fractureid2");
 						fid2->shardID = id;
diff --git a/source/blender/modifiers/intern/MOD_fracture.c b/source/blender/modifiers/intern/MOD_fracture.c
index 22db6a4..b6819ec 100644
--- a/source/blender/modifiers/intern/MOD_fracture.c
+++ b/source/blender/modifiers/intern/MOD_fracture.c
@@ -1167,6 +1167,64 @@ static FracPointCloud get_points_global(FractureModifierData *emd, Object *ob, D
 		add_v3_v3v3(bmax, max, cent);
 		add_v3_v3v3(bmin, min, cent);
 
+		//first impact only, so shard has id 0
+		if (emd->fracture_mode == MOD_FRACTURE_DYNAMIC && emd->limit_impact && id == 0) {
+			//shrink pointcloud container around impact point, to a size
+			Shard *s = BKE_shard_by_id(emd->frac_mesh, 0, fracmesh);
+			if (s != NULL) {
+				float size[3], nmin[3], nmax[3], loc[3], imat[4][4], tmin[3], tmax[3], quat[4];
+				print_v3("Impact Loc\n", s->impact_loc);
+				print_v3("Impact Size\n", s->impact_size);
+
+				//invert_m4_m4(imat, ob->obmat);
+				//mul_v3_m4v3(loc, imat, s->impact_loc);
+				//mat4_to_quat(quat, imat);
+				//sub_v3_v3v3(loc, s->impact_loc, ob->loc);
+				//mul_qt_v3(quat, loc);
+				copy_v3_v3(loc, s->impact_loc);
+				mul_v3_v3fl(size, s->impact_size, 0.5f);
+				sub_v3_v3v3(nmin, loc, size);
+				add_v3_v3v3(nmax, loc, size);
+
+				copy_v3_v3(tmin, min);
+				copy_v3_v3(tmax, max);
+
+				/*mat4_to_quat(quat, ob->obmat);
+				mul_qt_v3(quat, tmin);
+				mul_qt_v3(quat, tmax);
+				add_v3_v3(tmin, ob->loc);
+				add_v3_v3(tmax, ob->loc);*/
+
+				//clamp
+				if (fabsf(tmin[0]) < fabsf(nmin[0])) {
+					nmin[0] = tmin[0];
+				}
+
+				if (fabsf(tmin[1]) < fabsf(nmin[1])) {
+					nmin[1] = tmin[1];
+				}
+
+				if (fabsf(tmin[2]) < fabsf(nmin[2])) {
+					nmin[2] = tmin[2];
+				}
+
+				if (fabsf(tmax[0]) < fabsf(nmax[0])) {
+					nmax[0] = tmax[0];
+				}
+
+				if (fabsf(tmax[1]) < fabsf(nmax[1])) {
+					nmax[1] = tmax[1];
+				}
+
+				if (fabsf(tmax[2]) < fabsf(nmax[2])) {
+					nmax[2] = tmax[2];
+				}
+
+				copy_v3_v3(max, nmax);
+				copy_v3_v3(min, nmin);
+			}
+		}
+
 		printf("min, max: (%f %f %f), (%f %f %f)\n", min[0], min[1], min[2], max[0], max[1], max[2]);
 
 		if (emd->frac_algorithm == MOD_FRACTURE_BISECT_FAST || emd->frac_algorithm == MOD_FRACTURE_BISECT_FAST_FILL ||
@@ -3098,6 +3156,8 @@ static MeshIsland* find_meshisland(ListBase* meshIslands, int id)
 	return NULL;
 }
 
+
+#if 0
 static bool contains(float loc[3], float size[3], float point[3])
 {
 	if ((fabsf(loc[0] - point[0]) < size[0]) &&
@@ -3140,6 +3200,7 @@ void set_rigidbody_type(FractureModifierData *fmd, Shard *s, MeshIsland *mi)
 		}
 	}
 }
+#endif
 
 static void do_island_from_shard(FractureModifierData *fmd, Object *ob, Shard* s, DerivedMesh *orig_dm,
                                  int i, int thresh_defgrp_index, int ground_defgrp_index, int vertstart)
@@ -3287,10 +3348,10 @@ static void do_island_from_shard(FractureModifierData *fmd, Object *ob, Shard* s
 			mi->rigidbody->flag = par->rigidbody->flag;
 		}
 
-		if (fmd->limit_impact)
+		/*if (fmd->limit_impact)
 		{
 			set_rigidbody_type(fmd, s, mi);
-		}
+		}*/
 	}
 }
 
@@ -4128,6 +4189,8 @@ static Shard* copy_shard(Shard *s)
 	t->raw_volume = s->raw_volume;
 	t->shard_id = s->shard_id;
 	t->parent_id = s->parent_id;
+	copy_v3_v3(t->impact_loc, s->impact_loc);
+	copy_v3_v3(t->impact_size, s->impact_size);
 
 	return t;
 }




More information about the Bf-blender-cvs mailing list