diff options
Diffstat (limited to 'source/blender/physics/intern')
-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 |
3 files changed, 61 insertions, 20 deletions
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) */ |