Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuca Rood <dev@lucarood.com>2018-09-26 18:18:16 +0300
committerLuca Rood <dev@lucarood.com>2018-09-26 18:49:40 +0300
commit0666ece2e2f96571200d693d9d7bee1ca72d026f (patch)
treed19df74e5f36d4a745dd5ea917ccf840a6e61923 /source/blender/physics
parenta27d97d1b737037e7c09d3052ba5c644588024ec (diff)
Cloth: Collision improvements
This commit includes several performance, stability, and reliability improvements to cloth collisions. Most notably: * The implementation of a new self-collisions system. * Multithreading of collision detection. * Implementation of single sided collisions and normal overrides. * Replacement of the `plNearestPoints` function from Bullet with a dedicated solution. Further, this also includes several bug fixes, and algorithmic improvements. Reviewed By: brecht Differential Revision: http://developer.blender.org/D3712
Diffstat (limited to 'source/blender/physics')
-rw-r--r--source/blender/physics/intern/BPH_mass_spring.cpp102
1 files changed, 23 insertions, 79 deletions
diff --git a/source/blender/physics/intern/BPH_mass_spring.cpp b/source/blender/physics/intern/BPH_mass_spring.cpp
index d94f2094f81..d43ce37cbfe 100644
--- a/source/blender/physics/intern/BPH_mass_spring.cpp
+++ b/source/blender/physics/intern/BPH_mass_spring.cpp
@@ -884,20 +884,13 @@ static void cloth_calc_volume_force(ClothModifierData *clmd)
}
#endif
-/* old collision stuff for cloth, use for continuity
- * until a good replacement is ready
- */
-static void cloth_collision_solve_extra(
- Depsgraph *depsgraph, Scene *scene, Object *ob, ClothModifierData *clmd, ListBase *effectors,
- float frame, float step, float dt)
+static void cloth_solve_collisions(Depsgraph *depsgraph, Object *ob, ClothModifierData *clmd, float step, float dt)
{
Cloth *cloth = clmd->clothObject;
Implicit_Data *id = cloth->implicit;
ClothVertex *verts = cloth->verts;
int mvert_num = cloth->mvert_num;
- const float spf = (float)clmd->sim_parms->stepsPerFrame / clmd->sim_parms->timescale;
-
- bool do_extra_solve;
+ const float time_multiplier = 1.0f / (clmd->sim_parms->dt * clmd->sim_parms->timescale);
int i;
if (!(clmd->coll_parms->flags & (CLOTH_COLLSETTINGS_FLAG_ENABLED | CLOTH_COLLSETTINGS_FLAG_SELF)))
@@ -906,69 +899,26 @@ static void cloth_collision_solve_extra(
if (!clmd->clothObject->bvhtree)
return;
- // update verts to current positions
+ BPH_mass_spring_solve_positions(id, dt);
+
+ /* Update verts to current positions. */
for (i = 0; i < mvert_num; i++) {
BPH_mass_spring_get_new_position(id, i, verts[i].tx);
sub_v3_v3v3(verts[i].tv, verts[i].tx, verts[i].txold);
- copy_v3_v3(verts[i].v, verts[i].tv);
- }
-
-#if 0 /* unused */
- for (i=0, cv=cloth->verts; i<cloth->mvert_num; i++, cv++) {
- copy_v3_v3(initial_cos[i], cv->tx);
- }
-#endif
-
- // call collision function
- // TODO: check if "step" or "step+dt" is correct - dg
- do_extra_solve = cloth_bvh_objcollision(
- depsgraph, ob, clmd, step / clmd->sim_parms->timescale, dt / clmd->sim_parms->timescale);
-
- // copy corrected positions back to simulation
- for (i = 0; i < mvert_num; i++) {
- float curx[3];
- BPH_mass_spring_get_position(id, i, curx);
- // correct velocity again, just to be sure we had to change it due to adaptive collisions
- sub_v3_v3v3(verts[i].tv, verts[i].tx, curx);
+ zero_v3(verts[i].dcvel);
}
- if (do_extra_solve) {
-// cloth_calc_helper_forces(ob, clmd, initial_cos, step/clmd->sim_parms->timescale, dt/clmd->sim_parms->timescale);
-
+ if (cloth_bvh_collision(depsgraph, ob, clmd, step / clmd->sim_parms->timescale, dt / clmd->sim_parms->timescale)) {
for (i = 0; i < mvert_num; i++) {
-
- float newv[3];
-
- if ((clmd->sim_parms->vgroup_mass > 0) && (verts [i].flags & CLOTH_VERT_FLAG_PINNED))
+ if ((clmd->sim_parms->vgroup_mass > 0) && (verts[i].flags & CLOTH_VERT_FLAG_PINNED))
continue;
- BPH_mass_spring_set_new_position(id, i, verts[i].tx);
- mul_v3_v3fl(newv, verts[i].tv, spf);
- BPH_mass_spring_set_new_velocity(id, i, newv);
+ BPH_mass_spring_get_new_velocity(id, i, verts[i].tv);
+ madd_v3_v3fl(verts[i].tv, verts[i].dcvel, time_multiplier);
+ BPH_mass_spring_set_new_velocity(id, i, verts[i].tv);
}
}
-
- // X = Xnew;
- BPH_mass_spring_apply_result(id);
-
- if (do_extra_solve) {
- ImplicitSolverResult result;
-
- /* initialize forces to zero */
- BPH_mass_spring_clear_forces(id);
-
- // calculate forces
- cloth_calc_force(scene, clmd, frame, effectors, step);
-
- // calculate new velocity and position
- BPH_mass_spring_solve_velocities(id, dt, &result);
-// cloth_record_result(clmd, &result, clmd->sim_parms->stepsPerFrame);
-
- /* note: positions are advanced only once in the main solver step! */
-
- BPH_mass_spring_apply_result(id);
- }
}
static void cloth_clear_result(ClothModifierData *clmd)
@@ -981,7 +931,7 @@ static void cloth_clear_result(ClothModifierData *clmd)
sres->avg_iterations = 0.0f;
}
-static void cloth_record_result(ClothModifierData *clmd, ImplicitSolverResult *result, int steps)
+static void cloth_record_result(ClothModifierData *clmd, ImplicitSolverResult *result, float dt)
{
ClothSolverResult *sres = clmd->solver_result;
@@ -990,22 +940,22 @@ static void cloth_record_result(ClothModifierData *clmd, ImplicitSolverResult *r
if (result->status == BPH_SOLVER_SUCCESS) {
sres->min_error = min_ff(sres->min_error, result->error);
sres->max_error = max_ff(sres->max_error, result->error);
- sres->avg_error += result->error / (float)steps;
+ sres->avg_error += result->error * dt;
}
sres->min_iterations = min_ii(sres->min_iterations, result->iterations);
sres->max_iterations = max_ii(sres->max_iterations, result->iterations);
- sres->avg_iterations += (float)result->iterations / (float)steps;
+ sres->avg_iterations += (float)result->iterations * dt;
}
else {
/* error only makes sense for successful iterations */
if (result->status == BPH_SOLVER_SUCCESS) {
sres->min_error = sres->max_error = result->error;
- sres->avg_error += result->error / (float)steps;
+ sres->avg_error += result->error * dt;
}
sres->min_iterations = sres->max_iterations = result->iterations;
- sres->avg_iterations += (float)result->iterations / (float)steps;
+ sres->avg_iterations += (float)result->iterations * dt;
}
sres->status |= result->status;
@@ -1025,7 +975,7 @@ int BPH_cloth_solve(Depsgraph *depsgraph, Object *ob, float frame, ClothModifier
Cloth *cloth = clmd->clothObject;
ClothVertex *verts = cloth->verts/*, *cv*/;
unsigned int mvert_num = cloth->mvert_num;
- float dt = clmd->sim_parms->timescale / clmd->sim_parms->stepsPerFrame;
+ float dt = clmd->sim_parms->dt * clmd->sim_parms->timescale;
Implicit_Data *id = cloth->implicit;
ColliderContacts *contacts = NULL;
int totcolliders = 0;
@@ -1053,12 +1003,6 @@ int BPH_cloth_solve(Depsgraph *depsgraph, Object *ob, float frame, ClothModifier
while (step < tf) {
ImplicitSolverResult result;
- /* copy velocities for collision */
- for (i = 0; i < mvert_num; i++) {
- BPH_mass_spring_get_motion_state(id, i, NULL, verts[i].tv);
- copy_v3_v3(verts[i].v, verts[i].tv);
- }
-
if (is_hair) {
/* determine contact points */
if (clmd->coll_parms->flags & CLOTH_COLLSETTINGS_FLAG_ENABLED) {
@@ -1081,18 +1025,18 @@ int BPH_cloth_solve(Depsgraph *depsgraph, Object *ob, float frame, ClothModifier
// calculate new velocity and position
BPH_mass_spring_solve_velocities(id, dt, &result);
- cloth_record_result(clmd, &result, clmd->sim_parms->stepsPerFrame);
+ cloth_record_result(clmd, &result, dt);
+
+ /* Calculate collision impulses. */
+ if (!is_hair) {
+ cloth_solve_collisions(depsgraph, ob, clmd, step, dt);
+ }
if (is_hair) {
cloth_continuum_step(clmd, dt);
}
BPH_mass_spring_solve_positions(id, dt);
-
- if (!is_hair) {
- cloth_collision_solve_extra(depsgraph, scene, ob, clmd, effectors, frame, step, dt);
- }
-
BPH_mass_spring_apply_result(id);
/* move pinned verts to correct position */