[Bf-blender-cvs] [fdea8ecb5b] cloth-improvements: Implement velocity based adaptive step size calculation
Luca Rood
noreply at git.blender.org
Wed Feb 1 07:11:55 CET 2017
Commit: fdea8ecb5b42fb82590a1fc63f639ccbb5f65b3b
Author: Luca Rood
Date: Wed Feb 1 00:55:23 2017 -0200
Branches: cloth-improvements
https://developer.blender.org/rBfdea8ecb5b42fb82590a1fc63f639ccbb5f65b3b
Implement velocity 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 17acca7823..5bfa378fda 100644
--- a/release/scripts/startup/bl_ui/properties_physics_cloth.py
+++ b/release/scripts/startup/bl_ui/properties_physics_cloth.py
@@ -313,6 +313,29 @@ class PHYSICS_PT_cloth_scaling(PhysicButtonsPanel, Panel):
sub.prop(cloth, "shrinking_max", text="Max")
+class PHYSICS_PT_cloth_adaptive_subframes(PhysicButtonsPanel, Panel):
+ bl_label = "Cloth Adaptive Subframes"
+ bl_options = {'DEFAULT_CLOSED'}
+ COMPAT_ENGINES = {'BLENDER_RENDER'}
+
+ def draw(self, context):
+ layout = self.layout
+
+ md = context.cloth
+ cloth = context.cloth.settings
+
+ layout.active = cloth_panel_enabled(md)
+
+ 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")
+
+
class PHYSICS_PT_cloth_field_weights(PhysicButtonsPanel, Panel):
bl_label = "Cloth Field Weights"
bl_options = {'DEFAULT_CLOSED'}
diff --git a/source/blender/blenkernel/BKE_cloth.h b/source/blender/blenkernel/BKE_cloth.h
index ac8838591c..cadacc6948 100644
--- a/source/blender/blenkernel/BKE_cloth.h
+++ b/source/blender/blenkernel/BKE_cloth.h
@@ -111,6 +111,7 @@ typedef struct ClothVertex {
float tx[3]; /* temporary position */
float txold[3]; /* temporary old position */
float tv[3]; /* temporary "velocity", mostly used as tv = tx-txold */
+ float tvold[3];
float mass; /* mass / weight of the vertex */
float goal; /* goal, from SB */
float impulse[3]; /* used in collision.c */
@@ -167,6 +168,7 @@ 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_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 8611e5b98f..16936c1524 100644
--- a/source/blender/blenkernel/intern/cloth.c
+++ b/source/blender/blenkernel/intern/cloth.c
@@ -118,6 +118,11 @@ void cloth_init(ClothModifierData *clmd )
clmd->sim_parms->struct_yield_fact = 1.0f;
clmd->sim_parms->bend_plasticity = 0.0f;
clmd->sim_parms->bend_yield_fact = 0.0f;
+
+ /* Adaptive subframes */
+ clmd->sim_parms->max_subframes = 50;
+ clmd->sim_parms->max_vel = 0.04f;
+ clmd->sim_parms->adjustment_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 b13ba036e8..14a06a450a 100644
--- a/source/blender/makesdna/DNA_cloth_types.h
+++ b/source/blender/makesdna/DNA_cloth_types.h
@@ -111,6 +111,12 @@ typedef struct ClothSimSettings {
char pad0[6];
struct EffectorWeights *effector_weights;
+
+ /* Adaptive subframe stuff */
+ int max_subframes;
+ float max_vel;
+ float adjustment_factor;
+ char pad1[4];
} ClothSimSettings;
diff --git a/source/blender/makesrna/intern/rna_cloth.c b/source/blender/makesrna/intern/rna_cloth.c
index 9c4b545494..fd626e3a1b 100644
--- a/source/blender/makesrna/intern/rna_cloth.c
+++ b/source/blender/makesrna/intern/rna_cloth.c
@@ -197,6 +197,28 @@ static void rna_ClothSettings_max_shrink_set(struct PointerRNA *ptr, float value
settings->max_shrink = value;
}
+static void rna_ClothSettings_subframes_set(struct PointerRNA *ptr, float value)
+{
+ ClothSimSettings *settings = (ClothSimSettings *)ptr->data;
+
+ settings->stepsPerFrame = value;
+
+ /* check for max clipping */
+ if (value > settings->max_subframes)
+ settings->max_subframes = value;
+}
+
+static void rna_ClothSettings_max_subframes_set(struct PointerRNA *ptr, int value)
+{
+ ClothSimSettings *settings = (ClothSimSettings *)ptr->data;
+
+ /* check for clipping */
+ if (value < settings->stepsPerFrame)
+ value = settings->stepsPerFrame;
+
+ settings->max_subframes = value;
+}
+
static void rna_ClothSettings_mass_vgroup_get(PointerRNA *ptr, char *value)
{
ClothSimSettings *sim = (ClothSimSettings *)ptr->data;
@@ -545,6 +567,7 @@ static void rna_def_cloth_sim_settings(BlenderRNA *brna)
RNA_def_property_int_sdna(prop, NULL, "stepsPerFrame");
RNA_def_property_range(prop, 1, INT_MAX);
RNA_def_property_ui_range(prop, 1, 80, 1, -1);
+ RNA_def_property_int_funcs(prop, NULL, "rna_ClothSettings_subframes_set", NULL);
RNA_def_property_ui_text(prop, "Quality",
"Quality of the simulation in steps per frame (higher is better quality but slower)");
RNA_def_property_update(prop, 0, "rna_cloth_update");
@@ -583,6 +606,33 @@ static void rna_def_cloth_sim_settings(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Voxel Grid Cell Size", "Size of the voxel grid cells for interaction effects");
RNA_def_property_update(prop, 0, "rna_cloth_update");
+ /* 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_clear_flag(prop, PROP_ANIMATABLE);
+ RNA_def_property_update(prop, 0, "rna_cloth_update");
+
+ prop = RNA_def_property(srna, "max_sub_steps", PROP_INT, PROP_NONE);
+ RNA_def_property_int_sdna(prop, NULL, "max_subframes");
+ RNA_def_property_range(prop, 1, INT_MAX);
+ RNA_def_property_ui_range(prop, 1, 80, 1, -1);
+ RNA_def_property_int_funcs(prop, NULL, "rna_ClothSettings_max_subframes_set", NULL);
+ RNA_def_property_ui_text(prop, "Max Subframes", "Maximum number of subframes to use with adaptive subframes");
+ RNA_def_property_update(prop, 0, "rna_cloth_update");
+
+ prop = RNA_def_property(srna, "max_velocity", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "max_vel");
+ RNA_def_property_range(prop, 0.001f, 1.0f);
+ RNA_def_property_ui_text(prop, "Maximum Velocity", "Maximum velocity before increasing subframes");
+ RNA_def_property_update(prop, 0, "rna_cloth_update");
+
+ prop = RNA_def_property(srna, "adjustment_factor", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "adjustment_factor");
+ RNA_def_property_range(prop, 0.1f, 1.0f);
+ 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");
+
/* 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 53ca40158e..c05a8b9fd9 100644
--- a/source/blender/physics/intern/BPH_mass_spring.cpp
+++ b/source/blender/physics/intern/BPH_mass_spring.cpp
@@ -128,6 +128,7 @@ void BKE_cloth_solver_set_positions(ClothModifierData *clmd)
BPH_mass_spring_set_rest_transform(id, i, I3);
BPH_mass_spring_set_motion_state(id, i, verts[i].x, verts[i].v);
+ copy_v3_v3(verts[i].tvold, verts[i].v);
}
}
@@ -1027,10 +1028,12 @@ int BPH_cloth_solve(Object *ob, float frame, ClothModifierData *clmd, ListBase *
Cloth *cloth = clmd->clothObject;
ClothVertex *verts = cloth->verts/*, *cv*/;
unsigned int mvert_num = cloth->mvert_num;
- float dt = clmd->sim_parms->dt * clmd->sim_parms->timescale;
Implicit_Data *id = cloth->implicit;
ColliderContacts *contacts = NULL;
int totcolliders = 0;
+ float max_vel;
+ float vel;
+ float tmp_vec[3];
BKE_sim_debug_data_clear_category("collision");
@@ -1054,7 +1057,13 @@ int BPH_cloth_solve(Object *ob, float frame, ClothModifierData *clmd, ListBase *
while (step < tf) {
ImplicitSolverResult result;
-
+ float dt = clmd->sim_parms->dt * clmd->sim_parms->timescale;
+ max_vel = 0.0f;
+
+ if (step + dt > tf) {
+ dt = tf - step;
+ }
+
if (is_hair) {
/* determine contact points */
if (clmd->coll_parms->flags & CLOTH_COLLSETTINGS_FLAG_ENABLED) {
@@ -1100,7 +1109,32 @@ int BPH_cloth_solve(Object *ob, float frame, ClothModifierData *clmd, ListBase *
}
BPH_mass_spring_solve_positions(id, dt);
-
+
+ for (i = 0; i < mvert_num; i++) {
+ BPH_mass_spring_get_new_position(id, i, tmp_vec);
+ vel = len_v3v3(tmp_vec, verts[i].txold);
+ max_vel = max_ff(max_vel, vel);
+ }
+
+ /* 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;
+ 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) {
+ for (i = 0; i < mvert_num; i++) {
+ BPH_mass_spring_set_motion_state(id, i, verts[i].txold, verts[i].tvold);
+ }
+
+ continue;
+ }
+ }
+ }
+
BPH_mass_spring_apply_result(id);
/* move pinned verts to correct position */
@@ -1113,15 +1147,15 @@ int BPH_cloth_solve(Object *ob, float frame, ClothModifierData *clmd, ListBase *
BPH_mass_spring_set_position(id, i, x);
}
}
-
- BPH_mass_spring_get_motion_state(id, i, verts[i].txold, NULL);
+
+ BPH_mass_spring_get_motion_state(id, i, verts[i].txold, verts[i].tvold);
}
/* free contact points */
if (contacts) {
cloth_free_contacts(contacts, totcolliders);
}
-
+
step += dt;
}
More information about the Bf-blender-cvs
mailing list