From 362b3bbe58ae378d5e154dd1a27d55d913594a1a Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 30 Jul 2016 14:46:19 +1000 Subject: Cloth Simulation: add time scale property This setting can also be animated, to create a "time warp" effect. D2122 by @LucaRood --- source/blender/blenkernel/intern/cloth.c | 3 ++- source/blender/blenloader/intern/versioning_270.c | 19 +++++++++++++++++++ source/blender/makesdna/DNA_cloth_types.h | 2 ++ source/blender/makesrna/intern/rna_cloth.c | 7 +++++++ source/blender/physics/intern/BPH_mass_spring.cpp | 8 ++++++-- 5 files changed, 36 insertions(+), 3 deletions(-) (limited to 'source/blender') diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c index 22d7cbafe41..681b93172b2 100644 --- a/source/blender/blenkernel/intern/cloth.c +++ b/source/blender/blenkernel/intern/cloth.c @@ -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, ×cale); - 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; diff --git a/source/blender/blenloader/intern/versioning_270.c b/source/blender/blenloader/intern/versioning_270.c index a254a854c66..3e6b0d34ba6 100644 --- a/source/blender/blenloader/intern/versioning_270.c +++ b/source/blender/blenloader/intern/versioning_270.c @@ -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; + } + } + } + } + } } } diff --git a/source/blender/makesdna/DNA_cloth_types.h b/source/blender/makesdna/DNA_cloth_types.h index d385e303a7c..ee147da8dae 100644 --- a/source/blender/makesdna/DNA_cloth_types.h +++ b/source/blender/makesdna/DNA_cloth_types.h @@ -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; diff --git a/source/blender/makesrna/intern/rna_cloth.c b/source/blender/makesrna/intern/rna_cloth.c index 41c08250f0e..781e44c9ed6 100644 --- a/source/blender/makesrna/intern/rna_cloth.c +++ b/source/blender/makesrna/intern/rna_cloth.c @@ -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"); diff --git a/source/blender/physics/intern/BPH_mass_spring.cpp b/source/blender/physics/intern/BPH_mass_spring.cpp index 648ef132655..359395b63c4 100644 --- a/source/blender/physics/intern/BPH_mass_spring.cpp +++ b/source/blender/physics/intern/BPH_mass_spring.cpp @@ -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); } } -- cgit v1.2.3