[Bf-blender-cvs] [6f9cddec21] cloth-improvements: Implement collision impulse based adaptive step size calculation

Luca Rood noreply at git.blender.org
Wed Feb 1 07:11:58 CET 2017


Commit: 6f9cddec2179bca2df89a9ba3b0472bd154d86c9
Author: Luca Rood
Date:   Wed Feb 1 04:09:54 2017 -0200
Branches: cloth-improvements
https://developer.blender.org/rB6f9cddec2179bca2df89a9ba3b0472bd154d86c9

Implement collision impulse based adaptive step size calculation

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

M	release/scripts/startup/bl_ui/properties_physics_cloth.py
M	source/blender/blenkernel/BKE_cloth.h
M	source/blender/blenkernel/intern/cloth.c
M	source/blender/makesdna/DNA_cloth_types.h
M	source/blender/makesrna/intern/rna_cloth.c
M	source/blender/physics/intern/BPH_mass_spring.cpp

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

diff --git a/release/scripts/startup/bl_ui/properties_physics_cloth.py b/release/scripts/startup/bl_ui/properties_physics_cloth.py
index 5bfa378fda..f91bfdc08a 100644
--- a/release/scripts/startup/bl_ui/properties_physics_cloth.py
+++ b/release/scripts/startup/bl_ui/properties_physics_cloth.py
@@ -326,15 +326,25 @@ class PHYSICS_PT_cloth_adaptive_subframes(PhysicButtonsPanel, Panel):
 
         layout.active = cloth_panel_enabled(md)
 
+        layout.prop(cloth, "max_sub_steps")
+        layout.separator()
+
         layout.prop(cloth, "use_adaptive_subframes")
 
         col = layout.column()
         col.active = cloth.use_adaptive_subframes
 
-        col.prop(cloth, "max_sub_steps")
         col.prop(cloth, "max_velocity")
         col.prop(cloth, "adjustment_factor")
 
+        layout.prop(cloth, "use_impulse_adaptive_subframes")
+
+        col = layout.column()
+        col.active = cloth.use_impulse_adaptive_subframes
+
+        col.prop(cloth, "max_impulse")
+        col.prop(cloth, "impulse_adjustment_factor")
+
 
 class PHYSICS_PT_cloth_field_weights(PhysicButtonsPanel, Panel):
     bl_label = "Cloth Field Weights"
diff --git a/source/blender/blenkernel/BKE_cloth.h b/source/blender/blenkernel/BKE_cloth.h
index cadacc6948..0438128b41 100644
--- a/source/blender/blenkernel/BKE_cloth.h
+++ b/source/blender/blenkernel/BKE_cloth.h
@@ -168,7 +168,8 @@ typedef struct ClothSpring {
 /* SIMULATION FLAGS: goal flags,.. */
 /* These are the bits used in SimSettings.flags. */
 typedef enum {
-	CLOTH_SIMSETTINGS_FLAG_ADAPTIVE_SUBFRAMES = (1 << 0), /* use velocity based adaptive subframes*/
+	CLOTH_SIMSETTINGS_FLAG_ADAPTIVE_SUBFRAMES_VEL = (1 << 0), /* use velocity based adaptive subframes*/
+	CLOTH_SIMSETTINGS_FLAG_ADAPTIVE_SUBFRAMES_IMP = (1 << 1), /* use velocity based adaptive subframes*/
 	CLOTH_SIMSETTINGS_FLAG_COLLOBJ = ( 1 << 2 ),// object is only collision object, no cloth simulation is done
 	CLOTH_SIMSETTINGS_FLAG_TEARING = ( 1 << 4 ),// true if tearing is enabled
 	CLOTH_SIMSETTINGS_FLAG_CCACHE_EDIT = (1 << 12),	/* edit cache in editmode */
diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c
index 16936c1524..86087abf3f 100644
--- a/source/blender/blenkernel/intern/cloth.c
+++ b/source/blender/blenkernel/intern/cloth.c
@@ -123,6 +123,8 @@ void cloth_init(ClothModifierData *clmd )
 	clmd->sim_parms->max_subframes = 50;
 	clmd->sim_parms->max_vel = 0.04f;
 	clmd->sim_parms->adjustment_factor = 0.8f;
+	clmd->sim_parms->max_imp = 0.04f;
+	clmd->sim_parms->imp_adj_factor = 0.8f;
 	
 	clmd->coll_parms->self_friction = 5.0;
 	clmd->coll_parms->friction = 5.0;
diff --git a/source/blender/makesdna/DNA_cloth_types.h b/source/blender/makesdna/DNA_cloth_types.h
index 14a06a450a..72fe79d7cb 100644
--- a/source/blender/makesdna/DNA_cloth_types.h
+++ b/source/blender/makesdna/DNA_cloth_types.h
@@ -116,6 +116,8 @@ typedef struct ClothSimSettings {
 	int max_subframes;
 	float max_vel;
 	float adjustment_factor;
+	float max_imp;
+	float imp_adj_factor;
 	char pad1[4];
 } ClothSimSettings;
 
diff --git a/source/blender/makesrna/intern/rna_cloth.c b/source/blender/makesrna/intern/rna_cloth.c
index fd626e3a1b..5dd26d9916 100644
--- a/source/blender/makesrna/intern/rna_cloth.c
+++ b/source/blender/makesrna/intern/rna_cloth.c
@@ -608,8 +608,14 @@ static void rna_def_cloth_sim_settings(BlenderRNA *brna)
 
 	/* Adaptive subframes */
 	prop = RNA_def_property(srna, "use_adaptive_subframes", PROP_BOOLEAN, PROP_NONE);
-	RNA_def_property_boolean_sdna(prop, NULL, "flags", CLOTH_SIMSETTINGS_FLAG_ADAPTIVE_SUBFRAMES);
-	RNA_def_property_ui_text(prop, "Use Adaptive Subframes", "Adapt subframes to the cloth velocity");
+	RNA_def_property_boolean_sdna(prop, NULL, "flags", CLOTH_SIMSETTINGS_FLAG_ADAPTIVE_SUBFRAMES_VEL);
+	RNA_def_property_ui_text(prop, "Use Adaptive Velocity Subframes", "Adapt subframes to the cloth velocity");
+	RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+	RNA_def_property_update(prop, 0, "rna_cloth_update");
+
+	prop = RNA_def_property(srna, "use_impulse_adaptive_subframes", PROP_BOOLEAN, PROP_NONE);
+	RNA_def_property_boolean_sdna(prop, NULL, "flags", CLOTH_SIMSETTINGS_FLAG_ADAPTIVE_SUBFRAMES_IMP);
+	RNA_def_property_ui_text(prop, "Use Adaptive Impulse Subframes", "Adapt subframes to the cloth collision impulses");
 	RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
 	RNA_def_property_update(prop, 0, "rna_cloth_update");
 
@@ -633,6 +639,18 @@ static void rna_def_cloth_sim_settings(BlenderRNA *brna)
 	RNA_def_property_ui_text(prop, "Adjustment Factor", "Factor of the velocity to adjust subframes by (lower means more subframes)");
 	RNA_def_property_update(prop, 0, "rna_cloth_update");
 
+	prop = RNA_def_property(srna, "max_impulse", PROP_FLOAT, PROP_NONE);
+	RNA_def_property_float_sdna(prop, NULL, "max_imp");
+	RNA_def_property_range(prop, 0.001f, 1.0f);
+	RNA_def_property_ui_text(prop, "Maximum Collision Impulse", "Maximum collision impulse before increasing subframes");
+	RNA_def_property_update(prop, 0, "rna_cloth_update");
+
+	prop = RNA_def_property(srna, "impulse_adjustment_factor", PROP_FLOAT, PROP_NONE);
+	RNA_def_property_float_sdna(prop, NULL, "imp_adj_factor");
+	RNA_def_property_range(prop, 0.1f, 1.0f);
+	RNA_def_property_ui_text(prop, "Adjustment Factor", "Factor of the impulse to adjust subframes by (lower means more subframes)");
+	RNA_def_property_update(prop, 0, "rna_cloth_update");
+
 	/* springs */
 	
 	prop = RNA_def_property(srna, "tension_damping", PROP_FLOAT, PROP_NONE);
diff --git a/source/blender/physics/intern/BPH_mass_spring.cpp b/source/blender/physics/intern/BPH_mass_spring.cpp
index c05a8b9fd9..581d3c30a6 100644
--- a/source/blender/physics/intern/BPH_mass_spring.cpp
+++ b/source/blender/physics/intern/BPH_mass_spring.cpp
@@ -928,19 +928,21 @@ static void cloth_calc_volume_force(ClothModifierData *clmd)
 }
 #endif
 
-static void cloth_solve_collisions(Object *ob, ClothModifierData *clmd, float step, float dt)
+static float cloth_solve_collisions(Object *ob, ClothModifierData *clmd, float step, float dt)
 {
 	Cloth *cloth = clmd->clothObject;
 	Implicit_Data *id = cloth->implicit;
 	ClothVertex *verts = cloth->verts;
+	float impulse;
+	float max_impulse = 0.0f;
 	int mvert_num = cloth->mvert_num;
 	const float time_multiplier = 1.0f / (clmd->sim_parms->dt * clmd->sim_parms->timescale);
 	int i;
 	
 	if (!(clmd->coll_parms->flags & (CLOTH_COLLSETTINGS_FLAG_ENABLED | CLOTH_COLLSETTINGS_FLAG_SELF)))
-		return;
+		return 0.0f;
 	if (!clmd->clothObject->bvhtree)
-		return;
+		return 0.0f;
 
 	/* do inertial solve */
 	BPH_mass_spring_solve_velocities_inertial(id);
@@ -963,6 +965,11 @@ static void cloth_solve_collisions(Object *ob, ClothModifierData *clmd, float st
 			if ((clmd->sim_parms->vgroup_mass>0) && (verts [i].flags & CLOTH_VERT_FLAG_PINNED))
 				continue;
 
+			impulse = len_v3(verts[i].dcvel);
+			if (impulse > max_impulse) {
+				max_impulse = impulse;
+			}
+
 			/* Update position, based on old position, only applying delta caused by collision responce */
 			add_v3_v3v3(verts[i].tx, verts[i].txold, verts[i].dcvel);
 			BPH_mass_spring_set_position(id, i, verts[i].tx);
@@ -973,6 +980,8 @@ static void cloth_solve_collisions(Object *ob, ClothModifierData *clmd, float st
 			BPH_mass_spring_set_velocity(id, i, verts[i].tv);
 		}
 	}
+
+	return max_impulse;
 }
 
 static void cloth_clear_result(ClothModifierData *clmd)
@@ -1033,7 +1042,9 @@ int BPH_cloth_solve(Object *ob, float frame, ClothModifierData *clmd, ListBase *
 	int totcolliders = 0;
 	float max_vel;
 	float vel;
+	float max_impulse = 0.0f;
 	float tmp_vec[3];
+	float adapt_fact;
 	
 	BKE_sim_debug_data_clear_category("collision");
 	
@@ -1059,6 +1070,7 @@ int BPH_cloth_solve(Object *ob, float frame, ClothModifierData *clmd, ListBase *
 		ImplicitSolverResult result;
 		float dt = clmd->sim_parms->dt * clmd->sim_parms->timescale;
 		max_vel = 0.0f;
+		adapt_fact = FLT_MAX;
 
 		if (step + dt > tf) {
 			dt = tf - step;
@@ -1094,7 +1106,7 @@ int BPH_cloth_solve(Object *ob, float frame, ClothModifierData *clmd, ListBase *
 		
 		// calculate collision impulses
 		if (!is_hair) {
-			cloth_solve_collisions(ob, clmd, step, dt);
+			max_impulse = cloth_solve_collisions(ob, clmd, step, dt);
 		}
 
 		// calculate forces
@@ -1117,19 +1129,47 @@ int BPH_cloth_solve(Object *ob, float frame, ClothModifierData *clmd, ListBase *
 		}
 
 		/* Adaptive step calculation */
-		if (clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_ADAPTIVE_SUBFRAMES) {
-			clmd->sim_parms->dt *= clmd->sim_parms->max_vel / max_vel * clmd->sim_parms->adjustment_factor;
+		if (clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_ADAPTIVE_SUBFRAMES_VEL) {
+			if (max_vel < FLT_EPSILON) {
+				adapt_fact = FLT_MAX;
+			}
+			else {
+				adapt_fact = clmd->sim_parms->max_vel / max_vel * clmd->sim_parms->adjustment_factor;
+			}
+		}
+
+		if (clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_ADAPTIVE_SUBFRAMES_IMP) {
+			float tmp_fact;
+
+			if (max_impulse < FLT_EPSILON) {
+				tmp_fact = FLT_MAX;
+			}
+			else {
+				tmp_fact = clmd->sim_parms->max_imp / max_impulse * clmd->sim_parms->imp_adj_factor;
+			}
+
+			if (tmp_fact < adapt_fact) {
+				adapt_fact = tmp_fact;
+			}
+		}
+
+		if (clmd->sim_parms->flags & (CLOTH_SIMSETTINGS_FLAG_ADAPTIVE_SUBFRAMES_VEL | CLOTH_SIMSETTINGS_FLAG_ADAPTIVE_SUBFRAMES_IMP)) {
+			clmd->sim_parms->dt *= adapt_fact;
 			clmd->sim_parms->dt = min_ff(1.0f / clmd->sim_parms->stepsPerFrame, clmd->sim_parms->dt);
 
 			if ((clmd->sim_parms->max_subframes > 0) && ((1.0f / clmd->sim_parms->max_subframes) > clmd->sim_parms->dt)) {
 				clmd->sim_parms->dt = 1.0f / clmd->sim_parms->max_subframes;
 			}
 			else {
-				if (max_vel > clmd->sim_parms->max_vel) {
+				if (((max_vel > clmd->sim_parms->max_vel) && (clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_ADAPTIVE_SUBFRAMES_VEL)) ||
+				    ((max_impulse > clmd->sim_parms->max_imp) && (clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_ADAPTIVE_SUBFRAMES_IMP)))
+				{
 					for (i = 0; i < mvert_num; i++) {
 						BPH_mass_spring_set_motion_state(id, i, verts[i].txold, verts[i].tvold);
 					}
 
+					printf("Resetting\n");
+
 					continue;
 				}
 			}




More information about the Bf-blender-cvs mailing list