[Bf-blender-cvs] [fe95515de04] fracture_modifier: performance improvement with convert to keyframes and new adaptive keyframe option (threshold of changes)

Martin Felke noreply at git.blender.org
Tue May 30 17:44:39 CEST 2017


Commit: fe95515de049fe9eecdd540a65283a5935a4534c
Author: Martin Felke
Date:   Tue May 30 17:44:18 2017 +0200
Branches: fracture_modifier
https://developer.blender.org/rBfe95515de049fe9eecdd540a65283a5935a4534c

performance improvement with convert to keyframes and new adaptive keyframe option (threshold of changes)

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

M	source/blender/blenkernel/intern/rigidbody.c
M	source/blender/editors/object/object_modifier.c

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

diff --git a/source/blender/blenkernel/intern/rigidbody.c b/source/blender/blenkernel/intern/rigidbody.c
index 30b57de5e75..338509453db 100644
--- a/source/blender/blenkernel/intern/rigidbody.c
+++ b/source/blender/blenkernel/intern/rigidbody.c
@@ -489,7 +489,7 @@ void BKE_rigidbody_update_cell(struct MeshIsland *mi, Object *ob, float loc[3],
 {
 	float startco[3], centr[3], size[3];
 	short startno[3];
-	int j, n = 0;
+	int j, n = 0, x = 0;
 	bool invalidData;
 
 	/* hrm have to init Normals HERE, because we cant do this in readfile.c in case the file is loaded (have no access to the Object there)*/
@@ -506,22 +506,23 @@ void BKE_rigidbody_update_cell(struct MeshIsland *mi, Object *ob, float loc[3],
 	//invert_m4_m4(ob->imat, ob->obmat);
 	mat4_to_size(size, ob->obmat);
 
-	if (rmd->fracture_mode == MOD_FRACTURE_PREFRACTURED && frame > -1) {
+	if (rmd->fracture_mode != MOD_FRACTURE_DYNAMIC && frame > -1) {
 		/*record only in prefracture case here, when you want to convert to keyframes*/
 		n = frame - mi->start_frame + 1;
+		x = frame - mi->start_frame;
 
 		if (n > mi->frame_count) {
-			mi->locs = MEM_reallocN(mi->locs, sizeof(float) * 3 * (n+1));
-			mi->rots = MEM_reallocN(mi->rots, sizeof(float) * 4 * (n+1));
+			mi->locs = MEM_reallocN(mi->locs, sizeof(float) * 3 * n);
+			mi->rots = MEM_reallocN(mi->rots, sizeof(float) * 4 * n);
 
-			mi->locs[n*3] = loc[0];
-			mi->locs[n*3+1] = loc[1];
-			mi->locs[n*3+2] = loc[2];
+			mi->locs[x*3] = loc[0];
+			mi->locs[x*3+1] = loc[1];
+			mi->locs[x*3+2] = loc[2];
 
-			mi->rots[n*4] = rot[0];
-			mi->rots[n*4+1] = rot[1];
-			mi->rots[n*4+2] = rot[2];
-			mi->rots[n*4+3] = rot[3];
+			mi->rots[x*4] = rot[0];
+			mi->rots[x*4+1] = rot[1];
+			mi->rots[x*4+2] = rot[2];
+			mi->rots[x*4+3] = rot[3];
 			mi->frame_count = n;
 		}
 	}
diff --git a/source/blender/editors/object/object_modifier.c b/source/blender/editors/object/object_modifier.c
index a5be5533250..09ae0fb68b9 100644
--- a/source/blender/editors/object/object_modifier.c
+++ b/source/blender/editors/object/object_modifier.c
@@ -3084,6 +3084,31 @@ static bAnimContext* make_anim_context(Scene* scene, Object* ob)
 	return ac;
 }
 
+MINLINE void div_v3_v3(float r[3], const float a[3], const float b[3])
+{
+	if (b[0] != 0)
+		r[0] = a[0] / b[0];
+	else
+		r[0] = a[0];
+
+	if (b[1] != 0)
+		r[1] = a[1] / b[1];
+	else
+		r[1] = a[1];
+
+	if (b[2] != 0)
+		r[2] = a[2] / b[2];
+	else
+		r[2] = a[2];
+}
+
+MINLINE void compare_v3_fl(bool r[3], const float a[3], const float b)
+{
+	r[0] = fabsf(1.0f - a[0]) > b;
+	r[1] = fabsf(1.0f - a[1]) > b;
+	r[2] = fabsf(1.0f - a[2]) > b;
+}
+
 static Object* do_convert_meshIsland(FractureModifierData* fmd, MeshIsland *mi, Group* gr, Object* ob, Scene* scene,
                                   int start, int end, int count, Object* parent, bool is_baked,
                                   PTCacheID* pid, PointCache *cache, float obloc[3], float diff[3], int *j, Base **base,
@@ -3093,6 +3118,11 @@ static Object* do_convert_meshIsland(FractureModifierData* fmd, MeshIsland *mi,
 	Object* ob_new = NULL;
 	Mesh* me;
 	float cent[3];
+	float prevloc[3] = {0, 0, 0};
+	float prevploc[3] = {0, 0, 0};
+	float prevrot[3] = {0, 0, 0};
+	float prevprot[3] = {0, 0, 0};
+	bool adaptive = threshold > 0;
 
 	char *name = BLI_strdupcat(ob->id.name + 2, "_key");
 
@@ -3135,25 +3165,44 @@ static Object* do_convert_meshIsland(FractureModifierData* fmd, MeshIsland *mi,
 	mul_m4_v3(ob_new->obmat, cent);
 	copy_v3_v3(ob_new->loc, cent);
 
-	if (mi->frame_count > 0) {
+	/*if (mi->frame_count > 0)*/ {
 		if (start < mi->start_frame) {
 			start = mi->start_frame;
 		}
 
-		if (end != mi->start_frame + mi->frame_count) {
+		if (end > (mi->start_frame + mi->frame_count)) {
 			end = mi->start_frame + mi->frame_count;
 		}
 	}
 
 	if (mi->rigidbody->type == RBO_TYPE_ACTIVE)
 	{
-		bAnimContext *ac;
-		short flag = INSERTKEY_FAST | INSERTKEY_NEEDED | INSERTKEY_NO_USERPREF;
-		for (i = start; i < end; i += step)
+		//bAnimContext *ac;
+		int stepp = adaptive ? 1 : step;
+		short flag = INSERTKEY_FAST /*| INSERTKEY_NEEDED*/ | INSERTKEY_NO_USERPREF;
+		for (i = start; i < end; i += stepp)
 		{
-			float size[3];
+			bool dostep = adaptive ? (((i + start) % step == 0) || i == start || i == end) : true;
+			float size[3] = {1, 1, 1};
+			bool locset[3] = {true, true, true};
+			bool rotset[3] = {true, true, true};
+
+			//adaptive optimization, only try to insert necessary frames... but doesnt INSERT_NEEDED do the same ?!
+			if (adaptive || !dostep)
+			{
+				locset[0] = false;
+				locset[1] = false;
+				locset[2] = false;
+
+				rotset[0] = false;
+				rotset[1] = false;
+				rotset[2] = false;
+			}
+
 			copy_v3_v3(size, ob->size);
 
+			//BKE_scene_frame_set(scene, (double)i);
+			if (adaptive || dostep)
 			{
 				float loc[3] = {0.0f, 0.0f, 0.0f}, rot[4] = {0.0f, 0.0f, 0.0f, 0.0f};
 				float mat[4][4];
@@ -3161,15 +3210,62 @@ static Object* do_convert_meshIsland(FractureModifierData* fmd, MeshIsland *mi,
 				//is there a bake, if yes... use that (disabled for now, odd probs...)
 				if (is_baked)
 				{
-					BKE_ptcache_id_time(pid, scene, (float)i, NULL, NULL, NULL);
-					if (BKE_ptcache_read(pid, (float)i, false))
+					//BKE_ptcache_id_time(pid, scene, (float)i, NULL, NULL, NULL);
+					//if (BKE_ptcache_read(pid, (float)i, false))
 					{
-						BKE_ptcache_validate(cache, i);
-						copy_v3_v3(loc, mi->rigidbody->pos);
-						copy_qt_qt(rot, mi->rigidbody->orn);
+						//BKE_ptcache_validate(cache, i);
+						//copy_v3_v3(loc, mi->rigidbody->pos);
+						//copy_qt_qt(rot, mi->rigidbody->orn);
+						int x = i - start;
+
+						loc[0] = mi->locs[x*3];
+						loc[1] = mi->locs[x*3+1];
+						loc[2] = mi->locs[x*3+2];
+
+						rot[0] = mi->rots[x*4];
+						rot[1] = mi->rots[x*4+1];
+						rot[2] = mi->rots[x*4+2];
+						rot[3] = mi->rots[x*4+3];
+
+						if (adaptive)
+						{
+							float diffloc[3], diffploc[3], diffrot[3], diffprot[3], difflq[3], diffrq[3];
+							if (i >= start + 2)
+							{
+								sub_v3_v3v3(diffploc, prevploc, prevloc);
+								sub_v3_v3v3(diffloc, prevloc, loc);
+								div_v3_v3(difflq, diffploc, diffloc);
+								compare_v3_fl(locset, difflq, threshold);
+
+								sub_v3_v3v3(diffprot, prevprot, prevrot);
+								sub_v3_v3v3(diffrot, prevrot, rot);
+								div_v3_v3(diffrq, diffprot, diffrot);
+								compare_v3_fl(rotset, diffrq, threshold);
+							}
+
+							if (i >= start + 1)
+							{
+								copy_v3_v3(prevploc, prevloc);
+								copy_v3_v3(prevprot, prevrot);
+							}
+
+							copy_v3_v3(prevloc, loc);
+							copy_v3_v3(prevrot, rot);
+						}
+
+						if (dostep)
+						{
+							locset[0] = true;
+							locset[1] = true;
+							locset[2] = true;
+
+							rotset[0] = true;
+							rotset[1] = true;
+							rotset[2] = true;
+						}
 					}
 				}
-				else //should not happen anymore, because baking is required now
+				/*else //should not happen anymore, because baking is required now
 				{
 					loc[0] = mi->locs[i*3];
 					loc[1] = mi->locs[i*3+1];
@@ -3179,13 +3275,15 @@ static Object* do_convert_meshIsland(FractureModifierData* fmd, MeshIsland *mi,
 					rot[1] = mi->rots[i*4+1];
 					rot[2] = mi->rots[i*4+2];
 					rot[3] = mi->rots[i*4+3];
-				}
+				}*/
 
 				sub_v3_v3(loc, obloc);
 				add_v3_v3(loc, diff);
 
 				loc_quat_size_to_mat4(mat, loc, rot, size);
-				BKE_scene_frame_set(scene, (double)i);
+
+				if (locset[0] || locset[1] || locset[2] || rotset[0] || rotset[1] || rotset[2])
+					BKE_scene_frame_set(scene, (double)i);
 
 				copy_m4_m4(ob_new->obmat, mat);
 
@@ -3195,25 +3293,35 @@ static Object* do_convert_meshIsland(FractureModifierData* fmd, MeshIsland *mi,
 				copy_v3_v3(ob_new->size, size);
 			}
 
-			insert_keyframe(NULL, (ID*)ob_new, NULL, "Location", "location", 0, i, BEZT_KEYTYPE_KEYFRAME, flag);
-			insert_keyframe(NULL, (ID*)ob_new, NULL, "Location", "location", 1, i, BEZT_KEYTYPE_KEYFRAME, flag);
-			insert_keyframe(NULL, (ID*)ob_new, NULL, "Location", "location", 2, i, BEZT_KEYTYPE_KEYFRAME, flag);
+			if (locset[0])
+				insert_keyframe(NULL, (ID*)ob_new, NULL, "Location", "location", 0, i, BEZT_KEYTYPE_KEYFRAME, flag);
 
-			insert_keyframe(NULL, (ID*)ob_new, NULL, "Rotation", "rotation_euler", 0, i, BEZT_KEYTYPE_KEYFRAME, flag);
-			insert_keyframe(NULL, (ID*)ob_new, NULL, "Rotation", "rotation_euler", 1, i, BEZT_KEYTYPE_KEYFRAME, flag);
-			insert_keyframe(NULL, (ID*)ob_new, NULL, "Rotation", "rotation_euler", 2, i, BEZT_KEYTYPE_KEYFRAME, flag);
+			if (locset[1])
+				insert_keyframe(NULL, (ID*)ob_new, NULL, "Location", "location", 1, i, BEZT_KEYTYPE_KEYFRAME, flag);
 
-			insert_keyframe(NULL, (ID*)ob_new, NULL, "Scale", "scale", 0, i, BEZT_KEYTYPE_KEYFRAME, flag);
-			insert_keyframe(NULL, (ID*)ob_new, NULL, "Scale", "scale", 1, i, BEZT_KEYTYPE_KEYFRAME, flag);
-			insert_keyframe(NULL, (ID*)ob_new, NULL, "Scale", "scale", 2, i, BEZT_KEYTYPE_KEYFRAME, flag);
+			if (locset[2])
+				insert_keyframe(NULL, (ID*)ob_new, NULL, "Location", "location", 2, i, BEZT_KEYTYPE_KEYFRAME, flag);
+
+			if (rotset[0])
+				insert_keyframe(NULL, (ID*)ob_new, NULL, "Rotation", "rotation_euler", 0, i, BEZT_KEYTYPE_KEYFRAME, flag);
+
+			if (rotset[1])
+				insert_keyframe(NULL, (ID*)ob_new, NULL, "Rotation", "rotation_euler", 1, i, BEZT_KEYTYPE_KEYFRAME, flag);
+
+			if (rotset[2])
+				insert_keyframe(NULL, (ID*)ob_new, NULL, "Rotation", "rotation_euler", 2, i, BEZT_KEYTYPE_KEYFRAME, flag);
+
+			//insert_keyframe(NULL, (ID*)ob_new, NULL, "Scale", "scale", 0, i, BEZT_KEYTYPE_KEYFRAME, flag);
+			//insert_keyframe(NULL, (ID*)ob_new, NULL, "Scale", "scale", 1, i, BEZT_KEYTYPE_KEYFRAME, flag);
+			//insert_keyframe(NULL, (ID*)ob_new, NULL, "Scale", "scale", 2, i, BEZT_KEYTYPE_KEYFRAME, flag);
 		}
 
-		if (i + step > end || i == end)
+		/*if (i + step > end || i == end)
 		{
 			ac = make_anim_context(scene, ob_new);
 			clean_action_keys(ac, threshold, false);
 			MEM_freeN(ac);
-		}
+		}*/
 	}
 	else
 	{
@@ -3252,15 +3360,18 @@ static bool convert_modifier_to_keyframes(FractureModifierData* fmd, Group* gr,
 	Base** basarray_old = MEM_mallocN(sizeof(Base*) * count, "conversion_tempbases_old");
 	double starttime;
 
+	is_baked = true;
+
+#if 0


@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list