[Bf-blender-cvs] [d12c650] cloth-improvements: Implement proper sub-step independent plasticity scaling
Luca Rood
noreply at git.blender.org
Fri Jan 6 00:07:00 CET 2017
Commit: d12c6503495d6050e1b888fc1dca447e866797a2
Author: Luca Rood
Date: Wed Jan 4 19:47:48 2017 -0200
Branches: cloth-improvements
https://developer.blender.org/rBd12c6503495d6050e1b888fc1dca447e866797a2
Implement proper sub-step independent plasticity scaling
===================================================================
M source/blender/physics/intern/BPH_mass_spring.cpp
===================================================================
diff --git a/source/blender/physics/intern/BPH_mass_spring.cpp b/source/blender/physics/intern/BPH_mass_spring.cpp
index a8b1a61..b215f5e 100644
--- a/source/blender/physics/intern/BPH_mass_spring.cpp
+++ b/source/blender/physics/intern/BPH_mass_spring.cpp
@@ -333,7 +333,7 @@ static int UNUSED_FUNCTION(cloth_calc_helper_forces)(Object *UNUSED(ob), ClothMo
return 1;
}
-BLI_INLINE void cloth_calc_spring_force(ClothModifierData *clmd, ClothSpring *s, float time)
+BLI_INLINE void cloth_calc_spring_force(ClothModifierData *clmd, ClothSpring *s, float time, float struct_plast, float bend_plast)
{
Cloth *cloth = clmd->clothObject;
ClothSimSettings *parms = clmd->sim_parms;
@@ -384,7 +384,7 @@ BLI_INLINE void cloth_calc_spring_force(ClothModifierData *clmd, ClothSpring *s,
}
BPH_mass_spring_force_spring_linear(data, s->ij, s->kl, s->restlen, &s->lenfact, k_tension, k_compression,
- d_tension, d_compression, no_compress, 0.0f, parms->struct_plasticity, parms->struct_yield_fact);
+ d_tension, d_compression, no_compress, 0.0f, struct_plast, parms->struct_yield_fact);
}
#endif
}
@@ -406,7 +406,7 @@ BLI_INLINE void cloth_calc_spring_force(ClothModifierData *clmd, ClothSpring *s,
}
BPH_mass_spring_force_spring_linear(data, s->ij, s->kl, s->restlen, &s->lenfact, k, 0.0f, d, 0.0f, true, 0.0f,
- parms->struct_plasticity, parms->struct_yield_fact);
+ struct_plast, parms->struct_yield_fact);
#endif
}
else if (s->type & CLOTH_SPRING_TYPE_GOAL) {
@@ -437,7 +437,7 @@ BLI_INLINE void cloth_calc_spring_force(ClothModifierData *clmd, ClothSpring *s,
k = scaling * s->restlen * s->lenfact * 0.1f; /* multiplying by 0.1, just to scale the forces to more reasonable values */
BPH_mass_spring_force_spring_angular(data, s->ij, s->kl, s->pa, s->pb, s->la, s->lb, s->restang, &s->angoffset,
- k, parms->bending_damping, parms->bend_plasticity, parms->bend_yield_fact * M_PI * 2);
+ k, parms->bending_damping, bend_plast, parms->bend_yield_fact * M_PI * 2);
#endif
}
else if (s->type & CLOTH_SPRING_TYPE_BENDING_HAIR) {
@@ -506,6 +506,7 @@ static void cloth_calc_force(ClothModifierData *clmd, float UNUSED(frame), ListB
const MVertTri *tri = cloth->tri;
unsigned int mvert_num = cloth->mvert_num;
ClothVertex *vert;
+ float struct_plast, bend_plast;
#ifdef CLOTH_FORCE_GRAVITY
/* global acceleration (gravitation) */
@@ -578,13 +579,45 @@ static void cloth_calc_force(ClothModifierData *clmd, float UNUSED(frame), ListB
MEM_freeN(winvec);
}
-
+
+ /* Implementation note:
+ * Plasticity defines how much the springs will retain deformations, after reaching the yield factor.
+ * However, this change accumulates over each time step, so say a spring is stretched above the yield factor,
+ * then at each time step that passes, the rest shape will approach the current position.
+ * This causes simulations with more sub-steps to approach the current shape faster.
+ * This is solved by properly scaling the plasticity value.
+ *
+ * Plasticity progresses according to the sum:
+ * sum_1_to_n((1/x - 1)^(i - 1) / (1/x)^i)
+ * Where 'n' is the number of sub-steps, and 'x' is the plasticity.
+ *
+ * For artistic control, we set sum_1_to_n((x - 1)^(i - 1) / x^i) = a
+ * where the artist now controls 'a', which represents how much the shape
+ * changes in one frame (considering all sub-steps).
+ * This has the partial sum formula:
+ * 1 - ((1/x - 1) * x)^n
+ *
+ * Which we can now set equal to 'a' and easily solve for 'x':
+ * x = 1 - (1-a)^(1/n) */
+
+ struct_plast = clmd->sim_parms->struct_plasticity;
+
+ if (!(struct_plast < FLT_EPSILON || 1.0f - struct_plast < FLT_EPSILON)) {
+ struct_plast = 1.0f - powf(1.0f - struct_plast, 1.0f / clmd->sim_parms->stepsPerFrame);
+ }
+
+ bend_plast = clmd->sim_parms->bend_plasticity;
+
+ if (!(bend_plast < FLT_EPSILON || 1.0f - bend_plast < FLT_EPSILON)) {
+ bend_plast = 1.0f - powf(1.0f - bend_plast, 1.0f / clmd->sim_parms->stepsPerFrame);
+ }
+
// calculate spring forces
for (LinkNode *link = cloth->springs; link; link = link->next) {
ClothSpring *spring = (ClothSpring *)link->link;
// only handle active springs
if (!(spring->flags & CLOTH_SPRING_FLAG_DEACTIVATE))
- cloth_calc_spring_force(clmd, spring, time);
+ cloth_calc_spring_force(clmd, spring, time, struct_plast, bend_plast);
}
}
More information about the Bf-blender-cvs
mailing list