diff options
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/blenkernel/BKE_cloth.h | 8 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/cloth.c | 18 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/particle_system.c | 2 | ||||
-rw-r--r-- | source/blender/blenloader/intern/versioning_280.c | 24 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_cloth_types.h | 18 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_cloth.c | 179 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_particle.c | 2 | ||||
-rw-r--r-- | source/blender/physics/intern/BPH_mass_spring.cpp | 38 | ||||
-rw-r--r-- | source/blender/physics/intern/implicit.h | 5 | ||||
-rw-r--r-- | source/blender/physics/intern/implicit_blender.c | 38 |
10 files changed, 267 insertions, 65 deletions
diff --git a/source/blender/blenkernel/BKE_cloth.h b/source/blender/blenkernel/BKE_cloth.h index 82a8d7f4e43..a099ae46d78 100644 --- a/source/blender/blenkernel/BKE_cloth.h +++ b/source/blender/blenkernel/BKE_cloth.h @@ -167,11 +167,17 @@ typedef enum { CLOTH_SIMSETTINGS_FLAG_TEARING = ( 1 << 4 ),// true if tearing is enabled CLOTH_SIMSETTINGS_FLAG_SCALING = ( 1 << 8 ), /* is advanced scaling active? */ CLOTH_SIMSETTINGS_FLAG_CCACHE_EDIT = (1 << 12), /* edit cache in editmode */ - CLOTH_SIMSETTINGS_FLAG_NO_SPRING_COMPRESS = (1 << 13), /* don't allow spring compression */ + CLOTH_SIMSETTINGS_FLAG_RESIST_SPRING_COMPRESS = (1 << 13), /* don't allow spring compression */ CLOTH_SIMSETTINGS_FLAG_SEW = (1 << 14), /* pull ends of loose edges together */ CLOTH_SIMSETTINGS_FLAG_DYNAMIC_BASEMESH = (1 << 15), /* make simulation respect deformations in the base object */ } CLOTH_SIMSETTINGS_FLAGS; +/* ClothSimSettings.bending_model. */ +typedef enum { + CLOTH_BENDING_LINEAR = 0, + CLOTH_BENDING_ANGULAR = 1, +} CLOTH_BENDING_MODEL; + /* COLLISION FLAGS */ typedef enum { CLOTH_COLLSETTINGS_FLAG_ENABLED = ( 1 << 1 ), /* enables cloth - object collisions */ diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c index caf5b94b30e..54236785509 100644 --- a/source/blender/blenkernel/intern/cloth.c +++ b/source/blender/blenkernel/intern/cloth.c @@ -85,13 +85,18 @@ void cloth_init(ClothModifierData *clmd ) clmd->sim_parms->gravity[0] = 0.0; clmd->sim_parms->gravity[1] = 0.0; clmd->sim_parms->gravity[2] = -9.81; - clmd->sim_parms->structural = 15.0; - clmd->sim_parms->max_struct = 15.0; - clmd->sim_parms->shear = 15.0; + clmd->sim_parms->tension = 15.0; + clmd->sim_parms->max_tension = 15.0; + clmd->sim_parms->compression = 15.0; + clmd->sim_parms->max_compression = 15.0; + clmd->sim_parms->shear = 5.0; + clmd->sim_parms->max_shear = 5.0; clmd->sim_parms->bending = 0.5; clmd->sim_parms->max_bend = 0.5; + clmd->sim_parms->tension_damp = 5.0; + clmd->sim_parms->compression_damp = 5.0; + clmd->sim_parms->shear_damp = 5.0; clmd->sim_parms->bending_damping = 0.5; - clmd->sim_parms->Cdis = 5.0; clmd->sim_parms->Cvi = 1.0; clmd->sim_parms->mass = 0.3f; clmd->sim_parms->stepsPerFrame = 5; @@ -134,6 +139,8 @@ void cloth_init(ClothModifierData *clmd ) clmd->sim_parms->voxel_cell_size = 0.1f; + clmd->sim_parms->bending_model = CLOTH_BENDING_ANGULAR; + if (!clmd->sim_parms->effector_weights) clmd->sim_parms->effector_weights = BKE_add_effector_weights(NULL); @@ -728,6 +735,9 @@ static void cloth_apply_vgroup ( ClothModifierData *clmd, Mesh *mesh ) if (clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_SCALING ) { if ( dvert->dw[j].def_nr == (clmd->sim_parms->vgroup_struct-1)) { verts->struct_stiff = dvert->dw [j].weight; + } + + if ( dvert->dw[j].def_nr == (clmd->sim_parms->vgroup_shear-1)) { verts->shear_stiff = dvert->dw [j].weight; } diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c index de4d25a95d9..a5ce7893d3e 100644 --- a/source/blender/blenkernel/intern/particle_system.c +++ b/source/blender/blenkernel/intern/particle_system.c @@ -3171,7 +3171,7 @@ static void do_hair_dynamics(ParticleSimulationData *sim) psys->clmd = (ClothModifierData*)modifier_new(eModifierType_Cloth); psys->clmd->sim_parms->goalspring = 0.0f; psys->clmd->sim_parms->vel_damping = 1.0f; - psys->clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_GOAL|CLOTH_SIMSETTINGS_FLAG_NO_SPRING_COMPRESS; + psys->clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_GOAL|CLOTH_SIMSETTINGS_FLAG_RESIST_SPRING_COMPRESS; psys->clmd->coll_parms->flags &= ~CLOTH_COLLSETTINGS_FLAG_SELF; } diff --git a/source/blender/blenloader/intern/versioning_280.c b/source/blender/blenloader/intern/versioning_280.c index 987e4bb3cfa..a35c0531059 100644 --- a/source/blender/blenloader/intern/versioning_280.c +++ b/source/blender/blenloader/intern/versioning_280.c @@ -40,6 +40,7 @@ #include "DNA_object_types.h" #include "DNA_camera_types.h" +#include "DNA_cloth_types.h" #include "DNA_collection_types.h" #include "DNA_constraint_types.h" #include "DNA_gpu_types.h" @@ -80,6 +81,7 @@ #include "BKE_gpencil.h" #include "BKE_paint.h" #include "BKE_object.h" +#include "BKE_cloth.h" #include "BLT_translation.h" @@ -1920,5 +1922,27 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain) } } } + + if (!DNA_struct_elem_find(fd->filesdna, "ClothSimSettings", "short", "bending_model")) { + for (Object *ob = bmain->object.first; ob; ob = ob->id.next) { + for (ModifierData *md = ob->modifiers.first; md; md = md->next) { + if (md->type == eModifierType_Cloth) { + ClothModifierData *clmd = (ClothModifierData *)md; + + clmd->sim_parms->bending_model = CLOTH_BENDING_LINEAR; + clmd->sim_parms->tension = clmd->sim_parms->structural; + clmd->sim_parms->compression = clmd->sim_parms->structural; + clmd->sim_parms->shear = clmd->sim_parms->structural; + clmd->sim_parms->max_tension = clmd->sim_parms->max_struct; + clmd->sim_parms->max_compression = clmd->sim_parms->max_struct; + clmd->sim_parms->max_shear = clmd->sim_parms->max_struct; + clmd->sim_parms->vgroup_shear = clmd->sim_parms->vgroup_struct; + clmd->sim_parms->tension_damp = clmd->sim_parms->Cdis; + clmd->sim_parms->compression_damp = clmd->sim_parms->Cdis; + clmd->sim_parms->shear_damp = clmd->sim_parms->Cdis; + } + } + } + } } } diff --git a/source/blender/makesdna/DNA_cloth_types.h b/source/blender/makesdna/DNA_cloth_types.h index 940872fd08d..1b7f3ab9c4a 100644 --- a/source/blender/makesdna/DNA_cloth_types.h +++ b/source/blender/makesdna/DNA_cloth_types.h @@ -49,17 +49,17 @@ typedef struct ClothSimSettings { struct LinkNode *cache; /* UNUSED atm */ float mingoal; /* see SB */ - float Cdis; /* Mechanical damping of springs. */ + float Cdis DNA_DEPRECATED; /* Mechanical damping of springs. */ float Cvi; /* Viscous/fluid damping. */ float gravity[3]; /* Gravity/external force vector. */ float dt; /* This is the duration of our time step, computed. */ float mass; /* The mass of the entire cloth. */ - float structural; /* Structural spring stiffness. */ + float structural DNA_DEPRECATED; /* Structural spring stiffness. */ float shear; /* Shear spring stiffness. */ float bending; /* Flexion spring stiffness. */ float max_bend; /* max bending scaling value, min is "bending" */ - float max_struct; /* max structural scaling value, min is "structural" */ - float max_shear; /* max shear scaling value, UNUSED */ + float max_struct DNA_DEPRECATED; /* max structural scaling value, min is "structural" */ + float max_shear; /* max shear scaling value */ float max_sewing; /* max sewing force */ float avg_spring_len; /* used for normalized springs */ float timescale; /* parameter how fast cloth runs */ @@ -101,6 +101,16 @@ typedef struct ClothSimSettings { char pad0[4]; struct EffectorWeights *effector_weights; + + short bending_model; + short vgroup_shear; /* Vertex group for scaling structural stiffness. */ + float tension; + float compression; + float max_tension; + float max_compression; + float tension_damp; /* Mechanical damping of tension springs. */ + float compression_damp; /* Mechanical damping of compression springs. */ + float shear_damp; /* Mechanical damping of shear springs. */ } ClothSimSettings; diff --git a/source/blender/makesrna/intern/rna_cloth.c b/source/blender/makesrna/intern/rna_cloth.c index 0958011a7f0..f46f6e96b62 100644 --- a/source/blender/makesrna/intern/rna_cloth.c +++ b/source/blender/makesrna/intern/rna_cloth.c @@ -97,26 +97,70 @@ static void rna_ClothSettings_max_bend_set(struct PointerRNA *ptr, float value) settings->max_bend = value; } -static void rna_ClothSettings_structural_set(struct PointerRNA *ptr, float value) +static void rna_ClothSettings_tension_set(struct PointerRNA *ptr, float value) { ClothSimSettings *settings = (ClothSimSettings *)ptr->data; - settings->structural = value; + settings->tension = value; /* check for max clipping */ - if (value > settings->max_struct) - settings->max_struct = value; + if (value > settings->max_tension) + settings->max_tension = value; } -static void rna_ClothSettings_max_struct_set(struct PointerRNA *ptr, float value) +static void rna_ClothSettings_max_tension_set(struct PointerRNA *ptr, float value) { ClothSimSettings *settings = (ClothSimSettings *)ptr->data; /* check for clipping */ - if (value < settings->structural) - value = settings->structural; + if (value < settings->tension) + value = settings->tension; - settings->max_struct = value; + settings->max_tension = value; +} + +static void rna_ClothSettings_compression_set(struct PointerRNA *ptr, float value) +{ + ClothSimSettings *settings = (ClothSimSettings *)ptr->data; + + settings->compression = value; + + /* check for max clipping */ + if (value > settings->max_compression) + settings->max_compression = value; +} + +static void rna_ClothSettings_max_compression_set(struct PointerRNA *ptr, float value) +{ + ClothSimSettings *settings = (ClothSimSettings *)ptr->data; + + /* check for clipping */ + if (value < settings->compression) + value = settings->compression; + + settings->max_compression = value; +} + +static void rna_ClothSettings_shear_set(struct PointerRNA *ptr, float value) +{ + ClothSimSettings *settings = (ClothSimSettings *)ptr->data; + + settings->shear = value; + + /* check for max clipping */ + if (value > settings->max_shear) + settings->max_shear = value; +} + +static void rna_ClothSettings_max_shear_set(struct PointerRNA *ptr, float value) +{ + ClothSimSettings *settings = (ClothSimSettings *)ptr->data; + + /* check for clipping */ + if (value < settings->shear) + value = settings->shear; + + settings->max_shear = value; } static void rna_ClothSettings_max_sewing_set(struct PointerRNA *ptr, float value) @@ -184,6 +228,24 @@ static void rna_ClothSettings_struct_vgroup_set(PointerRNA *ptr, const char *val rna_object_vgroup_name_index_set(ptr, value, &sim->vgroup_struct); } +static void rna_ClothSettings_shear_vgroup_get(PointerRNA *ptr, char *value) +{ + ClothSimSettings *sim = (ClothSimSettings *)ptr->data; + rna_object_vgroup_name_index_get(ptr, value, sim->vgroup_shear); +} + +static int rna_ClothSettings_shear_vgroup_length(PointerRNA *ptr) +{ + ClothSimSettings *sim = (ClothSimSettings *)ptr->data; + return rna_object_vgroup_name_index_length(ptr, sim->vgroup_shear); +} + +static void rna_ClothSettings_shear_vgroup_set(PointerRNA *ptr, const char *value) +{ + ClothSimSettings *sim = (ClothSimSettings *)ptr->data; + rna_object_vgroup_name_index_set(ptr, value, &sim->vgroup_shear); +} + static void rna_ClothSettings_bend_vgroup_get(PointerRNA *ptr, char *value) { ClothSimSettings *sim = (ClothSimSettings *)ptr->data; @@ -350,6 +412,12 @@ static void rna_def_cloth_sim_settings(BlenderRNA *brna) StructRNA *srna; PropertyRNA *prop; + static const EnumPropertyItem prop_bending_model_items[] = { + {CLOTH_BENDING_ANGULAR, "ANGULAR", 0, "Angular", "Cloth model with angular bending springs"}, + {CLOTH_BENDING_LINEAR, "LINEAR", 0, "Linear", "Cloth model with linear bending springs (legacy)"}, + {0, NULL, 0, NULL, NULL} + }; + srna = RNA_def_struct(brna, "ClothSettings", NULL); RNA_def_struct_ui_text(srna, "Cloth Settings", "Cloth simulation settings for an object"); RNA_def_struct_sdna(srna, "ClothSimSettings"); @@ -511,25 +579,67 @@ static void rna_def_cloth_sim_settings(BlenderRNA *brna) RNA_def_property_update(prop, 0, "rna_cloth_update"); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - prop = RNA_def_property(srna, "spring_damping", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "Cdis"); + prop = RNA_def_property(srna, "tension_damping", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "tension_damp"); RNA_def_property_range(prop, 0.0f, 50.0f); - RNA_def_property_ui_text(prop, "Spring Damping", - "Damping of cloth velocity (higher = more smooth, less jiggling)"); + RNA_def_property_ui_text(prop, "Tension Spring Damping", + "Damping of spring velocity (higher = more smooth, less jiggling)"); RNA_def_property_update(prop, 0, "rna_cloth_update"); - prop = RNA_def_property(srna, "structural_stiffness", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "structural"); + prop = RNA_def_property(srna, "compression_damping", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "compression_damp"); + RNA_def_property_range(prop, 0.0f, 50.0f); + RNA_def_property_ui_text(prop, "Compression Spring Damping", + "Damping of spring velocity (higher = more smooth, less jiggling)"); + RNA_def_property_update(prop, 0, "rna_cloth_update"); + + prop = RNA_def_property(srna, "shear_damping", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "shear_damp"); + RNA_def_property_range(prop, 0.0f, 50.0f); + RNA_def_property_ui_text(prop, "Shear Spring Damping", + "Damping of spring velocity (higher = more smooth, less jiggling)"); + RNA_def_property_update(prop, 0, "rna_cloth_update"); + + prop = RNA_def_property(srna, "tension_stiffness", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "tension"); RNA_def_property_range(prop, 0.0f, 10000.0f); - RNA_def_property_float_funcs(prop, NULL, "rna_ClothSettings_structural_set", NULL); - RNA_def_property_ui_text(prop, "Structural Stiffness", "Overall stiffness of structure"); + RNA_def_property_float_funcs(prop, NULL, "rna_ClothSettings_tension_set", NULL); + RNA_def_property_ui_text(prop, "Tension Stiffness", "Tension stiffness of structure"); + RNA_def_property_update(prop, 0, "rna_cloth_update"); + + prop = RNA_def_property(srna, "tension_stiffness_max", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "max_tension"); + RNA_def_property_range(prop, 0.0f, 10000.0f); + RNA_def_property_float_funcs(prop, NULL, "rna_ClothSettings_max_tension_set", NULL); + RNA_def_property_ui_text(prop, "Tension Stiffness Maximum", "Maximum tension stiffness value"); + RNA_def_property_update(prop, 0, "rna_cloth_update"); + + prop = RNA_def_property(srna, "compression_stiffness", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "compression"); + RNA_def_property_range(prop, 0.0f, 10000.0f); + RNA_def_property_float_funcs(prop, NULL, "rna_ClothSettings_compression_set", NULL); + RNA_def_property_ui_text(prop, "Compression Stiffness", "Compression stiffness of structure"); + RNA_def_property_update(prop, 0, "rna_cloth_update"); + + prop = RNA_def_property(srna, "compression_stiffness_max", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "max_compression"); + RNA_def_property_range(prop, 0.0f, 10000.0f); + RNA_def_property_float_funcs(prop, NULL, "rna_ClothSettings_max_compression_set", NULL); + RNA_def_property_ui_text(prop, "Compression Stiffness Maximum", "Maximum compression stiffness value"); + RNA_def_property_update(prop, 0, "rna_cloth_update"); + + prop = RNA_def_property(srna, "shear_stiffness", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "shear"); + RNA_def_property_range(prop, 0.0f, 10000.0f); + RNA_def_property_float_funcs(prop, NULL, "rna_ClothSettings_shear_set", NULL); + RNA_def_property_ui_text(prop, "Shear Stiffness", "Shear spring stiffness"); RNA_def_property_update(prop, 0, "rna_cloth_update"); - prop = RNA_def_property(srna, "structural_stiffness_max", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "max_struct"); + prop = RNA_def_property(srna, "shear_stiffness_max", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "max_shear"); RNA_def_property_range(prop, 0.0f, 10000.0f); - RNA_def_property_float_funcs(prop, NULL, "rna_ClothSettings_max_struct_set", NULL); - RNA_def_property_ui_text(prop, "Structural Stiffness Maximum", "Maximum structural stiffness value"); + RNA_def_property_float_funcs(prop, NULL, "rna_ClothSettings_max_shear_set", NULL); + RNA_def_property_ui_text(prop, "Shear Stiffness Maximum", "Maximum shear scaling value"); RNA_def_property_update(prop, 0, "rna_cloth_update"); prop = RNA_def_property(srna, "sewing_force_max", PROP_FLOAT, PROP_NONE); @@ -547,6 +657,14 @@ static void rna_def_cloth_sim_settings(BlenderRNA *brna) "Vertex group for fine control over structural stiffness"); RNA_def_property_update(prop, 0, "rna_cloth_update"); + prop = RNA_def_property(srna, "vertex_group_shear_stiffness", PROP_STRING, PROP_NONE); + RNA_def_property_string_funcs(prop, "rna_ClothSettings_shear_vgroup_get", + "rna_ClothSettings_shear_vgroup_length", + "rna_ClothSettings_shear_vgroup_set"); + RNA_def_property_ui_text(prop, "Shear Stiffness Vertex Group", + "Vertex group for fine control over shear stiffness"); + RNA_def_property_update(prop, 0, "rna_cloth_update"); + prop = RNA_def_property(srna, "bending_stiffness", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "bending"); RNA_def_property_range(prop, 0.0f, 10000.0f); @@ -601,24 +719,17 @@ static void rna_def_cloth_sim_settings(BlenderRNA *brna) RNA_def_property_update(prop, 0, "rna_cloth_update"); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + prop = RNA_def_property(srna, "bending_model", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "bending_model"); + RNA_def_property_enum_items(prop, prop_bending_model_items); + RNA_def_property_ui_text(prop, "Bending Model", "Physical model for simulating bending forces"); + RNA_def_property_update(prop, 0, "rna_cloth_update"); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + /* unused */ /* unused still */ #if 0 - prop = RNA_def_property(srna, "shear_stiffness", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "shear"); - RNA_def_property_range(prop, 0.0f, 1000.0f); - RNA_def_property_ui_text(prop, "Shear Stiffness", "Shear spring stiffness"); -#endif - /* unused still */ -#if 0 - prop = RNA_def_property(srna, "shear_stiffness_max", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "max_shear"); - RNA_def_property_range(prop, 0.0f, upperLimitf); - RNA_def_property_ui_text(prop, "Shear Stiffness Maximum", "Maximum shear scaling value"); -#endif - /* unused still */ -#if 0 prop = RNA_def_property(srna, "effector_force_scale", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "eff_force_scale"); RNA_def_property_range(prop, 0.0f, 100.0f); diff --git a/source/blender/makesrna/intern/rna_particle.c b/source/blender/makesrna/intern/rna_particle.c index 979e5d433e7..02574b2c38c 100644 --- a/source/blender/makesrna/intern/rna_particle.c +++ b/source/blender/makesrna/intern/rna_particle.c @@ -755,7 +755,7 @@ static void rna_Particle_hair_dynamics_update(Main *bmain, Scene *scene, Pointer if (psys && !psys->clmd) { psys->clmd = (ClothModifierData *)modifier_new(eModifierType_Cloth); psys->clmd->sim_parms->goalspring = 0.0f; - psys->clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_GOAL | CLOTH_SIMSETTINGS_FLAG_NO_SPRING_COMPRESS; + psys->clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_GOAL | CLOTH_SIMSETTINGS_FLAG_RESIST_SPRING_COMPRESS; psys->clmd->coll_parms->flags &= ~CLOTH_COLLSETTINGS_FLAG_SELF; rna_Particle_redo(bmain, scene, ptr); } diff --git a/source/blender/physics/intern/BPH_mass_spring.cpp b/source/blender/physics/intern/BPH_mass_spring.cpp index 2f24231f992..668e40e71cc 100644 --- a/source/blender/physics/intern/BPH_mass_spring.cpp +++ b/source/blender/physics/intern/BPH_mass_spring.cpp @@ -341,31 +341,53 @@ BLI_INLINE void cloth_calc_spring_force(ClothModifierData *clmd, ClothSpring *s) Cloth *cloth = clmd->clothObject; ClothSimSettings *parms = clmd->sim_parms; Implicit_Data *data = cloth->implicit; - - bool no_compress = parms->flags & CLOTH_SIMSETTINGS_FLAG_NO_SPRING_COMPRESS; + bool new_compress = parms->bending_model == CLOTH_BENDING_ANGULAR; + bool resist_compress = (parms->flags & CLOTH_SIMSETTINGS_FLAG_RESIST_SPRING_COMPRESS) && !new_compress; s->flags &= ~CLOTH_SPRING_FLAG_NEEDED; // calculate force of structural + shear springs - if ((s->type & CLOTH_SPRING_TYPE_STRUCTURAL) || (s->type & CLOTH_SPRING_TYPE_SHEAR) || (s->type & CLOTH_SPRING_TYPE_SEWING) ) { + if ((s->type & CLOTH_SPRING_TYPE_STRUCTURAL) || (s->type & CLOTH_SPRING_TYPE_SEWING)) { #ifdef CLOTH_FORCE_SPRING_STRUCTURAL - float k, scaling; + float k_tension, scaling_tension; s->flags |= CLOTH_SPRING_FLAG_NEEDED; - scaling = parms->structural + s->stiffness * fabsf(parms->max_struct - parms->structural); - k = scaling / (parms->avg_spring_len + FLT_EPSILON); + scaling_tension = parms->tension + s->stiffness * fabsf(parms->max_tension - parms->tension); + k_tension = scaling_tension / (parms->avg_spring_len + FLT_EPSILON); if (s->type & CLOTH_SPRING_TYPE_SEWING) { // TODO: verify, half verified (couldn't see error) // sewing springs usually have a large distance at first so clamp the force so we don't get tunnelling through colission objects - BPH_mass_spring_force_spring_linear(data, s->ij, s->kl, s->restlen, k, parms->Cdis, no_compress, parms->max_sewing); + BPH_mass_spring_force_spring_linear(data, s->ij, s->kl, s->restlen, + k_tension, parms->tension_damp, + 0.0f, 0.0f, false, false, parms->max_sewing); } else { - BPH_mass_spring_force_spring_linear(data, s->ij, s->kl, s->restlen, k, parms->Cdis, no_compress, 0.0f); + float k_compression, scaling_compression; + scaling_compression = parms->compression + s->stiffness * fabsf(parms->max_compression - parms->compression); + k_compression = scaling_compression / (parms->avg_spring_len + FLT_EPSILON); + + BPH_mass_spring_force_spring_linear(data, s->ij, s->kl, s->restlen, + k_tension, parms->tension_damp, + k_compression, parms->compression_damp, + resist_compress, new_compress, 0.0f); } #endif } + else if (s->type & CLOTH_SPRING_TYPE_SHEAR) { +#ifdef CLOTH_FORCE_SPRING_SHEAR + float k, scaling; + + s->flags |= CLOTH_SPRING_FLAG_NEEDED; + + scaling = parms->shear + s->stiffness * fabsf(parms->max_shear - parms->shear); + k = scaling / (parms->avg_spring_len + FLT_EPSILON); + + BPH_mass_spring_force_spring_linear(data, s->ij, s->kl, s->restlen, k, parms->shear_damp, + 0.0f, 0.0f, resist_compress, false, 0.0f); +#endif + } else if (s->type & CLOTH_SPRING_TYPE_BENDING) { /* calculate force of bending springs */ #ifdef CLOTH_FORCE_SPRING_BEND float kb, cb, scaling; diff --git a/source/blender/physics/intern/implicit.h b/source/blender/physics/intern/implicit.h index 2eadd3171b0..ffe9dbbec04 100644 --- a/source/blender/physics/intern/implicit.h +++ b/source/blender/physics/intern/implicit.h @@ -50,6 +50,7 @@ extern "C" { #define CLOTH_FORCE_GRAVITY #define CLOTH_FORCE_DRAG #define CLOTH_FORCE_SPRING_STRUCTURAL +#define CLOTH_FORCE_SPRING_SHEAR #define CLOTH_FORCE_SPRING_BEND #define CLOTH_FORCE_SPRING_GOAL #define CLOTH_FORCE_EFFECTORS @@ -114,7 +115,9 @@ void BPH_mass_spring_force_edge_wind(struct Implicit_Data *data, int v1, int v2, void BPH_mass_spring_force_vertex_wind(struct Implicit_Data *data, int v, float radius, const float (*winvec)[3]); /* Linear spring force between two points */ bool BPH_mass_spring_force_spring_linear(struct Implicit_Data *data, int i, int j, float restlen, - float stiffness, float damping, bool no_compress, float clamp_force); + float stiffness_tension, float damping_tension, + float stiffness_compression, float damping_compression, + bool resist_compress, bool new_compress, float clamp_force); /* Bending force, forming a triangle at the base of two structural springs */ bool BPH_mass_spring_force_spring_bending(struct Implicit_Data *data, int i, int j, float restlen, float kb, float cb); /* Angular bending force based on local target vectors */ diff --git a/source/blender/physics/intern/implicit_blender.c b/source/blender/physics/intern/implicit_blender.c index ddd71eb93e3..677e566ff39 100644 --- a/source/blender/physics/intern/implicit_blender.c +++ b/source/blender/physics/intern/implicit_blender.c @@ -1585,9 +1585,13 @@ BLI_INLINE void apply_spring(Implicit_Data *data, int i, int j, const float f[3] } bool BPH_mass_spring_force_spring_linear(Implicit_Data *data, int i, int j, float restlen, - float stiffness, float damping, bool no_compress, float clamp_force) + float stiffness_tension, float damping_tension, + float stiffness_compression, float damping_compression, + bool resist_compress, bool new_compress, float clamp_force) { float extent[3], length, dir[3], vel[3]; + float f[3], dfdx[3][3], dfdv[3][3]; + float damping = 0; // calculate elonglation spring_length(data, i, j, extent, dir, &length, vel); @@ -1595,29 +1599,41 @@ bool BPH_mass_spring_force_spring_linear(Implicit_Data *data, int i, int j, floa /* This code computes not only the force, but also its derivative. Zero derivative effectively disables the spring for the implicit solver. Thus length > restlen makes cloth unconstrained at the start of simulation. */ - if ((length >= restlen && length > 0) || no_compress) { - float stretch_force, f[3], dfdx[3][3], dfdv[3][3]; + if ((length >= restlen && length > 0) || resist_compress) { + float stretch_force; + + damping = damping_tension; - stretch_force = stiffness * (length - restlen); + stretch_force = stiffness_tension * (length - restlen); if (clamp_force > 0.0f && stretch_force > clamp_force) { stretch_force = clamp_force; } mul_v3_v3fl(f, dir, stretch_force); - // Ascher & Boxman, p.21: Damping only during elonglation - // something wrong with it... - madd_v3_v3fl(f, dir, damping * dot_v3v3(vel, dir)); + dfdx_spring(dfdx, dir, length, restlen, stiffness_tension); + } + else if (new_compress) { + /* This is based on the Choi and Ko bending model, which works surprisingly well for compression. */ + float kb = stiffness_compression; + float cb = kb; /* cb equal to kb seems to work, but a factor can be added if necessary */ - dfdx_spring(dfdx, dir, length, restlen, stiffness); - dfdv_damp(dfdv, dir, damping); + damping = damping_compression; - apply_spring(data, i, j, f, dfdx, dfdv); + mul_v3_v3fl(f, dir, fbstar(length, restlen, kb, cb)); - return true; + outerproduct(dfdx, dir, dir); + mul_m3_fl(dfdx, fbstar_jacobi(length, restlen, kb, cb)); } else { return false; } + + madd_v3_v3fl(f, dir, damping * dot_v3v3(vel, dir)); + dfdv_damp(dfdv, dir, damping); + + apply_spring(data, i, j, f, dfdx, dfdv); + + return true; } /* See "Stable but Responsive Cloth" (Choi, Ko 2005) */ |