[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