Cloth Simulation: add time scale property

This setting can also be animated, to create a "time warp" effect.

D2122 by @LucaRood
This commit is contained in:
Campbell Barton 2016-07-30 14:46:19 +10:00
parent 7a4353160c
commit 362b3bbe58
6 changed files with 41 additions and 3 deletions

View File

@ -75,6 +75,11 @@ class PHYSICS_PT_cloth(PhysicButtonsPanel, Panel):
split.label(text="Quality:")
split.prop(cloth, "quality", text="Steps")
split = layout.split(percentage=0.25)
split.label(text="Speed:")
split.prop(cloth, "time_scale", text="Multiplier")
split = layout.split()
col = split.column()

View File

@ -97,6 +97,7 @@ void cloth_init(ClothModifierData *clmd )
clmd->sim_parms->avg_spring_len = 0.0;
clmd->sim_parms->presets = 2; /* cotton as start setting */
clmd->sim_parms->timescale = 1.0f; /* speed factor, describes how fast cloth moves */
clmd->sim_parms->time_scale = 1.0f; /* multiplies cloth speed */
clmd->sim_parms->reset = 0;
clmd->sim_parms->vel_damping = 1.0f; /* 1.0 = no damping, 0.0 = fully dampened */
@ -411,7 +412,7 @@ void clothModifier_do(ClothModifierData *clmd, Scene *scene, Object *ob, Derived
BKE_ptcache_id_from_cloth(&pid, ob, clmd);
BKE_ptcache_id_time(&pid, scene, framenr, &startframe, &endframe, &timescale);
clmd->sim_parms->timescale= timescale;
clmd->sim_parms->timescale= timescale * clmd->sim_parms->time_scale;
if (clmd->sim_parms->reset || (clmd->clothObject && dm->getNumVerts(dm) != clmd->clothObject->mvert_num)) {
clmd->sim_parms->reset = 0;

View File

@ -1231,5 +1231,24 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main)
br->flag |= BRUSH_ACCUMULATE;
}
}
if (!DNA_struct_elem_find(fd->filesdna, "ClothSimSettings", "float", "time_scale")) {
Object *ob;
ModifierData *md;
for (ob = main->object.first; ob; ob = ob->id.next) {
for (md = ob->modifiers.first; md; md = md->next) {
if (md->type == eModifierType_Cloth) {
ClothModifierData *clmd = (ClothModifierData *)md;
clmd->sim_parms->time_scale = 1.0f;
}
else if (md->type == eModifierType_ParticleSystem) {
ParticleSystemModifierData *pmd = (ParticleSystemModifierData *)md;
if (pmd->psys->clmd) {
pmd->psys->clmd->sim_parms->time_scale = 1.0f;
}
}
}
}
}
}
}

View File

@ -63,6 +63,7 @@ typedef struct ClothSimSettings {
float max_sewing; /* max sewing force */
float avg_spring_len; /* used for normalized springs */
float timescale; /* parameter how fast cloth runs */
float time_scale; /* multiplies cloth speed */
float maxgoal; /* see SB */
float eff_force_scale;/* Scaling of effector forces (see softbody_calc_forces).*/
float eff_wind_scale; /* Scaling of effector wind (see softbody_calc_forces). */
@ -98,6 +99,7 @@ typedef struct ClothSimSettings {
short presets; /* used for presets on GUI */
short reset;
char pad0[4];
struct EffectorWeights *effector_weights;
} ClothSimSettings;

View File

@ -442,6 +442,13 @@ static void rna_def_cloth_sim_settings(BlenderRNA *brna)
"Quality of the simulation in steps per frame (higher is better quality but slower)");
RNA_def_property_update(prop, 0, "rna_cloth_update");
prop = RNA_def_property(srna, "time_scale", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "time_scale");
RNA_def_property_range(prop, 0.0f, FLT_MAX);
RNA_def_property_ui_range(prop, 0.0f, 10.0f, 10, 3);
RNA_def_property_ui_text(prop, "Speed", "Cloth speed is multiplied by this value");
RNA_def_property_update(prop, 0, "rna_cloth_update");
prop = RNA_def_property(srna, "vertex_group_shrink", PROP_STRING, PROP_NONE);
RNA_def_property_string_funcs(prop, "rna_ClothSettings_shrink_vgroup_get", "rna_ClothSettings_shrink_vgroup_length",
"rna_ClothSettings_shrink_vgroup_set");

View File

@ -376,7 +376,8 @@ BLI_INLINE void cloth_calc_spring_force(ClothModifierData *clmd, ClothSpring *s,
s->flags |= CLOTH_SPRING_FLAG_NEEDED;
// current_position = xold + t * (newposition - xold)
interp_v3_v3v3(goal_x, verts[s->ij].xold, verts[s->ij].xconst, time);
/* divide by time_scale to prevent goal vertices' delta locations from being multiplied */
interp_v3_v3v3(goal_x, verts[s->ij].xold, verts[s->ij].xconst, time / parms->time_scale);
sub_v3_v3v3(goal_v, verts[s->ij].xconst, verts[s->ij].xold); // distance covered over dt==1
scaling = parms->goalspring + s->stiffness * fabsf(parms->max_struct - parms->goalspring);
@ -1004,6 +1005,8 @@ int BPH_cloth_solve(Object *ob, float frame, ClothModifierData *clmd, ListBase *
float v[3];
sub_v3_v3v3(v, verts[i].xconst, verts[i].xold);
// mul_v3_fl(v, clmd->sim_parms->stepsPerFrame);
/* divide by time_scale to prevent constrained velocities from being multiplied */
mul_v3_fl(v, 1.0f / clmd->sim_parms->time_scale);
BPH_mass_spring_set_velocity(id, i, v);
}
}
@ -1070,7 +1073,8 @@ int BPH_cloth_solve(Object *ob, float frame, ClothModifierData *clmd, ListBase *
if (clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL) {
if (verts[i].flags & CLOTH_VERT_FLAG_PINNED) {
float x[3];
interp_v3_v3v3(x, verts[i].xold, verts[i].xconst, step + dt);
/* divide by time_scale to prevent pinned vertices' delta locations from being multiplied */
interp_v3_v3v3(x, verts[i].xold, verts[i].xconst, (step + dt) / clmd->sim_parms->time_scale);
BPH_mass_spring_set_position(id, i, x);
}
}