[Bf-blender-cvs] [9161459] fracture_modifier: dynamic fracture: finally the transforms seem correct... but this mode still is highly unstable, and is prone to crash often, use sparsely !

Martin Felke noreply at git.blender.org
Mon Jun 1 21:29:25 CEST 2015


Commit: 916145951527eb44a1952798aaf42ed23ace0fe3
Author: Martin Felke
Date:   Wed May 20 23:03:31 2015 +0200
Branches: fracture_modifier
https://developer.blender.org/rB916145951527eb44a1952798aaf42ed23ace0fe3

dynamic fracture: finally the transforms seem correct... but this mode still is highly unstable, and is prone to crash often, use sparsely !

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

M	source/blender/blenkernel/intern/fracture.c
M	source/blender/blenkernel/intern/rigidbody.c
M	source/blender/blenloader/intern/readfile.c
M	source/blender/modifiers/intern/MOD_fracture.c

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

diff --git a/source/blender/blenkernel/intern/fracture.c b/source/blender/blenkernel/intern/fracture.c
index 95d1adb..2c114b3 100644
--- a/source/blender/blenkernel/intern/fracture.c
+++ b/source/blender/blenkernel/intern/fracture.c
@@ -279,7 +279,18 @@ float BKE_shard_calc_minmax(Shard *shard)
 Shard *BKE_shard_by_id(FracMesh *mesh, ShardID id, DerivedMesh *dm) {
 	if ((id < mesh->shard_count) && (id >= 0)) {
 		//return mesh->shard_map[id];
-		return (Shard *)BLI_findlink(&mesh->shard_map, id);
+		//return (Shard *)BLI_findlink(&mesh->shard_map, id);
+		Shard *s = mesh->shard_map.first;
+		while (s)
+		{
+			if (s->shard_id == id)
+			{
+				return s;
+			}
+			s = s->next;
+		}
+
+		return NULL;
 	}
 	else if (id == -1)
 	{
@@ -299,6 +310,7 @@ void BKE_get_shard_minmax(FracMesh *mesh, ShardID id, float min_r[3], float max_
 {
 	Shard *shard = BKE_shard_by_id(mesh, id, dm);
 	if (shard != NULL) {
+		BKE_shard_calc_minmax(shard);
 		copy_v3_v3(min_r, shard->min);
 		copy_v3_v3(max_r, shard->max);
 
@@ -621,13 +633,18 @@ static void parse_cells(cell *cells, int expected_shards, ShardID parent_id, Fra
 	int i = 0, j = 0;
 	Shard *p = BKE_shard_by_id(fm, parent_id, dm), *t;
 	float obmat[4][4]; /* use unit matrix for now */
-	float centroid[3];
+	float centroid[3], pcentroid[3] = {0,0,0};
 	BMesh *bm_parent = NULL;
 	DerivedMesh *dm_parent = NULL;
 	DerivedMesh *dm_p = NULL;
 	Shard **tempshards;
 	Shard **tempresults;
 
+	if (p == NULL)
+	{
+		return;
+	}
+
 	tempshards = MEM_mallocN(sizeof(Shard *) * expected_shards, "tempshards");
 	tempresults = MEM_mallocN(sizeof(Shard *) * expected_shards, "tempresults");
 
@@ -636,6 +653,8 @@ static void parse_cells(cell *cells, int expected_shards, ShardID parent_id, Fra
 
 	if (mode == MOD_FRACTURE_DYNAMIC)
 	{
+		copy_v3_v3(pcentroid, p->centroid);
+		parent_id = p->shard_id;
 		//remove parent shard from map as well
 		BLI_remlink(&fm->shard_map, p);
 		fm->shard_count--;
@@ -697,51 +716,52 @@ static void parse_cells(cell *cells, int expected_shards, ShardID parent_id, Fra
 	fm->shard_count = 0; /* may be not matching with expected shards, so reset... did increment this for
 	                      *progressbar only */
 
-	if (mode == MOD_FRACTURE_DYNAMIC)
-	{
-		Shard *t;
-		/* correct ids of shards here,
-		 * count how many new shards we have*/
-		for (i = 0; i < expected_shards; i++) {
-			Shard *s = tempresults[i];
-			if (s != NULL) {
-				j++;
-			}
-		}
-
+#if 0
+	if (mode == MOD_FRACTURE_DYNAMIC) {
 		/* and start reassigning ids for existing shards */
 		for (t = fm->shard_map.first; t; t = t->next)
 		{
-			//t->parent_id = parent_id;
-			//if (t->shard_id > parent_id)
-			{
-				t->shard_id += j;
-				t->parent_id = t->shard_id;
-			}
+			//mark unfractured (other) shards, just need their meshislands movement instead of parent's
+			t->parent_id = -1;
 		}
 	}
+#endif
 
-#if 0
 	//keep empty ids... need to catch this later
 	if (mode == MOD_FRACTURE_DYNAMIC)
 	{
-		j = BLI_listbase_count(&fm->shard_map);//parent_id + 1;
+		j = 1;
+		if (fm->shard_map.last)
+		{
+			j += ((Shard*)(fm->shard_map.last))->shard_id;
+		}
+
 	}
 	else
 	{
 		j = 0;
 	}
-#endif
 
-	j = 0;
 	for (i = 0; i < expected_shards; i++) {
 		Shard *s = tempresults[i];
 		Shard *t = tempshards[i];
 
 		if (s != NULL) {
 			add_shard(fm, s, mat);
-			s->shard_id = j;
-			j++;
+			s->shard_id += j+1;
+			s->parent_id = parent_id;
+			//printf("ADDED: %d %d %d\n", i, j, s->shard_id);
+			if (parent_id > -1)
+			{
+				int i = 0;
+				MVert *v;
+
+				sub_v3_v3(s->centroid, pcentroid);
+				for (i = 0, v = s->mvert; i < s->totvert; i++, v++)
+				{
+					sub_v3_v3(v->co, pcentroid);
+				}
+			}
 		}
 
 		if (t != NULL) {
diff --git a/source/blender/blenkernel/intern/rigidbody.c b/source/blender/blenkernel/intern/rigidbody.c
index 991e858..1a45e17 100644
--- a/source/blender/blenkernel/intern/rigidbody.c
+++ b/source/blender/blenkernel/intern/rigidbody.c
@@ -1821,10 +1821,22 @@ static int filterCallback(void* world, void* island1, void* island2, void *blend
 static bool check_shard_size(FractureModifierData *fmd, int id)
 {
 	FractureID *fid;
-	float size = 0.01f;
-	Shard *s = BLI_findlink(&fmd->frac_mesh->shard_map, id);
+	float size = 0.1f;
+	Shard *t = fmd->frac_mesh->shard_map.first;
+	Shard *s = NULL;
 
-	if (s == NULL || s->flag & SHARD_FRACTURED)
+	while (t)
+	{
+		if (t->shard_id == id && t->flag & SHARD_INTACT)
+		{
+			printf("FOUND: %d\n", id);
+			s = t;
+			break;
+		}
+		t = t->next;
+	}
+
+	if (s == NULL)
 	{
 		return false;
 	}
@@ -1838,7 +1850,6 @@ static bool check_shard_size(FractureModifierData *fmd, int id)
 		return false;
 	}
 
-#if 0
 	for (fid = fmd->fracture_ids.first; fid; fid = fid->next)
 	{
 		if (fid->shardID == id)
@@ -1846,7 +1857,6 @@ static bool check_shard_size(FractureModifierData *fmd, int id)
 			return false;
 		}
 	}
-#endif
 
 	printf("FRACTURE : %d\n", id);
 
@@ -2553,7 +2563,7 @@ static void rigidbody_update_ob_array(RigidBodyWorld *rbw)
 			if (md->type == eModifierType_Fracture) {
 				rmd = (FractureModifierData *)md;
 				if (isModifierActive(rmd)) {
-					for (mi = rmd->meshIslands.first; j = 0, mi; mi = mi->next) {
+					for (mi = rmd->meshIslands.first, j = 0; mi; mi = mi->next) {
 						rbw->cache_index_map[counter] = mi->rigidbody; /* map all shards of an object to this object index*/
 						rbw->cache_offset_map[counter] = i;
 						mi->linear_index = counter;
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 3ded32a..b32d186 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -4871,6 +4871,9 @@ static void load_fracture_modifier(FileData* fd, FractureModifierData *fmd, Obje
 	fmd->vert_index_map = NULL;
 	fmd->vertex_island_map = NULL;
 
+	/*HARDCODING this for now, until we can version it properly, say with 2.75 ? */
+	fmd->fracture_mode = MOD_FRACTURE_PREFRACTURED;
+
 	if (fm == NULL || fmd->dm_group) {
 		fmd->dm = NULL;
 		fmd->meshIslands.first = NULL;
diff --git a/source/blender/modifiers/intern/MOD_fracture.c b/source/blender/modifiers/intern/MOD_fracture.c
index 0748609..1a46956 100644
--- a/source/blender/modifiers/intern/MOD_fracture.c
+++ b/source/blender/modifiers/intern/MOD_fracture.c
@@ -1522,7 +1522,7 @@ static void do_rigidbody(FractureModifierData *fmd, MeshIsland* mi, Object* ob,
 	mi->rigidbody = NULL;
 	mi->rigidbody = BKE_rigidbody_create_shard(fmd->modifier.scene, ob, mi);
 	mi->rigidbody->type = rb_type;
-	//mi->rigidbody->meshisland_index = i;
+	mi->rigidbody->meshisland_index = i;
 	BKE_rigidbody_calc_shard_mass(ob, mi, orig_dm);
 
 	if (fmd->frac_algorithm == MOD_FRACTURE_BOOLEAN_FRACTAL)
@@ -2777,13 +2777,16 @@ static void do_verts_weights(FractureModifierData *fmd, Shard *s, MeshIsland *mi
 	}
 }
 
-static void do_match_vertex_coords(MeshIsland* mi, MeshIsland *par, Object *ob, int frame)
+#define OUT(name, id, co) printf("%s : %d -> (%.2f, %.2f, %.2f) \n", (name), (id), (co)[0], (co)[1], (co)[2]);
+#define OUT4(name,id, co) printf("%s : %d -> (%.2f, %.2f, %.2f, %.2f) \n", (name), (id), (co)[0], (co)[1], (co)[2], (co)[3]);
+
+static void do_match_vertex_coords(MeshIsland* mi, MeshIsland *par, Object *ob, int frame, bool is_parent)
 {
 	float loc[3] = {0.0f, 0.0f, 0.0f};
 	float rot[4] = {0.0f, 0.0f, 0.0f, 1.0f};
 	int j = 0;
 	float irot[4];
-	//MVert *mvert = mi->physics_mesh->getVertArray(mi->physics_mesh);
+	float centr[3] = {0.0f, 0.0f, 0.0f};
 
 	invert_m4_m4(ob->imat, ob->obmat);
 
@@ -2796,44 +2799,93 @@ static void do_match_vertex_coords(MeshIsland* mi, MeshIsland *par, Object *ob,
 	rot[2] = par->rots[4*frame+2];
 	rot[3] = par->rots[4*frame+3];
 
+	mi->locs[0] = loc[0];
+	mi->locs[1] = loc[1];
+	mi->locs[2] = loc[2];
+
+	mi->rots[0] = rot[0];
+	mi->rots[1] = rot[1];
+	mi->rots[2] = rot[2];
+	mi->rots[3] = rot[3];
+
 	mul_m4_v3(ob->imat, loc);
-	//mat4_to_quat(irot, ob->imat);
-	//mul_qt_qtqt(rot, irot, rot);
+	mat4_to_quat(irot, ob->imat);
 
-	add_v3_v3(mi->centroid, loc);
-	//mul_qt_qtqt(mi->rot, mi->rot, rot);
+#if 0
+	OUT("mi->centroid",mi->id, mi->centroid);
+	OUT("par->centroid",par->id,  par->centroid);
+	OUT("centr", par->id, centr);
+	OUT("loc", par->id, loc);
+	OUT4("rot", par->id, rot);
+#endif
+
+	if (is_parent)
+	{
+		copy_v3_v3(centr, mi->centroid);
+		//mul_qt_v3(rot, centr);
+		add_v3_v3(centr, loc);
+	}
+	else
+	{
+		copy_v3_v3(centr, loc);
+	}
 
-	//match vertices and vertco, perhaps vertno too, yuck...
 	for (j = 0; j < mi->vertex_count; j++)
 	{
 		float co[3];
 
-		//mul_qt_v3(rot, mi->vertices_cached[j]->co);
-		add_v3_v3(mi->vertices_cached[j]->co, loc);
+		//first add vert to centroid, then rotate
+		copy_v3_v3(co, mi->vertices_cached[j]->co);
+		sub_v3_v3(co, mi->centroid);
+		mul_qt_v3(rot, co);
+		add_v3_v3(co, centr);
+		copy_v3_v3(mi->vertices_cached[j]->co, co);
 
 		co[0] = mi->vertco[3*j];
 		co[1] = mi->vertco[3*j+1];
 		co[2] = mi->vertco[3*j+2];
 
-		//mul_qt_v3(rot, co);
-		add_v3_v3(co, loc);
+		sub_v3_v3(co, mi->centroid);
+		mul_qt_v3(rot, co);
+		add_v3_v3(co, centr);
 
 		mi->vertco[3*j]   = co[0];
 		mi->vertco[3*j+1] = co[1];
 		mi->vertco[3*j+2] = co[2];
 	}
+
+	//init rigidbody properly ?
+	copy_v3_v3(mi->centroid, centr);
+	copy_qt_qt(mi->rot, rot);
+	mul_qt_qtqt(rot, irot, rot);
 }
 
-static void do_handle_parent_mi(FractureModifierData *fmd, MeshIsland *mi, MeshIsland *par, Object* ob, int frame)
+static void do_handle_parent_mi(FractureModifierData *fmd, MeshIsland *mi, MeshIsland *par, Object* ob, int frame, bool is_parent)
 {
 	frame -= par->start_frame;
-	do_match_vertex_coords(mi, par, ob, frame);
+	do_match_vertex_coords(mi, par, ob, frame, is_parent);
 
 	BKE_rigidbody_remove_shard(fmd->modifier.scene, par);
 	fmd->modifier.scene->rigidbody_world->object_changed = true;
 	par->rigidbody->flag |= RBO_FLAG_NEEDS_VALIDATE;
 }
 
+static MeshIsland* find_meshisland(ListBase* meshIslands, int id)
+{
+	MeshIsland* mi = meshIslands->first;
+	while (mi)
+	{
+		if (mi->id == id)
+		{
+			return mi;
+		}
+
+		mi = mi->next;
+	}
+
+	return NULL;
+}
+
 static void do_island_from_shard(FractureModifierData *fmd, Object *ob, Shard* s, DerivedMesh *orig_dm,
                           

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list